Merge pull request #3771 from OPM/dev

Merge dev into master for Release 2018.11
This commit is contained in:
Magne Sjaastad 2018-11-28 09:39:16 +01:00 committed by GitHub
commit bd44ec8d51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2093 changed files with 108614 additions and 38724 deletions

View File

@ -1,5 +1,5 @@
---
Checks: '-*,modernize-use-nullptr'
Checks: '-*,modernize-use-nullptr,modernize-use-override'
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
...

View File

@ -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

View File

@ -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

View File

@ -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
-------

View File

@ -7,8 +7,10 @@ ${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
@ -20,8 +22,10 @@ ${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

View File

@ -34,6 +34,7 @@
#include "RicImportInputEclipseCaseFeature.h"
#include "RicImportSummaryCasesFeature.h"
#include "ExportCommands/RicSnapshotAllViewsToFileFeature.h"
#include "HoloLensCommands/RicHoloLensSessionManager.h"
#include "Rim2dIntersectionViewCollection.h"
#include "RimCellRangeFilterCollection.h"
@ -57,6 +58,7 @@
#include "RimRftPlotCollection.h"
#include "RimStimPlanColors.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryCaseMainCollection.h"
#include "RimSummaryCrossPlotCollection.h"
#include "RimSummaryPlot.h"
@ -87,6 +89,7 @@
#include "cafPdmUiTreeView.h"
#include "cafProgressInfo.h"
#include "cafQTreeViewStateSerializer.h"
#include "cafSelectionManager.h"
#include "cafUiProcess.h"
#include "cafUtils.h"
@ -97,6 +100,7 @@
#include <QFileDialog>
#include <QMdiSubWindow>
#include <QMessageBox>
#include <QProcessEnvironment>
#include <QTreeView>
@ -404,6 +408,7 @@ bool RiaApplication::loadProject(const QString& projectFileName, ProjectLoadActi
if (!m_mainPlotWindow)
{
createMainPlotWindow();
m_mainPlotWindow->show();
}
else
{
@ -464,7 +469,7 @@ bool RiaApplication::loadProject(const QString& projectFileName, ProjectLoadActi
if (oilField->wellPathCollection)
{
oilField->wellPathCollection->readWellPathFiles();
oilField->wellPathCollection->loadDataAndUpdate();
oilField->wellPathCollection->readWellPathFormationFiles();
}
}
@ -596,6 +601,17 @@ bool RiaApplication::loadProject(const QString& projectFileName, ProjectLoadActi
cas->intersectionViewCollection()->syncFromExistingIntersections(false);
}
// Init summary case groups
for (RimOilField* oilField : m_project->oilFields)
{
auto sumMainCollection = oilField->summaryCaseMainCollection();
if(!sumMainCollection) continue;
for (auto sumCaseGroup : sumMainCollection->summaryCaseCollections())
{
sumCaseGroup->loadDataAndUpdate();
}
}
loadAndUpdatePlotData();
@ -980,13 +996,16 @@ bool RiaApplication::saveProjectAs(const QString& fileName)
//--------------------------------------------------------------------------------------------------
void RiaApplication::closeProject()
{
RicHoloLensSessionManager::instance()->terminateSession();
RicHoloLensSessionManager::refreshToolbarState();
RiuMainWindow* mainWnd = RiuMainWindow::instance();
RiaViewRedrawScheduler::instance()->clearViewsScheduledForUpdate();
terminateProcess();
RiuSelectionManager::instance()->deleteAllItems();
RiaApplication::clearAllSelections();
mainWnd->cleanupGuiBeforeProjectClose();
@ -1075,7 +1094,7 @@ QString RiaApplication::createAbsolutePathFromProjectRelativePath(QString projec
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication::openOdbCaseFromFile(const QString& fileName)
bool RiaApplication::openOdbCaseFromFile(const QString& fileName, bool applyTimeStepFilter)
{
if (!caf::Utils::fileExists(fileName)) return false;
@ -1085,7 +1104,8 @@ bool RiaApplication::openOdbCaseFromFile(const QString& fileName)
RimGeoMechCase* geoMechCase = new RimGeoMechCase();
geoMechCase->setFileName(fileName);
geoMechCase->caseUserDescription = caseName;
geoMechCase->setApplyTimeFilter(applyTimeStepFilter);
RimGeoMechModels* geoMechModelCollection = m_project->activeOilField() ? m_project->activeOilField()->geoMechModels() : nullptr;
// Create the geoMech model container if it is not there already
@ -1095,14 +1115,19 @@ bool RiaApplication::openOdbCaseFromFile(const QString& fileName)
m_project->activeOilField()->geoMechModels = geoMechModelCollection;
}
geoMechModelCollection->cases.push_back(geoMechCase);
RimGeoMechView* riv = geoMechCase->createAndAddReservoirView();
caf::ProgressInfo progress(11, "Loading Case");
progress.setNextProgressIncrement(10);
riv->loadDataAndUpdate();
if (!riv->geoMechCase())
{
delete geoMechCase;
return false;
}
geoMechModelCollection->cases.push_back(geoMechCase);
//if (!riv->cellResult()->hasResult())
//{
// riv->cellResult()->setResultVariable(RiaDefines::undefinedResultName());
@ -1212,15 +1237,6 @@ void RiaApplication::setActiveReservoirView(Rim3dView* rv)
RiuDockWidgetTools::instance()->changeDockWidgetVisibilityBasedOnView(rv);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::setUseShaders(bool enable)
{
m_preferences->useShaders = enable;
caf::PdmSettings::writeFieldsToApplicationStore(m_preferences);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1244,16 +1260,6 @@ RiaApplication::RINavigationPolicy RiaApplication::navigationPolicy() const
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::setShowPerformanceInfo(bool enable)
{
m_preferences->showHud = enable;
caf::PdmSettings::writeFieldsToApplicationStore(m_preferences);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1326,6 +1332,20 @@ int RiaApplication::launchUnitTestsWithConsole()
return launchUnitTests();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuPlotMainWindow* RiaApplication::getOrCreateMainPlotWindow()
{
if (!m_mainPlotWindow)
{
createMainPlotWindow();
m_mainPlotWindow->initializeGuiNewProjectLoaded();
loadAndUpdatePlotData();
}
return m_mainPlotWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1338,7 +1358,6 @@ void RiaApplication::createMainPlotWindow()
m_mainPlotWindow->setWindowTitle("Plots - ResInsight");
m_mainPlotWindow->setDefaultWindowSize();
m_mainPlotWindow->loadWinGeoAndDockToolBarLayout();
m_mainPlotWindow->showWindow();
}
//--------------------------------------------------------------------------------------------------
@ -1376,7 +1395,7 @@ RiuPlotMainWindow* RiaApplication::getOrCreateAndShowMainPlotWindow()
}
m_mainPlotWindow->raise();
m_mainPlotWindow->activateWindow();
return m_mainPlotWindow;
}
@ -1562,6 +1581,25 @@ void RiaApplication::saveWinGeoAndDockToolBarLayout()
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaApplication::enableDevelopmentFeatures()
{
QString environmentVar = QProcessEnvironment::systemEnvironment().value("RESINSIGHT_DEVEL", QString("0"));
return environmentVar.toInt() == 1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaApplication::clearAllSelections()
{
RiuSelectionManager::instance()->deleteAllItems(RiuSelectionManager::RUI_APPLICATION_GLOBAL);
RiuSelectionManager::instance()->deleteAllItems(RiuSelectionManager::RUI_TEMPORARY);
caf::SelectionManager::instance()->clearAll();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1898,6 +1936,14 @@ QString RiaApplication::lastUsedDialogDirectoryWithFallback(const QString& dialo
return lastUsedDirectory;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaApplication::lastUsedDialogDirectoryWithFallbackToProjectFolder(const QString& dialogName)
{
return lastUsedDialogDirectoryWithFallback(dialogName, currentProjectPath());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -2111,20 +2157,22 @@ void RiaApplication::addCommandObject(RimCommandObject* commandObject)
//--------------------------------------------------------------------------------------------------
void RiaApplication::executeCommandObjects()
{
std::list< RimCommandObject* >::iterator it = m_commandQueue.begin();
while (it != m_commandQueue.end())
{
RimCommandObject* toBeRemoved = *it;
if (!toBeRemoved->isAsyncronous())
std::list<RimCommandObject*>::iterator it = m_commandQueue.begin();
while (it != m_commandQueue.end())
{
toBeRemoved->redo();
RimCommandObject* toBeRemoved = *it;
if (!toBeRemoved->isAsyncronous())
{
toBeRemoved->redo();
++it;
m_commandQueue.remove(toBeRemoved);
}
else
{
++it;
++it;
m_commandQueue.remove(toBeRemoved);
}
else
{
++it;
}
}
}

View File

@ -92,7 +92,7 @@ public:
public:
RiaApplication(int& argc, char** argv);
~RiaApplication();
~RiaApplication() override;
static RiaApplication* instance();
@ -100,13 +100,13 @@ public:
bool parseArguments();
void setActiveReservoirView(Rim3dView*);
Rim3dView* activeReservoirView();
Rim3dView* activeReservoirView();
const Rim3dView* activeReservoirView() const;
RimGridView* activeGridView();
RimViewWindow* activePlotWindow() const;
RimProject* project();
RimProject* project();
void createMockModel();
void createResultsMockModel();
@ -115,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);
@ -144,10 +145,8 @@ public:
static const char* getVersionStringApp(bool includeCrtInfo);
void setUseShaders(bool enable);
bool useShaders() const;
void setShowPerformanceInfo(bool enable);
bool showPerformanceInfo() const;
RINavigationPolicy navigationPolicy() const;
@ -180,6 +179,7 @@ public:
int launchUnitTests();
int launchUnitTestsWithConsole();
RiuPlotMainWindow* getOrCreateMainPlotWindow();
RiuPlotMainWindow* getOrCreateAndShowMainPlotWindow();
RiuPlotMainWindow* mainPlotWindow();
RiuMainWindowBase* mainWindowByID(int mainWindowID);
@ -202,27 +202,30 @@ public:
void waitUntilCommandObjectsHasBeenProcessed();
void saveWinGeoAndDockToolBarLayout();
private:
void onProjectOpenedOrClosed();
void setWindowCaptionFromAppState();
static bool enableDevelopmentFeatures();
static void clearAllSelections();
void createMainPlotWindow();
void deleteMainPlotWindow();
private:
void onProjectOpenedOrClosed();
void setWindowCaptionFromAppState();
void createMainPlotWindow();
void deleteMainPlotWindow();
void loadAndUpdatePlotData();
void loadAndUpdatePlotData();
void storeTreeViewState();
void storeTreeViewState();
friend RiaArgumentParser;
void setHelpText(const QString& helpText);
void setHelpText(const QString& helpText);
virtual bool notify(QObject *, QEvent *) override;
bool notify(QObject *, QEvent *) override;
private slots:
void slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
void slotWorkerProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
private:
caf::PdmPointer<Rim3dView> m_activeReservoirView;
caf::PdmPointer<Rim3dView> m_activeReservoirView;
caf::PdmPointer<RimProject> m_project;
RiaSocketServer* m_socketServer;

View File

@ -114,12 +114,15 @@ void RiaCompletionTypeCalculationScheduler::slotRecalculateCompletionType()
for (RimEclipseCase* eclipseCase : uniqueCases)
{
for (const auto& w : eclipseCase->views())
if (eclipseCase)
{
RimEclipseView* eclView = dynamic_cast<RimEclipseView*>(w);
if (eclView)
for (const auto& w : eclipseCase->views())
{
eclView->calculateCompletionTypeAndRedrawIfRequired();
RimEclipseView* eclView = dynamic_cast<RimEclipseView*>(w);
if (eclView)
{
eclView->calculateCompletionTypeAndRedrawIfRequired();
}
}
}
}

View File

@ -40,7 +40,7 @@ private slots:
private:
RiaCompletionTypeCalculationScheduler() : m_recalculateCompletionTypeTimer(nullptr) {}
~RiaCompletionTypeCalculationScheduler();
~RiaCompletionTypeCalculationScheduler() override;
RiaCompletionTypeCalculationScheduler(const RiaCompletionTypeCalculationScheduler& o) = delete;
void operator=(const RiaCompletionTypeCalculationScheduler& o) = delete;

View File

@ -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());
}

View File

@ -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;
};

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() };
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

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
{

View File

@ -27,27 +27,37 @@ QString RiaDefines::conductivityResultName()
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
QString RiaDefines::unitStringConductivity(RiaEclipseUnitTools::UnitSystem unitSystem)
{
switch (unitSystem)
{
case RiaEclipseUnitTools::UNITS_METRIC: return "md-m";
case RiaEclipseUnitTools::UNITS_FIELD: return "md-ft";
default: return "";
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;
default: return 0.0;
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;
}
}

View File

@ -27,5 +27,5 @@ namespace RiaDefines
QString conductivityResultName();
QString unitStringConductivity(RiaEclipseUnitTools::UnitSystem unitSystem);
double nonDarcyFlowAlpha(RiaEclipseUnitTools::UnitSystem unitSystem);
};
double nonDarcyFlowAlpha(RiaEclipseUnitTools::UnitSystem unitSystem);
}; // namespace RiaDefines

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();

View File

@ -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";
}
}
}

View File

@ -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;
};

View File

@ -81,14 +81,14 @@ 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(&showTestToolbar, "showTestToolbar", false, "Enable Test Toolbar", "", "", "");
showTestToolbar.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", "", "", "");
@ -105,13 +105,20 @@ RiaPreferences::RiaPreferences(void)
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";
}
}
//--------------------------------------------------------------------------------------------------
@ -143,10 +150,10 @@ void RiaPreferences::defineEditorAttribute(const caf::PdmFieldHandle* field, QSt
field == &loadAndShowSoil ||
field == &useShaders ||
field == &showHud ||
field == &appendClassNameToUiText ||
field == &appendFieldKeywordToToolTipText ||
field == &showTestToolbar ||
field == &includeFractureDebugInfoFile ||
field == &m_appendClassNameToUiText ||
field == &m_appendFieldKeywordToToolTipText ||
field == &m_showTestToolbar ||
field == &m_includeFractureDebugInfoFile ||
field == &showLasCurveWithoutTvdWarning)
{
caf::PdmUiCheckBoxEditorAttribute* myAttr = dynamic_cast<caf::PdmUiCheckBoxEditorAttribute*>(attribute);
@ -155,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;
}
}
}
//--------------------------------------------------------------------------------------------------
@ -210,12 +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(&showTestToolbar);
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);
@ -272,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();
}

View File

@ -41,12 +41,19 @@ public:
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;
@ -69,11 +76,7 @@ public: // Pdm Fields
caf::PdmField<bool> showLegendBackground;
caf::PdmField<bool> useShaders;
caf::PdmField<bool> showHud;
caf::PdmField<bool> appendClassNameToUiText;
caf::PdmField<bool> appendFieldKeywordToToolTipText;
caf::PdmField<bool> showTestToolbar;
caf::PdmField<bool> includeFractureDebugInfoFile;
caf::PdmField<bool> showHud;
caf::PdmField<QString> lastUsedProjectFileName;
@ -85,12 +88,16 @@ public: // Pdm Fields
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;
};

View File

@ -144,11 +144,23 @@ bool RiaSummaryCurveDefinition::operator<(const RiaSummaryCurveDefinition& other
{
if (m_summaryCase != other.summaryCase())
{
// 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();
}
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());
}

View File

@ -37,7 +37,7 @@ public:
RiaSummaryCurveDefinition();
explicit RiaSummaryCurveDefinition(RimSummaryCase* summaryCase,
const RifEclipseSummaryAddress& summaryAddress,
RimSummaryCaseCollection* emsemble = nullptr);
RimSummaryCaseCollection* ensemble = nullptr);
RimSummaryCase* summaryCase() const;
const RifEclipseSummaryAddress& summaryAddress() const;

View File

@ -42,7 +42,7 @@ private:
void startTimer(int msecs);
RiaViewRedrawScheduler() : m_resViewUpdateTimer(nullptr) {}
~RiaViewRedrawScheduler();
~RiaViewRedrawScheduler() override;
RiaViewRedrawScheduler(const RiaViewRedrawScheduler& o) = delete;
void operator=(const RiaViewRedrawScheduler& o) = delete;

View File

@ -24,6 +24,20 @@ ${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
@ -51,6 +65,17 @@ ${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

View File

@ -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;
}

View File

@ -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);
};

View File

@ -158,34 +158,7 @@ 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 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
};
static caf::ColorTable colorTable = caf::ColorTable(colors);
static caf::ColorTable colorTable = caf::ColorTable(categoryColors());
return colorTable;
}
@ -428,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)),
@ -442,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);
@ -497,6 +470,38 @@ 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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -505,14 +510,85 @@ 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}};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RiaColorTables::perforationLengthColor()
std::vector<cvf::Color3ub> RiaColorTables::categoryColors()
{
// based on hwb ( 85, 9%, 67%) dark_olive_green
// added 10 to each component
cvf::Color3ub color(69, 94, 33);
// 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.
return cvf::Color3f(color);
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;
}

View File

@ -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();
@ -53,7 +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 cvf::Color3f perforationLengthColor();
static WellPathComponentColors wellPathComponentColors();
private:
static std::vector<cvf::Color3ub> categoryColors();
static std::vector<cvf::Color3ub> invertedCategoryColors();
};

View File

@ -88,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());
}

View File

@ -21,6 +21,7 @@
#include "cvfBase.h"
#include "cvfArray.h"
#include <QColor>
//==================================================================================================
///
@ -35,4 +36,6 @@ public:
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);
};

View File

@ -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)
{

View File

@ -32,7 +32,7 @@ class QDateTime;
//==================================================================================================
///
//==================================================================================================
class RigCurveDataTools
class RiaCurveDataTools
{
public:
typedef std::vector<std::pair<size_t, size_t>> CurveIntervals;

View File

@ -162,6 +162,9 @@ bool RiaDateStringParser::tryParseMonth(const std::string& s, int &month)
{
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)
@ -210,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;
}

View File

@ -125,13 +125,13 @@ QString RiaEclipseUnitTools::unitStringPressure(UnitSystem unitSystem)
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
double RiaEclipseUnitTools::convertToMeter(double sourceValue, const QString& unitText)
double RiaEclipseUnitTools::convertToMeter(double sourceValue, const QString& sourceValueUnitText)
{
QString timmed = unitText.trimmed();
QString timmed = sourceValueUnitText.trimmed();
if (timmed.compare("m", Qt::CaseInsensitive) == 0)
if (timmed.compare("m", Qt::CaseInsensitive) == 0 || timmed.compare("md-m", Qt::CaseInsensitive) == 0)
{
return sourceValue;
}
@ -139,11 +139,15 @@ double RiaEclipseUnitTools::convertToMeter(double sourceValue, const QString& un
{
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)
else if (timmed.compare("ft", Qt::CaseInsensitive) == 0 || timmed.compare("md-ft", Qt::CaseInsensitive) == 0)
{
return RiaEclipseUnitTools::feetToMeter(sourceValue);
}
@ -152,13 +156,13 @@ double RiaEclipseUnitTools::convertToMeter(double sourceValue, const QString& un
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
double RiaEclipseUnitTools::convertToFeet(double sourceValue, const QString& unitText)
double RiaEclipseUnitTools::convertToFeet(double sourceValue, const QString& sourceValueUnitText)
{
QString timmed = unitText.trimmed();
QString timmed = sourceValueUnitText.trimmed();
if (timmed.compare("ft", Qt::CaseInsensitive) == 0)
if (timmed.compare("ft", Qt::CaseInsensitive) == 0 || timmed.compare("md-ft", Qt::CaseInsensitive) == 0)
{
return sourceValue;
}
@ -171,11 +175,15 @@ double RiaEclipseUnitTools::convertToFeet(double sourceValue, const QString& uni
double meter = sourceValue / 100.0;
return RiaEclipseUnitTools::meterToFeet(meter);
}
else if (timmed.compare("m", Qt::CaseInsensitive) == 0)
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;
}

View File

@ -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);
}
}

View File

@ -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);
};

View File

@ -99,32 +99,16 @@ QString RiaFilePathTools::canonicalPath(const QString& path)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RiaFilePathTools::commonRootPath(const QStringList& paths)
std::pair<QString, QString> RiaFilePathTools::toFolderAndFileName(const QString& absFileName)
{
if (paths.size() < 2) return "";
int i = 0;
int iDir = 0;
for(i = 0; ; i++)
auto absFN = toInternalSeparator(absFileName);
int lastSep = absFN.lastIndexOf(SEPARATOR);
if (lastSep > 0)
{
bool isCommon = true;
QChar ch = i < paths.front().size() ? paths.front()[i] : 0;
// Remember last directory separator
if (i > 0 && (ch == '/' || ch == '\\')) iDir = i;
// Compare characters at position i
for (const QString& path : paths)
{
if (ch == 0 || path[i] != ch)
{
isCommon = false;
break;
}
}
if (!isCommon) break;
return std::make_pair(absFN.left(lastSep), absFN.mid(lastSep+1));
}
else
{
return std::make_pair("", absFN);
}
return paths.front().left(iDir + 1);
}

View File

@ -39,5 +39,5 @@ public:
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 QString commonRootPath(const QStringList& paths);
static std::pair<QString, QString> toFolderAndFileName(const QString& absFileName);
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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)

View File

@ -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();

View File

@ -35,14 +35,15 @@
#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 "RimSummaryCaseMainCollection.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryCaseMainCollection.h"
#include "RimSummaryCurve.h"
#include "RimSummaryCurveCollection.h"
#include "RimSummaryCurveFilter.h"
@ -111,16 +112,16 @@ bool RiaImportEclipseCaseTools::openEclipseCasesFromFile(const QStringList& file
// Replace all occurrences of file sum with ecl sum
std::vector<caf::PdmObjectHandle*> referringObjects;
existingFileSummaryCase->objectsWithReferringPtrFields(referringObjects);
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 (caf::PdmObjectHandle* objHandle : referringObjects)
for (RimSummaryCurve* summaryCurve : objects)
{
RimSummaryCurve* summaryCurve = dynamic_cast<RimSummaryCurve*>(objHandle);
if (summaryCurve)
{
RimSummaryCurveCollection* parentCollection = nullptr;
@ -158,6 +159,8 @@ bool RiaImportEclipseCaseTools::openEclipseCasesFromFile(const QStringList& file
RiaLogging::error(errorMessage);
}
project->activeOilField()->fractureDefinitionCollection()->setDefaultUnitSystemBasedOnLoadedCases();
RiuPlotMainWindowTools::refreshToolbars();
return true;

View File

@ -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);
@ -212,7 +212,7 @@ void RiaLogging::error(const QString& message)
{
if (sm_logger && sm_logger->level() >= RI_LL_ERROR)
{
#pragma omp critical
#pragma omp critical(critical_section_logging)
sm_logger->error(message.toLatin1().constData());
}
}
@ -224,7 +224,7 @@ void RiaLogging::warning(const QString& message)
{
if (sm_logger && sm_logger->level() >= RI_LL_WARNING)
{
#pragma omp critical
#pragma omp critical(critical_section_logging)
sm_logger->warning(message.toLatin1().constData());
}
}
@ -236,7 +236,7 @@ void RiaLogging::info(const QString& message)
{
if (sm_logger && sm_logger->level() >= RI_LL_INFO)
{
#pragma omp critical
#pragma omp critical(critical_section_logging)
sm_logger->info(message.toLatin1().constData());
}
}
@ -248,7 +248,7 @@ void RiaLogging::debug(const QString& message)
{
if (sm_logger && sm_logger->level() >= RI_LL_DEBUG)
{
#pragma omp critical
#pragma omp critical(critical_section_logging)
sm_logger->debug(message.toLatin1().constData());
}
}

View File

@ -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;
};

View File

@ -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));
}

View File

@ -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);
};

View File

@ -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"
@ -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);
}
}
}
}

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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);
};

View File

@ -1,17 +1,17 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
@ -22,39 +22,61 @@
#include "cafPdmUiFilePathEditor.h"
#include "cafPdmUiTextEditor.h"
CAF_PDM_SOURCE_INIT(RiaRegressionTest, "RiaRegressionTest");
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
RiaRegressionTest::RiaRegressionTest(void)
{
CAF_PDM_InitFieldNoDefault(&folderContainingCompareTool, "workingFolder", "Folder containing <b>compare</b>", "", "Location of compare tool from Image Magic suite", "");
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", "");
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
{
@ -62,7 +84,7 @@ void RiaRegressionTest::writeSettingsToApplicationStore() const
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTest::readSettingsFromApplicationStore()
{
@ -70,11 +92,14 @@ void RiaRegressionTest::readSettingsFromApplicationStore()
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTest::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
void RiaRegressionTest::defineEditorAttribute(const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute)
{
if (field == &folderContainingDiffTool || field == &folderContainingCompareTool || field == &regressionTestFolder)
if (field == &folderContainingDiffTool || field == &folderContainingCompareTool || field == &regressionTestFolder ||
field == &folderContainingGitTool)
{
caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast<caf::PdmUiFilePathEditorAttribute*>(attribute);
if (myAttr)

View File

@ -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,18 +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> folderContainingCompareTool;
caf::PdmField<QString> folderContainingDiffTool;
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;
};

View File

@ -19,6 +19,7 @@
#include "RiaRegressionTestRunner.h"
#include "RiaApplication.h"
#include "RiaGitDiff.h"
#include "RiaImageCompareReporter.h"
#include "RiaImageFileCompare.h"
#include "RiaLogging.h"
@ -32,13 +33,15 @@
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RiuPlotMainWindow.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>
@ -95,14 +98,14 @@ RiaRegressionTestRunner* RiaRegressionTestRunner::instance()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::runRegressionTest(const QString& testRootPath, const QStringList& testFilter)
void RiaRegressionTestRunner::runRegressionTest()
{
m_runningRegressionTests = true;
QString currentApplicationPath = QDir::currentPath();
RiaRegressionTest regressionTestConfig;
regressionTestConfig.readSettingsFromApplicationStore();
QString currentApplicationPath = QDir::currentPath();
if (!regressionTestConfig.folderContainingCompareTool().isEmpty())
{
// Windows Only : The image compare tool requires current working directory to be at the folder
@ -117,53 +120,290 @@ void RiaRegressionTestRunner::runRegressionTest(const QString& testRootPath, con
QString regTestProjectName = RegTestNames::testProjectName;
QString regTestFolderFilter = RegTestNames::testFolderFilter;
QDir testDir(testRootPath); // If string is empty it will end up as cwd
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 = testDir.entryInfoList();
if (!testFilter.isEmpty())
{
QFileInfoList subset;
for (auto fi : folderList)
{
QString path = fi.path();
QString baseName = fi.baseName();
for (auto s : testFilter)
{
QString trimmed = s.trimmed();
if (baseName.contains(trimmed))
{
subset.push_back(fi);
}
}
}
folderList = subset;
}
QFileInfoList folderList = subDirectoriesForTestExecution(testDir);
// delete diff and generated images
for (int i = 0; i < folderList.size(); ++i)
for (const QFileInfo& fi : folderList)
{
QDir testCaseFolder(folderList[i].filePath());
QDir testCaseFolder(fi.filePath());
QDir genDir(testCaseFolder.filePath(generatedFolderName));
removeDirectoryWithContent(genDir);
{
QDir genDir(testCaseFolder.filePath(generatedFolderName));
removeDirectoryWithContent(genDir);
}
QDir diffDir(testCaseFolder.filePath(diffFolderName));
removeDirectoryWithContent(diffDir);
{
QDir diffDir(testCaseFolder.filePath(diffFolderName));
removeDirectoryWithContent(diffDir);
}
QDir baseDir(testCaseFolder.filePath(baseFolderName));
{
QDir generatedFiles(testCaseFolder.filePath(RegTestNames::generatedFilesFolderName));
removeDirectoryWithContent(generatedFiles);
}
}
// Generate html report
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
@ -179,14 +419,9 @@ void RiaRegressionTestRunner::runRegressionTest(const QString& testRootPath, con
}
}
QTime timeStamp;
timeStamp.start();
logInfoTextWithTimeInSeconds(timeStamp, "Starting regression tests\n");
for (int dirIdx = 0; dirIdx < folderList.size(); ++dirIdx)
for (const QFileInfo& fi : folderList)
{
QDir testCaseFolder(folderList[dirIdx].filePath());
QDir testCaseFolder(fi.filePath());
QString testFolderName = testCaseFolder.dirName();
QString reportBaseFolderName = testCaseFolder.filePath(baseFolderName);
@ -200,175 +435,11 @@ void RiaRegressionTestRunner::runRegressionTest(const QString& testRootPath, con
}
QString htmlReportFileName = testDir.filePath(RegTestNames::reportFileName);
imageCompareReporter.generateHTMLReport(htmlReportFileName.toStdString());
// Open HTML report
QDesktopServices::openUrl(htmlReportFileName);
QString htmldiff2htmlText = diff2htmlHeaderText(m_rootPath);
imageCompareReporter.generateHTMLReport(htmlReportFileName.toStdString(), htmldiff2htmlText.toStdString());
for (int dirIdx = 0; dirIdx < folderList.size(); ++dirIdx)
{
QDir testCaseFolder(folderList[dirIdx].filePath());
// Detect any command files
QStringList filterList;
filterList << RegTestNames::commandFileFilter;
QFileInfoList commandFileEntries = testCaseFolder.entryInfoList(filterList);
if (!commandFileEntries.empty())
{
QString currentApplicationPath = 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(folderList[dirIdx].filePath());
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(currentApplicationPath);
// Create diff based on generated folders
{
QString html;
RiaRegressionTest regressionTestConfig;
regressionTestConfig.readSettingsFromApplicationStore();
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;
}
}
}
}
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);
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();
}
}
app->closeProject();
logInfoTextWithTimeInSeconds(timeStamp, "Completed test :" + testCaseFolder.absolutePath());
}
else
{
RiaLogging::error("Could not find a regression test file named : " + testCaseFolder.absolutePath() + "/" +
regTestProjectName + ".rsp");
}
}
RiaLogging::info("\n");
logInfoTextWithTimeInSeconds(timeStamp, "Completed regression tests");
QDir::setCurrent(currentApplicationPath);
m_runningRegressionTests = false;
return htmlReportFileName;
}
//--------------------------------------------------------------------------------------------------
@ -376,12 +447,7 @@ void RiaRegressionTestRunner::runRegressionTest(const QString& testRootPath, con
//--------------------------------------------------------------------------------------------------
void RiaRegressionTestRunner::removeDirectoryWithContent(QDir& dirToDelete)
{
QStringList files = dirToDelete.entryList();
for (int fIdx = 0; fIdx < files.size(); ++fIdx)
{
dirToDelete.remove(files[fIdx]);
}
dirToDelete.rmdir(".");
caf::Utils::removeDirectoryAndFilesRecursively(dirToDelete.absolutePath());
}
//--------------------------------------------------------------------------------------------------
@ -398,17 +464,14 @@ void RiaRegressionTestRunner::regressionTestConfigureProject()
std::vector<RimCase*> projectCases;
proj->allCases(projectCases);
for (size_t i = 0; i < projectCases.size(); i++)
for (RimCase* cas : projectCases)
{
RimCase* cas = projectCases[i];
if (!cas) continue;
std::vector<Rim3dView*> views = cas->views();
for (size_t j = 0; j < views.size(); j++)
for (Rim3dView* riv : views)
{
Rim3dView* riv = views[j];
if (riv && riv->viewer())
{
// Make sure all views are maximized for snapshotting
@ -472,6 +535,74 @@ 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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -498,7 +629,12 @@ void RiaRegressionTestRunner::executeRegressionTests(const QString& regressionTe
mainWnd->statusBar()->close();
mainWnd->setDefaultWindowSize();
runRegressionTest(regressionTestPath, testFilter);
m_regressionTestSettings.readSettingsFromApplicationStore();
m_rootPath = regressionTestPath;
m_testFilter = testFilter;
runRegressionTest();
mainWnd->loadWinGeoAndDockToolBarLayout();
}
@ -512,6 +648,16 @@ bool RiaRegressionTestRunner::isRunningRegressionTests() const
return m_runningRegressionTests;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaRegressionTestRunner::useOpenMPForGeometryCreation() const
{
if (!m_runningRegressionTests) return false;
return m_regressionTestSettings.useOpenMPForGeometryCreation;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -527,9 +673,9 @@ void RiaRegressionTestRunner::updateRegressionTest(const QString& testRootPath)
QFileInfoList folderList = testDir.entryInfoList();
for (int i = 0; i < folderList.size(); ++i)
for (const auto& fi : folderList)
{
QDir testCaseFolder(folderList[i].filePath());
QDir testCaseFolder(fi.filePath());
QDir baseDir(testCaseFolder.filePath(RegTestNames::baseFolderName));
removeDirectoryWithContent(baseDir);

View File

@ -18,10 +18,14 @@
#pragma once
#include "RiaRegressionTest.h"
#include <QFileInfo>
#include <QSize>
#include <QStringList>
class QDir;
class RiaRegressionTest;
//==================================================================================================
//
@ -35,21 +39,35 @@ public:
void executeRegressionTests();
bool isRunningRegressionTests() const;
bool useOpenMPForGeometryCreation() const;
static void updateRegressionTest(const QString& testRootPath);
static void regressionTestConfigureProject();
private:
RiaRegressionTestRunner();
void runRegressionTest(const QString& testRootPath, const QStringList& testFilter);
void runRegressionTest();
static void removeDirectoryWithContent(QDir& dirToDelete);
static void regressionTestConfigureProject();
static void resizeMaximizedPlotWindows();
static QSize regressionDefaultImageSize();
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:
const QString m_rootPath;
const QStringList m_testFilter;
QString m_rootPath;
QStringList m_testFilter;
bool m_runningRegressionTests;
RiaRegressionTest m_regressionTestSettings;
};

View File

@ -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;
}

View File

@ -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;
}
};

View File

@ -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);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -91,7 +99,7 @@ bool RiaStdStringTools::startsWithAlphabetic(const std::string& s)
{
if (s.empty()) return false;
return isalpha(s[0]);
return isalpha(s[0]) != 0;
}
//--------------------------------------------------------------------------------------------------

View File

@ -33,6 +33,7 @@ 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);

View File

@ -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;

View File

@ -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:

View File

@ -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);
}
}

View File

@ -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);

View File

@ -39,3 +39,20 @@ bool RiaTextStringTools::compare(const QString& expected, const QString& actual)
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;
}

View File

@ -25,5 +25,6 @@ class QString;
//--------------------------------------------------------------------------------------------------
namespace RiaTextStringTools
{
bool compare(const QString& expected, const QString& actual);
bool compare(const QString& expected, const QString& actual);
QString trimAndRemoveDoubleSpaces(const QString& s);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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"

View File

@ -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;
}

View File

@ -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);

View File

@ -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 )

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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();
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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();
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -0,0 +1,134 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RiaWellPlanCalculator.h"
#include "cvfGeometryTools.h"
#include "cvfMatrix4.h"
#include "RiaArcCurveCalculator.h"
#include "RiaOffshoreSphericalCoords.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaWellPlanCalculator::RiaWellPlanCalculator(const cvf::Vec3d& startTangent,
const std::vector<cvf::Vec3d>& lineArcEndPoints)
: m_startTangent(startTangent)
, m_lineArcEndPoints(lineArcEndPoints)
{
if (m_lineArcEndPoints.size() < 2) return ;
WellPlanSegment segment = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
RiaOffshoreSphericalCoords startAziIncRad(m_startTangent);
segment.inc = cvf::Math::toDegrees(startAziIncRad.inc());
segment.azi = cvf::Math::toDegrees(startAziIncRad.azi());
segment.TVD = -lineArcEndPoints[0].z();
segment.NS = lineArcEndPoints[0].y();
segment.EW = lineArcEndPoints[0].x();
m_wpResult.push_back(segment);
cvf::Vec3d p1 = m_lineArcEndPoints[0];
cvf::Vec3d p2 = m_lineArcEndPoints[1];
cvf::Vec3d t2 = m_startTangent;
for (size_t pIdx = 0; pIdx < m_lineArcEndPoints.size() - 1 ; ++pIdx)
{
addSegment(t2, m_lineArcEndPoints[pIdx], m_lineArcEndPoints[pIdx + 1] , &t2);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaWellPlanCalculator::addSegment(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)
{
addLineSegment(p1, p2, endTangent);
}
else // resample arc
{
addArcSegment(t1, p1, p2, endTangent);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaWellPlanCalculator::addLineSegment(cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent)
{
WellPlanSegment segment = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
cvf::Vec3d p1p2 = p2 - p1;
double length = p1p2.length();
segment.CL = length;
segment.MD = m_wpResult.back().MD + length;
cvf::Vec3d tangent = p1p2 / length;
RiaOffshoreSphericalCoords aziIncRad(p1p2);
segment.inc = cvf::Math::toDegrees(aziIncRad.inc());
segment.azi = cvf::Math::toDegrees(aziIncRad.azi());
segment.TVD = -p2.z();
segment.NS = p2.y();
segment.EW = p2.x();
segment.dogleg = 0.0;
segment.build = 0.0;
segment.turn = 0.0;
m_wpResult.push_back(segment);
*endTangent = tangent;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaWellPlanCalculator::addArcSegment(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent)
{
WellPlanSegment segment = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
RiaArcCurveCalculator arcCalc(p1, t1, p2);
segment.CL = arcCalc.arcLength();
segment.MD = m_wpResult.back().MD + segment.CL;
segment.inc = cvf::Math::toDegrees(arcCalc.endInclination());
segment.azi = cvf::Math::toDegrees(arcCalc.endAzimuth());
segment.TVD = -p2.z();
segment.NS = p2.y();
segment.EW = p2.x();
segment.dogleg = cvf::Math::toDegrees(30.0/arcCalc.radius());
RiaOffshoreSphericalCoords startAziIncRad(t1);
double buildInRadsPrLength = (arcCalc.endInclination() - startAziIncRad.inc())/arcCalc.arcLength();
double turnInRadsPrLength = (arcCalc.endAzimuth() - startAziIncRad.azi())/arcCalc.arcLength();
segment.build = 30*cvf::Math::toDegrees(buildInRadsPrLength) ;
segment.turn = 30*cvf::Math::toDegrees(turnInRadsPrLength) ;
m_wpResult.push_back(segment);
(*endTangent) = arcCalc.endTangent();
}

View File

@ -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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cvfBase.h"
#include "cvfVector3.h"
#include <vector>
class RiaWellPlanCalculator
{
public:
RiaWellPlanCalculator(const cvf::Vec3d& startTangent,
const std::vector<cvf::Vec3d>& lineArcEndPoints);
struct WellPlanSegment
{
double MD;
double CL;
double inc;
double azi;
double TVD;
double NS;
double EW;
double dogleg;
double build;
double turn;
};
const std::vector<WellPlanSegment>& wellPlan() const { return m_wpResult; }
private:
void addSegment(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent);
void addLineSegment(cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent);
void addArcSegment(cvf::Vec3d t1, cvf::Vec3d p1, cvf::Vec3d p2, cvf::Vec3d* endTangent);
cvf::Vec3d m_startTangent;
std::vector<cvf::Vec3d> m_lineArcEndPoints;
std::vector<WellPlanSegment> m_wpResult;
};

View File

@ -23,6 +23,8 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Adm
${CMAKE_CURRENT_SOURCE_DIR}/Application
${CMAKE_CURRENT_SOURCE_DIR}/Application/Tools
${CMAKE_CURRENT_SOURCE_DIR}/Application/Tools/WellPathTools
${CMAKE_CURRENT_SOURCE_DIR}/Commands
${CMAKE_CURRENT_SOURCE_DIR}/Commands/EclipseCommands
${CMAKE_CURRENT_SOURCE_DIR}/FileInterface
@ -77,7 +79,8 @@ list( APPEND CPP_SOURCES
list( APPEND REFERENCED_CMAKE_FILES
Application/CMakeLists_files.cmake
Application/Tools/CMakeLists_files.cmake
Application/Tools/CMakeLists_files.cmake
Application/Tools/WellPathTools/CMakeLists_files.cmake
ReservoirDataModel/CMakeLists_files.cmake
ReservoirDataModel/CMakeLists_filesNotToUnitTest.cmake
@ -107,6 +110,7 @@ list( APPEND REFERENCED_CMAKE_FILES
Commands/EclipseCommands/EclipseWell/CMakeLists_files.cmake
Commands/ExportCommands/CMakeLists_files.cmake
Commands/FlowCommands/CMakeLists_files.cmake
Commands/HoloLensCommands/CMakeLists_files.cmake
Commands/IntersectionBoxCommands/CMakeLists_files.cmake
Commands/IntersectionViewCommands/CMakeLists_files.cmake
Commands/OctaveScriptCommands/CMakeLists_files.cmake
@ -279,7 +283,20 @@ set( EXE_FILES
add_executable( ResInsight ${EXE_FILES} )
if (MSVC)
set_target_properties(ResInsight PROPERTIES COMPILE_FLAGS "/wd4190")
# The following warnings are supposed to be used in ResInsight, but temporarily disabled to avoid too much noise
# warning C4245: 'return': conversion from 'int' to 'size_t', signed/unsigned mismatch
# If possible, the following command is supposed to be the final target
# set_target_properties(ResInsight PROPERTIES COMPILE_FLAGS "/W4 /wd4190 /wd4100 /wd4127")
set_target_properties(ResInsight PROPERTIES COMPILE_FLAGS "/W4 /wd4190 /wd4100 /wd4127 /wd4245")
if (CMAKE_CXX_COMPILER_VERSION LESS_EQUAL 19.14)
# The following warning is generated over 800 times from a qwt header only using VS2015
# Disabling temporarily
# warning C4505 'function' : unreferenced local function has been removed
set_target_properties(ResInsight PROPERTIES COMPILE_FLAGS "/wd4505")
endif()
endif()
#############################################################################
@ -347,6 +364,9 @@ if(RESINSIGHT_ENABLE_COTIRE)
ReservoirDataModel/RigTransmissibilityCondenser.cpp
ReservoirDataModel/RigEclipseToStimPlanCellTransmissibilityCalculator.cpp
ReservoirDataModel/RigCellGeometryTools.cpp
# exclude file using SolveSpace
Application/Tools/RiaSCurveCalculator.cpp
# exclude test files due to cotire redefinition error report
UnitTests/RifCaseRealizationParametersReader-Test.cpp

View File

@ -20,6 +20,13 @@ ${CMAKE_CURRENT_LIST_DIR}/RicfSetStartDir.h
${CMAKE_CURRENT_LIST_DIR}/RicfSetTimeStep.h
${CMAKE_CURRENT_LIST_DIR}/RicfScaleFractureTemplate.h
${CMAKE_CURRENT_LIST_DIR}/RicfSetFractureContainment.h
${CMAKE_CURRENT_LIST_DIR}/RicfCreateMultipleFractures.h
${CMAKE_CURRENT_LIST_DIR}/RicfExportWellPaths.h
${CMAKE_CURRENT_LIST_DIR}/RicfExportVisibleCells.h
${CMAKE_CURRENT_LIST_DIR}/RicfExportPropertyInViews.h
${CMAKE_CURRENT_LIST_DIR}/RicfExportLgrForCompletions.h
${CMAKE_CURRENT_LIST_DIR}/RicfCreateLgrForCompletions.h
${CMAKE_CURRENT_LIST_DIR}/RicfApplicationTools.h
)
set (SOURCE_GROUP_SOURCE_FILES
@ -43,6 +50,13 @@ ${CMAKE_CURRENT_LIST_DIR}/RicfSetStartDir.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfSetTimeStep.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfScaleFractureTemplate.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfSetFractureContainment.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfCreateMultipleFractures.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfExportWellPaths.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfExportVisibleCells.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfExportPropertyInViews.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfExportLgrForCompletions.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfCreateLgrForCompletions.cpp
${CMAKE_CURRENT_LIST_DIR}/RicfApplicationTools.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -35,7 +35,7 @@ class RicfCommandObject : public caf::PdmObject, public RicfObjectCapability
{
public:
RicfCommandObject();
~RicfCommandObject();
~RicfCommandObject() override;
virtual void execute() = 0;
};

View File

@ -86,3 +86,47 @@ void RicfFieldWriter<QString>::writeFieldData(const QString& fieldValue, QTextSt
}
outputStream << "\"";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicfFieldReader<bool>::readFieldData(bool& fieldValue, QTextStream& inputStream, RicfMessages* errorMessageContainer)
{
errorMessageContainer->skipWhiteSpaceWithLineNumberCount(inputStream);
QString accumulatedFieldValue;
QChar nextChar;
QChar currentChar;
while (!inputStream.atEnd())
{
nextChar = errorMessageContainer->peekNextChar(inputStream);
if (nextChar.isLetter())
{
currentChar = errorMessageContainer->readCharWithLineNumberCount(inputStream);
accumulatedFieldValue += currentChar;
}
else
{
break;
}
}
// Accept TRUE or False in any case combination.
bool evaluatesToTrue = QString::compare(accumulatedFieldValue, QString("true"), Qt::CaseInsensitive) == 0;
bool evaluatesToFalse = QString::compare(accumulatedFieldValue, QString("false"), Qt::CaseInsensitive) == 0;
if (evaluatesToTrue == evaluatesToFalse)
{
QString formatString("Boolean argument \"%1\" for the command \"%2\" does not evaluate to either true or false");
QString errorMessage = formatString.arg(errorMessageContainer->currentArgument).arg(errorMessageContainer->currentCommand);
errorMessageContainer->addError(errorMessage);
}
fieldValue = evaluatesToTrue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicfFieldWriter<bool>::writeFieldData(const bool& fieldValue, QTextStream& outputStream)
{
// Lower-case true/false is used in the documentation.
outputStream << (fieldValue ? "true" : "false");
}

View File

@ -65,6 +65,19 @@ struct RicfFieldWriter<QString>
static void writeFieldData(const QString & fieldValue, QTextStream& outputStream);
};
template <>
struct RicfFieldReader<bool>
{
static void readFieldData(bool& fieldValue, QTextStream& inputStream, RicfMessages* errorMessageContainer);
};
template <>
struct RicfFieldWriter<bool>
{
static void writeFieldData(const bool& fieldValue, QTextStream& outputStream);
};
template <typename T>
struct RicfFieldReader< caf::AppEnum<T> >
{
@ -176,7 +189,7 @@ public:
// Xml Serializing
public:
virtual void readFieldData (QTextStream& inputStream, caf::PdmObjectFactory* objectFactory, RicfMessages* errorMessageContainer) override
void readFieldData (QTextStream& inputStream, caf::PdmObjectFactory* objectFactory, RicfMessages* errorMessageContainer) override
{
//m_field->xmlCapability()->assertValid();
typename FieldType::FieldDataType value;
@ -184,7 +197,7 @@ public:
m_field->setValue(value);
}
virtual void writeFieldData(QTextStream& outputStream) const override
void writeFieldData(QTextStream& outputStream) const override
{
//m_field->xmlCapability()->assertValid();
RicfFieldWriter<typename FieldType::FieldDataType>::writeFieldData(m_field->value(), outputStream);
@ -198,7 +211,7 @@ private:
template<typename FieldType>
void AddRicfCapabilityToField(FieldType* field)
{
if(field->template capability< RicfFieldCapability<FieldType> >() == NULL)
if(field->template capability< RicfFieldCapability<FieldType> >() == nullptr)
{
new RicfFieldCapability<FieldType>(field, true);
}

View File

@ -39,7 +39,7 @@ class RicfFieldHandle : public caf::PdmFieldCapability
public:
RicfFieldHandle(caf::PdmFieldHandle* owner , bool giveOwnership);
virtual ~RicfFieldHandle();
~RicfFieldHandle() override;
virtual void readFieldData (QTextStream& inputStream,
caf::PdmObjectFactory* objectFactory,

View File

@ -200,11 +200,12 @@ void RicfObjectCapability::writeFields(QTextStream& outputStream) const
if ( writtenFieldCount >= 1 )
{
outputStream << ", ";
++writtenFieldCount;
}
outputStream << keyword << " = ";
rcfField->writeFieldData(outputStream);
writtenFieldCount++;
}
}
}

View File

@ -38,7 +38,7 @@ class RicfObjectCapability : public caf::PdmObjectCapability
public:
RicfObjectCapability(caf::PdmObjectHandle* owner, bool giveOwnership);
virtual ~RicfObjectCapability();
~RicfObjectCapability() override;
void readFields(QTextStream& inputStream, caf::PdmObjectFactory* objectFactory, RicfMessages* errorMessageContainer);
void writeFields(QTextStream& outputStream) const;

View File

@ -40,7 +40,6 @@ std::vector<RicfCommandObject*> RicfCommandFileReader::readCommands(QTextStream&
errorMessageContainer->skipWhiteSpaceWithLineNumberCount(inputStream);
// Read command name
QString commandName;
bool foundStartBracet = false;
{
errorMessageContainer->skipWhiteSpaceWithLineNumberCount(inputStream);
while ( !inputStream.atEnd() )
@ -143,5 +142,16 @@ std::vector<RicfCommandObject*> RicfCommandFileReader::readCommands(QTextStream&
//--------------------------------------------------------------------------------------------------
void RicfCommandFileReader::writeCommands(QTextStream& outputStream, const std::vector<RicfCommandObject*>& commandsToWrite)
{
for (const auto& cmdObj : commandsToWrite)
{
auto rcfCap = cmdObj->capability<RicfObjectCapability>();
if (!rcfCap) continue;
outputStream << cmdObj->classKeyword();
outputStream << "(";
rcfCap->writeFields(outputStream);
outputStream << ")";
}
}

Some files were not shown because too many files have changed in this diff Show More