diff --git a/.clang-tidy b/.clang-tidy index e5ffe435bf..390f03e959 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,5 @@ --- -Checks: '-*,modernize-use-nullptr' +Checks: '-*,modernize-use-nullptr,modernize-use-override' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false ... diff --git a/ApplicationCode/Adm/LicenseInformation.txt b/ApplicationCode/Adm/LicenseInformation.txt index 94ff318884..a2b5cc53c5 100644 --- a/ApplicationCode/Adm/LicenseInformation.txt +++ b/ApplicationCode/Adm/LicenseInformation.txt @@ -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/. \ No newline at end of file diff --git a/ApplicationCode/Adm/projectfilekeywords/2018.05/ri-fieldKeywords.txt b/ApplicationCode/Adm/projectfilekeywords/2018.05/ri-fieldKeywords.txt new file mode 100644 index 0000000000..a58c876d23 --- /dev/null +++ b/ApplicationCode/Adm/projectfilekeywords/2018.05/ri-fieldKeywords.txt @@ -0,0 +1,1908 @@ +// ResInsight version string : 2018.05.0 +// Report generated : ti 22. mai 11:08:30 2018 +// +// + +AsciiDataCurve - class RimAsciiDataCurve + Show + CurveName + CurveDescription + AutoName + Color + Thickness + LineStyle + CurveInterpolation + PointSymbol + SymbolSkipPxDist + ShowLegend + PlotAxis + TimeSteps + Values + Title + +CalcScript - class RimCalcScript + AbsolutePath + Content + +CalculatedSummaryCase - class RimCalculatedSummaryCase + ShortName + AutoShortyName + SummaryHeaderFilename + +CellEdgeResultSlot - class RimCellEdgeColors + EnableCellEdgeColors + propertyType + CellEdgeVariable + UseXVariable + UseYVariable + UseZVariable + LegendDefinition + SingleVarEdgeResult + +CellFilter - class RimCellFilter + UserDescription + Active + FilterType + +CellPropertyFilter - class RimEclipsePropertyFilter + UserDescription + Active + FilterType + SelectedValues + EvaluationRegion + ResultDefinition + Dummy_keyword + LowerBound + UpperBound + CategorySelection + +CellPropertyFilters - class RimEclipsePropertyFilterCollection + Active + PropertyFilters + +CellRangeFilter - class RimCellRangeFilter + UserDescription + Active + FilterType + GridIndex + PropagateToSubGrids + StartIndexI + CellCountI + StartIndexJ + CellCountJ + StartIndexK + CellCountK + +CellRangeFilterCollection - class RimCellRangeFilterCollection + RangeFilters + Active + +ChangeDataSourceFeatureUi - class RicChangeDataSourceFeatureUi + CurveWellPath + CurveCase + +CmdAddItemExecData - class caf::CmdAddItemExecData + PathToField + indexAfter + createdItemIndex + +CmdDeleteItemExecData - class caf::CmdDeleteItemExecData + PathToField + indexToObject + deletedObjectAsXml + +CmdFieldChangeExecData - class caf::CmdFieldChangeExecData + PathToField + +CrossSection - class RimIntersection + UserDescription + Active + Type + Direction + WellPath + SimulationWell + Points + AzimuthAngle + DipAngle + CustomExtrusionPoints + TwoAzimuthPoints + Branch + ExtentLength + lengthUp + lengthDown + ShowInactiveCells + m_activateUiAppendPointsCommand + inputExtrusionPointsFromViewerEnabled + inputTwoAzimuthPointsFromViewerEnabled + +CrossSectionCollection - class RimIntersectionCollection + CrossSections + IntersectionBoxes + Active + +EclipseCase - class RimEclipseResultCase + CaseUserDescription + CaseId + DefaultFormationNames + TimeStepFilter + IntersectionViewCollection + ReservoirViews + MatrixModelResults + FractureModelResults + FlipXAxis + FlipYAxis + CachedFileNamesContainingFaults + FilesContainingFaults + CaseName + CaseFileName + FlowDiagSolutions + CaseFolder + SourSimFileName + +EclipseGeometrySelectionItem - class RimEclipseGeometrySelectionItem + EclipseCase + GridIndex + CellIndex + LocalIntersectionPoint + +Fault - class RimFaultInView + FaultName + ShowFault + Color + +Faults - class RimFaultInViewCollection + Active + ShowFaultFaces + ShowOppositeFaultFaces + ShowFaultsOutsideFilters + FaultFaceCulling + ShowFaultLabel + FaultLabelColor + ShowNNCs + HideNncsWhenNoResultIsAvailable + NoCommonAreaNnncCollection + Faults + +FileSummaryCase - class RimFileSummaryCase + ShortName + AutoShortyName + SummaryHeaderFilename + IncludeRestartFiles + +FishbonesCollection - class RimFishbonesCollection + Name + IsChecked + FishbonesSubs + WellPathCollection + StartMD + MainBoreDiameter + MainBoreSkinFactor + LinerDiameter + RoughnessFactor + PressureDrop + LengthAndDepth + +FishbonesMultipleSubs - class RimFishbonesMultipleSubs + Active + Name + Color + LateralCountPerSub + LateralLength + LateralExitAngle + LateralBuildAngle + LateralTubingDiameter + LateralOpenHoleRoghnessFactor + LateralTubingRoghnessFactor + LateralInstallSuccessFraction + IcdCount + IcdOrificeDiameter + IcdFlowCoefficient + LocationOfSubs + SubsLocationMode + RangeStart + RangeEnd + RangeSubSpacing + RangeSubCount + SubsOrientationMode + InstallationRotationAngles + FixedInstallationRotationAngle + PipeProperties + +FishbonesPipeProperties - class RimFishbonesPipeProperties + LateralHoleDiameter + SkinFactor + +FlowCharacteristicsPlot - class RimFlowCharacteristicsPlot + WindowController + ShowWindow + WindowGeometry + FlowCase + FlowDiagSolution + TimeSelectionType + SelectedTimeSteps + SelectedTimeStepsUi + ApplyTimeSteps + CellPVThreshold + ShowLegend + CellFilter + CellFilterView + TracerFilter + SelectedTracerNames + ShowRegion + MinCommunication + MaxTof + +FlowDiagSolution - class RimFlowDiagSolution + UserDescription + +FlowPlotCollection - class RimFlowPlotCollection + FlowCharacteristicsPlot + DefaultWellAllocationPlot + StoredWellAllocationPlots + StoredFlowCharacteristicsPlots + +FormationNames - class RimFormationNames + FormationNamesFileName + +FormationNamesCollectionObject - class RimFormationNamesCollection + FormationNamesList + +FractureContainment - class RimFractureContainment + IsUsingFractureContainment + TopKLayer + BaseKLayer + FaultTruncationType + +FractureDefinitionCollection - class RimFractureTemplateCollection + DefaultUnitForTemplates + FractureDefinitions + NextValidFractureTemplateId + +GeoMechGeometrySelectionItem - class RimGeoMechGeometrySelectionItem + GeoMechCase + m_gridIndex + m_cellIndex + m_elementFace + m_hasIntersectionTriangle + m_intersectionTriangle_0 + m_intersectionTriangle_1 + m_intersectionTriangle_2 + m_localIntersectionPoint + +GeoMechPropertyFilter - class RimGeoMechPropertyFilter + UserDescription + Active + FilterType + SelectedValues + ResultDefinition + LowerBound + UpperBound + +GeoMechPropertyFilters - class RimGeoMechPropertyFilterCollection + Active + PropertyFilters + +GeoMechResultDefinition - class RimGeoMechResultDefinition + ResultPositionType + ResultFieldName + ResultComponentName + IsTimeLapseResult + TimeLapseBaseTimeStep + CompactionRefLayer + ResultPositionTypeUi + ResultVariableUI + IsTimeLapseResultUI + TimeLapseBaseTimeStepUI + CompactionRefLayerUi + +GeoMechResultSlot - class RimGeoMechCellColors + ResultPositionType + ResultFieldName + ResultComponentName + IsTimeLapseResult + TimeLapseBaseTimeStep + CompactionRefLayer + ResultPositionTypeUi + ResultVariableUI + IsTimeLapseResultUI + TimeLapseBaseTimeStepUI + CompactionRefLayerUi + LegendDefinition + +GeoMechView - class RimGeoMechView + WindowController + ShowWindow + WindowGeometry + UserDescription + CameraPosition + CameraPointOfInterest + PerspectiveProjection + GridZScale + ViewBackgroundColor + MaximumFrameRate + AnimationMode + CurrentTimeStep + MeshMode + SurfaceMode + ShowGridBox + DisableLighting + RangeFilters + RangeFiltersControlled + CrossSections + GridCollection + OverlayInfoConfig + GridCellResult + TensorResults + PropertyFilters + +GridCollection - class RimGridCollection + IsActive + +GridSummaryCase - class RimGridSummaryCase + ShortName + AutoShortyName + SummaryHeaderFilename + Associated3DCase + CachedCasename + Associated3DCaseGridFileName + IncludeRestartFiles + +GridTimeHistoryCurve - class RimGridTimeHistoryCurve + Show + CurveName + CurveDescription + AutoName + Color + Thickness + LineStyle + CurveInterpolation + PointSymbol + SymbolSkipPxDist + ShowLegend + GeometrySelectionText + EclipseResultDefinition + GeoMechResultDefinition + GeometrySelectionItem + PlotAxis + +Intersection2dView - class Rim2dIntersectionView + WindowController + ShowWindow + WindowGeometry + UserDescription + CameraPosition + CameraPointOfInterest + PerspectiveProjection + GridZScale + ViewBackgroundColor + MaximumFrameRate + AnimationMode + CurrentTimeStep + MeshMode + SurfaceMode + ShowGridBox + DisableLighting + Intersection + LegendDefinition + TernaryLegendDefinition + ShowDefiningPoints + +Intersection2dViewCollection - class Rim2dIntersectionViewCollection + IntersectionViews + +IntersectionBox - class RimIntersectionBox + UserDescription + Active + singlePlaneState + MinXCoord + MaxXCoord + MinYCoord + MaxYCoord + MinDepth + MaxDepth + ShowInactiveCells + xySliderStepSize + DepthSliderStepSize + show3DManipulator + +Legend - class RimRegularLegendConfig + ShowLegend + NumberOfLevels + Precision + TickNumberFormat + ColorRangeMode + MappingMode + RangeType + UserDefinedMax + UserDefinedMin + ResultVariableUsage + +MainPlotCollection - class RimMainPlotCollection + Show + WellLogPlotCollection + RftPlotCollection + PltPlotCollection + SummaryPlotCollection + SummaryCrossPlotCollection + FlowPlotCollection + +MdiWindowController - class RimMdiWindowController + MainWindowID + xPos + yPos + Width + Height + IsMaximized + +MockModelSettings - class RimMockModelSettings + CellCountX + CellCountY + CellCountZ + TotalCellCount + ResultCount + TimeStepCount + +MultiSnapshotDefinition - class RimMultiSnapshotDefinition + IsActive + View + EclipseResultType + SelectedEclipseResults + TimeStepStart + TimeStepEnd + SnapShotDirection + RangeFilterStart + RangeFilterEnd + AdditionalCases + +NoCommonAreaNNC - class RimNoCommonAreaNNC + Name + +ObservedDataCollection - class RimObservedDataCollection + ObservedDataArray + +PdmDocument - class caf::PdmDocument + DocumentFileName + +PdmObjectCollection - class caf::PdmObjectCollection + PdmObjects + +PdmObjectGroup - class caf::PdmObjectGroup + +Perforation - class RimPerforationInterval + Name + IsChecked + StartMeasuredDepth + EndMeasuredDepth + Diameter + SkinFactor + StartOfHistory + StartDate + +PerforationCollection - class RimPerforationCollection + Name + IsChecked + Perforations + +PropertyFilter - class RimPropertyFilter + UserDescription + Active + FilterType + SelectedValues + +ResInsightAnalysisModels - class RimEclipseCaseCollection + Reservoirs + CaseGroups + +ResInsightGeoMechCase - class RimGeoMechCase + CaseUserDescription + CaseId + DefaultFormationNames + TimeStepFilter + IntersectionViewCollection + CaseFileName + GeoMechViews + CaseCohesion + FrctionAngleDeg + ElementPropertyFileNames + ElementPropertyFileNameIndexUiSelection + closeElementPropertyFileCommad + reloadElementPropertyFileCommand + +ResInsightGeoMechModels - class RimGeoMechModels + Cases + +ResInsightOilField - class RimOilField + AnalysisModels + GeoMechModels + WellPathCollection + FractureDefinitionCollection + SummaryCaseCollection + FormationNamesCollection + ObservedDataCollection + +ResInsightProject - class RimProject + DocumentFileName + ProjectFileVersionString + NextValidCaseId + NextValidCaseGroupId + OilFields + ScriptCollection + WellPathImport + MainPlotCollection + LinkedViews + CalculationCollection + CommandObjects + MultiSnapshotDefinitions + TreeViewState + TreeViewCurrentModelIndexPath + PlotWindowTreeViewState + PlotWindowTreeViewCurrentModelIndexPath + show3DWindow + showPlotWindow + DialogData + Reservoirs + CaseGroups + +ReservoirCellResultStorage - class RimReservoirCellResultsStorage + ResultCacheFileName + ResultCacheEntries + +ReservoirView - class RimEclipseView + WindowController + ShowWindow + WindowGeometry + UserDescription + CameraPosition + CameraPointOfInterest + PerspectiveProjection + GridZScale + ViewBackgroundColor + MaximumFrameRate + AnimationMode + CurrentTimeStep + MeshMode + SurfaceMode + ShowGridBox + DisableLighting + RangeFilters + RangeFiltersControlled + CrossSections + GridCollection + OverlayInfoConfig + GridCellResult + GridCellEdgeResult + FaultResultSettings + StimPlanColors + VirtualPerforationResult + WellCollection + FaultCollection + PropertyFilters + ShowMainGrid + ShowInactiveCells + ShowInvalidCells + +ResultDefinition - class RimEclipseResultDefinition + ResultType + PorosityModelType + ResultVariable + FlowDiagSolution + SelectedTracers + SelectedSouringTracers + FlowTracerSelectionMode + PhaseSelection + MResultType + MPorosityModelType + MResultVariable + MFlowDiagSolution + MSelectedTracers + MSelectedSouringTracers + SelectedTracersFilter + +ResultSlot - class RimEclipseCellColors + ResultType + PorosityModelType + ResultVariable + FlowDiagSolution + SelectedTracers + SelectedSouringTracers + FlowTracerSelectionMode + PhaseSelection + MResultType + MPorosityModelType + MResultVariable + MFlowDiagSolution + MSelectedTracers + MSelectedSouringTracers + SelectedTracersFilter + LegendDefinition + ResultVarLegendDefinitionList + TernaryLegendDefinition + LegendDefinitionPtrField + +ResultStorageEntryInfo - class RimReservoirCellResultsStorageEntryInfo + ResultType + ResultName + TimeSteps + DaysSinceSimulationStart + FilePositionDataStart + +RftAddress - class RimDataSourceForRftPlt + SourceType + EclipseCase + WellLogFile + +RiaPreferences - class RiaPreferences + navigationPolicy + scriptDirectory + scriptEditorExecutable + octaveExecutable + octaveShowHeaderInfoWhenExecutingScripts + ssihubAddress + defaultGridLines + defaultGridLineColors + defaultFaultGridLineColors + defaultWellLableColor + defaultViewerBackgroundColor + defaultScaleFactorZ + fontSizeInScene + showLasCurveWithoutTvdWarning + useShaders + showHud + appendClassNameToUiText + appendFieldKeywordToToolTipText + showTestToolbar + includeFractureDebugInfoFile + showLegendBackground + lastUsedProjectFileName + autocomputeDepth + loadAndShowSoil + summaryRestartFilesShowImportDialog + summaryImportMode + gridImportMode + readerSettings + +RiaRegressionTest - class RiaRegressionTest + workingFolder + folderContainingDiffTool + regressionTestFolder + showInteractiveDiffImages + testFilter + +RicCaseAndFileExportSettingsUi - class RicCaseAndFileExportSettingsUi + Folder + CaseToApply + +RicCellRangeUi - class RicCellRangeUi + Case + GridIndex + StartIndexI + StartIndexJ + StartIndexK + CellCountI + CellCountJ + CellCountK + +RicDeleteItemExecData - class RicDeleteItemExecData + PathToField + indexToObject + deletedObjectAsXml + +RicExportCarfinUi - class RicExportCarfinUi + CellRange + ExportFileName + CaseToApply + CellCountI + CellCountJ + CellCountK + MaxWellCount + +RicExportCompletionDataSettingsUi - class RicExportCompletionDataSettingsUi + Folder + CaseToApply + FileSplit + compdatExport + TimeStepIndex + UseLateralNTG + IncludePerforations + IncludeFishbones + IncludeFractures + ExcludeMainBoreForFishbones + ReportCompletionTypesSeparately + +RicExportToLasFileObj - class RicExportToLasFileObj + tvdrkbOffset + +RicExportToLasFileResampleUi - class RicExportToLasFileResampleUi + ExportFolder + ActivateResample + ResampleInterval + ExportTvdrkb + tvdrkbOffsets + +RicLinkVisibleViewsFeatureUi - class RicLinkVisibleViewsFeatureUi + MasterView + +RicPasteAsciiDataToSummaryPlotFeatureUi - class RicPasteAsciiDataToSummaryPlotFeatureUi + PlotTitle + CurvePrefix + DecimalSeparator + DateFormat + TimeFormat + UseCustomDateFormat + CustomDateTimeFormat + LineStyle + Symbol + SymbolSkipDinstance + CellSeparator + TimeColumnName + PreviewText + +RicSaveEclipseInputVisibleCellsUi - class RicSaveEclipseInputVisibleCellsUi + ExportFilename + ExportKeyword + VisibleActiveCellsValue + HiddenActiveCellsValue + InactiveCellsValue + +RicSelectSummaryPlotUI - class RicSelectSummaryPlotUI + SelectedSummaryPlot + CreateNewPlot + NewViewName + +RicSelectViewUI - class RicSelectViewUI + MasterView + CreateNewView + NewViewName + +RicSummaryAddressSelection - class RiuSummaryCurveDefSelection + SummaryCases + CurrentSummaryCategory + SelectedSummaryCategories + FieldVectors + Aquifers + AquiferVectors + NetworkVectors + MiscVectors + Regions + RegionsVectors + Region2RegionRegions + Region2RegionVectors + WellGroupWellGroupNames + WellGroupVectors + WellWellName + WellVectors + WellCompletionWellName + WellCompletionIjk + WellCompletionVectors + WellCompletionLgrLgrName + WellCompletionLgrWellName + WellCompletionLgrIjk + WellCompletionLgrVectors + WellLgrLgrName + WellLgrWellName + WellLgrVectors + WellSegmentWellName + WellSegmentNumber + WellSegmentVectors + BlockIjk + BlockVectors + BlockLgrLgrName + BlockLgrIjk + BlockLgrVectors + CalculatedVectors + ImportedVectors + +RicSummaryCurveCalculator - class RicSummaryCurveCalculator + CurrentCalculation + NewCalculation + DeleteCalculation + +RicSummaryCurveCreator - class RicSummaryCurveCreator + TargetPlot + UseAutoAppearanceAssignment + AppearanceApplyButton + CaseAppearanceType + VariableAppearanceType + WellAppearanceType + GroupAppearanceType + RegionAppearanceType + UseAutoPlotTitle + ApplySelection + Close + OK + SummaryCurveNameConfig + +RicWellPathsUnitSystemSettingsUi - class RicWellPathsUnitSystemSettingsUi + UnitSystem + +RifReaderSettings - class RifReaderSettings + importFaults + importSimulationNNCs + importAdvancedMswData + useResultIndexFile + skipWellData + faultIncludeFileAbsolutePathPrefix + +Rim3dWellLogCurveCollection - class Rim3dWellLogCurveCollection + Show3dWellLogCurves + PlaneWidthScaling + Show3dWellLogGrid + Show3dWellLogBackground + ArrayOf3dWellLogCurves + +Rim3dWellLogExtractionCurve - class Rim3dWellLogExtractionCurve + Show3dWellLogCurve + MinCurveValue + MaxCurveValue + DrawPlane + CurveColor + CurveCase + CurveTimeStep + CurveEclipseResult + CurveGeomechResult + NameConfig + +Rim3dWellLogFileCurve - class Rim3dWellLogFileCurve + Show3dWellLogCurve + MinCurveValue + MaxCurveValue + DrawPlane + CurveColor + CurveWellLogChannel + WellLogFile + NameConfig + +Rim3dWellLogRftCurve - class Rim3dWellLogRftCurve + Show3dWellLogCurve + MinCurveValue + MaxCurveValue + DrawPlane + CurveColor + eclipseResultCase + timeStep + wellLogChannelName + my2dWellLogRftCurve + NameConfig + +RimBinaryExportSettings - class RimBinaryExportSettings + Filename + EclipseKeyword + UndefinedValue + +RimCaseCollection - class RimCaseCollection + Reservoirs + +RimCommandExecuteScript - class RimCommandExecuteScript + Name + ScriptText + IsEnabled + Execute + +RimCommandIssueFieldChanged - class RimCommandIssueFieldChanged + CommandName + ObjectName + FieldName + FieldValueToApply + +RimCommandObject - class RimCommandObject + +RimCsvUserData - class RimCsvUserData + ShortName + AutoShortyName + SummaryHeaderFilename + ImportedSummaryData + UseCustomIdentifier + SummaryType + IdentifierName + ParseOptions + +RimCurveNameConfig - class RimCurveNameConfig + IsUsingAutoName + CustomCurveName + AutoCurveName + +RimDialogData - class RimDialogData + ExportCarfin + ExportCompletionData + +RimEllipseFractureTemplate - class RimEllipseFractureTemplate + Id + UserDescription + NameAndUnit + UnitSystem + Orientation + AzimuthAngle + SkinFactor + PerforationLength + PerforationEfficiency + WellDiameter + ConductivityType + FractureContainmentField + NonDarcyFlowType + UserDefinedDFactor + FractureWidthType + FractureWidth + InertialCoefficient + PermeabilityType + RelativePermeability + EffectivePermeability + RelativeGasDensity + GasViscosity + dFactorDisplayField + dFactorSummaryText + HeightScaleFactor + WidthScaleFactor + DFactorScaleFactor + ConductivityFactor + ScaleApplyButton + HalfLength + Height + Width + Permeability + +RimEnsembleCurveSet - class RimEnsembleCurveSet + EnsembleCurveSet + IsActive + SummaryGroup + SelectedVariableDisplayVar + VarListFilter + FilterResultSelection + SummaryAddress + SelectAddress + ColorMode + Color + EnsembleParameter + PlotAxis + LegendConfig + UserDefinedName + AutoGeneratedName + AutoName + SummaryAddressNameTools + +RimEnsembleCurveSetCollection - class RimEnsembleCurveSetCollection + EnsembleCurveSets + IsActive + +RimExportInputSettings - class RimExportInputSettings + Filename + Keyword + +RimFaultResultSlot - class RimEclipseFaultColors + ShowCustomFaultResult + CustomResultSlot + +RimFractureExportSettings - class RimFractureExportSettings + Filename + CaseToApply + +RimIdenticalGridCaseGroup - class RimIdenticalGridCaseGroup + UserDescription + GroupId + StatisticsCaseCollection + CaseCollection + +RimInputProperty - class RimEclipseInputProperty + ResultName + EclipseKeyword + FileName + ResolvedState + +RimInputPropertyCollection - class RimEclipseInputPropertyCollection + InputProperties + +RimInputReservoir - class RimEclipseInputCase + CaseUserDescription + CaseId + DefaultFormationNames + TimeStepFilter + IntersectionViewCollection + ReservoirViews + MatrixModelResults + FractureModelResults + FlipXAxis + FlipYAxis + CachedFileNamesContainingFaults + FilesContainingFaults + CaseName + GridFileName + InputPropertyCollection + AdditionalFileNamesProxy + AdditionalFileNames + +RimNoCommonAreaNncCollection - class RimNoCommonAreaNncCollection + UserDescription + NoCommonAreaNncs + +RimObservedEclipseUserData - class RimObservedEclipseUserData + ShortName + AutoShortyName + SummaryHeaderFilename + ImportedSummaryData + UseCustomIdentifier + SummaryType + IdentifierName + +RimOilFieldEntry - class RimOilFieldEntry + OilFieldName + EdmId + Selected + wellsFilePath + Wells + +RimOilRegionEntry - class RimOilRegionEntry + OilRegionEntry + Fields + Selected + +RimStatisticalCalculation - class RimEclipseStatisticsCase + CaseUserDescription + CaseId + DefaultFormationNames + TimeStepFilter + IntersectionViewCollection + ReservoirViews + MatrixModelResults + FractureModelResults + FlipXAxis + FlipYAxis + CachedFileNamesContainingFaults + FilesContainingFaults + CaseName + m_editingAllowed + SelectionSummary + ResultType + PorosityModel + DynamicPropertiesToCalculate + StaticPropertiesToCalculate + GeneratedPropertiesToCalculate + InputPropertiesToCalculate + FractureDynamicPropertiesToCalculate + FractureStaticPropertiesToCalculate + FractureGeneratedPropertiesToCalculate + FractureInputPropertiesToCalculate + CalculatePercentiles + PercentileCalculationType + LowPercentile + MidPercentile + HighPercentile + WellDataSourceCase + UseZeroAsInactiveCellValue + +RimStatisticalCollection - class RimEclipseStatisticsCaseCollection + Reservoirs + +RimStimPlanColors - class RimStimPlanColors + IsChecked + ResultName + DefaultColor + LegendConfigurations + ShowStimPlanMesh + StimPlanCellVizMode + +RimStimPlanFractureTemplate - class RimStimPlanFractureTemplate + Id + UserDescription + NameAndUnit + UnitSystem + Orientation + AzimuthAngle + SkinFactor + PerforationLength + PerforationEfficiency + WellDiameter + ConductivityType + FractureContainmentField + NonDarcyFlowType + UserDefinedDFactor + FractureWidthType + FractureWidth + InertialCoefficient + PermeabilityType + RelativePermeability + EffectivePermeability + RelativeGasDensity + GasViscosity + dFactorDisplayField + dFactorSummaryText + HeightScaleFactor + WidthScaleFactor + DFactorScaleFactor + ConductivityFactor + ScaleApplyButton + StimPlanFileName + WellPathDepthAtFracture + BorderPolygonResultName + ActiveTimeStepIndex + ConductivityResultName + ShowStimPlanMesh + +RimStimPlanLegendConfig - class RimStimPlanLegendConfig + Name + Legend + +RimSummaryCalculation - class RimSummaryCalculation + Description + Expression + Unit + Variables + CalculatedValues + TimeSteps + +RimSummaryCalculationCollection - class RimSummaryCalculationCollection + Calculations + CalculationsSummaryCase + +RimSummaryCalculationVariable - class RimSummaryCalculationVariable + VariableName + PushButton + SummaryAddressUi + SummaryCase + SummaryAddress + +RimSummaryCurveCollection - class RimSummaryCurveCollection + CollectionCurves + IsActive + YSourceStepping + XSourceStepping + UnionSourceStepping + +RimSummaryCurveCollectionModifier - class RimSummaryPlotSourceStepping + CurveCase + WellName + GroupName + Region + Quantities + Placeholder + +RimTensorResults - class RimTensorResults + LegendDefinition + ResultVariable + ResultVariableUI + ShowTensors + Principal1 + Principal2 + Principal3 + Threshold + VectorColor + ScaleMethod + SizeScale + RangeType + +RimTernaryLegendConfig - class RimTernaryLegendConfig + ShowTernaryLegend + Precision + RangeType + m_applyLocalMinMax + m_applyGlobalMinMax + m_applyFullRangeMinMax + ternaryRangeSummary + UserDefinedMaxSoil + UserDefinedMinSoil + UserDefinedMaxSgas + UserDefinedMinSgas + UserDefinedMaxSwat + UserDefinedMinSwat + +RimTimeStepFilter - class RimTimeStepFilter + TimeStepIndicesToImport + FirstTimeStep + LastTimeStep + FilterType + Interval + FilteredTimeSteps + ApplyReloadOfCase + +RimViewLinkerCollection - class RimViewLinkerCollection + Active + ViewLinkers + +RimVirtualPerforationResults - class RimVirtualPerforationResults + ShowConnectionFactors + ShowClosedConnections + GeometryScaleFactor + LegendDefinition + +RimWellLogExtractionCurve - class RimWellLogExtractionCurve + Show + CurveName + CurveDescription + AutoName + Color + Thickness + LineStyle + CurveInterpolation + PointSymbol + SymbolSkipPxDist + ShowLegend + TrajectoryType + CurveWellPath + SimulationWellName + BranchDetection + Branch + CurveCase + CurveEclipseResult + CurveGeomechResult + CurveTimeStep + AddCaseNameToCurveName + AddPropertyToCurveName + AddWellNameToCurveName + AddTimestepToCurveName + AddDateToCurveName + +RimWellLogExtractionCurveNameConfig - class RimWellLogExtractionCurveNameConfig + IsUsingAutoName + CustomCurveName + AutoCurveName + AddCaseName + AddProperty + AddWellName + AddTimeStep + AddDate + +RimWellLogFileCurveNameConfig - class RimWellLogFileCurveNameConfig + IsUsingAutoName + CustomCurveName + AutoCurveName + +RimWellLogRftCurveNameConfig - class RimWellLogRftCurveNameConfig + IsUsingAutoName + CustomCurveName + AutoCurveName + +RimWellPathEntry - class RimWellPathEntry + Name + Selected + WellPathType + surveyType + requestUrl + wellPathFilePath + +RimWellPathImport - class RimWellPathImport + WellTypeSurvey + WellTypePlans + UtmMode + UtmNorth + UtmSouth + UtmEast + UtmWest + Regions + +ScriptLocation - class RimScriptCollection + ScriptDirectory + CalcScripts + SubDirectories + +SimWellFracture - class RimSimWellFracture + Name + IsChecked + FractureDef + AnchorPosition + ui_positionAtWellpath + Azimuth + PerforationLength + PerforationEfficiency + WellDiameter + Dip + Tilt + FractureUnit + TimeIndexToPlot + WellPathAzimuth + WellFractureAzimuthDiff + WellFractureAzimithAngleWarning + MeasuredDepth + Cell_IJK + Branch + +SimWellFractureCollection - class RimSimWellFractureCollection + Fractures + +SummaryAddress - class RimSummaryAddress + SummaryVarType + SummaryQuantityName + SummaryRegion + SummaryRegion2 + SummaryWellGroup + SummaryWell + SummaryWellSegment + SummaryLgr + SummaryCellI + SummaryCellJ + SummaryCellK + SummaryAquifer + +SummaryCaseCollection - class RimSummaryCaseMainCollection + SummaryCases + SummaryCaseCollections + +SummaryCaseSubCollection - class RimSummaryCaseCollection + SummaryCases + SummaryCollectionName + NameCount + IsEnsemble + +SummaryCrossPlot - class RimSummaryCrossPlot + WindowController + ShowWindow + WindowGeometry + PlotDescription + ShowPlotTitle + ShowLegend + LegendFontSize + IsUsingAutoName + SummaryCurveFilters + SummaryCurveCollection + EnsembleCurveSetCollection + SummaryCurves + GridTimeHistoryCurves + AsciiDataCurves + LeftYAxisProperties + RightYAxisProperties + BottomAxisProperties + TimeAxisProperties + AutoZoom + +SummaryCrossPlotCollection - class RimSummaryCrossPlotCollection + SummaryCrossPlots + +SummaryCurve - class RimSummaryCurve + Show + CurveName + CurveDescription + AutoName + Color + Thickness + LineStyle + CurveInterpolation + PointSymbol + SymbolSkipPxDist + ShowLegend + SummaryCase + SelectedVariableDisplayVar + VarListFilter + FilterResultSelection + SummaryAddress + SelectAddress + SummaryCaseX + SelectedVariableDisplayVarX + VarListFilterX + FilterResultSelectionX + SummaryAddressX + SelectAddressX + PlotAxis + SummaryCurveNameConfig + +SummaryCurveAutoName - class RimSummaryCurveAutoName + VectorName + Unit + RegionNumber + WellGroupName + WellName + WellSegmentNumber + LgrName + Completion + Aquifer + CaseName + +SummaryCurveFilter - class RimSummaryCurveFilter_OBSOLETE + SummaryCases + VarListFilter + FilterResultSelection + FilteredCurves + ApplySelection + AutoApplyFilterChanges + IsActive + UseAutoAppearanceAssignment + CaseAppearanceType + VariableAppearanceType + WellAppearanceType + GroupAppearanceType + RegionAppearanceType + PlotAxis + ShowLegend + SummaryCurveNameConfig + +SummaryFilterSettings - class RimSummaryFilter + SummaryFilterType + SummaryCompleteVarStringFilter + SummaryVarQuantityFilter + SummaryRegionNumberFilter + SummaryRegionNumber2Filter + SummaryWellGroupNameFilter + SummaryWellNameFilter + SummaryWellSegmentNumberFilter + SummaryLgrNameFilter + SummaryCellIJKFilter + +SummaryObservedDataFile - class RimSummaryObservedDataFile + ShortName + AutoShortyName + SummaryHeaderFilename + ImportedSummaryData + UseCustomIdentifier + SummaryType + IdentifierName + +SummaryPageDownloadEntity - class SummaryPageDownloadEntity + Name + RequestUrl + ResponseFilename + +SummaryPlot - class RimSummaryPlot + WindowController + ShowWindow + WindowGeometry + PlotDescription + ShowPlotTitle + ShowLegend + LegendFontSize + IsUsingAutoName + SummaryCurveFilters + SummaryCurveCollection + EnsembleCurveSetCollection + SummaryCurves + GridTimeHistoryCurves + AsciiDataCurves + LeftYAxisProperties + RightYAxisProperties + BottomAxisProperties + TimeAxisProperties + AutoZoom + +SummaryPlotCollection - class RimSummaryPlotCollection + SummaryPlots + +SummaryTimeAxisProperties - class RimSummaryTimeAxisProperties + Active + ShowTitle + Title + TitlePosition + FontSize + ValuesFontSize + AutoZoom + TimeMode + TimeUnit + VisibleRangeMax + VisibleRangeMin + VisibleTimeModeRangeMax + VisibleTimeModeRangeMin + +SummaryYAxisProperties - class RimSummaryAxisProperties + Active + Name + AutoTitle + DisplayLongName + DisplayShortName + DisplayUnitText + CustomTitle + TitlePosition + FontSize + VisibleRangeMax + VisibleRangeMin + NumberFormat + Decimals + ScaleFactor + ValuesFontSize + AutoZoom + LogarithmicScale + +TC2 - class TC2 + ta + da + ia + +TestCommand1 - class TestCommand1 + TextArgument + DoubleArgument + IntArgument + +TofAccumulatedPhaseFractionsPlot - class RimTofAccumulatedPhaseFractionsPlot + WindowController + ShowWindow + WindowGeometry + PlotDescription + ShowPlotTitle + MaxTof + +TotalWellAllocationPlot - class RimTotalWellAllocationPlot + WindowController + ShowWindow + WindowGeometry + PlotDescription + ShowPlotTitle + +View3dOverlayInfoConfig - class Rim3dOverlayInfoConfig + Active + ShowAnimProgress + ShowInfoText + ShowResultInfo + ShowHistogram + ShowVolumeWeightedMean + StatisticsTimeRange + StatisticsCellRange + +ViewController - class RimViewController + Active + Name + ManagedView + SyncCamera + ShowCursor + SyncTimeStep + SyncCellResult + SyncLegendDefinitions + SyncVisibleCells + SyncRangeFilters + SyncPropertyFilters + +ViewLinker - class RimViewLinker + Name + MainView + ManagedViews + +Well - class RimSimWellInView + WellName + ShowWell + ShowWellLabel + ShowWellHead + ShowWellPipe + ShowWellSpheres + WellHeadScaleFactor + WellPipeRadiusScale + WellPipeColor + ShowWellCells + ShowWellCellFence + FractureCollection + +WellAllocationPlot - class RimWellAllocationPlot + WindowController + ShowWindow + WindowGeometry + PlotDescription + ShowPlotTitle + BranchDetection + CurveCase + PlotTimeStep + WellName + FlowDiagSolution + FlowType + GroupSmallContributions + SmallContributionsThreshold + AccumulatedWellFlowPlot + TotalWellFlowPlot + WellAllocLegend + TofAccumulatedPhaseFractionsPlot + +WellAllocationPlotLegend - class RimWellAllocationPlotLegend + ShowPlotLegend + +WellFlowRateCurve - class RimWellFlowRateCurve + Show + CurveName + CurveDescription + AutoName + Color + Thickness + LineStyle + CurveInterpolation + PointSymbol + SymbolSkipPxDist + ShowLegend + +WellLogFile - class RimWellLogFile + WellName + Date + FileName + Name + WellLogFileChannels + WellFlowCondition + InvalidDateMessage + +WellLogFileChannel - class RimWellLogFileChannel + Name + +WellLogFileCurve - class RimWellLogFileCurve + Show + CurveName + CurveDescription + AutoName + Color + Thickness + LineStyle + CurveInterpolation + PointSymbol + SymbolSkipPxDist + ShowLegend + CurveWellPath + CurveWellLogChannel + WellLogFile + +WellLogPlot - class RimWellLogPlot + WindowController + ShowWindow + WindowGeometry + PlotDescription + DepthType + DepthUnit + MinimumDepth + MaximumDepth + AutoScaleDepthEnabled + ShowTrackLegends + Tracks + +WellLogPlotCollection - class RimWellLogPlotCollection + WellLogPlots + +WellLogPlotTrack - class RimWellLogTrack + TrackDescription + Show + Curves + VisibleXRangeMin + VisibleXRangeMax + AutoScaleX + LogarithmicScaleX + ShowFormations + FormationSource + FormationTrajectoryType + FormationWellPath + FormationWellPathForSourceWellPath + FormationSimulationWellName + FormationBranchIndex + FormationBranchDetection + FormationCase + FormationLevel + ShowFormationFluids + +WellLogRftCurve - class RimWellLogRftCurve + Show + CurveName + CurveDescription + AutoName + Color + Thickness + LineStyle + CurveInterpolation + PointSymbol + SymbolSkipPxDist + ShowLegend + CurveEclipseResultCase + TimeStep + WellName + BranchIndex + BranchDetection + WellLogChannelName + +WellPath - class RimWellPath + WellPathName + WellPathId + SourceSystem + UTMZone + WellPathUpdateDate + WellPathUpdateUser + WellPathSurveyType + DatumElevation + UnitSystem + WellPathFilepath + WellPathNumberInFile + SimWellName + SimBranchIndex + ShowWellPathLabel + ShowWellPath + WellPathRadiusScale + WellPathColor + Completions + WellLogFiles + CollectionOf3dWellLogCurves + WellPathFormationKeyInFile + WellPathFormationFilePath + WellLogFile + +WellPathCompletion - class RimFishboneWellPath + Name + IsChecked + Coordinates + MeasuredDepth + DisplayCoordinates + +WellPathCompletionCollection - class RimFishboneWellPathCollection + Name + IsChecked + WellPaths + PipeProperties + +WellPathCompletions - class RimWellPathCompletions + Perforations + Fishbones + Fractures + WellNameForExport + +WellPathFracture - class RimWellPathFracture + Name + IsChecked + FractureDef + AnchorPosition + ui_positionAtWellpath + Azimuth + PerforationLength + PerforationEfficiency + WellDiameter + Dip + Tilt + FractureUnit + TimeIndexToPlot + WellPathAzimuth + WellFractureAzimuthDiff + WellFractureAzimithAngleWarning + MeasuredDepth + +WellPathFractureCollection - class RimWellPathFractureCollection + Name + IsChecked + Fractures + +WellPaths - class RimWellPathCollection + Active + ShowWellPathLabel + WellPathLabelColor + GlobalWellPathVisibility + WellPathRadiusScale + WellPathVertexCount + WellPathClip + WellPathClipZDistance + WellPaths + +WellPltPlot - class RimWellPltPlot + WindowController + ShowWindow + WindowGeometry + PlotDescription + ShowPlotTitle + WellLog + WellName + SourcesInternal + Sources + TimeSteps + UseStandardConditionCurves + UseReservoirConditionCurves + Phases + +WellPltPlotCollection - class RimPltPlotCollection + PltPlots + +WellRftPlot - class RimWellRftPlot + WindowController + ShowWindow + WindowGeometry + PlotDescription + ShowPlotTitle + WellLog + WellName + BranchIndex + BranchDetection + Sources + TimeSteps + +WellRftPlotCollection - class RimRftPlotCollection + RftPlots + +Wells - class RimSimWellInViewCollection + Active + ShowWellsIntersectingVisibleCells + ShowWellHeadTristate + ShowWellLabelTristate + ShowWellPipe + ShowWellSpheres + WellHeadScale + WellPipeRadiusScale + CellCenterSphereScale + WellLabelColor + ShowConnectionStatusColors + WellColorForApply + ApplySingleColorToWells + ApplyIndividualColorsToWells + WellPipeVertexCount + WellPipeCoordType + ShowWellCellsTristate + DefaultWellFenceDirection + WellCellTransparency + IsAutoDetectingBranches + WellHeadPosition + Wells + ShowWellCellFenceTristate + GlobalWellPipeVisibility + GlobalWellCellVisibility + ShowWellHead + ShowWellLabel + ShowWellFences + ShowWellCommunicationLines + +closeProject - class RicfCloseProject + +computeCaseGroupStatistics - class RicfComputeCaseGroupStatistics + caseIds + +exportMsw - class RicfExportMsw + caseId + wellPath + +exportMultiCaseSnapshots - class RicfExportMultiCaseSnapshots + gridListFile + +exportProperty - class RicfExportProperty + caseId + timeStep + property + type + eclipseKeyword + undefinedValue + exportFile + +exportSimWellFractureCompletions - class RicfExportSimWellFractureCompletions + caseId + viewName + timeStep + simulationWellNames + fileSplit + compdatExport + +exportSnapshots - class RicfExportSnapshots + type + +exportWellPathCompletions - class RicfExportWellPathCompletions + caseId + timeStep + wellPathNames + fileSplit + compdatExport + combinationMode + useNtgHorizontally + includePerforations + includeFishbones + includeFractures + excludeMainBoreForFishbones + +loadCase - class RicfLoadCase + path + +openProject - class RicfOpenProject + path + +replaceCase - class RicfSingleCaseReplace + caseId + newGridFile + +replaceCaseImpl_no_support_for_command_file_text_parsing - class RicfMultiCaseReplace + +replaceSourceCases - class RicfReplaceSourceCases + caseGroupId + gridListFile + +runOctaveScript - class RicfRunOctaveScript + path + caseIds + +scaleFractureTemplate - class RicfScaleFractureTemplate + id + width + height + dFactor + conductivity + +setExportFolder - class RicfSetExportFolder + type + path + +setFractureContainment - class RicfSetFractureContainment + id + topLayer + baseLayer + +setMainWindowSize - class RicfSetMainWindowSize + height + width + +setStartDir - class RicfSetStartDir + path + +setTimeStep - class RicfSetTimeStep + caseId + timeStep + diff --git a/ApplicationCode/Adm/projectfilekeywords/2018.05/ri-objectKeywords.txt b/ApplicationCode/Adm/projectfilekeywords/2018.05/ri-objectKeywords.txt new file mode 100644 index 0000000000..8458ec8f7b --- /dev/null +++ b/ApplicationCode/Adm/projectfilekeywords/2018.05/ri-objectKeywords.txt @@ -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 diff --git a/ApplicationCode/Adm/sourceCodeMaintenance/2018-18-10-delete-unused_functions.txt b/ApplicationCode/Adm/sourceCodeMaintenance/2018-18-10-delete-unused_functions.txt new file mode 100644 index 0000000000..d7329e35cb --- /dev/null +++ b/ApplicationCode/Adm/sourceCodeMaintenance/2018-18-10-delete-unused_functions.txt @@ -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 +------- diff --git a/ApplicationCode/Application/CMakeLists_files.cmake b/ApplicationCode/Application/CMakeLists_files.cmake index 6e0a95b270..e22ea375b9 100644 --- a/ApplicationCode/Application/CMakeLists_files.cmake +++ b/ApplicationCode/Application/CMakeLists_files.cmake @@ -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 diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index 4a932fb6ca..0b9e87aef1 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -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 #include #include +#include #include @@ -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::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; + } } } diff --git a/ApplicationCode/Application/RiaApplication.h b/ApplicationCode/Application/RiaApplication.h index 0d538520c8..4820c0dafc 100644 --- a/ApplicationCode/Application/RiaApplication.h +++ b/ApplicationCode/Application/RiaApplication.h @@ -92,7 +92,7 @@ class RiaApplication : public QApplication public: RiaApplication(int& argc, char** argv); - ~RiaApplication(); + ~RiaApplication() override; static RiaApplication* instance(); @@ -100,13 +100,13 @@ class RiaApplication : public QApplication 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 @@ class RiaApplication : public QApplication 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 @@ class RiaApplication : public QApplication 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 @@ class RiaApplication : public QApplication int launchUnitTests(); int launchUnitTestsWithConsole(); + RiuPlotMainWindow* getOrCreateMainPlotWindow(); RiuPlotMainWindow* getOrCreateAndShowMainPlotWindow(); RiuPlotMainWindow* mainPlotWindow(); RiuMainWindowBase* mainWindowByID(int mainWindowID); @@ -202,27 +202,30 @@ class RiaApplication : public QApplication void waitUntilCommandObjectsHasBeenProcessed(); void saveWinGeoAndDockToolBarLayout(); + static bool enableDevelopmentFeatures(); + static void clearAllSelections(); + private: - void onProjectOpenedOrClosed(); - void setWindowCaptionFromAppState(); + void onProjectOpenedOrClosed(); + void setWindowCaptionFromAppState(); - void createMainPlotWindow(); - void deleteMainPlotWindow(); + void createMainPlotWindow(); + void deleteMainPlotWindow(); - void loadAndUpdatePlotData(); + void loadAndUpdatePlotData(); - void storeTreeViewState(); + void storeTreeViewState(); 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 m_activeReservoirView; + caf::PdmPointer m_activeReservoirView; caf::PdmPointer m_project; RiaSocketServer* m_socketServer; diff --git a/ApplicationCode/Application/RiaCompletionTypeCalculationScheduler.cpp b/ApplicationCode/Application/RiaCompletionTypeCalculationScheduler.cpp index 95bdb29e3e..85399bcbbc 100644 --- a/ApplicationCode/Application/RiaCompletionTypeCalculationScheduler.cpp +++ b/ApplicationCode/Application/RiaCompletionTypeCalculationScheduler.cpp @@ -114,12 +114,15 @@ void RiaCompletionTypeCalculationScheduler::slotRecalculateCompletionType() for (RimEclipseCase* eclipseCase : uniqueCases) { - for (const auto& w : eclipseCase->views()) + if (eclipseCase) { - RimEclipseView* eclView = dynamic_cast(w); - if (eclView) + for (const auto& w : eclipseCase->views()) { - eclView->calculateCompletionTypeAndRedrawIfRequired(); + RimEclipseView* eclView = dynamic_cast(w); + if (eclView) + { + eclView->calculateCompletionTypeAndRedrawIfRequired(); + } } } } diff --git a/ApplicationCode/Application/RiaCompletionTypeCalculationScheduler.h b/ApplicationCode/Application/RiaCompletionTypeCalculationScheduler.h index 205f415f9f..1e9850eaec 100644 --- a/ApplicationCode/Application/RiaCompletionTypeCalculationScheduler.h +++ b/ApplicationCode/Application/RiaCompletionTypeCalculationScheduler.h @@ -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; diff --git a/ApplicationCode/Application/RiaCurveSetDefinition.cpp b/ApplicationCode/Application/RiaCurveSetDefinition.cpp new file mode 100644 index 0000000000..a8f5658e16 --- /dev/null +++ b/ApplicationCode/Application/RiaCurveSetDefinition.cpp @@ -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 +// 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()); +} diff --git a/ApplicationCode/Application/RiaCurveSetDefinition.h b/ApplicationCode/Application/RiaCurveSetDefinition.h new file mode 100644 index 0000000000..b1941ff8a6 --- /dev/null +++ b/ApplicationCode/Application/RiaCurveSetDefinition.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RifEclipseSummaryAddress.h" + +#include + +#include +#include + +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; +}; diff --git a/ApplicationCode/Application/RiaDefines.cpp b/ApplicationCode/Application/RiaDefines.cpp index 3d38462776..619fc20d9d 100644 --- a/ApplicationCode/Application/RiaDefines.cpp +++ b/ApplicationCode/Application/RiaDefines.cpp @@ -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 RiaDefines::wellPathAngleResultNames() +{ + return { RiaDefines::wellPathAzimuthResultName(), RiaDefines::wellPathInclinationResultName() }; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiaDefines::wellPathStabilityResultNames() +{ + return { RiaDefines::wellPathFGResultName(), RiaDefines::wellPathOBGResultName(), + RiaDefines::wellPathPPResultName(), RiaDefines::wellPathSFGResultName(), + RiaDefines::wellPathSHResultName() }; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaDefines.h b/ApplicationCode/Application/RiaDefines.h index c03ffdd0da..c8eb95b35a 100644 --- a/ApplicationCode/Application/RiaDefines.h +++ b/ApplicationCode/Application/RiaDefines.h @@ -21,6 +21,7 @@ #pragma once #include +#include 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 wellPathAngleResultNames(); + std::vector wellPathStabilityResultNames(); + //Units and conversions enum DepthUnitType { diff --git a/ApplicationCode/Application/RiaFractureDefines.cpp b/ApplicationCode/Application/RiaFractureDefines.cpp index 74f3b87d49..57054a44a5 100644 --- a/ApplicationCode/Application/RiaFractureDefines.cpp +++ b/ApplicationCode/Application/RiaFractureDefines.cpp @@ -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; } } diff --git a/ApplicationCode/Application/RiaFractureDefines.h b/ApplicationCode/Application/RiaFractureDefines.h index a87bbe5acf..238ae71c98 100644 --- a/ApplicationCode/Application/RiaFractureDefines.h +++ b/ApplicationCode/Application/RiaFractureDefines.h @@ -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 diff --git a/ApplicationCode/Application/RiaMain.cpp b/ApplicationCode/Application/RiaMain.cpp index 0332149550..c3e62d2fc4 100644 --- a/ApplicationCode/Application/RiaMain.cpp +++ b/ApplicationCode/Application/RiaMain.cpp @@ -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(); diff --git a/ApplicationCode/Application/RiaMemoryCleanup.cpp b/ApplicationCode/Application/RiaMemoryCleanup.cpp new file mode 100644 index 0000000000..15deb8b822 --- /dev/null +++ b/ApplicationCode/Application/RiaMemoryCleanup.cpp @@ -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 +// 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(m_case()); + RimGeoMechCase* geoMechCase = dynamic_cast(m_case()); + if (eclipseCase) + { + RigCaseCellResultsData* caseData = eclipseCase->results(RiaDefines::MATRIX_MODEL); + if (caseData) + { + std::vector 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 resultsToDelete = selectedGeoMechResults(); + for (RigFemResultAddress result : resultsToDelete) + { + resultsCollection->deleteResult(result); + } + } + } + } + m_resultsToDelete.v().clear(); + m_eclipseResultAddresses.clear(); + m_geomResultAddresses.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiaMemoryCleanup::selectedGeoMechResults() const +{ + std::vector results; + if (dynamic_cast(m_case())) + { + for (size_t index : m_resultsToDelete()) + { + CVF_ASSERT(index < m_geomResultAddresses.size()); + results.push_back(m_geomResultAddresses[index]); + } + } + return results; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiaMemoryCleanup::selectedEclipseResults() const +{ + std::vector results; + if (dynamic_cast(m_case())) + { + for (size_t index : m_resultsToDelete()) + { + CVF_ASSERT(index < m_eclipseResultAddresses.size()); + results.push_back(m_eclipseResultAddresses[index]); + } + } + return results; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RiaMemoryCleanup::findGeoMechCaseResultsInUse() const +{ + std::set resultsInUse; + RimGeoMechCase* geoMechCase = dynamic_cast(m_case()); + if (geoMechCase) + { + std::vector geoMechResults; + geoMechCase->descendantsIncludingThisOfType(geoMechResults); + for (RimFemResultObserver* resultDef : geoMechResults) + { + caf::PdmField* field = dynamic_cast*>(resultDef->objectToggleField()); + if (!field || (*field)()) + { + std::vector required = resultDef->observedResults(); + resultsInUse.insert(required.begin(), required.end()); + } + } + } + return resultsInUse; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RiaMemoryCleanup::findEclipseResultsInUse() const +{ + std::set resultsInUse; + RimEclipseCase* eclipseCase = dynamic_cast(m_case()); + if (eclipseCase) + { + std::vector 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 RiaMemoryCleanup::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) +{ + QList options; + if (fieldNeedingOptions == &m_case) + { + RimProject* proj = RiaApplication::instance()->project(); + if (proj) + { + std::vector eclipseCases = proj->eclipseCases(); + for (RimEclipseCase* c : eclipseCases) + { + options.push_back(caf::PdmOptionItemInfo(c->caseUserDescription(), c, false, c->uiIcon())); + } + + std::vector 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(m_case()); + RimGeoMechCase* geoMechCase = dynamic_cast(m_case()); + if (eclipseCase) + { + std::set 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::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 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::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(attribute); + if (attrib) + { + attrib->m_buttonText = "Clear Checked Data From Memory"; + } + } +} diff --git a/ApplicationCode/Application/RiaMemoryCleanup.h b/ApplicationCode/Application/RiaMemoryCleanup.h new file mode 100644 index 0000000000..a2d8f58b72 --- /dev/null +++ b/ApplicationCode/Application/RiaMemoryCleanup.h @@ -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 +// 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 selectedGeoMechResults() const; + std::vector selectedEclipseResults() const; + std::set findGeoMechCaseResultsInUse() const; + std::set findEclipseResultsInUse() const; + + QList 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 m_case; + caf::PdmField> m_resultsToDelete; + std::vector m_geomResultAddresses; + std::vector m_eclipseResultAddresses; + caf::PdmField m_performDelete; +}; \ No newline at end of file diff --git a/ApplicationCode/Application/RiaPreferences.cpp b/ApplicationCode/Application/RiaPreferences.cpp index 7de821f1a7..5431f8f102 100644 --- a/ApplicationCode/Application/RiaPreferences.cpp +++ b/ApplicationCode/Application/RiaPreferences.cpp @@ -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(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(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(); +} + diff --git a/ApplicationCode/Application/RiaPreferences.h b/ApplicationCode/Application/RiaPreferences.h index 4b2f9c532b..eba31f902e 100644 --- a/ApplicationCode/Application/RiaPreferences.h +++ b/ApplicationCode/Application/RiaPreferences.h @@ -41,12 +41,19 @@ class RiaPreferences : public caf::PdmObject typedef caf::AppEnum 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 > navigationPolicy; @@ -69,11 +76,7 @@ class RiaPreferences : public caf::PdmObject caf::PdmField showLegendBackground; caf::PdmField useShaders; - caf::PdmField showHud; - caf::PdmField appendClassNameToUiText; - caf::PdmField appendFieldKeywordToToolTipText; - caf::PdmField showTestToolbar; - caf::PdmField includeFractureDebugInfoFile; + caf::PdmField showHud; caf::PdmField lastUsedProjectFileName; @@ -85,12 +88,16 @@ class RiaPreferences : public caf::PdmObject caf::PdmField gridImportMode; protected: - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); - virtual QList 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 calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; private: caf::PdmChildField m_readerSettings; - + caf::PdmField m_appendClassNameToUiText; + caf::PdmField m_appendFieldKeywordToToolTipText; + caf::PdmField m_showTestToolbar; + caf::PdmField m_includeFractureDebugInfoFile; + caf::PdmField m_holoLensExportFolder; QStringList m_tabNames; }; diff --git a/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp b/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp index 4ebc23a301..3d3d0a663a 100644 --- a/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp +++ b/ApplicationCode/Application/RiaSummaryCurveDefinition.cpp @@ -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()); } diff --git a/ApplicationCode/Application/RiaSummaryCurveDefinition.h b/ApplicationCode/Application/RiaSummaryCurveDefinition.h index 3fd0940eb7..553e399191 100644 --- a/ApplicationCode/Application/RiaSummaryCurveDefinition.h +++ b/ApplicationCode/Application/RiaSummaryCurveDefinition.h @@ -37,7 +37,7 @@ class RiaSummaryCurveDefinition RiaSummaryCurveDefinition(); explicit RiaSummaryCurveDefinition(RimSummaryCase* summaryCase, const RifEclipseSummaryAddress& summaryAddress, - RimSummaryCaseCollection* emsemble = nullptr); + RimSummaryCaseCollection* ensemble = nullptr); RimSummaryCase* summaryCase() const; const RifEclipseSummaryAddress& summaryAddress() const; diff --git a/ApplicationCode/Application/RiaViewRedrawScheduler.h b/ApplicationCode/Application/RiaViewRedrawScheduler.h index 9a228a571f..c30eb67586 100644 --- a/ApplicationCode/Application/RiaViewRedrawScheduler.h +++ b/ApplicationCode/Application/RiaViewRedrawScheduler.h @@ -42,7 +42,7 @@ private slots: void startTimer(int msecs); RiaViewRedrawScheduler() : m_resViewUpdateTimer(nullptr) {} - ~RiaViewRedrawScheduler(); + ~RiaViewRedrawScheduler() override; RiaViewRedrawScheduler(const RiaViewRedrawScheduler& o) = delete; void operator=(const RiaViewRedrawScheduler& o) = delete; diff --git a/ApplicationCode/Application/Tools/CMakeLists_files.cmake b/ApplicationCode/Application/Tools/CMakeLists_files.cmake index 06095bc398..8644cd3742 100644 --- a/ApplicationCode/Application/Tools/CMakeLists_files.cmake +++ b/ApplicationCode/Application/Tools/CMakeLists_files.cmake @@ -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 diff --git a/ApplicationCode/Application/Tools/RiaCellDividingTools.cpp b/ApplicationCode/Application/Tools/RiaCellDividingTools.cpp new file mode 100644 index 0000000000..6f5ecd94ec --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaCellDividingTools.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaCellDividingTools.h" + +#include "cvfAssert.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// Internal functions +//-------------------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------------------- +/// Splits a line in a number of equal parts +//-------------------------------------------------------------------------------------------------- +std::vector 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> calcFacePoints(const std::vector edgeXPtsLow, + const std::vector edgeXPtsHigh, + const std::vector edgeYPtsLow, + const std::vector edgeYPtsHigh); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector +RiaCellDividingTools::createHexCornerCoords(std::array mainCellCorners, size_t nx, size_t ny, size_t nz) +{ + std::array, 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 nxyz = {nx, ny, nz}; + std::array, 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>> 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 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 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& 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 splitLine(cvf::Vec3d ptStart, cvf::Vec3d ptEnd, size_t partCount) +{ + std::vector 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> calcFacePoints(const std::vector edgeXPtsLow, + const std::vector edgeXPtsHigh, + const std::vector edgeYPtsLow, + const std::vector edgeYPtsHigh) +{ + CVF_ASSERT(edgeXPtsLow.size() == edgeXPtsHigh.size() && edgeYPtsLow.size() == edgeYPtsHigh.size()); + + size_t xSize = edgeXPtsLow.size(); + size_t ySize = edgeYPtsLow.size(); + + std::vector> 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; +} diff --git a/ApplicationCode/Application/Tools/RiaCellDividingTools.h b/ApplicationCode/Application/Tools/RiaCellDividingTools.h new file mode 100644 index 0000000000..9dba6a7554 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaCellDividingTools.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RiaCellDividingTools +{ +public: + static std::vector + createHexCornerCoords(std::array mainCellCorners, size_t nx, size_t ny, size_t nz); + + static double computeFlowDistance(const std::array& cellVertices, const cvf::Vec3d& areaCenter); +}; diff --git a/ApplicationCode/Application/Tools/RiaColorTables.cpp b/ApplicationCode/Application/Tools/RiaColorTables.cpp index 27b4d52408..c525c10691 100644 --- a/ApplicationCode/Application/Tools/RiaColorTables.cpp +++ b/ApplicationCode/Application/Tools/RiaColorTables.cpp @@ -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 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 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 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 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. + + static std::vector 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 RiaColorTables::invertedCategoryColors() +{ + static std::vector 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 cvf::Color3f(color); + return colors; } diff --git a/ApplicationCode/Application/Tools/RiaColorTables.h b/ApplicationCode/Application/Tools/RiaColorTables.h index ab1a3de8a1..77867a9d6c 100644 --- a/ApplicationCode/Application/Tools/RiaColorTables.h +++ b/ApplicationCode/Application/Tools/RiaColorTables.h @@ -18,8 +18,9 @@ #pragma once +#include "RiaDefines.h" #include "cafColorTable.h" - +#include //================================================================================================== /// @@ -28,6 +29,8 @@ class RiaColorTables { public: + typedef std::map WellPathComponentColors; + static const caf::ColorTable& normalPaletteColors(); static const caf::ColorTable& normalPaletteOppositeOrderingColors(); static const caf::ColorTable& blackWhitePaletteColors(); @@ -53,7 +56,14 @@ class RiaColorTables 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 categoryColors(); + static std::vector invertedCategoryColors(); }; diff --git a/ApplicationCode/Application/Tools/RiaColorTools.cpp b/ApplicationCode/Application/Tools/RiaColorTools.cpp index 0d74ee9489..37d08c6072 100644 --- a/ApplicationCode/Application/Tools/RiaColorTools.cpp +++ b/ApplicationCode/Application/Tools/RiaColorTools.cpp @@ -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()); +} diff --git a/ApplicationCode/Application/Tools/RiaColorTools.h b/ApplicationCode/Application/Tools/RiaColorTools.h index 8feb7a1d7c..8db509194c 100644 --- a/ApplicationCode/Application/Tools/RiaColorTools.h +++ b/ApplicationCode/Application/Tools/RiaColorTools.h @@ -21,6 +21,7 @@ #include "cvfBase.h" #include "cvfArray.h" +#include //================================================================================================== /// @@ -35,4 +36,6 @@ class RiaColorTools 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); }; diff --git a/ApplicationCode/ReservoirDataModel/RigCurveDataTools.cpp b/ApplicationCode/Application/Tools/RiaCurveDataTools.cpp similarity index 91% rename from ApplicationCode/ReservoirDataModel/RigCurveDataTools.cpp rename to ApplicationCode/Application/Tools/RiaCurveDataTools.cpp index cb0bcd9cbf..60aefcf7c9 100644 --- a/ApplicationCode/ReservoirDataModel/RigCurveDataTools.cpp +++ b/ApplicationCode/Application/Tools/RiaCurveDataTools.cpp @@ -17,7 +17,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RigCurveDataTools.h" +#include "RiaCurveDataTools.h" #include // Needed for HUGE_VAL on Linux @@ -26,7 +26,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigCurveDataTools::CurveIntervals RigCurveDataTools::calculateIntervalsOfValidValues(const std::vector& values, +RiaCurveDataTools::CurveIntervals RiaCurveDataTools::calculateIntervalsOfValidValues(const std::vector& 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> RigCurveDataTools::computePolyLineStartStopIndices(const CurveIntervals& intervals) +std::vector> RiaCurveDataTools::computePolyLineStartStopIndices(const CurveIntervals& intervals) { std::vector> lineStartAndStopIndices; @@ -90,7 +90,7 @@ std::vector> 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) { diff --git a/ApplicationCode/ReservoirDataModel/RigCurveDataTools.h b/ApplicationCode/Application/Tools/RiaCurveDataTools.h similarity index 98% rename from ApplicationCode/ReservoirDataModel/RigCurveDataTools.h rename to ApplicationCode/Application/Tools/RiaCurveDataTools.h index 0e812e5540..1dc9550058 100644 --- a/ApplicationCode/ReservoirDataModel/RigCurveDataTools.h +++ b/ApplicationCode/Application/Tools/RiaCurveDataTools.h @@ -32,7 +32,7 @@ class QDateTime; //================================================================================================== /// //================================================================================================== -class RigCurveDataTools +class RiaCurveDataTools { public: typedef std::vector> CurveIntervals; diff --git a/ApplicationCode/Application/Tools/RiaDateStringParser.cpp b/ApplicationCode/Application/Tools/RiaDateStringParser.cpp index c28575a548..f5e16b2b9a 100644 --- a/ApplicationCode/Application/Tools/RiaDateStringParser.cpp +++ b/ApplicationCode/Application/Tools/RiaDateStringParser.cpp @@ -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; } diff --git a/ApplicationCode/Application/Tools/RiaEclipseUnitTools.cpp b/ApplicationCode/Application/Tools/RiaEclipseUnitTools.cpp index a0c4d36cf7..6b40723765 100644 --- a/ApplicationCode/Application/Tools/RiaEclipseUnitTools.cpp +++ b/ApplicationCode/Application/Tools/RiaEclipseUnitTools.cpp @@ -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; } - diff --git a/ApplicationCode/Application/Tools/RiaFieldHandleTools.cpp b/ApplicationCode/Application/Tools/RiaFieldHandleTools.cpp new file mode 100644 index 0000000000..51919527f8 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaFieldHandleTools.cpp @@ -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 +// 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); + } +} diff --git a/ApplicationCode/Application/Tools/RiaFieldHandleTools.h b/ApplicationCode/Application/Tools/RiaFieldHandleTools.h new file mode 100644 index 0000000000..a48cdf212d --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaFieldHandleTools.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +namespace caf +{ +class PdmFieldHandle; +} + +//================================================================================================== +// +//================================================================================================== +class RiaFieldhandleTools +{ +public: + static void disableWriteAndSetFieldHidden(caf::PdmFieldHandle* fieldHandle); +}; diff --git a/ApplicationCode/Application/Tools/RiaFilePathTools.cpp b/ApplicationCode/Application/Tools/RiaFilePathTools.cpp index 2e844daf74..0baf49d767 100644 --- a/ApplicationCode/Application/Tools/RiaFilePathTools.cpp +++ b/ApplicationCode/Application/Tools/RiaFilePathTools.cpp @@ -99,32 +99,16 @@ QString RiaFilePathTools::canonicalPath(const QString& path) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiaFilePathTools::commonRootPath(const QStringList& paths) +std::pair 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); } diff --git a/ApplicationCode/Application/Tools/RiaFilePathTools.h b/ApplicationCode/Application/Tools/RiaFilePathTools.h index 255a93e6f6..e0fd937749 100644 --- a/ApplicationCode/Application/Tools/RiaFilePathTools.h +++ b/ApplicationCode/Application/Tools/RiaFilePathTools.h @@ -39,5 +39,5 @@ class RiaFilePathTools 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 toFolderAndFileName(const QString& absFileName); }; diff --git a/ApplicationCode/Application/Tools/RiaGitDiff.cpp b/ApplicationCode/Application/Tools/RiaGitDiff.cpp new file mode 100644 index 0000000000..41894f5cb0 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaGitDiff.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaGitDiff.h" + +#include "cafUtils.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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; +} diff --git a/ApplicationCode/Application/Tools/RiaGitDiff.h b/ApplicationCode/Application/Tools/RiaGitDiff.h new file mode 100644 index 0000000000..82fe113659 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaGitDiff.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +//================================================================================================== +// +// 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; +}; diff --git a/ApplicationCode/Application/Tools/RiaImageCompareReporter.cpp b/ApplicationCode/Application/Tools/RiaImageCompareReporter.cpp index f3afde6fdf..39f22e372e 100644 --- a/ApplicationCode/Application/Tools/RiaImageCompareReporter.cpp +++ b/ApplicationCode/Application/Tools/RiaImageCompareReporter.cpp @@ -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 += "\n"; html += "\n"; - html += "Regression-Test Report\n"; if (m_showInteractiveDiff) { html += cssString(); } + html += diff2htmlHeaderText; + html += "\n"; html += "\n"; html += "\n"; + html += "Regression-Test Report\n"; html += "\n"; for (size_t dsIdx = 0; dsIdx < m_directorySets.size(); ++dsIdx) diff --git a/ApplicationCode/Application/Tools/RiaImageCompareReporter.h b/ApplicationCode/Application/Tools/RiaImageCompareReporter.h index e580a55a52..913f85f725 100644 --- a/ApplicationCode/Application/Tools/RiaImageCompareReporter.h +++ b/ApplicationCode/Application/Tools/RiaImageCompareReporter.h @@ -28,7 +28,7 @@ class RiaImageCompareReporter 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(); diff --git a/ApplicationCode/Application/Tools/RiaImportEclipseCaseTools.cpp b/ApplicationCode/Application/Tools/RiaImportEclipseCaseTools.cpp index 139741cb1d..a4fd0d7c35 100644 --- a/ApplicationCode/Application/Tools/RiaImportEclipseCaseTools.cpp +++ b/ApplicationCode/Application/Tools/RiaImportEclipseCaseTools.cpp @@ -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 referringObjects; - existingFileSummaryCase->objectsWithReferringPtrFields(referringObjects); + std::vector 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(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; diff --git a/ApplicationCode/Application/Tools/RiaLogging.cpp b/ApplicationCode/Application/Tools/RiaLogging.cpp index cb1fa56ec2..51f92c9b40 100644 --- a/ApplicationCode/Application/Tools/RiaLogging.cpp +++ b/ApplicationCode/Application/Tools/RiaLogging.cpp @@ -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()); } } diff --git a/ApplicationCode/Application/Tools/RiaOffshoreSphericalCoords.h b/ApplicationCode/Application/Tools/RiaOffshoreSphericalCoords.h new file mode 100644 index 0000000000..f89cdbba75 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaOffshoreSphericalCoords.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include +#include "cvfVector3.h" +#include + +// 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 incAziR; +}; + diff --git a/ApplicationCode/Application/Tools/RiaOptionItemFactory.cpp b/ApplicationCode/Application/Tools/RiaOptionItemFactory.cpp new file mode 100644 index 0000000000..c594610921 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaOptionItemFactory.cpp @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaOptionItemFactory.h" + +#include "Rim3dView.h" +#include "RimCase.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaOptionItemFactory::appendOptionItemFromViewNameAndCaseName(Rim3dView* view, QList* optionItems) +{ + if (!view || !optionItems) return; + + QString caseName; + + RimCase* rimCase = nullptr; + view->firstAncestorOrThisOfType(rimCase); + if (rimCase) + { + caseName = rimCase->caseUserDescription(); + } + else + { + caseName = ""; + } + + QString displayName = caseName + " : " + view->name(); + + QIcon icon = view->uiCapability()->uiIcon(); + + optionItems->push_back(caf::PdmOptionItemInfo(displayName, view, false, icon)); +} diff --git a/ApplicationCode/Application/Tools/RiaOptionItemFactory.h b/ApplicationCode/Application/Tools/RiaOptionItemFactory.h new file mode 100644 index 0000000000..e2ab8b01ca --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaOptionItemFactory.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmUiItem.h" + +#include + +class Rim3dView; + +class RiaOptionItemFactory +{ +public: + static void appendOptionItemFromViewNameAndCaseName(Rim3dView* view, QList* optionItems); +}; diff --git a/ApplicationCode/Application/Tools/RiaProjectModifier.cpp b/ApplicationCode/Application/Tools/RiaProjectModifier.cpp index 82fae44ba2..168359af62 100644 --- a/ApplicationCode/Application/Tools/RiaProjectModifier.cpp +++ b/ApplicationCode/Application/Tools/RiaProjectModifier.cpp @@ -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(rimCase); - if (resultCase) + RimEclipseResultCase* eclipseResultCase = dynamic_cast(rimCase); + RimGeoMechCase* geomechCase = dynamic_cast(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); + } } } } diff --git a/ApplicationCode/Application/Tools/RiaQDateTimeTools.cpp b/ApplicationCode/Application/Tools/RiaQDateTimeTools.cpp index e84f9f5970..e2a35b6daf 100644 --- a/ApplicationCode/Application/Tools/RiaQDateTimeTools.cpp +++ b/ApplicationCode/Application/Tools/RiaQDateTimeTools.cpp @@ -18,13 +18,35 @@ #include "RiaQDateTimeTools.h" -#include #include +#include +#include + +#include #include #include +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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 RiaQDateTimeTools::dateTimePeriods() +{ + return std::vector( + { + 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); +} diff --git a/ApplicationCode/Application/Tools/RiaQDateTimeTools.h b/ApplicationCode/Application/Tools/RiaQDateTimeTools.h index 127f9d1435..8fa4d3c99f 100644 --- a/ApplicationCode/Application/Tools/RiaQDateTimeTools.h +++ b/ApplicationCode/Application/Tools/RiaQDateTimeTools.h @@ -21,34 +21,108 @@ #include #include +#include + #include +#include 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 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; +}; diff --git a/ApplicationCode/Application/Tools/RiaQIconTools.cpp b/ApplicationCode/Application/Tools/RiaQIconTools.cpp new file mode 100644 index 0000000000..6ed68f4850 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaQIconTools.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaQIconTools.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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; +} diff --git a/ApplicationCode/Application/Tools/RiaQIconTools.h b/ApplicationCode/Application/Tools/RiaQIconTools.h new file mode 100644 index 0000000000..370921b4da --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaQIconTools.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +//================================================================================================== +// +// +// +//================================================================================================== +class RiaQIconTools +{ +public: + static QPixmap appendPixmapUpperLeft(const QPixmap& pixmap, const QPixmap& overlayPixmap); +}; diff --git a/ApplicationCode/Application/Tools/RiaRegressionTest.cpp b/ApplicationCode/Application/Tools/RiaRegressionTest.cpp index 2d696c5f59..eb1f28f9a6 100644 --- a/ApplicationCode/Application/Tools/RiaRegressionTest.cpp +++ b/ApplicationCode/Application/Tools/RiaRegressionTest.cpp @@ -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 +// +// See the GNU General Public License at // 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 compare", "", "Location of compare tool from Image Magic suite", ""); + CAF_PDM_InitFieldNoDefault(&folderContainingCompareTool, + "workingFolder", + "Folder containing compare", + "", + "Location of compare tool from Image Magic suite", + ""); folderContainingCompareTool.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); - - CAF_PDM_InitFieldNoDefault(&folderContainingDiffTool, "folderContainingDiffTool", "Folder containing diff", "", "Location of diff tool used for text compare", ""); + + CAF_PDM_InitFieldNoDefault(&folderContainingDiffTool, + "folderContainingDiffTool", + "Folder containing diff", + "", + "Location of diff tool used for text compare", + ""); folderContainingDiffTool.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + CAF_PDM_InitFieldNoDefault(&folderContainingGitTool, + "folderContainingGitTool", + "Folder containing git", + "", + "Location of git tool used for text compare", + ""); + folderContainingGitTool.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + CAF_PDM_InitFieldNoDefault(®ressionTestFolder, "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 == ®ressionTestFolder) + if (field == &folderContainingDiffTool || field == &folderContainingCompareTool || field == ®ressionTestFolder || + field == &folderContainingGitTool) { caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast(attribute); if (myAttr) diff --git a/ApplicationCode/Application/Tools/RiaRegressionTest.h b/ApplicationCode/Application/Tools/RiaRegressionTest.h index e4d815ed4f..d9aff92eb6 100644 --- a/ApplicationCode/Application/Tools/RiaRegressionTest.h +++ b/ApplicationCode/Application/Tools/RiaRegressionTest.h @@ -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 +// +// See the GNU General Public License at // 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 folderContainingCompareTool; - caf::PdmField folderContainingDiffTool; - caf::PdmField regressionTestFolder; - caf::PdmField testFilter; - caf::PdmField showInteractiveDiffImages; + caf::PdmField folderContainingCompareTool; + caf::PdmField folderContainingDiffTool; + caf::PdmField folderContainingGitTool; + caf::PdmField regressionTestFolder; + caf::PdmField testFilter; + caf::PdmField showInteractiveDiffImages; + caf::PdmField 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; }; diff --git a/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp b/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp index 44d3631b17..b6a18553b4 100644 --- a/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp +++ b/ApplicationCode/Application/Tools/RiaRegressionTestRunner.cpp @@ -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 #include #include @@ -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,258 +120,326 @@ 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(); + QFileInfoList folderList = subDirectoriesForTestExecution(testDir); + + // delete diff and generated images - if (!testFilter.isEmpty()) + for (const QFileInfo& fi : folderList) { - QFileInfoList subset; + QDir testCaseFolder(fi.filePath()); - for (auto fi : folderList) { - QString path = fi.path(); - QString baseName = fi.baseName(); + QDir genDir(testCaseFolder.filePath(generatedFolderName)); + removeDirectoryWithContent(genDir); + } - for (auto s : testFilter) - { - QString trimmed = s.trimmed(); - if (baseName.contains(trimmed)) - { - subset.push_back(fi); - } - } + { + QDir diffDir(testCaseFolder.filePath(diffFolderName)); + removeDirectoryWithContent(diffDir); } - folderList = subset; + { + QDir generatedFiles(testCaseFolder.filePath(RegTestNames::generatedFilesFolderName)); + removeDirectoryWithContent(generatedFiles); + } } - // delete diff and generated images + QString htmlReportFileName = generateHtmlReport(folderList, baseFolderName, generatedFolderName, diffFolderName, testDir); + QDesktopServices::openUrl(htmlReportFileName); - for (int i = 0; i < folderList.size(); ++i) - { - QDir testCaseFolder(folderList[i].filePath()); + QTime timeStamp; + timeStamp.start(); - QDir genDir(testCaseFolder.filePath(generatedFolderName)); - removeDirectoryWithContent(genDir); + logInfoTextWithTimeInSeconds(timeStamp, "Starting regression tests\n"); - QDir diffDir(testCaseFolder.filePath(diffFolderName)); - removeDirectoryWithContent(diffDir); + for (const QFileInfo& folderFileInfo : folderList) + { + QDir testCaseFolder(folderFileInfo.filePath()); - QDir baseDir(testCaseFolder.filePath(baseFolderName)); - } + bool anyCommandFilesExecuted = findAndExecuteCommandFiles(testCaseFolder, regressionTestConfig, htmlReportFileName); - // Generate html report + if (!anyCommandFilesExecuted) + { + QString projectFileName; - RiaImageCompareReporter imageCompareReporter; + if (testCaseFolder.exists(regTestProjectName + ".rip")) + { + projectFileName = regTestProjectName + ".rip"; + } - // Minor workaround - // Use registry to define if interactive diff images should be created - // Defined by user in RiaRegressionTest - { - QSettings settings; + if (testCaseFolder.exists(regTestProjectName + ".rsp")) + { + projectFileName = regTestProjectName + ".rsp"; + } - bool useInteractiveDiff = settings.value("showInteractiveDiffImages").toBool(); - if (useInteractiveDiff) - { - imageCompareReporter.showInteractiveOnly(); - } - } + if (!projectFileName.isEmpty()) + { + logInfoTextWithTimeInSeconds(timeStamp, "Initializing test :" + testCaseFolder.absolutePath()); - QTime timeStamp; - timeStamp.start(); + RiaApplication* app = RiaApplication::instance(); - logInfoTextWithTimeInSeconds(timeStamp, "Starting regression tests\n"); + app->loadProject(testCaseFolder.filePath(projectFileName)); - for (int dirIdx = 0; dirIdx < folderList.size(); ++dirIdx) - { - QDir testCaseFolder(folderList[dirIdx].filePath()); + // Wait until all command objects have completed + app->waitUntilCommandObjectsHasBeenProcessed(); - QString testFolderName = testCaseFolder.dirName(); - QString reportBaseFolderName = testCaseFolder.filePath(baseFolderName); - QString reportGeneratedFolderName = testCaseFolder.filePath(generatedFolderName); - QString reportDiffFolderName = testCaseFolder.filePath(diffFolderName); + regressionTestConfigureProject(); - imageCompareReporter.addImageDirectoryComparisonSet(testFolderName.toStdString(), - reportBaseFolderName.toStdString(), - reportGeneratedFolderName.toStdString(), - reportDiffFolderName.toStdString()); - } + resizeMaximizedPlotWindows(); - QString htmlReportFileName = testDir.filePath(RegTestNames::reportFileName); - imageCompareReporter.generateHTMLReport(htmlReportFileName.toStdString()); + QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath(generatedFolderName); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(fullPathGeneratedFolder); - // Open HTML report - QDesktopServices::openUrl(htmlReportFileName); + RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(fullPathGeneratedFolder); - for (int dirIdx = 0; dirIdx < folderList.size(); ++dirIdx) - { - QDir testCaseFolder(folderList[dirIdx].filePath()); + app->closeProject(); + } + else + { + RiaLogging::error("Could not find a regression test file named : " + testCaseFolder.absolutePath() + "/" + + regTestProjectName + ".rsp"); + } + } - // Detect any command files - QStringList filterList; - filterList << RegTestNames::commandFileFilter; + 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(); - QFileInfoList commandFileEntries = testCaseFolder.entryInfoList(filterList); - if (!commandFileEntries.empty()) + for (int fIdx = 0; fIdx < baseImageFileNames.size(); ++fIdx) { - QString currentApplicationPath = QDir::current().absolutePath(); + 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()); + } - // 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()); + // Invoke git diff - for (const auto& fileInfo : commandFileEntries) + { + 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)) { - QString commandFile = fileInfo.absoluteFilePath(); + QTextStream stream(&file); + + QString divSectionForDiff = R"( +
+original +
+ +)"; + stream << divSectionForDiff; + stream << ""; - 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); + QString generateDiffString = R"( + + +)"; + stream << generateDiffString; } } + } + } - QDir::setCurrent(currentApplicationPath); - - // Create diff based on generated folders - { - QString html; - - RiaRegressionTest regressionTestConfig; - regressionTestConfig.readSettingsFromApplicationStore(); + RiaLogging::info("\n"); + logInfoTextWithTimeInSeconds(timeStamp, "Completed regression tests"); - RiaTextFileCompare textFileCompare(regressionTestConfig.folderContainingDiffTool()); + QDir::setCurrent(currentApplicationPath); - QString baseFilesFolderName = testCaseFolder.filePath(RegTestNames::baseFilesFolderName); - QString generatedFilesFolderName = testCaseFolder.filePath(RegTestNames::generatedFilesFolderName); + m_runningRegressionTests = false; +} - QFileInfo fib(baseFilesFolderName); - QFileInfo fig(generatedFilesFolderName); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiaRegressionTestRunner::findAndExecuteCommandFiles(const QDir& testCaseFolder, + const RiaRegressionTest& regressionTestConfig, + const QString& htmlReportFileName) +{ + QStringList filterList; + filterList << RegTestNames::commandFileFilter; - if (fib.exists() && fig.exists()) - { - { - QString headerText = testCaseFolder.dirName(); - - html += "\n"; - html += " \n"; - html += " \n"; - html += " \n"; - - textFileCompare.runComparison(baseFilesFolderName, generatedFilesFolderName); - - QString diff = textFileCompare.diffOutput(); - if (diff.isEmpty()) - { - html += " \n"; - html += " \n"; - html += " \n"; - } - else - { - html += " \n"; - html += " \n"; - html += " \n"; - } - - // Table end - html += "
" + headerText + "
No text diff detected
Text diff detected - output from diff tool :
\n"; - - if (!diff.isEmpty()) - { - html += QString(" %1 ").arg(diff); - } - } + QFileInfoList commandFileEntries = testCaseFolder.entryInfoList(filterList); + if (commandFileEntries.empty()) + { + return false; + } - QFile file(htmlReportFileName); - if (file.open(QIODevice::Append | QIODevice::Text)) - { - QTextStream stream(&file); + QString currentAbsolutePath = QDir::current().absolutePath(); - stream << html; - } - } - } - } + // 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()); - QString projectFileName; + for (const auto& fileInfo : commandFileEntries) + { + QString commandFile = fileInfo.absoluteFilePath(); - if (testCaseFolder.exists(regTestProjectName + ".rip")) + QFile file(commandFile); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - projectFileName = regTestProjectName + ".rip"; + RiaLogging::error("Failed to open command file : " + commandFile); } - - if (testCaseFolder.exists(regTestProjectName + ".rsp")) + else { - projectFileName = regTestProjectName + ".rsp"; + QTextStream in(&file); + RicfCommandFileExecutor::instance()->executeCommands(in); } + } - if (!projectFileName.isEmpty()) - { - logInfoTextWithTimeInSeconds(timeStamp, "Initializing test :" + testCaseFolder.absolutePath()); + QDir::setCurrent(currentAbsolutePath); - RiaApplication* app = RiaApplication::instance(); + // Create diff based on generated folders + { + QString html; - app->loadProject(testCaseFolder.filePath(projectFileName)); + RiaTextFileCompare textFileCompare(regressionTestConfig.folderContainingDiffTool()); - // Wait until all command objects have completed - app->waitUntilCommandObjectsHasBeenProcessed(); + QString baseFilesFolderName = testCaseFolder.filePath(RegTestNames::baseFilesFolderName); + QString generatedFilesFolderName = testCaseFolder.filePath(RegTestNames::generatedFilesFolderName); - regressionTestConfigureProject(); + QFileInfo fib(baseFilesFolderName); + QFileInfo fig(generatedFilesFolderName); - resizeMaximizedPlotWindows(); + if (fib.exists() && fig.exists()) + { + { + QString headerText = testCaseFolder.dirName(); - QString fullPathGeneratedFolder = testCaseFolder.absoluteFilePath(generatedFolderName); - RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(fullPathGeneratedFolder); + html += "\n"; + html += " \n"; + html += " \n"; + html += " \n"; - RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(fullPathGeneratedFolder); + textFileCompare.runComparison(baseFilesFolderName, generatedFilesFolderName); - 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(); + QString diff = textFileCompare.diffOutput(); + if (diff.isEmpty()) + { + html += " \n"; + html += " \n"; + html += " \n"; + } + else + { + html += " \n"; + html += " \n"; + html += " \n"; + } - 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) + // Table end + html += "
" + + headerText + "
No text diff " + "detected
Text diff detected - " + "output from diff tool :
\n"; + + if (!diff.isEmpty()) { - qDebug() << "Error comparing :" << imgComparator.errorMessage() << "\n" << imgComparator.errorDetails(); + html += QString(" %1 ").arg(diff); } } - app->closeProject(); + QFile file(htmlReportFileName); + if (file.open(QIODevice::Append | QIODevice::Text)) + { + QTextStream stream(&file); - logInfoTextWithTimeInSeconds(timeStamp, "Completed test :" + testCaseFolder.absolutePath()); + stream << html; + } } - else + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaRegressionTestRunner::generateHtmlReport(const QFileInfoList& folderList, + const QString& baseFolderName, + const QString& generatedFolderName, + const QString& diffFolderName, + const QDir& testDir) +{ + RiaImageCompareReporter imageCompareReporter; + + // Minor workaround + // Use registry to define if interactive diff images should be created + // Defined by user in RiaRegressionTest + { + QSettings settings; + + bool useInteractiveDiff = settings.value("showInteractiveDiffImages").toBool(); + if (useInteractiveDiff) { - RiaLogging::error("Could not find a regression test file named : " + testCaseFolder.absolutePath() + "/" + - regTestProjectName + ".rsp"); + imageCompareReporter.showInteractiveOnly(); } } - RiaLogging::info("\n"); - logInfoTextWithTimeInSeconds(timeStamp, "Completed regression tests"); + for (const QFileInfo& fi : folderList) + { + QDir testCaseFolder(fi.filePath()); - QDir::setCurrent(currentApplicationPath); + QString testFolderName = testCaseFolder.dirName(); + QString reportBaseFolderName = testCaseFolder.filePath(baseFolderName); + QString reportGeneratedFolderName = testCaseFolder.filePath(generatedFolderName); + QString reportDiffFolderName = testCaseFolder.filePath(diffFolderName); - m_runningRegressionTests = false; + imageCompareReporter.addImageDirectoryComparisonSet(testFolderName.toStdString(), + reportBaseFolderName.toStdString(), + reportGeneratedFolderName.toStdString(), + reportDiffFolderName.toStdString()); + } + + QString htmlReportFileName = testDir.filePath(RegTestNames::reportFileName); + + QString htmldiff2htmlText = diff2htmlHeaderText(m_rootPath); + imageCompareReporter.generateHTMLReport(htmlReportFileName.toStdString(), htmldiff2htmlText.toStdString()); + + return htmlReportFileName; } //-------------------------------------------------------------------------------------------------- @@ -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 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 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"( + + + + + + +)"; + + 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); diff --git a/ApplicationCode/Application/Tools/RiaRegressionTestRunner.h b/ApplicationCode/Application/Tools/RiaRegressionTestRunner.h index 40ec63cf9d..2a843a81a7 100644 --- a/ApplicationCode/Application/Tools/RiaRegressionTestRunner.h +++ b/ApplicationCode/Application/Tools/RiaRegressionTestRunner.h @@ -18,10 +18,14 @@ #pragma once +#include "RiaRegressionTest.h" + +#include #include #include class QDir; +class RiaRegressionTest; //================================================================================================== // @@ -35,21 +39,35 @@ class RiaRegressionTestRunner 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(); + + 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 regressionTestConfigureProject(); - static void resizeMaximizedPlotWindows(); - static QSize regressionDefaultImageSize(); + 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; }; diff --git a/ApplicationCode/Application/Tools/RiaStatisticsTools.cpp b/ApplicationCode/Application/Tools/RiaStatisticsTools.cpp new file mode 100644 index 0000000000..b927db933f --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaStatisticsTools.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaStatisticsTools.h" + +#include "RifEclipseSummaryAddress.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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; +} diff --git a/ApplicationCode/Application/Tools/RiaStatisticsTools.h b/ApplicationCode/Application/Tools/RiaStatisticsTools.h new file mode 100644 index 0000000000..25467e626a --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaStatisticsTools.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +class QString; + +//================================================================================================== +// +// +// +//================================================================================================== +class RiaStatisticsTools +{ +public: + static const QString replacePercentileByPValueText(const QString& percentile); + + + template static bool isInvalidNumber(NumberType value) + { + return !isValidNumber(value); + } + + template static bool isValidNumber(NumberType value) + { + if (std::isinf(value)) return false; + if (std::isnan(value)) return false; + + return true; + } +}; + diff --git a/ApplicationCode/Application/Tools/RiaStdStringTools.cpp b/ApplicationCode/Application/Tools/RiaStdStringTools.cpp index b144d8fc82..a82f4674df 100644 --- a/ApplicationCode/Application/Tools/RiaStdStringTools.cpp +++ b/ApplicationCode/Application/Tools/RiaStdStringTools.cpp @@ -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; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/Tools/RiaStdStringTools.h b/ApplicationCode/Application/Tools/RiaStdStringTools.h index dd1f15e59d..5de74be4ed 100644 --- a/ApplicationCode/Application/Tools/RiaStdStringTools.h +++ b/ApplicationCode/Application/Tools/RiaStdStringTools.h @@ -33,6 +33,7 @@ class RiaStdStringTools 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); diff --git a/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp b/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp index 595df584ba..b23b143140 100644 --- a/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp +++ b/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.cpp @@ -130,7 +130,7 @@ std::vector RiaSummaryCurveAnalyzer::identifierTexts(RifEclipseSummaryA /// //-------------------------------------------------------------------------------------------------- std::vector - RiaSummaryCurveAnalyzer::addressesForCategory(const std::vector& addresses, + RiaSummaryCurveAnalyzer::addressesForCategory(const std::set& addresses, RifEclipseSummaryAddress::SummaryVarCategory category) { std::vector filteredAddresses; diff --git a/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.h b/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.h index ba12c9cef8..e66475241f 100644 --- a/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.h +++ b/ApplicationCode/Application/Tools/RiaSummaryCurveAnalyzer.h @@ -50,7 +50,7 @@ class RiaSummaryCurveAnalyzer std::vector identifierTexts(RifEclipseSummaryAddress::SummaryVarCategory category) const; - static std::vector addressesForCategory(const std::vector& addresses, + static std::vector addressesForCategory(const std::set& addresses, RifEclipseSummaryAddress::SummaryVarCategory category); private: diff --git a/ApplicationCode/Application/Tools/RiaSummaryTools.cpp b/ApplicationCode/Application/Tools/RiaSummaryTools.cpp index 5d6af6a70f..892df17d38 100644 --- a/ApplicationCode/Application/Tools/RiaSummaryTools.cpp +++ b/ApplicationCode/Application/Tools/RiaSummaryTools.cpp @@ -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); } } diff --git a/ApplicationCode/Application/Tools/RiaSummaryTools.h b/ApplicationCode/Application/Tools/RiaSummaryTools.h index 92271a4bbc..1a3cdc510a 100644 --- a/ApplicationCode/Application/Tools/RiaSummaryTools.h +++ b/ApplicationCode/Application/Tools/RiaSummaryTools.h @@ -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); diff --git a/ApplicationCode/Application/Tools/RiaTextStringTools.cpp b/ApplicationCode/Application/Tools/RiaTextStringTools.cpp index 2f3992b35d..1e4d56fc84 100644 --- a/ApplicationCode/Application/Tools/RiaTextStringTools.cpp +++ b/ApplicationCode/Application/Tools/RiaTextStringTools.cpp @@ -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; +} + diff --git a/ApplicationCode/Application/Tools/RiaTextStringTools.h b/ApplicationCode/Application/Tools/RiaTextStringTools.h index ee915087f2..e287dc3cf0 100644 --- a/ApplicationCode/Application/Tools/RiaTextStringTools.h +++ b/ApplicationCode/Application/Tools/RiaTextStringTools.h @@ -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); } diff --git a/ApplicationCode/ReservoirDataModel/RigTimeHistoryCurveMerger.cpp b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveMerger.cpp similarity index 86% rename from ApplicationCode/ReservoirDataModel/RigTimeHistoryCurveMerger.cpp rename to ApplicationCode/Application/Tools/RiaTimeHistoryCurveMerger.cpp index 19d7b4634d..19fe6cfff0 100644 --- a/ApplicationCode/ReservoirDataModel/RigTimeHistoryCurveMerger.cpp +++ b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveMerger.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RigTimeHistoryCurveMerger.h" +#include "RiaTimeHistoryCurveMerger.h" #include // 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& values, const std::vector& timeSteps) +void RiaTimeHistoryCurveMerger::addCurveData(const std::vector& values, const std::vector& timeSteps) { CVF_ASSERT(values.size() == timeSteps.size()); @@ -43,7 +43,7 @@ void RigTimeHistoryCurveMerger::addCurveData(const std::vector& 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& RigTimeHistoryCurveMerger::allTimeSteps() const +const std::vector& RiaTimeHistoryCurveMerger::allTimeSteps() const { return m_allTimeSteps; } @@ -59,7 +59,7 @@ const std::vector& RigTimeHistoryCurveMerger::allTimeSteps() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector& RigTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const +const std::vector& RiaTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const { CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size()); @@ -69,7 +69,7 @@ const std::vector& RigTimeHistoryCurveMerger::interpolatedCurveValuesFor //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector& RigTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) +std::vector& RiaTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) { CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size()); @@ -79,7 +79,7 @@ std::vector& 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& curveValues, const std::vector& 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; } diff --git a/ApplicationCode/ReservoirDataModel/RigTimeHistoryCurveMerger.h b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveMerger.h similarity index 91% rename from ApplicationCode/ReservoirDataModel/RigTimeHistoryCurveMerger.h rename to ApplicationCode/Application/Tools/RiaTimeHistoryCurveMerger.h index 5a1de82f9d..b1687a50c6 100644 --- a/ApplicationCode/ReservoirDataModel/RigTimeHistoryCurveMerger.h +++ b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveMerger.h @@ -18,7 +18,7 @@ #pragma once -#include "RigCurveDataTools.h" +#include "RiaCurveDataTools.h" #include @@ -26,10 +26,10 @@ //================================================================================================== /// //================================================================================================== -class RigTimeHistoryCurveMerger +class RiaTimeHistoryCurveMerger { public: - RigTimeHistoryCurveMerger(); + RiaTimeHistoryCurveMerger(); void addCurveData(const std::vector& values, @@ -37,7 +37,7 @@ class RigTimeHistoryCurveMerger void computeInterpolatedValues(); - RigCurveDataTools::CurveIntervals validIntervalsForAllTimeSteps() const; + RiaCurveDataTools::CurveIntervals validIntervalsForAllTimeSteps() const; const std::vector& allTimeSteps() const; const std::vector& interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const; @@ -61,7 +61,7 @@ class RigTimeHistoryCurveMerger private: std::vector, std::vector>> m_originalValues; - RigCurveDataTools::CurveIntervals m_validIntervalsForAllTimeSteps; + RiaCurveDataTools::CurveIntervals m_validIntervalsForAllTimeSteps; std::vector m_allTimeSteps; std::vector> m_interpolatedValuesForAllCurves; diff --git a/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp new file mode 100644 index 0000000000..5162476970 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include +#include + +#include "RiaTimeHistoryCurveResampler.h" + +#include + +//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::infinity() + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaTimeHistoryCurveResampler::RiaTimeHistoryCurveResampler() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiaTimeHistoryCurveResampler::setCurveData(const std::vector& values, const std::vector& 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& RiaTimeHistoryCurveResampler::resampledTimeSteps() const +{ + return m_timeSteps; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RiaTimeHistoryCurveResampler::resampledValues() const +{ + return m_values; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiaTimeHistoryCurveResampler::timeStepsFromTimeRange(DateTimePeriod period, time_t minTime, time_t maxTime) +{ + if(minTime > maxTime) return std::vector(); + + auto firstOriginalTimeStep = QDT::fromTime_t(minTime); + auto lastOriginalTimeStep = QDT::fromTime_t(maxTime); + + auto currTimeStep = firstResampledTimeStep(firstOriginalTimeStep, period); + + std::vector 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; +} diff --git a/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.h b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.h new file mode 100644 index 0000000000..6d191aa704 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaCurveDataTools.h" +#include "RiaQDateTimeTools.h" + +#include + +using QDT = RiaQDateTimeTools; + +//================================================================================================== +/// +//================================================================================================== +class RiaTimeHistoryCurveResampler +{ +public: + RiaTimeHistoryCurveResampler(); + + void setCurveData(const std::vector& values, + const std::vector& timeSteps); + + void resampleAndComputePeriodEndValues(DateTimePeriod period); + void resampleAndComputeWeightedMeanValues(DateTimePeriod period); + + const std::vector& resampledTimeSteps() const; + const std::vector& resampledValues() const; + + static std::vector 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> m_originalValues; + + std::vector m_timeSteps; + std::vector m_values; +}; diff --git a/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.cpp b/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.cpp new file mode 100644 index 0000000000..075d0ac8a2 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaWeightedGeometricMeanCalculator.h" + +#include "cvfAssert.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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; +} diff --git a/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.h b/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.h new file mode 100644 index 0000000000..0720a5d19a --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaWeightedGeometricMeanCalculator.h @@ -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 +// 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; +}; diff --git a/ApplicationCode/Application/Tools/RiaWeightedHarmonicMeanCalculator.cpp b/ApplicationCode/Application/Tools/RiaWeightedHarmonicMeanCalculator.cpp new file mode 100644 index 0000000000..6b5ba0d847 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaWeightedHarmonicMeanCalculator.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaWeightedHarmonicMeanCalculator.h" + +#include "cvfAssert.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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; +} diff --git a/ApplicationCode/Application/Tools/RiaWeightedHarmonicMeanCalculator.h b/ApplicationCode/Application/Tools/RiaWeightedHarmonicMeanCalculator.h new file mode 100644 index 0000000000..07d194f48a --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaWeightedHarmonicMeanCalculator.h @@ -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 +// 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; +}; diff --git a/ApplicationCode/Application/Tools/RiaWeightedMeanCalculator.h b/ApplicationCode/Application/Tools/RiaWeightedMeanCalculator.h new file mode 100644 index 0000000000..09bfae0649 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaWeightedMeanCalculator.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +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" \ No newline at end of file diff --git a/ApplicationCode/Application/Tools/RiaWeightedMeanCalculator.inl b/ApplicationCode/Application/Tools/RiaWeightedMeanCalculator.inl new file mode 100644 index 0000000000..d3fb4dc687 --- /dev/null +++ b/ApplicationCode/Application/Tools/RiaWeightedMeanCalculator.inl @@ -0,0 +1,75 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "cvfAssert.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +RiaWeightedMeanCalculator::RiaWeightedMeanCalculator() + : m_aggregatedValue(T{}) + , m_aggregatedWeight(0.0) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void RiaWeightedMeanCalculator::addValueAndWeight(T value, double weight) +{ + CVF_ASSERT(weight >= 0.0); + + m_aggregatedValue = m_aggregatedValue + value * weight; + m_aggregatedWeight += weight; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +T RiaWeightedMeanCalculator::weightedMean() const +{ + bool validWeights = validAggregatedWeight(); + CVF_TIGHT_ASSERT(validWeights); + if (validWeights) + { + return m_aggregatedValue * (1.0 / m_aggregatedWeight); + } + return T{}; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +double RiaWeightedMeanCalculator::aggregatedWeight() const +{ + return m_aggregatedWeight; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +bool RiaWeightedMeanCalculator::validAggregatedWeight() const +{ + return m_aggregatedWeight > 1.0e-12; +} \ No newline at end of file diff --git a/ApplicationCode/Application/Tools/RiaWellNameComparer.h b/ApplicationCode/Application/Tools/RiaWellNameComparer.h index 3ef70b9744..a256840f38 100644 --- a/ApplicationCode/Application/Tools/RiaWellNameComparer.h +++ b/ApplicationCode/Application/Tools/RiaWellNameComparer.h @@ -33,9 +33,10 @@ class RiaWellNameComparer static QString tryFindMatchingSimWellName(QString searchName); static QString tryFindMatchingWellPath(QString wellName); -private: static QString tryMatchNameInList(QString searchName, const std::vector& nameList); + +private: static QString tryMatchName(QString searchName, const std::vector& nameList, std::function stringFormatter = nullptr); diff --git a/ApplicationCode/Application/Tools/WellPathTools/CMakeLists_files.cmake b/ApplicationCode/Application/Tools/WellPathTools/CMakeLists_files.cmake new file mode 100644 index 0000000000..0153169841 --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/CMakeLists_files.cmake @@ -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 ) diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaArcCurveCalculator.cpp b/ApplicationCode/Application/Tools/WellPathTools/RiaArcCurveCalculator.cpp new file mode 100644 index 0000000000..6f0c9e74b6 --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaArcCurveCalculator.cpp @@ -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 +// 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::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::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); +} + + diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaArcCurveCalculator.h b/ApplicationCode/Application/Tools/WellPathTools/RiaArcCurveCalculator.h new file mode 100644 index 0000000000..b05a582cd0 --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaArcCurveCalculator.h @@ -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 +// 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; +}; + + diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaJCurveCalculator.cpp b/ApplicationCode/Application/Tools/WellPathTools/RiaJCurveCalculator.cpp new file mode 100644 index 0000000000..2b8049988f --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaJCurveCalculator.cpp @@ -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 +// 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::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::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(); + +} + + diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaJCurveCalculator.h b/ApplicationCode/Application/Tools/WellPathTools/RiaJCurveCalculator.h new file mode 100644 index 0000000000..7dbfaeeaa8 --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaJCurveCalculator.h @@ -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 +// 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; +}; + + diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaLineArcWellPathCalculator.cpp b/ApplicationCode/Application/Tools/WellPathTools/RiaLineArcWellPathCalculator.cpp new file mode 100644 index 0000000000..d76a85206c --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaLineArcWellPathCalculator.cpp @@ -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 +// 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& 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::infinity(), + true, std::numeric_limits::infinity() }); + } + + return; + } + + m_targetStatuses.resize(activeWellPathTargets.size(), { false, 0.0, 0.0, + false, std::numeric_limits::infinity(), + false, std::numeric_limits::infinity() }); + + std::vector 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; +} + diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaLineArcWellPathCalculator.h b/ApplicationCode/Application/Tools/WellPathTools/RiaLineArcWellPathCalculator.h new file mode 100644 index 0000000000..4807fce197 --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaLineArcWellPathCalculator.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cvfBase.h" +#include "cvfVector3.h" + +#include + +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& 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& lineArcEndpoints() const { return m_lineArcEndpoints;} + const std::vector& targetStatuses() const { return m_targetStatuses;} + +private: + cvf::Vec3d m_startTangent; + std::vector m_lineArcEndpoints; + std::vector m_targetStatuses; +}; + diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaPolyArcLineSampler.cpp b/ApplicationCode/Application/Tools/WellPathTools/RiaPolyArcLineSampler.cpp new file mode 100644 index 0000000000..c83a6b0656 --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaPolyArcLineSampler.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaPolyArcLineSampler.h" +#include "RiaArcCurveCalculator.h" + +#include "cvfGeometryTools.h" +#include "cvfMatrix4.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaPolyArcLineSampler::RiaPolyArcLineSampler(const cvf::Vec3d& startTangent, const std::vector& 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* points, + std::vector* mds) +{ + CVF_ASSERT(sampleInterval > 0.0); + + m_samplingsInterval = sampleInterval; + m_isResamplingLines = isResamplingLines; + + double startMD = 0.0; + points->clear(); + mds->clear(); + + std::vector 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 RiaPolyArcLineSampler::pointsWithoutDuplicates(const std::vector& points) +{ + std::vector 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(); +} diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaPolyArcLineSampler.h b/ApplicationCode/Application/Tools/WellPathTools/RiaPolyArcLineSampler.h new file mode 100644 index 0000000000..0f8354dded --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaPolyArcLineSampler.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cvfBase.h" +#include "cvfVector3.h" + +#include + +class RiaPolyArcLineSampler +{ +public: + RiaPolyArcLineSampler(const cvf::Vec3d& startTangent, const std::vector& lineArcEndPoints); + + void sampledPointsAndMDs(double sampleInterval, + bool isResamplingLines, + std::vector* points, + std::vector* mds); + + static std::vector pointsWithoutDuplicates(const std::vector& 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* m_points; // Internal temporary pointers to collections beeing filled. + std::vector* m_meshDs; + + double m_samplingsInterval; + bool m_isResamplingLines; + double m_totalMD; + + cvf::Vec3d m_startTangent; + std::vector m_lineArcEndPoints; +}; diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaSCurveCalculator.cpp b/ApplicationCode/Application/Tools/WellPathTools/RiaSCurveCalculator.cpp new file mode 100644 index 0000000000..4777b432d5 --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaSCurveCalculator.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaSCurveCalculator.h" + +#include "RiaOffshoreSphericalCoords.h" + +#include "cvfMatrix4.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +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::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::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; + +} + diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaSCurveCalculator.h b/ApplicationCode/Application/Tools/WellPathTools/RiaSCurveCalculator.h new file mode 100644 index 0000000000..0b782a3f92 --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaSCurveCalculator.h @@ -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 +// 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; +}; diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaWellPlanCalculator.cpp b/ApplicationCode/Application/Tools/WellPathTools/RiaWellPlanCalculator.cpp new file mode 100644 index 0000000000..5436b432f9 --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaWellPlanCalculator.cpp @@ -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 +// 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& 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(); +} diff --git a/ApplicationCode/Application/Tools/WellPathTools/RiaWellPlanCalculator.h b/ApplicationCode/Application/Tools/WellPathTools/RiaWellPlanCalculator.h new file mode 100644 index 0000000000..e88d1b3fc4 --- /dev/null +++ b/ApplicationCode/Application/Tools/WellPathTools/RiaWellPlanCalculator.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cvfBase.h" +#include "cvfVector3.h" + +#include + +class RiaWellPlanCalculator +{ +public: + RiaWellPlanCalculator(const cvf::Vec3d& startTangent, + const std::vector& 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& 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 m_lineArcEndPoints; + + std::vector m_wpResult; + +}; + diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index 641863bcd1..1fabac1f27 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -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 diff --git a/ApplicationCode/CommandFileInterface/CMakeLists_files.cmake b/ApplicationCode/CommandFileInterface/CMakeLists_files.cmake index e7230c0ae7..7d9fe7cf0a 100644 --- a/ApplicationCode/CommandFileInterface/CMakeLists_files.cmake +++ b/ApplicationCode/CommandFileInterface/CMakeLists_files.cmake @@ -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 diff --git a/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.h b/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.h index 853076b8d2..00ab0a316d 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfCommandObject.h @@ -35,7 +35,7 @@ class RicfCommandObject : public caf::PdmObject, public RicfObjectCapability { public: RicfCommandObject(); - ~RicfCommandObject(); + ~RicfCommandObject() override; virtual void execute() = 0; }; diff --git a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp index aa696c2805..1b0e975aec 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.cpp @@ -86,3 +86,47 @@ void RicfFieldWriter::writeFieldData(const QString& fieldValue, QTextSt } outputStream << "\""; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfFieldReader::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::writeFieldData(const bool& fieldValue, QTextStream& outputStream) +{ + // Lower-case true/false is used in the documentation. + outputStream << (fieldValue ? "true" : "false"); +} diff --git a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h index d24c614574..960cd69f06 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfFieldCapability.h @@ -65,6 +65,19 @@ struct RicfFieldWriter static void writeFieldData(const QString & fieldValue, QTextStream& outputStream); }; +template <> +struct RicfFieldReader +{ + static void readFieldData(bool& fieldValue, QTextStream& inputStream, RicfMessages* errorMessageContainer); +}; + +template <> +struct RicfFieldWriter +{ + static void writeFieldData(const bool& fieldValue, QTextStream& outputStream); +}; + + template struct RicfFieldReader< caf::AppEnum > { @@ -176,7 +189,7 @@ class RicfFieldCapability : public RicfFieldHandle // 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 @@ class RicfFieldCapability : public RicfFieldHandle m_field->setValue(value); } - virtual void writeFieldData(QTextStream& outputStream) const override + void writeFieldData(QTextStream& outputStream) const override { //m_field->xmlCapability()->assertValid(); RicfFieldWriter::writeFieldData(m_field->value(), outputStream); @@ -198,7 +211,7 @@ class RicfFieldCapability : public RicfFieldHandle template void AddRicfCapabilityToField(FieldType* field) { - if(field->template capability< RicfFieldCapability >() == NULL) + if(field->template capability< RicfFieldCapability >() == nullptr) { new RicfFieldCapability(field, true); } diff --git a/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h b/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h index 9879eadace..03b9b9f565 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfFieldHandle.h @@ -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, diff --git a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp index 59dd9e200d..5d0651cbfd 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.cpp @@ -200,11 +200,12 @@ void RicfObjectCapability::writeFields(QTextStream& outputStream) const if ( writtenFieldCount >= 1 ) { outputStream << ", "; - ++writtenFieldCount; } outputStream << keyword << " = "; rcfField->writeFieldData(outputStream); + + writtenFieldCount++; } } } diff --git a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h index 8d85319d07..e64b83aed8 100644 --- a/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h +++ b/ApplicationCode/CommandFileInterface/Core/RicfObjectCapability.h @@ -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; diff --git a/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp b/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp index d10f25dbd0..49301aeed1 100644 --- a/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp +++ b/ApplicationCode/CommandFileInterface/Core/RifcCommandFileReader.cpp @@ -40,7 +40,6 @@ std::vector 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 RicfCommandFileReader::readCommands(QTextStream& //-------------------------------------------------------------------------------------------------- void RicfCommandFileReader::writeCommands(QTextStream& outputStream, const std::vector& commandsToWrite) { + for (const auto& cmdObj : commandsToWrite) + { + auto rcfCap = cmdObj->capability(); + if (!rcfCap) continue; + + outputStream << cmdObj->classKeyword(); + outputStream << "("; + rcfCap->writeFields(outputStream); + + outputStream << ")"; + } } diff --git a/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp b/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp new file mode 100644 index 0000000000..3944fe2b43 --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfApplicationTools.cpp @@ -0,0 +1,135 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicfApplicationTools.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" +#include "RiaWellNameComparer.h" + +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimProject.h" +#include "RimWellPath.h" + +#include + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// Empty wellPathNames returns all well paths +//-------------------------------------------------------------------------------------------------- +std::vector RicfApplicationTools::wellPathsFromNames(const QStringList& wellPathNames, QStringList* wellsNotFound) +{ + std::vector wellPaths; + auto allWellPaths = RiaApplication::instance()->project()->allWellPaths(); + + if (!wellPathNames.empty()) + { + std::set wellPathNameSet(wellPathNames.begin(), wellPathNames.end()); + + for (auto wellPath : allWellPaths) + { + auto matchedName = RiaWellNameComparer::tryMatchNameInList(wellPath->name(), toStringVector(wellPathNames)); + if (!matchedName.isEmpty()) + { + wellPaths.push_back(wellPath); + wellPathNameSet.erase(matchedName); + } + } + + if (wellsNotFound) + { + wellsNotFound->clear(); + if (!wellPathNameSet.empty()) + { + for (const auto& wpn : wellPathNameSet) + wellsNotFound->push_back(wpn); + } + } + } + else + { + wellPaths = allWellPaths; + } + return wellPaths; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicfApplicationTools::toStringVector(const QStringList& stringList) +{ + return std::vector(stringList.begin(), stringList.end()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RicfApplicationTools::toQStringList(const std::vector& v) +{ + QStringList stringList; + for (const auto& s : v) + { + stringList.push_back(s); + } + return stringList; +} + +//-------------------------------------------------------------------------------------------------- +/// If caseId is -1, return first case found +//-------------------------------------------------------------------------------------------------- +RimEclipseCase* RicfApplicationTools::caseFromId(int caseId) +{ + auto eclipseCases = RiaApplication::instance()->project()->eclipseCases(); + if (caseId < 0) + { + if (!eclipseCases.empty()) return eclipseCases.front(); + } + else + { + for (RimEclipseCase* c : eclipseCases) + { + if (c->caseId() == caseId) return c; + } + } + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseView* RicfApplicationTools::viewFromCaseIdAndViewName(int caseId, const QString& viewName) +{ + for (RimEclipseCase* c : RiaApplication::instance()->project()->eclipseCases()) + { + if (c->caseId() == caseId) + { + for (auto v : c->views()) + { + auto eclipseView = dynamic_cast(v); + if (eclipseView && eclipseView->name().compare(viewName, Qt::CaseInsensitive) == 0) + { + return eclipseView; + } + } + } + } + return nullptr; +} diff --git a/ApplicationCode/CommandFileInterface/RicfApplicationTools.h b/ApplicationCode/CommandFileInterface/RicfApplicationTools.h new file mode 100644 index 0000000000..182aa0d78a --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfApplicationTools.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +class RimEclipseCase; +class RimEclipseView; +class RimWellPath; +class QStringList; + +//================================================================================================== +// +// +// +//================================================================================================== +class RicfApplicationTools +{ +public: + static std::vector wellPathsFromNames(const QStringList& wellPathNames, QStringList* wellsNotFound); + static RimEclipseCase* caseFromId(int caseId); + static RimEclipseView* viewFromCaseIdAndViewName(int caseId, const QString& viewName); + + static std::vector toStringVector(const QStringList& stringList); + static QStringList toQStringList(const std::vector& v); +}; diff --git a/ApplicationCode/CommandFileInterface/RicfCloseProject.h b/ApplicationCode/CommandFileInterface/RicfCloseProject.h index 3d5cbba164..1494d13fe1 100644 --- a/ApplicationCode/CommandFileInterface/RicfCloseProject.h +++ b/ApplicationCode/CommandFileInterface/RicfCloseProject.h @@ -34,7 +34,7 @@ class RicfCloseProject : public RicfCommandObject public: RicfCloseProject(); - virtual void execute() override; + void execute() override; private: }; diff --git a/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.cpp b/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.cpp index bdef74898e..2e82cec54a 100644 --- a/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.cpp +++ b/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.cpp @@ -34,6 +34,9 @@ namespace caf { addItem(RicfCommandFileExecutor::PROPERTIES, "PROPERTIES", "Properties"); addItem(RicfCommandFileExecutor::SNAPSHOTS, "SNAPSHOTS", "Snapshots"); addItem(RicfCommandFileExecutor::STATISTICS, "STATISTICS", "Statistics"); + addItem(RicfCommandFileExecutor::WELLPATHS, "WELLPATHS", "Well Path"); + addItem(RicfCommandFileExecutor::CELLS, "CELLS", "Cells"); + addItem(RicfCommandFileExecutor::LGRS, "LGRS", "Lgrs"); setDefault(RicfCommandFileExecutor::COMPLETIONS); } } @@ -57,10 +60,13 @@ RicfCommandFileExecutor::~RicfCommandFileExecutor() //-------------------------------------------------------------------------------------------------- void RicfCommandFileExecutor::executeCommands(QTextStream& stream) { + RicfMessages messages; std::vector executableCommands; { - std::vector fileCommands = RicfCommandFileReader::readCommands(stream, caf::PdmDefaultObjectFactory::instance(), &m_messages); - for (auto message : m_messages.m_messages) + clearCachedData(); + + std::vector fileCommands = RicfCommandFileReader::readCommands(stream, caf::PdmDefaultObjectFactory::instance(), &messages); + for (auto message : messages.m_messages) { if (message.first == RicfMessages::MESSAGE_WARNING) { @@ -80,6 +86,11 @@ void RicfCommandFileExecutor::executeCommands(QTextStream& stream) } } + for (auto fileCommand : fileCommands) + { + fileCommand->initAfterReadRecursively(); + } + executableCommands = RicfCommandFileExecutor::prepareFileCommandsForExecution(fileCommands); } @@ -207,3 +218,12 @@ std::vector RicfCommandFileExecutor::prepareFileCommandsForE return executableCommands; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfCommandFileExecutor::clearCachedData() +{ + m_exportPaths.clear(); + m_lastProjectPath.clear(); +} diff --git a/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.h b/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.h index 3c38789a2c..24651576dc 100644 --- a/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.h +++ b/ApplicationCode/CommandFileInterface/RicfCommandFileExecutor.h @@ -39,7 +39,10 @@ class RicfCommandFileExecutor COMPLETIONS, SNAPSHOTS, PROPERTIES, - STATISTICS + STATISTICS, + WELLPATHS, + CELLS, + LGRS }; typedef caf::AppEnum ExportTypeEnum; @@ -59,7 +62,7 @@ class RicfCommandFileExecutor static std::vector prepareFileCommandsForExecution(const std::vector& commandsReadFromFile); private: - RicfMessages m_messages; + void clearCachedData(); std::map m_exportPaths; QString m_lastProjectPath; diff --git a/ApplicationCode/CommandFileInterface/RicfComputeCaseGroupStatistics.h b/ApplicationCode/CommandFileInterface/RicfComputeCaseGroupStatistics.h index 1e5a02ccde..70c9508dab 100644 --- a/ApplicationCode/CommandFileInterface/RicfComputeCaseGroupStatistics.h +++ b/ApplicationCode/CommandFileInterface/RicfComputeCaseGroupStatistics.h @@ -34,7 +34,7 @@ class RicfComputeCaseGroupStatistics : public RicfCommandObject public: RicfComputeCaseGroupStatistics(); - virtual void execute() override; + void execute() override; private: caf::PdmField< std::vector > m_caseIds; diff --git a/ApplicationCode/CommandFileInterface/RicfCreateLgrForCompletions.cpp b/ApplicationCode/CommandFileInterface/RicfCreateLgrForCompletions.cpp new file mode 100644 index 0000000000..101dd1ff78 --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfCreateLgrForCompletions.cpp @@ -0,0 +1,124 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicfCreateLgrForCompletions.h" + +#include "RicfCommandFileExecutor.h" +#include "RicfApplicationTools.h" + +#include "RicDeleteTemporaryLgrsFeature.h" +#include "RicCreateTemporaryLgrFeature.h" +#include "ExportCommands/RicExportLgrFeature.h" + +#include "RimDialogData.h" +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimFractureTemplate.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimWellPath.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" +#include "RiaWellNameComparer.h" + +#include "cafCmdFeatureManager.h" +#include + +CAF_PDM_SOURCE_INIT(RicfCreateLgrForCompletions, "createLgrForCompletions"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicfCreateLgrForCompletions::RicfCreateLgrForCompletions() +{ + RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); + RICF_InitField(&m_timeStep, "timeStep", 0, "Time Step Index", "", "", ""); + RICF_InitField(&m_wellPathNames, "wellPathNames", std::vector(), "Well Path Names", "", "", ""); + RICF_InitField(&m_refinementI, "refinementI", -1, "RefinementI", "", "", ""); + RICF_InitField(&m_refinementJ, "refinementJ", -1, "RefinementJ", "", "", ""); + RICF_InitField(&m_refinementK, "refinementK", -1, "RefinementK", "", "", ""); + RICF_InitField(&m_splitType, "splitType", Lgr::SplitTypeEnum(), "SplitType", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfCreateLgrForCompletions::execute() +{ + using TOOLS = RicfApplicationTools; + + std::vector wellPaths; + + // Find well paths + { + QStringList wellsNotFound; + wellPaths = TOOLS::wellPathsFromNames(TOOLS::toQStringList(m_wellPathNames), &wellsNotFound); + if (!wellsNotFound.empty()) + { + RiaLogging::error(QString("createLgrForCompletions: These well paths were not found: ") + wellsNotFound.join(", ")); + } + } + + if (!wellPaths.empty()) + { + caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance(); + auto feature = dynamic_cast(commandManager->getCommandFeature("RicCreateTemporaryLgrFeature")); + + RimEclipseCase* eclipseCase = nullptr; + { + for (RimEclipseCase* c : RiaApplication::instance()->project()->activeOilField()->analysisModels->cases()) + { + if (c->caseId() == m_caseId()) + { + eclipseCase = c; + break; + } + } + if (!eclipseCase) + { + RiaLogging::error(QString("createLgrForCompletions: Could not find case with ID %1").arg(m_caseId())); + return; + } + } + + RicDeleteTemporaryLgrsFeature::deleteAllTemporaryLgrs(eclipseCase); + + caf::VecIjk lgrCellCounts(m_refinementI, m_refinementJ, m_refinementK); + QStringList wellsIntersectingOtherLgrs; + + feature->createLgrsForWellPaths( + wellPaths, + eclipseCase, + m_timeStep, + lgrCellCounts, + m_splitType(), + {RigCompletionData::PERFORATION, RigCompletionData::FRACTURE, RigCompletionData::FISHBONES}, + &wellsIntersectingOtherLgrs); + + feature->updateViews(eclipseCase); + + if (!wellsIntersectingOtherLgrs.empty()) + { + auto wellsList = wellsIntersectingOtherLgrs.join(", "); + RiaLogging::error( + "createLgrForCompletions: No LGRs created for some wells due to existing intersecting LGR(s).Affected wells : " + + wellsList); + } + } +} diff --git a/ApplicationCode/CommandFileInterface/RicfCreateLgrForCompletions.h b/ApplicationCode/CommandFileInterface/RicfCreateLgrForCompletions.h new file mode 100644 index 0000000000..f2cb8938af --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfCreateLgrForCompletions.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicfCommandObject.h" + +#include "ExportCommands/RicLgrSplitType.h" + +#include "cafPdmField.h" +#include "cafAppEnum.h" + +class RimWellPath; + +//================================================================================================== +// +// +// +//================================================================================================== +class RicfCreateLgrForCompletions : public RicfCommandObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicfCreateLgrForCompletions(); + + void execute() override; + +private: + caf::PdmField m_caseId; + caf::PdmField m_timeStep; + caf::PdmField> m_wellPathNames; + caf::PdmField m_refinementI; + caf::PdmField m_refinementJ; + caf::PdmField m_refinementK; + caf::PdmField m_splitType; +}; diff --git a/ApplicationCode/CommandFileInterface/RicfCreateMultipleFractures.cpp b/ApplicationCode/CommandFileInterface/RicfCreateMultipleFractures.cpp new file mode 100644 index 0000000000..8e4a75bab5 --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfCreateMultipleFractures.cpp @@ -0,0 +1,173 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicfCreateMultipleFractures.h" + +#include "RicfApplicationTools.h" +#include "RicfCommandFileExecutor.h" + +#include "FractureCommands/RicCreateMultipleFracturesFeature.h" +#include "FractureCommands/RicCreateMultipleFracturesOptionItemUi.h" +#include "FractureCommands/RicCreateMultipleFracturesUi.h" + +#include "RimProject.h" +#include "RimDialogData.h" +#include "RimFractureTemplate.h" +#include "RimOilField.h" +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimWellPath.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" +#include "RiaWellNameComparer.h" + +#include "cafCmdFeatureManager.h" + + +CAF_PDM_SOURCE_INIT(RicfCreateMultipleFractures, "createMultipleFractures"); + +namespace caf +{ + template<> + void AppEnum< MultipleFractures::Action >::setUp() + { + addItem(MultipleFractures::APPEND_FRACTURES, "APPEND_FRACTURES", "Append Fractures"); + addItem(MultipleFractures::REPLACE_FRACTURES, "REPLACE_FRACTURES", "Replace Fractures"); + + setDefault(MultipleFractures::NONE); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicfCreateMultipleFractures::RicfCreateMultipleFractures() +{ + RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); + RICF_InitField(&m_wellPathNames, "wellPathNames", std::vector(), "Well Path Names", "", "", ""); + RICF_InitField(&m_minDistFromWellTd, "minDistFromWellTd", 100.0, "Min Distance From Well TD", "", "", ""); + RICF_InitField(&m_maxFracturesPerWell, "maxFracturesPerWell", 100, "Max Fractures per Well", "", "", ""); + RICF_InitField(&m_templateId, "templateId", -1, "Template ID", "", "", ""); + RICF_InitField(&m_topLayer, "topLayer", -1, "Top Layer", "", "", ""); + RICF_InitField(&m_baseLayer, "baseLayer", -1, "Base Layer", "", "", ""); + RICF_InitField(&m_spacing, "spacing", 300.0, "Spacing", "", "", ""); + RICF_InitField(&m_action, "action", caf::AppEnum(MultipleFractures::APPEND_FRACTURES), "Action", "", "", ""); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfCreateMultipleFractures::execute() +{ + using TOOLS = RicfApplicationTools; + + RimProject* project = RiaApplication::instance()->project(); + RiuCreateMultipleFractionsUi* settings = project->dialogData()->multipleFractionsData(); + + // Get case and fracture template + auto gridCase = TOOLS::caseFromId(m_caseId); + auto fractureTemplate = fractureTemplateFromId(m_templateId); + std::vector wellPaths; + + // Find well paths + { + QStringList wellsNotFound; + wellPaths = TOOLS::wellPathsFromNames(TOOLS::toQStringList(m_wellPathNames), &wellsNotFound); + if (!wellsNotFound.empty()) + { + RiaLogging::error(QString("createMultipleFractures: These well paths were not found: ") + wellsNotFound.join(", ")); + } + } + + if (!gridCase) + { + RiaLogging::error(QString("createMultipleFractures: Could not find case with ID %1").arg(m_caseId)); + } + + if (!fractureTemplate) + { + RiaLogging::error(QString("createMultipleFractures: Could not find fracture template with ID %1").arg(m_templateId)); + } + + if (gridCase && fractureTemplate && !wellPaths.empty() && validateArguments()) + { + RicCreateMultipleFracturesOptionItemUi* options = new RicCreateMultipleFracturesOptionItemUi(); + caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance(); + auto feature = dynamic_cast(commandManager->getCommandFeature("RicCreateMultipleFracturesFeature")); + + // Default layers + int topLayer = m_topLayer; + int baseLayer = m_baseLayer; + if (feature && (topLayer < 0 || baseLayer < 0)) + { + auto ijkRange = feature->ijkRangeForGrid(gridCase); + if (topLayer < 0) topLayer = static_cast(ijkRange.first.z()); + if (baseLayer < 0) baseLayer = static_cast(ijkRange.second.z()); + } + options->setValues(topLayer, baseLayer, fractureTemplate, m_spacing); + + settings->clearWellPaths(); + for (auto wellPath : wellPaths) + { + settings->addWellPath(wellPath); + } + + settings->setValues(gridCase, m_minDistFromWellTd, m_maxFracturesPerWell); + settings->clearOptions(); + settings->insertOptionItem(nullptr, options); + + + if (feature) + { + if (m_action == MultipleFractures::APPEND_FRACTURES) feature->appendFractures(); + if (m_action == MultipleFractures::REPLACE_FRACTURES) feature->replaceFractures(); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicfCreateMultipleFractures::validateArguments() const +{ + bool valid = + m_caseId >= 0 && + m_templateId >= 0; + + if (valid) return true; + + RiaLogging::error(QString("createMultipleFractures: Mandatory argument(s) missing")); + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFractureTemplate* RicfCreateMultipleFractures::fractureTemplateFromId(int templateId) const +{ + for (RimFractureTemplate* t : RiaApplication::instance()->project()->allFractureTemplates()) + { + if (t->id() == templateId) return t; + } + + RiaLogging::error(QString("createMultipleFractures: Could not find fracture template with ID %1").arg(templateId)); + return nullptr; +} diff --git a/ApplicationCode/CommandFileInterface/RicfCreateMultipleFractures.h b/ApplicationCode/CommandFileInterface/RicfCreateMultipleFractures.h new file mode 100644 index 0000000000..cc1cbf3b5d --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfCreateMultipleFractures.h @@ -0,0 +1,67 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicfCommandObject.h" + +#include "cafPdmField.h" +#include "cafAppEnum.h" + +namespace MultipleFractures +{ + enum Action + { + NONE, + APPEND_FRACTURES, + REPLACE_FRACTURES + }; +} + +class RimEclipseCase; +class RimFractureTemplate; +class RimWellPath; + +//================================================================================================== +// +// +// +//================================================================================================== +class RicfCreateMultipleFractures : public RicfCommandObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicfCreateMultipleFractures(); + + void execute() override; + +private: + bool validateArguments() const; + RimFractureTemplate* fractureTemplateFromId(int templateId) const; + + caf::PdmField m_caseId; + caf::PdmField> m_wellPathNames; + caf::PdmField m_minDistFromWellTd; + caf::PdmField m_maxFracturesPerWell; + caf::PdmField m_templateId; + caf::PdmField m_topLayer; + caf::PdmField m_baseLayer; + caf::PdmField m_spacing; + caf::PdmField> m_action; +}; diff --git a/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.cpp b/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.cpp new file mode 100644 index 0000000000..f89522f5c8 --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.cpp @@ -0,0 +1,108 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicfExportLgrForCompletions.h" + +#include "RicfApplicationTools.h" +#include "RicfCommandFileExecutor.h" + +#include "ExportCommands/RicExportLgrFeature.h" + +#include "RimProject.h" +#include "RimDialogData.h" +#include "RimFractureTemplate.h" +#include "RimOilField.h" +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimWellPath.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" +#include "RiaWellNameComparer.h" + +#include +#include "cafCmdFeatureManager.h" + + +CAF_PDM_SOURCE_INIT(RicfExportLgrForCompletions, "exportLgrForCompletions"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicfExportLgrForCompletions::RicfExportLgrForCompletions() +{ + RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); + RICF_InitField(&m_timeStep, "timeStep", -1, "Time Step Index", "", "", ""); + RICF_InitField(&m_wellPathNames, "wellPathNames", std::vector(), "Well Path Names", "", "", ""); + RICF_InitField(&m_refinementI, "refinementI", -1, "RefinementI", "", "", ""); + RICF_InitField(&m_refinementJ, "refinementJ", -1, "RefinementJ", "", "", ""); + RICF_InitField(&m_refinementK, "refinementK", -1, "RefinementK", "", "", ""); + RICF_InitField(&m_splitType, "splitType", Lgr::SplitTypeEnum(), "SplitType", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfExportLgrForCompletions::execute() +{ + using TOOLS = RicfApplicationTools; + + std::vector wellPaths; + + // Find well paths + { + QStringList wellsNotFound; + wellPaths = TOOLS::wellPathsFromNames(TOOLS::toQStringList(m_wellPathNames), &wellsNotFound); + if (!wellsNotFound.empty()) + { + RiaLogging::error(QString("exportLgrForCompletions: These well paths were not found: ") + wellsNotFound.join(", ")); + } + } + + if (!wellPaths.empty()) + { + QString exportFolder = RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::LGRS); + if (exportFolder.isNull()) + { + exportFolder = RiaApplication::instance()->createAbsolutePathFromProjectRelativePath("LGR"); + } + + caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance(); + auto feature = dynamic_cast(commandManager->getCommandFeature("RicExportLgrFeature")); + + RimEclipseCase* eclipseCase = TOOLS::caseFromId(m_caseId()); + if (!eclipseCase) + { + RiaLogging::error(QString("exportLgrForCompletions: Could not find case with ID %1").arg(m_caseId())); + return; + } + + caf::VecIjk lgrCellCounts(m_refinementI, m_refinementJ, m_refinementK); + QStringList wellsIntersectingOtherLgrs; + + feature->exportLgrsForWellPaths(exportFolder, wellPaths, eclipseCase, m_timeStep, lgrCellCounts, m_splitType(), + {RigCompletionData::PERFORATION, RigCompletionData::FRACTURE, RigCompletionData::FISHBONES}, &wellsIntersectingOtherLgrs); + + if (!wellsIntersectingOtherLgrs.empty()) + { + auto wellsList = wellsIntersectingOtherLgrs.join(", "); + RiaLogging::error("exportLgrForCompletions: No export for some wells due to existing intersecting LGR(s).Affected wells : " + wellsList); + } + } +} diff --git a/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.h b/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.h new file mode 100644 index 0000000000..b747cc16f8 --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfExportLgrForCompletions.h @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicfCommandObject.h" + +#include "ExportCommands/RicLgrSplitType.h" + +#include "cafAppEnum.h" +#include "cafPdmField.h" + +class RimWellPath; + + +//================================================================================================== +// +// +// +//================================================================================================== +class RicfExportLgrForCompletions : public RicfCommandObject +{ + CAF_PDM_HEADER_INIT; + +// typedef caf::AppEnum LgrSplitType; + +public: + RicfExportLgrForCompletions(); + + void execute() override; + +private: + caf::PdmField m_caseId; + caf::PdmField m_timeStep; + caf::PdmField> m_wellPathNames; + caf::PdmField m_refinementI; + caf::PdmField m_refinementJ; + caf::PdmField m_refinementK; + caf::PdmField m_splitType; +}; diff --git a/ApplicationCode/CommandFileInterface/RicfExportMsw.cpp b/ApplicationCode/CommandFileInterface/RicfExportMsw.cpp index 694d159006..5e83e13528 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportMsw.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportMsw.cpp @@ -18,6 +18,7 @@ #include "RicfExportMsw.h" +#include "RicfApplicationTools.h" #include "RicfCommandFileExecutor.h" #include "RiaApplication.h" @@ -50,25 +51,15 @@ RicfExportMsw::RicfExportMsw() //-------------------------------------------------------------------------------------------------- void RicfExportMsw::execute() { + using TOOLS = RicfApplicationTools; + RicCaseAndFileExportSettingsUi exportSettings; + auto eclipseCase = TOOLS::caseFromId(m_caseId()); + if (!eclipseCase) { - bool foundCase = false; - for (RimEclipseCase* c : RiaApplication::instance()->project()->activeOilField()->analysisModels->cases()) - { - if (c->caseId() == m_caseId()) - { - exportSettings.caseToApply = c; - foundCase = true; - break; - } - } - - if (!foundCase) - { - RiaLogging::error(QString("exportMsw: Could not find case with ID %1.").arg(m_caseId())); - return; - } + RiaLogging::error(QString("exportMsw: Could not find case with ID %1.").arg(m_caseId())); + return; } QString exportFolder = RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::COMPLETIONS); @@ -78,19 +69,15 @@ void RicfExportMsw::execute() } exportSettings.folder = exportFolder; - RimWellPath* wellPath = RiaApplication::instance()->project()->activeOilField()->wellPathCollection->wellPathByName(m_wellPathName); + RimWellPath* wellPath = RiaApplication::instance()->project()->wellPathByName(m_wellPathName); if (!wellPath) { RiaLogging::error(QString("exportMsw: Could not find well path with name %1").arg(m_wellPathName())); return; } - std::vector fishbonesSubs; - - for (RimFishbonesMultipleSubs* fishbones : wellPath->fishbonesCollection()->fishbonesSubs()) + if (!wellPath->fishbonesCollection()->activeFishbonesSubs().empty()) { - fishbonesSubs.push_back(fishbones); + RicExportFishbonesWellSegmentsFeature::exportWellSegments(wellPath, wellPath->fishbonesCollection()->activeFishbonesSubs(), exportSettings); } - - RicExportFishbonesWellSegmentsFeature::exportWellSegments(wellPath, fishbonesSubs, exportSettings); } diff --git a/ApplicationCode/CommandFileInterface/RicfExportMsw.h b/ApplicationCode/CommandFileInterface/RicfExportMsw.h index e9409d957a..f807440c04 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportMsw.h +++ b/ApplicationCode/CommandFileInterface/RicfExportMsw.h @@ -34,7 +34,7 @@ class RicfExportMsw : public RicfCommandObject public: RicfExportMsw(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_caseId; diff --git a/ApplicationCode/CommandFileInterface/RicfExportMultiCaseSnapshots.h b/ApplicationCode/CommandFileInterface/RicfExportMultiCaseSnapshots.h index 3052a51d2f..ce639542b7 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportMultiCaseSnapshots.h +++ b/ApplicationCode/CommandFileInterface/RicfExportMultiCaseSnapshots.h @@ -34,7 +34,7 @@ class RicfExportMultiCaseSnapshots : public RicfCommandObject public: RicfExportMultiCaseSnapshots(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_gridListFile; diff --git a/ApplicationCode/CommandFileInterface/RicfExportProperty.cpp b/ApplicationCode/CommandFileInterface/RicfExportProperty.cpp index 6b085884fa..1784a46e22 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportProperty.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportProperty.cpp @@ -1,37 +1,40 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RicfExportProperty.h" -#include "RicfCommandFileExecutor.h" - #include "RiaApplication.h" #include "RiaLogging.h" -#include "RimProject.h" -#include "RimOilField.h" -#include "RimEclipseCaseCollection.h" -#include "RimEclipseCase.h" -#include "RimEclipseView.h" -#include "RimEclipseCellColors.h" +#include "../Commands/ExportCommands/RicEclipseCellResultToFileImpl.h" +#include "RicfApplicationTools.h" +#include "RicfCommandFileExecutor.h" #include "RifEclipseInputFileTools.h" +#include "RigCaseCellResultsData.h" +#include "RigEclipseCaseData.h" +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseView.h" +#include "RimProject.h" + #include "cafUtils.h" #include @@ -39,74 +42,71 @@ CAF_PDM_SOURCE_INIT(RicfExportProperty, "exportProperty"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RicfExportProperty::RicfExportProperty() { - RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); - RICF_InitField(&m_timeStepIndex, "timeStep", -1, "Time Step Index", "", "", ""); - RICF_InitField(&m_propertyName, "property", QString(), "Property Name", "", "", ""); - RICF_InitField(&m_type, "type", caf::AppEnum(RiaDefines::DYNAMIC_NATIVE), "Property type", "", "", ""); - RICF_InitField(&m_eclipseKeyword, "eclipseKeyword", QString(), "Eclipse Keyword", "", "", ""); - RICF_InitField(&m_undefinedValue, "undefinedValue", 0.0, "Undefined Value", "", "", ""); - RICF_InitField(&m_path, "exportFile", QString(), "Export File", "", "", ""); + // clang-format off + RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); + RICF_InitField(&m_timeStepIndex, "timeStep", -1, "Time Step Index", "", "", ""); + RICF_InitField(&m_propertyName, "property", QString(), "Property Name", "", "", ""); + RICF_InitField(&m_eclipseKeyword, "eclipseKeyword", QString(), "Eclipse Keyword", "", "", ""); + RICF_InitField(&m_undefinedValue, "undefinedValue", 0.0, "Undefined Value", "", "", ""); + RICF_InitField(&m_exportFileName, "exportFile", QString(), "Export FileName", "", "", ""); + // clang-format on } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicfExportProperty::execute() { + using TOOLS = RicfApplicationTools; - RimEclipseCase* eclipseCase; + RimEclipseCase* eclipseCase = TOOLS::caseFromId(m_caseId()); { - bool foundCase = false; - for (RimEclipseCase* c : RiaApplication::instance()->project()->activeOilField()->analysisModels()->cases) - { - if (c->caseId == m_caseId) - { - eclipseCase = c; - foundCase = true; - break; - } - } - if (!foundCase) + if (!eclipseCase) { RiaLogging::error(QString("exportProperty: Could not find case with ID %1").arg(m_caseId())); return; } - } - QString filePath = m_path; - if (filePath.isNull()) - { - QDir propertiesDir(RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::PROPERTIES)); - QString fileName = QString("%1-%2").arg(eclipseCase->caseUserDescription()).arg(m_propertyName); - fileName = caf::Utils::makeValidFileBasename(fileName); - filePath = propertiesDir.filePath(fileName); + if (!eclipseCase->eclipseCaseData()) + { + if (!eclipseCase->openReserviorCase()) + { + RiaLogging::error(QString("exportProperty: Could not find eclipseCaseData with ID %1").arg(m_caseId())); + return; + } + } } - // FIXME : Select correct view? - RimEclipseView* view; - for (Rim3dView* v : eclipseCase->views()) - { - view = dynamic_cast(v); - if (view) break; - } - if (!view) + RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); + + RigCaseCellResultsData* cellResultsData = eclipseCaseData->results(RiaDefines::MATRIX_MODEL); + + size_t resultIdx = cellResultsData->findOrLoadScalarResult(m_propertyName); + if (resultIdx == cvf::UNDEFINED_SIZE_T) { - RiaLogging::error(QString("exportProperty: Could not find a view for case with ID %1").arg(m_caseId())); + RiaLogging::error(QString("exportProperty: Could not find result property : %1").arg(m_propertyName())); return; } - if (m_eclipseKeyword().isNull()) + QString filePath = m_exportFileName; + if (filePath.isNull()) { - m_eclipseKeyword = m_propertyName; + QDir propertiesDir(RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::PROPERTIES)); + QString fileName = QString("%1-%2").arg(eclipseCase->caseUserDescription()).arg(m_propertyName); + fileName = caf::Utils::makeValidFileBasename(fileName); + filePath = propertiesDir.filePath(fileName); } - view->cellResult()->setResultType(m_type()); - view->cellResult()->setResultVariable(m_propertyName()); - view->loadDataAndUpdate(); + QString eclipseKeyword = m_eclipseKeyword; + if (eclipseKeyword.isNull()) + { + eclipseKeyword = m_propertyName; + } - RifEclipseInputFileTools::writeBinaryResultToTextFile(filePath, eclipseCase->eclipseCaseData(), m_timeStepIndex, view->cellResult(), m_eclipseKeyword, m_undefinedValue); + RicEclipseCellResultToFileImpl::writePropertyToTextFile( + filePath, eclipseCase->eclipseCaseData(), m_timeStepIndex, m_propertyName, eclipseKeyword, m_undefinedValue); } diff --git a/ApplicationCode/CommandFileInterface/RicfExportProperty.h b/ApplicationCode/CommandFileInterface/RicfExportProperty.h index 40501186ad..950deec96c 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportProperty.h +++ b/ApplicationCode/CommandFileInterface/RicfExportProperty.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -22,6 +22,8 @@ #include "RicfCommandObject.h" +#include + #include "cafPdmField.h" //================================================================================================== @@ -36,14 +38,14 @@ class RicfExportProperty : public RicfCommandObject public: RicfExportProperty(); - virtual void execute() override; + void execute() override; private: - caf::PdmField m_caseId; - caf::PdmField m_timeStepIndex; - caf::PdmField m_propertyName; - caf::PdmField< caf::AppEnum > m_type; - caf::PdmField m_eclipseKeyword; - caf::PdmField m_undefinedValue; - caf::PdmField m_path; + caf::PdmField m_caseId; + caf::PdmField m_timeStepIndex; + caf::PdmField m_propertyName; + caf::PdmField> m_type; + caf::PdmField m_eclipseKeyword; + caf::PdmField m_undefinedValue; + caf::PdmField m_exportFileName; }; diff --git a/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp new file mode 100644 index 0000000000..ca82410244 --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.cpp @@ -0,0 +1,138 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicfExportProperty.h" + +#include "../Commands/ExportCommands/RicEclipseCellResultToFileImpl.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" + +#include "RicfApplicationTools.h" +#include "RicfCommandFileExecutor.h" +#include "RicfExportPropertyInViews.h" + +#include "RigResultAccessorFactory.h" + +#include "RimEclipseCase.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseView.h" +#include "RimProject.h" + +#include "cafUtils.h" + +#include + +#include + +CAF_PDM_SOURCE_INIT(RicfExportPropertyInViews, "exportPropertyInViews"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicfExportPropertyInViews::RicfExportPropertyInViews() +{ + RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); + RICF_InitField(&m_viewNames, "viewNames", std::vector(), "View Names", "", "", ""); + RICF_InitField(&m_undefinedValue, "undefinedValue", 0.0, "Undefined Value", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfExportPropertyInViews::execute() +{ + using TOOLS = RicfApplicationTools; + + RimEclipseCase* eclipseCase = TOOLS::caseFromId(m_caseId()); + if (!eclipseCase) + { + RiaLogging::error(QString("exportProperty: Could not find case with ID %1").arg(m_caseId())); + return; + } + + std::vector viewsForExport; + + for (Rim3dView* v : eclipseCase->views()) + { + RimEclipseView* view = dynamic_cast(v); + if (!view) continue; + + if (m_viewNames().empty()) + { + viewsForExport.push_back(view); + } + else + { + bool matchingName = false; + for (const auto& viewName : m_viewNames()) + { + if (view->name().compare(viewName, Qt::CaseInsensitive) == 0) + { + matchingName = true; + } + } + + if (matchingName) + { + viewsForExport.push_back(view); + } + } + } + + for (const auto& view : viewsForExport) + { + cvf::ref resultAccessor = nullptr; + { + const int mainGridIndex = 0; + + resultAccessor = RigResultAccessorFactory::createFromResultDefinition( + eclipseCase->eclipseCaseData(), mainGridIndex, view->currentTimeStep(), view->cellResult()); + } + + const QString propertyName = view->cellResult()->resultVariableUiShortName(); + + if (resultAccessor.isNull()) + { + RiaLogging::error(QString("exportProperty: Could not find property. Case ID %1, time step %2, property '%3'") + .arg(m_caseId) + .arg(view->currentTimeStep()) + .arg(propertyName)); + + continue; + } + + QDir propertiesDir(RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::PROPERTIES)); + + QString fileName = QString("%1-%2-T%3-%4") + .arg(eclipseCase->caseUserDescription()) + .arg(view->name()) + .arg(view->currentTimeStep()) + .arg(propertyName); + + fileName = caf::Utils::makeValidFileBasename(fileName); + const QString filePath = propertiesDir.filePath(fileName); + + RicEclipseCellResultToFileImpl::writeResultToTextFile(filePath, + eclipseCase->eclipseCaseData(), + resultAccessor.p(), + propertyName, + m_undefinedValue, + "exportPropertiesInViews"); + } +} diff --git a/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h new file mode 100644 index 0000000000..0d02b4f866 --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfExportPropertyInViews.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaDefines.h" + +#include "RicfCommandObject.h" + +#include "cafPdmField.h" + +#include + +#include + +//================================================================================================== +// +// +// +//================================================================================================== +class RicfExportPropertyInViews : public RicfCommandObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicfExportPropertyInViews(); + + void execute() override; + +private: + caf::PdmField m_caseId; + caf::PdmField> m_viewNames; + caf::PdmField m_undefinedValue; +}; diff --git a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp index 3310009243..f8e4cacd9d 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.cpp @@ -18,6 +18,7 @@ #include "RicfExportSimWellFractureCompletions.h" +#include "RicfApplicationTools.h" #include "RicfCommandFileExecutor.h" #include "RiaApplication.h" @@ -57,6 +58,8 @@ RicfExportSimWellFractureCompletions::RicfExportSimWellFractureCompletions() //-------------------------------------------------------------------------------------------------- void RicfExportSimWellFractureCompletions::execute() { + using TOOLS = RicfApplicationTools; + RimProject* project = RiaApplication::instance()->project(); RicExportCompletionDataSettingsUi* exportSettings = project->dialogData()->exportCompletionData(); @@ -65,21 +68,13 @@ void RicfExportSimWellFractureCompletions::execute() exportSettings->compdatExport = m_compdatExport; { - bool foundCase = false; - for (RimEclipseCase* c : RiaApplication::instance()->project()->activeOilField()->analysisModels->cases()) - { - if (c->caseId() == m_caseId()) - { - exportSettings->caseToApply = c; - foundCase = true; - break; - } - } - if (!foundCase) + auto eclipseCase = TOOLS::caseFromId(m_caseId()); + if (!eclipseCase) { RiaLogging::error(QString("exportSimWellCompletions: Could not find case with ID %1").arg(m_caseId())); return; } + exportSettings->caseToApply = eclipseCase; } QString exportFolder = RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::COMPLETIONS); diff --git a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h index 98bfb9fb0d..b98e4d3e71 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h +++ b/ApplicationCode/CommandFileInterface/RicfExportSimWellFractureCompletions.h @@ -37,7 +37,7 @@ class RicfExportSimWellFractureCompletions : public RicfCommandObject public: RicfExportSimWellFractureCompletions(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_caseId; diff --git a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp index 27c59aecd5..633bc85a49 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -31,27 +31,29 @@ CAF_PDM_SOURCE_INIT(RicfExportSnapshots, "exportSnapshots"); -namespace caf { - template<> - void RicfExportSnapshots::SnapshotsTypeEnum::setUp() - { - addItem(RicfExportSnapshots::ALL, "ALL", "All"); - addItem(RicfExportSnapshots::VIEWS, "VIEWS", "Views"); - addItem(RicfExportSnapshots::PLOTS, "PLOTS", "Plots"); - setDefault(RicfExportSnapshots::ALL); - } +namespace caf +{ +template<> +void RicfExportSnapshots::SnapshotsTypeEnum::setUp() +{ + addItem(RicfExportSnapshots::ALL, "ALL", "All"); + addItem(RicfExportSnapshots::VIEWS, "VIEWS", "Views"); + addItem(RicfExportSnapshots::PLOTS, "PLOTS", "Plots"); + setDefault(RicfExportSnapshots::ALL); } +} // namespace caf //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RicfExportSnapshots::RicfExportSnapshots() { - RICF_InitField(&m_type, "type", RicfExportSnapshots::SnapshotsTypeEnum(), "Type", "", "", ""); + RICF_InitField(&m_type, "type", RicfExportSnapshots::SnapshotsTypeEnum(), "Type", "", "", ""); + RICF_InitField(&m_prefix, "prefix", QString(), "Prefix", "", "", ""); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicfExportSnapshots::execute() { @@ -67,11 +69,11 @@ void RicfExportSnapshots::execute() } if (m_type == RicfExportSnapshots::VIEWS || m_type == RicfExportSnapshots::ALL) { - RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(absolutePathToSnapshotDir); + RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(absolutePathToSnapshotDir, m_prefix); } if (m_type == RicfExportSnapshots::PLOTS || m_type == RicfExportSnapshots::ALL) { - RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(absolutePathToSnapshotDir); + RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(absolutePathToSnapshotDir, m_prefix); } mainWnd->loadWinGeoAndDockToolBarLayout(); diff --git a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h index c7ea01e8cc..fcfac350f7 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h +++ b/ApplicationCode/CommandFileInterface/RicfExportSnapshots.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -44,8 +44,9 @@ class RicfExportSnapshots : public RicfCommandObject public: RicfExportSnapshots(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_type; -}; \ No newline at end of file + caf::PdmField m_prefix; +}; diff --git a/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp new file mode 100644 index 0000000000..ecd1d4c6de --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.cpp @@ -0,0 +1,122 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicfExportVisibleCells.h" + +#include "RiaFilePathTools.h" +#include "RiaViewRedrawScheduler.h" + +#include "ExportCommands/RicSaveEclipseInputVisibleCellsFeature.h" +#include "ExportCommands/RicSaveEclipseInputVisibleCellsUi.h" +#include "RicfApplicationTools.h" +#include "RicfCommandFileExecutor.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" + +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseView.h" +#include "RimOilField.h" +#include "RimProject.h" + +#include "RifEclipseInputFileTools.h" + +#include + +#include + +#include + +CAF_PDM_SOURCE_INIT(RicfExportVisibleCells, "exportVisibleCells"); + +namespace caf +{ +template<> +void AppEnum::setUp() +{ + addItem(RicfExportVisibleCells::FLUXNUM, "FLUXNUM", "FLUXNUM"); + addItem(RicfExportVisibleCells::MULTNUM, "MULTNUM", "MULTNUM"); + + setDefault(RicfExportVisibleCells::FLUXNUM); +} +} // namespace caf + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicfExportVisibleCells::RicfExportVisibleCells() +{ + RICF_InitField(&m_caseId, "caseId", -1, "Case ID", "", "", ""); + RICF_InitField(&m_viewName, "viewName", QString(), "View Name", "", "", ""); + RICF_InitField( + &m_exportKeyword, "exportKeyword", caf::AppEnum(), "Export Keyword", "", "", ""); + RICF_InitField(&m_visibleActiveCellsValue, "visibleActiveCellsValue", 1, "Visible Active Cells Value", "", "", ""); + RICF_InitField(&m_hiddenActiveCellsValue, "hiddenActiveCellsValue", 0, "Hidden Active Cells Value", "", "", ""); + RICF_InitField(&m_inactiveCellsValue, "inactiveCellsValue", 0, "Inactive Cells Value", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfExportVisibleCells::execute() +{ + if (m_caseId < 0 || m_viewName().isEmpty()) + { + RiaLogging::error("exportVisibleCells: CaseId or view name not specified"); + return; + } + + auto eclipseView = RicfApplicationTools::viewFromCaseIdAndViewName(m_caseId, m_viewName); + if (!eclipseView) + { + RiaLogging::error(QString("exportVisibleCells: Could not find view '%1' in case ID %2").arg(m_viewName).arg(m_caseId)); + return; + } + + QString exportFolder = RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::CELLS); + if (exportFolder.isNull()) + { + exportFolder = RiaApplication::instance()->createAbsolutePathFromProjectRelativePath("visibleCells"); + } + + RiaViewRedrawScheduler::instance()->clearViewsScheduledForUpdate(); + + RicSaveEclipseInputVisibleCellsUi exportSettings; + buildExportSettings(exportFolder, &exportSettings); + RicSaveEclipseInputVisibleCellsFeature::executeCommand(eclipseView, exportSettings, "exportVisibleCells"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfExportVisibleCells::buildExportSettings(const QString& exportFolder, RicSaveEclipseInputVisibleCellsUi* exportSettings) +{ + QDir baseDir(exportFolder); + exportSettings->exportFilename = baseDir.absoluteFilePath(QString("%1.grdecl").arg(m_exportKeyword().text())); + + if (m_exportKeyword == ExportKeyword::FLUXNUM) + exportSettings->exportKeyword = RicSaveEclipseInputVisibleCellsUi::FLUXNUM; + else if (m_exportKeyword == ExportKeyword::MULTNUM) + exportSettings->exportKeyword = RicSaveEclipseInputVisibleCellsUi::MULTNUM; + + exportSettings->visibleActiveCellsValue = m_visibleActiveCellsValue; + exportSettings->hiddenActiveCellsValue = m_hiddenActiveCellsValue; + exportSettings->inactiveCellsValue = m_inactiveCellsValue; +} diff --git a/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h new file mode 100644 index 0000000000..e5bb4986e9 --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfExportVisibleCells.h @@ -0,0 +1,59 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaDefines.h" + +#include "RicfCommandObject.h" + +#include "cafPdmField.h" + +class RimEclipseView; +class RicSaveEclipseInputVisibleCellsUi; + +//================================================================================================== +// +// +// +//================================================================================================== +class RicfExportVisibleCells : public RicfCommandObject +{ + CAF_PDM_HEADER_INIT; + + enum ExportKeyword + { + FLUXNUM, + MULTNUM + }; + +public: + RicfExportVisibleCells(); + + void execute() override; + +private: + void buildExportSettings(const QString& exportFolder, RicSaveEclipseInputVisibleCellsUi* exportSettings); + + caf::PdmField m_caseId; + caf::PdmField m_viewName; + caf::PdmField> m_exportKeyword; + caf::PdmField m_visibleActiveCellsValue; + caf::PdmField m_hiddenActiveCellsValue; + caf::PdmField m_inactiveCellsValue; +}; diff --git a/ApplicationCode/CommandFileInterface/RicfExportWellPathCompletions.cpp b/ApplicationCode/CommandFileInterface/RicfExportWellPathCompletions.cpp index a99148a1d7..dd55cdc43d 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportWellPathCompletions.cpp +++ b/ApplicationCode/CommandFileInterface/RicfExportWellPathCompletions.cpp @@ -18,6 +18,7 @@ #include "RicfExportWellPathCompletions.h" +#include "RicfApplicationTools.h" #include "RicfCommandFileExecutor.h" #include "RiaApplication.h" @@ -54,6 +55,11 @@ RicfExportWellPathCompletions::RicfExportWellPathCompletions() RICF_InitField(&m_includeFractures, "includeFractures", true, "Include Fractures", "", "", ""); RICF_InitField(&m_excludeMainBoreForFishbones, "excludeMainBoreForFishbones", false, "Exclude Main Bore for Fishbones", "", "", ""); + + RICF_InitField(&m_performTransScaling, "performTransScaling", false, "Perform Transmissibility Scaling", "", "", ""); + RICF_InitField(&m_transScalingTimeStep, "transScalingTimeStep", 0, "Transmissibility Scaling Pressure Time Step", "", "", ""); + RICF_InitField(&m_transScalingInitialWBHP, "transScalingWBHPFromSummary", RicExportCompletionDataSettingsUi::TransScalingWBHPSource(), "Transmissibility Scaling WBHP from summary", "", "", ""); + RICF_InitField(&m_transScalingWBHP, "transScalingWBHP", 200.0, "Transmissibility Scaling Constant WBHP Value", "", "", ""); } //-------------------------------------------------------------------------------------------------- @@ -61,6 +67,8 @@ RicfExportWellPathCompletions::RicfExportWellPathCompletions() //-------------------------------------------------------------------------------------------------- void RicfExportWellPathCompletions::execute() { + using TOOLS = RicfApplicationTools; + RimProject* project = RiaApplication::instance()->project(); RicExportCompletionDataSettingsUi* exportSettings = project->dialogData()->exportCompletionData(); @@ -76,6 +84,11 @@ void RicfExportWellPathCompletions::execute() exportSettings->fileSplit = m_fileSplit; exportSettings->compdatExport = m_compdatExport; + exportSettings->performTransScaling = m_performTransScaling; + exportSettings->transScalingTimeStep = m_transScalingTimeStep; + exportSettings->transScalingWBHPSource = m_transScalingInitialWBHP; + exportSettings->transScalingWBHP = m_transScalingWBHP; + exportSettings->useLateralNTG = m_useLateralNTG; exportSettings->includePerforations = m_includePerforations; exportSettings->includeFishbones = m_includeFishbones; @@ -85,21 +98,13 @@ void RicfExportWellPathCompletions::execute() exportSettings->setCombinationMode(m_combinationMode()); { - bool foundCase = false; - for (RimEclipseCase* c : RiaApplication::instance()->project()->activeOilField()->analysisModels->cases()) - { - if (c->caseId() == m_caseId()) - { - exportSettings->caseToApply = c; - foundCase = true; - break; - } - } - if (!foundCase) + auto eclipseCase = TOOLS::caseFromId(m_caseId()); + if (!eclipseCase) { RiaLogging::error(QString("exportWellPathCompletions: Could not find case with ID %1").arg(m_caseId())); return; } + exportSettings->caseToApply = eclipseCase; } QString exportFolder = RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::COMPLETIONS); diff --git a/ApplicationCode/CommandFileInterface/RicfExportWellPathCompletions.h b/ApplicationCode/CommandFileInterface/RicfExportWellPathCompletions.h index f7d5d57d3c..1d8e9128d1 100644 --- a/ApplicationCode/CommandFileInterface/RicfExportWellPathCompletions.h +++ b/ApplicationCode/CommandFileInterface/RicfExportWellPathCompletions.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -37,21 +37,25 @@ class RicfExportWellPathCompletions : public RicfCommandObject public: RicfExportWellPathCompletions(); - virtual void execute() override; + void execute() override; private: + caf::PdmField m_caseId; + caf::PdmField m_timeStep; + caf::PdmField> m_wellPathNames; - caf::PdmField m_caseId; - caf::PdmField m_timeStep; - caf::PdmField< std::vector > m_wellPathNames; - - caf::PdmField m_fileSplit; - caf::PdmField m_compdatExport; + caf::PdmField m_fileSplit; + caf::PdmField m_compdatExport; caf::PdmField m_combinationMode; - - caf::PdmField m_useLateralNTG; - caf::PdmField m_includePerforations; - caf::PdmField m_includeFishbones; - caf::PdmField m_includeFractures; - caf::PdmField m_excludeMainBoreForFishbones; + + caf::PdmField m_performTransScaling; + caf::PdmField m_transScalingTimeStep; + caf::PdmField m_transScalingInitialWBHP; + caf::PdmField m_transScalingWBHP; + + caf::PdmField m_useLateralNTG; + caf::PdmField m_includePerforations; + caf::PdmField m_includeFishbones; + caf::PdmField m_includeFractures; + caf::PdmField m_excludeMainBoreForFishbones; }; diff --git a/ApplicationCode/CommandFileInterface/RicfExportWellPaths.cpp b/ApplicationCode/CommandFileInterface/RicfExportWellPaths.cpp new file mode 100644 index 0000000000..59f630c3a1 --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfExportWellPaths.cpp @@ -0,0 +1,90 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicfExportWellPaths.h" + +#include "RicfCommandFileExecutor.h" +#include "RicfApplicationTools.h" + +#include "ExportCommands/RicExportSelectedWellPathsFeature.h" + +#include "RimProject.h" +#include "RimDialogData.h" +#include "RimFractureTemplate.h" +#include "RimOilField.h" +#include "RimEclipseCase.h" +#include "RimEclipseCaseCollection.h" +#include "RimWellPath.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" +#include "RiaWellNameComparer.h" + +#include "cafCmdFeatureManager.h" + + +CAF_PDM_SOURCE_INIT(RicfExportWellPaths, "exportWellPaths"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicfExportWellPaths::RicfExportWellPaths() +{ + RICF_InitField(&m_wellPathNames, "wellPathNames", std::vector(), "Well Path Names", "", "", ""); + RICF_InitField(&m_mdStepSize, "mdStepSize", 5.0, "MD Step Size", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfExportWellPaths::execute() +{ + using TOOLS = RicfApplicationTools; + + std::vector wellPaths; + + // Find well paths + { + QStringList wellsNotFound; + wellPaths = TOOLS::wellPathsFromNames(TOOLS::toQStringList(m_wellPathNames), &wellsNotFound); + if (!wellsNotFound.empty()) + { + RiaLogging::error(QString("exportWellPaths: These well paths were not found: ") + wellsNotFound.join(", ")); + } + } + + if (!wellPaths.empty()) + { + QString exportFolder = RicfCommandFileExecutor::instance()->getExportPath(RicfCommandFileExecutor::WELLPATHS); + if (exportFolder.isNull()) + { + exportFolder = RiaApplication::instance()->createAbsolutePathFromProjectRelativePath("wellpaths"); + } + + caf::CmdFeatureManager* commandManager = caf::CmdFeatureManager::instance(); + auto feature = dynamic_cast(commandManager->getCommandFeature("RicExportSelectedWellPathsFeature")); + + for (const auto wellPath : wellPaths) + { + if (wellPath) + { + feature->exportWellPath(wellPath, m_mdStepSize, exportFolder, false); + } + } + } +} diff --git a/ApplicationCode/CommandFileInterface/RicfExportWellPaths.h b/ApplicationCode/CommandFileInterface/RicfExportWellPaths.h new file mode 100644 index 0000000000..6c1ee4dc5c --- /dev/null +++ b/ApplicationCode/CommandFileInterface/RicfExportWellPaths.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicfCommandObject.h" + +#include "cafPdmField.h" +#include "cafAppEnum.h" + +class RimWellPath; + +//================================================================================================== +// +// +// +//================================================================================================== +class RicfExportWellPaths : public RicfCommandObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicfExportWellPaths(); + + void execute() override; + +private: + caf::PdmField> m_wellPathNames; + caf::PdmField m_mdStepSize; +}; diff --git a/ApplicationCode/CommandFileInterface/RicfLoadCase.h b/ApplicationCode/CommandFileInterface/RicfLoadCase.h index 1142d92f44..34dfa3fd1c 100644 --- a/ApplicationCode/CommandFileInterface/RicfLoadCase.h +++ b/ApplicationCode/CommandFileInterface/RicfLoadCase.h @@ -34,7 +34,7 @@ class RicfLoadCase : public RicfCommandObject public: RicfLoadCase(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_path; diff --git a/ApplicationCode/CommandFileInterface/RicfOpenProject.cpp b/ApplicationCode/CommandFileInterface/RicfOpenProject.cpp index 166963a44b..2a0d3461fe 100644 --- a/ApplicationCode/CommandFileInterface/RicfOpenProject.cpp +++ b/ApplicationCode/CommandFileInterface/RicfOpenProject.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -22,11 +22,12 @@ #include "RiaApplication.h" #include "RiaLogging.h" +#include "RiaRegressionTestRunner.h" CAF_PDM_SOURCE_INIT(RicfOpenProject, "openProject"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RicfOpenProject::RicfOpenProject() { @@ -34,7 +35,7 @@ RicfOpenProject::RicfOpenProject() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicfOpenProject::execute() { @@ -45,5 +46,10 @@ void RicfOpenProject::execute() return; } + if (RiaRegressionTestRunner::instance()->isRunningRegressionTests()) + { + RiaRegressionTestRunner::regressionTestConfigureProject(); + } + RicfCommandFileExecutor::instance()->setLastProjectPath(m_path); } diff --git a/ApplicationCode/CommandFileInterface/RicfOpenProject.h b/ApplicationCode/CommandFileInterface/RicfOpenProject.h index ec253679a2..4584818fbd 100644 --- a/ApplicationCode/CommandFileInterface/RicfOpenProject.h +++ b/ApplicationCode/CommandFileInterface/RicfOpenProject.h @@ -34,7 +34,7 @@ class RicfOpenProject : public RicfCommandObject public: RicfOpenProject(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_path; diff --git a/ApplicationCode/CommandFileInterface/RicfReplaceCase.h b/ApplicationCode/CommandFileInterface/RicfReplaceCase.h index 031a241b6b..791ece466d 100644 --- a/ApplicationCode/CommandFileInterface/RicfReplaceCase.h +++ b/ApplicationCode/CommandFileInterface/RicfReplaceCase.h @@ -40,7 +40,7 @@ class RicfSingleCaseReplace : public RicfCommandObject int caseId() const; QString filePath() const; - virtual void execute() override; + void execute() override; private: caf::PdmField m_newGridFile; @@ -63,7 +63,7 @@ class RicfMultiCaseReplace : public RicfCommandObject void setCaseReplacePairs(const std::map& caseIdToGridFileNameMap); - virtual void execute() override; + void execute() override; private: std::map m_caseIdToGridFileNameMap; diff --git a/ApplicationCode/CommandFileInterface/RicfReplaceSourceCases.h b/ApplicationCode/CommandFileInterface/RicfReplaceSourceCases.h index 9389c1c135..f4d4cf6d6b 100644 --- a/ApplicationCode/CommandFileInterface/RicfReplaceSourceCases.h +++ b/ApplicationCode/CommandFileInterface/RicfReplaceSourceCases.h @@ -34,7 +34,7 @@ class RicfReplaceSourceCases : public RicfCommandObject public: RicfReplaceSourceCases(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_gridListFile; diff --git a/ApplicationCode/CommandFileInterface/RicfRunOctaveScript.h b/ApplicationCode/CommandFileInterface/RicfRunOctaveScript.h index 458d57facc..54d1fba458 100644 --- a/ApplicationCode/CommandFileInterface/RicfRunOctaveScript.h +++ b/ApplicationCode/CommandFileInterface/RicfRunOctaveScript.h @@ -34,7 +34,7 @@ class RicfRunOctaveScript : public RicfCommandObject public: RicfRunOctaveScript(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_path; diff --git a/ApplicationCode/CommandFileInterface/RicfScaleFractureTemplate.cpp b/ApplicationCode/CommandFileInterface/RicfScaleFractureTemplate.cpp index ac79a28717..82e3ef6c9a 100644 --- a/ApplicationCode/CommandFileInterface/RicfScaleFractureTemplate.cpp +++ b/ApplicationCode/CommandFileInterface/RicfScaleFractureTemplate.cpp @@ -2,17 +2,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -22,26 +22,32 @@ #include "RiaApplication.h" #include "RiaLogging.h" -#include "RimProject.h" #include "RimFractureTemplate.h" #include "RimFractureTemplateCollection.h" +#include "RimProject.h" CAF_PDM_SOURCE_INIT(RicfScaleFractureTemplate, "scaleFractureTemplate"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RicfScaleFractureTemplate::RicfScaleFractureTemplate() { - RICF_InitField(&m_id, "id", -1, "Id", "", "", ""); - RICF_InitField(&m_widthScaleFactor, "width", 1.0, "WidthScaleFactor", "", "", ""); - RICF_InitField(&m_heightScaleFactor, "height", 1.0, "HeightScaleFactor", "", "", ""); - RICF_InitField(&m_dFactorScaleFactor, "dFactor", 1.0, "DFactorScaleFactor", "", "", ""); + // clang-format off + + RICF_InitField(&m_id, "id", -1, "Id", "", "", ""); + RICF_InitField(&m_halfLengthScaleFactor, "halfLength", 1.0, "HalfLengthScaleFactor", "", "", ""); + RICF_InitField(&m_heightScaleFactor, "height", 1.0, "HeightScaleFactor", "", "", ""); + RICF_InitField(&m_dFactorScaleFactor, "dFactor", 1.0, "DFactorScaleFactor", "", "", ""); RICF_InitField(&m_conductivityScaleFactor, "conductivity", 1.0, "ConductivityScaleFactor", "", "", ""); + + RICF_InitField(&m_OBSOLETE_widthScaleFactor, "width", 1.0, "WidthScaleFactor", "", "", ""); + + // clang-format on } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicfScaleFractureTemplate::execute() { @@ -59,15 +65,27 @@ void RicfScaleFractureTemplate::execute() return; } - RimFractureTemplateCollection* templColl = !project->allFractureTemplateCollections().empty() ? project->allFractureTemplateCollections()[0] : nullptr; + RimFractureTemplateCollection* templColl = + !project->allFractureTemplateCollections().empty() ? project->allFractureTemplateCollections()[0] : nullptr; RimFractureTemplate* templ = templColl ? templColl->fractureTemplate(m_id) : nullptr; - + if (!templ) { RiaLogging::error(QString("scaleFractureTemplate: Fracture template not found. Id=%1").arg(m_id)); return; } - templ->setScaleFactors(m_widthScaleFactor, m_heightScaleFactor, m_dFactorScaleFactor, m_conductivityScaleFactor); - templ->reload(); + templ->setScaleFactors(m_halfLengthScaleFactor, m_heightScaleFactor, m_dFactorScaleFactor, m_conductivityScaleFactor); + templ->loadDataAndUpdateGeometryHasChanged(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicfScaleFractureTemplate::initAfterRead() +{ + if (m_OBSOLETE_widthScaleFactor != m_OBSOLETE_widthScaleFactor.defaultValue()) + { + m_halfLengthScaleFactor = m_OBSOLETE_widthScaleFactor; + } } diff --git a/ApplicationCode/CommandFileInterface/RicfScaleFractureTemplate.h b/ApplicationCode/CommandFileInterface/RicfScaleFractureTemplate.h index bb78233215..7fa09a3e64 100644 --- a/ApplicationCode/CommandFileInterface/RicfScaleFractureTemplate.h +++ b/ApplicationCode/CommandFileInterface/RicfScaleFractureTemplate.h @@ -36,12 +36,17 @@ class RicfScaleFractureTemplate : public RicfCommandObject public: RicfScaleFractureTemplate(); - virtual void execute() override; + void execute() override; + +private: + void initAfterRead() override; private: caf::PdmField m_id; - caf::PdmField m_widthScaleFactor; + caf::PdmField m_halfLengthScaleFactor; caf::PdmField m_heightScaleFactor; caf::PdmField m_dFactorScaleFactor; caf::PdmField m_conductivityScaleFactor; + + caf::PdmField m_OBSOLETE_widthScaleFactor; }; diff --git a/ApplicationCode/CommandFileInterface/RicfSetExportFolder.cpp b/ApplicationCode/CommandFileInterface/RicfSetExportFolder.cpp index 7f74c3bdaa..f285511c1b 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetExportFolder.cpp +++ b/ApplicationCode/CommandFileInterface/RicfSetExportFolder.cpp @@ -1,18 +1,17 @@ -#include "RicfSetExportFolder.h" ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -20,23 +19,44 @@ #include "RicfSetExportFolder.h" #include "RiaApplication.h" +#include "RiaLogging.h" + +#include CAF_PDM_SOURCE_INIT(RicfSetExportFolder, "setExportFolder"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RicfSetExportFolder::RicfSetExportFolder() { + // clang-format off RICF_InitField(&m_type, "type", RicfCommandFileExecutor::ExportTypeEnum(RicfCommandFileExecutor::COMPLETIONS), "Type", "", "", ""); RICF_InitField(&m_path, "path", QString(), "Path", "", "", ""); + RICF_InitField(&m_createFolder, "createFolder", false, "Create Folder", "", "", ""); + // clang-format on } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicfSetExportFolder::execute() { + if (m_createFolder) + { + QDir dir; + + if (!dir.exists(m_path)) + { + dir.mkpath(m_path); + + if (!dir.exists(m_path)) + { + RiaLogging::error("Could not create folder : " + m_path); + } + } + } + RicfCommandFileExecutor* executor = RicfCommandFileExecutor::instance(); executor->setExportPath(m_type(), m_path); } diff --git a/ApplicationCode/CommandFileInterface/RicfSetExportFolder.h b/ApplicationCode/CommandFileInterface/RicfSetExportFolder.h index a42fd51c6a..7e2a1efed9 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetExportFolder.h +++ b/ApplicationCode/CommandFileInterface/RicfSetExportFolder.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -36,9 +36,10 @@ class RicfSetExportFolder : public RicfCommandObject public: RicfSetExportFolder(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_type; caf::PdmField m_path; + caf::PdmField m_createFolder; }; diff --git a/ApplicationCode/CommandFileInterface/RicfSetFractureContainment.cpp b/ApplicationCode/CommandFileInterface/RicfSetFractureContainment.cpp index f5eaa7e81c..d9ae34a3ff 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetFractureContainment.cpp +++ b/ApplicationCode/CommandFileInterface/RicfSetFractureContainment.cpp @@ -68,5 +68,5 @@ void RicfSetFractureContainment::execute() templ->setContainmentTopKLayer(m_topLayer); templ->setContainmentBaseKLayer(m_baseLayer); - templ->reload(); + templ->loadDataAndUpdateGeometryHasChanged(); } diff --git a/ApplicationCode/CommandFileInterface/RicfSetFractureContainment.h b/ApplicationCode/CommandFileInterface/RicfSetFractureContainment.h index 238fa6e37c..1389a88819 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetFractureContainment.h +++ b/ApplicationCode/CommandFileInterface/RicfSetFractureContainment.h @@ -36,7 +36,7 @@ class RicfSetFractureContainment : public RicfCommandObject public: RicfSetFractureContainment(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_id; diff --git a/ApplicationCode/CommandFileInterface/RicfSetMainWindowSize.h b/ApplicationCode/CommandFileInterface/RicfSetMainWindowSize.h index dd4f784bc7..ddce5cd87e 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetMainWindowSize.h +++ b/ApplicationCode/CommandFileInterface/RicfSetMainWindowSize.h @@ -34,7 +34,7 @@ class RicfSetMainWindowSize : public RicfCommandObject public: RicfSetMainWindowSize(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_height; diff --git a/ApplicationCode/CommandFileInterface/RicfSetStartDir.h b/ApplicationCode/CommandFileInterface/RicfSetStartDir.h index 4e900d2bf8..91fc11a52e 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetStartDir.h +++ b/ApplicationCode/CommandFileInterface/RicfSetStartDir.h @@ -34,7 +34,7 @@ class RicfSetStartDir : public RicfCommandObject public: RicfSetStartDir(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_path; diff --git a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp index 07630d0cad..a43b4e57f7 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp +++ b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.cpp @@ -43,7 +43,7 @@ RicfSetTimeStep::RicfSetTimeStep() //-------------------------------------------------------------------------------------------------- void RicfSetTimeStep::execute() { - RimEclipseCase* eclipseCase; + RimEclipseCase* eclipseCase = nullptr; { bool foundCase = false; diff --git a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h index 0c19572e8d..51d362c237 100644 --- a/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h +++ b/ApplicationCode/CommandFileInterface/RicfSetTimeStep.h @@ -34,7 +34,7 @@ class RicfSetTimeStep : public RicfCommandObject public: RicfSetTimeStep(); - virtual void execute() override; + void execute() override; private: caf::PdmField m_caseId; diff --git a/ApplicationCode/Commands/ApplicationCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/ApplicationCommands/CMakeLists_files.cmake index a104e060e6..503c54c485 100644 --- a/ApplicationCode/Commands/ApplicationCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/ApplicationCommands/CMakeLists_files.cmake @@ -15,6 +15,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicEditPreferencesFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicShowPlotDataFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicLaunchRegressionTestsFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicRunCommandFileFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicShowMemoryCleanupDialogFeature.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -33,6 +34,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicEditPreferencesFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicShowPlotDataFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicLaunchRegressionTestsFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicRunCommandFileFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicShowMemoryCleanupDialogFeature.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/Commands/ApplicationCommands/RicCloseProjectFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicCloseProjectFeature.h index 9bd00ea0fa..d5504eb8e5 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicCloseProjectFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicCloseProjectFeature.h @@ -30,9 +30,9 @@ class RicCloseProjectFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicEditPreferencesFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicEditPreferencesFeature.h index 2bebf4a594..6b6fe56c02 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicEditPreferencesFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicEditPreferencesFeature.h @@ -30,9 +30,9 @@ class RicEditPreferencesFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicExitApplicationFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicExitApplicationFeature.h index 1649301784..fa2c7405bd 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicExitApplicationFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicExitApplicationFeature.h @@ -30,9 +30,9 @@ class RicExitApplicationFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp b/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp index 4dfa6058f8..728e9a9bd0 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp +++ b/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.cpp @@ -88,6 +88,32 @@ void RicHelpAboutFeature::onActionTriggered(bool isChecked) dlg.addVersionEntry(" ", QString(" ") + caf::AboutDialog::versionStringForcurrentOpenGLContext()); dlg.addVersionEntry(" ", caf::Viewer::isShadersSupported() ? " Hardware OpenGL" : " Software OpenGL"); + if (RiaApplication::enableDevelopmentFeatures()) + { + QString vendor("Unknown"); + QString render("Unknown"); + + { + char* str = (char*)glGetString(GL_VENDOR); + + if (str) + { + vendor = str; + } + } + + { + char* str = (char*)glGetString(GL_RENDERER); + + if (str) + { + render = str; + } + } + + dlg.addVersionEntry(" ", QString(" ") + vendor + " : " + render); + } + dlg.create(); dlg.resize(300, 200); diff --git a/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.h b/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.h index c2e794c337..e152c2ec3a 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicHelpFeatures.h @@ -30,9 +30,9 @@ class RicHelpAboutFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; @@ -45,9 +45,9 @@ class RicHelpCommandLineFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; @@ -60,9 +60,9 @@ class RicHelpOpenUsersGuideFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicLaunchUnitTestsFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicLaunchUnitTestsFeature.h index 0c411298e9..513e03547d 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicLaunchUnitTestsFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicLaunchUnitTestsFeature.h @@ -30,9 +30,9 @@ class RicLaunchUnitTestsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicOpenLastUsedFileFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicOpenLastUsedFileFeature.h index 8e2a53c160..0fd72485d2 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicOpenLastUsedFileFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicOpenLastUsedFileFeature.h @@ -30,9 +30,9 @@ class RicOpenLastUsedFileFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicOpenProjectFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicOpenProjectFeature.h index 293f1934ac..d8a67ba186 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicOpenProjectFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicOpenProjectFeature.h @@ -30,9 +30,9 @@ class RicOpenProjectFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicRunCommandFileFeature.cpp b/ApplicationCode/Commands/ApplicationCommands/RicRunCommandFileFeature.cpp index a31c104c69..eff176dbfc 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicRunCommandFileFeature.cpp +++ b/ApplicationCode/Commands/ApplicationCommands/RicRunCommandFileFeature.cpp @@ -41,7 +41,7 @@ bool RicRunCommandFileFeature::isCommandEnabled() void RicRunCommandFileFeature::onActionTriggered(bool isChecked) { RiaApplication* app = RiaApplication::instance(); - QString defaultDir = app->lastUsedDialogDirectory("COMMAND_FILE"); + QString defaultDir = app->lastUsedDialogDirectoryWithFallbackToProjectFolder("COMMAND_FILE"); QString fileName = QFileDialog::getOpenFileName(nullptr, "Open ResInsight Command File", defaultDir, "ResInsight Command File (*.txt);;All files(*.*)"); diff --git a/ApplicationCode/Commands/ApplicationCommands/RicSaveProjectAsFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicSaveProjectAsFeature.h index 94ac73c996..f97fe02ffd 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicSaveProjectAsFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicSaveProjectAsFeature.h @@ -30,9 +30,9 @@ class RicSaveProjectAsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicSaveProjectFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicSaveProjectFeature.h index f6f2aa73dd..c735e0c34c 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicSaveProjectFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicSaveProjectFeature.h @@ -30,9 +30,9 @@ class RicSaveProjectFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicShowMainWindowFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicShowMainWindowFeature.h index bfca60d00e..611ba8a3e8 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicShowMainWindowFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicShowMainWindowFeature.h @@ -30,9 +30,9 @@ class RicShowMainWindowFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.cpp b/ApplicationCode/Commands/ApplicationCommands/RicShowMemoryCleanupDialogFeature.cpp similarity index 52% rename from ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.cpp rename to ApplicationCode/Commands/ApplicationCommands/RicShowMemoryCleanupDialogFeature.cpp index 0b2c1de315..2c378f0ece 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.cpp +++ b/ApplicationCode/Commands/ApplicationCommands/RicShowMemoryCleanupDialogFeature.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2016 Statoil ASA +// Copyright (C) 2016 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 @@ -16,57 +16,50 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RicChangeDataSourceFeatureUi.h" - -#include "RimCase.h" -#include "RimOilField.h" -#include "RimProject.h" -#include "RimTools.h" -#include "RimWellPath.h" -#include "RimWellPathCollection.h" +#include "RicShowMemoryCleanupDialogFeature.h" #include "RiaApplication.h" +#include "RiaMemoryCleanup.h" +#include "RiuMainWindow.h" + +#include "cafPdmUiPropertyViewDialog.h" -CAF_PDM_SOURCE_INIT(RicChangeDataSourceFeatureUi, "ChangeDataSourceFeatureUi"); +#include +CAF_CMD_SOURCE_INIT(RicShowMemoryCleanupDialogFeature, "RicShowMemoryCleanupDialogFeature"); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicChangeDataSourceFeatureUi::RicChangeDataSourceFeatureUi() +bool RicShowMemoryCleanupDialogFeature::isCommandEnabled() { - CAF_PDM_InitObject("Change Data Source", "", "", ""); - - CAF_PDM_InitFieldNoDefault(&wellPathToApply, "CurveWellPath", "Well Path", "", "", ""); - CAF_PDM_InitFieldNoDefault(&caseToApply, "CurveCase", "Case", "", "", ""); + return true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QList RicChangeDataSourceFeatureUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +void RicShowMemoryCleanupDialogFeature::onActionTriggered(bool isChecked) { - QList options; - - if (fieldNeedingOptions == &caseToApply) + RiaMemoryCleanup memoryCleanup; + Rim3dView* view = RiaApplication::instance()->activeReservoirView(); + if (view) { - RimTools::caseOptionItems(&options); + memoryCleanup.setPropertiesFromView(view); } - else if (fieldNeedingOptions == &wellPathToApply) + + caf::PdmUiPropertyViewDialog dialog(RiuMainWindow::instance(), &memoryCleanup, "Clear Results From Memory", "", QDialogButtonBox::Close); + dialog.resize(QSize(400, 400)); + if (dialog.exec() == QDialog::Accepted) { - RimTools::wellPathOptionItems(&options); + memoryCleanup.clearSelectedResultsFromMemory(); } - - return options; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicChangeDataSourceFeatureUi::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +void RicShowMemoryCleanupDialogFeature::setupActionLook(QAction* actionToSetup) { - caf::PdmUiGroup* group = uiOrdering.addNewGroup("Apply the following for all selected curves"); - - group->add(&caseToApply); - group->add(&wellPathToApply); + actionToSetup->setText("&Memory Cleanup..."); } diff --git a/ApplicationCode/Commands/ApplicationCommands/RicShowMemoryCleanupDialogFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicShowMemoryCleanupDialogFeature.h new file mode 100644 index 0000000000..d6105374d1 --- /dev/null +++ b/ApplicationCode/Commands/ApplicationCommands/RicShowMemoryCleanupDialogFeature.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + + +//================================================================================================== +/// +//================================================================================================== +class RicShowMemoryCleanupDialogFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; + + diff --git a/ApplicationCode/Commands/ApplicationCommands/RicShowPlotDataFeature.cpp b/ApplicationCode/Commands/ApplicationCommands/RicShowPlotDataFeature.cpp index 91f523f009..9f947331c3 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicShowPlotDataFeature.cpp +++ b/ApplicationCode/Commands/ApplicationCommands/RicShowPlotDataFeature.cpp @@ -88,9 +88,16 @@ void RicShowPlotDataFeature::onActionTriggered(bool isChecked) for (RimSummaryPlot* summaryPlot : selectedSummaryPlots) { QString title = summaryPlot->description(); - QString text = summaryPlot->asciiDataForPlotExport(); - RicShowPlotDataFeature::showTextWindow(title, text); + if (summaryPlot->containsResamplableCurves()) + { + RicShowPlotDataFeature::showTabbedTextWindow(title, [summaryPlot](DateTimePeriod period) { return summaryPlot->asciiDataForPlotExport(period); }); + } + else + { + QString text = summaryPlot->asciiDataForPlotExport(); + RicShowPlotDataFeature::showTextWindow(title, text); + } } for (RimWellLogPlot* wellLogPlot : wellLogPlots) @@ -115,6 +122,26 @@ void RicShowPlotDataFeature::setupActionLook(QAction* actionToSetup) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- +void RicShowPlotDataFeature::showTabbedTextWindow(const QString& title, std::function textProvider) +{ + RiuPlotMainWindow* plotwindow = RiaApplication::instance()->mainPlotWindow(); + CVF_ASSERT(plotwindow); + + RiuShowTabbedPlotDataDialog* textWiget = new RiuShowTabbedPlotDataDialog(); + textWiget->setMinimumSize(800, 600); + + textWiget->setWindowTitle(title); + textWiget->setDescription(title); + textWiget->setTextProvider(textProvider); + + textWiget->show(); + + plotwindow->addToTemporaryWidgets(textWiget); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- void RicShowPlotDataFeature::showTextWindow(const QString& title, const QString& text) { RiuPlotMainWindow* plotwindow = RiaApplication::instance()->mainPlotWindow(); diff --git a/ApplicationCode/Commands/ApplicationCommands/RicShowPlotDataFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicShowPlotDataFeature.h index 266d7e67d5..27284bcdfd 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicShowPlotDataFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicShowPlotDataFeature.h @@ -18,9 +18,11 @@ #pragma once -#include "cafCmdFeature.h" +#include "RiaQDateTimeTools.h" +#include "cafCmdFeature.h" +#include //================================================================================================== /// @@ -31,11 +33,12 @@ class RicShowPlotDataFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; public: + static void showTabbedTextWindow(const QString& title, std::function textProvider); static void showTextWindow(const QString& title, const QString& text); }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicShowPlotWindowFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicShowPlotWindowFeature.h index 9ffea25151..c2a51de5cc 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicShowPlotWindowFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicShowPlotWindowFeature.h @@ -30,9 +30,9 @@ class RicShowPlotWindowFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ApplicationCommands/RicTileWindowsFeature.h b/ApplicationCode/Commands/ApplicationCommands/RicTileWindowsFeature.h index c1f587f7d8..b698ed32ad 100644 --- a/ApplicationCode/Commands/ApplicationCommands/RicTileWindowsFeature.h +++ b/ApplicationCode/Commands/ApplicationCommands/RicTileWindowsFeature.h @@ -31,9 +31,9 @@ class RicTileWindowsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; //================================================================================================== @@ -45,8 +45,8 @@ class RicTilePlotWindowsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered(bool isChecked); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/CMakeLists_files.cmake b/ApplicationCode/Commands/CMakeLists_files.cmake index ea1f4736cd..51078ac36c 100644 --- a/ApplicationCode/Commands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/CMakeLists_files.cmake @@ -13,6 +13,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicGeoMechPropertyFilterNewFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicGeoMechPropertyFilterNewInViewFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicGeoMechPropertyFilterNewExec.h ${CMAKE_CURRENT_LIST_DIR}/RicNewViewFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicNewContourMapViewFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicPropertyFilterNewExec.h ${CMAKE_CURRENT_LIST_DIR}/RicRangeFilterExecImpl.h ${CMAKE_CURRENT_LIST_DIR}/RicRangeFilterInsertExec.h @@ -36,6 +37,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicWellLogsImportFileFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicTogglePerspectiveViewFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseTimeStepFilterFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCaseFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCasesFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportObservedDataFeature.h @@ -44,6 +46,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RicExportFeatureImpl.h ${CMAKE_CURRENT_LIST_DIR}/RicSelectOrCreateViewFeatureImpl.h +${CMAKE_CURRENT_LIST_DIR}/RicPickEventHandler.h +${CMAKE_CURRENT_LIST_DIR}/RicContourMapPickEventHandler.h # General delete of any object in a child array field ${CMAKE_CURRENT_LIST_DIR}/RicDeleteItemExec.h @@ -69,6 +73,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RicSummaryCaseRestartDialog.h ${CMAKE_CURRENT_LIST_DIR}/RicImportEnsembleFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryGroupFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicConvertGroupToEnsembleFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicResampleDialog.h +${CMAKE_CURRENT_LIST_DIR}/RicCreateTemporaryLgrFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicDeleteTemporaryLgrsFeature.h ) @@ -86,6 +93,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicGeoMechPropertyFilterNewFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicGeoMechPropertyFilterNewInViewFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicGeoMechPropertyFilterNewExec.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewViewFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicNewContourMapViewFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicRangeFilterExecImpl.cpp ${CMAKE_CURRENT_LIST_DIR}/RicRangeFilterInsertExec.cpp ${CMAKE_CURRENT_LIST_DIR}/RicRangeFilterInsertFeature.cpp @@ -106,6 +114,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicSelectColorResult.cpp ${CMAKE_CURRENT_LIST_DIR}/RicTogglePerspectiveViewFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicImportGeoMechCaseTimeStepFilterFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCaseFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryCasesFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportObservedDataFeature.cpp @@ -114,6 +123,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RicExportFeatureImpl.cpp ${CMAKE_CURRENT_LIST_DIR}/RicSelectOrCreateViewFeatureImpl.cpp +${CMAKE_CURRENT_LIST_DIR}/RicContourMapPickEventHandler.cpp + # General delete of any object in a child array field ${CMAKE_CURRENT_LIST_DIR}/RicDeleteItemExec.cpp ${CMAKE_CURRENT_LIST_DIR}/RicDeleteItemExecData.cpp @@ -136,6 +147,9 @@ ${CMAKE_CURRENT_LIST_DIR}/RicSummaryCaseRestartDialog.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportEnsembleFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportSummaryGroupFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicConvertGroupToEnsembleFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicResampleDialog.cpp +${CMAKE_CURRENT_LIST_DIR}/RicCreateTemporaryLgrFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicDeleteTemporaryLgrsFeature.cpp ) @@ -151,6 +165,7 @@ list(APPEND QT_MOC_HEADERS ${CMAKE_CURRENT_LIST_DIR}/RicGridStatisticsDialog.h ${CMAKE_CURRENT_LIST_DIR}/RicFileHierarchyDialog.h ${CMAKE_CURRENT_LIST_DIR}/RicSummaryCaseRestartDialog.h +${CMAKE_CURRENT_LIST_DIR}/RicResampleDialog.h ) source_group( "CommandFeature" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/CompletionCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/CompletionCommands/CMakeLists_files.cmake index 85a8736fc5..066c63754f 100644 --- a/ApplicationCode/Commands/CompletionCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/CompletionCommands/CMakeLists_files.cmake @@ -6,6 +6,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewFishbonesSubsAtMeasuredDepthFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewFishbonesSubsFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewPerforationIntervalFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewPerforationIntervalAtMeasuredDepthFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicNewValveFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathImportCompletionsFileFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathImportPerforationIntervalsFeature.h ) @@ -17,6 +18,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewFishbonesSubsAtMeasuredDepthFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewFishbonesSubsFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewPerforationIntervalFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewPerforationIntervalAtMeasuredDepthFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicNewValveFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathImportCompletionsFileFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathImportPerforationIntervalsFeature.cpp ) diff --git a/ApplicationCode/Commands/CompletionCommands/RicEditPerforationCollectionFeature.h b/ApplicationCode/Commands/CompletionCommands/RicEditPerforationCollectionFeature.h index 170fa535b9..e7893d936c 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicEditPerforationCollectionFeature.h +++ b/ApplicationCode/Commands/CompletionCommands/RicEditPerforationCollectionFeature.h @@ -30,9 +30,9 @@ class RicEditPerforationCollectionFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: static RimPerforationCollection* selectedPerforationCollection(); diff --git a/ApplicationCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.cpp b/ApplicationCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.cpp index bc36f9192a..728cf62b59 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.cpp +++ b/ApplicationCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.cpp @@ -21,6 +21,11 @@ #include "RiaApplication.h" #include "RiaLogging.h" +#include "ExportCommands/RicExportSelectedWellPathsFeature.h" +#include "ExportCommands/RicExportWellPathsUi.h" + +#include "RigWellPath.h" + #include "RimFishbonesCollection.h" #include "RimFishbonesMultipleSubs.h" #include "RimWellPath.h" @@ -31,7 +36,6 @@ #include "cvfAssert.h" #include -#include CAF_CMD_SOURCE_INIT(RicExportFishbonesLateralsFeature, "RicExportFishbonesLateralsFeature"); @@ -40,6 +44,8 @@ CAF_CMD_SOURCE_INIT(RicExportFishbonesLateralsFeature, "RicExportFishbonesLatera //-------------------------------------------------------------------------------------------------- void RicExportFishbonesLateralsFeature::onActionTriggered(bool isChecked) { + using EXP = RicExportSelectedWellPathsFeature; + RimFishbonesCollection* fishbonesCollection = selectedFishbonesCollection(); CVF_ASSERT(fishbonesCollection); @@ -48,81 +54,62 @@ void RicExportFishbonesLateralsFeature::onActionTriggered(bool isChecked) CVF_ASSERT(wellPath); RiaApplication* app = RiaApplication::instance(); - QString projectFolder = app->currentProjectPath(); - - QString defaultDir = app->lastUsedDialogDirectoryWithFallback("WELL_PATH_EXPORT_DIR", projectFolder); - QString defaultFileName = defaultDir + "/" + caf::Utils::makeValidFileBasename((wellPath->name())) + "_laterals.dev"; - QString completeFilename = QFileDialog::getSaveFileName(nullptr, "Select File for Well Path Data Export", defaultFileName, "Well Path Text File(*.dev);;All files(*.*)"); - if (completeFilename.isEmpty()) return; + QString defaultDir = app->lastUsedDialogDirectoryWithFallbackToProjectFolder("WELL_PATH_EXPORT_DIR"); + auto fileName = caf::Utils::makeValidFileBasename(wellPath->name()) + "_laterals.dev"; - RiaLogging::info("Starting export of Fishbones well path laterals to : " + completeFilename); - - QFile exportFile(completeFilename); - if (!exportFile.open(QIODevice::WriteOnly)) + auto dialogData = EXP::openDialog(); + if (dialogData) { - RiaLogging::error("Could not open the file :\n" + completeFilename); - return; - } - - - // See RifWellPathAsciiFileReader::readAllWellData for reading of dev files - // - // http://resinsight.org/docs/wellpaths/ - // Export format - // - // WELLNAME: __Sub_Lat - // - // for each coordinate along lateral, export - // x y TVD MD - // separate laterals using -999 on a single line - - QTextStream stream(&exportFile); - for (RimFishbonesMultipleSubs* fishbone : fishbonesCollection->fishbonesSubs()) - { - if (!fishbone->isActive()) continue; + auto folder = dialogData->exportFolder(); + auto mdStepSize = dialogData->mdStepSize(); + if (folder.isEmpty()) + { + return; + } - const QString fishboneName = fishbone->generatedName(); + auto exportFile = EXP::openFileForExport(folder, fileName); + auto stream = EXP::createOutputFileStream(*exportFile); - for (auto& sub : fishbone->installedLateralIndices()) + for (RimFishbonesMultipleSubs* fishbone : wellPath->fishbonesCollection()->activeFishbonesSubs()) { - for (size_t lateralIndex : sub.lateralIndices) + const QString fishboneName = fishbone->generatedName(); + + for (auto& sub : fishbone->installedLateralIndices()) { - std::vector> coordsAndMD = fishbone->coordsAndMDForLateral(sub.subIndex, lateralIndex); - - // Pad with "0" to get a total of two characters defining the sub index text - QString subIndexText = QString("%1").arg(sub.subIndex, 2, 10, QChar('0')); + for (size_t lateralIndex : sub.lateralIndices) + { + std::vector> coordsAndMD = fishbone->coordsAndMDForLateral(sub.subIndex, lateralIndex); + + std::vector lateralCoords; + std::vector lateralMDs; - QString lateralNameCandidate = QString("%1_%2_Sub%3_Lat%4").arg(wellPath->name()).arg(fishboneName).arg(subIndexText).arg(lateralIndex); - QString lateralName = caf::Utils::makeValidFileBasename(lateralNameCandidate); + lateralCoords.reserve(coordsAndMD.size()); + lateralMDs.reserve(coordsAndMD.size()); - stream << "WELLNAME: " << lateralName << endl; + for (auto& coordMD : coordsAndMD) + { + lateralCoords.push_back(coordMD.first); + lateralMDs.push_back(coordMD.second); + } - for (auto coordMD : coordsAndMD) - { - int numberOfDecimals = 2; + RigWellPath geometry; + geometry.m_wellPathPoints = lateralCoords; + geometry.m_measuredDepths = lateralMDs; - // Export X and Y unchanged, invert sign of Z to get TVD, export MD unchanged - stream << formatNumber(coordMD.first.x(), numberOfDecimals); - stream << " " << formatNumber(coordMD.first.y(), numberOfDecimals); - stream << " " << formatNumber(-coordMD.first.z(), numberOfDecimals); - stream << " " << formatNumber(coordMD.second, numberOfDecimals) << endl; + // Pad with "0" to get a total of two characters defining the sub index text + QString subIndexText = QString("%1").arg(sub.subIndex, 2, 10, QChar('0')); + QString lateralName = QString("%1_%2_Sub%3_Lat%4").arg(wellPath->name()).arg(fishboneName).arg(subIndexText).arg(lateralIndex); + + EXP::writeWellPathGeometryToStream(*stream, wellPath, lateralName, mdStepSize); } - stream << -999 << endl << endl; - } } - } - RiaLogging::info("Completed export of Fishbones well path laterals to : " + completeFilename); -} + exportFile->close(); + } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RicExportFishbonesLateralsFeature::formatNumber(double val, int numberOfDecimals) -{ - return QString("%1").arg(val, 0, 'f', numberOfDecimals); + RiaLogging::info("Completed export of Fishbones well path laterals to : " + fileName); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.h b/ApplicationCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.h index 8422c11694..ad88f1475f 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.h +++ b/ApplicationCode/Commands/CompletionCommands/RicExportFishbonesLateralsFeature.h @@ -18,9 +18,22 @@ #pragma once +#include + #include "cafCmdFeature.h" +#include + class RimFishbonesCollection; +class RimWellPath; +class QTextStream; + +//================================================================================================== +/// +//================================================================================================== +#ifndef DOUBLE_INF +#define DOUBLE_INF std::numeric_limits::infinity() +#endif //================================================================================================== /// @@ -29,12 +42,13 @@ class RicExportFishbonesLateralsFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; + //static void exportFishboneLaterals(const RimWellPath* wellPath, QTextStream& stream, double mdStepSize); + protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; private: - static QString formatNumber(double val, int numberOfDecimals); static RimFishbonesCollection* selectedFishbonesCollection(); }; diff --git a/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.h b/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.h index dc58ed094b..6fd1805ccb 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.h +++ b/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsAtMeasuredDepthFeature.h @@ -30,9 +30,9 @@ class RicNewFishbonesSubsAtMeasuredDepthFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; private: static RiuWellPathSelectionItem* wellPathSelectionItem(); diff --git a/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.h b/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.h index a10a71bec2..aea8eb054e 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.h +++ b/ApplicationCode/Commands/CompletionCommands/RicNewFishbonesSubsFeature.h @@ -33,9 +33,9 @@ class RicNewFishbonesSubsFeature : public caf::CmdFeature static void askUserToSetUsefulScaling(RimFishbonesCollection* fishboneCollection); protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; private: static RimFishbonesCollection* selectedFishbonesCollection(); diff --git a/ApplicationCode/Commands/CompletionCommands/RicNewPerforationIntervalAtMeasuredDepthFeature.h b/ApplicationCode/Commands/CompletionCommands/RicNewPerforationIntervalAtMeasuredDepthFeature.h index ae77586bf5..4c6aaf2e75 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicNewPerforationIntervalAtMeasuredDepthFeature.h +++ b/ApplicationCode/Commands/CompletionCommands/RicNewPerforationIntervalAtMeasuredDepthFeature.h @@ -30,9 +30,9 @@ class RicNewPerforationIntervalAtMeasuredDepthFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; private: static RiuWellPathSelectionItem* wellPathSelectionItem(); diff --git a/ApplicationCode/Commands/CompletionCommands/RicNewPerforationIntervalFeature.h b/ApplicationCode/Commands/CompletionCommands/RicNewPerforationIntervalFeature.h index 162ad9c390..5a9d59cf0d 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicNewPerforationIntervalFeature.h +++ b/ApplicationCode/Commands/CompletionCommands/RicNewPerforationIntervalFeature.h @@ -32,9 +32,9 @@ class RicNewPerforationIntervalFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: RimPerforationCollection* selectedPerforationCollection(); diff --git a/ApplicationCode/Commands/CompletionCommands/RicNewValveFeature.cpp b/ApplicationCode/Commands/CompletionCommands/RicNewValveFeature.cpp new file mode 100644 index 0000000000..6dbf2e4c53 --- /dev/null +++ b/ApplicationCode/Commands/CompletionCommands/RicNewValveFeature.cpp @@ -0,0 +1,55 @@ +#include "RicNewValveFeature.h" +#include "Riu3DMainWindowTools.h" + +#include "RiaApplication.h" +#include "RimPerforationInterval.h" +#include "RimWellPathValve.h" +#include "RimWellPathCollection.h" + +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicNewValveFeature, "RicNewValveFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewValveFeature::isCommandEnabled() +{ + const RimPerforationInterval* perfInterval = caf::SelectionManager::instance()->selectedItemOfType(); + return perfInterval != nullptr && RiaApplication::enableDevelopmentFeatures(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewValveFeature::onActionTriggered(bool isChecked) +{ + RimPerforationInterval* perfInterval = caf::SelectionManager::instance()->selectedItemOfType(); + if (perfInterval) + { + RimWellPathValve* valve = new RimWellPathValve; + perfInterval->addValve(valve); + valve->setMeasuredDepthAndCount(perfInterval->startMD(), perfInterval->endMD() - perfInterval->startMD(), 1); + + RimWellPathCollection* wellPathCollection = nullptr; + perfInterval->firstAncestorOrThisOfType(wellPathCollection); + if (!wellPathCollection) return; + + wellPathCollection->uiCapability()->updateConnectedEditors(); + wellPathCollection->scheduleRedrawAffectedViews(); + + Riu3DMainWindowTools::selectAsCurrentItem(valve); + + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewValveFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/ICDValve16x16.png")); + actionToSetup->setText("New Valve"); +} diff --git a/ApplicationCode/Commands/CompletionCommands/RicNewValveFeature.h b/ApplicationCode/Commands/CompletionCommands/RicNewValveFeature.h new file mode 100644 index 0000000000..7be5cfada4 --- /dev/null +++ b/ApplicationCode/Commands/CompletionCommands/RicNewValveFeature.h @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicNewValveFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; + +}; diff --git a/ApplicationCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.cpp b/ApplicationCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.cpp index 2fbc001077..ca027f5f85 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.cpp +++ b/ApplicationCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.cpp @@ -78,7 +78,7 @@ void RicWellPathImportCompletionsFileFeature::onActionTriggered(bool isChecked) if (app->project()) { - app->project()->createDisplayModelAndRedrawAllViews(); + app->project()->scheduleCreateDisplayModelAndRedrawAllViews(); } } diff --git a/ApplicationCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.h b/ApplicationCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.h index cc98eed860..6a28281ed5 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.h +++ b/ApplicationCode/Commands/CompletionCommands/RicWellPathImportCompletionsFileFeature.h @@ -31,9 +31,9 @@ class RicWellPathImportCompletionsFileFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static RimFishboneWellPathCollection* selectedWellPathCollection(); diff --git a/ApplicationCode/Commands/CompletionCommands/RicWellPathImportPerforationIntervalsFeature.cpp b/ApplicationCode/Commands/CompletionCommands/RicWellPathImportPerforationIntervalsFeature.cpp index 8b51f0c6df..d80df64cdc 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicWellPathImportPerforationIntervalsFeature.cpp +++ b/ApplicationCode/Commands/CompletionCommands/RicWellPathImportPerforationIntervalsFeature.cpp @@ -87,13 +87,10 @@ void RicWellPathImportPerforationIntervalsFeature::onActionTriggered(bool isChec perforationInterval->setStartAndEndMD(interval.startMD, interval.endMD); perforationInterval->setDiameter(interval.diameter); perforationInterval->setSkinFactor(interval.skinFactor); - if (interval.startOfHistory) + if (!interval.startOfHistory) { - perforationInterval->setStartOfHistory(); - } - else - { - perforationInterval->setDate(interval.date); + perforationInterval->setCustomStartDate(interval.date); + perforationInterval->enableCustomStartDate(true); } wellPath->perforationIntervalCollection()->appendPerforation(perforationInterval); lastPerforationInterval = perforationInterval; @@ -104,7 +101,7 @@ void RicWellPathImportPerforationIntervalsFeature::onActionTriggered(bool isChec if (app->project()) { - app->project()->createDisplayModelAndRedrawAllViews(); + app->project()->scheduleCreateDisplayModelAndRedrawAllViews(); } if (lastPerforationInterval) diff --git a/ApplicationCode/Commands/CompletionCommands/RicWellPathImportPerforationIntervalsFeature.h b/ApplicationCode/Commands/CompletionCommands/RicWellPathImportPerforationIntervalsFeature.h index d034a764e1..fe0967a525 100644 --- a/ApplicationCode/Commands/CompletionCommands/RicWellPathImportPerforationIntervalsFeature.h +++ b/ApplicationCode/Commands/CompletionCommands/RicWellPathImportPerforationIntervalsFeature.h @@ -31,9 +31,9 @@ class RicWellPathImportPerforationIntervalsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static RimWellPathCollection* selectedWellPathCollection(); diff --git a/ApplicationCode/Commands/CompletionExportCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/CompletionExportCommands/CMakeLists_files.cmake index e94144b290..8fb0094b74 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/CompletionExportCommands/CMakeLists_files.cmake @@ -5,10 +5,15 @@ ${CMAKE_CURRENT_LIST_DIR}/RicWellPathExportCompletionDataFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathExportCompletionDataFeatureImpl.h ${CMAKE_CURRENT_LIST_DIR}/RicFishbonesTransmissibilityCalculationFeatureImp.h ${CMAKE_CURRENT_LIST_DIR}/RicExportFishbonesWellSegmentsFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicExportFracturesWellSegmentsFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicCaseAndFileExportSettingsUi.h ${CMAKE_CURRENT_LIST_DIR}/RicExportFractureCompletionsImpl.h ${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForVisibleWellPathsFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForVisibleSimWellsFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicMultiSegmentWellExportInfo.h +${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureTextReportFeatureImpl.h +${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureReportItem.h +${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForTemporaryLgrsFeature.h ) @@ -18,10 +23,15 @@ ${CMAKE_CURRENT_LIST_DIR}/RicWellPathExportCompletionDataFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathExportCompletionDataFeatureImpl.cpp ${CMAKE_CURRENT_LIST_DIR}/RicFishbonesTransmissibilityCalculationFeatureImp.cpp ${CMAKE_CURRENT_LIST_DIR}/RicExportFishbonesWellSegmentsFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicExportFracturesWellSegmentsFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicCaseAndFileExportSettingsUi.cpp ${CMAKE_CURRENT_LIST_DIR}/RicExportFractureCompletionsImpl.cpp ${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForVisibleWellPathsFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForVisibleSimWellsFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicMultiSegmentWellExportInfo.cpp +${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureTextReportFeatureImpl.cpp +${CMAKE_CURRENT_LIST_DIR}/RicWellPathFractureReportItem.cpp +${CMAKE_CURRENT_LIST_DIR}/RicExportCompletionsForTemporaryLgrsFeature.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicCaseAndFileExportSettingsUi.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicCaseAndFileExportSettingsUi.cpp index 7925b2ad50..7bcc3172ac 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicCaseAndFileExportSettingsUi.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicCaseAndFileExportSettingsUi.cpp @@ -59,7 +59,7 @@ void RicCaseAndFileExportSettingsUi::defineEditorAttribute(const caf::PdmFieldHa { if (field == &folder) { - caf::PdmUiFilePathEditorAttribute* myAttr = static_cast(attribute); + caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast(attribute); if (myAttr) { myAttr->m_selectDirectory = true; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicCaseAndFileExportSettingsUi.h b/ApplicationCode/Commands/CompletionExportCommands/RicCaseAndFileExportSettingsUi.h index eeb2d126b6..4e23b14dc1 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicCaseAndFileExportSettingsUi.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicCaseAndFileExportSettingsUi.h @@ -38,7 +38,7 @@ class RicCaseAndFileExportSettingsUi : public caf::PdmObject caf::PdmField folder; caf::PdmPtrField caseToApply; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; protected: - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; }; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.cpp index f0f59d47b8..bd5fab7391 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.cpp @@ -1,23 +1,31 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// +#include "RiaApplication.h" + #include "RicExportCompletionDataSettingsUi.h" +#include "RicExportFractureCompletionsImpl.h" + +#include "RimProject.h" +#include "RimWellPath.h" +#include "RimWellPathCompletions.h" +// clang-format off namespace caf { template<> @@ -34,6 +42,9 @@ namespace caf { addItem(RicExportCompletionDataSettingsUi::TRANSMISSIBILITIES, "TRANSMISSIBILITIES", "Calculated Transmissibilities"); addItem(RicExportCompletionDataSettingsUi::WPIMULT_AND_DEFAULT_CONNECTION_FACTORS, "WPIMULT_AND_DEFAULT_CONNECTION_FACTORS", "Default Connection Factors and WPIMULT (Fractures Not Supported)"); +#ifdef _DEBUG + addItem(RicExportCompletionDataSettingsUi::NO_COMPLETIONS, "NO_COMPLETIONS", "None"); +#endif setDefault(RicExportCompletionDataSettingsUi::TRANSMISSIBILITIES); } @@ -44,13 +55,22 @@ namespace caf addItem(RicExportCompletionDataSettingsUi::COMBINED, "COMBINED", "Combined"); setDefault(RicExportCompletionDataSettingsUi::INDIVIDUALLY); } -} + template<> + void RicExportCompletionDataSettingsUi::TransScalingWBHPSource::setUp() + { + addItem(RicExportFractureCompletionsImpl::WBHP_FROM_SUMMARY, "WBHP_SUMMARY", "WBHP From Summary Case"); + addItem(RicExportFractureCompletionsImpl::WBHP_FROM_USER_DEF, "WBHP_USER_DEFINED", "Fixed User Defined WBHP"); + + setDefault(RicExportFractureCompletionsImpl::WBHP_FROM_SUMMARY); + } +} +// clang-format on CAF_PDM_SOURCE_INIT(RicExportCompletionDataSettingsUi, "RicExportCompletionDataSettingsUi"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RicExportCompletionDataSettingsUi::RicExportCompletionDataSettingsUi() { @@ -60,7 +80,9 @@ RicExportCompletionDataSettingsUi::RicExportCompletionDataSettingsUi() CAF_PDM_InitFieldNoDefault(&compdatExport, "compdatExport", "Export", "", " ", ""); - CAF_PDM_InitField(&timeStep, "TimeStepIndex", 0, " Time Step", "", "", ""); + CAF_PDM_InitField(&timeStep, "TimeStepIndex", 0, " Time Step", "", "", ""); + + CAF_PDM_InitField(&includeMsw, "IncludeMSW", false, "Include Multi Segment Well Model", "", "", ""); CAF_PDM_InitField(&useLateralNTG, "UseLateralNTG", false, "Use NTG Horizontally", "", "", ""); @@ -68,19 +90,31 @@ RicExportCompletionDataSettingsUi::RicExportCompletionDataSettingsUi() CAF_PDM_InitField(&includeFishbones, "IncludeFishbones", true, "Fishbones", "", "", ""); CAF_PDM_InitField(&includeFractures, "IncludeFractures", true, "Fractures", "", "", ""); - CAF_PDM_InitField(&excludeMainBoreForFishbones, "ExcludeMainBoreForFishbones", false, " Exclude Main Bore Transmissibility", "", "", ""); - - CAF_PDM_InitFieldNoDefault(&m_reportCompletionTypesSeparately, "ReportCompletionTypesSeparately", "Export Completion Types", "", "", ""); + CAF_PDM_InitField(&performTransScaling, "TransScalingType", false, "Perform Transmissibility Scaling", "", "", ""); + CAF_PDM_InitField(&transScalingTimeStep, "TransScalingTimeStep", 0, "Current Time Step", "", "", ""); + CAF_PDM_InitFieldNoDefault(&transScalingWBHPSource, "TransScalingWBHPSource", "WBHP Selection", "", "", ""); + CAF_PDM_InitField(&transScalingWBHP, "TransScalingWBHP", 200.0, "WBHP Before Production Start", "", "", ""); + + CAF_PDM_InitField(&excludeMainBoreForFishbones, + "ExcludeMainBoreForFishbones", + false, + " Exclude Main Bore Transmissibility", + "", + "Main bore perforation intervals are defined by start/end MD of each active fishbone sub definition", + ""); + + CAF_PDM_InitFieldNoDefault( + &m_reportCompletionTypesSeparately, "ReportCompletionTypesSeparately", "Export Completion Types", "", "", ""); m_displayForSimWell = true; - - m_fracturesEnabled = true; + + m_fracturesEnabled = true; m_perforationsEnabled = true; - m_fishbonesEnabled = true; + m_fishbonesEnabled = true; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicExportCompletionDataSettingsUi::showForSimWells() { @@ -88,7 +122,7 @@ void RicExportCompletionDataSettingsUi::showForSimWells() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicExportCompletionDataSettingsUi::showForWellPath() { @@ -96,7 +130,7 @@ void RicExportCompletionDataSettingsUi::showForWellPath() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicExportCompletionDataSettingsUi::setCombinationMode(CombinationMode combinationMode) { @@ -104,7 +138,7 @@ void RicExportCompletionDataSettingsUi::setCombinationMode(CombinationMode combi } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicExportCompletionDataSettingsUi::showFractureInUi(bool enable) { @@ -112,7 +146,7 @@ void RicExportCompletionDataSettingsUi::showFractureInUi(bool enable) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicExportCompletionDataSettingsUi::showPerforationsInUi(bool enable) { @@ -120,7 +154,7 @@ void RicExportCompletionDataSettingsUi::showPerforationsInUi(bool enable) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicExportCompletionDataSettingsUi::showFishbonesInUi(bool enable) { @@ -128,7 +162,7 @@ void RicExportCompletionDataSettingsUi::showFishbonesInUi(bool enable) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RicExportCompletionDataSettingsUi::reportCompletionsTypesIndividually() const { @@ -136,29 +170,30 @@ bool RicExportCompletionDataSettingsUi::reportCompletionsTypesIndividually() con } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RicExportCompletionDataSettingsUi::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RicExportCompletionDataSettingsUi::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { if (changedField == &compdatExport) { if (compdatExport == WPIMULT_AND_DEFAULT_CONNECTION_FACTORS) { includeFractures = false; - includeFractures.uiCapability()->setUiReadOnly(true); } - else if (compdatExport == TRANSMISSIBILITIES) + else if (compdatExport == TRANSMISSIBILITIES || includeMsw) { includeFractures = true; - includeFractures.uiCapability()->setUiReadOnly(false); } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QList RicExportCompletionDataSettingsUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +QList + RicExportCompletionDataSettingsUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) { QList options; if (fieldNeedingOptions == &timeStep) @@ -169,12 +204,70 @@ QList RicExportCompletionDataSettingsUi::calculateValueO { timeStepNames = caseToApply->timeStepStrings(); } - for (int i = 0; i < timeStepNames.size(); i++) { options.push_back(caf::PdmOptionItemInfo(timeStepNames[i], i)); } } + else if (fieldNeedingOptions == &transScalingTimeStep) + { + std::map>> wellProductionStartStrings = generateWellProductionStartStrings(); + + QStringList timeStepNames; + + if (caseToApply) + { + timeStepNames = caseToApply->timeStepStrings(); + } + for (int i = 0; i < timeStepNames.size(); i++) + { + QString timeStepString = timeStepNames[i]; + auto it = wellProductionStartStrings.find(i); + if (it != wellProductionStartStrings.end()) + { + int numberOfWells = static_cast(it->second.size()); + QStringList wellList; + QStringList wellPressureList; + const int maxStringLength = 70; + QString startStringFormat(" [Start: %1]"); + + for (int w = 0; w < numberOfWells; ++w) + { + QString wellString = it->second[w].first; + QStringList candidateWellList = wellList; candidateWellList << wellString; + + if (startStringFormat.arg(candidateWellList.join(", ")).length() < maxStringLength) + { + wellList = candidateWellList; + } + + QString wellStringWithPressure = QString("%1 (%2)").arg(it->second[w].first).arg(it->second[w].second); + QStringList candidateWellPressureList = wellPressureList; candidateWellPressureList << wellStringWithPressure; + if (startStringFormat.arg(candidateWellPressureList.join(", ")).length() < maxStringLength) + { + wellPressureList = candidateWellPressureList; + } + } + + if (wellList.size() < numberOfWells) + { + wellList += QString("+ %1 more").arg(numberOfWells - wellList.size()); + timeStepString += startStringFormat.arg(wellList.join(", ")); + } + else if (wellPressureList.size() < numberOfWells) + { + timeStepString += startStringFormat.arg(wellList.join(", ")); + } + else + { + timeStepString += startStringFormat.arg(wellPressureList.join(", ")); + } + } + + options.push_back(caf::PdmOptionItemInfo(timeStepString, i)); + } + } + else { options = RicCaseAndFileExportSettingsUi::calculateValueOptions(fieldNeedingOptions, useOptionsOnly); @@ -183,28 +276,27 @@ QList RicExportCompletionDataSettingsUi::calculateValueO } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicExportCompletionDataSettingsUi::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { { - caf::PdmUiGroup* group = uiOrdering.addNewGroup("File Settings"); - - group->add(&folder); - group->add(&fileSplit); - group->add(&m_reportCompletionTypesSeparately); + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Export Settings"); + group->add(&compdatExport); + group->add(&caseToApply); + group->add(&useLateralNTG); + group->add(&includeMsw); } { - caf::PdmUiGroup* group = uiOrdering.addNewGroup("Settings"); - - group->add(&caseToApply); - group->add(&compdatExport); - group->add(&useLateralNTG); + caf::PdmUiGroup* group = uiOrdering.addNewGroup("File Settings"); + group->add(&fileSplit); + group->add(&m_reportCompletionTypesSeparately); + group->add(&folder); } { - caf::PdmUiGroup* group = uiOrdering.addNewGroup("Visible Completions"); + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Completions Export Selection"); if (!m_displayForSimWell) { if (m_perforationsEnabled) @@ -222,14 +314,47 @@ void RicExportCompletionDataSettingsUi::defineUiOrdering(QString uiConfigName, c { group->add(&includeFractures); - if (compdatExport == WPIMULT_AND_DEFAULT_CONNECTION_FACTORS) + caf::PdmUiGroup* pddGroup = group->addNewGroup("Pressure Differential Depletion Scaling"); + pddGroup->setUiReadOnly(!includeFractures()); + + pddGroup->add(&performTransScaling); + pddGroup->add(&transScalingTimeStep); + pddGroup->add(&transScalingWBHPSource); + pddGroup->add(&transScalingWBHP); + + if (!includeFractures()) + { + performTransScaling = false; + performTransScaling.uiCapability()->setUiReadOnly(true); + } + else { - includeFractures.uiCapability()->setUiReadOnly(true); + performTransScaling.uiCapability()->setUiReadOnly(false); } - else if (compdatExport == TRANSMISSIBILITIES) + + if (!performTransScaling()) { - includeFractures.uiCapability()->setUiReadOnly(false); + transScalingTimeStep.uiCapability()->setUiReadOnly(true); + transScalingWBHPSource.uiCapability()->setUiReadOnly(true); + transScalingWBHP.uiCapability()->setUiReadOnly(true); + } + else + { + transScalingTimeStep.uiCapability()->setUiReadOnly(false); + transScalingWBHPSource.uiCapability()->setUiReadOnly(false); + transScalingWBHP.uiCapability()->setUiReadOnly(false); + if (transScalingWBHPSource == RicExportFractureCompletionsImpl::WBHP_FROM_SUMMARY) + { + transScalingWBHP.uiCapability()->setUiName("WBHP Before Production Start"); + } + else + { + transScalingWBHP.uiCapability()->setUiName("User Defined WBHP"); + } } + + // Set visibility + includeFractures.uiCapability()->setUiHidden(compdatExport == WPIMULT_AND_DEFAULT_CONNECTION_FACTORS && !includeMsw); } if (!m_displayForSimWell) @@ -238,6 +363,8 @@ void RicExportCompletionDataSettingsUi::defineUiOrdering(QString uiConfigName, c { group->add(&includeFishbones); group->add(&excludeMainBoreForFishbones); + + // Set visibility if (!includeFishbones) excludeMainBoreForFishbones.uiCapability()->setUiReadOnly(true); else @@ -248,3 +375,35 @@ void RicExportCompletionDataSettingsUi::defineUiOrdering(QString uiConfigName, c uiOrdering.skipRemainingFields(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map>> RicExportCompletionDataSettingsUi::generateWellProductionStartStrings() +{ + std::map>> wellProductionStartStrings; + + const RimProject* project = nullptr; + if (caseToApply) + { + caseToApply->firstAncestorOrThisOfTypeAsserted(project); + for (const RimWellPath* wellPath : project->allWellPaths()) + { + int initialWellProductionTimeStep = -1; + double initialWellPressure = 0.0; + double currentWellPressure = 0.0; + RicExportFractureCompletionsImpl::getWellPressuresAndInitialProductionTimeStepFromSummaryData(caseToApply, + wellPath->completions()->wellNameForExport(), + 0, + &initialWellProductionTimeStep, + &initialWellPressure, + ¤tWellPressure); + if (initialWellProductionTimeStep >= 0) + { + QString pressureUnits = RiaEclipseUnitTools::unitStringPressure(wellPath->unitSystem()); + wellProductionStartStrings[initialWellProductionTimeStep].push_back(std::make_pair(wellPath->name(), QString("%1 %2").arg(initialWellPressure, 4, 'f', 1).arg(pressureUnits))); + } + } + } + return wellProductionStartStrings; +} diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.h b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.h index 2b35840844..9ddedbc6af 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionDataSettingsUi.h @@ -19,6 +19,7 @@ #pragma once #include "RicCaseAndFileExportSettingsUi.h" +#include "RicExportFractureCompletionsImpl.h" #include "cafPdmField.h" #include "cafAppEnum.h" @@ -41,6 +42,10 @@ class RicExportCompletionDataSettingsUi : public RicCaseAndFileExportSettingsUi enum CompdatExport { TRANSMISSIBILITIES, WPIMULT_AND_DEFAULT_CONNECTION_FACTORS, + +#ifdef _DEBUG + NO_COMPLETIONS +#endif }; typedef caf::AppEnum CompdatExportType; @@ -51,6 +56,7 @@ class RicExportCompletionDataSettingsUi : public RicCaseAndFileExportSettingsUi }; typedef caf::AppEnum CombinationModeType; + typedef caf::AppEnum TransScalingWBHPSource; RicExportCompletionDataSettingsUi(); @@ -59,10 +65,17 @@ class RicExportCompletionDataSettingsUi : public RicCaseAndFileExportSettingsUi caf::PdmField fileSplit; caf::PdmField compdatExport; + caf::PdmField performTransScaling; + caf::PdmField transScalingTimeStep; + caf::PdmField transScalingWBHPSource; + caf::PdmField transScalingWBHP; + + caf::PdmField includeMsw; caf::PdmField useLateralNTG; caf::PdmField includePerforations; caf::PdmField includeFishbones; caf::PdmField excludeMainBoreForFishbones; + caf::PdmField includeFractures; void showForSimWells(); @@ -76,14 +89,15 @@ class RicExportCompletionDataSettingsUi : public RicCaseAndFileExportSettingsUi bool reportCompletionsTypesIndividually() const; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; protected: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + std::map>> generateWellProductionStartStrings(); private: - caf::PdmField m_reportCompletionTypesSeparately; + caf::PdmField m_reportCompletionTypesSeparately; bool m_displayForSimWell; bool m_fracturesEnabled; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForTemporaryLgrsFeature.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForTemporaryLgrsFeature.cpp new file mode 100644 index 0000000000..5aa177829a --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForTemporaryLgrsFeature.cpp @@ -0,0 +1,117 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicExportCompletionsForTemporaryLgrsFeature.h" + +#include "RiaApplication.h" + +#include "RicWellPathExportCompletionDataFeature.h" + +#include "RigMainGrid.h" + +#include "RiuPlotMainWindow.h" + +#include "RimEclipseCase.h" +#include "RimGridCollection.h" +#include "RimProject.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" + +#include "cafSelectionManagerTools.h" + +#include + +CAF_CMD_SOURCE_INIT(RicExportCompletionsForTemporaryLgrsFeature, "RicExportCompletionsForTemporaryLgrsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExportCompletionsForTemporaryLgrsFeature::isCommandEnabled() +{ + if (wellPathsAssociatedWithLgrs().empty()) + { + return false; + } + + std::vector selGridInfos = caf::selectedObjectsByTypeStrict(); + return selGridInfos.size() == 1 && selGridInfos.front()->uiName() == RimGridCollection::temporaryGridUiName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportCompletionsForTemporaryLgrsFeature::onActionTriggered(bool isChecked) +{ + std::vector wellPaths = wellPathsAssociatedWithLgrs(); + if (wellPaths.empty()) + { + return; + } + + std::vector simWells; + QString dialogTitle = "Export Completion Data for Temporary LGRs"; + + RicWellPathExportCompletionDataFeature::prepareExportSettingsAndExportCompletions(dialogTitle, wellPaths, simWells); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportCompletionsForTemporaryLgrsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Export Completion Data"); + actionToSetup->setIcon(QIcon(":/ExportCompletionsSymbol16x16.png")); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicExportCompletionsForTemporaryLgrsFeature::wellPathsAssociatedWithLgrs() +{ + std::vector wellPaths; + + auto selectedEclipseCase = caf::firstAncestorOfTypeFromSelectedObject(); + if (selectedEclipseCase) + { + auto mainGrid = selectedEclipseCase->mainGrid(); + + std::set wellPathNames; + + for (size_t i = 0; i < mainGrid->gridCount(); i++) + { + const RigGridBase* grid = mainGrid->gridByIndex(i); + + if (!grid->associatedWellPathName().empty()) + { + wellPathNames.insert(QString::fromStdString(grid->associatedWellPathName())); + } + } + + auto project = RiaApplication::instance()->project(); + for (const auto& wellPathName : wellPathNames) + { + auto wellPath = project->wellPathByName(wellPathName); + if (wellPath) + { + wellPaths.push_back(wellPath); + } + } + } + + return wellPaths; +} diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForTemporaryLgrsFeature.h b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForTemporaryLgrsFeature.h new file mode 100644 index 0000000000..9786da92a0 --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForTemporaryLgrsFeature.h @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimSimWellInView; +class RimWellPath; +class RigMainGrid; + +//================================================================================================== +/// +//================================================================================================== +class RicExportCompletionsForTemporaryLgrsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + +public: + static std::vector wellPathsAssociatedWithLgrs(); +}; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleSimWellsFeature.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleSimWellsFeature.cpp index fe82fa65b4..bc1172ab08 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleSimWellsFeature.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleSimWellsFeature.cpp @@ -64,6 +64,8 @@ void RicExportCompletionsForVisibleSimWellsFeature::onActionTriggered(bool isChe void RicExportCompletionsForVisibleSimWellsFeature::setupActionLook(QAction* actionToSetup) { actionToSetup->setText("Export Completion Data for Visible Simulation Wells"); + actionToSetup->setIcon(QIcon(":/ExportCompletionsSymbol16x16.png")); + } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleSimWellsFeature.h b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleSimWellsFeature.h index 9e6a49ef0b..6d2e516f61 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleSimWellsFeature.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleSimWellsFeature.h @@ -30,9 +30,9 @@ class RicExportCompletionsForVisibleSimWellsFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; private: std::vector visibleSimWells(); diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.cpp index 7c5fb9adff..7747d04c7d 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.cpp @@ -89,6 +89,8 @@ void RicExportCompletionsForVisibleWellPathsFeature::onActionTriggered(bool isCh void RicExportCompletionsForVisibleWellPathsFeature::setupActionLook(QAction* actionToSetup) { actionToSetup->setText("Export Completion Data for Visible Well Paths"); + actionToSetup->setIcon(QIcon(":/ExportCompletionsSymbol16x16.png")); + } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.h b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.h index c80ba540ca..af0f8aed1f 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.h @@ -31,10 +31,10 @@ class RicExportCompletionsForVisibleWellPathsFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; -private: - std::vector visibleWellPaths(); +public: + static std::vector visibleWellPaths(); }; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.cpp index 3b2de36453..fc5e8aeca2 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.cpp @@ -21,7 +21,11 @@ #include "RiaApplication.h" #include "RiaLogging.h" +#include "RifEclipseDataTableFormatter.h" + #include "RicExportFeatureImpl.h" +#include "RicMultiSegmentWellExportInfo.h" +#include "RicWellPathExportCompletionDataFeatureImpl.h" #include "RimProject.h" #include "RimFishboneWellPathCollection.h" @@ -53,15 +57,14 @@ CAF_CMD_SOURCE_INIT(RicExportFishbonesWellSegmentsFeature, "RicExportFishbonesWe //-------------------------------------------------------------------------------------------------- void RicExportFishbonesWellSegmentsFeature::onActionTriggered(bool isChecked) { - RimFishbonesCollection* fishbonesCollection = selectedFishbonesCollection(); - RimWellPath* wellPath = selectedWellPath(); + RimFishbonesCollection* fishbonesCollection = caf::SelectionManager::instance()->selectedItemAncestorOfType(); + RimWellPath* wellPath = caf::SelectionManager::instance()->selectedItemAncestorOfType(); CVF_ASSERT(fishbonesCollection); CVF_ASSERT(wellPath); RiaApplication* app = RiaApplication::instance(); - QString projectFolder = app->currentProjectPath(); - QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallback("COMPLETIONS", projectFolder); + QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallbackToProjectFolder("COMPLETIONS"); RicCaseAndFileExportSettingsUi exportSettings; std::vector cases; @@ -85,50 +88,11 @@ void RicExportFishbonesWellSegmentsFeature::onActionTriggered(bool isChecked) { RiaApplication::instance()->setLastUsedDialogDirectory("COMPLETIONS", QFileInfo(exportSettings.folder).absolutePath()); - std::vector fishbonesSubs; - for (RimFishbonesMultipleSubs* subs : fishbonesCollection->fishbonesSubs) + if (!fishbonesCollection->activeFishbonesSubs().empty()) { - fishbonesSubs.push_back(subs); + exportWellSegments(wellPath, fishbonesCollection->activeFishbonesSubs(), exportSettings); } - - exportWellSegments(wellPath, fishbonesSubs, exportSettings); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimFishbonesCollection* RicExportFishbonesWellSegmentsFeature::selectedFishbonesCollection() -{ - RimFishbonesCollection* objToFind = nullptr; - - caf::PdmUiItem* pdmUiItem = caf::SelectionManager::instance()->selectedItem(); - - caf::PdmObjectHandle* objHandle = dynamic_cast(pdmUiItem); - if (objHandle) - { - objHandle->firstAncestorOrThisOfType(objToFind); - } - - return objToFind; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPath* RicExportFishbonesWellSegmentsFeature::selectedWellPath() -{ - RimWellPath* objToFind = nullptr; - - caf::PdmUiItem* pdmUiItem = caf::SelectionManager::instance()->selectedItem(); - - caf::PdmObjectHandle* objHandle = dynamic_cast(pdmUiItem); - if (objHandle) - { - objHandle->firstAncestorOrThisOfType(objToFind); } - - return objToFind; } //-------------------------------------------------------------------------------------------------- @@ -144,7 +108,7 @@ void RicExportFishbonesWellSegmentsFeature::setupActionLook(QAction* actionToSet //-------------------------------------------------------------------------------------------------- bool RicExportFishbonesWellSegmentsFeature::isCommandEnabled() { - if (selectedFishbonesCollection()) + if (caf::SelectionManager::instance()->selectedItemAncestorOfType()) { return true; } @@ -157,6 +121,8 @@ bool RicExportFishbonesWellSegmentsFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicExportFishbonesWellSegmentsFeature::exportWellSegments(const RimWellPath* wellPath, const std::vector& fishbonesSubs, const RicCaseAndFileExportSettingsUi& settings) { + if (fishbonesSubs.empty()) return; + if (settings.caseToApply() == nullptr) { RiaLogging::error("Export Well Segments: Cannot export completions data without specified eclipse case"); @@ -165,269 +131,30 @@ void RicExportFishbonesWellSegmentsFeature::exportWellSegments(const RimWellPath QString fileName = QString("%1-Welsegs").arg(settings.caseToApply()->caseUserDescription()); fileName = caf::Utils::makeValidFileBasename(fileName); - QString filePath = QDir(settings.folder()).filePath(fileName); - QFile exportFile(filePath); - if (!exportFile.open(QIODevice::WriteOnly)) + QDir exportFolder(settings.folder()); + if (!exportFolder.exists()) + { + bool createdPath = exportFolder.mkpath("."); + if (createdPath) + RiaLogging::info("Created export folder " + settings.folder()); + else + RiaLogging::error("Selected output folder does not exist, and could not be created."); + } + + QString filePath = exportFolder.filePath(fileName); + QFile exportFile(filePath); + if (!exportFile.open(QIODevice::WriteOnly | QIODevice::Text)) { RiaLogging::error(QString("Export Well Segments: Could not open the file: %1").arg(filePath)); return; } - - std::vector locations = RicWellPathExportCompletionDataFeatureImpl::findWellSegmentLocations(settings.caseToApply, wellPath, fishbonesSubs); + + RicMswExportInfo exportInfo = RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMswExportInfo(settings.caseToApply, wellPath, fishbonesSubs, true); QTextStream stream(&exportFile); RifEclipseDataTableFormatter formatter(stream); - generateWelsegsTable(formatter, wellPath, settings, locations); - generateCompsegsTable(formatter, wellPath, settings, locations); - generateWsegvalvTable(formatter, wellPath, settings, locations); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicExportFishbonesWellSegmentsFeature::generateWelsegsTable(RifEclipseDataTableFormatter& formatter, - const RimWellPath* wellPath, - const RicCaseAndFileExportSettingsUi& settings, - const std::vector& locations) -{ - RiaEclipseUnitTools::UnitSystem unitSystem = settings.caseToApply->eclipseCaseData()->unitsType(); - - formatter.keyword("WELSEGS"); - - double startMD = wellPath->fishbonesCollection()->startMD(); - double startTVD = -wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(startMD).z(); - - { - std::vector header = { - RifEclipseOutputTableColumn("Name"), - RifEclipseOutputTableColumn("Dep 1"), - RifEclipseOutputTableColumn("Tlen 1"), - RifEclipseOutputTableColumn("Vol 1"), - RifEclipseOutputTableColumn("Len&Dep"), - RifEclipseOutputTableColumn("PresDrop"), - }; - formatter.header(header); - - formatter.add(wellPath->name()); - formatter.add(startTVD); - formatter.add(startMD); - formatter.add("1*"); - formatter.add(wellPath->fishbonesCollection()->lengthAndDepth().text()); - formatter.add(wellPath->fishbonesCollection()->pressureDrop().text()); - - formatter.rowCompleted(); - } - - { - std::vector header = { - RifEclipseOutputTableColumn("First Seg"), - RifEclipseOutputTableColumn("Last Seg"), - RifEclipseOutputTableColumn("Branch Num"), - RifEclipseOutputTableColumn("Outlet Seg"), - RifEclipseOutputTableColumn("Length"), - RifEclipseOutputTableColumn("Depth Change"), - RifEclipseOutputTableColumn("Diam"), - RifEclipseOutputTableColumn("Rough"), - }; - formatter.header(header); - } - - { - formatter.comment("Main stem"); - - double depth = 0; - double length = 0; - double previousMD = startMD; - double previousTVD = startTVD; - - for (const WellSegmentLocation& location : locations) - { - if (wellPath->fishbonesCollection()->lengthAndDepth() == RimFishbonesCollection::INC) - { - depth = location.trueVerticalDepth - previousTVD; - length = location.fishbonesSubs->measuredDepth(location.subIndex) - previousMD; - } - else - { - depth += location.trueVerticalDepth - previousTVD; - length += location.fishbonesSubs->measuredDepth(location.subIndex) - previousMD; - } - - formatter.comment(QString("Segment for sub %1").arg(location.subIndex)); - formatter.add(location.segmentNumber).add(location.segmentNumber); - formatter.add(1); // All segments on main stem are branch 1 - formatter.add(location.segmentNumber - 1); // All main stem segments are connected to the segment below them - formatter.add(length); - formatter.add(depth); - formatter.add(wellPath->fishbonesCollection()->linerDiameter(unitSystem)); - formatter.add(wellPath->fishbonesCollection()->roughnessFactor(unitSystem)); - formatter.rowCompleted(); - - previousMD = location.measuredDepth; - previousTVD = location.trueVerticalDepth; - } - } - - { - formatter.comment("Laterals"); - formatter.comment("Diam: MSW - Tubing Radius"); - formatter.comment("Rough: MSW - Open Hole Roughness Factor"); - for (const WellSegmentLocation& location : locations) - { - formatter.comment("ICD"); - formatter.add(location.icdSegmentNumber).add(location.icdSegmentNumber); - formatter.add(location.icdBranchNumber); - formatter.add(location.segmentNumber); - formatter.add(0.1); // ICDs have 0.1 length - formatter.add(0); // Depth change - formatter.add(wellPath->fishbonesCollection()->linerDiameter(unitSystem)); - formatter.add(wellPath->fishbonesCollection()->roughnessFactor(unitSystem)); - formatter.rowCompleted(); - - for (const WellSegmentLateral& lateral : location.laterals) - { - formatter.comment(QString("%1 : Sub index %2 - Lateral %3").arg(location.fishbonesSubs->generatedName()).arg(location.subIndex).arg(lateral.lateralIndex)); - - double depth = 0; - double length = 0; - - for (const WellSegmentLateralIntersection& intersection : lateral.intersections) - { - if (wellPath->fishbonesCollection()->lengthAndDepth() == RimFishbonesCollection::INC) - { - depth = intersection.tvdChangeFromPreviousIntersection; - length = intersection.mdFromPreviousIntersection; - } - else - { - depth += intersection.tvdChangeFromPreviousIntersection; - length += intersection.mdFromPreviousIntersection; - } - double diameter = computeEffectiveDiameter(location.fishbonesSubs->tubingDiameter(unitSystem), location.fishbonesSubs->holeDiameter(unitSystem)); - formatter.add(intersection.segmentNumber); - formatter.add(intersection.segmentNumber); - formatter.add(lateral.branchNumber); - formatter.add(intersection.attachedSegmentNumber); - formatter.add(length); - formatter.add(depth); - formatter.add(diameter); - formatter.add(location.fishbonesSubs->openHoleRoughnessFactor(unitSystem)); - formatter.rowCompleted(); - } - } - } - } - - formatter.tableCompleted(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicExportFishbonesWellSegmentsFeature::generateCompsegsTable(RifEclipseDataTableFormatter& formatter, - const RimWellPath* wellPath, - const RicCaseAndFileExportSettingsUi& settings, - const std::vector& locations) -{ - RigMainGrid* grid = settings.caseToApply->eclipseCaseData()->mainGrid(); - formatter.keyword("COMPSEGS"); - { - std::vector header = { - RifEclipseOutputTableColumn("Name") - }; - formatter.header(header); - formatter.add(wellPath->name()); - formatter.rowCompleted(); - } - - { - std::vector header = { - RifEclipseOutputTableColumn("I"), - RifEclipseOutputTableColumn("J"), - RifEclipseOutputTableColumn("K"), - RifEclipseOutputTableColumn("Branch no"), - RifEclipseOutputTableColumn("Start Length"), - RifEclipseOutputTableColumn("End Length"), - RifEclipseOutputTableColumn("Dir Pen"), - RifEclipseOutputTableColumn("End Range"), - RifEclipseOutputTableColumn("Connection Depth") - }; - formatter.header(header); - } - - for (const WellSegmentLocation& location : locations) - { - for (const WellSegmentLateral& lateral : location.laterals) - { - double aggregatedLength = 0; - for (const WellSegmentLateralIntersection& intersection : lateral.intersections) - { - size_t i, j, k; - grid->ijkFromCellIndex(intersection.globalCellIndex, &i, &j, &k); - - formatter.addZeroBasedCellIndex(i).addZeroBasedCellIndex(j).addZeroBasedCellIndex(k); - formatter.add(lateral.branchNumber); - formatter.add(aggregatedLength); - formatter.add(aggregatedLength + intersection.mdFromPreviousIntersection); - formatter.rowCompleted(); - - aggregatedLength += intersection.mdFromPreviousIntersection; - } - } - } - - formatter.tableCompleted(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicExportFishbonesWellSegmentsFeature::generateWsegvalvTable(RifEclipseDataTableFormatter& formatter, - const RimWellPath* wellPath, - const RicCaseAndFileExportSettingsUi& settings, - const std::vector& locations) -{ - RiaEclipseUnitTools::UnitSystem unitSystem = settings.caseToApply->eclipseCaseData()->unitsType(); - - { - formatter.keyword("WSEGVALV"); - std::vector header = { - RifEclipseOutputTableColumn("Well Name"), - RifEclipseOutputTableColumn("Seg No"), - RifEclipseOutputTableColumn("Cv"), - RifEclipseOutputTableColumn("Ac"), - }; - formatter.header(header); - } - for (const WellSegmentLocation& location : locations) - { - formatter.add(wellPath->name()); - formatter.add(location.icdSegmentNumber); - formatter.add(location.fishbonesSubs->icdFlowCoefficient()); - - double icdOrificeRadius = location.fishbonesSubs->icdOrificeDiameter(unitSystem) / 2; - double icdArea = icdOrificeRadius * icdOrificeRadius * cvf::PI_D; - formatter.add(icdArea * static_cast(location.fishbonesSubs->icdCount())); - formatter.rowCompleted(); - } - formatter.tableCompleted(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RicExportFishbonesWellSegmentsFeature::computeEffectiveDiameter(double innerDiameter, double outerDiameter) -{ - double innerRadius = innerDiameter / 2; - double innerArea = cvf::PI_D * innerRadius * innerRadius; - - double outerRadius = outerDiameter / 2; - double outerArea = cvf::PI_D * outerRadius * outerRadius; - - double effectiveArea = outerArea - innerArea; - - double effectiveRadius = cvf::Math::sqrt(effectiveArea / cvf::PI_D); - - return effectiveRadius * 2; + RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable (formatter, exportInfo); + RicWellPathExportCompletionDataFeatureImpl::generateCompsegTables(formatter, exportInfo); + RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(formatter, exportInfo); } diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.h b/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.h index fe125abb2c..a8ba80aa1c 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFishbonesWellSegmentsFeature.h @@ -18,11 +18,7 @@ #pragma once -#include "RifEclipseDataTableFormatter.h" - #include "RicCaseAndFileExportSettingsUi.h" -#include "RicWellPathExportCompletionDataFeatureImpl.h" - #include "cafCmdFeature.h" @@ -30,6 +26,8 @@ class RimFishbonesCollection; class RimFishbonesMultipleSubs; class RimWellPath; + + //================================================================================================== /// //================================================================================================== @@ -38,20 +36,12 @@ class RicExportFishbonesWellSegmentsFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; public: - static void exportWellSegments(const RimWellPath* wellPath, const std::vector& fishbonesSubs, const RicCaseAndFileExportSettingsUi& settings); - -private: - static RimFishbonesCollection* selectedFishbonesCollection(); - static RimWellPath* selectedWellPath(); - - static void generateWelsegsTable(RifEclipseDataTableFormatter& formatter, const RimWellPath* wellPath, const RicCaseAndFileExportSettingsUi& settings, const std::vector& locations); - static void generateCompsegsTable(RifEclipseDataTableFormatter& formatter, const RimWellPath* wellPath, const RicCaseAndFileExportSettingsUi& settings, const std::vector& locations); - static void generateWsegvalvTable(RifEclipseDataTableFormatter& formatter, const RimWellPath* wellPath, const RicCaseAndFileExportSettingsUi& settings, const std::vector& locations); - - static double computeEffectiveDiameter(double innerDiameter, double outerDiameter); + static void exportWellSegments(const RimWellPath* wellPath, + const std::vector& fishbonesSubs, + const RicCaseAndFileExportSettingsUi& settings); }; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp index e11e605814..04c91e4103 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.cpp @@ -1,89 +1,104 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RicExportFractureCompletionsImpl.h" -#include "RiaLogging.h" +#include "RicWellPathFractureReportItem.h" -#include "RicExportCompletionDataSettingsUi.h" +#include "RiaLogging.h" +#include "RiaQDateTimeTools.h" +#include "RiaSummaryTools.h" #include "RimEclipseCase.h" +#include "RimEclipseResultCase.h" #include "RimEclipseView.h" #include "RimFracture.h" +#include "RimFractureContainmentTools.h" #include "RimFractureTemplate.h" +#include "RimObservedEclipseUserData.h" +#include "RimProject.h" #include "RimSimWellFracture.h" #include "RimSimWellFractureCollection.h" #include "RimSimWellInView.h" #include "RimStimPlanFractureTemplate.h" +#include "RimSummaryCase.h" +#include "RimSummaryCaseMainCollection.h" #include "RimWellPath.h" #include "RimWellPathCompletions.h" #include "RimWellPathFracture.h" #include "RimWellPathFractureCollection.h" +#include "RifEclipseSummaryAddress.h" +#include "RifSummaryReaderInterface.h" +#include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" -#include "RigTransmissibilityCondenser.h" +#include "RigEclipseToStimPlanCalculator.h" +#include "RigEclipseToStimPlanCellTransmissibilityCalculator.h" #include "RigFractureCell.h" #include "RigFractureGrid.h" -#include "RigEclipseToStimPlanCellTransmissibilityCalculator.h" #include "RigFractureTransmissibilityEquations.h" -#include "RigWellPathStimplanIntersector.h" #include "RigMainGrid.h" +#include "RigResultAccessorFactory.h" #include "RigSimWellData.h" #include "RigSimulationWellCoordsAndMD.h" +#include "RigTransmissibilityCondenser.h" +#include "RigTransmissibilityEquations.h" #include "RigWellPath.h" +#include "RigWellPathStimplanIntersector.h" #include //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RicExportFractureCompletionsImpl::generateCompdatValuesForWellPath(RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings, - QTextStream* outputStreamForIntermediateResultsText) +std::vector RicExportFractureCompletionsImpl::generateCompdatValuesForWellPath( + RimWellPath* wellPath, + RimEclipseCase* caseToApply, + std::vector* fractureDataForReport, + QTextStream* outputStreamForIntermediateResultsText, + PressureDepletionParameters pdParams) { - RimEclipseCase* caseToApply = settings.caseToApply(); - - std::vector fracturesAlongWellPath; + std::vector fracturesAlongWellPath; - if (wellPath->fractureCollection()->isChecked()) + for (auto& frac : wellPath->fractureCollection()->activeFractures()) { - for (const auto& frac : wellPath->fractureCollection()->fractures) - { - if (frac->isChecked()) - { - fracturesAlongWellPath.push_back(frac); - } - } + frac->ensureValidNonDarcyProperties(); + + fracturesAlongWellPath.push_back(frac); } return generateCompdatValues(caseToApply, wellPath->completions()->wellNameForExport(), wellPath->wellPathGeometry(), fracturesAlongWellPath, - outputStreamForIntermediateResultsText); + fractureDataForReport, + outputStreamForIntermediateResultsText, + pdParams); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RicExportFractureCompletionsImpl::generateCompdatValuesForSimWell(RimEclipseCase* eclipseCase, - const RimSimWellInView* well, - QTextStream* outputStreamForIntermediateResultsText) +std::vector + RicExportFractureCompletionsImpl::generateCompdatValuesForSimWell(RimEclipseCase* eclipseCase, + const RimSimWellInView* well, + QTextStream* outputStreamForIntermediateResultsText, + PressureDepletionParameters pdParams) { std::vector completionData; @@ -91,7 +106,7 @@ std::vector RicExportFractureCompletionsImpl::generateCompdat for (size_t branchIndex = 0; branchIndex < branches.size(); ++branchIndex) { - std::vector fractures; + std::vector fractures; for (RimSimWellFracture* fracture : well->simwellFractureCollection->simwellFractures()) { if (fracture->isChecked() && static_cast(fracture->branchIndex()) == branchIndex) @@ -100,7 +115,13 @@ std::vector RicExportFractureCompletionsImpl::generateCompdat } } - std::vector branchCompletions = generateCompdatValues(eclipseCase, well->name(), branches[branchIndex], fractures, outputStreamForIntermediateResultsText); + std::vector branchCompletions = generateCompdatValues(eclipseCase, + well->name(), + branches[branchIndex], + fractures, + nullptr, + outputStreamForIntermediateResultsText, + pdParams); completionData.insert(completionData.end(), branchCompletions.begin(), branchCompletions.end()); } @@ -109,26 +130,164 @@ std::vector RicExportFractureCompletionsImpl::generateCompdat } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RicExportFractureCompletionsImpl::generateCompdatValues(RimEclipseCase* caseToApply, - const QString& wellPathName, - const RigWellPath* wellPathGeometry, - const std::vector& fractures, - QTextStream* outputStreamForIntermediateResultsText) +std::vector + RicExportFractureCompletionsImpl::generateCompdatValues(RimEclipseCase* caseToApply, + const QString& wellPathName, + const RigWellPath* wellPathGeometry, + const std::vector& fractures, + std::vector* fractureDataReportItems, + QTextStream* outputStreamForIntermediateResultsText, + PressureDepletionParameters pdParams) { - double cDarcyInCorrectUnit = RiaEclipseUnitTools::darcysConstant(caseToApply->eclipseCaseData()->unitsType()); - const RigMainGrid* mainGrid = caseToApply->eclipseCaseData()->mainGrid(); + std::vector fractureCompletions; + + if (!caseToApply || !caseToApply->eclipseCaseData()) + { + return fractureCompletions; + } + + { + // Load the data required by computations to be able to use const access only inside OpenMP loop + + std::vector resultNames = RigEclipseToStimPlanCellTransmissibilityCalculator::requiredResultNames(); - // To handle several fractures in the same eclipse cell we need to keep track of the transmissibility + if (!caseToApply->loadStaticResultsByName(resultNames)) + { + QString msg; + msg += "Compdat Export : Required data missing. Required results "; + + for (const auto& r : resultNames) + { + msg += " "; + msg += r; + } + RiaLogging::error(msg); + + return fractureCompletions; + } + } + + { + // Load the data required by fracture summary header + + std::vector resultNames{"TRANX", "TRANY", "TRANZ"}; + + caseToApply->loadStaticResultsByName(resultNames); + } + + { + // Optional results + std::vector resultNames = RigEclipseToStimPlanCellTransmissibilityCalculator::optionalResultNames(); + + caseToApply->loadStaticResultsByName(resultNames); + } + + if (pdParams.performScaling) + { + RigCaseCellResultsData* results = caseToApply->results(RiaDefines::MATRIX_MODEL); + results->findOrLoadScalarResult(RiaDefines::DYNAMIC_NATIVE, "PRESSURE"); + } + + return generateCompdatValuesConst(caseToApply, + wellPathName, + wellPathGeometry, + fractures, + fractureDataReportItems, + outputStreamForIntermediateResultsText, + pdParams); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicExportFractureCompletionsImpl::generateCompdatValuesConst( + const RimEclipseCase* caseToApply, + const QString& wellPathName, + const RigWellPath* wellPathGeometry, + const std::vector& fractures, + std::vector* fractureDataReportItems, + QTextStream* outputStreamForIntermediateResultsText, + PressureDepletionParameters pdParams) +{ + std::vector fractureCompletions; + + if (!caseToApply || !caseToApply->eclipseCaseData()) + { + return fractureCompletions; + } + + double cDarcyInCorrectUnit = RiaEclipseUnitTools::darcysConstant(caseToApply->eclipseCaseData()->unitsType()); + const RigMainGrid* mainGrid = caseToApply->eclipseCaseData()->mainGrid(); + + const RigCaseCellResultsData* results = caseToApply->results(RiaDefines::MATRIX_MODEL); + size_t pressureResultIndex = results->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "PRESSURE"); + const RigActiveCellInfo* actCellInfo = caseToApply->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); + + bool performPressureDepletionScaling = pdParams.performScaling; + + int initialWellProductionTimeStep = 0; + double currentWellPressure = 0; + + if (performPressureDepletionScaling) + { + double userWBHP = pdParams.userWBHP; + + double initialWBHPFromSummary = 0.0; + double currentWBHPFromSummary = 0.0; + // Find well pressures (WBHP) from summary case. + getWellPressuresAndInitialProductionTimeStepFromSummaryData(caseToApply, + wellPathName, + pdParams.pressureScalingTimeStep, + &initialWellProductionTimeStep, + &initialWBHPFromSummary, + ¤tWBHPFromSummary); + + if (pdParams.wbhpSource == WBHP_FROM_SUMMARY) + { + currentWellPressure = currentWBHPFromSummary; + if (pdParams.pressureScalingTimeStep <= initialWellProductionTimeStep) + { + currentWellPressure = userWBHP; + } + } + else + { + currentWellPressure = userWBHP; + } + } + + const std::vector>* pressureResultVector = nullptr; + const std::vector* currentMatrixPressures = nullptr; + if (performPressureDepletionScaling) + { + pressureResultVector = &results->cellScalarResults(pressureResultIndex); + CVF_ASSERT(!pressureResultVector->empty()); + + if (pdParams.pressureScalingTimeStep < static_cast(pressureResultVector->size())) + { + currentMatrixPressures = &pressureResultVector->at(pdParams.pressureScalingTimeStep); + } + else + { + // Don't perform scaling if the current pressure time step is beyond the case range. + performPressureDepletionScaling = false; + } + } + + // To handle several fractures in the same eclipse cell we need to keep track of the transmissibility // to the well from each fracture intersecting the cell and sum these transmissibilities at the end. - // std::map > - std::map > eclCellIdxToTransPrFractureMap; - std::vector fractureCompletions; + // std::map > + // std::map> eclCellIdxToTransPrFractureMap; + + std::vector> sharedComplForFracture(fractures.size()); - for (RimFracture* fracture : fractures) +#pragma omp parallel for + for (int i = 0; i < (int)fractures.size(); i++) { - RimFractureTemplate* fracTemplate = fracture->fractureTemplate(); + const RimFracture* fracture = fractures[i]; + const RimFractureTemplate* fracTemplate = fracture->fractureTemplate(); if (!fracTemplate) continue; @@ -137,256 +296,479 @@ std::vector RicExportFractureCompletionsImpl::generateCompdat bool useFiniteConductivityInFracture = (fracTemplate->conductivityType() == RimFractureTemplate::FINITE_CONDUCTIVITY); - //If finite cond chosen and conductivity not present in stimplan file, do not calculate trans for this fracture - if (useFiniteConductivityInFracture) + // If finite cond chosen and conductivity not present in stimplan file, do not calculate trans for this fracture + if (useFiniteConductivityInFracture && !checkForStimPlanConductivity(fracTemplate, fracture)) { - if (dynamic_cast(fracTemplate)) - { - RimStimPlanFractureTemplate* fracTemplateStimPlan = dynamic_cast(fracTemplate); - if (!fracTemplateStimPlan->hasConductivity()) - { - RiaLogging::error("Trying to export completion data for stimPlan fracture without conductivity data for " + fracture->name()); - RiaLogging::error("No transmissibilities will be calculated for " + fracture->name()); - - continue; - } - } + continue; } - - using CellIdxSpace = RigTransmissibilityCondenser::CellAddress; RigTransmissibilityCondenser transCondenser; ////// - // Calculate Matrix To Fracture Trans + // Calculate Matrix To Fracture Trans + RigEclipseToStimPlanCalculator eclToFractureCalc( + caseToApply, fracture->transformMatrix(), fracTemplate->skinFactor(), cDarcyInCorrectUnit, *fractureGrid, fracture); - const std::vector& fractureCells = fractureGrid->fractureCells(); + eclToFractureCalc.appendDataToTransmissibilityCondenser(useFiniteConductivityInFracture, &transCondenser); - for (const RigFractureCell& fractureCell : fractureCells) + if (useFiniteConductivityInFracture) { - if (!fractureCell.hasNonZeroConductivity()) continue; - - RigEclipseToStimPlanCellTransmissibilityCalculator eclToFractureTransCalc(caseToApply, - fracture->transformMatrix(), - fracture->fractureTemplate()->skinFactor(), - cDarcyInCorrectUnit, - fractureCell); + calculateInternalFractureTransmissibilities(fractureGrid, cDarcyInCorrectUnit, transCondenser); + } - const std::vector& fractureCellContributingEclipseCells = eclToFractureTransCalc.globalIndeciesToContributingEclipseCells(); - const std::vector& fractureCellContributingEclipseCellTransmissibilities = eclToFractureTransCalc.contributingEclipseCellTransmissibilities(); - - size_t stimPlanCellIndex = fractureGrid->getGlobalIndexFromIJ(fractureCell.getI(), fractureCell.getJ()); + if (useFiniteConductivityInFracture) + { + calculateFractureToWellTransmissibilities( + fracTemplate, fractureGrid, fracture, cDarcyInCorrectUnit, wellPathGeometry, transCondenser); + } - for ( size_t i = 0; i < fractureCellContributingEclipseCells.size(); i++ ) - { - if ( fracture->isEclipseCellWithinContainment(caseToApply->eclipseCaseData()->mainGrid(), fractureCellContributingEclipseCells[i]) ) - { - if ( useFiniteConductivityInFracture ) - { - transCondenser.addNeighborTransmissibility({ true, CellIdxSpace::ECLIPSE, fractureCellContributingEclipseCells[i] }, - { false, CellIdxSpace::STIMPLAN, stimPlanCellIndex }, - fractureCellContributingEclipseCellTransmissibilities[i]); + ///// + // Insert total transmissibility from eclipse-cell to well for this fracture into the map + std::map matrixToWellTrans = calculateMatrixToWellTransmissibilities(transCondenser); - } - else - { - transCondenser.addNeighborTransmissibility({ true, CellIdxSpace::ECLIPSE, fractureCellContributingEclipseCells[i] }, - { true, CellIdxSpace::WELL, 1 }, - fractureCellContributingEclipseCellTransmissibilities[i]); - } - } + double maxPressureDrop = 0.0, minPressureDrop = 0.0; + if (performPressureDepletionScaling) + { + RigTransmissibilityCondenser scaledCondenser = transCondenser; + // 1. Scale matrix to fracture transmissibilities by matrix to fracture pressure + std::map originalLumpedMatrixToFractureTrans = scaledCondenser.scaleMatrixToFracTransByMatrixWellDP( + actCellInfo, + currentWellPressure, + *currentMatrixPressures, &minPressureDrop, &maxPressureDrop); + // 2: Calculate new external transmissibilities + scaledCondenser.calculateCondensedTransmissibilities(); + + { // 3: H�gst�l correction. + + // a. Calculate new effective fracture to well transmissiblities + std::map fictitiousFractureToWellTransmissibilities = + scaledCondenser.calculateFicticiousFractureToWellTransmissibilities(); + // b. Calculate new effective matrix to well transmissibilities + std::map effectiveMatrixToWellTrans = + scaledCondenser.calculateEffectiveMatrixToWellTransmissibilities(originalLumpedMatrixToFractureTrans, + fictitiousFractureToWellTransmissibilities); + matrixToWellTrans = effectiveMatrixToWellTrans; } + } + + std::vector allCompletionsForOneFracture = + generateCompdatValuesForFracture(matrixToWellTrans, wellPathName, caseToApply, fracture, fracTemplate); + if (fractureDataReportItems) + { + RicWellPathFractureReportItem reportItem( + wellPathName, fracture->name(), fracTemplate->name(), fracture->fractureMD()); + reportItem.setUnitSystem(fracTemplate->fractureTemplateUnit()); + reportItem.setPressureDepletionParameters(performPressureDepletionScaling, + caseToApply->timeStepStrings()[pdParams.pressureScalingTimeStep], + caf::AppEnum::uiTextFromIndex(pdParams.wbhpSource), + pdParams.userWBHP, currentWellPressure, minPressureDrop, maxPressureDrop); + + RicExportFractureCompletionsImpl::calculateAndSetReportItemData( + allCompletionsForOneFracture, eclToFractureCalc, reportItem); + +#pragma omp critical(critical_section_fractureDataReportItems) + { + fractureDataReportItems->push_back(reportItem); + } } - ////// - // Calculate Transmissibility in the fracture: From one StimPlan Cell to the other + std::copy(allCompletionsForOneFracture.begin(), + allCompletionsForOneFracture.end(), + std::back_inserter(sharedComplForFracture[i])); - if (useFiniteConductivityInFracture) + if (outputStreamForIntermediateResultsText) { - for (size_t i = 0; i < fractureGrid->iCellCount(); i++) +#pragma omp critical(critical_section_outputStreamForIntermediateResultsText) { - for (size_t j = 0; j < fractureGrid->jCellCount(); j++) - { - size_t fractureCellIndex = fractureGrid->getGlobalIndexFromIJ(i, j); - - const RigFractureCell& fractureCell = fractureGrid->cellFromIndex(fractureCellIndex); + outputIntermediateResultsText( + outputStreamForIntermediateResultsText, fracture, transCondenser, mainGrid, fractureGrid); + } + } + } - if (!fractureCell.hasNonZeroConductivity()) continue; + for (const auto& completions : sharedComplForFracture) + { + std::copy(completions.begin(), completions.end(), std::back_inserter(fractureCompletions)); + } + return fractureCompletions; +} - if ( i < fractureGrid->iCellCount() - 1 ) - { - size_t fractureCellNeighbourXIndex = fractureGrid->getGlobalIndexFromIJ(i + 1, j); - const RigFractureCell& fractureCellNeighbourX = fractureGrid->cellFromIndex(fractureCellNeighbourXIndex); - - double horizontalTransToXneigbour = - RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans(fractureCell.getConductivtyValue(), - fractureCell.cellSizeX(), - fractureCell.cellSizeZ(), - fractureCellNeighbourX.getConductivtyValue(), - fractureCellNeighbourX.cellSizeX(), - fractureCellNeighbourX.cellSizeZ(), - cDarcyInCorrectUnit); - - transCondenser.addNeighborTransmissibility({ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex }, - { false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourXIndex }, - horizontalTransToXneigbour); - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportFractureCompletionsImpl::getWellPressuresAndInitialProductionTimeStepFromSummaryData( + const RimEclipseCase* caseToApply, + const QString& wellPathName, + int currentTimeStep, + int* initialCaseTimeStep, + double* initialWellPressure, + double* currentWellPressure) +{ + const RimEclipseResultCase* resultCase = dynamic_cast(caseToApply); + if (resultCase) + { + std::vector caseTimeSteps = resultCase->timeStepDates(); + QDateTime initialProductionDate; + QDateTime currentDate; + if (currentTimeStep < static_cast(caseTimeSteps.size())) + { + currentDate = caseTimeSteps[currentTimeStep]; + } + else + { + currentDate = caseTimeSteps.back(); + } - if ( j < fractureGrid->jCellCount() - 1 ) + RifEclipseSummaryAddress wbhpPressureAddress = RifEclipseSummaryAddress::wellAddress("WBHP", wellPathName.toStdString()); + RimSummaryCaseMainCollection* mainCollection = RiaSummaryTools::summaryCaseMainCollection(); + if (mainCollection) + { + RimSummaryCase* summaryCase = mainCollection->findSummaryCaseFromEclipseResultCase(resultCase); + + if (summaryCase) + { + std::vector values; + if (summaryCase->summaryReader()->values(wbhpPressureAddress, &values)) + { + std::vector summaryTimeSteps = summaryCase->summaryReader()->timeSteps(wbhpPressureAddress); + CVF_ASSERT(values.size() == summaryTimeSteps.size()); + for (size_t i = 0; i < summaryTimeSteps.size(); ++i) { - size_t fractureCellNeighbourZIndex = fractureGrid->getGlobalIndexFromIJ(i, j + 1); - const RigFractureCell& fractureCellNeighbourZ = fractureGrid->cellFromIndex(fractureCellNeighbourZIndex); - - double verticalTransToZneigbour = - RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans(fractureCell.getConductivtyValue(), - fractureCell.cellSizeZ(), - fractureCell.cellSizeX(), - fractureCellNeighbourZ.getConductivtyValue(), - fractureCellNeighbourZ.cellSizeZ(), - fractureCellNeighbourZ.cellSizeX(), - cDarcyInCorrectUnit); - - transCondenser.addNeighborTransmissibility({ false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex }, - { false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourZIndex }, - verticalTransToZneigbour); + QDateTime summaryDate = RiaQDateTimeTools::fromTime_t(summaryTimeSteps[i]); + if (initialProductionDate.isNull() && values[i] > 0.0) + { + initialProductionDate = summaryDate; + *initialWellPressure = values[i]; + } + if (summaryDate <= currentDate) + { + *currentWellPressure = values[i]; + } } } - } + } } - - ///// - // Calculate transmissibility into the well - - if (useFiniteConductivityInFracture) + if (initialProductionDate.isValid()) { - //// - //If fracture has orientation Azimuth or Transverse, assume only radial inflow - - if ( fracture->fractureTemplate()->orientationType() == RimFractureTemplate::AZIMUTH - || fracture->fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) + for (size_t i = 0; i < caseTimeSteps.size(); ++i) { - const RigFractureGrid* fracGrid = fracture->fractureTemplate()->fractureGrid(); - if (fracGrid) + // Pick last time step that isn't bigger than the initial production time. + if (caseTimeSteps[i] < initialProductionDate) + { + *initialCaseTimeStep = static_cast(i); + } + else { - std::pair wellCellIJ = fracGrid->fractureCellAtWellCenter(); - size_t wellCellIndex = fracGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second); + break; + } + } + } + } +} - const RigFractureCell& wellCell = fractureGrid->cellFromIndex(wellCellIndex); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExportFractureCompletionsImpl::checkForStimPlanConductivity(const RimFractureTemplate* fracTemplate, + const RimFracture* fracture) +{ + auto fracTemplateStimPlan = dynamic_cast(fracTemplate); + if (fracTemplateStimPlan) + { + if (!fracTemplateStimPlan->hasConductivity()) + { + RiaLogging::error("Trying to export completion data for stimPlan fracture without conductivity data for " + + fracture->name()); + RiaLogging::error("No transmissibilities will be calculated for " + fracture->name()); + return false; + } + } + return true; +} - double radialTrans = RigFractureTransmissibilityEquations::fractureCellToWellRadialTrans(wellCell.getConductivtyValue(), - wellCell.cellSizeX(), - wellCell.cellSizeZ(), - fracture->wellRadius(), - fracTemplate->skinFactor(), - cDarcyInCorrectUnit); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportFractureCompletionsImpl::calculateInternalFractureTransmissibilities(const RigFractureGrid* fractureGrid, + double cDarcyInCorrectUnit, + RigTransmissibilityCondenser& transCondenser) +{ + for (size_t i = 0; i < fractureGrid->iCellCount(); i++) + { + for (size_t j = 0; j < fractureGrid->jCellCount(); j++) + { + size_t fractureCellIndex = fractureGrid->getGlobalIndexFromIJ(i, j); - transCondenser.addNeighborTransmissibility({ true, RigTransmissibilityCondenser::CellAddress::WELL, 1 }, - { false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, wellCellIndex }, - radialTrans); - } + const RigFractureCell& fractureCell = fractureGrid->cellFromIndex(fractureCellIndex); + + if (!fractureCell.hasNonZeroConductivity()) continue; + + if (i < fractureGrid->iCellCount() - 1) + { + size_t fractureCellNeighbourXIndex = fractureGrid->getGlobalIndexFromIJ(i + 1, j); + const RigFractureCell& fractureCellNeighbourX = fractureGrid->cellFromIndex(fractureCellNeighbourXIndex); + + double horizontalTransToXneigbour = RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans( + fractureCell.getConductivityValue(), + fractureCell.cellSizeX(), + fractureCell.cellSizeZ(), + fractureCellNeighbourX.getConductivityValue(), + fractureCellNeighbourX.cellSizeX(), + fractureCellNeighbourX.cellSizeZ(), + cDarcyInCorrectUnit); + + transCondenser.addNeighborTransmissibility( + {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex}, + {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourXIndex}, + horizontalTransToXneigbour); } - else if (fracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) + + if (j < fractureGrid->jCellCount() - 1) { + size_t fractureCellNeighbourZIndex = fractureGrid->getGlobalIndexFromIJ(i, j + 1); + const RigFractureCell& fractureCellNeighbourZ = fractureGrid->cellFromIndex(fractureCellNeighbourZIndex); + + double verticalTransToZneigbour = RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans( + fractureCell.getConductivityValue(), + fractureCell.cellSizeZ(), + fractureCell.cellSizeX(), + fractureCellNeighbourZ.getConductivityValue(), + fractureCellNeighbourZ.cellSizeZ(), + fractureCellNeighbourZ.cellSizeX(), + cDarcyInCorrectUnit); + + transCondenser.addNeighborTransmissibility( + {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellIndex}, + {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fractureCellNeighbourZIndex}, + verticalTransToZneigbour); + } + } + } +} - //// - //If fracture has orientation along well, linear inflow along well and radial flow at endpoints +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportFractureCompletionsImpl::calculateFractureToWellTransmissibilities(const RimFractureTemplate* fracTemplate, + const RigFractureGrid* fractureGrid, + const RimFracture* fracture, + double cDarcyInCorrectUnit, + const RigWellPath* wellPathGeometry, + RigTransmissibilityCondenser& transCondenser) +{ + //// + // If fracture has orientation Azimuth or Transverse, assume only radial inflow - RigWellPathStimplanIntersector wellFractureIntersector(wellPathGeometry, fracture); - const std::map& fractureWellCells = wellFractureIntersector.intersections(); + if (fracTemplate->orientationType() == RimFractureTemplate::AZIMUTH || + fracTemplate->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) + { + std::pair wellCellIJ = fractureGrid->fractureCellAtWellCenter(); + size_t wellCellIndex = fractureGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second); - for (const auto& fracCellIdxIsectDataPair : fractureWellCells) - { - size_t fracWellCellIdx = fracCellIdxIsectDataPair.first; + const RigFractureCell& wellCell = fractureGrid->cellFromIndex(wellCellIndex); - RigWellPathStimplanIntersector::WellCellIntersection intersection = fracCellIdxIsectDataPair.second; + double radialTrans = RigFractureTransmissibilityEquations::fractureCellToWellRadialTrans(wellCell.getConductivityValue(), + wellCell.cellSizeX(), + wellCell.cellSizeZ(), + fracture->wellRadius(), + fracTemplate->skinFactor(), + cDarcyInCorrectUnit); - const RigFractureCell& fractureWellCell = fractureGrid->cellFromIndex(fracWellCellIdx); + transCondenser.addNeighborTransmissibility({true, RigTransmissibilityCondenser::CellAddress::WELL, 1}, + {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, wellCellIndex}, + radialTrans); + } + else if (fracTemplate->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) + { + //// + // If fracture has orientation along well, linear inflow along well and radial flow at endpoints - double linearTrans = 0.0; - if (intersection.hlength > 0.0 || intersection.vlength > 0.0) - { - linearTrans = RigFractureTransmissibilityEquations::fractureCellToWellLinearTrans(fractureWellCell.getConductivtyValue(), - fractureWellCell.cellSizeX(), - fractureWellCell.cellSizeZ(), - intersection.vlength, - intersection.hlength, - fracture->perforationEfficiency(), - fracTemplate->skinFactor(), - cDarcyInCorrectUnit); - } + RigWellPathStimplanIntersector wellFractureIntersector(wellPathGeometry, fracture); + const std::map& fractureWellCells = + wellFractureIntersector.intersections(); - transCondenser.addNeighborTransmissibility({ true, RigTransmissibilityCondenser::CellAddress::WELL, 1 }, - { false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fracWellCellIdx }, - linearTrans); - } - } - } + for (const auto& fracCellIdxIsectDataPair : fractureWellCells) + { + size_t fracWellCellIdx = fracCellIdxIsectDataPair.first; - ///// - // Insert total transmissibility from eclipse-cell to well for this fracture into the map + RigWellPathStimplanIntersector::WellCellIntersection intersection = fracCellIdxIsectDataPair.second; - std::vector allCompletionsForOneFracture; + const RigFractureCell& fractureWellCell = fractureGrid->cellFromIndex(fracWellCellIdx); - std::set externalCells = transCondenser.externalCells(); - for (RigTransmissibilityCondenser::CellAddress externalCell : externalCells) - { - if (externalCell.m_cellIndexSpace == RigTransmissibilityCondenser::CellAddress::ECLIPSE) + double linearTrans = 0.0; + if (intersection.hlength > 0.0 || intersection.vlength > 0.0) { - double trans = transCondenser.condensedTransmissibility(externalCell, { true, RigTransmissibilityCondenser::CellAddress::WELL, 1 }); - - eclCellIdxToTransPrFractureMap[externalCell.m_globalCellIdx][fracture] = trans; - - RigCompletionData compDat(wellPathName, - RigCompletionDataGridCell(externalCell.m_globalCellIdx, caseToApply->mainGrid()), - fracture->fractureMD()); - - double diameter = 2.0 * fracture->wellRadius(); - compDat.setFromFracture(trans, fracture->fractureTemplate()->skinFactor(), diameter); - compDat.addMetadata(fracture->name(), QString::number(trans)); - allCompletionsForOneFracture.push_back(compDat); + linearTrans = + RigFractureTransmissibilityEquations::fractureCellToWellLinearTrans(fractureWellCell.getConductivityValue(), + fractureWellCell.cellSizeX(), + fractureWellCell.cellSizeZ(), + intersection.vlength, + intersection.hlength, + fracture->perforationEfficiency(), + fracTemplate->skinFactor(), + cDarcyInCorrectUnit, + fracture->wellRadius()); } + + transCondenser.addNeighborTransmissibility( + {true, RigTransmissibilityCondenser::CellAddress::WELL, 1}, + {false, RigTransmissibilityCondenser::CellAddress::STIMPLAN, fracWellCellIdx}, + linearTrans); } + } +} - ///// - // Compute Non-Dracy Flow parameters +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map + RicExportFractureCompletionsImpl::calculateMatrixToWellTransmissibilities(RigTransmissibilityCondenser& transCondenser) +{ + std::map matrixToWellTransmissibilities; - if (fracture->fractureTemplate()->isNonDarcyFlowEnabled()) + std::set externalCells = transCondenser.externalCells(); + for (RigTransmissibilityCondenser::CellAddress externalCell : externalCells) + { + if (externalCell.m_cellIndexSpace == RigTransmissibilityCondenser::CellAddress::ECLIPSE) { - double dFactorForFracture = fracture->fractureTemplate()->dFactor(); - double khForFracture = fracture->fractureTemplate()->kh(); + double trans = transCondenser.condensedTransmissibility(externalCell, + {true, RigTransmissibilityCondenser::CellAddress::WELL, 1}); - double sumOfTransmissibilitiesInFracture = 0.0; - for (const auto& c : allCompletionsForOneFracture) - { - sumOfTransmissibilitiesInFracture += c.transmissibility(); - } + matrixToWellTransmissibilities.insert(std::make_pair(externalCell.m_globalCellIdx, trans)); + } + } + return matrixToWellTransmissibilities; +} - for (auto& c : allCompletionsForOneFracture) - { - // NOTE : What is supposed to happen when the transmissibility is close to zero? +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicExportFractureCompletionsImpl::generateCompdatValuesForFracture( + const std::map& matrixToWellTransmissibilites, + const QString& wellPathName, + const RimEclipseCase* caseToApply, + const RimFracture* fracture, + const RimFractureTemplate* fracTemplate) +{ + std::vector allCompletionsForOneFracture; + for (const auto& matrixToWellTransmissibility : matrixToWellTransmissibilites) + { + size_t globalCellIndex = matrixToWellTransmissibility.first; + double trans = matrixToWellTransmissibility.second; + RigCompletionData compDat( + wellPathName, RigCompletionDataGridCell(globalCellIndex, caseToApply->mainGrid()), fracture->fractureMD()); + + double diameter = 2.0 * fracture->wellRadius(); + compDat.setFromFracture(trans, fracTemplate->skinFactor(), diameter); + compDat.addMetadata(fracture->name(), QString::number(trans)); + compDat.setSourcePdmObject(fracture); + allCompletionsForOneFracture.push_back(compDat); + } - double dFactorForOneConnection = dFactorForFracture * sumOfTransmissibilitiesInFracture / c.transmissibility(); - c.setDFactor(dFactorForOneConnection); + if (fracTemplate->isNonDarcyFlowEnabled()) + { + computeNonDarcyFlowParameters(fracture, allCompletionsForOneFracture); + } - double khForOneConnection = khForFracture * c.transmissibility() / sumOfTransmissibilitiesInFracture; + return allCompletionsForOneFracture; +} - c.setKh(khForOneConnection); - } - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportFractureCompletionsImpl::computeNonDarcyFlowParameters(const RimFracture* fracture, + std::vector& allCompletionsForOneFracture) +{ + double dFactorForFracture = fracture->nonDarcyProperties().dFactor; + double khForFracture = fracture->nonDarcyProperties().conductivity; + + double sumOfTransmissibilitiesInFracture = sumUpTransmissibilities(allCompletionsForOneFracture); + + for (auto& c : allCompletionsForOneFracture) + { + // NOTE : What is supposed to happen when the transmissibility is close to zero? - std::copy(allCompletionsForOneFracture.begin(), allCompletionsForOneFracture.end(), std::back_inserter(fractureCompletions)); + double dFactorForOneConnection = dFactorForFracture * sumOfTransmissibilitiesInFracture / c.transmissibility(); + c.setDFactor(dFactorForOneConnection); - if ( outputStreamForIntermediateResultsText ) + double khForOneConnection = khForFracture * c.transmissibility() / sumOfTransmissibilitiesInFracture; + + c.setKh(khForOneConnection); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double + RicExportFractureCompletionsImpl::sumUpTransmissibilities(const std::vector& allCompletionsForOneFracture) +{ + double transmissibility = 0.0; + for (const auto& c : allCompletionsForOneFracture) + { + transmissibility += c.transmissibility(); + } + return transmissibility; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportFractureCompletionsImpl::calculateAndSetReportItemData( + const std::vector& allCompletionsForOneFracture, + const RigEclipseToStimPlanCalculator& eclToFractureCalc, + RicWellPathFractureReportItem& reportItem) +{ + double areaWeightedMatrixPermeability = eclToFractureCalc.areaWeightedMatrixPermeability(); + reportItem.setAreaWeightedPermeability(areaWeightedMatrixPermeability); + + double totalAreaOpenForFlow = eclToFractureCalc.totalEclipseAreaOpenForFlow(); + double areaWeightedConductivity = eclToFractureCalc.areaWeightedConductivity(); + + if (totalAreaOpenForFlow > 0.0) + { + double halfLength = 0.0; + double height = eclToFractureCalc.longestYSectionOpenForFlow(); + if (height > 0.0) { - (*outputStreamForIntermediateResultsText) << "\n" << "\n" << "\n----------- All Transimissibilities " << fracture->name() << " -------------------- \n\n"; - (*outputStreamForIntermediateResultsText) << QString::fromStdString(transCondenser.neighborTransDebugOutput(mainGrid, fractureGrid)); - (*outputStreamForIntermediateResultsText) << "\n" << "\n" << "\n----------- Condensed Results " << fracture->name() << " -------------------- \n\n"; - (*outputStreamForIntermediateResultsText) << QString::fromStdString(transCondenser.condensedTransDebugOutput(mainGrid, fractureGrid)); - (*outputStreamForIntermediateResultsText) << "\n" ; + double length = totalAreaOpenForFlow / height; + halfLength = length / 2.0; } - } - return fractureCompletions; + reportItem.setHeightAndHalfLength(height, halfLength); + } + + double aggregatedTransmissibility = sumUpTransmissibilities(allCompletionsForOneFracture); + reportItem.setData(aggregatedTransmissibility, allCompletionsForOneFracture.size(), totalAreaOpenForFlow); + + reportItem.setWidthAndConductivity(eclToFractureCalc.areaWeightedWidth(), areaWeightedConductivity); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportFractureCompletionsImpl::outputIntermediateResultsText(QTextStream* outputStreamForIntermediateResultsText, + const RimFracture* fracture, + RigTransmissibilityCondenser& transCondenser, + const RigMainGrid* mainGrid, + const RigFractureGrid* fractureGrid) +{ + (*outputStreamForIntermediateResultsText) + << "\n" + << "\n" + << "\n----------- All Transmissibilities " << fracture->name() << " -------------------- \n\n"; + + (*outputStreamForIntermediateResultsText) + << QString::fromStdString(transCondenser.neighborTransDebugOutput(mainGrid, fractureGrid)); + + (*outputStreamForIntermediateResultsText) + << "\n" + << "\n" + << "\n----------- Condensed Results " << fracture->name() << " -------------------- \n\n"; + + (*outputStreamForIntermediateResultsText) + << QString::fromStdString(transCondenser.condensedTransDebugOutput(mainGrid, fractureGrid)); + + (*outputStreamForIntermediateResultsText) << "\n"; +} diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.h b/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.h index cbb79cf57f..643222f059 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFractureCompletionsImpl.h @@ -1,55 +1,144 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once - #include "RigCompletionData.h" +#include #include -class RimWellPath; -class RicExportCompletionDataSettingsUi; - -class QTextStream; +class RigFractureGrid; +class RicWellPathFractureReportItem; class RigWellPath; +class RigTransmissibilityCondenser; +class RigEclipseToStimPlanCalculator; + class RimEclipseCase; class RimFracture; +class RimFractureTemplate; class RimSimWellInView; +class RimWellPath; + +class QTextStream; +class QString; //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- class RicExportFractureCompletionsImpl { public: + + enum PressureDepletionWBHPSource + { + WBHP_FROM_SUMMARY, + WBHP_FROM_USER_DEF + }; + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + struct PressureDepletionParameters + { + PressureDepletionParameters(bool performScaling = false, + int pressureScalingTimeStep = 0, + PressureDepletionWBHPSource wbhpSource = WBHP_FROM_SUMMARY, + double userWBHP = 200.0) + : performScaling(performScaling) + , pressureScalingTimeStep(pressureScalingTimeStep) + , wbhpSource(wbhpSource) + , userWBHP(userWBHP) + {} + + bool performScaling; + int pressureScalingTimeStep; + PressureDepletionWBHPSource wbhpSource; + double userWBHP; + }; + static std::vector generateCompdatValuesForWellPath(RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings, - QTextStream* outputStreamForIntermediateResultsText); + RimEclipseCase* caseToApply, + std::vector* fractureDataForReport, + QTextStream* outputStreamForIntermediateResultsText, + PressureDepletionParameters pdParams = PressureDepletionParameters()); static std::vector generateCompdatValuesForSimWell(RimEclipseCase* eclipseCase, const RimSimWellInView* well, - QTextStream* outputStreamForIntermediateResultsText); + QTextStream* outputStreamForIntermediateResultsText, + PressureDepletionParameters pdParams = PressureDepletionParameters()); -private: static std::vector generateCompdatValues(RimEclipseCase* caseToApply, const QString& wellPathName, const RigWellPath* wellPathGeometry, - const std::vector& fractures, - QTextStream* outputStreamForIntermediateResultsText); + const std::vector& fractures, + std::vector* fractureDataReportItems, + QTextStream* outputStreamForIntermediateResultsText, + PressureDepletionParameters pdParams = PressureDepletionParameters()); + + static void getWellPressuresAndInitialProductionTimeStepFromSummaryData(const RimEclipseCase* caseToApply, + const QString& wellPathName, + int currentTimeStep, + int* initialTimeStep, + double* initialWellPressure, + double* currentWellPressure); + +private: + static std::vector generateCompdatValuesConst(const RimEclipseCase* caseToApply, + const QString& wellPathName, + const RigWellPath* wellPathGeometry, + const std::vector& fractures, + std::vector* fractureDataReportItems, + QTextStream* outputStreamForIntermediateResultsText, + PressureDepletionParameters pdParams); + + static bool checkForStimPlanConductivity(const RimFractureTemplate* fracTemplate, const RimFracture* fracture); + + static void calculateInternalFractureTransmissibilities(const RigFractureGrid* fractureGrid, + double cDarcyInCorrectUnit, + RigTransmissibilityCondenser& transCondenser); + + static void calculateFractureToWellTransmissibilities(const RimFractureTemplate* fracTemplate, + const RigFractureGrid* fractureGrid, + const RimFracture* fracture, + double cDarcyInCorrectUnit, + const RigWellPath* wellPathGeometry, + RigTransmissibilityCondenser& transCondenser); + + static std::map calculateMatrixToWellTransmissibilities(RigTransmissibilityCondenser& transCondenser); + + static std::vector generateCompdatValuesForFracture(const std::map& matrixToWellTransmissibilites, + const QString& wellPathName, + const RimEclipseCase* caseToApply, + const RimFracture* fracture, + const RimFractureTemplate* fracTemplate); + + static void computeNonDarcyFlowParameters(const RimFracture* fracture, std::vector& allCompletionsForOneFracture); + + static double sumUpTransmissibilities(const std::vector& allCompletionsForOneFracture); + + static void calculateAndSetReportItemData(const std::vector& allCompletionsForOneFracture, + const RigEclipseToStimPlanCalculator& calculator, + RicWellPathFractureReportItem& reportItem); + + static void outputIntermediateResultsText(QTextStream* outputStreamForIntermediateResultsText, + const RimFracture* fracture, + RigTransmissibilityCondenser& transCondenser, + const RigMainGrid* mainGrid, + const RigFractureGrid* fractureGrid); }; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicExportFracturesWellSegmentsFeature.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicExportFracturesWellSegmentsFeature.cpp new file mode 100644 index 0000000000..d1b87bd49d --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFracturesWellSegmentsFeature.cpp @@ -0,0 +1,168 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicExportFracturesWellSegmentsFeature.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" + +#include "RicCaseAndFileExportSettingsUi.h" +#include "RicExportFeatureImpl.h" +#include "RicMultiSegmentWellExportInfo.h" +#include "RicWellPathExportCompletionDataFeatureImpl.h" + +#include "RimProject.h" +#include "RimWellPath.h" +#include "RimWellPathFracture.h" +#include "RimWellPathFractureCollection.h" + +#include "RifEclipseDataTableFormatter.h" + +#include "Riu3DMainWindowTools.h" + +#include "cafSelectionManager.h" +#include "cafPdmUiPropertyViewDialog.h" +#include "cafUtils.h" + +#include +#include + + +CAF_CMD_SOURCE_INIT(RicExportFracturesWellSegmentsFeature, "RicExportFracturesWellSegmentsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportFracturesWellSegmentsFeature::exportWellSegments(const RimWellPath* wellPath, const std::vector& fractures, const RicCaseAndFileExportSettingsUi& settings) +{ + if (settings.caseToApply() == nullptr) + { + RiaLogging::error("Export Fracture Well Segments: Cannot export completions data without specified eclipse case"); + return; + } + + QString fileName = QString("%1-Fracture-Welsegs").arg(settings.caseToApply()->caseUserDescription()); + fileName = caf::Utils::makeValidFileBasename(fileName); + + QDir exportFolder(settings.folder()); + if (!exportFolder.exists()) + { + bool createdPath = exportFolder.mkpath("."); + if (createdPath) + RiaLogging::info("Export Fracture Well Segments: Created export folder " + settings.folder()); + else + RiaLogging::error("Export Fracture Well Segments: Selected output folder does not exist, and could not be created."); + } + + QString filePath = exportFolder.filePath(fileName); + QFile exportFile(filePath); + if (!exportFile.open(QIODevice::WriteOnly | QIODevice::Text)) + { + RiaLogging::error(QString("Export Fracture Well Segments: Could not open the file: %1").arg(filePath)); + return; + } + + RicMswExportInfo exportInfo = RicWellPathExportCompletionDataFeatureImpl::generateFracturesMswExportInfo(settings.caseToApply, wellPath, fractures); + + QTextStream stream(&exportFile); + RifEclipseDataTableFormatter formatter(stream); + RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(formatter, exportInfo); + RicWellPathExportCompletionDataFeatureImpl::generateCompsegTables(formatter, exportInfo); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportFracturesWellSegmentsFeature::onActionTriggered(bool isChecked) +{ + RimWellPath* wellPath = caf::SelectionManager::instance()->selectedItemAncestorOfType(); + RimWellPathFracture* fracture = caf::SelectionManager::instance()->selectedItemAncestorOfType(); + RimWellPathFractureCollection* collection = caf::SelectionManager::instance()->selectedItemAncestorOfType(); + + CVF_ASSERT(wellPath); + CVF_ASSERT(collection); + + RiaApplication* app = RiaApplication::instance(); + + QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallbackToProjectFolder("COMPLETIONS"); + + RicCaseAndFileExportSettingsUi exportSettings; + std::vector cases; + app->project()->allCases(cases); + for (auto c : cases) + { + RimEclipseCase* eclipseCase = dynamic_cast(c); + if (eclipseCase != nullptr) + { + exportSettings.caseToApply = eclipseCase; + break; + } + } + + exportSettings.folder = defaultDir; + + caf::PdmUiPropertyViewDialog propertyDialog(Riu3DMainWindowTools::mainWindowWidget(), &exportSettings, "Export Fractures as Multi Segment Wells", ""); + RicExportFeatureImpl::configureForExport(&propertyDialog); + + if (propertyDialog.exec() == QDialog::Accepted) + { + RiaApplication::instance()->setLastUsedDialogDirectory("COMPLETIONS", QFileInfo(exportSettings.folder).absolutePath()); + std::vector fractures; + if (fracture) + { + fractures.push_back(fracture); + } + else + { + for (RimWellPathFracture* activeFracture : collection->activeFractures()) + { + fractures.push_back(activeFracture); + } + } + + exportWellSegments(wellPath, fractures, exportSettings); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportFracturesWellSegmentsFeature::setupActionLook(QAction* actionToSetup) +{ + if (caf::SelectionManager::instance()->selectedItemOfType()) + { + actionToSetup->setText("Export Fracture as Multi Segment Well"); + } + else + { + actionToSetup->setText("Export Fractures as Multi Segment Well"); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExportFracturesWellSegmentsFeature::isCommandEnabled() +{ + if (RiaApplication::enableDevelopmentFeatures() && caf::SelectionManager::instance()->selectedItemAncestorOfType()) + { + return true; + } + + return false; +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.h b/ApplicationCode/Commands/CompletionExportCommands/RicExportFracturesWellSegmentsFeature.h similarity index 62% rename from ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.h rename to ApplicationCode/Commands/CompletionExportCommands/RicExportFracturesWellSegmentsFeature.h index f97ec5c768..aac083976f 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeatureUi.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicExportFracturesWellSegmentsFeature.h @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) 2016 Statoil ASA +// 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 @@ -18,29 +18,26 @@ #pragma once -#include "cafPdmObject.h" -#include "cafPdmPtrField.h" -#include "cafPdmUiOrdering.h" +#include "RicCaseAndFileExportSettingsUi.h" -class RimCase; -class RimWellPath; +#include "cafCmdFeature.h" +class RimWellPath; +class RimWellPathFracture; +class RimWellPathFractureCollection; //================================================================================================== /// //================================================================================================== -class RicChangeDataSourceFeatureUi : public caf::PdmObject +class RicExportFracturesWellSegmentsFeature : public caf::CmdFeature { - CAF_PDM_HEADER_INIT; + CAF_CMD_HEADER_INIT; public: - RicChangeDataSourceFeatureUi(); - - caf::PdmPtrField caseToApply; - caf::PdmPtrField wellPathToApply; + static void exportWellSegments(const RimWellPath* wellPath, const std::vector& fractures, const RicCaseAndFileExportSettingsUi& settings); protected: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; }; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp index e4775e46c6..378d19cc8b 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -28,24 +28,31 @@ #include "RigWellPath.h" #include "RigWellPathIntersectionTools.h" +#include "RigWellLogExtractor.h" #include "RimFishboneWellPath.h" #include "RimFishboneWellPathCollection.h" #include "RimFishbonesCollection.h" #include "RimFishbonesMultipleSubs.h" #include "RimWellPath.h" #include "RimWellPathCompletions.h" -#include "RigWellLogExtractor.h" + +#include +#include //================================================================================================== -/// +/// //================================================================================================== struct WellBorePartForTransCalc { WellBorePartForTransCalc(cvf::Vec3d lengthsInCell, double wellRadius, double skinFactor, bool isMainBore, QString metaData) - : lengthsInCell(lengthsInCell), wellRadius(wellRadius), skinFactor(skinFactor), isMainBore(isMainBore), metaData(metaData) + : lengthsInCell(lengthsInCell) + , wellRadius(wellRadius) + , skinFactor(skinFactor) + , isMainBore(isMainBore) + , metaData(metaData) + , intersectionWithWellMeasuredDepth(HUGE_VAL) + , lateralIndex(cvf::UNDEFINED_SIZE_T) { - intersectionWithWellMeasuredDepth = HUGE_VAL; - lateralIndex = cvf::UNDEFINED_SIZE_T; } cvf::Vec3d lengthsInCell; @@ -54,56 +61,20 @@ struct WellBorePartForTransCalc QString metaData; bool isMainBore; - double intersectionWithWellMeasuredDepth; - size_t lateralIndex; -}; - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWellBoreParts(std::map >& wellBorePartsInCells, - const RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings) -{ - if (!wellPath) return; - - // Generate data - const RigEclipseCaseData* caseData = settings.caseToApply()->eclipseCaseData(); - std::vector locations = RicWellPathExportCompletionDataFeatureImpl::findWellSegmentLocations(settings.caseToApply, wellPath); - - RiaEclipseUnitTools::UnitSystem unitSystem = caseData->unitsType(); - bool isMainBore = false; - - for (const WellSegmentLocation& location : locations) - { - for (const WellSegmentLateral& lateral : location.laterals) - { - for (const WellSegmentLateralIntersection& intersection : lateral.intersections) - { - double diameter = location.fishbonesSubs->holeDiameter(unitSystem); - QString completionMetaData = (location.fishbonesSubs->generatedName() + QString(": Sub: %1 Lateral: %2").arg(location.subIndex).arg(lateral.lateralIndex)); - WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc(intersection.lengthsInCell, - diameter / 2, - location.fishbonesSubs->skinFactor(), - isMainBore, - completionMetaData); + double intersectionWithWellMeasuredDepth; + size_t lateralIndex; - wellBorePart.intersectionWithWellMeasuredDepth = location.measuredDepth; - wellBorePart.lateralIndex = lateral.lateralIndex; - - wellBorePartsInCells[intersection.globalCellIndex].push_back(wellBorePart); - - } - } - } - -} + void setSourcePdmObject(const caf::PdmObject* sourcePdmObj) { this->sourcePdmObject = const_cast(sourcePdmObj); } + caf::PdmPointer sourcePdmObject; +}; //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RicFishbonesTransmissibilityCalculationFeatureImp::generateFishboneCompdatValuesUsingAdjustedCellVolume(const RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings) +std::vector + RicFishbonesTransmissibilityCalculationFeatureImp::generateFishboneCompdatValuesUsingAdjustedCellVolume( + const RimWellPath* wellPath, + const RicExportCompletionDataSettingsUi& settings) { std::vector completionData; @@ -111,28 +82,24 @@ std::vector RicFishbonesTransmissibilityCalculationFeatureImp { return completionData; } - - std::map > wellBorePartsInCells; //wellBore = main bore or fishbone lateral + + std::map> wellBorePartsInCells; // wellBore = main bore or fishbone lateral findFishboneLateralsWellBoreParts(wellBorePartsInCells, wellPath, settings); findFishboneImportedLateralsWellBoreParts(wellBorePartsInCells, wellPath, settings); - if (!wellBorePartsInCells.empty() && !settings.excludeMainBoreForFishbones) - { - findMainWellBoreParts(wellBorePartsInCells, wellPath, settings); - } const RigActiveCellInfo* activeCellInfo = settings.caseToApply->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); for (const auto& cellAndWellBoreParts : wellBorePartsInCells) { - size_t globalCellIndex = cellAndWellBoreParts.first; - const std::vector& wellBoreParts = cellAndWellBoreParts.second; + size_t globalCellIndex = cellAndWellBoreParts.first; + const std::vector& wellBoreParts = cellAndWellBoreParts.second; bool cellIsActive = activeCellInfo->isActive(globalCellIndex); if (!cellIsActive) continue; // Find main bore and number of laterals - size_t numberOfLaterals = 0; + size_t numberOfLaterals = 0; CellDirection mainBoreDirection = DIR_I; for (const auto& wellBorePart : wellBoreParts) { @@ -142,57 +109,65 @@ std::vector RicFishbonesTransmissibilityCalculationFeatureImp } else { - mainBoreDirection = RicWellPathExportCompletionDataFeatureImpl::calculateDirectionInCell(settings.caseToApply, - globalCellIndex, - wellBorePart.lengthsInCell); + mainBoreDirection = RicWellPathExportCompletionDataFeatureImpl::calculateCellMainDirection( + settings.caseToApply, globalCellIndex, wellBorePart.lengthsInCell); } } - + for (WellBorePartForTransCalc wellBorePart : wellBoreParts) { - RigCompletionData completion(wellPath->completions()->wellNameForExport(), RigCompletionDataGridCell(globalCellIndex, settings.caseToApply->mainGrid()), wellBorePart.intersectionWithWellMeasuredDepth); + if (wellBorePart.isMainBore && settings.excludeMainBoreForFishbones()) + { + continue; + } + + RigCompletionData completion(wellPath->completions()->wellNameForExport(), + RigCompletionDataGridCell(globalCellIndex, settings.caseToApply->mainGrid()), + wellBorePart.intersectionWithWellMeasuredDepth); completion.setSecondOrderingValue(wellBorePart.lateralIndex); double transmissibility = 0.0; if (wellBorePart.isMainBore) { - //No change in transmissibility for main bore - transmissibility = RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibility(settings.caseToApply, - wellPath, - wellBorePart.lengthsInCell, - wellBorePart.skinFactor, - wellBorePart.wellRadius, - globalCellIndex, - settings.useLateralNTG); - + // No change in transmissibility for main bore + auto transmissibilityAndPermeability = + RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibilityData( + settings.caseToApply, + wellPath, + wellBorePart.lengthsInCell, + wellBorePart.skinFactor, + wellBorePart.wellRadius, + globalCellIndex, + settings.useLateralNTG); + + transmissibility = transmissibilityAndPermeability.connectionFactor(); } else { - //Adjust transmissibility for fishbone laterals - transmissibility = RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibility(settings.caseToApply, - wellPath, - wellBorePart.lengthsInCell, - wellBorePart.skinFactor, - wellBorePart.wellRadius, - globalCellIndex, - settings.useLateralNTG, - numberOfLaterals, - mainBoreDirection); - + // Adjust transmissibility for fishbone laterals + auto transmissibilityAndPermeability = + RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibilityData( + settings.caseToApply, + wellPath, + wellBorePart.lengthsInCell, + wellBorePart.skinFactor, + wellBorePart.wellRadius, + globalCellIndex, + settings.useLateralNTG, + numberOfLaterals, + mainBoreDirection); + + transmissibility = transmissibilityAndPermeability.connectionFactor(); } - CellDirection direction = RicWellPathExportCompletionDataFeatureImpl::calculateDirectionInCell(settings.caseToApply, - globalCellIndex, - wellBorePart.lengthsInCell); + CellDirection direction = RicWellPathExportCompletionDataFeatureImpl::calculateCellMainDirection( + settings.caseToApply, globalCellIndex, wellBorePart.lengthsInCell); - completion.setTransAndWPImultBackgroundDataFromFishbone(transmissibility, - wellBorePart.skinFactor, - wellBorePart.wellRadius *2, - direction, - wellBorePart.isMainBore); + completion.setTransAndWPImultBackgroundDataFromFishbone( + transmissibility, wellBorePart.skinFactor, wellBorePart.wellRadius * 2, direction, wellBorePart.isMainBore); completion.addMetadata(wellBorePart.metaData, QString::number(transmissibility)); - + completion.setSourcePdmObject(wellBorePart.sourcePdmObject); completionData.push_back(completion); } } @@ -200,85 +175,153 @@ std::vector RicFishbonesTransmissibilityCalculationFeatureImp } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneImportedLateralsWellBoreParts(std::map >& wellBorePartsInCells, - const RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings) +void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneLateralsWellBoreParts( + std::map>& wellBorePartsInCells, + const RimWellPath* wellPath, + const RicExportCompletionDataSettingsUi& settings) +{ + if (!wellPath) return; + + // Generate data + const RigEclipseCaseData* caseData = settings.caseToApply()->eclipseCaseData(); + RicMswExportInfo exportInfo = + RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMswExportInfo(settings.caseToApply(), wellPath, false); + + RiaEclipseUnitTools::UnitSystem unitSystem = caseData->unitsType(); + bool isMainBore = false; + + for (const RicMswSegment& location : exportInfo.wellSegmentLocations()) + { + for (const RicMswCompletion& completion : location.completions()) + { + for (const RicMswSubSegment& segment : completion.subSegments()) + { + for (const RicMswSubSegmentCellIntersection& intersection : segment.intersections()) + { + double diameter = location.holeDiameter(); + QString completionMetaData = + (location.label() + QString(": Sub: %1 Lateral: %2").arg(location.subIndex()).arg(completion.index())); + + WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc( + intersection.lengthsInCell(), diameter / 2.0, location.skinFactor(), isMainBore, completionMetaData); + + wellBorePart.intersectionWithWellMeasuredDepth = location.endMD(); + wellBorePart.lateralIndex = completion.index(); + wellBorePart.setSourcePdmObject(location.sourcePdmObject()); + + wellBorePartsInCells[intersection.globalCellIndex()].push_back(wellBorePart); + } + } + } + } + + { + // Note that it is not supported to export main bore perforation intervals for Imported Laterals, only for fishbones + // defined by ResInsight. It is not trivial to define the open section of the main bore for imported laterals. + + if (wellPath->fishbonesCollection()->isChecked()) + { + double holeRadius = wellPath->fishbonesCollection()->mainBoreDiameter(unitSystem) / 2.0; + double skinFactor = wellPath->fishbonesCollection()->mainBoreSkinFactor(); + + for (const auto& fishboneDefinition : wellPath->fishbonesCollection()->activeFishbonesSubs()) + { + double startMD = fishboneDefinition->startMD(); + double endMD = fishboneDefinition->endMD(); + + if (fabs(startMD - endMD) < 1e-3) + { + // Start and end md are close, adjust to be sure we get an intersection along the well path + startMD -= 0.5; + endMD += 0.5; + } + + appendMainWellBoreParts(wellBorePartsInCells, wellPath, settings, skinFactor, holeRadius, startMD, endMD, fishboneDefinition); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicFishbonesTransmissibilityCalculationFeatureImp::findFishboneImportedLateralsWellBoreParts( + std::map>& wellBorePartsInCells, + const RimWellPath* wellPath, + const RicExportCompletionDataSettingsUi& settings) { RiaEclipseUnitTools::UnitSystem unitSystem = settings.caseToApply->eclipseCaseData()->unitsType(); if (!wellPath) return; if (!wellPath->wellPathGeometry()) return; - std::set wellPathCells = RigWellPathIntersectionTools::findIntersectedGlobalCellIndicesForWellPath( - settings.caseToApply()->eclipseCaseData(), wellPath->wellPathGeometry()); + bool isMainBore = false; + double holeRadius = wellPath->fishbonesCollection()->wellPathCollection()->holeDiameter(unitSystem) / 2.0; + double skinFactor = wellPath->fishbonesCollection()->wellPathCollection()->skinFactor(); - bool isMainBore = false; - double diameter = wellPath->fishbonesCollection()->wellPathCollection()->holeDiameter(unitSystem); for (const RimFishboneWellPath* fishbonesPath : wellPath->fishbonesCollection()->wellPathCollection()->wellPaths()) { - std::vector intersectedCells = RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath(settings.caseToApply->eclipseCaseData(), - fishbonesPath->coordinates(), - fishbonesPath->measuredDepths()); - for (auto& cell : intersectedCells) + if (!fishbonesPath->isChecked()) + { + continue; + } + + std::vector intersectedCells = + RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath( + settings.caseToApply->eclipseCaseData(), fishbonesPath->coordinates(), fishbonesPath->measuredDepths()); + + for (const auto& cellIntersectionInfo : intersectedCells) { - if (wellPathCells.count(cell.globCellIndex) ) continue; - - double skinFactor = wellPath->fishbonesCollection()->wellPathCollection()->skinFactor(); - QString completionMetaData = fishbonesPath->name(); - WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc(cell.intersectionLengthsInCellCS, - diameter / 2, - skinFactor, - isMainBore, - completionMetaData); - wellBorePart.intersectionWithWellMeasuredDepth = cell.startMD; - - wellBorePartsInCells[cell.globCellIndex].push_back(wellBorePart); + QString completionMetaData = fishbonesPath->name(); + WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc( + cellIntersectionInfo.intersectionLengthsInCellCS, holeRadius, skinFactor, isMainBore, completionMetaData); + wellBorePart.intersectionWithWellMeasuredDepth = cellIntersectionInfo.startMD; + + wellBorePartsInCells[cellIntersectionInfo.globCellIndex].push_back(wellBorePart); } } + + // Note that it is not supported to export main bore perforation intervals for Imported Laterals, only for fishbones + // defined by ResInsight } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RicFishbonesTransmissibilityCalculationFeatureImp::findMainWellBoreParts(std::map>& wellBorePartsInCells, - const RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings) +void RicFishbonesTransmissibilityCalculationFeatureImp::appendMainWellBoreParts( + std::map>& wellBorePartsInCells, + const RimWellPath* wellPath, + const RicExportCompletionDataSettingsUi& settings, + double skinFactor, + double holeRadius, + double startMeasuredDepth, + double endMeasuredDepth, + const RimFishbonesMultipleSubs* fishbonesDefintions) { if (!wellPath) return; if (!wellPath->wellPathGeometry()) return; + if (!wellPath->fishbonesCollection()) return; - RiaEclipseUnitTools::UnitSystem unitSystem = settings.caseToApply->eclipseCaseData()->unitsType(); bool isMainBore = true; - double holeDiameter = wellPath->fishbonesCollection()->mainBoreDiameter(unitSystem); - - std::vector wellPathMD = wellPath->wellPathGeometry()->m_measuredDepths; - double wellPathEndMD = 0.0; - if (wellPathMD.size() > 1) wellPathEndMD = wellPathMD.back(); - std::pair< std::vector, std::vector > fishbonePerfWellPathCoords = wellPath->wellPathGeometry()->clippedPointSubset(wellPath->fishbonesCollection()->startMD(), - wellPathEndMD); + std::pair, std::vector> fishbonePerfWellPathCoords = + wellPath->wellPathGeometry()->clippedPointSubset(startMeasuredDepth, endMeasuredDepth); - std::vector intersectedCellsIntersectionInfo = RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath(settings.caseToApply->eclipseCaseData(), - fishbonePerfWellPathCoords.first, - fishbonePerfWellPathCoords.second); + std::vector intersectedCellsIntersectionInfo = + RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath( + settings.caseToApply->eclipseCaseData(), fishbonePerfWellPathCoords.first, fishbonePerfWellPathCoords.second); - if (!wellPath->fishbonesCollection()) return; - - for (auto& cell : intersectedCellsIntersectionInfo) + for (const auto& cellIntersectionInfo : intersectedCellsIntersectionInfo) { - double skinFactor = wellPath->fishbonesCollection()->mainBoreSkinFactor(); - QString completionMetaData = wellPath->name() + " main bore"; - WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc(cell.intersectionLengthsInCellCS, - holeDiameter / 2, - skinFactor, - isMainBore, - completionMetaData); + QString completionMetaData = wellPath->name() + " main bore"; + WellBorePartForTransCalc wellBorePart = WellBorePartForTransCalc( + cellIntersectionInfo.intersectionLengthsInCellCS, holeRadius, skinFactor, isMainBore, completionMetaData); - wellBorePart.intersectionWithWellMeasuredDepth = cell.startMD; + wellBorePart.intersectionWithWellMeasuredDepth = cellIntersectionInfo.startMD; - wellBorePartsInCells[cell.globCellIndex].push_back(wellBorePart); + wellBorePart.setSourcePdmObject(fishbonesDefintions); + wellBorePartsInCells[cellIntersectionInfo.globCellIndex].push_back(wellBorePart); } } - diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h b/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h index 651a23f3e8..6f1a60bab1 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicFishbonesTransmissibilityCalculationFeatureImp.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -21,39 +21,44 @@ #include "cvfBase.h" #include "cvfVector3.h" -#include #include #include +#include class RigCompletionData; class RimWellPath; +class RimFishbonesMultipleSubs; class RicExportCompletionDataSettingsUi; class RigEclipseCaseData; struct WellBorePartForTransCalc; - //================================================================================================== -/// +/// //================================================================================================== class RicFishbonesTransmissibilityCalculationFeatureImp { public: - static std::vector generateFishboneCompdatValuesUsingAdjustedCellVolume(const RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings); - + static std::vector + generateFishboneCompdatValuesUsingAdjustedCellVolume(const RimWellPath* wellPath, + const RicExportCompletionDataSettingsUi& settings); private: - static void findFishboneLateralsWellBoreParts(std::map>& wellBorePartsInCells, - const RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings); - - static void findFishboneImportedLateralsWellBoreParts(std::map>& wellBorePartsInCells, - const RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings); - - static void findMainWellBoreParts(std::map>& wellBorePartsInCells, - const RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings); + static void findFishboneLateralsWellBoreParts(std::map>& wellBorePartsInCells, + const RimWellPath* wellPath, + const RicExportCompletionDataSettingsUi& settings); + + static void + findFishboneImportedLateralsWellBoreParts(std::map>& wellBorePartsInCells, + const RimWellPath* wellPath, + const RicExportCompletionDataSettingsUi& settings); + + static void appendMainWellBoreParts(std::map>& wellBorePartsInCells, + const RimWellPath* wellPath, + const RicExportCompletionDataSettingsUi& settings, + double skinFactor, + double holeRadius, + double startMeasuredDepth, + double endMeasuredDepth, + const RimFishbonesMultipleSubs* fishbonesDefintions); }; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.cpp new file mode 100644 index 0000000000..6439d49e80 --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.cpp @@ -0,0 +1,656 @@ +#include "RicMultiSegmentWellExportInfo.h" + +#include "RimMswCompletionParameters.h" +#include "RimWellPath.h" + +#include "RigWellPath.h" + +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicMswSubSegmentCellIntersection::RicMswSubSegmentCellIntersection(const QString& gridName, + size_t globalCellIndex, + const cvf::Vec3st& gridLocalCellIJK, + const cvf::Vec3d& lengthsInCell) + : m_gridName(gridName) + , m_globalCellIndex(globalCellIndex) + , m_gridLocalCellIJK(gridLocalCellIJK) + , m_lengthsInCell(lengthsInCell) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QString& RicMswSubSegmentCellIntersection::gridName() const +{ + return m_gridName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RicMswSubSegmentCellIntersection::globalCellIndex() const +{ + return m_globalCellIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec3st RicMswSubSegmentCellIntersection::gridLocalCellIJK() const +{ + return m_gridLocalCellIJK; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const cvf::Vec3d& RicMswSubSegmentCellIntersection::lengthsInCell() const +{ + return m_lengthsInCell; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicMswSubSegment::RicMswSubSegment(double startMD, double deltaMD, double startTVD, double deltaTVD) + : m_startMD(startMD) + , m_deltaMD(deltaMD) + , m_startTVD(startTVD) + , m_deltaTVD(deltaTVD) + , m_segmentNumber(-1) + , m_attachedSegmentNumber(-1) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSubSegment::startMD() const +{ + return m_startMD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSubSegment::deltaMD() const +{ + return m_deltaMD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSubSegment::startTVD() const +{ + return m_startTVD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSubSegment::deltaTVD() const +{ + return m_deltaTVD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RicMswSubSegment::segmentNumber() const +{ + return m_segmentNumber; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RicMswSubSegment::attachedSegmentNumber() const +{ + return m_attachedSegmentNumber; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSubSegment::setSegmentNumber(int segmentNumber) +{ + m_segmentNumber = segmentNumber; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSubSegment::setAttachedSegmentNumber(int attachedSegmentNumber) +{ + m_attachedSegmentNumber = attachedSegmentNumber; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSubSegment::addIntersection(const RicMswSubSegmentCellIntersection& intersection) +{ + m_intersections.push_back(intersection); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RicMswSubSegment::intersections() const +{ + return m_intersections; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector& RicMswSubSegment::intersections() +{ + return m_intersections; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicMswCompletion::RicMswCompletion(RigCompletionData::CompletionType completionType, + const QString& label, + size_t index /* = cvf::UNDEFINED_SIZE_T */, + int branchNumber /*= 0*/) + : m_completionType(completionType) + , m_label(label) + , m_index(index) + , m_branchNumber(branchNumber) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigCompletionData::CompletionType RicMswCompletion::completionType() const +{ + return m_completionType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QString& RicMswCompletion::label() const +{ + return m_label; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RicMswCompletion::index() const +{ + return m_index; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RicMswCompletion::branchNumber() const +{ + return m_branchNumber; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswCompletion::setBranchNumber(int branchNumber) +{ + m_branchNumber = branchNumber; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswCompletion::addSubSegment(const RicMswSubSegment& subSegment) +{ + m_subSegments.push_back(subSegment); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector& RicMswCompletion::subSegments() +{ + return m_subSegments; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RicMswCompletion::subSegments() const +{ + return m_subSegments; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicMswSegment::RicMswSegment(const QString& label, + double startMD, + double endMD, + double startTVD, + double endTVD, + size_t subIndex, + int segmentNumber /*= -1*/) + : m_label(label) + , m_startMD(startMD) + , m_endMD(endMD) + , m_startTVD(startTVD) + , m_endTVD(endTVD) + , m_effectiveDiameter(0.15) + , m_holeDiameter(RicMswExportInfo::defaultDoubleValue()) + , m_openHoleRoughnessFactor(5.0e-5) + , m_skinFactor(RicMswExportInfo::defaultDoubleValue()) + , m_icdFlowCoefficient(RicMswExportInfo::defaultDoubleValue()) + , m_icdArea(RicMswExportInfo::defaultDoubleValue()) + , m_subIndex(subIndex) + , m_segmentNumber(segmentNumber) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicMswSegment::label() const +{ + return m_label; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::startMD() const +{ + return m_startMD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::endMD() const +{ + return m_endMD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::deltaMD() const +{ + return m_endMD - m_startMD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::startTVD() const +{ + return m_startTVD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::endTVD() const +{ + return m_endTVD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::deltaTVD() const +{ + return m_endTVD - m_startTVD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::effectiveDiameter() const +{ + return m_effectiveDiameter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::holeDiameter() const +{ + return m_holeDiameter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::openHoleRoughnessFactor() const +{ + return m_openHoleRoughnessFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::skinFactor() const +{ + return m_skinFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::icdFlowCoefficient() const +{ + return m_icdFlowCoefficient; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswSegment::icdArea() const +{ + return m_icdArea; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RicMswSegment::subIndex() const +{ + return m_subIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RicMswSegment::segmentNumber() const +{ + return m_segmentNumber; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RicMswSegment::completions() const +{ + return m_completions; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector& RicMswSegment::completions() +{ + return m_completions; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::setEffectiveDiameter(double effectiveDiameter) +{ + m_effectiveDiameter = effectiveDiameter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::setHoleDiameter(double holeDiameter) +{ + m_holeDiameter = holeDiameter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::setOpenHoleRoughnessFactor(double roughnessFactor) +{ + m_openHoleRoughnessFactor = roughnessFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::setSkinFactor(double skinFactor) +{ + m_skinFactor = skinFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::setIcdFlowCoefficient(double icdFlowCoefficient) +{ + m_icdFlowCoefficient = icdFlowCoefficient; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::setIcdArea(double icdArea) +{ + m_icdArea = icdArea; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::setSegmentNumber(int segmentNumber) +{ + m_segmentNumber = segmentNumber; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::addCompletion(const RicMswCompletion& completion) +{ + m_completions.push_back(completion); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswSegment::setSourcePdmObject(const caf::PdmObject* object) +{ + m_sourcePdmObject = const_cast(object); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const caf::PdmObject* RicMswSegment::sourcePdmObject() const +{ + return m_sourcePdmObject; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicMswSegment::operator<(const RicMswSegment& rhs) const +{ + return startMD() < rhs.startMD(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicMswExportInfo::RicMswExportInfo(const RimWellPath* wellPath, + RiaEclipseUnitTools::UnitSystem unitSystem, + double initialMD, + const QString& lengthAndDepthText, + const QString& pressureDropText) + : m_wellPath(wellPath) + , m_initialMD(initialMD) + , m_unitSystem(unitSystem) + , m_topWellBoreVolume(RicMswExportInfo::defaultDoubleValue()) + , m_linerDiameter(RimMswCompletionParameters::defaultLinerDiameter(unitSystem)) + , m_roughnessFactor(RimMswCompletionParameters::defaultRoughnessFactor(unitSystem)) + , m_lengthAndDepthText(lengthAndDepthText) + , m_pressureDropText(pressureDropText) + , m_hasSubGridIntersections(false) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswExportInfo::setTopWellBoreVolume(double topWellBoreVolume) +{ + m_topWellBoreVolume = topWellBoreVolume; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswExportInfo::setLinerDiameter(double linerDiameter) +{ + m_linerDiameter = linerDiameter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswExportInfo::setRoughnessFactor(double roughnessFactor) +{ + m_roughnessFactor = roughnessFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswExportInfo::setHasSubGridIntersections(bool subGridIntersections) +{ + m_hasSubGridIntersections = subGridIntersections; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswExportInfo::addWellSegmentLocation(const RicMswSegment& location) +{ + m_wellSegmentLocations.push_back(location); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicMswExportInfo::sortLocations() +{ + std::sort(m_wellSegmentLocations.begin(), m_wellSegmentLocations.end()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimWellPath* RicMswExportInfo::wellPath() const +{ + return m_wellPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswExportInfo::initialMD() const +{ + return m_initialMD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswExportInfo::initialTVD() const +{ + return -m_wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(m_initialMD).z(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaEclipseUnitTools::UnitSystem RicMswExportInfo::unitSystem() const +{ + return m_unitSystem; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswExportInfo::topWellBoreVolume() const +{ + return m_topWellBoreVolume; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswExportInfo::linerDiameter() const +{ + return m_linerDiameter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswExportInfo::roughnessFactor() const +{ + return m_roughnessFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicMswExportInfo::lengthAndDepthText() const +{ + return m_lengthAndDepthText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicMswExportInfo::pressureDropText() const +{ + return m_pressureDropText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicMswExportInfo::hasSubGridIntersections() const +{ + return m_hasSubGridIntersections; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicMswExportInfo::defaultDoubleValue() +{ + return std::numeric_limits::infinity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RicMswExportInfo::wellSegmentLocations() const +{ + return m_wellSegmentLocations; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector& RicMswExportInfo::wellSegmentLocations() +{ + return m_wellSegmentLocations; +} diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.h b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.h new file mode 100644 index 0000000000..aded04da13 --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicMultiSegmentWellExportInfo.h @@ -0,0 +1,235 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaEclipseUnitTools.h" +#include "RigCompletionData.h" + +#include "cvfBase.h" +#include "cvfMath.h" +#include "cvfVector3.h" + +#include + +class RimWellPath; +class RimFishbonesMultipleSubs; + +//================================================================================================== +/// +//================================================================================================== +class RicMswSubSegmentCellIntersection +{ +public: + RicMswSubSegmentCellIntersection(const QString& gridName, // Pass in empty string for main grid + size_t globalCellIndex, + const cvf::Vec3st& gridLocalCellIJK, + const cvf::Vec3d& lengthsInCell); + const QString& gridName() const; + size_t globalCellIndex() const; + cvf::Vec3st gridLocalCellIJK() const; + const cvf::Vec3d& lengthsInCell() const; +private: + QString m_gridName; + size_t m_globalCellIndex; + cvf::Vec3st m_gridLocalCellIJK; + cvf::Vec3d m_lengthsInCell; +}; + +//================================================================================================== +/// +//================================================================================================== +class RicMswSubSegment +{ +public: + RicMswSubSegment(double startMD, + double deltaMD, + double startTVD, + double deltaTVD); + + double startMD() const; + double deltaMD() const; + double startTVD() const; + double deltaTVD() const; + + int segmentNumber() const; + int attachedSegmentNumber() const; + + void setSegmentNumber(int segmentNumber); + void setAttachedSegmentNumber(int attachedSegmentNumber); + void addIntersection(const RicMswSubSegmentCellIntersection& intersection); + + const std::vector& intersections() const; + std::vector& intersections(); + + +private: + double m_startMD; + double m_deltaMD; + double m_startTVD; + double m_deltaTVD; + int m_segmentNumber; + int m_attachedSegmentNumber; + + std::vector m_intersections; +}; + +//================================================================================================== +/// +//================================================================================================== +class RicMswCompletion +{ +public: + RicMswCompletion(RigCompletionData::CompletionType completionType, const QString& label, size_t index = cvf::UNDEFINED_SIZE_T, int branchNumber = cvf::UNDEFINED_INT); + + RigCompletionData::CompletionType completionType() const; + const QString& label() const; + size_t index() const; + int branchNumber() const; + void setBranchNumber(int branchNumber); + + void addSubSegment(const RicMswSubSegment& subSegment); + + std::vector& subSegments(); + const std::vector& subSegments() const; + +private: + RigCompletionData::CompletionType m_completionType; + QString m_label; + size_t m_index; + int m_branchNumber; + std::vector m_subSegments; +}; + +//================================================================================================== +/// +//================================================================================================== +class RicMswSegment +{ +public: + RicMswSegment(const QString& label, + double startMD, + double endMD, + double startTVD, + double endTVD, + size_t subIndex = cvf::UNDEFINED_SIZE_T, + int segmentNumber = -1); + + QString label() const; + + double startMD() const; + double endMD() const; + double deltaMD() const; + double startTVD() const; + double endTVD() const; + double deltaTVD() const; + + double effectiveDiameter() const; + double holeDiameter() const; + double openHoleRoughnessFactor() const; + double skinFactor() const; + double icdFlowCoefficient() const; + double icdArea() const; + + size_t subIndex() const; + int segmentNumber() const; + + const std::vector& completions() const; + std::vector& completions(); + + void setEffectiveDiameter(double effectiveDiameter); + void setHoleDiameter(double holeDiameter); + void setOpenHoleRoughnessFactor(double roughnessFactor); + void setSkinFactor(double skinFactor); + void setIcdFlowCoefficient(double icdFlowCoefficient); + void setIcdArea(double icdArea); + void setSegmentNumber(int segmentNumber); + void addCompletion(const RicMswCompletion& completion); + + void setSourcePdmObject(const caf::PdmObject* object); + const caf::PdmObject* sourcePdmObject() const; + + bool operator<(const RicMswSegment& rhs) const; + +private: + QString m_label; + double m_startMD; + double m_endMD; + double m_startTVD; + double m_endTVD; + double m_effectiveDiameter; + double m_holeDiameter; + double m_linerDiameter; + double m_openHoleRoughnessFactor; + double m_skinFactor; + double m_icdFlowCoefficient; + double m_icdArea; + + size_t m_subIndex; + int m_segmentNumber; + + std::vector m_completions; + + caf::PdmPointer m_sourcePdmObject; +}; + +class RicMswExportInfo +{ +public: + RicMswExportInfo(const RimWellPath* wellPath, + RiaEclipseUnitTools::UnitSystem unitSystem, + double initialMD, + const QString& lengthAndDepthText, + const QString& pressureDropText); + + void setTopWellBoreVolume(double topWellBoreVolume); + void setLinerDiameter(double linerDiameter); + void setRoughnessFactor(double roughnessFactor); + void setHasSubGridIntersections(bool subGridIntersections); + + void addWellSegmentLocation(const RicMswSegment& location); + void sortLocations(); + + const RimWellPath* wellPath() const; + RiaEclipseUnitTools::UnitSystem unitSystem() const; + double initialMD() const; + double initialTVD() const; + double topWellBoreVolume() const; + double linerDiameter() const; + double roughnessFactor() const; + QString lengthAndDepthText() const; + QString pressureDropText() const; + bool hasSubGridIntersections() const; + static double defaultDoubleValue(); + + const std::vector& wellSegmentLocations() const; + std::vector& wellSegmentLocations(); + +private: + const RimWellPath* m_wellPath; + RiaEclipseUnitTools::UnitSystem m_unitSystem; + double m_initialMD; + double m_topWellBoreVolume; + double m_linerDiameter; + double m_roughnessFactor; + QString m_lengthAndDepthText; + QString m_pressureDropText; + bool m_hasSubGridIntersections; + std::vector m_wellSegmentLocations; +}; + diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.cpp index ea34f91857..11d975fbfa 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.cpp @@ -22,6 +22,7 @@ #include "RiaApplication.h" #include "RicExportFeatureImpl.h" +#include "ExportCommands/RicExportLgrFeature.h" #include "RimDialogData.h" #include "RimFishbonesMultipleSubs.h" @@ -51,11 +52,9 @@ void RicWellPathExportCompletionDataFeature::prepareExportSettingsAndExportCompl const std::vector& wellPaths, const std::vector& simWells) { - RiaApplication* app = RiaApplication::instance(); - RimProject* project = app->project(); - - QString projectFolder = app->currentProjectPath(); - QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallback("COMPLETIONS", projectFolder); + RiaApplication* app = RiaApplication::instance(); + RimProject* project = app->project(); + QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallbackToProjectFolder("COMPLETIONS"); RicExportCompletionDataSettingsUi* exportSettings = project->dialogData()->exportCompletionData(); @@ -175,6 +174,8 @@ void RicWellPathExportCompletionDataFeature::onActionTriggered(bool isChecked) void RicWellPathExportCompletionDataFeature::setupActionLook(QAction* actionToSetup) { actionToSetup->setText("Export Completion Data for Selected Well Paths"); + actionToSetup->setIcon(QIcon(":/ExportCompletionsSymbol16x16.png")); + } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.h b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.h index d5595e5b00..b4608e4887 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeature.h @@ -36,9 +36,9 @@ class RicWellPathExportCompletionDataFeature : public caf::CmdFeature const std::vector& simWells); protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; private: std::vector selectedWellPaths(); diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp index 9398094783..c6d26579f7 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.cpp @@ -19,13 +19,18 @@ #include "RicWellPathExportCompletionDataFeatureImpl.h" #include "RiaApplication.h" +#include "RiaFilePathTools.h" +#include "RiaFractureDefines.h" #include "RiaLogging.h" #include "RiaPreferences.h" +#include "../ExportCommands/RicExportLgrFeature.h" #include "RicExportCompletionDataSettingsUi.h" #include "RicExportFeatureImpl.h" #include "RicExportFractureCompletionsImpl.h" #include "RicFishbonesTransmissibilityCalculationFeatureImp.h" +#include "RicWellPathFractureReportItem.h" +#include "RicWellPathFractureTextReportFeatureImpl.h" #include "RifEclipseDataTableFormatter.h" @@ -33,33 +38,90 @@ #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" #include "RigMainGrid.h" +#include "RigPerforationTransmissibilityEquations.h" #include "RigResultAccessorFactory.h" #include "RigTransmissibilityEquations.h" +#include "RigVirtualPerforationTransmissibilities.h" #include "RigWellLogExtractionTools.h" #include "RigWellLogExtractor.h" #include "RigWellPath.h" #include "RigWellPathIntersectionTools.h" +#include "RimFileWellPath.h" #include "RimFishbonesCollection.h" #include "RimFishbonesMultipleSubs.h" +#include "RimFractureTemplate.h" +#include "RimNonDarcyPerforationParameters.h" #include "RimPerforationCollection.h" #include "RimPerforationInterval.h" +#include "RimProject.h" #include "RimSimWellInView.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" #include "RimWellPathCompletions.h" +#include "RimWellPathFracture.h" +#include "RimWellPathFractureCollection.h" #include "RiuMainWindow.h" #include "cafPdmUiPropertyViewDialog.h" #include "cafProgressInfo.h" #include "cafSelectionManager.h" +#include "cafUtils.h" #include "cvfPlane.h" -#include "RigVirtualPerforationTransmissibilities.h" #include +//-------------------------------------------------------------------------------------------------- +/// Internal definitions +//-------------------------------------------------------------------------------------------------- +class SubSegmentIntersectionInfo +{ +public: + SubSegmentIntersectionInfo(size_t globCellIndex, + double startTVD, + double endTVD, + double startMD, + double endMD, + cvf::Vec3d lengthsInCell) + : globCellIndex(globCellIndex) + , startTVD(startTVD) + , endTVD(endTVD) + , startMD(startMD) + , endMD(endMD) + , intersectionLengthsInCellCS(lengthsInCell) + { + } + + size_t globCellIndex; + double startTVD; + double endTVD; + double startMD; + double endMD; + cvf::Vec3d intersectionLengthsInCellCS; +}; + +const RimWellPath* findWellPathFromExportName(const QString& wellNameForExport); +std::vector + spiltIntersectionSegmentsToMaxLength(const RigWellPath* pathGeometry, + const std::vector& intersections, + double maxSegmentLength); +int numberOfSplittedSegments(double startMd, double endMd, double maxSegmentLength); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class OpenFileException +{ +public: + OpenFileException(const QString& message) + : message(message) + { + } + QString message; +}; + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -73,193 +135,301 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions(const std::ve return; } - - std::vector usedWellPaths; - for (RimWellPath* wellPath : wellPaths) + exportCarfinForTemporaryLgrs(exportSettings.caseToApply(), exportSettings.folder); + + if (exportSettings.compdatExport == RicExportCompletionDataSettingsUi::TRANSMISSIBILITIES || + exportSettings.compdatExport == RicExportCompletionDataSettingsUi::WPIMULT_AND_DEFAULT_CONNECTION_FACTORS) { - if (wellPath->unitSystem() == exportSettings.caseToApply->eclipseCaseData()->unitsType()) - { - usedWellPaths.push_back(wellPath); - } - else + std::vector usedWellPaths; + for (RimWellPath* wellPath : wellPaths) { - int caseId = exportSettings.caseToApply->caseId(); - QString format = QString("Unit systems for well path \"%1\" must match unit system of chosen eclipse case \"%2\""); - QString errMsg = format.arg(wellPath->name()).arg(caseId); - RiaLogging::error(errMsg); + if (wellPath->unitSystem() == exportSettings.caseToApply->eclipseCaseData()->unitsType()) + { + usedWellPaths.push_back(wellPath); + } + else + { + int caseId = exportSettings.caseToApply->caseId(); + QString format = + QString("Unit systems for well path \"%1\" must match unit system of chosen eclipse case \"%2\""); + QString errMsg = format.arg(wellPath->name()).arg(caseId); + RiaLogging::error(errMsg); + } } - } - - // FractureTransmissibilityExportInformation - std::unique_ptr fractureTransmissibilityExportInformationStream = nullptr; - QFile fractureTransmissibilityExportInformationFile; - - RiaPreferences* prefs = RiaApplication::instance()->preferences(); - if (prefs->includeFractureDebugInfoFile()) - { - QDir outputDir = QDir(exportSettings.folder); - outputDir.mkpath("."); + std::vector fractureDataReportItems; - QString fractureTransmisibillityExportInformationPath = - QDir(exportSettings.folder).absoluteFilePath("FractureTransmissibilityExportInformation"); + // FractureTransmissibilityExportInformation + std::unique_ptr fractureTransmissibilityExportInformationStream = nullptr; + QFile fractureTransmissibilityExportInformationFile; - fractureTransmissibilityExportInformationFile.setFileName(fractureTransmisibillityExportInformationPath); - if (!fractureTransmissibilityExportInformationFile.open(QIODevice::WriteOnly)) + RiaPreferences* prefs = RiaApplication::instance()->preferences(); + if (prefs->includeFractureDebugInfoFile()) { - RiaLogging::error(QString("Export Completions Data: Could not open the file: %1") - .arg(fractureTransmisibillityExportInformationPath)); - } - else - { - fractureTransmissibilityExportInformationStream = - std::unique_ptr(new QTextStream(&fractureTransmissibilityExportInformationFile)); - } - } + QDir outputDir = QDir(exportSettings.folder); + if (!outputDir.mkpath(".")) + { + QString errMsg = QString("Could not create export folder: %1").arg(exportSettings.folder); + RiaLogging::error(errMsg); + return; + } - size_t maxProgress = usedWellPaths.size() * 3 + simWells.size() + - (exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL - ? usedWellPaths.size() - : exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL_AND_COMPLETION_TYPE - ? usedWellPaths.size() * 3 - : 1) + - simWells.size(); + QString fractureTransmisibillityExportInformationPath = + QDir(exportSettings.folder).absoluteFilePath("FractureTransmissibilityExportInformation"); - caf::ProgressInfo progress(maxProgress, "Export Completions"); + fractureTransmissibilityExportInformationFile.setFileName(fractureTransmisibillityExportInformationPath); + if (!fractureTransmissibilityExportInformationFile.open(QIODevice::WriteOnly | QIODevice::Text)) + { + RiaLogging::error(QString("Export Completions Data: Could not open the file: %1") + .arg(fractureTransmisibillityExportInformationPath)); + } + else + { + fractureTransmissibilityExportInformationStream = + std::unique_ptr(new QTextStream(&fractureTransmissibilityExportInformationFile)); + } + } - progress.setProgressDescription("Read Completion Data"); + size_t maxProgress = + usedWellPaths.size() * 3 + simWells.size() + + (exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL + ? usedWellPaths.size() + : exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL_AND_COMPLETION_TYPE + ? usedWellPaths.size() * 3 + : 1) + + simWells.size(); - std::vector completions; + caf::ProgressInfo progress(maxProgress, "Export Completions"); - for (auto wellPath : usedWellPaths) - { - std::map> completionsPerEclipseCellAllCompletionTypes; - std::map> completionsPerEclipseCellFishbones; - std::map> completionsPerEclipseCellFracture; - std::map> completionsPerEclipseCellPerforations; + progress.setProgressDescription("Read Completion Data"); - // Generate completion data + std::vector completions; - if (exportSettings.includePerforations) + for (auto wellPath : usedWellPaths) { - std::vector perforationCompletionData = - generatePerforationsCompdatValues(wellPath, exportSettings); - - appendCompletionData(&completionsPerEclipseCellAllCompletionTypes, perforationCompletionData); - appendCompletionData(&completionsPerEclipseCellPerforations, perforationCompletionData); - } - progress.incrementProgress(); + std::map> completionsPerEclipseCellAllCompletionTypes; + std::map> completionsPerEclipseCellFishbones; + std::map> completionsPerEclipseCellFracture; + std::map> completionsPerEclipseCellPerforations; - if (exportSettings.includeFishbones) - { - std::vector fishbonesCompletionData = - RicFishbonesTransmissibilityCalculationFeatureImp::generateFishboneCompdatValuesUsingAdjustedCellVolume( - wellPath, exportSettings); - - appendCompletionData(&completionsPerEclipseCellAllCompletionTypes, fishbonesCompletionData); - appendCompletionData(&completionsPerEclipseCellFishbones, fishbonesCompletionData); - } - progress.incrementProgress(); + // Generate completion data - if (exportSettings.includeFractures()) - { - std::vector fractureCompletionData = - RicExportFractureCompletionsImpl::generateCompdatValuesForWellPath( - wellPath, exportSettings, fractureTransmissibilityExportInformationStream.get()); - - appendCompletionData(&completionsPerEclipseCellAllCompletionTypes, fractureCompletionData); - appendCompletionData(&completionsPerEclipseCellFracture, fractureCompletionData); - } + if (exportSettings.includePerforations) + { + std::vector perforationCompletionData = generatePerforationsCompdatValues( + wellPath, wellPath->perforationIntervalCollection()->perforations(), exportSettings); - if (exportSettings.reportCompletionsTypesIndividually()) - { - for (auto& data : completionsPerEclipseCellFracture) + appendCompletionData(&completionsPerEclipseCellAllCompletionTypes, perforationCompletionData); + appendCompletionData(&completionsPerEclipseCellPerforations, perforationCompletionData); + } + progress.incrementProgress(); + + if (exportSettings.includeFishbones) { - completions.push_back(combineEclipseCellCompletions(data.second, exportSettings)); + std::vector fishbonesCompletionData = + RicFishbonesTransmissibilityCalculationFeatureImp::generateFishboneCompdatValuesUsingAdjustedCellVolume( + wellPath, exportSettings); + + appendCompletionData(&completionsPerEclipseCellAllCompletionTypes, fishbonesCompletionData); + appendCompletionData(&completionsPerEclipseCellFishbones, fishbonesCompletionData); } + progress.incrementProgress(); - for (auto& data : completionsPerEclipseCellFishbones) + if (exportSettings.includeFractures()) { - completions.push_back(combineEclipseCellCompletions(data.second, exportSettings)); + // If no report is wanted, set reportItems = nullptr + std::vector* reportItems = &fractureDataReportItems; + + std::vector fractureCompletionData = + RicExportFractureCompletionsImpl::generateCompdatValuesForWellPath( + wellPath, + exportSettings.caseToApply(), + reportItems, + fractureTransmissibilityExportInformationStream.get(), + RicExportFractureCompletionsImpl::PressureDepletionParameters(exportSettings.performTransScaling(), + exportSettings.transScalingTimeStep(), + exportSettings.transScalingWBHPSource(), + exportSettings.transScalingWBHP())); + + appendCompletionData(&completionsPerEclipseCellAllCompletionTypes, fractureCompletionData); + appendCompletionData(&completionsPerEclipseCellFracture, fractureCompletionData); } - for (auto& data : completionsPerEclipseCellPerforations) + if (exportSettings.reportCompletionsTypesIndividually()) { - completions.push_back(combineEclipseCellCompletions(data.second, exportSettings)); + for (auto& data : completionsPerEclipseCellFracture) + { + completions.push_back(combineEclipseCellCompletions(data.second, exportSettings)); + } + + for (auto& data : completionsPerEclipseCellFishbones) + { + completions.push_back(combineEclipseCellCompletions(data.second, exportSettings)); + } + + for (auto& data : completionsPerEclipseCellPerforations) + { + completions.push_back(combineEclipseCellCompletions(data.second, exportSettings)); + } + } + else + { + for (auto& data : completionsPerEclipseCellAllCompletionTypes) + { + completions.push_back(combineEclipseCellCompletions(data.second, exportSettings)); + } } + + progress.incrementProgress(); } - else + + for (auto simWell : simWells) { - for (auto& data : completionsPerEclipseCellAllCompletionTypes) + std::map> completionsPerEclipseCell; + + std::vector fractureCompletionData = + RicExportFractureCompletionsImpl::generateCompdatValuesForSimWell( + exportSettings.caseToApply(), + simWell, + fractureTransmissibilityExportInformationStream.get(), + RicExportFractureCompletionsImpl::PressureDepletionParameters(exportSettings.performTransScaling(), + exportSettings.transScalingTimeStep(), + exportSettings.transScalingWBHPSource(), + exportSettings.transScalingWBHP())); + + appendCompletionData(&completionsPerEclipseCell, fractureCompletionData); + + for (auto& data : completionsPerEclipseCell) { completions.push_back(combineEclipseCellCompletions(data.second, exportSettings)); } - } - progress.incrementProgress(); - } - - for (auto simWell : simWells) - { - std::map> completionsPerEclipseCell; + progress.incrementProgress(); + } - std::vector fractureCompletionData = RicExportFractureCompletionsImpl::generateCompdatValuesForSimWell( - exportSettings.caseToApply(), simWell, fractureTransmissibilityExportInformationStream.get()); - appendCompletionData(&completionsPerEclipseCell, fractureCompletionData); + const QString eclipseCaseName = exportSettings.caseToApply->caseUserDescription(); - for (auto& data : completionsPerEclipseCell) + progress.setProgressDescription("Write Export Files"); + if (exportSettings.fileSplit == RicExportCompletionDataSettingsUi::UNIFIED_FILE) { - completions.push_back(combineEclipseCellCompletions(data.second, exportSettings)); + QString fileName = QString("UnifiedCompletions_%1").arg(eclipseCaseName); + sortAndExportCompletionsToFile(exportSettings.caseToApply, + exportSettings.folder, + fileName, + completions, + fractureDataReportItems, + exportSettings.compdatExport); + progress.incrementProgress(); } + else if (exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL) + { + for (auto wellPath : usedWellPaths) + { + std::vector completionsForWell; + for (const auto& completion : completions) + { + if (completion.wellName() == wellPath->completions()->wellNameForExport()) + { + completionsForWell.push_back(completion); + } + } - progress.incrementProgress(); - } + if (completionsForWell.empty()) continue; - const QString eclipseCaseName = exportSettings.caseToApply->caseUserDescription(); + std::vector reportItemsForWell; + for (const auto& fracItem : fractureDataReportItems) + { + if (fracItem.wellPathNameForExport() == wellPath->completions()->wellNameForExport()) + { + reportItemsForWell.push_back(fracItem); + } + } - progress.setProgressDescription("Write Export Files"); - if (exportSettings.fileSplit == RicExportCompletionDataSettingsUi::UNIFIED_FILE) - { - const QString fileName = QString("UnifiedCompletions_%1").arg(eclipseCaseName); - sortAndExportCompletionsToFile(exportSettings.folder, fileName, completions, exportSettings.compdatExport); - progress.incrementProgress(); - } - else if (exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL) - { - for (auto wellPath : usedWellPaths) + QString fileName = QString("%1_unifiedCompletions_%2").arg(wellPath->name()).arg(eclipseCaseName); + sortAndExportCompletionsToFile(exportSettings.caseToApply, + exportSettings.folder, + fileName, + completionsForWell, + reportItemsForWell, + exportSettings.compdatExport); + progress.incrementProgress(); + } + } + else if (exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL_AND_COMPLETION_TYPE) { - std::vector wellCompletions; - for (const auto& completion : completions) + std::vector completionTypes; + completionTypes.push_back(RigCompletionData::FISHBONES); + completionTypes.push_back(RigCompletionData::FRACTURE); + completionTypes.push_back(RigCompletionData::PERFORATION); + + for (const auto& completionType : completionTypes) { - if (completion.wellName() == wellPath->completions()->wellNameForExport()) + for (auto wellPath : usedWellPaths) { - wellCompletions.push_back(completion); - } - } + std::vector completionsForWell; + for (const auto& completion : completions) + { + if (completion.wellName() == wellPath->completions()->wellNameForExport() && + completionType == completion.completionType()) + { + completionsForWell.push_back(completion); + } + } - if (wellCompletions.empty()) continue; + if (completionsForWell.empty()) continue; - QString fileName = QString("%1_unifiedCompletions_%2").arg(wellPath->name()).arg(eclipseCaseName); - sortAndExportCompletionsToFile(exportSettings.folder, fileName, wellCompletions, exportSettings.compdatExport); - progress.incrementProgress(); + { + QString completionTypeText; + if (completionType == RigCompletionData::FISHBONES) completionTypeText = "Fishbones"; + if (completionType == RigCompletionData::FRACTURE) completionTypeText = "Fracture"; + if (completionType == RigCompletionData::PERFORATION) completionTypeText = "Perforation"; + + QString fileName = QString("%1_%2_%3").arg(wellPath->name()).arg(completionTypeText).arg(eclipseCaseName); + if (completionType == RigCompletionData::FRACTURE) + { + std::vector reportItemsForWell; + for (const auto& fracItem : fractureDataReportItems) + { + if (fracItem.wellPathNameForExport() == wellPath->completions()->wellNameForExport()) + { + reportItemsForWell.push_back(fracItem); + } + } + + sortAndExportCompletionsToFile(exportSettings.caseToApply, + exportSettings.folder, + fileName, + completionsForWell, + reportItemsForWell, + exportSettings.compdatExport); + } + else + { + std::vector emptyReportItemVector; + sortAndExportCompletionsToFile(exportSettings.caseToApply, + exportSettings.folder, + fileName, + completionsForWell, + emptyReportItemVector, + exportSettings.compdatExport); + } + } + + progress.incrementProgress(); + } + } } - } - else if (exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL_AND_COMPLETION_TYPE) - { - std::vector completionTypes; - completionTypes.push_back(RigCompletionData::FISHBONES); - completionTypes.push_back(RigCompletionData::FRACTURE); - completionTypes.push_back(RigCompletionData::PERFORATION); - for (const auto& completionType : completionTypes) + // Export sim wells + if (exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL || + exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL_AND_COMPLETION_TYPE) { - for (auto wellPath : usedWellPaths) + for (auto simWell : simWells) { std::vector wellCompletions; for (const auto& completion : completions) { - if (completion.wellName() == wellPath->completions()->wellNameForExport() && - completionType == completion.completionType()) + if (completion.wellName() == simWell->name()) { wellCompletions.push_back(completion); } @@ -267,43 +437,91 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompletions(const std::ve if (wellCompletions.empty()) continue; - { - QString completionTypeText; - if (completionType == RigCompletionData::FISHBONES) completionTypeText = "Fishbones"; - if (completionType == RigCompletionData::FRACTURE) completionTypeText = "Fracture"; - if (completionType == RigCompletionData::PERFORATION) completionTypeText = "Perforation"; - - QString fileName = QString("%1_%2_%3").arg(wellPath->name()).arg(completionTypeText).arg(eclipseCaseName); - sortAndExportCompletionsToFile( - exportSettings.folder, fileName, wellCompletions, exportSettings.compdatExport); - } + QString fileName = QString("%1_Fractures_%2").arg(simWell->name()).arg(eclipseCaseName); + sortAndExportCompletionsToFile(exportSettings.caseToApply, + exportSettings.folder, + fileName, + wellCompletions, + fractureDataReportItems, + exportSettings.compdatExport); progress.incrementProgress(); } } } - // Export sim wells - if (exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL || - exportSettings.fileSplit == RicExportCompletionDataSettingsUi::SPLIT_ON_WELL_AND_COMPLETION_TYPE) + if (exportSettings.includeMsw) { - for (auto simWell : simWells) + if (exportSettings.includeFractures()) + { + bool anyActiveFractures = false; + + for (const auto& wellPath : wellPaths) + { + if (!wellPath->fractureCollection()->activeFractures().empty()) + { + anyActiveFractures = true; + } + } + + if (anyActiveFractures) + { + QString fileName = QString("%1-Fracture-Welsegs").arg(exportSettings.caseToApply->caseUserDescription()); + QFilePtr exportFile = openFileForExport(exportSettings.folder, fileName); + + for (const auto wellPath : wellPaths) + { + auto fractures = wellPath->fractureCollection()->activeFractures(); + if (!fractures.empty()) + { + exportWellSegments(exportSettings.caseToApply, exportFile, wellPath, fractures); + } + } + exportFile->close(); + } + } + + if (exportSettings.includeFishbones()) { - std::vector wellCompletions; - for (const auto& completion : completions) + bool anyFishbones = false; + + for (const auto& wellPath : wellPaths) { - if (completion.wellName() == simWell->name()) + if (!wellPath->fishbonesCollection()->activeFishbonesSubs().empty()) { - wellCompletions.push_back(completion); + anyFishbones = true; } } - if (wellCompletions.empty()) continue; + if (anyFishbones) + { + QString fileName = QString("%1-Fishbone-Welsegs").arg(exportSettings.caseToApply->caseUserDescription()); + QFilePtr exportFile = openFileForExport(exportSettings.folder, fileName); - QString fileName = QString("%1_Fractures_%2").arg(simWell->name()).arg(eclipseCaseName); - sortAndExportCompletionsToFile(exportSettings.folder, fileName, wellCompletions, exportSettings.compdatExport); + for (const auto wellPath : wellPaths) + { + auto fishbones = wellPath->fishbonesCollection()->activeFishbonesSubs(); + if (!fishbones.empty()) + { + exportWellSegments(exportSettings.caseToApply, exportFile, wellPath, fishbones); + } + } - progress.incrementProgress(); + exportFile->close(); + } + } + + if (exportSettings.includePerforations()) + { + QString fileName = QString("%1-Perforation-Welsegs").arg(exportSettings.caseToApply->caseUserDescription()); + QFilePtr exportFile = openFileForExport(exportSettings.folder, fileName); + + for (const auto wellPath : wellPaths) + { + auto perforations = wellPath->perforationIntervalCollection()->perforations(); + exportWellSegments(exportSettings, exportFile, wellPath, perforations); + } + exportFile->close(); } } } @@ -336,7 +554,7 @@ std::vector { std::vector completionData = - RicExportFractureCompletionsImpl::generateCompdatValuesForWellPath(wellPath, exportSettings, nullptr); + RicExportFractureCompletionsImpl::generateCompdatValuesForWellPath(wellPath, eclipseCase, nullptr, nullptr); std::copy(completionData.begin(), completionData.end(), std::back_inserter(completionsPerEclipseCell)); } @@ -364,10 +582,403 @@ std::vector exportSettings.includePerforations = true; exportSettings.includeFractures = true; - completionsPerEclipseCell = generatePerforationsCompdatValues(wellPath, exportSettings); + completionsPerEclipseCell = generatePerforationsCompdatValues( + wellPath, wellPath->perforationIntervalCollection()->perforations(), exportSettings); + } + + return completionsPerEclipseCell; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo) +{ + formatter.keyword("WELSEGS"); + + double startMD = exportInfo.initialMD(); + double startTVD = exportInfo.initialTVD(); + + { + std::vector header = { + RifEclipseOutputTableColumn("Name"), + RifEclipseOutputTableColumn("Dep 1"), + RifEclipseOutputTableColumn("Tlen 1"), + RifEclipseOutputTableColumn("Vol 1"), + RifEclipseOutputTableColumn("Len&Dep"), + RifEclipseOutputTableColumn("PresDrop"), + }; + formatter.header(header); + + formatter.add(exportInfo.wellPath()->name()); + formatter.add(startTVD); + formatter.add(startMD); + formatter.addValueOrDefaultMarker(exportInfo.topWellBoreVolume(), RicMswExportInfo::defaultDoubleValue()); + formatter.add(exportInfo.lengthAndDepthText()); + formatter.add(exportInfo.pressureDropText()); + + formatter.rowCompleted(); + } + + { + std::vector header = { + RifEclipseOutputTableColumn("First Seg"), + RifEclipseOutputTableColumn("Last Seg"), + RifEclipseOutputTableColumn("Branch Num"), + RifEclipseOutputTableColumn("Outlet Seg"), + RifEclipseOutputTableColumn("Length"), + RifEclipseOutputTableColumn("Depth Change"), + RifEclipseOutputTableColumn("Diam"), + RifEclipseOutputTableColumn("Rough"), + }; + formatter.header(header); + } + + { + double prevMD = exportInfo.initialMD(); + double prevTVD = exportInfo.initialTVD(); + formatter.comment("Main Stem Segments"); + for (const RicMswSegment& location : exportInfo.wellSegmentLocations()) + { + double depth = 0; + double length = 0; + + if (exportInfo.lengthAndDepthText() == QString("INC")) + { + depth = location.endTVD() - prevTVD; + length = location.endMD() - prevMD; + } + else + { + depth = location.endTVD(); + length = location.endMD(); + } + + if (location.subIndex() != cvf::UNDEFINED_SIZE_T) + { + QString comment = location.label() + QString(", sub %1").arg(location.subIndex()); + formatter.comment(comment); + } + + formatter.add(location.segmentNumber()).add(location.segmentNumber()); + formatter.add(1); // All segments on main stem are branch 1 + formatter.add(location.segmentNumber() - 1); // All main stem segments are connected to the segment below them + formatter.add(length); + formatter.add(depth); + formatter.add(exportInfo.linerDiameter()); + formatter.add(exportInfo.roughnessFactor()); + formatter.rowCompleted(); + prevMD = location.endMD(); + prevTVD = location.endTVD(); + } + } + + { + generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::ICD, RigCompletionData::FISHBONES}); + generateWelsegsSegments(formatter, exportInfo, {RigCompletionData::FRACTURE}); + } + + formatter.tableCompleted(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsSegments( + RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo, + const std::set& exportCompletionTypes) +{ + bool generatedHeader = false; + for (const RicMswSegment& segment : exportInfo.wellSegmentLocations()) + { + for (const RicMswCompletion& completion : segment.completions()) + { + if (exportCompletionTypes.count(completion.completionType())) + { + if (!generatedHeader) + { + generateWelsegsCompletionCommentHeader(formatter, completion.completionType()); + generatedHeader = true; + } + + if (completion.completionType() == RigCompletionData::ICD) // Found ICD + { + formatter.comment(completion.label()); + formatter.add(completion.subSegments().front().segmentNumber()); + formatter.add(completion.subSegments().front().segmentNumber()); + formatter.add(completion.branchNumber()); + formatter.add(segment.segmentNumber()); + formatter.add(0.1); // ICDs have 0.1 length + formatter.add(0); // Depth change + formatter.add(exportInfo.linerDiameter()); + formatter.add(exportInfo.roughnessFactor()); + formatter.rowCompleted(); + } + else + { + if (completion.completionType() == RigCompletionData::FISHBONES) + { + formatter.comment(QString("%1 : Sub index %2 - %3") + .arg(segment.label()) + .arg(segment.subIndex()) + .arg(completion.label())); + } + else if (completion.completionType() == RigCompletionData::FRACTURE) + { + formatter.comment(QString("%1 connected to %2").arg(completion.label()).arg(segment.label())); + } + + for (const RicMswSubSegment& subSegment : completion.subSegments()) + { + double depth = 0; + double length = 0; + + if (exportInfo.lengthAndDepthText() == QString("INC")) + { + depth = subSegment.deltaTVD(); + length = subSegment.deltaMD(); + } + else + { + depth = subSegment.startTVD() + subSegment.deltaTVD(); + length = subSegment.startMD() + subSegment.deltaMD(); + } + double diameter = segment.effectiveDiameter(); + formatter.add(subSegment.segmentNumber()); + formatter.add(subSegment.segmentNumber()); + formatter.add(completion.branchNumber()); + formatter.add(subSegment.attachedSegmentNumber()); + formatter.add(length); + formatter.add(depth); + formatter.add(diameter); + formatter.add(segment.openHoleRoughnessFactor()); + formatter.rowCompleted(); + } + } + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::generateWelsegsCompletionCommentHeader( + RifEclipseDataTableFormatter& formatter, + RigCompletionData::CompletionType completionType) +{ + if (completionType == RigCompletionData::CT_UNDEFINED) + { + formatter.comment("Main stem"); + } + else if (completionType == RigCompletionData::ICD) + { + formatter.comment("Fishbone Laterals"); + formatter.comment("Diam: MSW - Tubing Radius"); + formatter.comment("Rough: MSW - Open Hole Roughness Factor"); + } + else if (completionType == RigCompletionData::FRACTURE) + { + formatter.comment("Fracture Segments"); + formatter.comment("Diam: MSW - Default Dummy"); + formatter.comment("Rough: MSW - Default Dummy"); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::generateCompsegTables(RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo) +{ + /* + * TODO: Creating the regular perforation COMPSEGS table should come in here, before the others + * should take precedence by appearing later in the output. See #3230. + */ + + { + std::set fishbonesTypes = {RigCompletionData::ICD, RigCompletionData::FISHBONES}; + generateCompsegTable(formatter, exportInfo, false, fishbonesTypes); + if (exportInfo.hasSubGridIntersections()) + { + generateCompsegTable(formatter, exportInfo, true, fishbonesTypes); + } + } + + { + std::set fractureTypes = {RigCompletionData::FRACTURE}; + generateCompsegTable(formatter, exportInfo, false, fractureTypes); + if (exportInfo.hasSubGridIntersections()) + { + generateCompsegTable(formatter, exportInfo, true, fractureTypes); + } + } + + { + std::set completionTypes = {RigCompletionData::PERFORATION}; + generateCompsegTable(formatter, exportInfo, false, completionTypes); + if (exportInfo.hasSubGridIntersections()) + { + generateCompsegTable(formatter, exportInfo, true, completionTypes); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::generateCompsegTable( + RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo, + bool exportSubGridIntersections, + const std::set& exportCompletionTypes) +{ + bool generatedHeader = false; + + for (const RicMswSegment& location : exportInfo.wellSegmentLocations()) + { + double startMD = location.startMD(); + + for (const RicMswCompletion& completion : location.completions()) + { + if (exportCompletionTypes.count(completion.completionType())) + { + if (!generatedHeader) + { + generateCompsegHeader(formatter, exportInfo, completion.completionType(), exportSubGridIntersections); + generatedHeader = true; + } + + for (const RicMswSubSegment& segment : completion.subSegments()) + { + if (completion.completionType() == RigCompletionData::ICD) + { + startMD = segment.startMD(); + } + + for (const RicMswSubSegmentCellIntersection& intersection : segment.intersections()) + { + bool isSubGridIntersection = !intersection.gridName().isEmpty(); + if (isSubGridIntersection == exportSubGridIntersections) + { + if (exportSubGridIntersections) + { + formatter.add(intersection.gridName()); + } + cvf::Vec3st ijk = intersection.gridLocalCellIJK(); + formatter.addOneBasedCellIndex(ijk.x()).addOneBasedCellIndex(ijk.y()).addOneBasedCellIndex(ijk.z()); + formatter.add(completion.branchNumber()); + + double startLength = segment.startMD(); + if (exportInfo.lengthAndDepthText() == QString("INC") && + completion.completionType() != RigCompletionData::PERFORATION) + { + startLength -= startMD; + } + formatter.add(startLength); + formatter.add(startLength + segment.deltaMD()); + + formatter.rowCompleted(); + } + } + } + } + } + } + if (generatedHeader) + { + formatter.tableCompleted(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::generateCompsegHeader(RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo, + RigCompletionData::CompletionType completionType, + bool exportSubGridIntersections) +{ + if (exportSubGridIntersections) + { + formatter.keyword("COMPSEGL"); + } + else + { + formatter.keyword("COMPSEGS"); + } + + if (completionType == RigCompletionData::ICD) + { + formatter.comment("Fishbones"); + } + else if (completionType == RigCompletionData::FRACTURE) + { + formatter.comment("Fractures"); + } + + { + std::vector header = {RifEclipseOutputTableColumn("Name")}; + formatter.header(header); + formatter.add(exportInfo.wellPath()->name()); + formatter.rowCompleted(); + } + + { + std::vector allHeaders; + if (exportSubGridIntersections) + { + allHeaders.push_back(RifEclipseOutputTableColumn("Grid")); + } + + std::vector commonHeaders = {RifEclipseOutputTableColumn("I"), + RifEclipseOutputTableColumn("J"), + RifEclipseOutputTableColumn("K"), + RifEclipseOutputTableColumn("Branch no"), + RifEclipseOutputTableColumn("Start Length"), + RifEclipseOutputTableColumn("End Length"), + RifEclipseOutputTableColumn("Dir Pen"), + RifEclipseOutputTableColumn("End Range"), + RifEclipseOutputTableColumn("Connection Depth")}; + allHeaders.insert(allHeaders.end(), commonHeaders.begin(), commonHeaders.end()); + formatter.header(allHeaders); } +} - return completionsPerEclipseCell; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo) +{ + { + formatter.keyword("WSEGVALV"); + std::vector header = { + RifEclipseOutputTableColumn("Well Name"), + RifEclipseOutputTableColumn("Seg No"), + RifEclipseOutputTableColumn("Cv"), + RifEclipseOutputTableColumn("Ac"), + }; + formatter.header(header); + } + for (const RicMswSegment& location : exportInfo.wellSegmentLocations()) + { + for (const RicMswCompletion& completion : location.completions()) + { + if (completion.completionType() == RigCompletionData::ICD) + { + CVF_ASSERT(completion.subSegments().size() == 1u); + formatter.add(exportInfo.wellPath()->name()); + formatter.add(completion.subSegments().front().segmentNumber()); + formatter.add(location.icdFlowCoefficient()); + formatter.add(location.icdArea()); + formatter.rowCompleted(); + } + } + } + formatter.tableCompleted(); } //================================================================================================== @@ -489,31 +1100,78 @@ RigCompletionData //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportCompletionDataFeatureImpl::sortAndExportCompletionsToFile( - const QString& folderName, - const QString& fileName, - std::vector& completions, - RicExportCompletionDataSettingsUi::CompdatExportType exportType) +QFilePtr RicWellPathExportCompletionDataFeatureImpl::openFileForExport(const QString& fullFileName) { - // Sort completions based on grid they belong to - std::vector completionsForMainGrid; + std::pair folderAndFileName = RiaFilePathTools::toFolderAndFileName(fullFileName); + return openFileForExport(folderAndFileName.first, folderAndFileName.second); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QFilePtr RicWellPathExportCompletionDataFeatureImpl::openFileForExport(const QString& folderName, const QString& fileName) +{ + QDir exportFolder = QDir(folderName); + if (!exportFolder.exists()) + { + bool createdPath = exportFolder.mkpath("."); + if (createdPath) + RiaLogging::info("Created export folder " + folderName); + else + { + auto errorMessage = QString("Selected output folder does not exist, and could not be created."); + RiaLogging::error(errorMessage); + throw OpenFileException(errorMessage); + } + } + + QString filePath = exportFolder.filePath(fileName); + QFilePtr exportFile(new QFile(filePath)); + if (!exportFile->open(QIODevice::WriteOnly | QIODevice::Text)) + { + auto errorMessage = QString("Export Completions Data: Could not open the file: %1").arg(filePath); + RiaLogging::error(errorMessage); + throw OpenFileException(errorMessage); + } + return exportFile; +} - std::map> completionsForSubGrids; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector + RicWellPathExportCompletionDataFeatureImpl::mainGridCompletions(std::vector& allCompletions) +{ + std::vector completions; - for (const auto& completion : completions) + for (const auto& completion : allCompletions) { QString gridName = completion.completionDataGridCell().lgrName(); if (gridName.isEmpty()) { - completionsForMainGrid.push_back(completion); + completions.push_back(completion); } - else + } + return completions; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map> + RicWellPathExportCompletionDataFeatureImpl::subGridsCompletions(std::vector& allCompletions) +{ + std::map> completions; + + for (const auto& completion : allCompletions) + { + QString gridName = completion.completionDataGridCell().lgrName(); + if (!gridName.isEmpty()) { - auto it = completionsForSubGrids.find(gridName); - if (it == completionsForSubGrids.end()) + auto it = completions.find(gridName); + if (it == completions.end()) { - completionsForSubGrids.insert( - std::pair>(gridName, std::vector{completion})); + completions.insert(std::pair>(gridName, {completion})); } else { @@ -521,19 +1179,237 @@ void RicWellPathExportCompletionDataFeatureImpl::sortAndExportCompletionsToFile( } } } + return completions; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::exportWellPathFractureReport( + RimEclipseCase* sourceCase, + QFilePtr exportFile, + const std::vector& wellPathFractureReportItems) +{ + QTextStream stream(exportFile.get()); + + if (!wellPathFractureReportItems.empty()) + { + std::vector sortedReportItems; + { + std::set fractureReportItemsSet; + + for (const auto& reportItem : wellPathFractureReportItems) + { + fractureReportItemsSet.insert(reportItem); + } + + for (const auto& reportItem : fractureReportItemsSet) + { + sortedReportItems.emplace_back(reportItem); + } + } + + std::vector wellPathsToReport; + { + std::set wellPathsSet; + + auto allWellPaths = RicWellPathFractureTextReportFeatureImpl::wellPathsWithActiveFractures(); + for (const auto& wellPath : allWellPaths) + { + for (const auto& reportItem : sortedReportItems) + { + if (reportItem.wellPathNameForExport() == wellPath->completions()->wellNameForExport()) + { + wellPathsSet.insert(wellPath); + } + } + } + + std::copy(wellPathsSet.begin(), wellPathsSet.end(), std::back_inserter(wellPathsToReport)); + } + + RicWellPathFractureTextReportFeatureImpl reportGenerator; + QString summaryText = reportGenerator.wellPathFractureReport(sourceCase, wellPathsToReport, sortedReportItems); + + stream << summaryText; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::exportWelspecsToFile(RimEclipseCase* gridCase, + QFilePtr exportFile, + const std::vector& completions) +{ + QTextStream stream(exportFile.get()); + + RifEclipseDataTableFormatter formatter(stream); + formatter.setColumnSpacing(3); + + std::vector header = {RifEclipseOutputTableColumn("Well"), + RifEclipseOutputTableColumn("Grp"), + RifEclipseOutputTableColumn("I"), + RifEclipseOutputTableColumn("J"), + RifEclipseOutputTableColumn("RefDepth"), + RifEclipseOutputTableColumn("WellType")}; + + formatter.keyword("WELSPECS"); + formatter.header(header); + + std::set wellPathSet; + + // Build list of unique RimWellPath + for (const auto& completion : completions) + { + const auto wellPath = findWellPathFromExportName(completion.wellName()); + if (wellPath) + { + wellPathSet.insert(wellPath); + } + } + + // Export + for (const auto wellPath : wellPathSet) + { + auto rimCcompletions = wellPath->completions(); + auto ijIntersection = wellPathUpperGridIntersectionIJ(gridCase, wellPath); + + formatter.add(rimCcompletions->wellNameForExport()) + .add(rimCcompletions->wellGroupNameForExport()) + .addOneBasedCellIndex(ijIntersection.second.x()) + .addOneBasedCellIndex(ijIntersection.second.y()) + .add(rimCcompletions->referenceDepthForExport()) + .add(rimCcompletions->wellTypeNameForExport()) + .rowCompleted(); + } + + formatter.tableCompleted(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::exportWelspeclToFile( + RimEclipseCase* gridCase, + QFilePtr exportFile, + const std::map>& completions) +{ + QTextStream stream(exportFile.get()); + + RifEclipseDataTableFormatter formatter(stream); + formatter.setColumnSpacing(3); + + std::vector header = {RifEclipseOutputTableColumn("Well"), + RifEclipseOutputTableColumn("Grp"), + RifEclipseOutputTableColumn("LGR"), + RifEclipseOutputTableColumn("I"), + RifEclipseOutputTableColumn("J"), + RifEclipseOutputTableColumn("RefDepth"), + RifEclipseOutputTableColumn("WellType")}; + + formatter.keyword("WELSPECL"); + formatter.header(header); + + std::map> wellPathToLgrNameMap; + + for (const auto& completionsForLgr : completions) + { + for (const auto& completion : completionsForLgr.second) + { + const auto wellPath = findWellPathFromExportName(completion.wellName()); + auto item = wellPathToLgrNameMap.find(wellPath); + wellPathToLgrNameMap[wellPath].insert(completionsForLgr.first); + } + } + + for (const auto& wellPathsForLgr : wellPathToLgrNameMap) + { + const RimWellPath* wellPath = wellPathsForLgr.first; + + std::tuple itemWithLowestMD = + std::make_tuple(std::numeric_limits::max(), cvf::Vec2i(), ""); + + // Find first LGR-intersection along the well path + + for (const auto& lgrName : wellPathsForLgr.second) + { + auto ijIntersection = wellPathUpperGridIntersectionIJ(gridCase, wellPath, lgrName); + if (ijIntersection.first < std::get<0>(itemWithLowestMD)) + { + itemWithLowestMD = std::make_tuple(ijIntersection.first, ijIntersection.second, lgrName); + } + } + + { + double measuredDepth = 0.0; + cvf::Vec2i ijIntersection; + QString lgrName; + + std::tie(measuredDepth, ijIntersection, lgrName) = itemWithLowestMD; + + auto rimCompletions = wellPath->completions(); + + formatter.add(rimCompletions->wellNameForExport()) + .add(rimCompletions->wellGroupNameForExport()) + .add(lgrName) + .addOneBasedCellIndex(ijIntersection.x()) + .addOneBasedCellIndex(ijIntersection.y()) + .add(rimCompletions->referenceDepthForExport()) + .add(rimCompletions->wellTypeNameForExport()) + .rowCompleted(); + } + } + formatter.tableCompleted(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::sortAndExportCompletionsToFile( + RimEclipseCase* eclipseCase, + const QString& folderName, + const QString& fileName, + std::vector& completions, + const std::vector& wellPathFractureReportItems, + RicExportCompletionDataSettingsUi::CompdatExportType exportType) +{ + // Sort completions based on grid they belong to + std::vector completionsForMainGrid = mainGridCompletions(completions); + std::map> completionsForSubGrids = subGridsCompletions(completions); if (!completionsForMainGrid.empty()) { - std::map> completionsForGrid; - completionsForGrid.insert(std::pair>("", completionsForMainGrid)); + try + { + QFilePtr exportFile = openFileForExport(folderName, fileName); + + std::map> completionsForGrid; + completionsForGrid.insert(std::pair>("", completionsForMainGrid)); - exportCompdatAndWpimultTables(folderName, fileName, completionsForGrid, exportType); + exportWellPathFractureReport(eclipseCase, exportFile, wellPathFractureReportItems); + exportWelspecsToFile(eclipseCase, exportFile, completionsForMainGrid); + exportCompdatAndWpimultTables(eclipseCase, exportFile, completionsForGrid, exportType); + } + catch (OpenFileException) + { + } } if (!completionsForSubGrids.empty()) { - QString lgrFileName = fileName + "_LGR"; - exportCompdatAndWpimultTables(folderName, lgrFileName, completionsForSubGrids, exportType); + try + { + QString lgrFileName = fileName + "_LGR"; + QFilePtr exportFile = openFileForExport(folderName, lgrFileName); + + exportWellPathFractureReport(eclipseCase, exportFile, wellPathFractureReportItems); + exportWelspeclToFile(eclipseCase, exportFile, completionsForSubGrids); + exportCompdatAndWpimultTables(eclipseCase, exportFile, completionsForSubGrids, exportType); + } + catch (OpenFileException) + { + } } } @@ -541,32 +1417,15 @@ void RicWellPathExportCompletionDataFeatureImpl::sortAndExportCompletionsToFile( /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportCompletionDataFeatureImpl::exportCompdatAndWpimultTables( - const QString& folderName, - const QString& fileName, + RimEclipseCase* sourceCase, + QFilePtr exportFile, const std::map>& completionsPerGrid, RicExportCompletionDataSettingsUi::CompdatExportType exportType) { if (completionsPerGrid.empty()) return; - QDir exportFolder(folderName); - if (!exportFolder.exists()) - { - bool createdPath = exportFolder.mkpath("."); - if (createdPath) - RiaLogging::info("Created export folder " + folderName); - else - RiaLogging::error("Selected output folder does not exist, and could not be created."); - } - - QString filePath = exportFolder.filePath(fileName); - QFile exportFile(filePath); - if (!exportFile.open(QIODevice::WriteOnly)) - { - RiaLogging::error(QString("Export Completions Data: Could not open the file: %1").arg(filePath)); - return; - } + QTextStream stream(exportFile.get()); - QTextStream stream(&exportFile); RifEclipseDataTableFormatter formatter(stream); formatter.setColumnSpacing(3); @@ -587,7 +1446,7 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompdatAndWpimultTables( } } - RiaLogging::info(QString("Successfully exported completion data to %1").arg(filePath)); + RiaLogging::info(QString("Successfully exported completion data to %1").arg(exportFile->fileName())); } //-------------------------------------------------------------------------------------------------- @@ -617,8 +1476,7 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompdatTableUsingFormatte RifEclipseOutputTableColumn("S"), RifEclipseOutputTableColumn( "Df", RifEclipseOutputTableDoubleFormatting(RifEclipseOutputTableDoubleFormat::RIF_SCIENTIFIC)), - RifEclipseOutputTableColumn("DIR"), - RifEclipseOutputTableColumn("r0")}; + RifEclipseOutputTableColumn("DIR")}; formatter.keyword("COMPDAT"); } @@ -640,8 +1498,7 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompdatTableUsingFormatte RifEclipseOutputTableColumn("S"), RifEclipseOutputTableColumn( "Df", RifEclipseOutputTableDoubleFormatting(RifEclipseOutputTableDoubleFormat::RIF_SCIENTIFIC)), - RifEclipseOutputTableColumn("DIR"), - RifEclipseOutputTableColumn("r0")}; + RifEclipseOutputTableColumn("DIR")}; formatter.keyword("COMPDATL"); } @@ -682,10 +1539,10 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompdatTableUsingFormatte formatter.add(gridName); } - formatter.addZeroBasedCellIndex(data.completionDataGridCell().localCellIndexI()) - .addZeroBasedCellIndex(data.completionDataGridCell().localCellIndexJ()) - .addZeroBasedCellIndex(data.completionDataGridCell().localCellIndexK()) - .addZeroBasedCellIndex(data.completionDataGridCell().localCellIndexK()); + formatter.addOneBasedCellIndex(data.completionDataGridCell().localCellIndexI()) + .addOneBasedCellIndex(data.completionDataGridCell().localCellIndexJ()) + .addOneBasedCellIndex(data.completionDataGridCell().localCellIndexK()) + .addOneBasedCellIndex(data.completionDataGridCell().localCellIndexK()); switch (data.connectionState()) { case OPEN: @@ -699,63 +1556,28 @@ void RicWellPathExportCompletionDataFeatureImpl::exportCompdatTableUsingFormatte break; } - if (RigCompletionData::isDefaultValue(data.saturation())) + formatter.addValueOrDefaultMarker(data.saturation(), RigCompletionData::defaultValue()); + formatter.addValueOrDefaultMarker(data.transmissibility(), RigCompletionData::defaultValue()); + formatter.addValueOrDefaultMarker(data.diameter(), RigCompletionData::defaultValue()); + formatter.addValueOrDefaultMarker(data.kh(), RigCompletionData::defaultValue()); + formatter.addValueOrDefaultMarker(data.skinFactor(), RigCompletionData::defaultValue()); + if (RigCompletionData::isDefaultValue(data.dFactor())) formatter.add("1*"); else - formatter.add(data.saturation()); - - if (data.isNonDarcyFlow() || RigCompletionData::isDefaultValue(data.transmissibility())) - { - if (RigCompletionData::isDefaultValue(data.transmissibility())) - formatter.add("1*"); - else - formatter.add(data.transmissibility()); - - if (RigCompletionData::isDefaultValue(data.diameter())) - formatter.add("1*"); - else - formatter.add(data.diameter()); - if (RigCompletionData::isDefaultValue(data.kh())) - formatter.add("1*"); - else - formatter.add(data.kh()); - if (RigCompletionData::isDefaultValue(data.skinFactor())) - formatter.add("1*"); - else - formatter.add(data.skinFactor()); - if (RigCompletionData::isDefaultValue(data.dFactor())) - formatter.add("1*"); - else - formatter.add(-data.dFactor()); + formatter.add(-data.dFactor()); - switch (data.direction()) - { - case DIR_I: - formatter.add("'X'"); - break; - case DIR_J: - formatter.add("'Y'"); - break; - case DIR_K: - formatter.add("'Z'"); - break; - default: - formatter.add("'Z'"); - break; - } - } - else + switch (data.direction()) { - formatter.add(data.transmissibility()); - - // Based on feedback from Shunping for COMPDATL, hhgs required COMPDAT - // Always include diameter - // See https://github.com/OPM/ResInsight/issues/2517 - // See https://github.com/OPM/ResInsight/issues/2709 - if (RigCompletionData::isDefaultValue(data.diameter())) - formatter.add("1*"); - else - formatter.add(data.diameter()); + case DIR_I: + formatter.add("'X'"); + break; + case DIR_J: + formatter.add("'Y'"); + break; + case DIR_K: + default: + formatter.add("'Z'"); + break; } formatter.rowCompleted(); @@ -806,16 +1628,17 @@ void RicWellPathExportCompletionDataFeatureImpl::exportWpimultTableUsingFormatte } formatter.add(completion.wellName()); - formatter.add(completion.wpimult()); if (!gridName.isEmpty()) { formatter.add(gridName); } - formatter.addZeroBasedCellIndex(completion.completionDataGridCell().localCellIndexI()) - .addZeroBasedCellIndex(completion.completionDataGridCell().localCellIndexJ()) - .addZeroBasedCellIndex(completion.completionDataGridCell().localCellIndexK()); + formatter.add(completion.wpimult()); + + formatter.addOneBasedCellIndex(completion.completionDataGridCell().localCellIndexI()) + .addOneBasedCellIndex(completion.completionDataGridCell().localCellIndexJ()) + .addOneBasedCellIndex(completion.completionDataGridCell().localCellIndexK()); formatter.rowCompleted(); } @@ -826,8 +1649,9 @@ void RicWellPathExportCompletionDataFeatureImpl::exportWpimultTableUsingFormatte /// //-------------------------------------------------------------------------------------------------- std::vector RicWellPathExportCompletionDataFeatureImpl::generatePerforationsCompdatValues( - const RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings) + const RimWellPath* wellPath, + const std::vector& intervals, + const RicExportCompletionDataSettingsUi& settings) { RiaEclipseUnitTools::UnitSystem unitSystem = settings.caseToApply->eclipseCaseData()->unitsType(); @@ -836,7 +1660,7 @@ std::vector RicWellPathExportCompletionDataFeatureImpl::gener if (wellPath->perforationIntervalCollection()->isChecked()) { - for (const RimPerforationInterval* interval : wellPath->perforationIntervalCollection()->perforations()) + for (const RimPerforationInterval* interval : intervals) { if (!interval->isChecked()) continue; if (!interval->isActiveOnDate(settings.caseToApply->timeStepDates()[settings.timeStep])) continue; @@ -859,108 +1683,388 @@ std::vector RicWellPathExportCompletionDataFeatureImpl::gener cell.startMD); CellDirection direction = - calculateDirectionInCell(settings.caseToApply, cell.globCellIndex, cell.intersectionLengthsInCellCS); + calculateCellMainDirection(settings.caseToApply, cell.globCellIndex, cell.intersectionLengthsInCellCS); + + const RimNonDarcyPerforationParameters* nonDarcyParameters = + wellPath->perforationIntervalCollection()->nonDarcyParameters(); + + double transmissibility = 0.0; + double kh = RigCompletionData::defaultValue(); + double dFactor = RigCompletionData::defaultValue(); + + { + auto transmissibilityData = calculateTransmissibilityData(settings.caseToApply, + wellPath, + cell.intersectionLengthsInCellCS, + interval->skinFactor(), + interval->diameter(unitSystem) / 2, + cell.globCellIndex, + settings.useLateralNTG); + + transmissibility = transmissibilityData.connectionFactor(); + + if (nonDarcyParameters->nonDarcyFlowType() == RimNonDarcyPerforationParameters::NON_DARCY_USER_DEFINED) + { + kh = transmissibilityData.kh(); + dFactor = nonDarcyParameters->userDefinedDFactor(); + } + else if (nonDarcyParameters->nonDarcyFlowType() == RimNonDarcyPerforationParameters::NON_DARCY_COMPUTED) + { + kh = transmissibilityData.kh(); + + const double effectiveH = transmissibilityData.effectiveH(); + + const double effectivePermeability = + nonDarcyParameters->gridPermeabilityScalingFactor() * transmissibilityData.effectiveK(); + + dFactor = calculateDFactor(settings.caseToApply, + effectiveH, + cell.globCellIndex, + wellPath->perforationIntervalCollection()->nonDarcyParameters(), + effectivePermeability); + } + } + + completion.setTransAndWPImultBackgroundDataFromPerforation( + transmissibility, interval->skinFactor(), interval->diameter(unitSystem), dFactor, kh, direction); + completion.addMetadata("Perforation Completion", + QString("MD In: %1 - MD Out: %2").arg(cell.startMD).arg(cell.endMD) + + QString(" Transmissibility: ") + QString::number(transmissibility)); + completion.setSourcePdmObject(interval); + completionData.push_back(completion); + } + } + } + + return completionData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMswExportInfo(const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + bool enableSegmentSplitting) +{ + std::vector fishbonesSubs = wellPath->fishbonesCollection()->activeFishbonesSubs(); + + return generateFishbonesMswExportInfo(caseToApply, wellPath, fishbonesSubs, enableSegmentSplitting); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMswExportInfo( + const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + const std::vector& fishbonesSubs, + bool enableSegmentSplitting) +{ + RiaEclipseUnitTools::UnitSystem unitSystem = caseToApply->eclipseCaseData()->unitsType(); + + RicMswExportInfo exportInfo(wellPath, + unitSystem, + wellPath->fishbonesCollection()->startMD(), + wellPath->fishbonesCollection()->mswParameters()->lengthAndDepth().text(), + wellPath->fishbonesCollection()->mswParameters()->pressureDrop().text()); + exportInfo.setLinerDiameter(wellPath->fishbonesCollection()->mswParameters()->linerDiameter(unitSystem)); + exportInfo.setRoughnessFactor(wellPath->fishbonesCollection()->mswParameters()->roughnessFactor(unitSystem)); + + double maxSegmentLength = enableSegmentSplitting ? wellPath->fishbonesCollection()->mswParameters()->maxSegmentLength() + : std::numeric_limits::infinity(); + bool foundSubGridIntersections = false; + double subStartMD = wellPath->fishbonesCollection()->startMD(); + for (RimFishbonesMultipleSubs* subs : fishbonesSubs) + { + for (auto& sub : subs->installedLateralIndices()) + { + double subEndMD = subs->measuredDepth(sub.subIndex); + double subEndTVD = -wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(subEndMD).z(); + int subSegCount = numberOfSplittedSegments(subStartMD, subEndMD, maxSegmentLength); + double subSegLen = (subEndMD - subStartMD) / subSegCount; + + double startMd = subStartMD; + double startTvd = -wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(startMd).z(); + for (int ssi = 0; ssi < subSegCount; ssi++) + { + double endMd = startMd + subSegLen; + double endTvd = -wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMd).z(); + + RicMswSegment location = RicMswSegment(subs->generatedName(), startMd, endMd, startTvd, endTvd, sub.subIndex); + location.setEffectiveDiameter(subs->effectiveDiameter(unitSystem)); + location.setHoleDiameter(subs->holeDiameter(unitSystem)); + location.setOpenHoleRoughnessFactor(subs->openHoleRoughnessFactor(unitSystem)); + location.setSkinFactor(subs->skinFactor()); + location.setIcdFlowCoefficient(subs->icdFlowCoefficient()); + double icdOrificeRadius = subs->icdOrificeDiameter(unitSystem) / 2; + location.setIcdArea(icdOrificeRadius * icdOrificeRadius * cvf::PI_D * subs->icdCount()); + location.setSourcePdmObject(subs); + + if (ssi == 0) + { + // Add completion for ICD + RicMswCompletion icdCompletion(RigCompletionData::ICD, QString("ICD")); + RicMswSubSegment icdSegment(subEndMD, 0.1, subEndTVD, 0.0); + icdCompletion.addSubSegment(icdSegment); + location.addCompletion(icdCompletion); + + for (size_t lateralIndex : sub.lateralIndices) + { + QString label = QString("Lateral %1").arg(lateralIndex); + location.addCompletion(RicMswCompletion(RigCompletionData::FISHBONES, label, lateralIndex)); + } + assignFishbonesLateralIntersections( + caseToApply, subs, &location, &foundSubGridIntersections, maxSegmentLength); + } - double transmissibility = - RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibility(settings.caseToApply, - wellPath, - cell.intersectionLengthsInCellCS, - interval->skinFactor(), - interval->diameter(unitSystem) / 2, - cell.globCellIndex, - settings.useLateralNTG); + exportInfo.addWellSegmentLocation(location); - completion.setTransAndWPImultBackgroundDataFromPerforation( - transmissibility, interval->skinFactor(), interval->diameter(unitSystem), direction); - completion.addMetadata("Perforation Completion", - QString("MD In: %1 - MD Out: %2").arg(cell.startMD).arg(cell.endMD) + - QString(" Transmissibility: ") + QString::number(transmissibility)); - completionData.push_back(completion); + startMd = endMd; + startTvd = endTvd; } + + subStartMD = subEndMD; } } + exportInfo.setHasSubGridIntersections(foundSubGridIntersections); + exportInfo.sortLocations(); - return completionData; + assignBranchAndSegmentNumbers(caseToApply, &exportInfo); + + return exportInfo; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RicWellPathExportCompletionDataFeatureImpl::wellSegmentLocationOrdering(const WellSegmentLocation& first, - const WellSegmentLocation& second) +RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generateFracturesMswExportInfo(RimEclipseCase* caseToApply, + const RimWellPath* wellPath) { - return first.measuredDepth < second.measuredDepth; + std::vector fractures = wellPath->fractureCollection()->activeFractures(); + + return generateFracturesMswExportInfo(caseToApply, wellPath, fractures); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector - RicWellPathExportCompletionDataFeatureImpl::findWellSegmentLocations(const RimEclipseCase* caseToApply, - const RimWellPath* wellPath) +RicMswExportInfo + RicWellPathExportCompletionDataFeatureImpl::generateFracturesMswExportInfo(RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + const std::vector& fractures) { - std::vector fishbonesSubs; + const RigMainGrid* grid = caseToApply->eclipseCaseData()->mainGrid(); + const RigActiveCellInfo* activeCellInfo = caseToApply->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); + RiaEclipseUnitTools::UnitSystem unitSystem = caseToApply->eclipseCaseData()->unitsType(); + + const RigWellPath* wellPathGeometry = wellPath->wellPathGeometry(); + const std::vector& coords = wellPathGeometry->wellPathPoints(); + const std::vector& mds = wellPathGeometry->measureDepths(); + CVF_ASSERT(!coords.empty() && !mds.empty()); + + std::vector intersections = + RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath(caseToApply->eclipseCaseData(), coords, mds); + + double maxSegmentLength = wellPath->fractureCollection()->mswParameters()->maxSegmentLength(); + std::vector subSegIntersections = + spiltIntersectionSegmentsToMaxLength(wellPathGeometry, intersections, maxSegmentLength); + + double initialMD = 0.0; + if (wellPath->fractureCollection()->referenceMDType() == RimWellPathFractureCollection::MANUAL_REFERENCE_MD) + { + initialMD = wellPath->fractureCollection()->manualReferenceMD(); + } + else + { + for (WellPathCellIntersectionInfo intersection : intersections) + { + if (activeCellInfo->isActive(intersection.globCellIndex)) + { + initialMD = intersection.startMD; + break; + } + } + } - if (wellPath->fishbonesCollection()->isChecked()) + RicMswExportInfo exportInfo(wellPath, + unitSystem, + initialMD, + wellPath->fractureCollection()->mswParameters()->lengthAndDepth().text(), + wellPath->fractureCollection()->mswParameters()->pressureDrop().text()); + + exportInfo.setLinerDiameter(wellPath->fractureCollection()->mswParameters()->linerDiameter(unitSystem)); + exportInfo.setRoughnessFactor(wellPath->fractureCollection()->mswParameters()->roughnessFactor(unitSystem)); + + bool foundSubGridIntersections = false; + + // Main bore + int mainBoreSegment = 1; + for (const auto& cellIntInfo : subSegIntersections) { - for (RimFishbonesMultipleSubs* subs : wellPath->fishbonesCollection()->fishbonesSubs()) + double startTVD = cellIntInfo.startTVD; + double endTVD = cellIntInfo.endTVD; + + size_t localGridIdx = 0u; + const RigGridBase* localGrid = grid->gridAndGridLocalIdxFromGlobalCellIdx(cellIntInfo.globCellIndex, &localGridIdx); + QString gridName; + if (localGrid != grid) + { + gridName = QString::fromStdString(localGrid->gridName()); + foundSubGridIntersections = true; + } + + size_t i = 0u, j = 0u, k = 0u; + localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k); + QString label = QString("Main stem segment %1").arg(++mainBoreSegment); + RicMswSegment location(label, cellIntInfo.startMD, cellIntInfo.endMD, startTVD, endTVD); + + // Check if fractures are to be assigned to current main bore segment + for (RimWellPathFracture* fracture : fractures) { - if (subs->isActive()) + double fractureStartMD = fracture->fractureMD(); + if (fracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) { - fishbonesSubs.push_back(subs); + double perforationLength = fracture->fractureTemplate()->perforationLength(); + fractureStartMD -= 0.5 * perforationLength; + } + + if (cvf::Math::valueInRange(fractureStartMD, cellIntInfo.startMD, cellIntInfo.endMD)) + { + std::vector completionData = + RicExportFractureCompletionsImpl::generateCompdatValues(caseToApply, + wellPath->completions()->wellNameForExport(), + wellPath->wellPathGeometry(), + {fracture}, + nullptr, + nullptr); + + assignFractureIntersections(caseToApply, fracture, completionData, &location, &foundSubGridIntersections); } } + + exportInfo.addWellSegmentLocation(location); } + exportInfo.setHasSubGridIntersections(foundSubGridIntersections); + exportInfo.sortLocations(); + assignBranchAndSegmentNumbers(caseToApply, &exportInfo); - return findWellSegmentLocations(caseToApply, wellPath, fishbonesSubs); + return exportInfo; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RicWellPathExportCompletionDataFeatureImpl::findWellSegmentLocations( - const RimEclipseCase* caseToApply, - const RimWellPath* wellPath, - const std::vector& fishbonesSubs) +RicMswExportInfo RicWellPathExportCompletionDataFeatureImpl::generatePerforationsMswExportInfo( + const RicExportCompletionDataSettingsUi& exportSettings, + const RimWellPath* wellPath, + const std::vector& perforationIntervals) { - std::vector wellSegmentLocations; - for (RimFishbonesMultipleSubs* subs : fishbonesSubs) + const RimEclipseCase* caseToApply = exportSettings.caseToApply; + const RigMainGrid* grid = caseToApply->eclipseCaseData()->mainGrid(); + const RigActiveCellInfo* activeCellInfo = caseToApply->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); + RiaEclipseUnitTools::UnitSystem unitSystem = caseToApply->eclipseCaseData()->unitsType(); + + const RigWellPath* wellPathGeometry = wellPath->wellPathGeometry(); + const std::vector& coords = wellPathGeometry->wellPathPoints(); + const std::vector& mds = wellPathGeometry->measureDepths(); + CVF_ASSERT(!coords.empty() && !mds.empty()); + + std::vector intersections = + RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath(caseToApply->eclipseCaseData(), coords, mds); + + double maxSegmentLength = wellPath->perforationIntervalCollection()->mswParameters()->maxSegmentLength(); + std::vector subSegIntersections = + spiltIntersectionSegmentsToMaxLength(wellPathGeometry, intersections, maxSegmentLength); + + double initialMD = 0.0; + for (WellPathCellIntersectionInfo intersection : intersections) { - for (auto& sub : subs->installedLateralIndices()) + if (activeCellInfo->isActive(intersection.globCellIndex)) + { + initialMD = intersection.startMD; + break; + } + } + + RicMswExportInfo exportInfo(wellPath, + unitSystem, + initialMD, + wellPath->perforationIntervalCollection()->mswParameters()->lengthAndDepth().text(), + wellPath->perforationIntervalCollection()->mswParameters()->pressureDrop().text()); + + exportInfo.setLinerDiameter(wellPath->perforationIntervalCollection()->mswParameters()->linerDiameter(unitSystem)); + exportInfo.setRoughnessFactor(wellPath->perforationIntervalCollection()->mswParameters()->roughnessFactor(unitSystem)); + + bool foundSubGridIntersections = false; + + // Main bore + int mainBoreSegment = 1; + for (const auto& cellIntInfo : subSegIntersections) + { + double startTVD = cellIntInfo.startTVD; + double endTVD = cellIntInfo.endTVD; + + size_t localGridIdx = 0u; + const RigGridBase* localGrid = grid->gridAndGridLocalIdxFromGlobalCellIdx(cellIntInfo.globCellIndex, &localGridIdx); + QString gridName; + if (localGrid != grid) + { + gridName = QString::fromStdString(localGrid->gridName()); + foundSubGridIntersections = true; + } + + size_t i = 0u, j = 0u, k = 0u; + localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k); + QString label = QString("Main stem segment %1").arg(++mainBoreSegment); + RicMswSegment location(label, cellIntInfo.startMD, cellIntInfo.endMD, startTVD, endTVD); + + // Check if fractures are to be assigned to current main bore segment + for (const RimPerforationInterval* interval : perforationIntervals) { - double measuredDepth = subs->measuredDepth(sub.subIndex); - cvf::Vec3d position = wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(measuredDepth); - WellSegmentLocation location = WellSegmentLocation(subs, measuredDepth, -position.z(), sub.subIndex); + double intervalStartMD = interval->startMD(); + double intervalEndMD = interval->endMD(); - for (size_t lateralIndex : sub.lateralIndices) + if (cellIntInfo.endMD > intervalStartMD && cellIntInfo.startMD < intervalEndMD) { - location.laterals.push_back(WellSegmentLateral(lateralIndex)); + std::vector completionData = + generatePerforationsCompdatValues(wellPath, {interval}, exportSettings); + assignPerforationIntervalIntersections( + caseToApply, interval, completionData, &location, &cellIntInfo, &foundSubGridIntersections); } - wellSegmentLocations.push_back(location); } - } - std::sort(wellSegmentLocations.begin(), wellSegmentLocations.end(), wellSegmentLocationOrdering); - assignLateralIntersectionsAndBranchAndSegmentNumbers(caseToApply, &wellSegmentLocations); + exportInfo.addWellSegmentLocation(location); + } + exportInfo.setHasSubGridIntersections(foundSubGridIntersections); + exportInfo.sortLocations(); + assignBranchAndSegmentNumbers(caseToApply, &exportInfo); - return wellSegmentLocations; + return exportInfo; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersections(const RimEclipseCase* caseToApply, - WellSegmentLocation* location, - int* branchNum, - int* segmentNum) +void RicWellPathExportCompletionDataFeatureImpl::assignFishbonesLateralIntersections( + const RimEclipseCase* caseToApply, + const RimFishbonesMultipleSubs* fishbonesSubs, + RicMswSegment* location, + bool* foundSubGridIntersections, + double maxSegmentLength) { - for (WellSegmentLateral& lateral : location->laterals) + CVF_ASSERT(foundSubGridIntersections != nullptr); + + const RigMainGrid* grid = caseToApply->eclipseCaseData()->mainGrid(); + + for (RicMswCompletion& completion : location->completions()) { - ++(*branchNum); - lateral.branchNumber = (*branchNum); + if (completion.completionType() != RigCompletionData::FISHBONES) + { + continue; + } std::vector> lateralCoordMDPairs = - location->fishbonesSubs->coordsAndMDForLateral(location->subIndex, lateral.lateralIndex); + fishbonesSubs->coordsAndMDForLateral(location->subIndex(), completion.index()); if (lateralCoordMDPairs.empty()) { @@ -982,25 +2086,155 @@ void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersections(cons std::vector intersections = RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath( caseToApply->eclipseCaseData(), lateralCoords, lateralMDs); + + RigWellPath pathGeometry; + pathGeometry.m_wellPathPoints = lateralCoords; + pathGeometry.m_measuredDepths = lateralMDs; + std::vector subSegIntersections = + spiltIntersectionSegmentsToMaxLength(&pathGeometry, intersections, maxSegmentLength); + double previousExitMD = lateralMDs.front(); - double previousExitTVD = lateralCoords.front().z(); + double previousExitTVD = -lateralCoords.front().z(); + + for (const auto& cellIntInfo : subSegIntersections) + { + size_t localGridIdx = 0u; + const RigGridBase* localGrid = grid->gridAndGridLocalIdxFromGlobalCellIdx(cellIntInfo.globCellIndex, &localGridIdx); + QString gridName; + if (localGrid != grid) + { + gridName = QString::fromStdString(localGrid->gridName()); + *foundSubGridIntersections = true; + } + + size_t i = 0u, j = 0u, k = 0u; + localGrid->ijkFromCellIndex(localGridIdx, &i, &j, &k); + RicMswSubSegment subSegment( + previousExitMD, cellIntInfo.endMD - previousExitMD, previousExitTVD, cellIntInfo.endTVD - previousExitTVD); + + RicMswSubSegmentCellIntersection intersection( + gridName, cellIntInfo.globCellIndex, cvf::Vec3st(i, j, k), cellIntInfo.intersectionLengthsInCellCS); + subSegment.addIntersection(intersection); + completion.addSubSegment(subSegment); + + previousExitMD = cellIntInfo.endMD; + previousExitTVD = cellIntInfo.endTVD; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::assignFractureIntersections(const RimEclipseCase* caseToApply, + const RimWellPathFracture* fracture, + const std::vector& completionData, + RicMswSegment* location, + bool* foundSubGridIntersections) +{ + CVF_ASSERT(foundSubGridIntersections != nullptr); + + RicMswCompletion fractureCompletion(RigCompletionData::FRACTURE, fracture->name()); + double position = fracture->fractureMD(); + double width = fracture->fractureTemplate()->computeFractureWidth(fracture); + + if (fracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) + { + double perforationLength = fracture->fractureTemplate()->perforationLength(); + position -= 0.5 * perforationLength; + width = perforationLength; + } + + RicMswSubSegment subSegment(position, width, 0.0, 0.0); + for (const RigCompletionData& compIntersection : completionData) + { + const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell(); + cvf::Vec3st localIJK(cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK()); + + RicMswSubSegmentCellIntersection intersection(cell.lgrName(), cell.globalCellIndex(), localIJK, cvf::Vec3d::ZERO); + subSegment.addIntersection(intersection); + } + fractureCompletion.addSubSegment(subSegment); + location->addCompletion(fractureCompletion); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::assignPerforationIntervalIntersections( + const RimEclipseCase* caseToApply, + const RimPerforationInterval* interval, + const std::vector& completionData, + RicMswSegment* location, + const SubSegmentIntersectionInfo* cellIntInfo, + bool* foundSubGridIntersections) +{ + CVF_ASSERT(foundSubGridIntersections != nullptr); - int attachedSegmentNumber = location->icdSegmentNumber; - for (const auto& cellIntInfo : intersections) + RicMswCompletion intervalCompletion(RigCompletionData::PERFORATION, interval->name()); + double startMd = std::max(location->startMD(), interval->startMD()); + double endMd = std::min(location->endMD(), interval->endMD()); + RicMswSubSegment subSegment(startMd, endMd - startMd, 0.0, 0.0); + + size_t currCellId = cellIntInfo->globCellIndex; + + for (const RigCompletionData& compIntersection : completionData) + { + const RigCompletionDataGridCell& cell = compIntersection.completionDataGridCell(); + + if (cell.globalCellIndex() != currCellId) continue; + + cvf::Vec3st localIJK(cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK()); + + RicMswSubSegmentCellIntersection intersection( + cell.lgrName(), cell.globalCellIndex(), localIJK, cellIntInfo->intersectionLengthsInCellCS); + subSegment.addIntersection(intersection); + } + intervalCompletion.addSubSegment(subSegment); + location->addCompletion(intervalCompletion); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply, + RicMswSegment* location, + int* branchNum, + int* segmentNum) +{ + int icdSegmentNumber = cvf::UNDEFINED_INT; + for (RicMswCompletion& completion : location->completions()) + { + if (completion.completionType() == RigCompletionData::PERFORATION) + { + completion.setBranchNumber(1); + } + else if (completion.completionType() != RigCompletionData::ICD) { - ++(*segmentNum); - WellSegmentLateralIntersection lateralIntersection((*segmentNum), - attachedSegmentNumber, - cellIntInfo.globCellIndex, - cellIntInfo.endMD - previousExitMD, - cellIntInfo.endPoint.z() - previousExitTVD, - cellIntInfo.intersectionLengthsInCellCS); + ++(*branchNum); + completion.setBranchNumber(*branchNum); + } - lateral.intersections.push_back(lateralIntersection); + int attachedSegmentNumber = location->segmentNumber(); + if (icdSegmentNumber != cvf::UNDEFINED_INT) + { + attachedSegmentNumber = icdSegmentNumber; + } - attachedSegmentNumber = (*segmentNum); - previousExitMD = cellIntInfo.endMD; - previousExitTVD = cellIntInfo.endPoint.z(); + for (auto& subSegment : completion.subSegments()) + { + if (completion.completionType() == RigCompletionData::ICD) + { + subSegment.setSegmentNumber(location->segmentNumber() + 1); + icdSegmentNumber = subSegment.segmentNumber(); + } + else + { + ++(*segmentNum); + subSegment.setSegmentNumber(*segmentNum); + } + subSegment.setAttachedSegmentNumber(attachedSegmentNumber); + attachedSegmentNumber = *segmentNum; } } } @@ -1008,25 +2242,30 @@ void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersections(cons //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersectionsAndBranchAndSegmentNumbers( - const RimEclipseCase* caseToApply, - std::vector* locations) +void RicWellPathExportCompletionDataFeatureImpl::assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply, + RicMswExportInfo* exportInfo) { int segmentNumber = 1; int branchNumber = 1; // First loop over the locations so that each segment on the main stem is an incremental number - for (WellSegmentLocation& location : *locations) + for (RicMswSegment& location : exportInfo->wellSegmentLocations()) { - location.segmentNumber = ++segmentNumber; - location.icdBranchNumber = ++branchNumber; - location.icdSegmentNumber = ++segmentNumber; + location.setSegmentNumber(++segmentNumber); + for (RicMswCompletion& completion : location.completions()) + { + if (completion.completionType() == RigCompletionData::ICD) + { + ++segmentNumber; // Skip a segment number because we need one for the ICD + completion.setBranchNumber(++branchNumber); + } + } } - // Then assign branch and segment numbers to each lateral parts - for (WellSegmentLocation& location : *locations) + // Then assign branch and segment numbers to each completion sub segment + for (RicMswSegment& location : exportInfo->wellSegmentLocations()) { - assignLateralIntersections(caseToApply, &location, &branchNumber, &segmentNumber); + assignBranchAndSegmentNumbers(caseToApply, &location, &branchNumber, &segmentNumber); } } @@ -1034,20 +2273,20 @@ void RicWellPathExportCompletionDataFeatureImpl::assignLateralIntersectionsAndBr /// //-------------------------------------------------------------------------------------------------- void RicWellPathExportCompletionDataFeatureImpl::appendCompletionData( - std::map>* completionData, - const std::vector& data) + std::map>* completionData, + const std::vector& completionsToAppend) { - for (auto& completion : data) + for (const auto& completion : completionsToAppend) { - auto it = completionData->find(completion.completionDataGridCell()); + auto it = completionData->find(completion.completionDataGridCell().globalCellIndex()); if (it != completionData->end()) { it->second.push_back(completion); } else { - completionData->insert(std::pair>( - completion.completionDataGridCell(), std::vector{completion})); + completionData->insert(std::pair>( + completion.completionDataGridCell().globalCellIndex(), std::vector{completion})); } } } @@ -1055,9 +2294,9 @@ void RicWellPathExportCompletionDataFeatureImpl::appendCompletionData( //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -CellDirection RicWellPathExportCompletionDataFeatureImpl::calculateDirectionInCell(RimEclipseCase* eclipseCase, - size_t globalCellIndex, - const cvf::Vec3d& lengthsInCell) +CellDirection RicWellPathExportCompletionDataFeatureImpl::calculateCellMainDirection(RimEclipseCase* eclipseCase, + size_t globalCellIndex, + const cvf::Vec3d& lengthsInCell) { RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); @@ -1092,15 +2331,16 @@ CellDirection RicWellPathExportCompletionDataFeatureImpl::calculateDirectionInCe //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibility(RimEclipseCase* eclipseCase, - const RimWellPath* wellPath, - const cvf::Vec3d& internalCellLengths, - double skinFactor, - double wellRadius, - size_t globalCellIndex, - bool useLateralNTG, - size_t volumeScaleConstant, - CellDirection directionForVolumeScaling) +TransmissibilityData + RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibilityData(RimEclipseCase* eclipseCase, + const RimWellPath* wellPath, + const cvf::Vec3d& internalCellLengths, + double skinFactor, + double wellRadius, + size_t globalCellIndex, + bool useLateralNTG, + size_t volumeScaleConstant, + CellDirection directionForVolumeScaling) { RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); @@ -1124,13 +2364,24 @@ double RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibility(Rim cvf::ref permzAccessObject = RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, 0, RiaDefines::MATRIX_MODEL, 0, "PERMZ"); - double ntg = 1.0; - size_t ntgResIdx = eclipseCase->results(RiaDefines::MATRIX_MODEL)->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "NTG"); - if (ntgResIdx != cvf::UNDEFINED_SIZE_T) + if (dxAccessObject.isNull() || dyAccessObject.isNull() || dzAccessObject.isNull() || permxAccessObject.isNull() || + permyAccessObject.isNull() || permzAccessObject.isNull()) { + return TransmissibilityData(); + } + + double ntg = 1.0; + { + // Trigger loading from file + eclipseCase->results(RiaDefines::MATRIX_MODEL)->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "NTG"); + cvf::ref ntgAccessObject = RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, 0, RiaDefines::MATRIX_MODEL, 0, "NTG"); - ntg = ntgAccessObject->cellScalarGlobIdx(globalCellIndex); + + if (ntgAccessObject.notNull()) + { + ntg = ntgAccessObject->cellScalarGlobIdx(globalCellIndex); + } } double latNtg = useLateralNTG ? ntg : 1.0; @@ -1141,6 +2392,11 @@ double RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibility(Rim double permy = permyAccessObject->cellScalarGlobIdx(globalCellIndex); double permz = permzAccessObject->cellScalarGlobIdx(globalCellIndex); + const double totalKh = RigTransmissibilityEquations::totalKh(permx, permy, permz, internalCellLengths, latNtg, ntg); + + const double effectiveK = RigTransmissibilityEquations::effectiveK(permx, permy, permz, internalCellLengths, latNtg, ntg); + const double effectiveH = RigTransmissibilityEquations::effectiveH(internalCellLengths, latNtg, ntg); + double darcy = RiaEclipseUnitTools::darcysConstant(wellPath->unitSystem()); if (volumeScaleConstant != 1) @@ -1150,14 +2406,65 @@ double RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibility(Rim if (directionForVolumeScaling == CellDirection::DIR_K) dz = dz / volumeScaleConstant; } - double transx = RigTransmissibilityEquations::wellBoreTransmissibilityComponent( + const double transx = RigTransmissibilityEquations::wellBoreTransmissibilityComponent( internalCellLengths.x() * latNtg, permy, permz, dy, dz, wellRadius, skinFactor, darcy); - double transy = RigTransmissibilityEquations::wellBoreTransmissibilityComponent( + const double transy = RigTransmissibilityEquations::wellBoreTransmissibilityComponent( internalCellLengths.y() * latNtg, permx, permz, dx, dz, wellRadius, skinFactor, darcy); - double transz = RigTransmissibilityEquations::wellBoreTransmissibilityComponent( + const double transz = RigTransmissibilityEquations::wellBoreTransmissibilityComponent( internalCellLengths.z() * ntg, permy, permx, dy, dx, wellRadius, skinFactor, darcy); - return RigTransmissibilityEquations::totalConnectionFactor(transx, transy, transz); + const double totalConnectionFactor = RigTransmissibilityEquations::totalConnectionFactor(transx, transy, transz); + + TransmissibilityData trData; + trData.setData(effectiveH, effectiveK, totalConnectionFactor, totalKh); + return trData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathExportCompletionDataFeatureImpl::calculateDFactor(RimEclipseCase* eclipseCase, + double effectiveH, + size_t globalCellIndex, + const RimNonDarcyPerforationParameters* nonDarcyParameters, + const double effectivePermeability) +{ + using EQ = RigPerforationTransmissibilityEquations; + + if (!eclipseCase || !eclipseCase->eclipseCaseData()) + { + return std::numeric_limits::infinity(); + } + + RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); + + double porosity = 0.0; + { + eclipseCase->results(RiaDefines::MATRIX_MODEL)->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "PORO"); + cvf::ref poroAccessObject = + RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, 0, RiaDefines::MATRIX_MODEL, 0, "PORO"); + + if (poroAccessObject.notNull()) + { + porosity = poroAccessObject->cellScalar(globalCellIndex); + } + } + + const double betaFactor = EQ::betaFactor(nonDarcyParameters->inertialCoefficientBeta0(), + effectivePermeability, + nonDarcyParameters->permeabilityScalingFactor(), + porosity, + nonDarcyParameters->porosityScalingFactor()); + + const double alpha = RiaDefines::nonDarcyFlowAlpha(eclipseCaseData->unitsType()); + + return EQ::dFactor(alpha, + betaFactor, + effectivePermeability, + effectiveH, + nonDarcyParameters->wellRadius(), + nonDarcyParameters->relativeGasDensity(), + nonDarcyParameters->gasViscosity()); } //-------------------------------------------------------------------------------------------------- @@ -1229,3 +2536,214 @@ double RicWellPathExportCompletionDataFeatureImpl::calculateTransmissibilityAsEc return trans; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair + RicWellPathExportCompletionDataFeatureImpl::wellPathUpperGridIntersectionIJ(const RimEclipseCase* gridCase, + const RimWellPath* wellPath, + const QString& gridName) +{ + const RigEclipseCaseData* caseData = gridCase->eclipseCaseData(); + const RigMainGrid* mainGrid = caseData->mainGrid(); + const RigActiveCellInfo* activeCellInfo = caseData->activeCellInfo(RiaDefines::MATRIX_MODEL); + const RigWellPath* wellPathGeometry = wellPath->wellPathGeometry(); + const std::vector& coords = wellPathGeometry->wellPathPoints(); + const std::vector& mds = wellPathGeometry->measureDepths(); + CVF_ASSERT(!coords.empty() && !mds.empty()); + + std::vector intersections = + RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath(caseData, coords, mds); + + int gridId = 0; + + if (!gridName.isEmpty()) + { + const auto grid = caseData->grid(gridName); + if (grid) gridId = grid->gridId(); + } + + for (WellPathCellIntersectionInfo intersection : intersections) + { + size_t gridLocalCellIndex = 0; + const RigGridBase* grid = mainGrid->gridAndGridLocalIdxFromGlobalCellIdx(intersection.globCellIndex, &gridLocalCellIndex); + + if (grid->gridId() == gridId && activeCellInfo->isActive(intersection.globCellIndex)) + { + size_t i, j, k; + if (grid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k)) + { + return std::make_pair(intersection.startMD, cvf::Vec2i((int)i, (int)j)); + } + } + } + return std::make_pair(cvf::UNDEFINED_DOUBLE, cvf::Vec2i()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::exportWellSegments(RimEclipseCase* eclipseCase, + QFilePtr exportFile, + const RimWellPath* wellPath, + const std::vector& fractures) +{ + if (eclipseCase == nullptr) + { + RiaLogging::error("Export Fracture Well Segments: Cannot export completions data without specified eclipse case"); + return; + } + + RicMswExportInfo exportInfo = + RicWellPathExportCompletionDataFeatureImpl::generateFracturesMswExportInfo(eclipseCase, wellPath, fractures); + + QTextStream stream(exportFile.get()); + RifEclipseDataTableFormatter formatter(stream); + RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(formatter, exportInfo); + RicWellPathExportCompletionDataFeatureImpl::generateCompsegTables(formatter, exportInfo); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::exportWellSegments(RimEclipseCase* eclipseCase, + QFilePtr exportFile, + const RimWellPath* wellPath, + const std::vector& fishbonesSubs) +{ + if (eclipseCase == nullptr) + { + RiaLogging::error("Export Well Segments: Cannot export completions data without specified eclipse case"); + return; + } + + RicMswExportInfo exportInfo = + RicWellPathExportCompletionDataFeatureImpl::generateFishbonesMswExportInfo(eclipseCase, wellPath, fishbonesSubs, true); + + QTextStream stream(exportFile.get()); + RifEclipseDataTableFormatter formatter(stream); + RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(formatter, exportInfo); + RicWellPathExportCompletionDataFeatureImpl::generateCompsegTables(formatter, exportInfo); + RicWellPathExportCompletionDataFeatureImpl::generateWsegvalvTable(formatter, exportInfo); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::exportWellSegments( + const RicExportCompletionDataSettingsUi& exportSettings, + QFilePtr exportFile, + const RimWellPath* wellPath, + const std::vector& perforationIntervals) +{ + if (exportSettings.caseToApply == nullptr) + { + RiaLogging::error("Export Well Segments: Cannot export completions data without specified eclipse case"); + return; + } + + RicMswExportInfo exportInfo = RicWellPathExportCompletionDataFeatureImpl::generatePerforationsMswExportInfo( + exportSettings, wellPath, perforationIntervals); + + QTextStream stream(exportFile.get()); + RifEclipseDataTableFormatter formatter(stream); + RicWellPathExportCompletionDataFeatureImpl::generateWelsegsTable(formatter, exportInfo); + RicWellPathExportCompletionDataFeatureImpl::generateCompsegTables(formatter, exportInfo); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathExportCompletionDataFeatureImpl::exportCarfinForTemporaryLgrs(const RimEclipseCase* sourceCase, + const QString& folder) +{ + if (!sourceCase || !sourceCase->mainGrid()) return; + + const auto mainGrid = sourceCase->mainGrid(); + const auto& lgrInfosForWells = RicExportLgrFeature::createLgrInfoListForTemporaryLgrs(mainGrid); + + for (const auto& lgrInfoForWell : lgrInfosForWells) + { + RicExportLgrFeature::exportLgrs(folder, lgrInfoForWell.first, lgrInfoForWell.second); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Internal function +//-------------------------------------------------------------------------------------------------- +const RimWellPath* findWellPathFromExportName(const QString& wellNameForExport) +{ + auto allWellPaths = RiaApplication::instance()->project()->allWellPaths(); + + for (const auto wellPath : allWellPaths) + { + if (wellPath->completions()->wellNameForExport() == wellNameForExport) return wellPath; + } + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector + spiltIntersectionSegmentsToMaxLength(const RigWellPath* pathGeometry, + const std::vector& intersections, + double maxSegmentLength) +{ + std::vector out; + + if (!pathGeometry) return out; + + for (size_t i = 0; i < intersections.size(); i++) + { + const auto& intersection = intersections[i]; + double segLen = intersection.endMD - intersection.startMD; + int segCount = (int)std::trunc(segLen / maxSegmentLength) + 1; + + // Calc effective max length + double effectiveMaxSegLen = segLen / segCount; + + if (segCount == 1) + { + out.push_back(SubSegmentIntersectionInfo(intersection.globCellIndex, + -intersection.startPoint.z(), + -intersection.endPoint.z(), + intersection.startMD, + intersection.endMD, + intersection.intersectionLengthsInCellCS)); + } + else + { + double currStartMd = intersection.startMD; + double currEndMd = currStartMd; + double lastTvd = -intersection.startPoint.z(); + + for (int segIndex = 0; segIndex < segCount; segIndex++) + { + bool lasti = segIndex == (segCount - 1); + currEndMd = currStartMd + effectiveMaxSegLen; + + cvf::Vec3d segEndPoint = pathGeometry->interpolatedPointAlongWellPath(currEndMd); + out.push_back(SubSegmentIntersectionInfo(intersection.globCellIndex, + lastTvd, + lasti ? -intersection.endPoint.z() : -segEndPoint.z(), + currStartMd, + lasti ? intersection.endMD : currEndMd, + intersection.intersectionLengthsInCellCS / segCount)); + + currStartMd = currEndMd; + lastTvd = -segEndPoint.z(); + } + } + } + return out; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int numberOfSplittedSegments(double startMd, double endMd, double maxSegmentLength) +{ + return (int)(std::trunc((endMd - startMd) / maxSegmentLength) + 1); +} diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h index 0836e4c073..176fdb70c4 100644 --- a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h @@ -21,11 +21,17 @@ #include "RigCompletionData.h" #include "RicExportCompletionDataSettingsUi.h" +#include "RicMultiSegmentWellExportInfo.h" +#include "RicWellPathFractureReportItem.h" + +#include #include "cvfBase.h" #include "cvfVector3.h" +#include "cvfVector2.h" #include +#include class RigCell; class RigEclipseCaseData; @@ -33,84 +39,70 @@ class RigMainGrid; class RimEclipseCase; class RimFishbonesMultipleSubs; class RimSimWellInView; +class RimPerforationInterval; class RimWellPath; +class RimWellPathFracture; +class RimNonDarcyPerforationParameters; class RifEclipseDataTableFormatter; class RigVirtualPerforationTransmissibilities; +class SubSegmentIntersectionInfo; //================================================================================================== /// //================================================================================================== -struct WellSegmentLateralIntersection +typedef std::shared_ptr QFilePtr; + +class TransmissibilityData { - WellSegmentLateralIntersection(int segmentNumber, - int attachedSegmentNumber, - size_t globalCellIndex, - double length, - double depth, - const cvf::Vec3d& lengthsInCell) - : segmentNumber(segmentNumber) - , attachedSegmentNumber(attachedSegmentNumber) - , globalCellIndex(globalCellIndex) - , mdFromPreviousIntersection(length) - , tvdChangeFromPreviousIntersection(depth) - , lengthsInCell(lengthsInCell) - , mainBoreCell(false) +public: + TransmissibilityData() + : m_isValid(false) + , m_effectiveH(0.0) + , m_effectiveK(0.0) + , m_connectionFactor(0.0) + , m_kh(0.0) { } - int segmentNumber; - int attachedSegmentNumber; - size_t globalCellIndex; - bool mainBoreCell; - double mdFromPreviousIntersection; - double tvdChangeFromPreviousIntersection; - cvf::Vec3d lengthsInCell; -}; + bool isValid() const + { + return m_isValid; + } -//================================================================================================== -/// -//================================================================================================== -struct WellSegmentLateral -{ - WellSegmentLateral(size_t lateralIndex) - : lateralIndex(lateralIndex) - , branchNumber(0) + void setData(double effectiveH, double effectiveK, double connectionFactor, double kh) { + m_isValid = true; + + m_effectiveH = effectiveH; + m_effectiveK = effectiveK; + m_connectionFactor = connectionFactor; + m_kh = kh; } - size_t lateralIndex; - int branchNumber; - std::vector intersections; -}; + double effectiveH() const + { + return m_effectiveH; + } -//================================================================================================== -/// -//================================================================================================== -struct WellSegmentLocation -{ - WellSegmentLocation(const RimFishbonesMultipleSubs* subs, - double measuredDepth, - double trueVerticalDepth, - size_t subIndex, - int segmentNumber = -1) - : fishbonesSubs(subs) - , measuredDepth(measuredDepth) - , trueVerticalDepth(trueVerticalDepth) - , subIndex(subIndex) - , segmentNumber(segmentNumber) - , icdBranchNumber(-1) - , icdSegmentNumber(-1) + double effectiveK() const + { + return m_effectiveK; + } + double connectionFactor() const + { + return m_connectionFactor; + } + double kh() const { + return m_kh; } - const RimFishbonesMultipleSubs* fishbonesSubs; - double measuredDepth; - double trueVerticalDepth; - size_t subIndex; - int segmentNumber; - int icdBranchNumber; - int icdSegmentNumber; - std::vector laterals; +private: + bool m_isValid; + double m_effectiveH; + double m_effectiveK; + double m_connectionFactor; + double m_kh; }; //================================================================================================== @@ -120,81 +112,182 @@ class RicWellPathExportCompletionDataFeatureImpl { public: - static std::vector findWellSegmentLocations(const RimEclipseCase* caseToApply, - const RimWellPath* wellPath); + static RicMswExportInfo generateFishbonesMswExportInfo(const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + bool enableSegmentSplitting); - static std::vector findWellSegmentLocations(const RimEclipseCase* caseToApply, - const RimWellPath* wellPath, - const std::vector& fishbonesSubs); + static RicMswExportInfo generateFishbonesMswExportInfo(const RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + const std::vector& fishbonesSubs, + bool enableSegmentSplitting); - static CellDirection calculateDirectionInCell(RimEclipseCase* eclipseCase, - size_t globalCellIndex, - const cvf::Vec3d& lengthsInCell); - - static double calculateTransmissibility(RimEclipseCase* eclipseCase, - const RimWellPath* wellPath, - const cvf::Vec3d& internalCellLengths, - double skinFactor, - double wellRadius, - size_t globalCellIndex, - bool useLateralNTG, - size_t volumeScaleConstant = 1, - CellDirection directionForVolumeScaling = CellDirection::DIR_I); + static RicMswExportInfo generateFracturesMswExportInfo(RimEclipseCase* caseToApply, + const RimWellPath* wellPath); + + static RicMswExportInfo generateFracturesMswExportInfo(RimEclipseCase* caseToApply, + const RimWellPath* wellPath, + const std::vector& fractures); + + static RicMswExportInfo generatePerforationsMswExportInfo(const RicExportCompletionDataSettingsUi& exportSettings, + const RimWellPath* wellPath, + const std::vector& perforationIntervals); + + static CellDirection calculateCellMainDirection(RimEclipseCase* eclipseCase, + size_t globalCellIndex, + const cvf::Vec3d& lengthsInCell); + + static TransmissibilityData + calculateTransmissibilityData(RimEclipseCase* eclipseCase, + const RimWellPath* wellPath, + const cvf::Vec3d& internalCellLengths, + double skinFactor, + double wellRadius, + size_t globalCellIndex, + bool useLateralNTG, + size_t volumeScaleConstant = 1, + CellDirection directionForVolumeScaling = CellDirection::DIR_I); + static double calculateDFactor(RimEclipseCase* eclipseCase, + double effectiveH, + size_t globalCellIndex, + const RimNonDarcyPerforationParameters* nonDarcyParameters, + const double effectivePermeability); - static void exportCompletions(const std::vector& wellPaths, - const std::vector& simWells, - const RicExportCompletionDataSettingsUi& exportSettings); + static void exportCompletions(const std::vector& wellPaths, + const std::vector& simWells, + const RicExportCompletionDataSettingsUi& exportSettings); - static std::vector computeStaticCompletionsForWellPath(RimWellPath* wellPath, - RimEclipseCase* eclipseCase); + static std::vector computeStaticCompletionsForWellPath(RimWellPath* wellPath, + RimEclipseCase* eclipseCase); - static std::vector computeDynamicCompletionsForWellPath(RimWellPath* wellPath, - RimEclipseCase* eclipseCase, - size_t timeStepIndex); + static std::vector computeDynamicCompletionsForWellPath(RimWellPath* wellPath, + RimEclipseCase* eclipseCase, + size_t timeStepIndex); + + static void generateWelsegsTable(RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo); + + static void generateWelsegsSegments(RifEclipseDataTableFormatter &formatter, + const RicMswExportInfo &exportInfo, + const std::set& exportCompletionTypes); + static void generateWelsegsCompletionCommentHeader(RifEclipseDataTableFormatter &formatter, + RigCompletionData::CompletionType completionType); + static void generateCompsegTables(RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo); + static void generateCompsegTable(RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo, + bool exportSubGridIntersections, + const std::set& exportCompletionTypes); + static void generateCompsegHeader(RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo, + RigCompletionData::CompletionType completionType, + bool exportSubGridIntersections); + static void generateWsegvalvTable(RifEclipseDataTableFormatter& formatter, + const RicMswExportInfo& exportInfo); private: - static double calculateTransmissibilityAsEclipseDoes(RimEclipseCase* eclipseCase, - double skinFactor, - double wellRadius, - size_t globalCellIndex, - CellDirection direction); + static double calculateTransmissibilityAsEclipseDoes(RimEclipseCase* eclipseCase, + double skinFactor, + double wellRadius, + size_t globalCellIndex, + CellDirection direction); - static RigCompletionData combineEclipseCellCompletions(const std::vector& completions, - const RicExportCompletionDataSettingsUi& settings); + static RigCompletionData combineEclipseCellCompletions(const std::vector& completions, + const RicExportCompletionDataSettingsUi& settings); + + static QFilePtr openFileForExport(const QString& fullFileName); + + static QFilePtr openFileForExport(const QString& folderName, + const QString& fileName); + + static std::vector mainGridCompletions(std::vector& allCompletions); - static void sortAndExportCompletionsToFile(const QString& exportFolder, + static std::map> subGridsCompletions(std::vector& allCompletions); + + static void exportWellPathFractureReport(RimEclipseCase* sourceCase, + QFilePtr exportFile, + const std::vector& wellPathFractureReportItems); + + static void exportWelspecsToFile(RimEclipseCase* gridCase, + QFilePtr exportFile, + const std::vector& completions); + + static void exportWelspeclToFile(RimEclipseCase* gridCase, + QFilePtr exportFile, + const std::map>& completions); + + static void sortAndExportCompletionsToFile(RimEclipseCase* eclipseCase, + const QString& exportFolder, const QString& fileName, std::vector& completions, + const std::vector& wellPathFractureReportItems, RicExportCompletionDataSettingsUi::CompdatExportType exportType); - static void exportCompdatAndWpimultTables(const QString& folderName, - const QString& fileName, + static void exportCompdatAndWpimultTables(RimEclipseCase* sourceCase, + QFilePtr exportFile, const std::map>& completionsPerGrid, RicExportCompletionDataSettingsUi::CompdatExportType exportType); - static void exportCompdatTableUsingFormatter(RifEclipseDataTableFormatter& formatter, - const QString& gridName, - const std::vector& completionData); + static void exportCompdatTableUsingFormatter(RifEclipseDataTableFormatter& formatter, + const QString& gridName, + const std::vector& completionData); + + static void exportWpimultTableUsingFormatter(RifEclipseDataTableFormatter& formatter, + const QString& gridName, + const std::vector& completionData); + + static std::vector generatePerforationsCompdatValues(const RimWellPath* wellPath, + const std::vector& intervals, + const RicExportCompletionDataSettingsUi& settings); + + static void assignFishbonesLateralIntersections(const RimEclipseCase* caseToApply, + const RimFishbonesMultipleSubs* fishbonesSubs, + RicMswSegment* location, + bool* foundSubGridIntersections, + double maxSegmentLength); + + static void assignFractureIntersections(const RimEclipseCase* caseToApply, + const RimWellPathFracture* fracture, + const std::vector& completionData, + RicMswSegment* location, + bool* foundSubGridIntersections); + + static void assignPerforationIntervalIntersections(const RimEclipseCase* caseToApply, + const RimPerforationInterval* interval, + const std::vector& completionData, + RicMswSegment* location, + const SubSegmentIntersectionInfo* cellIntInfo, + bool* foundSubGridIntersections); + + static void assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply, + RicMswSegment* location, + int* branchNum, + int* segmentNum); + static void assignBranchAndSegmentNumbers(const RimEclipseCase* caseToApply, + RicMswExportInfo* exportInfo); + + static void appendCompletionData(std::map>* completionData, + const std::vector& data); - static void exportWpimultTableUsingFormatter(RifEclipseDataTableFormatter& formatter, - const QString& gridName, - const std::vector& completionData); + static std::pair wellPathUpperGridIntersectionIJ(const RimEclipseCase* gridCase, + const RimWellPath* wellPath, + const QString& gridName = ""); - static std::vector generatePerforationsCompdatValues(const RimWellPath* wellPath, - const RicExportCompletionDataSettingsUi& settings); + static void exportWellSegments(RimEclipseCase* eclipseCase, + QFilePtr exportFile, + const RimWellPath* wellPath, + const std::vector& fractures); - static bool wellSegmentLocationOrdering(const WellSegmentLocation& first, - const WellSegmentLocation& second); + static void exportWellSegments(RimEclipseCase* eclipseCase, + QFilePtr exportFile, + const RimWellPath* wellPath, + const std::vector& fishbonesSubs); - static void assignLateralIntersections(const RimEclipseCase* caseToApply, - WellSegmentLocation* location, - int* branchNum, - int* segmentNum); + static void exportWellSegments(const RicExportCompletionDataSettingsUi& exportSettings, + QFilePtr exportFile, + const RimWellPath* wellPath, + const std::vector& perforationIntervals); - static void assignLateralIntersectionsAndBranchAndSegmentNumbers(const RimEclipseCase* caseToApply, - std::vector* locations); + static void exportCarfinForTemporaryLgrs(const RimEclipseCase* sourceCase, const QString& folder); - static void appendCompletionData(std::map>* completionData, - const std::vector& data); }; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureReportItem.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureReportItem.cpp new file mode 100644 index 0000000000..70022f4a93 --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureReportItem.cpp @@ -0,0 +1,310 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicWellPathFractureReportItem.h" + +#include "RigTransmissibilityEquations.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicWellPathFractureReportItem::RicWellPathFractureReportItem(const QString& wellPathNameForExport, + const QString& fractureName, + const QString& fractureTemplateName, + double measuredDepth) + : m_wellPathNameForExport(wellPathNameForExport) + , m_wellPathFracture(fractureName) + , m_wellPathFractureTemplate(fractureTemplateName) + , m_mesuredDepth(measuredDepth) + , m_transmissibility(0.0) + , m_connectionCount(0) + , m_area(0.0) + , m_kfwf(0.0) + , m_kf(0.0) + , m_wf(0.0) + , m_xf(0.0) + , m_h(0.0) + , m_km(0.0) + , m_performPressureDepletionScaling(false) + , m_pressureDepletionUserWBHP(0.0) + , m_pressureDepletionActualWBHP(0.0) + , m_pressureDepletionMinPressureDrop(-1.0) + , m_pressureDepletionMaxPressureDrop(-1.0) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathFractureReportItem::setData(double trans, size_t connCount, double area) +{ + m_transmissibility = trans; + m_connectionCount = connCount; + m_area = area; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathFractureReportItem::setWidthAndConductivity(double width, double conductivity) +{ + m_wf = width; + + double permeability = RigTransmissibilityEquations::permeability(conductivity, width); + m_kf = permeability; + + m_kfwf = conductivity; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathFractureReportItem::setHeightAndHalfLength(double height, double halfLength) +{ + m_h = height; + m_xf = halfLength; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathFractureReportItem::setAreaWeightedPermeability(double permeability) +{ + m_km = permeability; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureReportItem::wellPathNameForExport() const +{ + return m_wellPathNameForExport; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureReportItem::fractureName() const +{ + return m_wellPathFracture; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureReportItem::fractureTemplateName() const +{ + return m_wellPathFractureTemplate; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathFractureReportItem::setUnitSystem(RiaEclipseUnitTools::UnitSystem unitSystem) +{ + m_unitSystem = unitSystem; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathFractureReportItem::setPressureDepletionParameters(bool performPDDScaling, QString timeStepString, QString wbhpString, double userWBHP, double actualWBHP, double minPressureDrop, double maxPressureDrop) +{ + m_performPressureDepletionScaling = performPDDScaling; + m_pressureDepletionTimeStepString = timeStepString; + m_pressureDepletionWBHPString = wbhpString; + m_pressureDepletionUserWBHP = userWBHP; + m_pressureDepletionActualWBHP = actualWBHP; + m_pressureDepletionMinPressureDrop = minPressureDrop; + m_pressureDepletionMaxPressureDrop = maxPressureDrop; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaEclipseUnitTools::UnitSystem RicWellPathFractureReportItem::unitSystem() const +{ + return m_unitSystem; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::transmissibility() const +{ + return m_transmissibility; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RicWellPathFractureReportItem::connectionCount() const +{ + return m_connectionCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::fcd() const +{ + double myFcd = 0.0; + + double threshold = 1.0e-7; + if (fabs(kmxf()) > threshold) + { + myFcd = kfwf() / kmxf(); + } + + return myFcd; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::area() const +{ + return m_area; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::kfwf() const +{ + return m_kfwf; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::kf() const +{ + return m_kf; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::wf() const +{ + return m_wf; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::xf() const +{ + return m_xf; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::h() const +{ + return m_h; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::km() const +{ + return m_km; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::kmxf() const +{ + return m_km * m_xf; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicWellPathFractureReportItem::performPressureDepletionScaling() const +{ + return m_performPressureDepletionScaling; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureReportItem::pressureDepletionTimeStepString() const +{ + return m_pressureDepletionTimeStepString; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureReportItem::pressureDepletionWBHPString() const +{ + return m_pressureDepletionWBHPString; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::pressureDepletionUserWBHP() const +{ + return m_pressureDepletionUserWBHP; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::pressureDepletionActualWBHP() const +{ + return m_pressureDepletionActualWBHP; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::pressureDepletionMinPressureDrop() const +{ + return m_pressureDepletionMinPressureDrop; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicWellPathFractureReportItem::pressureDepletionMaxPressureDrop() const +{ + return m_pressureDepletionMaxPressureDrop; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicWellPathFractureReportItem::operator<(const RicWellPathFractureReportItem& other) const +{ + if (this->wellPathNameForExport() != other.wellPathNameForExport()) + { + return this->wellPathNameForExport() < other.wellPathNameForExport(); + } + + return this->m_mesuredDepth < other.m_mesuredDepth; +} diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureReportItem.h b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureReportItem.h new file mode 100644 index 0000000000..e9a6dc6910 --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureReportItem.h @@ -0,0 +1,95 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaEclipseUnitTools.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicWellPathFractureReportItem +{ +public: + RicWellPathFractureReportItem(const QString& wellPathName, const QString& fractureName, const QString& fractureTemplateName, double measuredDepth); + + void setData(double trans, size_t connCount, double area); + void setWidthAndConductivity(double width, double conductivity); + void setHeightAndHalfLength(double height, double halfLength); + void setAreaWeightedPermeability(double permeability); + void setUnitSystem(RiaEclipseUnitTools::UnitSystem unitSystem); + void setPressureDepletionParameters(bool performPressureDepletionScaling, QString timeStepString, QString wbhpString, double userWBHP, double actualWBHP, double minPressureDrop, double maxPressureDrop); + + QString wellPathNameForExport() const; + QString fractureName() const; + QString fractureTemplateName() const; + + RiaEclipseUnitTools::UnitSystem unitSystem() const; + + double transmissibility() const; + size_t connectionCount() const; + double fcd() const; + double area() const; + + double kfwf() const; + double kf() const; + double wf() const; + + double xf() const; + double h() const; + double km() const; + double kmxf() const; + + bool performPressureDepletionScaling() const; + QString pressureDepletionTimeStepString() const; + QString pressureDepletionWBHPString() const; + double pressureDepletionUserWBHP() const; + double pressureDepletionActualWBHP() const; + double pressureDepletionMinPressureDrop() const; + double pressureDepletionMaxPressureDrop() const; + + bool operator < (const RicWellPathFractureReportItem& other) const; + +private: + RiaEclipseUnitTools::UnitSystem m_unitSystem; + QString m_wellPathNameForExport; + QString m_wellPathFracture; + QString m_wellPathFractureTemplate; + double m_mesuredDepth; + + double m_transmissibility; + size_t m_connectionCount; + double m_area; + + double m_kfwf; + double m_kf; + double m_wf; + double m_xf; + double m_h; + double m_km; + + bool m_performPressureDepletionScaling; + QString m_pressureDepletionTimeStepString; + QString m_pressureDepletionWBHPString; + double m_pressureDepletionUserWBHP; + double m_pressureDepletionActualWBHP; + double m_pressureDepletionMinPressureDrop; + double m_pressureDepletionMaxPressureDrop; +}; diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureTextReportFeatureImpl.cpp b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureTextReportFeatureImpl.cpp new file mode 100644 index 0000000000..a9b38bce1b --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureTextReportFeatureImpl.cpp @@ -0,0 +1,819 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicWellPathFractureTextReportFeatureImpl.h" + +#include "RiaApplication.h" +#include "RiaRegressionTestRunner.h" + +#include "RicExportFractureCompletionsImpl.h" +#include "RicWellPathFractureReportItem.h" + +#include "RifEclipseDataTableFormatter.h" + +#include "RigCompletionData.h" +#include "RigTransmissibilityEquations.h" + +#include "RimEclipseCase.h" +#include "RimEllipseFractureTemplate.h" +#include "RimFileWellPath.h" +#include "RimFractureContainment.h" +#include "RimFractureTemplate.h" +#include "RimFractureTemplateCollection.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimStimPlanFractureTemplate.h" +#include "RimTools.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RimWellPathFracture.h" +#include "RimWellPathFractureCollection.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString orientationText(RimFractureTemplate::FracOrientationEnum orientation) +{ + return caf::AppEnum::uiText(orientation); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseOutputTableColumn floatNumberColumn(const QString& text) +{ + return RifEclipseOutputTableColumn(text, RifEclipseOutputTableDoubleFormatting(RIF_FLOAT, 3), RIGHT); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureTextReportFeatureImpl::wellPathFractureReport( + RimEclipseCase* sourceCase, + const std::vector& wellPaths, + const std::vector& wellPathFractureReportItems) const +{ + QString lineStart = "--"; + + QString text; + QTextStream textStream(&text); + + textStream << lineStart + << "========================================================================================================\n"; + + textStream << lineStart << " RESINSIGHT DATA\n"; + + textStream << lineStart << "\n"; + + + std::vector stimPlanTemplates; + std::vector ellipseTemplates; + + + { + auto proj = RiaApplication::instance()->project(); + auto fractureTemplates = proj->activeOilField()->fractureDefinitionCollection()->fractureTemplates(); + + std::set usedFractureTemplateNames; + for (const auto& item : wellPathFractureReportItems) + { + usedFractureTemplateNames.insert(item.fractureTemplateName()); + } + + for (const auto fracTemplate : fractureTemplates) + { + if (usedFractureTemplateNames.find(fracTemplate->name()) == usedFractureTemplateNames.end()) + { + continue; + } + + auto stimPlanTemplate = dynamic_cast(fracTemplate); + if (stimPlanTemplate) + { + stimPlanTemplates.push_back(stimPlanTemplate); + } + + auto ellipseTemplate = dynamic_cast(fracTemplate); + if (ellipseTemplate) + { + ellipseTemplates.push_back(ellipseTemplate); + } + } + } + + if (!RiaRegressionTestRunner::instance()->isRunningRegressionTests()) + { + if (sourceCase) + { + textStream << lineStart << " Grid Model:\n"; + textStream << lineStart << " " << sourceCase->gridFileName() << "\n"; + textStream << lineStart << "\n"; + } + + { + QString tableText = createWellFileLocationText(wellPaths); + textStream << tableText; + textStream << lineStart << "\n"; + } + + { + QString tableText = createStimPlanFileLocationText(stimPlanTemplates); + textStream << tableText; + textStream << lineStart << "\n"; + } + } + + { + QString tableText = createEllipseFractureText(ellipseTemplates); + textStream << tableText; + textStream << lineStart << "\n"; + } + + { + QString tableText = createStimPlanFractureText(stimPlanTemplates); + textStream << tableText; + textStream << lineStart << "\n"; + } + + { + std::vector fracTemplates; + fracTemplates.insert(fracTemplates.end(), ellipseTemplates.begin(), ellipseTemplates.end()); + fracTemplates.insert(fracTemplates.end(), stimPlanTemplates.begin(), stimPlanTemplates.end()); + + QString tableText = createFractureText(fracTemplates); + textStream << tableText; + textStream << lineStart << "\n"; + } + + { + std::vector wellPathFractures; + for (const auto& w : wellPaths) + { + for (const auto& frac : w->fractureCollection()->activeFractures()) + { + wellPathFractures.push_back(frac); + } + } + + std::sort(wellPathFractures.begin(), wellPathFractures.end(), RimWellPathFracture::compareByWellPathNameAndMD); + + { + QString tableText = createFractureInstancesText(wellPathFractures); + textStream << tableText; + textStream << lineStart << "\n"; + } + + { + QString tableText = createFractureCompletionSummaryText(wellPathFractureReportItems); + textStream << tableText; + textStream << lineStart << "\n"; + } + + { + QString tableText = createFracturePressureDepletionSummaryText(wellPathFractureReportItems); + textStream << tableText; + textStream << lineStart << "\n"; + } + + { + textStream << lineStart << " Maximum number of connections per well\n"; + textStream << lineStart << "\n"; + + QString tableText = createConnectionsPerWellText(wellPathFractureReportItems); + textStream << tableText; + textStream << lineStart << "\n"; + } + } + + return text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicWellPathFractureTextReportFeatureImpl::wellPathsWithActiveFractures() +{ + std::vector wellPaths; + + auto* wellPathColl = RimTools::wellPathCollection(); + if (wellPathColl) + { + for (const auto& wellPath : wellPathColl->wellPaths()) + { + if (!wellPath->fractureCollection()->activeFractures().empty()) + { + wellPaths.push_back(wellPath); + } + } + } + + return wellPaths; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureTextReportFeatureImpl::createWellFileLocationText(const std::vector& wellPaths) const +{ + if (wellPaths.empty()) return ""; + + QString tableText; + + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + configureFormatter(&formatter); + + std::vector header = { + RifEclipseOutputTableColumn("Well"), + RifEclipseOutputTableColumn("Location"), + }; + + formatter.header(header); + + formatter.addHorizontalLine('-'); + + if (!wellPaths.empty()) + { + for (const auto& wellPath : wellPaths) + { + auto fileWellPath = dynamic_cast(wellPath); + if (fileWellPath) + { + formatter.add(wellPath->name()); + formatter.add(fileWellPath->filepath()); + formatter.rowCompleted(); + } + } + } + + formatter.tableCompleted(); + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureTextReportFeatureImpl::createStimPlanFileLocationText( + const std::vector& stimPlanTemplates) const +{ + if (stimPlanTemplates.empty()) return ""; + + QString tableText; + + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + configureFormatter(&formatter); + + std::vector header = { + RifEclipseOutputTableColumn("StimPlan Name"), + RifEclipseOutputTableColumn("Location"), + }; + + formatter.header(header); + + formatter.addHorizontalLine('-'); + + if (!stimPlanTemplates.empty()) + { + for (const auto& stimPlanTemplate : stimPlanTemplates) + { + formatter.add(stimPlanTemplate->name()); + formatter.add(stimPlanTemplate->fileName()); + formatter.rowCompleted(); + } + } + + formatter.tableCompleted(); + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureTextReportFeatureImpl::createStimPlanFractureText( + const std::vector& stimPlanTemplates) const +{ + if (stimPlanTemplates.empty()) return ""; + + QString tableText; + + RiaEclipseUnitTools::UnitSystem unitSystem = stimPlanTemplates.front()->fractureTemplateUnit(); + bool isFieldUnits = unitSystem == RiaEclipseUnitTools::UNITS_FIELD; + + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + configureFormatter(&formatter); + + std::vector header = { + RifEclipseOutputTableColumn("StimPlan"), + RifEclipseOutputTableColumn(" "), + floatNumberColumn("WDiam"), + floatNumberColumn("Skin"), + }; + + formatter.header(header); + + // Second header line + { + formatter.add("Template"); // Template + formatter.add("Orientation"); // Orientation + formatter.add(isFieldUnits ? "[in]" : "[m]"); // WDiam + formatter.add("[] "); // Skin + formatter.rowCompleted(); + } + + formatter.addHorizontalLine('-'); + + for (const auto& stimPlanTemplate : stimPlanTemplates) + { + formatter.add(stimPlanTemplate->name()); + formatter.add(orientationText(stimPlanTemplate->orientationType())); + formatter.add(stimPlanTemplate->wellDiameter()); + formatter.add(stimPlanTemplate->skinFactor()); + + formatter.rowCompleted(); + } + + formatter.tableCompleted(); + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureTextReportFeatureImpl::createEllipseFractureText( + const std::vector& ellipseTemplates) const +{ + if (ellipseTemplates.empty()) return ""; + + QString tableText; + + RiaEclipseUnitTools::UnitSystem unitSystem = ellipseTemplates.front()->fractureTemplateUnit(); + bool isFieldUnits = unitSystem == RiaEclipseUnitTools::UNITS_FIELD; + + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + configureFormatter(&formatter); + + std::vector header = { + RifEclipseOutputTableColumn("Ellipse"), + RifEclipseOutputTableColumn(" "), + floatNumberColumn("Xf"), + floatNumberColumn("Height"), + floatNumberColumn("Kf"), + floatNumberColumn("Wf"), + floatNumberColumn("WDiam"), + floatNumberColumn("Skin"), + }; + + formatter.header(header); + + // Second header line + { + formatter.add("Template"); // Template + formatter.add("Orientation"); // Orientation + formatter.add(isFieldUnits ? "[ft]" : "[m]"); // Xf + formatter.add(isFieldUnits ? "[ft]" : "[m]"); // Height + formatter.add("[mD]"); // Kf + formatter.add(isFieldUnits ? "[in]" : "[m]"); // Wf + formatter.add(isFieldUnits ? "[ft]" : "[m]"); // WDiam + formatter.add("[] "); // Skin + formatter.rowCompleted(); + } + + formatter.addHorizontalLine('-'); + + for (const auto& ellipseTemplate : ellipseTemplates) + { + formatter.add(ellipseTemplate->name()); + formatter.add(orientationText(ellipseTemplate->orientationType())); + + formatter.add(ellipseTemplate->halfLength()); + formatter.add(ellipseTemplate->height()); + + formatter.add(RigTransmissibilityEquations::permeability(ellipseTemplate->conductivity(), ellipseTemplate->width())); + formatter.add(ellipseTemplate->width()); + + formatter.add(ellipseTemplate->wellDiameter()); + formatter.add(ellipseTemplate->skinFactor()); + + formatter.rowCompleted(); + } + + formatter.tableCompleted(); + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString + RicWellPathFractureTextReportFeatureImpl::createFractureText(const std::vector& fractureTemplates) const +{ + if (fractureTemplates.empty()) return ""; + + QString tableText; + + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + configureFormatter(&formatter); + + std::vector header = { + RifEclipseOutputTableColumn(" "), + floatNumberColumn("Top"), + floatNumberColumn("Bot"), + floatNumberColumn("Fault"), + floatNumberColumn("Height"), + floatNumberColumn("Half Length"), + floatNumberColumn("DFac"), + floatNumberColumn("Conductivity"), + }; + + formatter.header(header); + + // Second header line + { + formatter.add("Template"); + formatter.add("Cont"); + formatter.add("Cont"); + formatter.add("Truncation"); + formatter.add("Scale"); + formatter.add("Scale"); + formatter.add("Scale"); + formatter.add("Scale"); + formatter.rowCompleted(); + } + + formatter.addHorizontalLine('-'); + + for (const auto& fracTemplate : fractureTemplates) + { + formatter.add(fracTemplate->name()); + + if (fracTemplate->fractureContainment()->isEnabled()) + { + formatter.add(fracTemplate->fractureContainment()->topKLayer()); + formatter.add(fracTemplate->fractureContainment()->baseKLayer()); + } + else + { + formatter.add("N/A"); + formatter.add("N/A"); + } + + if (fracTemplate->fractureContainment()->minimumFaultThrow() >= 0.0) + { + formatter.add(fracTemplate->fractureContainment()->minimumFaultThrow()); + } + else + { + formatter.add("N/A"); + } + + double halfLengthScale, heightScale, dfactorScale, conductivityScale; + fracTemplate->scaleFactors(&halfLengthScale, &heightScale, &dfactorScale, &conductivityScale); + formatter.add(heightScale); + formatter.add(halfLengthScale); + formatter.add(dfactorScale); + formatter.add(conductivityScale); + + formatter.rowCompleted(); + } + + formatter.tableCompleted(); + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureTextReportFeatureImpl::createFractureInstancesText( + const std::vector& fractures) const +{ + if (fractures.empty()) return ""; + + RiaEclipseUnitTools::UnitSystem unitSystem = fractures.front()->fractureUnit(); // Fix + bool isFieldUnits = unitSystem == RiaEclipseUnitTools::UNITS_FIELD; + + QString tableText; + + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + configureFormatter(&formatter); + + std::vector header = { + RifEclipseOutputTableColumn(""), + RifEclipseOutputTableColumn(""), + RifEclipseOutputTableColumn(""), + floatNumberColumn("MD"), + floatNumberColumn("Dip"), + floatNumberColumn("Tilt"), + floatNumberColumn("LPerf"), + floatNumberColumn("PerfEff"), + floatNumberColumn("Wdia"), + RifEclipseOutputTableColumn( + "Dfac", RifEclipseOutputTableDoubleFormatting(RifEclipseOutputTableDoubleFormat::RIF_SCIENTIFIC), RIGHT), + }; + + formatter.header(header); + + // Second header line + { + formatter.add("Well"); + formatter.add("Fracture"); + formatter.add("Template"); + formatter.add(""); // MD + formatter.add(""); // Dip + formatter.add(""); // Tilt + formatter.add(isFieldUnits ? "[ft]" : "[m]"); // LPerf + formatter.add("[]"); // PerfEff + formatter.add(isFieldUnits ? "[ft]" : "[m]"); // WDia + formatter.add("[...]"); // Dfac + + formatter.rowCompleted(); + } + + formatter.addHorizontalLine('-'); + + for (const auto& fracture : fractures) + { + fracture->ensureValidNonDarcyProperties(); + + QString wellName; + + RimWellPath* wellPath = nullptr; + fracture->firstAncestorOrThisOfType(wellPath); + if (wellPath) + { + wellName = wellPath->name(); + } + + formatter.add(wellName); + formatter.add(fracture->name()); + + if (fracture->fractureTemplate()) + { + formatter.add(fracture->fractureTemplate()->name()); + } + else + { + formatter.add("N/A"); + } + + formatter.add(fracture->fractureMD()); + formatter.add(fracture->dip()); + formatter.add(fracture->tilt()); + + if (fracture->fractureTemplate() && + fracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) + { + formatter.add(fracture->perforationLength()); + } + else + { + formatter.add("N/A"); + } + + formatter.add(fracture->perforationEfficiency()); + formatter.add(fracture->wellRadius() * 2.0); + + if (fracture->fractureTemplate() && fracture->fractureTemplate()->isNonDarcyFlowEnabled()) + { + formatter.add(fracture->nonDarcyProperties().dFactor); + } + else + { + formatter.add("N/A"); + } + + formatter.rowCompleted(); + } + + formatter.tableCompleted(); + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureTextReportFeatureImpl::createFractureCompletionSummaryText( + const std::vector& wellPathFractureReportItems) const +{ + QString tableText; + + RiaEclipseUnitTools::UnitSystem unitSystem = wellPathFractureReportItems.front().unitSystem(); + bool isFieldUnits = unitSystem == RiaEclipseUnitTools::UNITS_FIELD; + + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + configureFormatter(&formatter); + + const QString meanText = "Mean"; + + std::vector header = { + RifEclipseOutputTableColumn(""), // Well + RifEclipseOutputTableColumn(""), // Fracture + RifEclipseOutputTableColumn(""), // Template + floatNumberColumn(""), // Tr + floatNumberColumn(""), //#con + floatNumberColumn(""), // Fcd + RifEclipseOutputTableColumn("", RifEclipseOutputTableDoubleFormatting(RIF_FLOAT, 1), RIGHT), // Area + RifEclipseOutputTableColumn(meanText, RifEclipseOutputTableDoubleFormatting(RIF_FLOAT, 1), RIGHT), // KfWf + RifEclipseOutputTableColumn(meanText, RifEclipseOutputTableDoubleFormatting(RIF_FLOAT, 1), RIGHT), // Kf + floatNumberColumn(meanText), // wf + RifEclipseOutputTableColumn(meanText, RifEclipseOutputTableDoubleFormatting(RIF_FLOAT, 1), RIGHT), // xf + RifEclipseOutputTableColumn(meanText, RifEclipseOutputTableDoubleFormatting(RIF_FLOAT, 1), RIGHT), // H + floatNumberColumn(meanText), // Km + }; + + formatter.header(header); + + // Second header line + { + formatter.add(""); + formatter.add(""); + formatter.add(""); + formatter.add("Tr"); // Tr + formatter.add("#con"); // #con + formatter.add("Fcd"); // Fcd + formatter.add("Area"); // Area + formatter.add("KfWf"); // KfWf + formatter.add("Kf"); // Kf + formatter.add("wf"); // wf + formatter.add("Xf"); // Xf + formatter.add("H"); // H + formatter.add("Km"); // Km + formatter.rowCompleted(); + } + + // Third header line + { + formatter.add("Well"); + formatter.add("Fracture"); + formatter.add("Template"); + formatter.add(isFieldUnits ? "[cP.rb/day/psi]" : "[cP.rm3/day/bars]"); // Tr + formatter.add(""); // #con + formatter.add("[]"); // Fcd + formatter.add(isFieldUnits ? "[ft2]" : "[m2]"); // Area + formatter.add(isFieldUnits ? "[mDft]" : "[mDm]"); // KfWf + formatter.add("[mD]"); // Kf + formatter.add(isFieldUnits ? "[ft]" : "[m]"); // wf + formatter.add(isFieldUnits ? "[ft]" : "[m]"); // Xf + formatter.add(isFieldUnits ? "[ft]" : "[m]"); // H + formatter.add("[mD]"); // Km + formatter.rowCompleted(); + } + + formatter.addHorizontalLine('-'); + + for (const auto& reportItem : wellPathFractureReportItems) + { + formatter.add(reportItem.wellPathNameForExport()); + formatter.add(reportItem.fractureName()); + formatter.add(reportItem.fractureTemplateName()); + + formatter.add(reportItem.transmissibility()); + formatter.add(reportItem.connectionCount()); + formatter.add(reportItem.fcd()); + formatter.add(reportItem.area()); + + formatter.add(reportItem.kfwf()); // KfWf + formatter.add(reportItem.kf()); // Kf + formatter.add(reportItem.wf()); // wf + + formatter.add(reportItem.xf()); // Xf + formatter.add(reportItem.h()); // H + formatter.add(reportItem.km()); // Km + + formatter.rowCompleted(); + } + + formatter.tableCompleted(); + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureTextReportFeatureImpl::createFracturePressureDepletionSummaryText( + const std::vector& wellPathFractureReportItems) const +{ + QString tableText; + + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + configureFormatter(&formatter); + + std::vector header = {RifEclipseOutputTableColumn("Well"), + RifEclipseOutputTableColumn("Fracture"), + RifEclipseOutputTableColumn("Actual WBHP"), + RifEclipseOutputTableColumn("Min Pressure Drop"), + RifEclipseOutputTableColumn("Max Pressure Drop")}; + + bool createdTable = false; + + for (const auto& reportItem : wellPathFractureReportItems) + { + if (reportItem.performPressureDepletionScaling()) + { + if (!createdTable) + { + formatter.comment(QString("Pressure Depletion Time step: %1").arg(reportItem.pressureDepletionTimeStepString())); + formatter.comment(QString("WBHP Source: %1").arg(reportItem.pressureDepletionWBHPString())); + formatter.comment(QString("User Defined WBHP: %1").arg(reportItem.pressureDepletionUserWBHP())); + + formatter.header(header); + formatter.addHorizontalLine('-'); + createdTable = true; + } + formatter.add(reportItem.wellPathNameForExport()); + formatter.add(reportItem.fractureName()); + formatter.add(reportItem.pressureDepletionActualWBHP()); + formatter.add(reportItem.pressureDepletionMinPressureDrop()); + formatter.add(reportItem.pressureDepletionMaxPressureDrop()); + formatter.rowCompleted(); + } + } + if (createdTable) + { + formatter.tableCompleted(); + } + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicWellPathFractureTextReportFeatureImpl::createConnectionsPerWellText( + const std::vector& wellPathFractureReportItems) const +{ + QString tableText; + + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + configureFormatter(&formatter); + + std::vector header = {RifEclipseOutputTableColumn("Well"), floatNumberColumn("ConnCount")}; + + formatter.header(header); + formatter.addHorizontalLine('-'); + + std::map wellConnectionCounts; + for (const auto& reportItem : wellPathFractureReportItems) + { + QString wellPathName = reportItem.wellPathNameForExport(); + if (wellConnectionCounts.find(wellPathName) == wellConnectionCounts.end()) + { + wellConnectionCounts.insert(std::make_pair(wellPathName, 0)); + } + + wellConnectionCounts[wellPathName] += reportItem.connectionCount(); + } + + for (const auto& connCount : wellConnectionCounts) + { + formatter.add(connCount.first); + formatter.add(connCount.second); + + formatter.rowCompleted(); + } + + formatter.tableCompleted(); + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathFractureTextReportFeatureImpl::configureFormatter(RifEclipseDataTableFormatter* formatter) const +{ + if (!formatter) return; + + formatter->setColumnSpacing(3); + formatter->setTableRowPrependText("-- "); + formatter->setTableRowLineAppendText(""); +} diff --git a/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureTextReportFeatureImpl.h b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureTextReportFeatureImpl.h new file mode 100644 index 0000000000..6b768e3027 --- /dev/null +++ b/ApplicationCode/Commands/CompletionExportCommands/RicWellPathFractureTextReportFeatureImpl.h @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimWellPath; +class RimWellPathFracture; +class RimEclipseCase; +class RimFractureTemplate; +class RimEllipseFractureTemplate; +class RimStimPlanFractureTemplate; +class RifEclipseDataTableFormatter; +class RicWellPathFractureReportItem; + +//================================================================================================== +/// +//================================================================================================== +class RicWellPathFractureTextReportFeatureImpl +{ +public: + QString wellPathFractureReport(RimEclipseCase* sourceCase, + const std::vector& wellPaths, + const std::vector& wellPathFractureReportItems) const; + + static std::vector wellPathsWithActiveFractures(); + +private: + QString createWellFileLocationText(const std::vector& wellPaths) const; + QString createStimPlanFileLocationText(const std::vector& stimPlanTemplates) const; + QString createStimPlanFractureText(const std::vector& stimPlanTemplates) const; + QString createEllipseFractureText(const std::vector& ellipseTemplates) const; + QString createFractureText(const std::vector& fractureTemplates) const; + QString createFractureInstancesText(const std::vector& fractureTemplates) const; + + QString + createFractureCompletionSummaryText(const std::vector& wellPathFractureReportItems) const; + QString + createFracturePressureDepletionSummaryText(const std::vector& wellPathFractureReportItems) const; + + QString createConnectionsPerWellText(const std::vector& wellPathFractureReportItems) const; + + void configureFormatter(RifEclipseDataTableFormatter* formatter) const; +}; diff --git a/ApplicationCode/Commands/CrossSectionCommands/RicAppendIntersectionFeature.h b/ApplicationCode/Commands/CrossSectionCommands/RicAppendIntersectionFeature.h index ccadce2511..1b706aa5b7 100644 --- a/ApplicationCode/Commands/CrossSectionCommands/RicAppendIntersectionFeature.h +++ b/ApplicationCode/Commands/CrossSectionCommands/RicAppendIntersectionFeature.h @@ -33,11 +33,11 @@ class RicAppendIntersectionFeatureCmd : public caf::CmdExecuteCommand { public: explicit RicAppendIntersectionFeatureCmd(RimIntersectionCollection* intersectionCollection); - virtual ~RicAppendIntersectionFeatureCmd(); + ~RicAppendIntersectionFeatureCmd() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: caf::PdmPointer m_intersectionCollection; @@ -54,9 +54,9 @@ class RicAppendIntersectionFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/CrossSectionCommands/RicCopyIntersectionsToAllViewsInCaseFeature.h b/ApplicationCode/Commands/CrossSectionCommands/RicCopyIntersectionsToAllViewsInCaseFeature.h index 17de22fb44..1c7286914e 100644 --- a/ApplicationCode/Commands/CrossSectionCommands/RicCopyIntersectionsToAllViewsInCaseFeature.h +++ b/ApplicationCode/Commands/CrossSectionCommands/RicCopyIntersectionsToAllViewsInCaseFeature.h @@ -38,9 +38,9 @@ class RicCopyIntersectionsToAllViewsInCaseFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; void copyIntersectionsToOtherViews(RimCase& gridCase, std::vector intersections); void copyIntersectionBoxesToOtherViews(RimCase& gridCase, std::vector intersectionBoxes); diff --git a/ApplicationCode/Commands/CrossSectionCommands/RicNewAzimuthDipIntersectionFeature.h b/ApplicationCode/Commands/CrossSectionCommands/RicNewAzimuthDipIntersectionFeature.h index 7f4fe88177..78d380cc4c 100644 --- a/ApplicationCode/Commands/CrossSectionCommands/RicNewAzimuthDipIntersectionFeature.h +++ b/ApplicationCode/Commands/CrossSectionCommands/RicNewAzimuthDipIntersectionFeature.h @@ -18,7 +18,7 @@ #pragma once -#include "RicViewerEventInterface.h" +#include "RicPickEventHandler.h" #include "cafCmdExecuteCommand.h" #include "cafPdmPointer.h" @@ -33,11 +33,11 @@ class RicNewAzimuthDipIntersectionFeatureCmd : public caf::CmdExecuteCommand { public: explicit RicNewAzimuthDipIntersectionFeatureCmd(RimIntersectionCollection* intersectionCollection); - virtual ~RicNewAzimuthDipIntersectionFeatureCmd(); + ~RicNewAzimuthDipIntersectionFeatureCmd() override; - virtual QString name() override; - virtual void redo() override; - virtual void undo() override; + QString name() override; + void redo() override; + void undo() override; private: caf::PdmPointer m_intersectionCollection; @@ -56,9 +56,9 @@ class RicNewAzimuthDipIntersectionFeature : public caf::CmdFeature RicNewAzimuthDipIntersectionFeature(); protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/CrossSectionCommands/RicNewPolylineIntersectionFeature.h b/ApplicationCode/Commands/CrossSectionCommands/RicNewPolylineIntersectionFeature.h index e878b6a2a3..4a6591e579 100644 --- a/ApplicationCode/Commands/CrossSectionCommands/RicNewPolylineIntersectionFeature.h +++ b/ApplicationCode/Commands/CrossSectionCommands/RicNewPolylineIntersectionFeature.h @@ -19,7 +19,7 @@ #pragma once -#include "RicViewerEventInterface.h" +#include "RicPickEventHandler.h" #include "cafCmdExecuteCommand.h" #include "cafPdmPointer.h" @@ -34,11 +34,11 @@ class RicNewPolylineIntersectionFeatureCmd : public caf::CmdExecuteCommand { public: explicit RicNewPolylineIntersectionFeatureCmd(RimIntersectionCollection* intersectionCollection); - virtual ~RicNewPolylineIntersectionFeatureCmd(); + ~RicNewPolylineIntersectionFeatureCmd() override; - virtual QString name() override; - virtual void redo() override; - virtual void undo() override; + QString name() override; + void redo() override; + void undo() override; private: caf::PdmPointer m_intersectionCollection; @@ -57,9 +57,9 @@ class RicNewPolylineIntersectionFeature : public caf::CmdFeature RicNewPolylineIntersectionFeature(); protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/CrossSectionCommands/RicNewSimWellIntersectionFeature.h b/ApplicationCode/Commands/CrossSectionCommands/RicNewSimWellIntersectionFeature.h index 99117a545a..66bce4b3f3 100644 --- a/ApplicationCode/Commands/CrossSectionCommands/RicNewSimWellIntersectionFeature.h +++ b/ApplicationCode/Commands/CrossSectionCommands/RicNewSimWellIntersectionFeature.h @@ -34,11 +34,11 @@ class RicNewSimWellIntersectionCmd : public caf::CmdExecuteCommand { public: RicNewSimWellIntersectionCmd(RimIntersectionCollection* intersectionCollection, RimSimWellInView* simWell); - virtual ~RicNewSimWellIntersectionCmd(); + ~RicNewSimWellIntersectionCmd() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: caf::PdmPointer m_intersectionCollection; @@ -56,9 +56,9 @@ class RicNewSimWellIntersectionFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/CrossSectionCommands/RicNewWellPathIntersectionFeature.h b/ApplicationCode/Commands/CrossSectionCommands/RicNewWellPathIntersectionFeature.h index d3b74a3576..acce46edca 100644 --- a/ApplicationCode/Commands/CrossSectionCommands/RicNewWellPathIntersectionFeature.h +++ b/ApplicationCode/Commands/CrossSectionCommands/RicNewWellPathIntersectionFeature.h @@ -34,11 +34,11 @@ class RicNewWellPathIntersectionFeatureCmd : public caf::CmdExecuteCommand { public: RicNewWellPathIntersectionFeatureCmd(RimIntersectionCollection* intersectionCollection, RimWellPath* wellPath); - virtual ~RicNewWellPathIntersectionFeatureCmd(); + ~RicNewWellPathIntersectionFeatureCmd() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: caf::PdmPointer m_intersectionCollection; @@ -59,9 +59,9 @@ class RicNewWellPathIntersectionFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellFeatureImpl.cpp b/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellFeatureImpl.cpp index 2b60dc5ab2..70232b680b 100644 --- a/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellFeatureImpl.cpp +++ b/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellFeatureImpl.cpp @@ -50,22 +50,3 @@ std::vector RicEclipseWellFeatureImpl::selectedWells() return selection; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimSimWellInViewCollection* RicEclipseWellFeatureImpl::wellCollectionFromSelection() -{ - std::vector selection = selectedWells(); - if (selection.size() > 0) - { - RimSimWellInView* firstWell = selection[0]; - - RimSimWellInViewCollection* wellCollection = nullptr; - firstWell->firstAncestorOrThisOfType(wellCollection); - - return wellCollection; - } - - return nullptr; -} - diff --git a/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellFeatureImpl.h b/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellFeatureImpl.h index 3e4c8b1103..5d928a2e5c 100644 --- a/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellFeatureImpl.h +++ b/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellFeatureImpl.h @@ -31,5 +31,4 @@ class RicEclipseWellFeatureImpl public: static bool isAnyWellSelected(); static std::vector selectedWells(); - static RimSimWellInViewCollection* wellCollectionFromSelection(); }; diff --git a/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellShowFeatures.h b/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellShowFeatures.h index 2b794d3256..63511e5044 100644 --- a/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellShowFeatures.h +++ b/ApplicationCode/Commands/EclipseCommands/EclipseWell/RicEclipseWellShowFeatures.h @@ -29,10 +29,10 @@ class RicEclipseWellShowLabelFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; - virtual bool isCommandChecked() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + bool isCommandChecked() override; }; //================================================================================================== @@ -43,10 +43,10 @@ class RicEclipseWellShowHeadFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; - virtual bool isCommandChecked() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + bool isCommandChecked() override; }; //================================================================================================== @@ -57,10 +57,10 @@ class RicEclipseWellShowPipeFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; - virtual bool isCommandChecked() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + bool isCommandChecked() override; }; //================================================================================================== @@ -71,10 +71,10 @@ class RicEclipseWellShowSpheresFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; - virtual bool isCommandChecked() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + bool isCommandChecked() override; }; //================================================================================================== @@ -85,10 +85,10 @@ class RicEclipseWellShowWellCellsFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; - virtual bool isCommandChecked() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + bool isCommandChecked() override; }; //================================================================================================== @@ -99,9 +99,9 @@ class RicEclipseWellShowWellCellFenceFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; - virtual bool isCommandChecked() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + bool isCommandChecked() override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicAddEclipseInputPropertyFeature.cpp b/ApplicationCode/Commands/EclipseCommands/RicAddEclipseInputPropertyFeature.cpp index 06e9b95963..f292a5726f 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicAddEclipseInputPropertyFeature.cpp +++ b/ApplicationCode/Commands/EclipseCommands/RicAddEclipseInputPropertyFeature.cpp @@ -47,8 +47,20 @@ bool RicAddEclipseInputPropertyFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicAddEclipseInputPropertyFeature::onActionTriggered(bool isChecked) { + RimEclipseInputPropertyCollection* inputPropertyCollection = selectedInputPropertyCollection(); + if (!inputPropertyCollection) return; + + QString casePath; + { + RimEclipseInputCase* inputReservoir = nullptr; + inputPropertyCollection->firstAncestorOrThisOfTypeAsserted(inputReservoir); + + QFileInfo fi(inputReservoir->gridFileName()); + casePath = fi.absolutePath(); + } + RiaApplication* app = RiaApplication::instance(); - QString defaultDir = app->lastUsedDialogDirectory("INPUT_FILES"); + QString defaultDir = app->lastUsedDialogDirectoryWithFallback("INPUT_FILES", casePath); QStringList fileNames = QFileDialog::getOpenFileNames(Riu3DMainWindowTools::mainWindowWidget(), "Select Eclipse Input Property Files", defaultDir, "All Files (*.* *)"); if (fileNames.isEmpty()) return; @@ -57,7 +69,6 @@ void RicAddEclipseInputPropertyFeature::onActionTriggered(bool isChecked) defaultDir = QFileInfo(fileNames.last()).absolutePath(); app->setLastUsedDialogDirectory("INPUT_FILES", defaultDir); - RimEclipseInputPropertyCollection* inputPropertyCollection = selectedInputPropertyCollection(); if (inputPropertyCollection) { addEclipseInputProperty(fileNames, inputPropertyCollection); @@ -77,10 +88,7 @@ void RicAddEclipseInputPropertyFeature::setupActionLook(QAction* actionToSetup) //-------------------------------------------------------------------------------------------------- RimEclipseInputPropertyCollection* RicAddEclipseInputPropertyFeature::selectedInputPropertyCollection() const { - std::vector selection; - caf::SelectionManager::instance()->objectsByType(&selection); - - return selection.size() > 0 ? selection[0] : NULL; + return caf::SelectionManager::instance()->selectedItemOfType(); } //-------------------------------------------------------------------------------------------------- @@ -90,12 +98,9 @@ void RicAddEclipseInputPropertyFeature::addEclipseInputProperty(const QStringLis { CVF_ASSERT(inputPropertyCollection); - RimEclipseInputCase* inputReservoir = dynamic_cast(inputPropertyCollection->parentField()->ownerObject()); - CVF_ASSERT(inputReservoir); - if (inputReservoir) - { - inputReservoir->openDataFileSet(fileNames); - } + RimEclipseInputCase* inputReservoir = nullptr; + inputPropertyCollection->firstAncestorOrThisOfTypeAsserted(inputReservoir); + inputReservoir->openDataFileSet(fileNames); inputPropertyCollection->updateConnectedEditors(); } diff --git a/ApplicationCode/Commands/EclipseCommands/RicAddEclipseInputPropertyFeature.h b/ApplicationCode/Commands/EclipseCommands/RicAddEclipseInputPropertyFeature.h index a12c39d407..a291417542 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicAddEclipseInputPropertyFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicAddEclipseInputPropertyFeature.h @@ -33,9 +33,9 @@ class RicAddEclipseInputPropertyFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: RimEclipseInputPropertyCollection* selectedInputPropertyCollection() const; diff --git a/ApplicationCode/Commands/EclipseCommands/RicApplyPropertyFilterAsCellResultFeature.h b/ApplicationCode/Commands/EclipseCommands/RicApplyPropertyFilterAsCellResultFeature.h index bfbe11beea..087fd65997 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicApplyPropertyFilterAsCellResultFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicApplyPropertyFilterAsCellResultFeature.h @@ -29,8 +29,8 @@ class RicApplyPropertyFilterAsCellResultFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicComputeStatisticsFeature.h b/ApplicationCode/Commands/EclipseCommands/RicComputeStatisticsFeature.h index 40311dd00f..62f315922a 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicComputeStatisticsFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicComputeStatisticsFeature.h @@ -34,9 +34,9 @@ class RicComputeStatisticsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: std::vector selectedCases(); diff --git a/ApplicationCode/Commands/EclipseCommands/RicCreateGridCaseGroupFeature.h b/ApplicationCode/Commands/EclipseCommands/RicCreateGridCaseGroupFeature.h index ef7d863655..09ece0b2c0 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicCreateGridCaseGroupFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicCreateGridCaseGroupFeature.h @@ -32,9 +32,9 @@ class RicCreateGridCaseGroupFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicCreateGridCaseGroupFromFilesFeature.h b/ApplicationCode/Commands/EclipseCommands/RicCreateGridCaseGroupFromFilesFeature.h index 94ef8a8bb5..5253e54b99 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicCreateGridCaseGroupFromFilesFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicCreateGridCaseGroupFromFilesFeature.h @@ -34,9 +34,9 @@ class RicCreateGridCaseGroupFromFilesFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: QString m_pathFilter; diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipseCaseNewGroupExec.h b/ApplicationCode/Commands/EclipseCommands/RicEclipseCaseNewGroupExec.h index 75e5013341..e8b1103c85 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipseCaseNewGroupExec.h +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipseCaseNewGroupExec.h @@ -28,10 +28,10 @@ class RicEclipseCaseNewGroupExec : public caf::CmdExecuteCommand { public: RicEclipseCaseNewGroupExec(); - virtual ~RicEclipseCaseNewGroupExec(); + ~RicEclipseCaseNewGroupExec() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipseCaseNewGroupFeature.h b/ApplicationCode/Commands/EclipseCommands/RicEclipseCaseNewGroupFeature.h index 669c92ef5d..3623425bcb 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipseCaseNewGroupFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipseCaseNewGroupFeature.h @@ -31,9 +31,9 @@ class RicEclipseCaseNewGroupFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipseHideFaultFeature.h b/ApplicationCode/Commands/EclipseCommands/RicEclipseHideFaultFeature.h index 60a4c29107..c2343e73a3 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipseHideFaultFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipseHideFaultFeature.h @@ -29,9 +29,9 @@ class RicEclipseHideFaultFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterInsertExec.h b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterInsertExec.h index f996fb5240..0a4c938374 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterInsertExec.h +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterInsertExec.h @@ -31,11 +31,11 @@ class RicEclipsePropertyFilterInsertExec : public caf::CmdExecuteCommand { public: explicit RicEclipsePropertyFilterInsertExec(RimEclipsePropertyFilter* propertyFilter); - virtual ~RicEclipsePropertyFilterInsertExec(); + ~RicEclipsePropertyFilterInsertExec() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: caf::PdmPointer m_propertyFilter; diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterInsertFeature.h b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterInsertFeature.h index 965ea705b2..96e42e7e64 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterInsertFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterInsertFeature.h @@ -31,9 +31,9 @@ class RicEclipsePropertyFilterInsertFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewExec.h b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewExec.h index f20f8d0481..afbba2bdfa 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewExec.h +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewExec.h @@ -31,11 +31,11 @@ class RicEclipsePropertyFilterNewExec : public caf::CmdExecuteCommand { public: explicit RicEclipsePropertyFilterNewExec(RimEclipsePropertyFilterCollection* propertyFilterCollection); - virtual ~RicEclipsePropertyFilterNewExec(); + ~RicEclipsePropertyFilterNewExec() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: caf::PdmPointer m_propertyFilterCollection; diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewFeature.h b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewFeature.h index da3ac841c7..bbb1e191a3 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewFeature.h @@ -31,9 +31,9 @@ class RicEclipsePropertyFilterNewFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewInViewFeature.h b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewInViewFeature.h index a68aeaecf6..1e22a4f8ef 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewInViewFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicEclipsePropertyFilterNewInViewFeature.h @@ -29,9 +29,9 @@ class RicEclipsePropertyFilterNewInViewFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCaseFeature.h b/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCaseFeature.h index 54100a7227..3eed62c52c 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCaseFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCaseFeature.h @@ -32,9 +32,9 @@ class RicImportEclipseCaseFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCaseTimeStepFilterFeature.h b/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCaseTimeStepFilterFeature.h index 9a7aa65038..aec4a9906a 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCaseTimeStepFilterFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCaseTimeStepFilterFeature.h @@ -30,9 +30,9 @@ class RicImportEclipseCaseTimeStepFilterFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCasesFeature.h b/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCasesFeature.h index ac1c49f8c7..22a93cef8d 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCasesFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicImportEclipseCasesFeature.h @@ -35,9 +35,9 @@ class RicImportEclipseCasesFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: QString m_pathFilter; diff --git a/ApplicationCode/Commands/EclipseCommands/RicImportInputEclipseCaseFeature.h b/ApplicationCode/Commands/EclipseCommands/RicImportInputEclipseCaseFeature.h index 85ad907df9..8fd8f46cff 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicImportInputEclipseCaseFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicImportInputEclipseCaseFeature.h @@ -38,9 +38,9 @@ class RicImportInputEclipseCaseFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/EclipseCommands/RicNewStatisticsCaseFeature.h b/ApplicationCode/Commands/EclipseCommands/RicNewStatisticsCaseFeature.h index 61ddb9baae..2178462f83 100644 --- a/ApplicationCode/Commands/EclipseCommands/RicNewStatisticsCaseFeature.h +++ b/ApplicationCode/Commands/EclipseCommands/RicNewStatisticsCaseFeature.h @@ -39,9 +39,9 @@ class RicNewStatisticsCaseFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: caf::PdmUiItem* selectedValidUIItem(); diff --git a/ApplicationCode/Commands/ExportCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/ExportCommands/CMakeLists_files.cmake index 5fdd3d1c04..b044e3b81c 100644 --- a/ApplicationCode/Commands/ExportCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/ExportCommands/CMakeLists_files.cmake @@ -1,4 +1,3 @@ - set (SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RicCellRangeUi.h ${CMAKE_CURRENT_LIST_DIR}/RicExportCarfin.h @@ -17,6 +16,13 @@ ${CMAKE_CURRENT_LIST_DIR}/RicSnapshotAllViewsToFileFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicSnapshotFilenameGenerator.h ${CMAKE_CURRENT_LIST_DIR}/RicSnapshotViewToClipboardFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicSnapshotViewToFileFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicExportSelectedWellPathsFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicExportVisibleWellPathsFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicExportWellPathsUi.h +${CMAKE_CURRENT_LIST_DIR}/RicExportLgrFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicExportLgrUi.h +${CMAKE_CURRENT_LIST_DIR}/RicEclipseCellResultToFileImpl.h +${CMAKE_CURRENT_LIST_DIR}/RicLgrSplitType.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -37,6 +43,12 @@ ${CMAKE_CURRENT_LIST_DIR}/RicSnapshotAllViewsToFileFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicSnapshotFilenameGenerator.cpp ${CMAKE_CURRENT_LIST_DIR}/RicSnapshotViewToClipboardFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicSnapshotViewToFileFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicExportSelectedWellPathsFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicExportVisibleWellPathsFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicExportWellPathsUi.cpp +${CMAKE_CURRENT_LIST_DIR}/RicExportLgrFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicExportLgrUi.cpp +${CMAKE_CURRENT_LIST_DIR}/RicEclipseCellResultToFileImpl.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/Commands/ExportCommands/RicCellRangeUi.h b/ApplicationCode/Commands/ExportCommands/RicCellRangeUi.h index efe2f1b018..590f51d855 100644 --- a/ApplicationCode/Commands/ExportCommands/RicCellRangeUi.h +++ b/ApplicationCode/Commands/ExportCommands/RicCellRangeUi.h @@ -44,10 +44,10 @@ class RicCellRangeUi : public caf::PdmObject QString gridName() const; private: - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; void clampValues(); void setDefaultValues(); diff --git a/ApplicationCode/Commands/ExportCommands/RicEclipseCellResultToFileImpl.cpp b/ApplicationCode/Commands/ExportCommands/RicEclipseCellResultToFileImpl.cpp new file mode 100644 index 0000000000..b1d32ca2fb --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicEclipseCellResultToFileImpl.cpp @@ -0,0 +1,156 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicEclipseCellResultToFileImpl.h" + +#include "RiaLogging.h" +#include "RigCaseCellResultsData.h" +#include "RigEclipseCaseData.h" +#include "RigMainGrid.h" +#include "RigResultAccessor.h" +#include "RigResultAccessorFactory.h" + +#include "RimEclipseResultDefinition.h" + +#include "cafProgressInfo.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicEclipseCellResultToFileImpl::writePropertyToTextFile(const QString& fileName, + RigEclipseCaseData* eclipseCase, + size_t timeStep, + const QString& resultName, + const QString& eclipseKeyword, + const double undefinedValue) +{ + CVF_TIGHT_ASSERT(eclipseCase); + if (!eclipseCase) return false; + + cvf::ref resultAccessor = + RigResultAccessorFactory::createFromUiResultName(eclipseCase, 0, RiaDefines::MATRIX_MODEL, timeStep, resultName); + if (resultAccessor.isNull()) + { + return false; + } + + return writeResultToTextFile( + fileName, eclipseCase, resultAccessor.p(), eclipseKeyword, undefinedValue, "writePropertyToTextFile"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicEclipseCellResultToFileImpl::writeBinaryResultToTextFile(const QString& fileName, + RigEclipseCaseData* eclipseCase, + size_t timeStep, + RimEclipseResultDefinition* resultDefinition, + const QString& eclipseKeyword, + const double undefinedValue, + const QString& logPrefix) +{ + CVF_TIGHT_ASSERT(eclipseCase); + + cvf::ref resultAccessor = + RigResultAccessorFactory::createFromResultDefinition(eclipseCase, 0, timeStep, resultDefinition); + if (resultAccessor.isNull()) + { + return false; + } + + return writeResultToTextFile(fileName, eclipseCase, resultAccessor.p(), eclipseKeyword, undefinedValue, logPrefix); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicEclipseCellResultToFileImpl::writeResultToTextFile(const QString& fileName, + RigEclipseCaseData* eclipseCase, + RigResultAccessor* resultAccessor, + const QString& eclipseKeyword, + const double undefinedValue, + const QString& logPrefix) +{ + if (!resultAccessor) + { + RiaLogging::error(logPrefix + QString(" : : Could not access result data for '%1'").arg(fileName)); + return false; + } + + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + RiaLogging::error(logPrefix + QString(" : Could not open file '%1'. Do the folder exist?").arg(fileName)); + return false; + } + + std::vector resultData; + for (size_t i = 0; i < eclipseCase->mainGrid()->cellCount(); i++) + { + double resultValue = resultAccessor->cellScalar(i); + if (resultValue == HUGE_VAL) + { + resultValue = undefinedValue; + } + + resultData.push_back(resultValue); + } + + writeDataToTextFile(&file, eclipseKeyword, resultData); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicEclipseCellResultToFileImpl::writeDataToTextFile(QFile* file, + const QString& eclipseKeyword, + const std::vector& resultData) +{ + QTextStream textstream(file); + textstream << "\n"; + textstream << "-- Exported from ResInsight" + << "\n"; + textstream << eclipseKeyword << "\n" << right << qSetFieldWidth(16); + + caf::ProgressInfo pi(resultData.size(), QString("Writing data to file %1").arg(file->fileName())); + size_t progressSteps = resultData.size() / 20; + + size_t i; + for (i = 0; i < resultData.size(); i++) + { + textstream << resultData[i]; + + if ((i + 1) % 5 == 0) + { + textstream << "\n"; + } + + if (i % progressSteps == 0) + { + pi.setProgress(i); + } + } + + textstream << "\n" + << "/" + << "\n"; +} diff --git a/ApplicationCode/Commands/ExportCommands/RicEclipseCellResultToFileImpl.h b/ApplicationCode/Commands/ExportCommands/RicEclipseCellResultToFileImpl.h new file mode 100644 index 0000000000..56e8237ee1 --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicEclipseCellResultToFileImpl.h @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +#include + +class QFile; + +class RigEclipseCaseData; +class RimEclipseResultDefinition; +class RigResultAccessor; + +//================================================================================================== +/// +//================================================================================================== +class RicEclipseCellResultToFileImpl +{ +public: + static bool writePropertyToTextFile(const QString& fileName, + RigEclipseCaseData* eclipseCase, + size_t timeStep, + const QString& resultName, + const QString& eclipseKeyword, + const double undefinedValue); + + static bool writeBinaryResultToTextFile(const QString& fileName, + RigEclipseCaseData* eclipseCase, + size_t timeStep, + RimEclipseResultDefinition* resultDefinition, + const QString& eclipseKeyword, + const double undefinedValue, + const QString& logPrefix); + + static bool writeResultToTextFile(const QString& fileName, + RigEclipseCaseData* eclipseCase, + RigResultAccessor* resultAccessor, + const QString& eclipseKeyword, + const double undefinedValue, + const QString& logPrefix); + + static void writeDataToTextFile(QFile* file, const QString& eclipseKeyword, const std::vector& resultData); +}; diff --git a/ApplicationCode/Commands/ExportCommands/RicExportCarfin.cpp b/ApplicationCode/Commands/ExportCommands/RicExportCarfin.cpp index f4e0347960..9bf720c5ee 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportCarfin.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicExportCarfin.cpp @@ -74,7 +74,7 @@ void RicExportCarfin::onActionTriggered(bool isChecked) { QString filePath = exportCarfinObject->exportFileName(); QFile exportFile(filePath); - if (!exportFile.open(QIODevice::WriteOnly)) + if (!exportFile.open(QIODevice::WriteOnly | QIODevice::Text)) { RiaLogging::error(QString("Export CARFIN: Could not open the file: %1").arg(filePath)); return; diff --git a/ApplicationCode/Commands/ExportCommands/RicExportCarfin.h b/ApplicationCode/Commands/ExportCommands/RicExportCarfin.h index c124400cab..14b0095362 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportCarfin.h +++ b/ApplicationCode/Commands/ExportCommands/RicExportCarfin.h @@ -31,9 +31,9 @@ class RicExportCarfin : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static RimEclipseCase* selectedCase(); diff --git a/ApplicationCode/Commands/ExportCommands/RicExportCarfinUi.h b/ApplicationCode/Commands/ExportCommands/RicExportCarfinUi.h index 0e972f533b..0d5dc3082f 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportCarfinUi.h +++ b/ApplicationCode/Commands/ExportCommands/RicExportCarfinUi.h @@ -53,10 +53,10 @@ class RicExportCarfinUi : public caf::PdmObject void setCasePointers(RimEclipseCase* rimCase); void setDefaultValuesFromCase(); - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; private: diff --git a/ApplicationCode/Commands/ExportCommands/RicExportFaultsFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicExportFaultsFeature.cpp index fb86a2eb9c..0c715839b2 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportFaultsFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicExportFaultsFeature.cpp @@ -64,10 +64,7 @@ void RicExportFaultsFeature::onActionTriggered(bool isChecked) if (selectedFaults.size() == 0) return; - RiaApplication* app = RiaApplication::instance(); - - QString projectFolder = app->currentProjectPath(); - QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallback("FAULTS", projectFolder); + QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallbackToProjectFolder("FAULTS"); QString selectedDir = QFileDialog::getExistingDirectory(nullptr, tr("Select Directory"), defaultDir); @@ -81,20 +78,22 @@ void RicExportFaultsFeature::onActionTriggered(bool isChecked) RimEclipseCase* eclCase = nullptr; rimFault->firstAncestorOrThisOfType(eclCase); - QString caseName; - - if (eclCase) caseName = eclCase->caseUserDescription(); + if (eclCase) + { + QString caseName = eclCase->caseUserDescription(); - QString faultName = rimFault->name(); - if ( faultName == RiaDefines::undefinedGridFaultName() ) faultName = "UNDEF"; - if ( faultName == RiaDefines::undefinedGridFaultWithInactiveName() ) faultName = "UNDEF_IA"; + QString faultName = rimFault->name(); + if (faultName == RiaDefines::undefinedGridFaultName()) faultName = "UNDEF"; + if (faultName == RiaDefines::undefinedGridFaultWithInactiveName()) faultName = "UNDEF_IA"; - QString baseFilename = "Fault_" + faultName + "_" + caseName; - baseFilename = caf::Utils::makeValidFileBasename(baseFilename); + QString baseFilename = "Fault_" + faultName + "_" + caseName; + baseFilename = caf::Utils::makeValidFileBasename(baseFilename); - QString completeFilename = selectedDir + "/" + baseFilename + ".grdecl"; + QString completeFilename = selectedDir + "/" + baseFilename + ".grdecl"; - RicExportFaultsFeature::saveFault(completeFilename, eclCase->eclipseCaseData()->mainGrid(), rimFault->faultGeometry()->faultFaces(), faultName); + RicExportFaultsFeature::saveFault( + completeFilename, eclCase->eclipseCaseData()->mainGrid(), rimFault->faultGeometry()->faultFaces(), faultName); + } } @@ -189,7 +188,7 @@ void RicExportFaultsFeature::saveFault(QString completeFilename, const RigMainGr { QFile exportFile(completeFilename); - if (!exportFile.open(QIODevice::WriteOnly) ) + if (!exportFile.open(QIODevice::WriteOnly | QIODevice::Text) ) { RiaLogging::error("Could not open the file : " + completeFilename); } diff --git a/ApplicationCode/Commands/ExportCommands/RicExportFaultsFeature.h b/ApplicationCode/Commands/ExportCommands/RicExportFaultsFeature.h index 5633e1b4f1..379e9591a3 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportFaultsFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicExportFaultsFeature.h @@ -37,9 +37,9 @@ class RicExportFaultsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static void saveFault(QString completeFilename, const RigMainGrid* mainGrid, const std::vector& faultFaces, QString faultName); diff --git a/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.cpp new file mode 100644 index 0000000000..4819bf5ed3 --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.cpp @@ -0,0 +1,1135 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicExportLgrFeature.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" + +#include "CompletionExportCommands/RicWellPathExportCompletionDataFeature.h" +#include "RicExportLgrUi.h" + +#include "RifEclipseDataTableFormatter.h" + +#include "RigCaseCellResultsData.h" +#include "RigMainGrid.h" +#include "RigResultAccessor.h" +#include "RigResultAccessorFactory.h" +#include "RigVirtualPerforationTransmissibilities.h" +#include "RigWellLogExtractor.h" +#include "RigWellPath.h" +#include "RigWellPathIntersectionTools.h" + +#include "RimDialogData.h" +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimProject.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RimWellPathCompletions.h" +#include "RimWellPathFractureCollection.h" +#include "RimFishbonesCollection.h" +#include "RimPerforationCollection.h" + +#include "RiuPlotMainWindow.h" + +#include "RimFishbonesMultipleSubs.h" +#include "RimWellPathFracture.h" +#include "RimPerforationInterval.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +CAF_CMD_SOURCE_INIT(RicExportLgrFeature, "RicExportLgrFeature"); + +//-------------------------------------------------------------------------------------------------- +// +//-------------------------------------------------------------------------------------------------- +#define DOUBLE_INF std::numeric_limits::infinity() + +//-------------------------------------------------------------------------------------------------- +/// Internal class +//-------------------------------------------------------------------------------------------------- +class CellInfo +{ +public: + CellInfo(size_t globCellIndex) + : globCellIndex(globCellIndex) + , startMd(DOUBLE_INF) + , endMd(DOUBLE_INF) + { + } + CellInfo(size_t globCellIndex, double startMd, double endMd) + : globCellIndex(globCellIndex) + , startMd(startMd) + , endMd(endMd) + { + } + + size_t globCellIndex; + double startMd; + double endMd; + + bool operator<(const CellInfo& other) const + { + return startMd < other.startMd; + } +}; + +//-------------------------------------------------------------------------------------------------- +/// Internal class +//-------------------------------------------------------------------------------------------------- +class LgrNameFactory +{ +public: + LgrNameFactory(); + QString newName(RigCompletionData::CompletionType completionType); + QString newName(const QString& baseName, int number); + void resetNumbering(); + +private: + std::map> m_counters; +}; + +//-------------------------------------------------------------------------------------------------- +/// Internal class +//-------------------------------------------------------------------------------------------------- +class IjkBoundingBox +{ + const size_t MAX_SIZE_T = std::numeric_limits::max(); + enum Index {I, J, K}; + +public: + IjkBoundingBox() + : m_min({ MAX_SIZE_T, MAX_SIZE_T, MAX_SIZE_T}), m_max({MAX_SIZE_T, MAX_SIZE_T, MAX_SIZE_T}) {} + + IjkBoundingBox(const IjkBoundingBox& other) + : m_min(other.m_min) + , m_max(other.m_max) + { + } + IjkBoundingBox(const caf::VecIjk& minCell, const caf::VecIjk& maxCell) + { + m_min[I] = minCell.i(); + m_min[J] = minCell.j(); + m_min[K] = minCell.k(); + m_max[I] = maxCell.i(); + m_max[J] = maxCell.j(); + m_max[K] = maxCell.k(); + } + + IjkBoundingBox& operator=(const IjkBoundingBox& other) + { + m_min = other.m_min; + m_max = other.m_max; + return *this; + } + + bool isValid() const + { + return m_min[I] != MAX_SIZE_T && m_min[J] != MAX_SIZE_T && m_min[K] != MAX_SIZE_T && + m_max[I] != MAX_SIZE_T && m_max[J] != MAX_SIZE_T && m_max[K] != MAX_SIZE_T; + } + void addCell(size_t i, size_t j, size_t k) + { + if (!isValid()) + { + m_min = m_max = { i, j, k }; + } + else + { + if (i < m_min[I]) m_min[I] = i; + if (j < m_min[J]) m_min[J] = j; + if (k < m_min[K]) m_min[K] = k; + if (i > m_max[I]) m_max[I] = i; + if (j > m_max[J]) m_max[J] = j; + if (k > m_max[K]) m_max[K] = k; + } + } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + bool intersects(const IjkBoundingBox& box) const + { + CVF_TIGHT_ASSERT(isValid()); + CVF_TIGHT_ASSERT(box.isValid()); + + if (m_max[I] < box.m_min[I] || m_min[I] > box.m_max[I]) return false; + if (m_max[J] < box.m_min[J] || m_min[J] > box.m_max[J]) return false; + if (m_max[K] < box.m_min[K] || m_min[K] > box.m_max[K]) return false; + + return true; + } + + caf::VecIjk min() const + { + return caf::VecIjk(m_min[I], m_min[J], m_min[K]); + } + caf::VecIjk max() const + { + return caf::VecIjk(m_max[I], m_max[J], m_max[K]); + } + +private: + std::array m_min; + std::array m_max; +}; + +//-------------------------------------------------------------------------------------------------- +// Internal function +//-------------------------------------------------------------------------------------------------- +//int completionPriority(const RigCompletionData& completion) +//{ +// return completion.completionType() == RigCompletionData::FRACTURE ? 1 : +// completion.completionType() == RigCompletionData::FISHBONES ? 2 : +// completion.completionType() == RigCompletionData::PERFORATION ? 3 : 4; +//} + +//-------------------------------------------------------------------------------------------------- +// Internal function +//-------------------------------------------------------------------------------------------------- +std::vector filterCompletionsOnType(const std::vector& completions, + const std::set& includedCompletionTypes) +{ + std::vector filtered; + for (const auto& completion : completions) + { + if (includedCompletionTypes.count(completion.completionType()) > 0) filtered.push_back(completion); + } + return filtered; +} + +//-------------------------------------------------------------------------------------------------- +// Internal function +//-------------------------------------------------------------------------------------------------- +QString completionName(const caf::PdmObject* object) +{ + auto perf = dynamic_cast(object); + auto frac = dynamic_cast(object); + auto fish = dynamic_cast(object); + + QString name; + if (perf) name = perf->name(); + else if (frac) name = frac->name(); + else if (fish) name = fish->generatedName(); + return name; +} + +//-------------------------------------------------------------------------------------------------- +/// Internal function +/// Returns the completion having highest priority. +/// Pri: 1. Fractures, 2. Fishbones, 3. Perforation intervals +//-------------------------------------------------------------------------------------------------- +//RigCompletionData findCompletionByPriority(const std::vector& completions) +//{ +// std::vector sorted = completions; +// +// std::sort(sorted.begin(), sorted.end(), +// [](const RigCompletionData& c1, const RigCompletionData& c2 ) +// { +// if (completionPriority(c1) == completionPriority(c2)) +// { +// return completionName(c1.sourcePdmObject()) < completionName(c2.sourcePdmObject()); +// } +// return completionPriority(c1) < completionPriority(c2); +// }); +// return sorted.front(); +//} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicExportLgrUi* RicExportLgrFeature::openDialog(const QString& dialogTitle, + RimEclipseCase* defaultCase, + int defaultTimeStep, + bool hideExportFolderField) +{ + RiaApplication* app = RiaApplication::instance(); + RimProject* proj = app->project(); + + QString startPath = app->lastUsedDialogDirectory("LGR_EXPORT_DIR"); + if (startPath.isEmpty()) + { + QFileInfo fi(proj->fileName()); + startPath = fi.absolutePath(); + } + + RicExportLgrUi* featureUi = app->project()->dialogData()->exportLgrData(); + if (featureUi->exportFolder().isEmpty()) + { + featureUi->setExportFolder(startPath); + } + + if (!featureUi->caseToApply() && !defaultCase) + { + std::vector cases; + app->project()->allCases(cases); + for (auto c : cases) + { + RimEclipseCase* eclipseCase = dynamic_cast(c); + if (eclipseCase != nullptr) + { + featureUi->setCase(eclipseCase); + break; + } + } + } + if (defaultCase) featureUi->setCase(defaultCase); + featureUi->setTimeStep(defaultTimeStep); + featureUi->hideExportFolderField(hideExportFolderField); + + caf::PdmUiPropertyViewDialog propertyDialog( + nullptr, featureUi, dialogTitle, "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + propertyDialog.resize(QSize(300, 320)); + + if (propertyDialog.exec() == QDialog::Accepted && !featureUi->exportFolder().isEmpty()) + { + app->setLastUsedDialogDirectory("LGR_EXPORT_DIR", featureUi->exportFolder()); + return featureUi; + } + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExportLgrFeature::openFileForExport(const QString& folderName, const QString& fileName, QFile* exportFile) +{ + QDir exportFolder = QDir(folderName); + if (!exportFolder.exists()) + { + bool createdPath = exportFolder.mkpath("."); + if (createdPath) RiaLogging::info("Created export folder " + folderName); + } + + QString filePath = exportFolder.filePath(fileName); + exportFile->setFileName(filePath); + if (!exportFile->open(QIODevice::WriteOnly | QIODevice::Text)) + { + auto errorMessage = QString("Export Well Path: Could not open the file: %1").arg(filePath); + RiaLogging::error(errorMessage); + return false; + } + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrFeature::writeLgrs(QTextStream& stream, const std::vector& lgrInfos) +{ + for (auto lgrInfo : lgrInfos) + { + { + RifEclipseDataTableFormatter formatter(stream); + formatter.comment(QString("LGR: ") + lgrInfo.name); + formatter.keyword("CARFIN"); + formatter.header({RifEclipseOutputTableColumn("Name"), + RifEclipseOutputTableColumn("I1"), + RifEclipseOutputTableColumn("I2"), + RifEclipseOutputTableColumn("J1"), + RifEclipseOutputTableColumn("J2"), + RifEclipseOutputTableColumn("K1"), + RifEclipseOutputTableColumn("K2"), + RifEclipseOutputTableColumn("NX"), + RifEclipseOutputTableColumn("NY"), + RifEclipseOutputTableColumn("NZ")}); + + formatter.add(lgrInfo.name); + formatter.addOneBasedCellIndex(lgrInfo.mainGridStartCell.i()); + formatter.addOneBasedCellIndex(lgrInfo.mainGridEndCell.i()); + formatter.addOneBasedCellIndex(lgrInfo.mainGridStartCell.j()); + formatter.addOneBasedCellIndex(lgrInfo.mainGridEndCell.j()); + formatter.addOneBasedCellIndex(lgrInfo.mainGridStartCell.k()); + formatter.addOneBasedCellIndex(lgrInfo.mainGridEndCell.k()); + formatter.add(lgrInfo.sizesPerMainGridCell().i()); + formatter.add(lgrInfo.sizesPerMainGridCell().j()); + formatter.add(lgrInfo.sizesPerMainGridCell().k()); + formatter.rowCompleted(); + formatter.tableCompleted("", false); + } + + { + RifEclipseDataTableFormatter formatter(stream); + formatter.keyword("ENDFIN"); + formatter.tableCompleted("", true); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrFeature::exportLgrsForWellPaths(const QString& exportFolder, + std::vector wellPaths, + RimEclipseCase* eclipseCase, + size_t timeStep, + caf::VecIjk lgrCellCounts, + Lgr::SplitType splitType, + const std::set& completionTypes, + QStringList* wellsIntersectingOtherLgrs) +{ + std::vector lgrs; + + lgrs = buildLgrsForWellPaths(wellPaths, + eclipseCase, + timeStep, + lgrCellCounts, + splitType, + completionTypes, + wellsIntersectingOtherLgrs); + + for (const auto& wellPath : wellPaths) + { + std::vector expLgrs; + for (const auto& lgr : lgrs) + { + if (lgr.associatedWellPathName == wellPath->name()) + expLgrs.push_back(lgr); + } + + if (!lgrs.empty()) + { + exportLgrs(exportFolder, wellPath->name(), expLgrs); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrFeature::exportLgrs(const QString& exportFolder, const QString& wellName, const std::vector& lgrInfos) +{ + if (!lgrInfos.empty()) + { + // Export + QFile file; + QString fileName = caf::Utils::makeValidFileBasename(QString("LGR_%1").arg(wellName)) + ".dat"; + openFileForExport(exportFolder, fileName, &file); + QTextStream stream(&file); + stream.setRealNumberNotation(QTextStream::FixedNotation); + stream.setRealNumberPrecision(2); + writeLgrs(stream, lgrInfos); + file.close(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicExportLgrFeature::buildLgrsForWellPaths(std::vector wellPaths, + RimEclipseCase* eclipseCase, + size_t timeStep, + caf::VecIjk lgrCellCounts, + Lgr::SplitType splitType, + const std::set& completionTypes, + QStringList* wellsIntersectingOtherLgrs) +{ + std::vector lgrs; + LgrNameFactory lgrNameFactory; + + wellsIntersectingOtherLgrs->clear(); + + bool isIntersectingOtherLgrs = false; + + int firstLgrId = firstAvailableLgrId(eclipseCase->mainGrid()); + + if (splitType == Lgr::LGR_PER_CELL) + { + for (const auto& wellPath : wellPaths) + { + auto intersectingCells = + cellsIntersectingCompletions(eclipseCase, wellPath, timeStep, completionTypes, &isIntersectingOtherLgrs); + auto newLgrs = buildLgrsPerMainCell(firstLgrId + (int)lgrs.size(), eclipseCase, wellPath, intersectingCells, lgrCellCounts, lgrNameFactory); + + lgrs.insert(lgrs.end(), newLgrs.begin(), newLgrs.end()); + if (isIntersectingOtherLgrs) wellsIntersectingOtherLgrs->push_back(wellPath->name()); + } + } + else if (splitType == Lgr::LGR_PER_COMPLETION) + { + auto intersectingCells = cellsIntersectingCompletions_PerCompletion( + eclipseCase, wellPaths, timeStep, completionTypes, wellsIntersectingOtherLgrs); + + auto newLgrs = buildLgrsPerCompletion(firstLgrId + (int)lgrs.size(), eclipseCase, intersectingCells, lgrCellCounts, lgrNameFactory); + lgrs.insert(lgrs.end(), newLgrs.begin(), newLgrs.end()); + } + else if (splitType == Lgr::LGR_PER_WELL) + { + for (const auto& wellPath : wellPaths) + { + int lgrId = firstLgrId + (int)lgrs.size(); + auto lgrName = lgrNameFactory.newName("WELL", lgrId); + + auto intersectingCells = + cellsIntersectingCompletions(eclipseCase, wellPath, timeStep, completionTypes, &isIntersectingOtherLgrs); + lgrs.push_back(buildLgr(lgrId, lgrName, eclipseCase, wellPath->name(), intersectingCells, lgrCellCounts)); + + if (isIntersectingOtherLgrs) wellsIntersectingOtherLgrs->push_back(wellPath->name()); + } + } + return lgrs; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicExportLgrFeature::buildLgrsPerMainCell(int firstLgrId, + RimEclipseCase* eclipseCase, + RimWellPath* wellPath, + const std::vector& intersectingCells, + const caf::VecIjk& lgrSizes, + LgrNameFactory& lgrNameFactory) +{ + std::vector lgrs; + int lgrId = firstLgrId; + for (const auto& intersectionCell : intersectingCells) + { + auto lgrName = lgrNameFactory.newName("", lgrId); + lgrs.push_back(buildLgr(lgrId++, lgrName, eclipseCase, wellPath->name(), {intersectionCell}, lgrSizes)); + } + return lgrs; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicExportLgrFeature::buildLgrsPerCompletion( + int firstLgrId, + RimEclipseCase* eclipseCase, + const std::map>& completionInfo, + const caf::VecIjk& lgrSizesPerMainGridCell, + LgrNameFactory& lgrNameFactory) +{ + std::vector lgrs; + + std::vector> occupiedBbs; + + for (const auto& complInfo : completionInfo) + { + auto complCells = std::set(complInfo.second.begin(), complInfo.second.end()); + std::vector cellsUsedInBb; + + while (!complCells.empty()) + { + IjkBoundingBox maxBb; + + for (const auto& cell : complCells) + { + auto candidateBb = maxBb; + candidateBb.addCell(cell.localCellIndexI(), cell.localCellIndexJ(), cell.localCellIndexK()); + + // Test bounding box + bool intersectsExistingBb = false; + for (const auto& bb : occupiedBbs) + { + if (candidateBb.intersects(bb.second)) + { + intersectsExistingBb = true; + break; + } + } + + if (!intersectsExistingBb) + { + maxBb = candidateBb; + cellsUsedInBb.push_back(cell); + } + } + + // If bounding box is invalid, all cells are already occupied + if (!maxBb.isValid()) break; + + occupiedBbs.emplace_back(complInfo.first, maxBb); + + // Remove cells used in bounding box + for (const auto& cell : cellsUsedInBb) + complCells.erase(cell); + } + } + + int lgrId = firstLgrId; + for (auto complInfo : occupiedBbs) + { + auto lgrName = lgrNameFactory.newName(complInfo.first.type); + lgrs.push_back(buildLgr(lgrId++, lgrName, eclipseCase, complInfo.first.wellPathName, complInfo.second, lgrSizesPerMainGridCell)); + } + return lgrs; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LgrInfo RicExportLgrFeature::buildLgr(int lgrId, + const QString& lgrName, + RimEclipseCase* eclipseCase, + const QString& wellPathName, + const std::vector& intersectingCells, + const caf::VecIjk& lgrSizesPerMainGridCell) +{ + // Find min and max IJK + auto iRange = initRange(); + auto jRange = initRange(); + auto kRange = initRange(); + + for (const auto& cell : intersectingCells) + { + iRange.first = std::min(cell.localCellIndexI(), iRange.first); + iRange.second = std::max(cell.localCellIndexI(), iRange.second); + jRange.first = std::min(cell.localCellIndexJ(), jRange.first); + jRange.second = std::max(cell.localCellIndexJ(), jRange.second); + kRange.first = std::min(cell.localCellIndexK(), kRange.first); + kRange.second = std::max(cell.localCellIndexK(), kRange.second); + } + + caf::VecIjk mainGridStartCell(iRange.first, jRange.first, kRange.first); + caf::VecIjk mainGridEndCell(iRange.second, jRange.second, kRange.second); + + IjkBoundingBox boundingBox(mainGridStartCell, mainGridEndCell); + return buildLgr(lgrId, lgrName, eclipseCase, wellPathName, boundingBox, lgrSizesPerMainGridCell); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LgrInfo RicExportLgrFeature::buildLgr(int lgrId, + const QString& lgrName, + RimEclipseCase* eclipseCase, + const QString& wellPathName, + const IjkBoundingBox& boundingBox, + const caf::VecIjk& lgrSizesPerMainGridCell) +{ + caf::VecIjk lgrSizes((boundingBox.max().i() - boundingBox.min().i() + 1) * lgrSizesPerMainGridCell.i(), + (boundingBox.max().j() - boundingBox.min().j() + 1) * lgrSizesPerMainGridCell.j(), + (boundingBox.max().k() - boundingBox.min().k() + 1) * lgrSizesPerMainGridCell.k()); + + return LgrInfo(lgrId, lgrName, wellPathName, lgrSizes, boundingBox.min(), boundingBox.max()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector +RicExportLgrFeature::cellsIntersectingCompletions(RimEclipseCase* eclipseCase, + const RimWellPath* wellPath, + size_t timeStep, + const std::set& completionTypes, + bool* isIntersectingOtherLgrs) +{ + std::vector cells; + + const RigMainGrid* mainGrid = eclipseCase->mainGrid(); + + *isIntersectingOtherLgrs = false; + auto completions = eclipseCase->computeAndGetVirtualPerforationTransmissibilities(); + if (completions) + { + auto intCells = completions->multipleCompletionsPerEclipseCell(wellPath, timeStep); + + for (auto intCell : intCells) + { + const RigGridBase* grid = hostGrid(mainGrid, intCell.first); + if (grid != mainGrid) + { + *isIntersectingOtherLgrs = true; + continue; + } + + auto filteredCompletions = filterCompletionsOnType(intCell.second, completionTypes); + + if (filteredCompletions.empty()) continue; + + cells.push_back(RigCompletionDataGridCell(intCell.first, mainGrid)); + } + } + + return cells; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector cellsIntersectingCompletion(const std::map>& allCells, + caf::PdmObject* sourcePdmObject) +{ + std::vector cells; + for (const auto& intInfo : allCells) + { + for (const auto& completion : intInfo.second) + { + if (completion.sourcePdmObject() == sourcePdmObject) cells.push_back(intInfo.first); + } + } + return cells; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector>> + createOrderedIntersectionList(const std::vector& allWellPathCells, + const std::map>& completionCells) +{ + // All cell indices intersecting a completion and lookup into map + std::set complCellIndices; + std::map complCellLookup; + std::set cellsOnWellPath; + std::vector> cellsNotOnWellPath; + { + for (const auto& complCell : completionCells) + { + complCellIndices.insert(complCell.first.globalCellIndex()); + complCellLookup.insert({complCell.first.globalCellIndex(), complCell.first}); + + bool cellFoundOnWellPath = false; + for (const auto& wellPathCell : allWellPathCells) + { + if (complCell.first.globalCellIndex() == wellPathCell.globCellIndex) + { + cellsOnWellPath.insert(CellInfo(complCell.first.globalCellIndex(), wellPathCell.startMD, wellPathCell.endMD)); + cellFoundOnWellPath = true; + break; + } + } + + if (!cellFoundOnWellPath) + { + cellsNotOnWellPath.emplace_back( true, CellInfo(complCell.first.globalCellIndex()) ); + } + } + } + + std::set cellsTaken; + std::vector>> result; + + // Walk along well path + for (const auto& cellOnWellPath : cellsOnWellPath) + { + // Add cell on well path first + auto complDataGridCell = complCellLookup.at(cellOnWellPath.globCellIndex); + auto complDataList = completionCells.at(complDataGridCell); + result.emplace_back(complDataGridCell, complDataList); + + // Check intersected completions in current cell + RigCompletionData::CompletionType complTypes[] = { RigCompletionData::FRACTURE, RigCompletionData::FISHBONES, RigCompletionData::PERFORATION }; + + for (auto complType : complTypes) + { + const caf::PdmObject* completion = nullptr; + for (const auto& complData : complDataList) + { + if (complData.completionType() == complType) + { + completion = complData.sourcePdmObject(); + break; + } + } + + if (completion) + { + // Add all cells intersecting this completion + for (auto& cellNotOnWellPath : cellsNotOnWellPath) + { + if (!cellNotOnWellPath.first) continue; + + auto complDataList2 = completionCells.at(complCellLookup.at(cellNotOnWellPath.second.globCellIndex)); + auto itr = std::find_if(complDataList2.begin(), complDataList2.end(), + [&completion](const RigCompletionData& cd) { return cd.sourcePdmObject() == completion; }); + + if (itr != complDataList2.end()) + { + result.emplace_back( complCellLookup.at(cellNotOnWellPath.second.globCellIndex), complDataList2); + cellNotOnWellPath.first = false; + } + } + } + } + } + + return result; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +//std::map> +// RicExportLgrFeature::cellsIntersectingCompletions_PerCompletion_old(RimEclipseCase* eclipseCase, +// const RimWellPath* wellPath, +// size_t timeStep, +// const std::set& completionTypes, +// bool* isIntersectingOtherLgrs) +//{ +// std::map> completionToCells; +// +// *isIntersectingOtherLgrs = false; +// +// auto wellPathGeometry = wellPath->wellPathGeometry(); +// auto completions = eclipseCase->computeAndGetVirtualPerforationTransmissibilities(); +// if (wellPathGeometry && completions) +// { +// const auto& intCells = completions->multipleCompletionsPerEclipseCell(wellPath, timeStep); +// CompletionInfo lastCompletionInfo; +// +// auto wpIntCells = RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath(eclipseCase->eclipseCaseData(), +// wellPathGeometry->wellPathPoints(), +// wellPathGeometry->measureDepths()); +// +// auto wpComplCells = createOrderedIntersectionList(wpIntCells, intCells); +// +// // This loop assumes that cells are ordered downwards along well path +// for (auto intCell : wpComplCells) +// { +// if (!intCell.first.isMainGridCell()) +// { +// *isIntersectingOtherLgrs = true; +// continue; +// } +// +// auto filteredCompletions = filterCompletionsOnType(intCell.second, completionTypes); +// if (filteredCompletions.empty()) continue; +// +// auto completion = findCompletionByPriority(filteredCompletions); +// +// QString name = completionName(completion.sourcePdmObject()); +// CompletionInfo completionInfo(completion.completionType(), name, 0); +// +// if (!lastCompletionInfo.isValid()) lastCompletionInfo = completionInfo; +// +// if (completionInfo != lastCompletionInfo && completionToCells.count(completionInfo) > 0) +// { +// completionInfo.number++; +// } +// completionToCells[completionInfo].push_back(intCell.first); +// lastCompletionInfo = completionInfo; +// } +// } +// return completionToCells; +//} + + +template +void appendVector(std::vector& dest, const std::vector& append) +{ + dest.insert(dest.end(), append.begin(), append.end()); +} + +void appendIntersectedCells(std::map>& dest, + const std::map>& append) +{ + for (auto& intCell : append) + { + if (dest.count(intCell.first) == 0) + { + dest.insert(intCell); + } + else + { + appendVector(dest[intCell.first], intCell.second); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map> RicExportLgrFeature::cellsIntersectingCompletions_PerCompletion( + RimEclipseCase* eclipseCase, + const std::vector wellPaths, + size_t timeStep, + const std::set& completionTypes, + QStringList* wellsIntersectingOtherLgrs) +{ + const RigMainGrid* mainGrid = eclipseCase->mainGrid(); + + std::map> completionToCells; + + wellsIntersectingOtherLgrs->clear(); + + auto completions = eclipseCase->computeAndGetVirtualPerforationTransmissibilities(); + if (!completions) return completionToCells; + + for (const auto& wellPath : wellPaths) + { + bool isIntersectingOtherLgrs = false; + const auto& intCells = completions->multipleCompletionsPerEclipseCell(wellPath, timeStep); + + for (const auto& intCell : intCells) + { + const RigGridBase* grid = hostGrid(mainGrid, intCell.first); + if (grid != mainGrid) + { + isIntersectingOtherLgrs = true; + continue; + } + + for (const auto& completion : intCell.second) + { + auto complName = completionName(completion.sourcePdmObject()); + CompletionInfo ci(completion.completionType(), complName, completion.wellName()); + + auto& item = completionToCells[ci]; + item.push_back(RigCompletionDataGridCell(intCell.first, mainGrid)); + } + } + + if (isIntersectingOtherLgrs) wellsIntersectingOtherLgrs->push_back(wellPath->name()); + } + + return completionToCells; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExportLgrFeature::isCommandEnabled() +{ + std::vector completions = caf::selectedObjectsByTypeStrict(); + std::vector wellPaths = caf::selectedObjectsByTypeStrict(); + + return !completions.empty() || !wellPaths.empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrFeature::onActionTriggered(bool isChecked) +{ + std::vector wellPaths = selectedWellPaths(); + if(wellPaths.empty()) return; + + QString dialogTitle = "Export LGR for Completions"; + + RimEclipseCase* defaultEclipseCase = nullptr; + int defaultTimeStep = 0; + auto activeView = dynamic_cast(RiaApplication::instance()->activeGridView()); + if (activeView) + { + defaultEclipseCase = activeView->eclipseCase(); + defaultTimeStep = activeView->currentTimeStep(); + } + + auto dialogData = openDialog(dialogTitle, defaultEclipseCase, defaultTimeStep); + if (dialogData) + { + auto eclipseCase = dialogData->caseToApply(); + auto lgrCellCounts = dialogData->lgrCellCount(); + size_t timeStep = dialogData->timeStep(); + + QStringList wellsIntersectingOtherLgrs; + exportLgrsForWellPaths(dialogData->exportFolder(), + wellPaths, + eclipseCase, + timeStep, + lgrCellCounts, + dialogData->splitType(), + dialogData->completionTypes(), + &wellsIntersectingOtherLgrs); + + if (!wellsIntersectingOtherLgrs.empty()) + { + auto wellsList = wellsIntersectingOtherLgrs.join(", "); + QMessageBox::warning(nullptr, + "LGR cells intersected", + "No export for some wells due to existing intersecting LGR(s). Affected wells: " + wellsList); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Export LGR for completions"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicExportLgrFeature::selectedWellPaths() +{ + std::vector selectedCompletions = caf::selectedObjectsByTypeStrict(); + std::vector wellPaths = caf::selectedObjectsByTypeStrict(); + + for (auto completion : selectedCompletions) + { + RimWellPath* parentWellPath; + completion->firstAncestorOrThisOfType(parentWellPath); + + if (parentWellPath) wellPaths.push_back(parentWellPath); + } + return wellPaths; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair mainGridCellBoundingBoxFromLgr(const RigGridBase* lgr) +{ + auto mainGrid = lgr->mainGrid(); + + // Find min and max IJK + auto iRange = RicExportLgrFeature::initRange(); + auto jRange = RicExportLgrFeature::initRange(); + auto kRange = RicExportLgrFeature::initRange(); + + for (size_t c = 0; c < lgr->cellCount(); c++) + { + const auto& cell = lgr->cell(c); + size_t mainGridCellIndex = cell.mainGridCellIndex(); + + size_t i, j, k; + mainGrid->ijkFromCellIndex(mainGridCellIndex, &i, &j, &k); + + iRange.first = std::min(i, iRange.first); + iRange.second = std::max(i, iRange.second); + jRange.first = std::min(j, jRange.first); + jRange.second = std::max(j, jRange.second); + kRange.first = std::min(k, kRange.first); + kRange.second = std::max(k, kRange.second); + } + + caf::VecIjk mainGridStartCell(iRange.first, jRange.first, kRange.first); + caf::VecIjk mainGridEndCell(iRange.second, jRange.second, kRange.second); + return std::make_pair(mainGridStartCell, mainGridEndCell); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map> RicExportLgrFeature::createLgrInfoListForTemporaryLgrs(const RigMainGrid* mainGrid) +{ + std::map> lgrInfosPerWell; + + for (size_t i = 0; i < mainGrid->gridCount(); i++) + { + const auto grid = mainGrid->gridByIndex(i); + if (!grid->isTempGrid()) continue; + + caf::VecIjk lgrSizes(grid->cellCountI(), grid->cellCountJ(), grid->cellCountK()); + std::pair mainGridBoundingBox = mainGridCellBoundingBoxFromLgr(grid); + + QString wellName = QString::fromStdString(grid->associatedWellPathName()); + auto& item = lgrInfosPerWell[wellName]; + + item.emplace_back(LgrInfo(grid->gridId(), + QString::fromStdString(grid->gridName()), + QString::fromStdString(grid->associatedWellPathName()), + lgrSizes, + mainGridBoundingBox.first, + mainGridBoundingBox.second)); + } + + return lgrInfosPerWell; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RicExportLgrFeature::firstAvailableLgrId(const RigMainGrid* mainGrid) +{ + int gridCount = (int)mainGrid->gridCount(); + int lastUsedId = 0; + for (int i = 0; i < gridCount; i++) + { + lastUsedId = std::max(lastUsedId, mainGrid->gridByIndex(i)->gridId()); + } + return lastUsedId + 1; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigGridBase* RicExportLgrFeature::hostGrid(const RigMainGrid* mainGrid, size_t reservoirCellIndex) +{ + size_t dummy = 0; + + return mainGrid->gridAndGridLocalIdxFromGlobalCellIdx(reservoirCellIndex, &dummy); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +LgrNameFactory::LgrNameFactory() +{ + m_counters = { + {RigCompletionData::FRACTURE, {"FRAC", 1}}, + {RigCompletionData::FISHBONES, {"FB", 1}}, + {RigCompletionData::PERFORATION, {"PERF", 1}} + }; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString LgrNameFactory::newName(RigCompletionData::CompletionType completionType) +{ + switch (completionType) + { + case RigCompletionData::FRACTURE: + case RigCompletionData::FISHBONES: + case RigCompletionData::PERFORATION: + { + auto& counter = m_counters[completionType]; + QString name = counter.first + "_" + QString::number(counter.second); + counter.second++; + return name; + } + default: + return "Unknown type"; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString LgrNameFactory::newName(const QString& baseName, int number) +{ + QString lgrName; + if(baseName.isEmpty()) lgrName = "LGR"; + lgrName += baseName + "_" + QString::number(number); + return lgrName.replace(" ", "_"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void LgrNameFactory::resetNumbering() +{ + for (auto& counter : m_counters) + { + counter.second.second = 1; + } +} diff --git a/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.h b/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.h new file mode 100644 index 0000000000..436db3034f --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicExportLgrFeature.h @@ -0,0 +1,233 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RigCompletionData.h" +#include "RigCompletionDataGridCell.h" + +#include "RicExportLgrUi.h" + +#include "cafCmdFeature.h" +#include "cafVecIjk.h" + +#include +#include + +class LgrNameFactory; +class RigMainGrid; +class RigGridBase; +class RimEclipseCase; +class RimSimWellInView; +class RimWellPath; +class QFile; +class QTextStream; +class IjkBoundingBox; + +//================================================================================================== +/// Candidate for refactoring +//================================================================================================== + + +//================================================================================================== +/// +//================================================================================================== +class LgrInfo +{ +public: + LgrInfo(int id, + const QString& name, + const QString& associatedWellPathName, + const caf::VecIjk& sizes, + const caf::VecIjk& mainGridStartCell, + const caf::VecIjk& mainGridEndCell) + : id(id), name(name), associatedWellPathName(associatedWellPathName), + sizes(sizes), mainGridStartCell(mainGridStartCell), mainGridEndCell(mainGridEndCell) + { + } + + caf::VecIjk sizesPerMainGridCell() const + { + return caf::VecIjk(sizes.i() / (mainGridEndCell.i() - mainGridStartCell.i() + 1), + sizes.j() / (mainGridEndCell.j() - mainGridStartCell.j() + 1), + sizes.k() / (mainGridEndCell.k() - mainGridStartCell.k() + 1)); + } + + size_t cellCount() const + { + return sizes.i() * sizes.j() * sizes.k(); + } + + int id; + QString name; + QString associatedWellPathName; + caf::VecIjk sizes; + + caf::VecIjk mainGridStartCell; + caf::VecIjk mainGridEndCell; +}; + +//================================================================================================== +/// +//================================================================================================== +class CompletionInfo +{ +public: + CompletionInfo() + : type(RigCompletionData::CT_UNDEFINED), name(""), wellPathName("") {} + CompletionInfo(RigCompletionData::CompletionType type, const QString& name, const QString& wellPathName) + : type(type), name(name), wellPathName(wellPathName) {} + + + CompletionInfo(RigCompletionData::CompletionType type, const QString& name) + : type(type) + , name(name) + , wellPathName(wellPathName) + { + } + RigCompletionData::CompletionType type; + QString name; + QString wellPathName; + + bool isValid() const { return type != RigCompletionData::CT_UNDEFINED && !name.isEmpty() && !wellPathName.isEmpty(); } + + int priority() const + { + return type == RigCompletionData::FRACTURE ? 1 : + type == RigCompletionData::FISHBONES ? 2 : + type == RigCompletionData::PERFORATION ? 3 : 4; + } + + // Sort by priority, then name, then number + bool operator<(const CompletionInfo& other) const + { + if (priority() == other.priority()) + { + if (wellPathName == other.wellPathName) return name < other.name; + return wellPathName < other.wellPathName; + } + return priority() < other.priority(); + } + + bool operator==(const CompletionInfo& other) const + { + return type == other.type && name == other.name && wellPathName == other.wellPathName; + } + + bool operator!=(const CompletionInfo& other) const + { + return !operator==(other); + } +}; + +//================================================================================================== +/// +//================================================================================================== +class RicExportLgrFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + + using Range = std::pair; + static Range initRange() { return std::make_pair(std::numeric_limits::max(), 0); } + + static RicExportLgrUi* openDialog(const QString& dialogTitle, + RimEclipseCase* defaultCase = nullptr, + int defaultTimeStep = 0, + bool hideExportFolderField = false); + static bool openFileForExport(const QString& folderName, const QString& fileName, QFile* exportFile); + static void exportLgrsForWellPaths(const QString& exportFolder, + std::vector wellPaths, + RimEclipseCase* eclipseCase, + size_t timeStep, + caf::VecIjk lgrCellCounts, + Lgr::SplitType splitType, + const std::set& completionTypes, + QStringList* wellsIntersectingOtherLgrs); + + static void exportLgrs(const QString& exportFolder, + const QString& wellName, + const std::vector& lgrInfos); + + static std::vector buildLgrsForWellPaths(std::vector wellPaths, + RimEclipseCase* eclipseCase, + size_t timeStep, + caf::VecIjk lgrCellCounts, + Lgr::SplitType splitType, + const std::set& completionTypes, + QStringList* wellsIntersectingOtherLgrs); + + static std::vector selectedWellPaths(); + + static std::map> createLgrInfoListForTemporaryLgrs(const RigMainGrid* mainGrid); + +protected: + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + +private: + static void writeLgrs(QTextStream& stream, const std::vector& lgrInfos); + + static std::vector buildLgrsPerMainCell(int firstLgrId, + RimEclipseCase* eclipseCase, + RimWellPath* wellPath, + const std::vector& intersectingCells, + const caf::VecIjk& lgrSizes, + LgrNameFactory& lgrNameFactory); + static std::vector + buildLgrsPerCompletion(int firstLgrId, + RimEclipseCase* eclipseCase, + const std::map>& completionInfo, + const caf::VecIjk& lgrSizesPerMainGridCell, + LgrNameFactory& lgrNameFactory); + static LgrInfo buildLgr(int lgrId, + const QString& lgrName, + RimEclipseCase* eclipseCase, + const QString& wellPathName, + const std::vector& intersectingCells, + const caf::VecIjk& lgrSizesPerMainGridCell); + + static LgrInfo buildLgr(int lgrId, + const QString& lgrName, + RimEclipseCase* eclipseCase, + const QString& wellPathName, + const IjkBoundingBox& boundingBox, + const caf::VecIjk& lgrSizesPerMainGridCell); + + static std::vector cellsIntersectingCompletions(RimEclipseCase* eclipseCase, + const RimWellPath* wellPath, + size_t timeStep, + const std::set& completionTypes, + bool* isIntersectingOtherLgrs); + //static std::map> + // cellsIntersectingCompletions_PerCompletion_old(RimEclipseCase* eclipseCase, + // const RimWellPath* wellPath, + // size_t timeStep, + // const std::set& completionTypes, + // bool* isIntersectingOtherLgrs); + + static std::map> + cellsIntersectingCompletions_PerCompletion(RimEclipseCase* eclipseCase, + const std::vector wellPaths, + size_t timeStep, + const std::set& completionTypes, + QStringList* wellsIntersectingOtherLgrs); + + static int firstAvailableLgrId(const RigMainGrid* mainGrid); + static const RigGridBase* hostGrid(const RigMainGrid* mainGrid, size_t reservoirCellIndex); +}; diff --git a/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.cpp b/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.cpp new file mode 100644 index 0000000000..35b8ad4fef --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.cpp @@ -0,0 +1,264 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicExportLgrUi.h" + +#include "RicCellRangeUi.h" + +#include "RimEclipseCase.h" +#include "RimTools.h" + +#include "cafPdmUiFilePathEditor.h" +#include "cafPdmUiTextEditor.h" +#include "cafVecIjk.h" + + +CAF_PDM_SOURCE_INIT(RicExportLgrUi, "RicExportLgrUi"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +namespace caf +{ + template<> + void Lgr::SplitTypeEnum::setUp() + { + addItem(Lgr::LGR_PER_CELL, "LGR_PER_CELL", "LGR Per Cell"); + addItem(Lgr::LGR_PER_COMPLETION, "LGR_PER_COMPLETION", "LGR Per Completion"); + addItem(Lgr::LGR_PER_WELL, "LGR_PER_WELL", "LGR Per Well"); + + setDefault(Lgr::LGR_PER_COMPLETION); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicExportLgrUi::RicExportLgrUi() +{ + CAF_PDM_InitObject("Export CARFIN", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_exportFolder, "ExportFolder", "Export Folder", "", "", ""); + m_exportFolder.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + + CAF_PDM_InitFieldNoDefault(&m_caseToApply, "CaseToApply", "Source Case", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_timeStep, "TimeStepIndex", "Time Step", "", "", ""); + + CAF_PDM_InitField(&m_includePerforations, "IncludePerforations", true, "Perforations", "", "", ""); + CAF_PDM_InitField(&m_includeFractures, "IncludeFractures", true, "Fractures", "", "", ""); + CAF_PDM_InitField(&m_includeFishbones, "IncludeFishbones", true, "Fishbones", "", "", ""); + + QString ijkLabel = "Cell Count I, J, K"; + CAF_PDM_InitField(&m_cellCountI, "CellCountI", 2, ijkLabel, "", "", ""); + CAF_PDM_InitField(&m_cellCountJ, "CellCountJ", 2, "", "", "", ""); + CAF_PDM_InitField(&m_cellCountK, "CellCountK", 2, "", "", "", ""); + + m_cellCountJ.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_cellCountK.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + CAF_PDM_InitField(&m_splitType, "SplitType", Lgr::SplitTypeEnum(), "Split Type", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrUi::setCase(RimEclipseCase* rimCase) +{ + bool isDifferent = (rimCase != m_caseToApply); + + if (isDifferent) + { + m_caseToApply = rimCase; + setDefaultValuesFromCase(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrUi::setTimeStep(int timeStep) +{ + bool isDifferent = timeStep != m_timeStep; + + if (isDifferent) + { + m_timeStep = timeStep; + setDefaultValuesFromCase(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::VecIjk RicExportLgrUi::lgrCellCount() const +{ + return caf::VecIjk (m_cellCountI, m_cellCountJ, m_cellCountK); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicExportLgrUi::exportFolder() const +{ + return m_exportFolder(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseCase* RicExportLgrUi::caseToApply() const +{ + return m_caseToApply(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RicExportLgrUi::timeStep() const +{ + return m_timeStep; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RicExportLgrUi::completionTypes() const +{ + std::set cts; + if (m_includePerforations()) cts.insert(RigCompletionData::PERFORATION); + if (m_includeFractures()) cts.insert(RigCompletionData::FRACTURE); + if (m_includeFishbones()) cts.insert(RigCompletionData::FISHBONES); + return cts; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Lgr::SplitType RicExportLgrUi::splitType() const +{ + return m_splitType(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrUi::hideExportFolderField(bool hide) +{ + m_exportFolder.uiCapability()->setUiHidden(hide); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrUi::setExportFolder(const QString& folder) +{ + m_exportFolder = folder; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrUi::setDefaultValuesFromCase() +{ + if (m_caseToApply) + { + QString caseFolder = m_caseToApply->locationOnDisc(); + m_exportFolder = caseFolder; + } + + m_cellCountI = 2; + m_cellCountJ = 2; + m_cellCountK = 2; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RicExportLgrUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList options; + + if (fieldNeedingOptions == &m_caseToApply) + { + RimTools::caseOptionItems(&options); + } + else if (fieldNeedingOptions == &m_timeStep) + { + QStringList timeStepNames; + + if (m_caseToApply) + { + timeStepNames = m_caseToApply->timeStepStrings(); + } + for (int i = 0; i < timeStepNames.size(); i++) + { + options.push_back(caf::PdmOptionItemInfo(timeStepNames[i], i)); + } + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrUi::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &m_caseToApply) + { + setDefaultValuesFromCase(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrUi::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiOrdering::LayoutOptions layout(true, 6, 1); + uiOrdering.add(&m_caseToApply, layout); + uiOrdering.add(&m_timeStep, layout); + uiOrdering.add(&m_exportFolder, layout); + uiOrdering.add(&m_includeFractures, layout); + uiOrdering.add(&m_includeFishbones, layout); + uiOrdering.add(&m_includePerforations, layout); + uiOrdering.add(&m_splitType, {true, 6, 1}); + + caf::PdmUiGroup* gridRefinement = uiOrdering.addNewGroup("Grid Refinement"); + gridRefinement->add(&m_cellCountI, { true, 2, 1}); + gridRefinement->add(&m_cellCountJ, { false }); + gridRefinement->add(&m_cellCountK, { false }); + +// uiOrdering.add(&m_wellPathsInfo); + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportLgrUi::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_exportFolder) + { + caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast(attribute); + if (myAttr) + { + myAttr->m_selectDirectory = true; + } + } +} diff --git a/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.h b/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.h new file mode 100644 index 0000000000..df0eb97e81 --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicExportLgrUi.h @@ -0,0 +1,87 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RigCompletionData.h" + +#include "RicLgrSplitType.h" + +#include "cafPdmObject.h" +#include "cafPdmChildField.h" +#include "cafPdmField.h" +#include "cafPdmPtrField.h" +#include "cafPdmProxyValueField.h" + +#include + +#include + +class RimEclipseCase; +class RicCellRangeUi; + +namespace caf { + class VecIjk; +} + +//================================================================================================== +/// +//================================================================================================== +class RicExportLgrUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicExportLgrUi(); + + void setCase(RimEclipseCase* rimCase); + void setTimeStep(int timeStep); + + caf::VecIjk lgrCellCount() const; + QString exportFolder() const; + RimEclipseCase* caseToApply() const; + int timeStep() const; + std::set completionTypes() const; + Lgr::SplitType splitType() const; + + void hideExportFolderField(bool hide); + void setExportFolder(const QString& folder); + +private: + void setDefaultValuesFromCase(); + + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + +private: + caf::PdmField m_exportFolder; + caf::PdmPtrField m_caseToApply; + caf::PdmField m_timeStep; + caf::PdmField m_includePerforations; + caf::PdmField m_includeFractures; + caf::PdmField m_includeFishbones; + + + caf::PdmField m_cellCountI; + caf::PdmField m_cellCountJ; + caf::PdmField m_cellCountK; + + caf::PdmField m_splitType; +}; diff --git a/ApplicationCode/Commands/ExportCommands/RicExportMultipleSnapshotsFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicExportMultipleSnapshotsFeature.cpp index b5a21c50eb..d3ae5ed35b 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportMultipleSnapshotsFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicExportMultipleSnapshotsFeature.cpp @@ -253,26 +253,26 @@ void RicExportMultipleSnapshotsFeature::exportViewVariationsToFolder(RimGridView bool rangeFilterInitState = rimView->rangeFilterCollection()->isActive(); rimView->rangeFilterCollection()->isActive = true; - for (int i = msd->startSliceIndex(); i <= msd->endSliceIndex(); i++) + for (int sliceIndex = msd->startSliceIndex(); sliceIndex <= msd->endSliceIndex(); sliceIndex++) { - QString rangeFilterString = msd->sliceDirection().text() + "-" + QString::number(i); + QString rangeFilterString = msd->sliceDirection().text() + "-" + QString::number(sliceIndex); QString fileName = viewCaseResultString + "_" + timeStepString + "_" + rangeFilterString; rangeFilter->setDefaultValues(); if (msd->sliceDirection == RimMultiSnapshotDefinition::RANGEFILTER_I) { rangeFilter->cellCountI = 1; - rangeFilter->startIndexI = i; + rangeFilter->startIndexI = sliceIndex; } else if (msd->sliceDirection == RimMultiSnapshotDefinition::RANGEFILTER_J) { rangeFilter->cellCountJ = 1; - rangeFilter->startIndexJ = i; + rangeFilter->startIndexJ = sliceIndex; } else if (msd->sliceDirection == RimMultiSnapshotDefinition::RANGEFILTER_K) { rangeFilter->cellCountK = 1; - rangeFilter->startIndexK = i; + rangeFilter->startIndexK = sliceIndex; } rimView->rangeFilterCollection()->updateDisplayModeNotifyManagedViews(rangeFilter); diff --git a/ApplicationCode/Commands/ExportCommands/RicExportMultipleSnapshotsFeature.h b/ApplicationCode/Commands/ExportCommands/RicExportMultipleSnapshotsFeature.h index d241bd348c..f05b1dc7bd 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportMultipleSnapshotsFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicExportMultipleSnapshotsFeature.h @@ -33,9 +33,9 @@ class RicExportMultipleSnapshotsFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; public: static void exportMultipleSnapshots(const QString& folder, RimProject* project); diff --git a/ApplicationCode/Commands/ExportCommands/RicExportSelectedWellPathsFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicExportSelectedWellPathsFeature.cpp new file mode 100644 index 0000000000..37086e16a8 --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicExportSelectedWellPathsFeature.cpp @@ -0,0 +1,254 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicExportSelectedWellPathsFeature.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" + +#include "RicExportWellPathsUi.h" + +#include "RifEclipseDataTableFormatter.h" + +#include "RigWellPath.h" + +#include "RimWellPath.h" +#include "RimModeledWellPath.h" +#include "RimWellPathGeometryDef.h" +#include "RimProject.h" +#include "RimDialogData.h" + +#include "cafSelectionManagerTools.h" +#include "cafPdmUiPropertyViewDialog.h" + +#include +#include + +#include + +#include + + +CAF_CMD_SOURCE_INIT(RicExportSelectedWellPathsFeature, "RicExportSelectedWellPathsFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportSelectedWellPathsFeature::exportWellPath(const RimWellPath* wellPath, + double mdStepSize, + const QString& folder, + bool writeProjectInfo) +{ + auto fileName = wellPath->name() + ".dev"; + auto filePtr = openFileForExport(folder, fileName); + auto stream = createOutputFileStream(*filePtr); + + writeWellPathGeometryToStream(*stream, wellPath, wellPath->name(), mdStepSize, writeProjectInfo); + filePtr->close(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportSelectedWellPathsFeature::writeWellPathGeometryToStream(QTextStream& stream, + const RimWellPath* wellPath, + const QString& exportName, + double mdStepSize, + bool writeProjectInfo) +{ + auto wellPathGeom = wellPath->wellPathGeometry(); + if (!wellPathGeom) return; + + double currMd = wellPathGeom->measureDepths().front() - mdStepSize; + double endMd = wellPathGeom->measureDepths().back(); + + RifEclipseDataTableFormatter formatter(stream); + formatter.setCommentPrefix("#"); + formatter.setTableRowPrependText(" "); + + if (writeProjectInfo) + { + formatter.comment("Project: " + RiaApplication::instance()->project()->fileName); + stream << endl; + } + + bool useMdRkb = false; + double rkb = 0.0; + { + const RimModeledWellPath* modeledWellPath = dynamic_cast(wellPath); + if (modeledWellPath) + { + useMdRkb = true; + rkb = modeledWellPath->geometryDefinition()->mdrkbAtFirstTarget(); + } + } + + stream << "WELLNAME: '" << caf::Utils::makeValidFileBasename(exportName) << "'" << endl; + + auto numberFormat = RifEclipseOutputTableDoubleFormatting(RIF_FLOAT, 2); + formatter.header( + { + {"X", numberFormat, RIGHT}, + {"Y", numberFormat, RIGHT}, + {"TVDMSL", numberFormat, RIGHT}, + {useMdRkb ? "MDRKB" : "MDMSL", numberFormat, RIGHT} + }); + + while (currMd < endMd) + { + currMd += mdStepSize; + if (currMd > endMd) currMd = endMd; + + auto pt = wellPathGeom->interpolatedPointAlongWellPath(currMd); + double tvd = -pt.z(); + + // Write to file + formatter.add(pt.x()); + formatter.add(pt.y()); + formatter.add(tvd); + formatter.add(currMd + rkb); + formatter.rowCompleted(""); + } + formatter.tableCompleted("", false); + + stream << -999 << endl << endl; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QFilePtr RicExportSelectedWellPathsFeature::openFileForExport(const QString& folderName, const QString& fileName) +{ + QDir exportFolder = QDir(folderName); + if (!exportFolder.exists()) + { + bool createdPath = exportFolder.mkpath("."); + if (createdPath) + RiaLogging::info("Created export folder " + folderName); + } + + QString filePath = exportFolder.filePath(fileName); + QFilePtr exportFile(new QFile(filePath)); + if (!exportFile->open(QIODevice::WriteOnly | QIODevice::Text)) + { + auto errorMessage = QString("Export Well Path: Could not open the file: %1").arg(filePath); + RiaLogging::error(errorMessage); + } + return exportFile; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QTextStreamPtr RicExportSelectedWellPathsFeature::createOutputFileStream(QFile& file) +{ + auto stream = QTextStreamPtr(new QTextStream(&file)); + stream->setRealNumberNotation(QTextStream::FixedNotation); + stream->setRealNumberPrecision(2); + return stream; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportSelectedWellPathsFeature::handleAction(const std::vector& wellPaths) +{ + if (!wellPaths.empty()) + { + auto dialogData = openDialog(); + if (dialogData) + { + auto folder = dialogData->exportFolder(); + auto mdStepSize = dialogData->mdStepSize(); + if (folder.isEmpty()) + { + return; + } + + for (auto wellPath : wellPaths) + { + exportWellPath(wellPath, mdStepSize, folder); + } + + } + + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExportSelectedWellPathsFeature::isCommandEnabled() +{ + std::vector wellPaths = caf::selectedObjectsByTypeStrict(); + + return !wellPaths.empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportSelectedWellPathsFeature::onActionTriggered(bool isChecked) +{ + std::vector wellPaths = caf::selectedObjectsByTypeStrict(); + + handleAction(wellPaths); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportSelectedWellPathsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Export Selected Well Paths"); + actionToSetup->setIcon(QIcon(":/WellLogCurve16x16.png")); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicExportWellPathsUi* RicExportSelectedWellPathsFeature::openDialog() +{ + RiaApplication* app = RiaApplication::instance(); + RimProject* proj = app->project(); + + QString startPath = app->lastUsedDialogDirectoryWithFallbackToProjectFolder("WELL_PATH_EXPORT_DIR"); + if (startPath.isEmpty()) + { + QFileInfo fi(proj->fileName()); + startPath = fi.absolutePath(); + } + + RicExportWellPathsUi* featureUi = app->project()->dialogData()->wellPathsExportData(); + if (featureUi->exportFolder().isEmpty()) + { + featureUi->setExportFolder(startPath); + } + + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, featureUi, "Export Well Paths", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + propertyDialog.resize(QSize(600, 60)); + + if (propertyDialog.exec() == QDialog::Accepted && !featureUi->exportFolder().isEmpty()) + { + auto dialogData = app->project()->dialogData()->wellPathsExportData(); + app->setLastUsedDialogDirectory("WELL_PATH_EXPORT_DIR", dialogData->exportFolder()); + return dialogData; + } + return nullptr; +} diff --git a/ApplicationCode/Commands/ExportCommands/RicExportSelectedWellPathsFeature.h b/ApplicationCode/Commands/ExportCommands/RicExportSelectedWellPathsFeature.h new file mode 100644 index 0000000000..702e076fba --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicExportSelectedWellPathsFeature.h @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +#include + +class RigWellPath; +class RimWellPath; +class RicExportWellPathsUi; +class QTextStream; + +//================================================================================================== +/// +//================================================================================================== +typedef std::shared_ptr QFilePtr; +typedef std::shared_ptr QTextStreamPtr; + +//================================================================================================== +/// +//================================================================================================== +class RicExportSelectedWellPathsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + + static void handleAction(const std::vector& wellPaths); + static void exportWellPath(const RimWellPath* wellPath, + double mdStepSize, + const QString& folder, + bool writeProjectInfo = true); + + static RicExportWellPathsUi* openDialog(); + static QFilePtr openFileForExport(const QString& folderName, const QString& fileName); + static QTextStreamPtr createOutputFileStream(QFile& file); + static void writeWellPathGeometryToStream(QTextStream& stream, + const RimWellPath* wellPath, + const QString& exportName, + double mdStepSize, + bool writeProjectInfo = true); + +private: + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; +}; diff --git a/ApplicationCode/Commands/ExportCommands/RicExportToLasFileFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicExportToLasFileFeature.cpp index 98e563fd44..89db296f87 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportToLasFileFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicExportToLasFileFeature.cpp @@ -63,10 +63,7 @@ void RicExportToLasFileFeature::onActionTriggered(bool isChecked) std::vector curves = RicWellLogPlotCurveFeatureImpl::selectedWellLogCurves(); if (curves.size() == 0) return; - RiaApplication* app = RiaApplication::instance(); - - QString projectFolder = app->currentProjectPath(); - QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallback("WELL_LOGS_DIR", projectFolder); + QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallbackToProjectFolder("WELL_LOGS_DIR"); RigLasFileExporter lasExporter(curves); RicExportToLasFileResampleUi featureUi; @@ -81,7 +78,7 @@ void RicExportToLasFileFeature::onActionTriggered(bool isChecked) caf::PdmUiPropertyViewDialog propertyDialog(nullptr, &featureUi, "Export Curve Data to LAS file(s)", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel); RicExportFeatureImpl::configureForExport(&propertyDialog); - propertyDialog.resize(QSize(400, 200)); + propertyDialog.resize(QSize(400, 330)); if (propertyDialog.exec() == QDialog::Accepted && !featureUi.exportFolder().isEmpty()) diff --git a/ApplicationCode/Commands/ExportCommands/RicExportToLasFileFeature.h b/ApplicationCode/Commands/ExportCommands/RicExportToLasFileFeature.h index ebb1362d00..aa28e20480 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportToLasFileFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicExportToLasFileFeature.h @@ -34,8 +34,8 @@ class RicExportToLasFileFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ExportCommands/RicExportToLasFileResampleUi.h b/ApplicationCode/Commands/ExportCommands/RicExportToLasFileResampleUi.h index d9b264a93b..bce367bd39 100644 --- a/ApplicationCode/Commands/ExportCommands/RicExportToLasFileResampleUi.h +++ b/ApplicationCode/Commands/ExportCommands/RicExportToLasFileResampleUi.h @@ -46,7 +46,7 @@ class RicExportToLasFileResampleUi : public caf::PdmObject public: RicExportToLasFileResampleUi(void); - ~RicExportToLasFileResampleUi(); + ~RicExportToLasFileResampleUi() override; caf::PdmField exportFolder; @@ -58,11 +58,11 @@ class RicExportToLasFileResampleUi : public caf::PdmObject void tvdrkbDiffForWellPaths(std::vector* rkbDiffs); void setRkbDiffs(const std::vector& wellNames, const std::vector& rkbDiffs); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: void updateFieldVisibility(); diff --git a/ApplicationCode/Commands/ExportCommands/RicExportVisibleWellPathsFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicExportVisibleWellPathsFeature.cpp new file mode 100644 index 0000000000..8262718340 --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicExportVisibleWellPathsFeature.cpp @@ -0,0 +1,107 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicExportVisibleWellPathsFeature.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" + +#include "RicExportSelectedWellPathsFeature.h" +#include "CompletionExportCommands/RicExportCompletionsForVisibleWellPathsFeature.h" + +#include "RigWellPath.h" + +#include "RimWellPath.h" +#include "RimProject.h" +#include "RimSummaryCaseMainCollection.h" + +#include "RiuPlotMainWindowTools.h" + +#include "cafSelectionManagerTools.h" + +#include +#include +#include +#include + +#include + + +CAF_CMD_SOURCE_INIT(RicExportVisibleWellPathsFeature, "RicExportVisibleWellPathsFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportVisibleWellPathsFeature::exportWellPath(const RimWellPath* wellPath, double mdStepSize, const QString& folder) +{ + auto geom = wellPath->wellPathGeometry(); + double currMd = geom->measureDepths().front() - mdStepSize; + double endMd = geom->measureDepths().back(); + + auto fileName = wellPath->name() + ".dev"; + auto filePtr = RicExportSelectedWellPathsFeature::openFileForExport(folder, fileName); + QTextStream stream(filePtr.get()); + stream.setRealNumberNotation(QTextStream::FixedNotation); + + stream << "WELLNAME: " << wellPath->name() << endl; + + while (currMd < endMd) + { + currMd += mdStepSize; + if (currMd > endMd) currMd = endMd; + + auto pt = geom->interpolatedPointAlongWellPath(currMd); + double tvd = -pt.z(); + + // Write to file + stream << pt.x() << " " << pt.y() << " " << tvd << " " << currMd << endl; + } + + filePtr->close(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicExportVisibleWellPathsFeature::isCommandEnabled() +{ + std::vector selectedWellPaths = caf::selectedObjectsByTypeStrict(); + std::vector visibleWellPaths = RicExportCompletionsForVisibleWellPathsFeature::visibleWellPaths(); + + return !selectedWellPaths.empty() && !visibleWellPaths.empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportVisibleWellPathsFeature::onActionTriggered(bool isChecked) +{ + std::vector wellPaths = RicExportCompletionsForVisibleWellPathsFeature::visibleWellPaths(); + + RicExportSelectedWellPathsFeature::handleAction(wellPaths); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportVisibleWellPathsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Export Visible Well Paths"); + actionToSetup->setIcon(QIcon(":/WellLogCurve16x16.png")); +} diff --git a/ApplicationCode/Commands/ExportCommands/RicExportVisibleWellPathsFeature.h b/ApplicationCode/Commands/ExportCommands/RicExportVisibleWellPathsFeature.h new file mode 100644 index 0000000000..f0bf83aa92 --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicExportVisibleWellPathsFeature.h @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + + +#include "cafCmdFeature.h" + +#include + +#include + +class RimWellPath; + +//================================================================================================== +/// +//================================================================================================== +typedef std::shared_ptr QFilePtr; + +//================================================================================================== +/// +//================================================================================================== +class RicExportVisibleWellPathsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + + void exportWellPath(const RimWellPath* wellPath, double mdStepSize, const QString& folder); + +private: + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; +}; diff --git a/ApplicationCode/Commands/ExportCommands/RicExportWellPathsUi.cpp b/ApplicationCode/Commands/ExportCommands/RicExportWellPathsUi.cpp new file mode 100644 index 0000000000..c4d7baf293 --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicExportWellPathsUi.cpp @@ -0,0 +1,85 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicExportWellPathsUi.h" + +#include "RiaApplication.h" +#include "RiaOptionItemFactory.h" + +#include "RimCase.h" +#include "RimGridView.h" +#include "RimProject.h" + +#include "cafPdmUiFilePathEditor.h" +#include "cafPdmUiOrdering.h" + +CAF_PDM_SOURCE_INIT(RicExportWellPathsUi, "RicExportWellPathsUi"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicExportWellPathsUi::RicExportWellPathsUi() +{ + CAF_PDM_InitObject("Resample LAS curves for export", "", "", ""); + + CAF_PDM_InitField(&m_exportFolder, "ExportFolder", QString(), "Export Folder", "", "", ""); + m_exportFolder.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); + + CAF_PDM_InitField(&m_mdStepSize, "MdStepSize", 5.0, "MD Step Size", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportWellPathsUi::setExportFolder(const QString& exportFolder) +{ + m_exportFolder = exportFolder; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicExportWellPathsUi::exportFolder() const +{ + return m_exportFolder; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicExportWellPathsUi::mdStepSize() const +{ + return m_mdStepSize; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicExportWellPathsUi::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_exportFolder) + { + caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast(attribute); + if (myAttr) + { + myAttr->m_selectDirectory = true; + } + } +} diff --git a/ApplicationCode/Commands/ExportCommands/RicExportWellPathsUi.h b/ApplicationCode/Commands/ExportCommands/RicExportWellPathsUi.h new file mode 100644 index 0000000000..0a3759a65d --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicExportWellPathsUi.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +class RimGridView; + +//================================================================================================== +/// +//================================================================================================== +class RicExportWellPathsUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicExportWellPathsUi(); + + void setExportFolder(const QString& exportFolder); + + QString exportFolder() const; + double mdStepSize() const; + +private: + void defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; + +private: + caf::PdmField m_exportFolder; + caf::PdmField m_mdStepSize; +}; diff --git a/ApplicationCode/Commands/ExportCommands/RicLgrSplitType.h b/ApplicationCode/Commands/ExportCommands/RicLgrSplitType.h new file mode 100644 index 0000000000..29912d40de --- /dev/null +++ b/ApplicationCode/Commands/ExportCommands/RicLgrSplitType.h @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +//================================================================================================== +/// +//================================================================================================== +namespace Lgr +{ + enum SplitType + { + LGR_PER_CELL, + LGR_PER_COMPLETION, + LGR_PER_WELL + }; + + typedef caf::AppEnum SplitTypeEnum; +} + diff --git a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputPropertyFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputPropertyFeature.cpp index a2db7490cd..5780514643 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputPropertyFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputPropertyFeature.cpp @@ -22,8 +22,7 @@ #include "RiaApplication.h" #include "RicExportFeatureImpl.h" - -#include "RifEclipseInputFileTools.h" +#include "RicEclipseCellResultToFileImpl.h" #include "RimEclipseInputCase.h" #include "RimEclipseInputProperty.h" @@ -106,7 +105,14 @@ void RicSaveEclipseInputPropertyFeature::onActionTriggered(bool isChecked) if (propertyDialog.exec() == QDialog::Accepted) { - bool isOk = RifEclipseInputFileTools::writePropertyToTextFile(exportSettings.fileName, inputReservoir->eclipseCaseData(), 0, inputProperty->resultName, exportSettings.eclipseKeyword); + const double undefinedValue = 0.0; + + bool isOk = RicEclipseCellResultToFileImpl::writePropertyToTextFile(exportSettings.fileName, + inputReservoir->eclipseCaseData(), + 0, + inputProperty->resultName, + exportSettings.eclipseKeyword, + undefinedValue); if (isOk) { inputProperty->fileName = exportSettings.fileName; @@ -134,7 +140,7 @@ RimEclipseInputProperty* RicSaveEclipseInputPropertyFeature::selectedInputProper std::vector selection; caf::SelectionManager::instance()->objectsByType(&selection); - return selection.size() > 0 ? selection[0] : NULL; + return selection.size() > 0 ? selection[0] : nullptr; } diff --git a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputPropertyFeature.h b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputPropertyFeature.h index 774d95f40c..5e16b897ae 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputPropertyFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputPropertyFeature.h @@ -32,9 +32,9 @@ class RicSaveEclipseInputPropertyFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: RimEclipseInputProperty* selectedInputProperty() const; diff --git a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsFeature.cpp index d78730c50b..43b1eefa7d 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsFeature.cpp @@ -22,11 +22,9 @@ #include "RiaLogging.h" #include "RicExportFeatureImpl.h" - +#include "RicEclipseCellResultToFileImpl.h" #include "RicSaveEclipseInputVisibleCellsUi.h" -#include "RifEclipseInputFileTools.h" - #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" @@ -49,7 +47,7 @@ CAF_CMD_SOURCE_INIT(RicSaveEclipseInputActiveVisibleCellsFeature, "RicSaveEclips //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void executeCommand(RimEclipseView* view) +void RicSaveEclipseInputVisibleCellsFeature::openDialogAndExecuteCommand(RimEclipseView* view) { if (!view) return; @@ -59,37 +57,48 @@ void executeCommand(RimEclipseView* view) if (propertyDialog.exec() == QDialog::Accepted) { - std::vector values; - cvf::UByteArray visibleCells; - view->calculateCurrentTotalCellVisibility(&visibleCells, view->currentTimeStep()); - RigActiveCellInfo* activeCellInfo = view->eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); - values.resize(visibleCells.size()); - for (size_t i = 0; i < visibleCells.size(); ++i) + executeCommand(view, exportSettings, "saveEclipseInputVisibleCells"); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicSaveEclipseInputVisibleCellsFeature::executeCommand(RimEclipseView* view, + const RicSaveEclipseInputVisibleCellsUi& exportSettings, + const QString& logPrefix) +{ + std::vector values; + cvf::UByteArray visibleCells; + view->calculateCurrentTotalCellVisibility(&visibleCells, view->currentTimeStep()); + RigActiveCellInfo* activeCellInfo = view->eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); + values.resize(visibleCells.size()); + for (size_t i = 0; i < visibleCells.size(); ++i) + { + if (activeCellInfo->isActive(i)) { - if (activeCellInfo->isActive(i)) + if (visibleCells[i]) { - if (visibleCells[i]) - { - values[i] = static_cast(exportSettings.visibleActiveCellsValue); - } - else - { - values[i] = static_cast(exportSettings.hiddenActiveCellsValue); - } + values[i] = static_cast(exportSettings.visibleActiveCellsValue); } else { - values[i] = static_cast(exportSettings.inactiveCellsValue); + values[i] = static_cast(exportSettings.hiddenActiveCellsValue); } } - QFile exportFile(exportSettings.exportFilename); - if (!exportFile.open(QIODevice::WriteOnly | QIODevice::Text)) + else { - RiaLogging::error(QString("saveEclipseInputVisibleCells: Unable to open file '%1' for writing.").arg(exportSettings.exportFilename)); - return; + values[i] = static_cast(exportSettings.inactiveCellsValue); } - RifEclipseInputFileTools::writeDataToTextFile(&exportFile, exportSettings.exportKeyword().text(), values); } + QFile exportFile(exportSettings.exportFilename); + if (!exportFile.open(QIODevice::WriteOnly | QIODevice::Text)) + { + RiaLogging::error(QString("%1: Unable to open file '%2' for writing.").arg(logPrefix).arg(exportSettings.exportFilename)); + return; + } + + RicEclipseCellResultToFileImpl::writeDataToTextFile(&exportFile, exportSettings.exportKeyword().text(), values); } //-------------------------------------------------------------------------------------------------- @@ -106,7 +115,7 @@ bool RicSaveEclipseInputVisibleCellsFeature::isCommandEnabled() void RicSaveEclipseInputVisibleCellsFeature::onActionTriggered(bool isChecked) { RimEclipseView* view = RicSaveEclipseInputVisibleCellsFeature::selectedView(); - executeCommand(view); + openDialogAndExecuteCommand(view); } //-------------------------------------------------------------------------------------------------- @@ -157,7 +166,7 @@ bool RicSaveEclipseInputActiveVisibleCellsFeature::isCommandEnabled() void RicSaveEclipseInputActiveVisibleCellsFeature::onActionTriggered(bool isChecked) { RimEclipseView* view = RicSaveEclipseInputActiveVisibleCellsFeature::getEclipseActiveView(); - executeCommand(view); + RicSaveEclipseInputVisibleCellsFeature::openDialogAndExecuteCommand(view); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsFeature.h b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsFeature.h index 35b0f38d03..bdb363c0b6 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsFeature.h @@ -20,8 +20,8 @@ #include "cafCmdFeature.h" -class RimEclipseInputProperty; class RimEclipseView; +class RicSaveEclipseInputVisibleCellsUi; //================================================================================================== /// @@ -30,10 +30,16 @@ class RicSaveEclipseInputVisibleCellsFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; +public : + static void openDialogAndExecuteCommand(RimEclipseView* view); + static void executeCommand(RimEclipseView* view, + const RicSaveEclipseInputVisibleCellsUi& exportSettings, + const QString& logPrefix); + protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; private: RimEclipseView* selectedView() const; @@ -47,9 +53,9 @@ class RicSaveEclipseInputActiveVisibleCellsFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static RimEclipseView* getEclipseActiveView(); diff --git a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsUi.h b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsUi.h index fbcaf1adc4..6e7ed37185 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsUi.h +++ b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseInputVisibleCellsUi.h @@ -41,7 +41,7 @@ class RicSaveEclipseInputVisibleCellsUi : public caf::PdmObject public: RicSaveEclipseInputVisibleCellsUi(void); - ~RicSaveEclipseInputVisibleCellsUi(); + ~RicSaveEclipseInputVisibleCellsUi() override; caf::PdmField exportFilename; caf::PdmField exportKeyword; @@ -50,9 +50,9 @@ class RicSaveEclipseInputVisibleCellsUi : public caf::PdmObject caf::PdmField inactiveCellsValue; protected: - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: QString getDefaultExportPath() const; diff --git a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyExec.cpp b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyExec.cpp index cf3c628f66..0093f2abfe 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyExec.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyExec.cpp @@ -23,9 +23,7 @@ #include "RiaLogging.h" #include "RicExportFeatureImpl.h" - -#include "RifEclipseInputFileTools.h" -#include "RifReaderInterface.h" +#include "RicEclipseCellResultToFileImpl.h" #include "RigCaseCellResultsData.h" @@ -99,7 +97,7 @@ void RicSaveEclipseResultAsInputPropertyExec::redo() { size_t timeStep = m_cellColors->reservoirView()->currentTimeStep(); - bool isOk = RifEclipseInputFileTools::writeBinaryResultToTextFile(exportSettings.fileName, m_cellColors->reservoirView()->eclipseCase()->eclipseCaseData(), timeStep, m_cellColors, exportSettings.eclipseKeyword, exportSettings.undefinedValue); + bool isOk = RicEclipseCellResultToFileImpl::writeBinaryResultToTextFile(exportSettings.fileName, m_cellColors->reservoirView()->eclipseCase()->eclipseCaseData(), timeStep, m_cellColors, exportSettings.eclipseKeyword, exportSettings.undefinedValue, "saveEclipseResultAsInputPropertyExec"); if (!isOk) { RiaLogging::error("Failed to exported current result to " + exportSettings.fileName); diff --git a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyExec.h b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyExec.h index 6a949fc021..c3058227cc 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyExec.h +++ b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyExec.h @@ -31,11 +31,11 @@ class RicSaveEclipseResultAsInputPropertyExec : public caf::CmdExecuteCommand { public: explicit RicSaveEclipseResultAsInputPropertyExec(RimEclipseCellColors* cellColors); - virtual ~RicSaveEclipseResultAsInputPropertyExec(); + ~RicSaveEclipseResultAsInputPropertyExec() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: caf::PdmPointer m_cellColors; diff --git a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyFeature.h b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyFeature.h index da7977fb04..9119484b88 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicSaveEclipseResultAsInputPropertyFeature.h @@ -31,9 +31,9 @@ class RicSaveEclipseResultAsInputPropertyFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllPlotsToFileFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllPlotsToFileFeature.cpp index 3572a5c125..548cbaccde 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllPlotsToFileFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllPlotsToFileFeature.cpp @@ -68,7 +68,7 @@ void RicSnapshotAllPlotsToFileFeature::saveAllPlots() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(QString snapshotFolderName) +void RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(const QString& snapshotFolderName, const QString& prefix) { RiaApplication* app = RiaApplication::instance(); @@ -91,6 +91,11 @@ void RicSnapshotAllPlotsToFileFeature::exportSnapshotOfAllPlotsIntoFolder(QStrin if (viewWindow->isMdiWindow() && viewWindow->viewWidget()) { QString fileName = RicSnapshotFilenameGenerator::generateSnapshotFileName(viewWindow); + if (!prefix.isEmpty()) + { + fileName = prefix + fileName; + } + fileName.replace(" ", "_"); QString absoluteFileName = caf::Utils::constructFullFileName(absSnapshotPath, fileName, ".png"); diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllPlotsToFileFeature.h b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllPlotsToFileFeature.h index 922fe3914b..f191172432 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllPlotsToFileFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllPlotsToFileFeature.h @@ -32,13 +32,13 @@ class RicSnapshotAllPlotsToFileFeature : public caf::CmdFeature public: static void saveAllPlots(); - static void exportSnapshotOfAllPlotsIntoFolder(QString snapshotFolderName); + static void exportSnapshotOfAllPlotsIntoFolder(const QString& snapshotFolderName, const QString& prefix = ""); protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp index 46f51c874e..2d880c5cef 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp @@ -70,7 +70,7 @@ void RicSnapshotAllViewsToFileFeature::saveAllViews() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(QString snapshotFolderName) +void RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(const QString& snapshotFolderName, const QString& prefix) { RimProject* project = RiaApplication::instance()->project(); @@ -114,6 +114,10 @@ void RicSnapshotAllViewsToFileFeature::exportSnapshotOfAllViewsIntoFolder(QStrin viewer->repaint(); QString fileName = RicSnapshotFilenameGenerator::generateSnapshotFileName(riv); + if (!prefix.isEmpty()) + { + fileName = prefix + fileName; + } QString absoluteFileName = caf::Utils::constructFullFileName(absSnapshotPath, fileName, ".png"); diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h index f473523e49..e8d664f36b 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.h @@ -32,11 +32,11 @@ class RicSnapshotAllViewsToFileFeature : public caf::CmdFeature public: static void saveAllViews(); - static void exportSnapshotOfAllViewsIntoFolder(QString snapshotFolderName); + static void exportSnapshotOfAllViewsIntoFolder(const QString& snapshotFolderName, const QString& prefix = ""); protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToClipboardFeature.h b/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToClipboardFeature.h index 5a125e2675..e0e5b0b0af 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToClipboardFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToClipboardFeature.h @@ -37,9 +37,9 @@ class RicSnapshotViewToClipboardFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToFileFeature.cpp b/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToFileFeature.cpp index 9404695d3e..c0e8520031 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToFileFeature.cpp +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToFileFeature.cpp @@ -131,12 +131,11 @@ bool RicSnapshotViewToFileFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicSnapshotViewToFileFeature::onActionTriggered(bool isChecked) { - RiaApplication* app = RiaApplication::instance(); - // Get active view window before displaying the file selection dialog // If this is done after the file save dialog is displayed (and closed) - // app->activeViewWindow() returns NULL on Linux - RimViewWindow* viewWindow = app->activeViewWindow(); + // app->activeViewWindow() returns nullptr on Linux + + RimViewWindow* viewWindow = RiaApplication::activeViewWindow(); if (!viewWindow) { RiaLogging::error("No view window is available, nothing to do"); diff --git a/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToFileFeature.h b/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToFileFeature.h index afead616b0..cb33d429ec 100644 --- a/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToFileFeature.h +++ b/ApplicationCode/Commands/ExportCommands/RicSnapshotViewToFileFeature.h @@ -39,7 +39,7 @@ class RicSnapshotViewToFileFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/FlowCommands/RicAddStoredFlowCharacteristicsPlotFeature.h b/ApplicationCode/Commands/FlowCommands/RicAddStoredFlowCharacteristicsPlotFeature.h index 56090af68f..6f05101373 100644 --- a/ApplicationCode/Commands/FlowCommands/RicAddStoredFlowCharacteristicsPlotFeature.h +++ b/ApplicationCode/Commands/FlowCommands/RicAddStoredFlowCharacteristicsPlotFeature.h @@ -30,9 +30,9 @@ class RicAddStoredFlowCharacteristicsPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/FlowCommands/RicAddStoredWellAllocationPlotFeature.h b/ApplicationCode/Commands/FlowCommands/RicAddStoredWellAllocationPlotFeature.h index 651e2eaa17..d5ec2f3a8d 100644 --- a/ApplicationCode/Commands/FlowCommands/RicAddStoredWellAllocationPlotFeature.h +++ b/ApplicationCode/Commands/FlowCommands/RicAddStoredWellAllocationPlotFeature.h @@ -30,9 +30,9 @@ class RicAddStoredWellAllocationPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/FlowCommands/RicPlotProductionRateFeature.cpp b/ApplicationCode/Commands/FlowCommands/RicPlotProductionRateFeature.cpp index c59a8b4e63..2312bd3b27 100644 --- a/ApplicationCode/Commands/FlowCommands/RicPlotProductionRateFeature.cpp +++ b/ApplicationCode/Commands/FlowCommands/RicPlotProductionRateFeature.cpp @@ -280,7 +280,8 @@ RimSummaryCurve* RicPlotProductionRateFeature::addSummaryCurve( RimSummaryPlot* -1, -1, -1, - -1); + -1, + false); if (!gridSummaryCase->summaryReader()->hasAddress(addr)) { diff --git a/ApplicationCode/Commands/FlowCommands/RicPlotProductionRateFeature.h b/ApplicationCode/Commands/FlowCommands/RicPlotProductionRateFeature.h index 934de6721a..1b4544e5b4 100644 --- a/ApplicationCode/Commands/FlowCommands/RicPlotProductionRateFeature.h +++ b/ApplicationCode/Commands/FlowCommands/RicPlotProductionRateFeature.h @@ -37,9 +37,9 @@ class RicPlotProductionRateFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static RimGridSummaryCase* gridSummaryCaseForWell(RimSimWellInView* well); diff --git a/ApplicationCode/Commands/FlowCommands/RicSelectViewUI.cpp b/ApplicationCode/Commands/FlowCommands/RicSelectViewUI.cpp index f645cd9625..199a4426d5 100644 --- a/ApplicationCode/Commands/FlowCommands/RicSelectViewUI.cpp +++ b/ApplicationCode/Commands/FlowCommands/RicSelectViewUI.cpp @@ -97,7 +97,7 @@ QList RicSelectViewUI::calculateValueOptions(const caf:: for (Rim3dView* v : m_currentCase->views()) { QIcon icon = v->uiCapability()->uiIcon(); - QString displayName = v->name; + QString displayName = v->name(); options.push_back(caf::PdmOptionItemInfo(displayName, v, false, icon)); } diff --git a/ApplicationCode/Commands/FlowCommands/RicSelectViewUI.h b/ApplicationCode/Commands/FlowCommands/RicSelectViewUI.h index f3ecfa2355..e6748fa86c 100644 --- a/ApplicationCode/Commands/FlowCommands/RicSelectViewUI.h +++ b/ApplicationCode/Commands/FlowCommands/RicSelectViewUI.h @@ -42,10 +42,10 @@ class RicSelectViewUI : public caf::PdmObject bool createNewView() const; QString newViewName() const; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: caf::PdmPtrField m_selectedView; diff --git a/ApplicationCode/Commands/FlowCommands/RicShowContributingWellsFeature.h b/ApplicationCode/Commands/FlowCommands/RicShowContributingWellsFeature.h index ab99fa476e..1f28f60ece 100644 --- a/ApplicationCode/Commands/FlowCommands/RicShowContributingWellsFeature.h +++ b/ApplicationCode/Commands/FlowCommands/RicShowContributingWellsFeature.h @@ -29,9 +29,9 @@ class RicShowContributingWellsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/FlowCommands/RicShowContributingWellsFromPlotFeature.h b/ApplicationCode/Commands/FlowCommands/RicShowContributingWellsFromPlotFeature.h index bc4af31852..428abc63bd 100644 --- a/ApplicationCode/Commands/FlowCommands/RicShowContributingWellsFromPlotFeature.h +++ b/ApplicationCode/Commands/FlowCommands/RicShowContributingWellsFromPlotFeature.h @@ -30,9 +30,9 @@ class RicShowContributingWellsFromPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.h b/ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.h index a2caf77654..f7e5b67204 100644 --- a/ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.h +++ b/ApplicationCode/Commands/FlowCommands/RicShowFlowCharacteristicsPlotFeature.h @@ -29,9 +29,9 @@ class RicShowFlowCharacteristicsPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/FlowCommands/RicShowTotalAllocationDataFeature.h b/ApplicationCode/Commands/FlowCommands/RicShowTotalAllocationDataFeature.h index 6ac89e7e1b..e110de1e3c 100644 --- a/ApplicationCode/Commands/FlowCommands/RicShowTotalAllocationDataFeature.h +++ b/ApplicationCode/Commands/FlowCommands/RicShowTotalAllocationDataFeature.h @@ -33,9 +33,9 @@ class RicShowTotalAllocationDataFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; private: static std::set selectedWellAllocationPlots(); diff --git a/ApplicationCode/Commands/FlowCommands/RicShowWellAllocationPlotFeature.h b/ApplicationCode/Commands/FlowCommands/RicShowWellAllocationPlotFeature.h index a63dcf284c..5334614014 100644 --- a/ApplicationCode/Commands/FlowCommands/RicShowWellAllocationPlotFeature.h +++ b/ApplicationCode/Commands/FlowCommands/RicShowWellAllocationPlotFeature.h @@ -29,9 +29,9 @@ class RicShowWellAllocationPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/FractureCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/FractureCommands/CMakeLists_files.cmake index 9abc019ecd..6ab4d73b0b 100644 --- a/ApplicationCode/Commands/FractureCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/FractureCommands/CMakeLists_files.cmake @@ -12,6 +12,12 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewSimWellFractureFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewStimPlanFractureTemplateFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathFractureAtPosFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathFractureFeature.h + +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesOptionItemUi.h +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesUi.h +${CMAKE_CURRENT_LIST_DIR}/RicNewOptionItemFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicDeleteOptionItemFeature.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -27,8 +33,13 @@ ${CMAKE_CURRENT_LIST_DIR}/RicNewSimWellFractureFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewStimPlanFractureTemplateFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathFractureAtPosFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathFractureFeature.cpp -) +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesOptionItemUi.cpp +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesUi.cpp +${CMAKE_CURRENT_LIST_DIR}/RicNewOptionItemFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicDeleteOptionItemFeature.cpp +) list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES} @@ -38,4 +49,8 @@ list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES} ) +list(APPEND QT_MOC_HEADERS +${CMAKE_CURRENT_LIST_DIR}/RicCreateMultipleFracturesFeature.h +) + source_group( "CommandFeature\\Fracture" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/FractureCommands/RicConvertAllFractureTemplatesToFieldFeature.h b/ApplicationCode/Commands/FractureCommands/RicConvertAllFractureTemplatesToFieldFeature.h index 79a9a30dfd..a2f0fb5cd7 100644 --- a/ApplicationCode/Commands/FractureCommands/RicConvertAllFractureTemplatesToFieldFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicConvertAllFractureTemplatesToFieldFeature.h @@ -31,9 +31,9 @@ class RicConvertAllFractureTemplatesToFieldFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; }; diff --git a/ApplicationCode/Commands/FractureCommands/RicConvertAllFractureTemplatesToMetricFeature.h b/ApplicationCode/Commands/FractureCommands/RicConvertAllFractureTemplatesToMetricFeature.h index 26994bfebf..7d1fff23fb 100644 --- a/ApplicationCode/Commands/FractureCommands/RicConvertAllFractureTemplatesToMetricFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicConvertAllFractureTemplatesToMetricFeature.h @@ -31,9 +31,9 @@ class RicConvertAllFractureTemplatesToMetricFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; }; diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateDuplicateTemplateInOtherUnitSystemFeature.h b/ApplicationCode/Commands/FractureCommands/RicCreateDuplicateTemplateInOtherUnitSystemFeature.h index c7406382a1..797eed9b18 100644 --- a/ApplicationCode/Commands/FractureCommands/RicCreateDuplicateTemplateInOtherUnitSystemFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicCreateDuplicateTemplateInOtherUnitSystemFeature.h @@ -31,9 +31,9 @@ class RicCreateDuplicateTemplateInOtherUnitSystemFeature : public caf::CmdFeatur CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; }; diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp new file mode 100644 index 0000000000..0992cc5e0f --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.cpp @@ -0,0 +1,280 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicCreateMultipleFracturesFeature.h" +#include "RicFractureNameGenerator.h" + +#include "RiaApplication.h" + +#include "RicCreateMultipleFracturesUi.h" + +#include "RigActiveCellInfo.h" +#include "RigEclipseCaseData.h" + +#include "RimDialogData.h" +#include "RimEclipseCase.h" +#include "RimFractureTemplate.h" +#include "RimProject.h" +#include "RimWellPath.h" +#include "RimWellPathFracture.h" +#include "RimWellPathFractureCollection.h" +#include "RimEclipseView.h" +#include "RimStimPlanColors.h" + +#include "Riu3DMainWindowTools.h" + +#include "cafPdmUiPropertyViewDialog.h" +#include "cafSelectionManagerTools.h" + +#include "RiaPorosityModel.h" +#include +#include + +CAF_CMD_SOURCE_INIT(RicCreateMultipleFracturesFeature, "RicCreateMultipleFracturesFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::appendFractures() +{ + slotAppendFractures(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::replaceFractures() +{ + slotDeleteAndAppendFractures(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair RicCreateMultipleFracturesFeature::ijkRangeForGrid(RimEclipseCase* gridCase) const +{ + cvf::Vec3st minIJK; + cvf::Vec3st maxIJK; + if (gridCase && gridCase->eclipseCaseData()) + { + gridCase->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL)->IJKBoundingBox(minIJK, maxIJK); + return std::make_pair(minIJK, maxIJK); + } + return std::make_pair(cvf::Vec3st(), cvf::Vec3st()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::slotDeleteAndAppendFractures() +{ + RiuCreateMultipleFractionsUi* multipleFractionsUi = this->multipleFractionsUi(); + if (!multipleFractionsUi) return; + + auto items = multipleFractionsUi->locationsForNewFractures(); + for (auto item : items) + { + if (item.wellPath) + { + RimWellPathFractureCollection* fractureCollection = item.wellPath->fractureCollection(); + fractureCollection->deleteFractures(); + } + } + + slotAppendFractures(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::slotAppendFractures() +{ + RiuCreateMultipleFractionsUi* multipleFractionsUi = this->multipleFractionsUi(); + if (!multipleFractionsUi) return; + + auto items = multipleFractionsUi->locationsForNewFractures(); + for (auto item : items) + { + if (item.wellPath) + { + RimWellPathFractureCollection* fractureCollection = item.wellPath->fractureCollection(); + + // If this is the first fracture, set default result name + if (fractureCollection->allFractures().empty()) + { + RimEclipseView* activeView = dynamic_cast(RiaApplication::instance()->activeReservoirView()); + if (activeView) + { + activeView->fractureColors()->setDefaultResultName(); + } + } + + RimWellPathFracture* fracture = new RimWellPathFracture(); + fractureCollection->addFracture(fracture); + + fracture->setFractureUnit(item.wellPath->unitSystem()); + fracture->setMeasuredDepth(item.measuredDepth); + fracture->setFractureTemplate(item.fractureTemplate); + + QString fractureName = RicFractureNameGenerator::nameForNewFracture(); + if (item.fractureTemplate) + { + fractureName = QString("%1_%2").arg(item.fractureTemplate->name()).arg(item.measuredDepth); + } + + fracture->setName(fractureName); + } + } + + RiaApplication* app = RiaApplication::instance(); + RimProject* proj = app->project(); + + proj->updateConnectedEditors(); + proj->reloadCompletionTypeResultsInAllViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::slotClose() +{ + if (m_dialog) + { + m_dialog->close(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::onActionTriggered(bool isChecked) +{ + m_dialog = nullptr; + + RiuCreateMultipleFractionsUi* multipleFractionsUi = this->multipleFractionsUi(); + if (multipleFractionsUi) + { + m_copyOfObject = multipleFractionsUi->writeObjectToXmlString(); + + if (multipleFractionsUi->options().empty()) + { + RiaApplication* app = RiaApplication::instance(); + RimProject* proj = app->project(); + + RimEclipseCase* firstSourceCase = nullptr; + if (!proj->eclipseCases().empty()) + { + firstSourceCase = proj->eclipseCases().front(); + + auto ijkRange = ijkRangeForGrid(firstSourceCase); + int topK = static_cast(ijkRange.first.z()); + int baseK = static_cast(ijkRange.second.z()); + + double minimumDistanceFromTip = 100.0; + int maxFractureCount = 100; + multipleFractionsUi->setValues(firstSourceCase, minimumDistanceFromTip, maxFractureCount); + + // Options + auto newItem = new RicCreateMultipleFracturesOptionItemUi; + + RimFractureTemplate* firstFractureTemplate = nullptr; + if (!proj->allFractureTemplates().empty()) + { + firstFractureTemplate = proj->allFractureTemplates().front(); + } + + double minimumSpacing = 300.0; + newItem->setValues(topK + 1, baseK + 1, firstFractureTemplate, minimumSpacing); + + multipleFractionsUi->insertOptionItem(nullptr, newItem); + } + } + + // Selected well paths + std::vector selWells = caf::selectedObjectsByTypeStrict(); + multipleFractionsUi->clearWellPaths(); + for (auto wellPath : selWells) multipleFractionsUi->addWellPath(wellPath); + + caf::PdmUiPropertyViewDialog propertyDialog( + Riu3DMainWindowTools::mainWindowWidget(), multipleFractionsUi, "Create Multiple Fractures", ""); + + m_dialog = &propertyDialog; + multipleFractionsUi->setParentDialog(m_dialog); + + propertyDialog.resize(QSize(700, 450)); + + QDialogButtonBox* dialogButtonBox = propertyDialog.dialogButtonBox(); + + dialogButtonBox->clear(); + + { + QPushButton* pushButton = dialogButtonBox->addButton(RiuCreateMultipleFractionsUi::REPLACE_FRACTURES_BUTTON_TEXT, QDialogButtonBox::ActionRole); + connect(pushButton, SIGNAL(clicked()), this, SLOT(slotDeleteAndAppendFractures())); + pushButton->setDefault(false); + pushButton->setAutoDefault(false); + pushButton->setToolTip("Delete all existing fractures before adding new fractures"); + } + + { + QPushButton* pushButton = dialogButtonBox->addButton(RiuCreateMultipleFractionsUi::ADD_FRACTURES_BUTTON_TEXT, QDialogButtonBox::ActionRole); + connect(pushButton, SIGNAL(clicked()), this, SLOT(slotAppendFractures())); + pushButton->setDefault(false); + pushButton->setAutoDefault(false); + pushButton->setToolTip("Add new fractures"); + } + + { + QPushButton* pushButton = dialogButtonBox->addButton("Close", QDialogButtonBox::ActionRole); + connect(pushButton, SIGNAL(clicked()), this, SLOT(slotClose())); + pushButton->setDefault(false); + pushButton->setAutoDefault(false); + } + + propertyDialog.exec(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/FractureTemplate16x16.png")); + actionToSetup->setText("Create Multiple Fractures"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateMultipleFracturesFeature::isCommandEnabled() +{ + std::vector selWells = caf::selectedObjectsByTypeStrict(); + return !selWells.empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuCreateMultipleFractionsUi* RicCreateMultipleFracturesFeature::multipleFractionsUi() const +{ + RiaApplication* app = RiaApplication::instance(); + RimProject* proj = app->project(); + + return proj->dialogData()->multipleFractionsData(); +} diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h new file mode 100644 index 0000000000..39cf157f1b --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesFeature.h @@ -0,0 +1,65 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include "cvfAssert.h" +#include "cvfVector3.h" + +#include + +class RiuCreateMultipleFractionsUi; +class RimEclipseCase; + +namespace caf { + class PdmUiPropertyViewDialog; +} + +//================================================================================================== +/// +//================================================================================================== +class RicCreateMultipleFracturesFeature : public caf::CmdFeature +{ + Q_OBJECT + CAF_CMD_HEADER_INIT; + +public: + RicCreateMultipleFracturesFeature() {} + + void appendFractures(); + void replaceFractures(); + std::pair ijkRangeForGrid(RimEclipseCase* gridCase) const; + +private slots: + void slotDeleteAndAppendFractures(); + void slotAppendFractures(); + void slotClose(); + +private: + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + + RiuCreateMultipleFractionsUi* multipleFractionsUi() const; + +private: + QPointer m_dialog; + QString m_copyOfObject; +}; diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.cpp b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.cpp new file mode 100644 index 0000000000..043a390077 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.cpp @@ -0,0 +1,155 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicCreateMultipleFracturesOptionItemUi.h" + +#include "RiaApplication.h" + +#include "RicCreateMultipleFracturesUi.h" +#include "RimFractureTemplate.h" +#include "RimFractureTemplateCollection.h" +#include "RimOilField.h" +#include "RimProject.h" + +CAF_PDM_SOURCE_INIT(RicCreateMultipleFracturesOptionItemUi, "RiuMultipleFractionsOptions"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicCreateMultipleFracturesOptionItemUi::RicCreateMultipleFracturesOptionItemUi() +{ + CAF_PDM_InitField(&m_topKOneBased, "TopKLayer", 1, "Top K Layer", "", "", ""); + CAF_PDM_InitField(&m_baseKOneBased, "BaseKLayer", 1, "Base K Layer", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_fractureTemplate, "Template", "Template", "", "", ""); + CAF_PDM_InitField(&m_minSpacing, "MinSpacing", 300.0, "Spacing", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesOptionItemUi::setValues(int topKOneBased, + int baseKOneBased, + RimFractureTemplate* fractureTemplate, + double minimumSpacing) +{ + m_topKOneBased = topKOneBased; + m_baseKOneBased = baseKOneBased; + m_fractureTemplate = fractureTemplate; + m_minSpacing = minimumSpacing; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RicCreateMultipleFracturesOptionItemUi::topKLayer() const +{ + return m_topKOneBased; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RicCreateMultipleFracturesOptionItemUi::baseKLayer() const +{ + return m_baseKOneBased; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFractureTemplate* RicCreateMultipleFracturesOptionItemUi::fractureTemplate() const +{ + return m_fractureTemplate(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RicCreateMultipleFracturesOptionItemUi::minimumSpacing() const +{ + return m_minSpacing; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateMultipleFracturesOptionItemUi::isKLayerContained(int oneBasedK) const +{ + auto minMax = std::minmax(m_topKOneBased, m_baseKOneBased); + + if (oneBasedK < minMax.first) return false; + if (oneBasedK <= minMax.second) return true; + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateMultipleFracturesOptionItemUi::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) +{ + if (changedField == &m_topKOneBased) + { + if (m_topKOneBased > m_baseKOneBased) m_baseKOneBased = m_topKOneBased; + } + else if (changedField = &m_baseKOneBased) + { + if (m_baseKOneBased < m_topKOneBased) m_topKOneBased = m_baseKOneBased; + } + + RiuCreateMultipleFractionsUi* parent = nullptr; + this->firstAncestorOrThisOfType(parent); + if (parent) + { + parent->updateButtonsEnableState(); + parent->updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList + RicCreateMultipleFracturesOptionItemUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) +{ + QList options; + + RimProject* proj = RiaApplication::instance()->project(); + CVF_ASSERT(proj); + + if (fieldNeedingOptions == &m_fractureTemplate) + { + RimOilField* oilField = proj->activeOilField(); + if (oilField && oilField->fractureDefinitionCollection) + { + RimFractureTemplateCollection* fracDefColl = oilField->fractureDefinitionCollection(); + + for (RimFractureTemplate* fracDef : fracDefColl->fractureTemplates()) + { + QString displayText = fracDef->nameAndUnit(); + + options.push_back(caf::PdmOptionItemInfo(displayText, fracDef)); + } + } + } + + return options; +} diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.h b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.h new file mode 100644 index 0000000000..dd31db1956 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesOptionItemUi.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +class RimFractureTemplate; + +//================================================================================================== +/// +//================================================================================================== +class RicCreateMultipleFracturesOptionItemUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicCreateMultipleFracturesOptionItemUi(); + + void setValues(int topKOneBased, int baseKOneBased, RimFractureTemplate* fractureTemplate, double minimumSpacing); + + int topKLayer() const; + int baseKLayer() const; + RimFractureTemplate* fractureTemplate() const; + double minimumSpacing() const; + + bool isKLayerContained(int oneBasedK) const; + +private: + void + fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) override; + +private: + caf::PdmField m_topKOneBased; // Eclipse uses 1-based indexing + caf::PdmField m_baseKOneBased; // Eclipse uses 1-based indexing + caf::PdmPtrField m_fractureTemplate; + caf::PdmField m_minSpacing; +}; diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp new file mode 100644 index 0000000000..e9d9ec46e5 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.cpp @@ -0,0 +1,490 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicCreateMultipleFracturesUi.h" + +#include "RifEclipseDataTableFormatter.h" + +#include "RigEclipseCaseData.h" +#include "RigMainGrid.h" +#include "RigWellPath.h" +#include "RigWellPathIntersectionTools.h" +#include "RigWellLogExtractor.h" + +#include "RimEclipseCase.h" +#include "RimFractureTemplate.h" +#include "RimTools.h" +#include "RimWellPath.h" + +#include "cafCmdFeatureMenuBuilder.h" +#include "cafPdmUiTableViewEditor.h" +#include "cafPdmUiTextEditor.h" +#include "cafSelectionManagerTools.h" +#include "cafPdmUiPropertyViewDialog.h" + +#include "cvfBoundingBox.h" + +#include + +CAF_PDM_SOURCE_INIT(RiuCreateMultipleFractionsUi, "RiuCreateMultipleFractionsUi"); + +//-------------------------------------------------------------------------------------------------- +/// Internal definitions +//-------------------------------------------------------------------------------------------------- +#define DOUBLE_INF std::numeric_limits::infinity() + +// startMd > endMd (going upwards along well path) +class MultipleFracturesOption +{ +public: + MultipleFracturesOption() : startMd(0), endMd(0), startK(0), endK(0), uiOption(nullptr) {} + double startMd; + double endMd; + size_t startK; + size_t endK; + RicCreateMultipleFracturesOptionItemUi* uiOption; +}; + +std::vector fractureOptions(const RigEclipseCaseData* caseData, + const RimWellPath* wellPath, + const std::vector& allUiOptions); +RicCreateMultipleFracturesOptionItemUi* firstUiOptionContainingK(size_t k, + const std::vector& allUiOptions); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QString RiuCreateMultipleFractionsUi::ADD_FRACTURES_BUTTON_TEXT = "Add Fractures"; +const QString RiuCreateMultipleFractionsUi::REPLACE_FRACTURES_BUTTON_TEXT = "Replace Fractures"; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuCreateMultipleFractionsUi::RiuCreateMultipleFractionsUi() +{ + CAF_PDM_InitFieldNoDefault(&m_sourceCase, "SourceCase", "Case", "", "", ""); + + CAF_PDM_InitField(&m_minDistanceFromWellTd, "MinDistanceFromWellTd", 10.0, "Min Distance From Well TD", "", "", ""); + CAF_PDM_InitField(&m_maxFracturesPerWell, "MaxFracturesPerWell", 10, "Max Fractures Per Well", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_options, "Options", "Options", "", "", ""); + m_options.uiCapability()->setUiEditorTypeName(caf::PdmUiTableViewEditor::uiEditorTypeName()); + m_options.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_options.uiCapability()->setCustomContextMenuEnabled(true); + + CAF_PDM_InitFieldNoDefault(&m_fractureCreationSummary, "FractureCreationSummary", "Generated Fractures", "", "", ""); + m_fractureCreationSummary.registerGetMethod(this, &RiuCreateMultipleFractionsUi::summaryText); + m_fractureCreationSummary.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_fractureCreationSummary.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::setParentDialog(QPointer dialog) +{ + m_dialog = dialog; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::setValues(RimEclipseCase* eclipseCase, double minimumDistanceFromWellToe, int maxFracturesPerWell) +{ + m_sourceCase = eclipseCase; + m_minDistanceFromWellTd = minimumDistanceFromWellToe; + m_maxFracturesPerWell = maxFracturesPerWell; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::resetValues() +{ + m_sourceCase = nullptr; + m_options.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuCreateMultipleFractionsUi::options() const +{ + return m_options.childObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::insertOptionItem(RicCreateMultipleFracturesOptionItemUi* insertAfterThisObject, + RicCreateMultipleFracturesOptionItemUi* objectToInsert) +{ + size_t index = m_options.index(insertAfterThisObject); + if (index < m_options.size() - 1) + { + m_options.insert(index + 1, objectToInsert); + } + else + { + m_options.push_back(objectToInsert); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::deleteOptionItem(RicCreateMultipleFracturesOptionItemUi* optionsItem) +{ + m_options.removeChildObject(optionsItem); + delete optionsItem; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::clearOptions() +{ + m_options.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::addWellPath(RimWellPath* wellPath) +{ + m_wellPaths.push_back(wellPath); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::clearWellPaths() +{ + m_wellPaths.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RiuCreateMultipleFractionsUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) +{ + QList options; + + if (fieldNeedingOptions == &m_sourceCase) + { + RimTools::caseOptionItems(&options); + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, + QMenu* menu, + QWidget* fieldEditorWidget) +{ + caf::CmdFeatureMenuBuilder menuBuilder; + + menuBuilder << "RicNewOptionItemFeature"; + menuBuilder << "RicDeleteOptionItemFeature"; + + menuBuilder.appendToMenu(menu); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuCreateMultipleFractionsUi::summaryText() const +{ + std::vector locations = locationsForNewFractures(); + + std::set wellPathSet; + std::set fracTemplateSet; + + for (auto location : locations) + { + wellPathSet.insert(location.wellPath); + fracTemplateSet.insert(location.fractureTemplate); + } + + QString tableText; + + { + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + formatter.setTableRowLineAppendText(""); + formatter.setTableRowPrependText(" "); + + std::vector header; + header.push_back(RifEclipseOutputTableColumn("Selected Wells")); + + for (auto fracTemplate : fracTemplateSet) + { + header.push_back(RifEclipseOutputTableColumn( + fracTemplate->name(), RifEclipseOutputTableDoubleFormatting(), RifEclipseOutputTableAlignment::RIGHT)); + } + + formatter.header(header); + + for (auto wellPath : wellPathSet) + { + formatter.add(wellPath->name()); + + for (auto fractureTemplate : fracTemplateSet) + { + size_t fractureTemplateCount = 0; + for (auto fracLocation : locations) + { + if (fractureTemplate == fracLocation.fractureTemplate && wellPath == fracLocation.wellPath) + { + fractureTemplateCount++; + } + } + + formatter.add(fractureTemplateCount); + } + + formatter.rowCompleted(); + } + + formatter.tableCompleted(); + } + + return tableText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_fractureCreationSummary) + { + auto attr = dynamic_cast(attribute); + if (attr) + { + QFont font("Courier", 8); + + attr->font = font; + attr->wrapMode = caf::PdmUiTextEditorAttribute::NoWrap; + } + } + else if (field == &m_options) + { + auto attr = dynamic_cast(attribute); + if (attr) + { + attr->minimumHeight = 130; + attr->columnWidths = { 90, 90, 400, 70 }; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuCreateMultipleFractionsUi::locationsForNewFractures() const +{ + std::vector items; + + RigMainGrid* mainGrid = nullptr; + + if (m_sourceCase && m_sourceCase->eclipseCaseData()) + { + mainGrid = m_sourceCase->eclipseCaseData()->mainGrid(); + } + + if (mainGrid) + { + for (auto w : m_wellPaths) + { + auto wellPathGeometry = w->wellPathGeometry(); + if (wellPathGeometry) + { + int fractureCountForWell = 0; + auto options = fractureOptions(m_sourceCase->eclipseCaseData(), w, this->options()); + auto mdOfWellPathTip = wellPathGeometry->measureDepths().back(); + double lastFracMd = mdOfWellPathTip; + + // Iterate options which are sorted from deeper to shallower + for(size_t i = 0; i < options.size(); i++) + { + const auto& option = options[i]; + double fracMdCandidate; + if(i == 0) + { + fracMdCandidate = mdOfWellPathTip - m_minDistanceFromWellTd; + } + else + { + double spacing = std::max(options[i - 1].uiOption->minimumSpacing(), option.uiOption->minimumSpacing()); + fracMdCandidate = lastFracMd - spacing; + } + + if (fracMdCandidate > option.startMd) fracMdCandidate = option.startMd; + + while (fracMdCandidate > option.endMd) + { + items.push_back(LocationForNewFracture(option.uiOption->fractureTemplate(), w, fracMdCandidate)); + lastFracMd = fracMdCandidate; + fracMdCandidate -= option.uiOption->minimumSpacing(); + fractureCountForWell++; + + if (fractureCountForWell >= m_maxFracturesPerWell) break; + } + + if (fractureCountForWell >= m_maxFracturesPerWell) break; + } + } + } + } + + std::sort(items.begin(), items.end()); + return items; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuCreateMultipleFractionsUi::updateButtonsEnableState() +{ + if (m_dialog) + { + bool hasOverlappingK = false; + const auto& opts = options(); + for (size_t i = 0; i < opts.size(); i++) + { + for (size_t j = i + 1; j < opts.size(); j++) + { + int absMin = std::min(opts[i]->topKLayer(), opts[j]->topKLayer()); + int absMax = std::max(opts[i]->baseKLayer(), opts[j]->baseKLayer()); + int leni = opts[i]->baseKLayer() - opts[i]->topKLayer() + 1; + int lenj = opts[j]->baseKLayer() - opts[j]->topKLayer() + 1; + if (absMax - absMin + 1 < leni + lenj) + { + hasOverlappingK = true; + break; + } + } + } + + for (auto button : m_dialog->dialogButtonBox()->buttons()) + { + if (button->text() == ADD_FRACTURES_BUTTON_TEXT || button->text() == REPLACE_FRACTURES_BUTTON_TEXT) + { + button->setEnabled(!hasOverlappingK); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// Internal definitions +//-------------------------------------------------------------------------------------------------- + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector fractureOptions(const RigEclipseCaseData* caseData, + const RimWellPath* wellPath, + const std::vector& allUiOptions) +{ + std::vector options; + + if (!caseData->mainGrid()) return options; + + auto wellPathGeometry = wellPath->wellPathGeometry(); + + std::vector wellPathInfos = + RigWellPathIntersectionTools::findCellIntersectionInfosAlongPath(caseData, + wellPathGeometry->wellPathPoints(), + wellPathGeometry->measureDepths()); + std::reverse(wellPathInfos.begin(), wellPathInfos.end()); + + bool doCreateNewOption = true; + for (const auto& wellPathInfo : wellPathInfos) + { + size_t i, j, currK; + + if(!caseData->mainGrid()->ijkFromCellIndex(wellPathInfo.globCellIndex, &i, &j, &currK)) continue; + + RicCreateMultipleFracturesOptionItemUi* uiOption = firstUiOptionContainingK(currK, allUiOptions); + + if (!uiOption) + { + doCreateNewOption = true; + continue; + } + else if (options.empty() || options.back().uiOption != uiOption) + { + doCreateNewOption = true; + } + + if (doCreateNewOption) + { + // New option + MultipleFracturesOption option; + + option.startMd = wellPathInfo.endMD; // Deeper MD + option.endMd = wellPathInfo.startMD; // Upper MD + + option.startK = currK; + option.endK = currK; + + option.uiOption = uiOption; + options.push_back(option); + + doCreateNewOption = false; + } + else + { + // Update existing option + MultipleFracturesOption& option = options.back(); + + option.endMd = wellPathInfo.startMD; // Upper MD + option.startK = std::max(option.startK, currK); + option.endK = std::min(option.endK, currK); + } + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicCreateMultipleFracturesOptionItemUi* firstUiOptionContainingK(size_t k, + const std::vector& allUiOptions) +{ + for (auto uiOption : allUiOptions) + { + int oneBasedK = static_cast(k) + 1; + if (uiOption->isKLayerContained(oneBasedK) && uiOption->fractureTemplate()) + { + return uiOption; + } + } + return nullptr; +} diff --git a/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h new file mode 100644 index 0000000000..b0114e0ab4 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicCreateMultipleFracturesUi.h @@ -0,0 +1,118 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicCreateMultipleFracturesOptionItemUi.h" + +#include + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmProxyValueField.h" + +class RimEclipseCase; +class RimWellPath; +class RigMainGrid; + +namespace caf +{ + class PdmUiPropertyViewDialog; +} + +//================================================================================================== +/// +//================================================================================================== +class LocationForNewFracture +{ +public: + LocationForNewFracture(RimFractureTemplate* fractureTemplate, RimWellPath* wellPath, double measuredDepth) + : fractureTemplate(fractureTemplate) + , wellPath(wellPath) + , measuredDepth(measuredDepth) + { + } + + bool operator<(const LocationForNewFracture& loc) const + { + return measuredDepth < loc.measuredDepth; + } + + RimFractureTemplate* fractureTemplate; + RimWellPath* wellPath; + double measuredDepth; +}; + +//================================================================================================== +/// +//================================================================================================== +class RiuCreateMultipleFractionsUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + static const QString ADD_FRACTURES_BUTTON_TEXT; + static const QString REPLACE_FRACTURES_BUTTON_TEXT; + + RiuCreateMultipleFractionsUi(); + + void setParentDialog(QPointer dialog); + void setValues(RimEclipseCase* eclipseCase, double minimumDistanceFromWellTip, int maxFracturesPerWell); + void resetValues(); + + std::vector options() const; + + void insertOptionItem(RicCreateMultipleFracturesOptionItemUi* insertAfterThisObject, + RicCreateMultipleFracturesOptionItemUi* objectToInsert); + + void deleteOptionItem(RicCreateMultipleFracturesOptionItemUi* optionsItem); + + void clearOptions(); + + void addWellPath(RimWellPath* wellPath); + + void clearWellPaths(); + + std::vector locationsForNewFractures() const; + + void updateButtonsEnableState(); + +private: + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) override; + void + defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, QWidget* fieldEditorWidget) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; + + QString summaryText() const; + +private: + caf::PdmPtrField m_sourceCase; + caf::PdmField m_minDistanceFromWellTd; + caf::PdmField m_maxFracturesPerWell; + caf::PdmChildArrayField m_options; + + caf::PdmProxyValueField m_fractureCreationSummary; + + std::vector m_wellPaths; + + QPointer m_dialog; +}; diff --git a/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.cpp b/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.cpp new file mode 100644 index 0000000000..02b73dffaa --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.cpp @@ -0,0 +1,70 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicDeleteOptionItemFeature.h" + +#include "RicCreateMultipleFracturesOptionItemUi.h" +#include "RicCreateMultipleFracturesUi.h" + +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicDeleteOptionItemFeature, "RicDeleteOptionItemFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteOptionItemFeature::onActionTriggered(bool isChecked) +{ + std::vector optionItems; + caf::SelectionManager::instance()->objectsByType(&optionItems, caf::SelectionManager::FIRST_LEVEL); + + if (!optionItems.empty()) + { + RiuCreateMultipleFractionsUi* multipleFractionUi = nullptr; + optionItems[0]->firstAncestorOrThisOfTypeAsserted(multipleFractionUi); + + for (auto optionItem : optionItems) + { + multipleFractionUi->deleteOptionItem(optionItem); + } + + multipleFractionUi->updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteOptionItemFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete Option Items"); + // actionToSetup->setIcon(QIcon(":/FractureTemplate16x16.png")); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicDeleteOptionItemFeature::isCommandEnabled() +{ + std::vector optionItems; + caf::SelectionManager::instance()->objectsByType(&optionItems, caf::SelectionManager::FIRST_LEVEL); + + return !optionItems.empty(); +} diff --git a/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.h b/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.h new file mode 100644 index 0000000000..a32509d405 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicDeleteOptionItemFeature.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicDeleteOptionItemFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +private: + bool isCommandEnabled() override; + void setupActionLook(QAction* actionToSetup) override; + void onActionTriggered(bool isChecked) override; +}; diff --git a/ApplicationCode/Commands/FractureCommands/RicNewEllipseFractureTemplateFeature.h b/ApplicationCode/Commands/FractureCommands/RicNewEllipseFractureTemplateFeature.h index e6a45aa955..26a440b44c 100644 --- a/ApplicationCode/Commands/FractureCommands/RicNewEllipseFractureTemplateFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicNewEllipseFractureTemplateFeature.h @@ -37,7 +37,7 @@ class RicNewEllipseFractureTemplateFeature : public caf::CmdFeature RimFractureTemplate* ellipseFractureTemplate); protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; }; diff --git a/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.cpp b/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.cpp new file mode 100644 index 0000000000..16809fa500 --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.cpp @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewOptionItemFeature.h" + +#include "RiaApplication.h" + +#include "RicCreateMultipleFracturesOptionItemUi.h" +#include "RicCreateMultipleFracturesUi.h" + +#include "RimProject.h" +#include "RimDialogData.h" + +#include "cafPdmChildArrayField.h" +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicNewOptionItemFeature, "RicNewOptionItemFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewOptionItemFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewOptionItemFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Option Item"); + // actionToSetup->setIcon(QIcon(":/Well.png")); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewOptionItemFeature::onActionTriggered(bool isChecked) +{ + RiuCreateMultipleFractionsUi* multipleFractionUi = RiaApplication::instance()->project()->dialogData()->multipleFractionsData(); + RicCreateMultipleFracturesOptionItemUi* selectedOptionItem = nullptr; + + { + std::vector optionItems; + caf::SelectionManager::instance()->objectsByType(&optionItems, caf::SelectionManager::FIRST_LEVEL); + if (!optionItems.empty()) + { + selectedOptionItem = optionItems.front(); + selectedOptionItem->firstAncestorOrThisOfTypeAsserted(multipleFractionUi); + } + + if (!selectedOptionItem && multipleFractionUi && !multipleFractionUi->options().empty()) + { + selectedOptionItem = multipleFractionUi->options().back(); + } + } + + if (multipleFractionUi) + { + auto newItem = new RicCreateMultipleFracturesOptionItemUi(); + + if (selectedOptionItem) + { + newItem->setValues(selectedOptionItem->baseKLayer() + 1, + selectedOptionItem->baseKLayer() + 1, + selectedOptionItem->fractureTemplate(), + selectedOptionItem->minimumSpacing()); + } + multipleFractionUi->insertOptionItem(selectedOptionItem, newItem); + multipleFractionUi->updateButtonsEnableState(); + multipleFractionUi->updateConnectedEditors(); + } +} diff --git a/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.h b/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.h new file mode 100644 index 0000000000..5dafff108d --- /dev/null +++ b/ApplicationCode/Commands/FractureCommands/RicNewOptionItemFeature.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicNewOptionItemFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +private: + bool isCommandEnabled() override; + void setupActionLook(QAction* actionToSetup) override; + void onActionTriggered(bool isChecked) override; +}; diff --git a/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureAtPosFeature.cpp b/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureAtPosFeature.cpp index e4a31058d3..e02543f14c 100644 --- a/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureAtPosFeature.cpp +++ b/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureAtPosFeature.cpp @@ -72,10 +72,10 @@ void RicNewSimWellFractureAtPosFeature::onActionTriggered(bool isChecked) RimSimWellFracture* fracture = new RimSimWellFracture(); if (fractureCollection->simwellFractures.empty()) { - RimEclipseView* activeView = dynamic_cast(RiaApplication::instance()->activeReservoirView()); - if (activeView) + RimEclipseView* eclipseView = dynamic_cast(RiaApplication::instance()->activeReservoirView()); + if (eclipseView) { - activeView->fractureColors()->setDefaultResultName(); + eclipseView->fractureColors()->setDefaultResultName(); } } diff --git a/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureAtPosFeature.h b/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureAtPosFeature.h index 1d812124c0..551f2f7cd4 100644 --- a/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureAtPosFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureAtPosFeature.h @@ -31,9 +31,9 @@ class RicNewSimWellFractureAtPosFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; }; diff --git a/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureFeature.h b/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureFeature.h index 03369c84c5..cde0f0eb3c 100644 --- a/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicNewSimWellFractureFeature.h @@ -31,9 +31,9 @@ class RicNewSimWellFractureFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; }; diff --git a/ApplicationCode/Commands/FractureCommands/RicNewStimPlanFractureTemplateFeature.cpp b/ApplicationCode/Commands/FractureCommands/RicNewStimPlanFractureTemplateFeature.cpp index b0905a59f8..e3e231be1c 100644 --- a/ApplicationCode/Commands/FractureCommands/RicNewStimPlanFractureTemplateFeature.cpp +++ b/ApplicationCode/Commands/FractureCommands/RicNewStimPlanFractureTemplateFeature.cpp @@ -45,9 +45,9 @@ void RicNewStimPlanFractureTemplateFeature::onActionTriggered(bool isChecked) { RiaApplication* app = RiaApplication::instance(); QString defaultDir = app->lastUsedDialogDirectory("BINARY_GRID"); - QString fileName = QFileDialog::getOpenFileName(nullptr, "Open StimPlan XML File", defaultDir, "StimPlan XML File (*.xml);;All files(*.*)"); + QStringList fileNames = QFileDialog::getOpenFileNames(nullptr, "Open StimPlan XML File", defaultDir, "StimPlan XML File (*.xml);;All files(*.*)"); - if (fileName.isEmpty()) return; + if (fileNames.isEmpty()) return; RimProject* project = RiaApplication::instance()->project(); CVF_ASSERT(project); @@ -56,9 +56,12 @@ void RicNewStimPlanFractureTemplateFeature::onActionTriggered(bool isChecked) if (oilfield == nullptr) return; RimFractureTemplateCollection* fracDefColl = oilfield->fractureDefinitionCollection(); + if (!fracDefColl) return; - if (fracDefColl) + for(auto fileName : fileNames) { + if (fileName.isEmpty()) continue; + RimStimPlanFractureTemplate* fractureDef = new RimStimPlanFractureTemplate(); fracDefColl->addFractureTemplate(fractureDef); diff --git a/ApplicationCode/Commands/FractureCommands/RicNewStimPlanFractureTemplateFeature.h b/ApplicationCode/Commands/FractureCommands/RicNewStimPlanFractureTemplateFeature.h index c84af430da..271af8184d 100644 --- a/ApplicationCode/Commands/FractureCommands/RicNewStimPlanFractureTemplateFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicNewStimPlanFractureTemplateFeature.h @@ -31,9 +31,9 @@ class RicNewStimPlanFractureTemplateFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; }; diff --git a/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureAtPosFeature.h b/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureAtPosFeature.h index 8de994efbe..b1ac9cc462 100644 --- a/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureAtPosFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureAtPosFeature.h @@ -31,7 +31,7 @@ class RicNewWellPathFractureAtPosFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; }; diff --git a/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureFeature.cpp b/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureFeature.cpp index 36a3a18b0d..bf376908e6 100644 --- a/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureFeature.cpp +++ b/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureFeature.cpp @@ -61,7 +61,7 @@ void RicNewWellPathFractureFeature::addFracture(RimWellPath* wellPath, double me RimWellPathFractureCollection* fractureCollection = wellPath->fractureCollection(); CVF_ASSERT(fractureCollection); - if (fractureCollection->fractures.empty()) + if (fractureCollection->allFractures().empty()) { RimEclipseView* activeView = dynamic_cast(RiaApplication::instance()->activeReservoirView()); if (activeView) @@ -71,7 +71,7 @@ void RicNewWellPathFractureFeature::addFracture(RimWellPath* wellPath, double me } RimWellPathFracture* fracture = new RimWellPathFracture(); - fractureCollection->fractures.push_back(fracture); + fractureCollection->addFracture(fracture); fracture->setMeasuredDepth(measuredDepth); fracture->setFractureUnit(wellPath->unitSystem()); diff --git a/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureFeature.h b/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureFeature.h index 9063008a42..e4b13900a9 100644 --- a/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicNewWellPathFractureFeature.h @@ -36,9 +36,9 @@ class RicNewWellPathFractureFeature : public caf::CmdFeature static void addFracture(RimWellPath* wellPath, double measuredDepth); protected: - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; - virtual bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; private: static RimWellPathFractureCollection* selectedWellPathFractureCollection(); diff --git a/ApplicationCode/Commands/FractureCommands/RicPasteEllipseFractureFeature.h b/ApplicationCode/Commands/FractureCommands/RicPasteEllipseFractureFeature.h index e3fe726421..51ab307958 100644 --- a/ApplicationCode/Commands/FractureCommands/RicPasteEllipseFractureFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicPasteEllipseFractureFeature.h @@ -35,9 +35,9 @@ class RicPasteEllipseFractureFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; private: static RimFractureTemplateCollection* fractureTemplateCollection(); diff --git a/ApplicationCode/Commands/FractureCommands/RicPasteStimPlanFractureFeature.h b/ApplicationCode/Commands/FractureCommands/RicPasteStimPlanFractureFeature.h index 982b51ec21..f49bb8e7be 100644 --- a/ApplicationCode/Commands/FractureCommands/RicPasteStimPlanFractureFeature.h +++ b/ApplicationCode/Commands/FractureCommands/RicPasteStimPlanFractureFeature.h @@ -35,9 +35,9 @@ class RicPasteStimPlanFractureFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; private: static RimFractureTemplateCollection* fractureTemplateCollection(); diff --git a/ApplicationCode/Commands/HoloLensCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/HoloLensCommands/CMakeLists_files.cmake new file mode 100644 index 0000000000..dd22c000e5 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/CMakeLists_files.cmake @@ -0,0 +1,60 @@ + +set (SOURCE_GROUP_HEADER_FILES +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToFolderFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToFolderUi.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportImpl.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToSharingServerFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateSessionFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensTerminateSessionFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensRestClient.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensServerSettings.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateSessionUi.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensSession.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensSessionManager.h +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateDummyFileBackedSessionFeature.h + +${CMAKE_CURRENT_LIST_DIR}/VdeArrayDataPacket.h +${CMAKE_CURRENT_LIST_DIR}/VdeExportPart.h +${CMAKE_CURRENT_LIST_DIR}/VdeFileExporter.h +${CMAKE_CURRENT_LIST_DIR}/VdePacketDirectory.h +${CMAKE_CURRENT_LIST_DIR}/VdeVizDataExtractor.h +) + +set (SOURCE_GROUP_SOURCE_FILES +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToFolderFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportImpl.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToFolderUi.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensExportToSharingServerFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateSessionFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensTerminateSessionFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensRestClient.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensServerSettings.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateSessionUi.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensSession.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensSessionManager.cpp +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensCreateDummyFileBackedSessionFeature.cpp + +${CMAKE_CURRENT_LIST_DIR}/VdeArrayDataPacket.cpp +${CMAKE_CURRENT_LIST_DIR}/VdeExportPart.cpp +${CMAKE_CURRENT_LIST_DIR}/VdeFileExporter.cpp +${CMAKE_CURRENT_LIST_DIR}/VdePacketDirectory.cpp +${CMAKE_CURRENT_LIST_DIR}/VdeVizDataExtractor.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} +${CMAKE_CURRENT_LIST_DIR}/RicHoloLensRestClient.h +) + + + +source_group( "CommandFeature\\HoloLens" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateDummyFileBackedSessionFeature.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateDummyFileBackedSessionFeature.cpp new file mode 100644 index 0000000000..05fc22768b --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateDummyFileBackedSessionFeature.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensCreateDummyFileBackedSessionFeature.h" + +#include "RicHoloLensSessionManager.h" + +#include "RiaQIconTools.h" + +#include + +CAF_CMD_SOURCE_INIT(RicHoloLensCreateDummyFiledBackedSessionFeature, "RicHoloLensCreateDummyFiledBackedSessionFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensCreateDummyFiledBackedSessionFeature::isCommandEnabled() +{ + return RicHoloLensSessionManager::instance()->session() ? false : true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensCreateDummyFiledBackedSessionFeature::onActionTriggered(bool isChecked) +{ + RicHoloLensSessionManager::instance()->createDummyFileBackedSession(); + + RicHoloLensSessionManager::refreshToolbarState(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensCreateDummyFiledBackedSessionFeature::setupActionLook(QAction* actionToSetup) +{ + QPixmap pixmap(":/hololens.png"); + QPixmap overlayPixmap(":/plus-sign-green.png"); + + QPixmap combinedPixmap = RiaQIconTools::appendPixmapUpperLeft(pixmap, overlayPixmap); + actionToSetup->setIcon(QIcon(combinedPixmap)); + + actionToSetup->setText("Create Dummy File Backed Session"); +} diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateDummyFileBackedSessionFeature.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateDummyFileBackedSessionFeature.h new file mode 100644 index 0000000000..9518596fea --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateDummyFileBackedSessionFeature.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicHoloLensCreateDummyFiledBackedSessionFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +private: + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionFeature.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionFeature.cpp new file mode 100644 index 0000000000..606f88c8c0 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionFeature.cpp @@ -0,0 +1,83 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensCreateSessionFeature.h" + +#include "RiaQIconTools.h" + +#include "RicHoloLensCreateSessionUi.h" +#include "RicHoloLensServerSettings.h" +#include "RicHoloLensSessionManager.h" + +#include "cafPdmSettings.h" +#include "cafPdmUiPropertyViewDialog.h" + +#include +#include + +CAF_CMD_SOURCE_INIT(RicHoloLensCreateSessionFeature, "RicHoloLensCreateSessionFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensCreateSessionFeature::isCommandEnabled() +{ + return RicHoloLensSessionManager::instance()->session() ? false : true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensCreateSessionFeature::onActionTriggered(bool isChecked) +{ + RicHoloLensCreateSessionUi createSessionUi; + + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, &createSessionUi, "HoloLens - Create Session", ""); + propertyDialog.resize(QSize(400, 330)); + + { + QDialogButtonBox* dialogButtonBox = propertyDialog.dialogButtonBox(); + dialogButtonBox->clear(); + + QPushButton* pushButton = dialogButtonBox->addButton("Create Session", QDialogButtonBox::ActionRole); + connect(pushButton, SIGNAL(clicked()), &propertyDialog, SLOT(accept())); + } + + int ret = propertyDialog.exec(); + if (ret == QDialog::Accepted) + { + RicHoloLensSessionManager::instance()->createSession( + createSessionUi.serverUrl(), createSessionUi.sessionName(), createSessionUi.sessionPinCode()); + } + + RicHoloLensSessionManager::refreshToolbarState(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensCreateSessionFeature::setupActionLook(QAction* actionToSetup) +{ + QPixmap pixmap(":/hololens.png"); + QPixmap overlayPixmap(":/plus-sign-green.png"); + + QPixmap combinedPixmap = RiaQIconTools::appendPixmapUpperLeft(pixmap, overlayPixmap); + actionToSetup->setIcon(QIcon(combinedPixmap)); + + actionToSetup->setText("Create Session"); +} diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionFeature.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionFeature.h new file mode 100644 index 0000000000..ee61ab8314 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionFeature.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicHoloLensCreateSessionFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +private: + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionUi.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionUi.cpp new file mode 100644 index 0000000000..a890b21c37 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionUi.cpp @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensCreateSessionUi.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" +#include "RiaOptionItemFactory.h" + +#include "RicHoloLensServerSettings.h" + +#include "cafPdmSettings.h" +#include "cafPdmUiOrdering.h" + +CAF_PDM_SOURCE_INIT(RicHoloLensCreateSessionUi, "RicHoloLensCreateSessionUi"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensCreateSessionUi::RicHoloLensCreateSessionUi() +{ + CAF_PDM_InitObject("HoloLens Create Session", "", "", ""); + + CAF_PDM_InitField(&m_sessionName, "SessionName", QString("DummySessionName"), "Session Name", "", "", ""); + CAF_PDM_InitField(&m_sessionPinCode, "SessionPinCode", QString("1234"), "Session Pin Code", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_serverSettings, "ServerSettings", "Server Settings", "", "", ""); + m_serverSettings = new RicHoloLensServerSettings; + + caf::PdmSettings::readFieldsFromApplicationStore(m_serverSettings); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensCreateSessionUi::~RicHoloLensCreateSessionUi() +{ + caf::PdmSettings::writeFieldsToApplicationStore(m_serverSettings); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicHoloLensCreateSessionUi::serverUrl() const +{ + CVF_ASSERT(m_serverSettings()); + + return m_serverSettings->serverUrl(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicHoloLensCreateSessionUi::sessionName() const +{ + return m_sessionName; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicHoloLensCreateSessionUi::sessionPinCode() const +{ + return m_sessionPinCode; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensCreateSessionUi::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Server Configuration"); + + m_serverSettings->uiOrdering(uiConfigName, *group); + } + + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Create Session"); + + group->add(&m_sessionName); + group->add(&m_sessionPinCode); + } +} diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionUi.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionUi.h new file mode 100644 index 0000000000..d250767055 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensCreateSessionUi.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmChildField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +class RicHoloLensServerSettings; + +//================================================================================================== +/// +//================================================================================================== +class RicHoloLensCreateSessionUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicHoloLensCreateSessionUi(); + ~RicHoloLensCreateSessionUi() override; + + QString serverUrl() const; + QString sessionName() const; + QString sessionPinCode() const; + +protected: + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +private: + caf::PdmChildField m_serverSettings; + + caf::PdmField m_sessionName; + caf::PdmField m_sessionPinCode; +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportImpl.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportImpl.cpp new file mode 100644 index 0000000000..fb3a716aba --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportImpl.cpp @@ -0,0 +1,383 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensExportImpl.h" + +#include "RiaApplication.h" +#include "RiaPreferences.h" + +#include "RigMainGrid.h" + +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimFaultInView.h" +#include "RimGridView.h" +#include "RimSimWellInView.h" +#include "RimWellPath.h" + +#include "RiuViewer.h" +#include "RivFemPickSourceInfo.h" +#include "RivGeoMechVizLogic.h" +#include "RivIntersectionBoxSourceInfo.h" +#include "RivIntersectionSourceInfo.h" +#include "RivMeshLinesSourceInfo.h" +#include "RivSimWellPipeSourceInfo.h" +#include "RivSourceInfo.h" +#include "RivWellPathSourceInfo.h" + +#include "cafEffectGenerator.h" + +#include "cvfPart.h" +#include "cvfRenderState.h" +#include "cvfRenderStateTextureBindings.h" +#include "cvfRenderState_FF.h" +#include "cvfTexture.h" +#include "cvfTexture2D_FF.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicHoloLensExportImpl::partsForExport(const RimGridView& view) +{ + std::vector exportParts; + + RimEclipseCase* rimEclipseCase = nullptr; + view.firstAncestorOrThisOfType(rimEclipseCase); + + if (view.viewer()) + { + auto visibleParts = view.viewer()->visibleParts(); + + for (auto& visiblePart : visibleParts) + { + if (RicHoloLensExportImpl::isGrid(visiblePart.p())) + { + VdeExportPart exportPart(visiblePart.p()); + exportPart.setSourceObjectType(VdeExportPart::OBJ_TYPE_GRID); + + if (rimEclipseCase && rimEclipseCase->mainGrid()) + { + if (rimEclipseCase->mainGrid()->isFaceNormalsOutwards()) + { + exportPart.setWinding(VdeExportPart::COUNTERCLOCKWISE); + } + else + { + exportPart.setWinding(VdeExportPart::CLOCKWISE); + } + } + + { + auto* sourceInfo = dynamic_cast(visiblePart->sourceInfo()); + if (sourceInfo) + { + RimFaultInView* faultInView = dynamic_cast(sourceInfo->object()); + if (faultInView) + { + exportPart.setSourceObjectName(faultInView->name()); + exportPart.setColor(faultInView->faultColor()); + } + + RimEclipseCase* eclipseCase = dynamic_cast(sourceInfo->object()); + if (eclipseCase) + { + QString nameOfObject = rimEclipseCase->gridFileName(); + auto gridSourceInfo = dynamic_cast(visiblePart->sourceInfo()); + if (gridSourceInfo) + { + size_t gridIndex = gridSourceInfo->gridIndex(); + + nameOfObject += " Grid " + QString::number(gridIndex); + } + + const RimEclipseView* eclipseView = dynamic_cast(&view); + if (eclipseView) + { + cvf::Color4f color = eclipseView->colorFromCellCategory(sourceInfo->cellSetType()); + exportPart.setColor(color.toColor3f()); + exportPart.setOpacity(color.a()); + + QString text = RicHoloLensExportImpl::gridCellSetTypeText(sourceInfo->cellSetType()); + exportPart.setSourceObjectCellSetType(text); + } + + exportPart.setSourceObjectName(nameOfObject); + } + } + } + + { + auto femPartPickInfo = dynamic_cast(visiblePart->sourceInfo()); + if (femPartPickInfo) + { + exportPart.setColor(RivGeoMechVizLogic::staticCellColor()); + } + } + + appendTextureImage(exportPart, visiblePart.p()); + + exportParts.push_back(exportPart); + } + else if (RicHoloLensExportImpl::isPipe(visiblePart.p())) + { + VdeExportPart exportPart(visiblePart.p()); + exportPart.setSourceObjectType(VdeExportPart::OBJ_TYPE_PIPE); + + auto simWellSourceInfo = dynamic_cast(visiblePart->sourceInfo()); + if (simWellSourceInfo) + { + auto simWell = simWellSourceInfo->well(); + if (simWell) + { + exportPart.setSourceObjectName(simWell->name()); + exportPart.setColor(simWell->wellPipeColor()); + } + } + + auto wellPathSourceInfo = dynamic_cast(visiblePart->sourceInfo()); + if (wellPathSourceInfo) + { + RimWellPath* wellPath = wellPathSourceInfo->wellPath(); + if (wellPath) + { + exportPart.setSourceObjectName(wellPath->name()); + exportPart.setColor(wellPath->wellPathColor()); + } + } + + appendTextureImage(exportPart, visiblePart.p()); + + exportParts.push_back(exportPart); + } + else if (RicHoloLensExportImpl::isMeshLines(visiblePart.p())) + { + VdeExportPart exportPart(visiblePart.p()); + exportPart.setSourceObjectType(VdeExportPart::OBJ_TYPE_GRID); + + cvf::Color3f lineColor = RiaApplication::instance()->preferences()->defaultGridLineColors(); + + auto linesSourceInfo = dynamic_cast(visiblePart->sourceInfo()); + if (linesSourceInfo) + { + if (dynamic_cast(linesSourceInfo->object())) + { + lineColor = RiaApplication::instance()->preferences()->defaultFaultGridLineColors(); + } + } + + exportPart.setColor(lineColor); + exportPart.setRole(VdeExportPart::MESH_LINES); + + appendTextureImage(exportPart, visiblePart.p()); + + exportParts.push_back(exportPart); + } + } + } + + return exportParts; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensExportImpl::appendTextureImage(VdeExportPart& exportPart, cvf::Part* part) +{ + if (part && part->effect()) + { + { + auto textureBindings = dynamic_cast( + part->effect()->renderStateOfType(cvf::RenderState::TEXTURE_BINDINGS)); + + if (textureBindings && textureBindings->bindingCount() > 0) + { + cvf::Texture* textureBinding = textureBindings->texture(0); + if (textureBinding) + { + exportPart.setTextureImage(textureBinding->image()); + } + } + } + + { + auto textureMappingFF = dynamic_cast( + part->effect()->renderStateOfType(cvf::RenderState::TEXTURE_MAPPING_FF)); + + if (textureMappingFF && textureMappingFF->texture()) + { + auto* texture = textureMappingFF->texture(); + if (texture) + { + exportPart.setTextureImage(texture->image()); + } + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicHoloLensExportImpl::gridCellSetTypeText(RivCellSetEnum cellSetType) +{ + switch (cellSetType) + { + case OVERRIDDEN_CELL_VISIBILITY: + return "OVERRIDDEN_CELL_VISIBILITY"; + break; + case ALL_CELLS: + return "ALL_CELLS"; + break; + case ACTIVE: + return "ACTIVE"; + break; + case ALL_WELL_CELLS: + return "ALL_WELL_CELLS"; + break; + case VISIBLE_WELL_CELLS: + return "VISIBLE_WELL_CELLS"; + break; + case VISIBLE_WELL_FENCE_CELLS: + return "VISIBLE_WELL_FENCE_CELLS"; + break; + case INACTIVE: + return "INACTIVE"; + break; + case RANGE_FILTERED: + return "RANGE_FILTERED"; + break; + case RANGE_FILTERED_INACTIVE: + return "RANGE_FILTERED_INACTIVE"; + break; + case RANGE_FILTERED_WELL_CELLS: + return "RANGE_FILTERED_WELL_CELLS"; + break; + case VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER: + return "VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER"; + break; + case VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER: + return "VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER"; + break; + case PROPERTY_FILTERED: + return "PROPERTY_FILTERED"; + break; + case PROPERTY_FILTERED_WELL_CELLS: + return "PROPERTY_FILTERED_WELL_CELLS"; + break; + default: + break; + } + + return "INVALID_CELL_SET_TYPE"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensExportImpl::isGrid(const cvf::Part* part) +{ + if (!part) return false; + + auto sourceInfo = part->sourceInfo(); + + { + { + auto sourceInfoOfType = dynamic_cast(sourceInfo); + if (sourceInfoOfType) + { + return true; + } + } + + { + auto sourceInfoOfType = dynamic_cast(sourceInfo); + if (sourceInfoOfType) + { + return true; + } + } + + { + auto sourceInfoOfType = dynamic_cast(sourceInfo); + if (sourceInfoOfType) + { + return true; + } + } + + { + auto sourceInfoOfType = dynamic_cast(sourceInfo); + if (sourceInfoOfType) + { + return true; + } + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensExportImpl::isPipe(const cvf::Part* part) +{ + if (!part) return false; + + auto sourceInfo = part->sourceInfo(); + + { + auto simWellSourceInfo = dynamic_cast(sourceInfo); + if (simWellSourceInfo) + { + return true; + } + } + + { + auto wellPathSourceInfo = dynamic_cast(sourceInfo); + if (wellPathSourceInfo) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensExportImpl::isMeshLines(const cvf::Part* part) +{ + if (!part) return false; + + auto sourceInfo = part->sourceInfo(); + + { + auto linesSourceInfo = dynamic_cast(sourceInfo); + if (linesSourceInfo) + { + return true; + } + } + + return false; +} diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportImpl.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportImpl.h new file mode 100644 index 0000000000..d95913bc1d --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportImpl.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RivCellSetEnum.h" + +#include "VdeExportPart.h" + +#include "cvfBase.h" +#include "cvfCollection.h" + +class QString; +class RimGridView; + +namespace cvf +{ +class Part; +} // namespace cvf + +//================================================================================================== +/// +//================================================================================================== +class RicHoloLensExportImpl +{ +public: + static std::vector partsForExport(const RimGridView& view); + +private: + static void appendTextureImage(VdeExportPart& exportPart, cvf::Part* part); + static QString gridCellSetTypeText(RivCellSetEnum cellSetType); + + static bool isGrid(const cvf::Part* part); + static bool isPipe(const cvf::Part* part); + static bool isMeshLines(const cvf::Part* part); +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderFeature.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderFeature.cpp new file mode 100644 index 0000000000..4e8716d2e7 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderFeature.cpp @@ -0,0 +1,128 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensExportToFolderFeature.h" +#include "RicHoloLensExportImpl.h" +#include "RicHoloLensExportToFolderUi.h" + +#include "VdeFileExporter.h" + +#include "RiaApplication.h" +#include "RimCase.h" +#include "RimDialogData.h" +#include "RimGridView.h" +#include "RimProject.h" + +#include "cafPdmUiPropertyViewDialog.h" + +#include "cvfCollection.h" +#include "cvfPart.h" + +#include +#include +#include +#include +#include + +CAF_CMD_SOURCE_INIT(RicHoloLensExportToFolderFeature, "RicHoloLensExportToFolderFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensExportToFolderFeature::isCommandEnabled() +{ + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensExportToFolderFeature::onActionTriggered(bool isChecked) +{ + RimGridView* activeView = RiaApplication::instance()->activeGridView(); + + RicHoloLensExportToFolderUi* featureUi = RiaApplication::instance()->project()->dialogData()->holoLensExportToFolderData(); + featureUi->setViewForExport(activeView); + + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, featureUi, "HoloLens - Export Data Folder", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + propertyDialog.resize(QSize(400, 330)); + + if (propertyDialog.exec() == QDialog::Accepted && !featureUi->exportFolder().isEmpty()) + { + /* + cvf::Collection allPartsColl; + + RimGridView* viewForExport = featureUi->viewForExport(); + if (!viewForExport) return; + + QString caseName("Unnamed Case"); + { + RimCase* rimCase = nullptr; + viewForExport->firstAncestorOrThisOfType(rimCase); + if (rimCase) + { + caseName = rimCase->caseUserDescription(); + } + } + RicHoloLensExportImpl::partsForExport(viewForExport, &allPartsColl); + + QDir dir(featureUi->exportFolder()); + + for (size_t i = 0; i < allPartsColl.size(); i++) + { + cvf::Part* part = allPartsColl.at(i); + + if (part) + { + QString nameOfObject = RicHoloLensExportImpl::nameFromPart(part); + // caseName is relevant to combine with name of object + + // bool isGrid = RicHoloLensExportImpl::isGrid(part); + + QString absolutePath = dir.absoluteFilePath(nameOfObject); + QFile outputFile(absolutePath); + if (outputFile.open(QIODevice::WriteOnly)) + { + QTextStream stream(&outputFile); + + stream << nameOfObject; + } + } + } + */ + + + RimGridView* viewForExport = featureUi->viewForExport(); + if (!viewForExport) return; + + QDir dir(featureUi->exportFolder()); + const QString absOutputFolder = dir.absolutePath(); + + VdeFileExporter exporter(absOutputFolder); + exporter.exportViewContents(*viewForExport); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensExportToFolderFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/Save.png")); + actionToSetup->setText("HoloLens : Export to Folder"); +} diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderFeature.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderFeature.h new file mode 100644 index 0000000000..1b8eeaa0f7 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderFeature.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicHoloLensExportToFolderFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +private: + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderUi.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderUi.cpp new file mode 100644 index 0000000000..0a136e822d --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderUi.cpp @@ -0,0 +1,107 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensExportToFolderUi.h" + +#include "RiaApplication.h" +#include "RiaOptionItemFactory.h" + +#include "RimCase.h" +#include "RimGridView.h" +#include "RimProject.h" + +#include "cafPdmUiFilePathEditor.h" +#include "cafPdmUiOrdering.h" + +CAF_PDM_SOURCE_INIT(RicHoloLensExportToFolderUi, "RicHoloLensExportToFolderUi"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensExportToFolderUi::RicHoloLensExportToFolderUi() +{ + CAF_PDM_InitObject("Resample LAS curves for export", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_viewForExport, "ViewForExport", "View", "", "", ""); + + CAF_PDM_InitField(&m_exportFolder, "ExportFolder", QString(), "Export Folder", "", "", ""); + m_exportFolder.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensExportToFolderUi::setViewForExport(RimGridView* view) +{ + m_viewForExport = view; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicHoloLensExportToFolderUi::exportFolder() const +{ + return m_exportFolder; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGridView* RicHoloLensExportToFolderUi::viewForExport() const +{ + return m_viewForExport; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RicHoloLensExportToFolderUi::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) +{ + QList options; + + if (fieldNeedingOptions == &m_viewForExport) + { + std::vector visibleViews; + RiaApplication::instance()->project()->allVisibleGridViews(visibleViews); + + for (RimGridView* v : visibleViews) + { + RiaOptionItemFactory::appendOptionItemFromViewNameAndCaseName(v, &options); + } + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensExportToFolderUi::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_exportFolder) + { + caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast(attribute); + if (myAttr) + { + myAttr->m_selectDirectory = true; + } + } +} diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderUi.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderUi.h new file mode 100644 index 0000000000..8e3089bd1f --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToFolderUi.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +class RimGridView; + +//================================================================================================== +/// +//================================================================================================== +class RicHoloLensExportToFolderUi : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicHoloLensExportToFolderUi(); + + void setViewForExport(RimGridView* view); + + QString exportFolder() const; + RimGridView* viewForExport() const; + +private: + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; + +private: + caf::PdmPtrField m_viewForExport; + caf::PdmField m_exportFolder; +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToSharingServerFeature.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToSharingServerFeature.cpp new file mode 100644 index 0000000000..12ebb0b322 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToSharingServerFeature.cpp @@ -0,0 +1,84 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensExportToSharingServerFeature.h" +#include "RicHoloLensSessionManager.h" +#include "RicHoloLensSession.h" + +#include "RiaApplication.h" +#include "RiaQIconTools.h" +#include "RiaLogging.h" + +#include "RimGridView.h" + +#include + +CAF_CMD_SOURCE_INIT(RicHoloLensExportToSharingServerFeature, "RicHoloLensExportToSharingServerFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensExportToSharingServerFeature::isCommandEnabled() +{ + RicHoloLensSession* session = RicHoloLensSessionManager::instance()->session(); + if (session && session->isSessionValid()) + { + return true; + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensExportToSharingServerFeature::onActionTriggered(bool isChecked) +{ + RicHoloLensSession* session = RicHoloLensSessionManager::instance()->session(); + if (!session || !session->isSessionValid()) + { + RiaLogging::error("No valid HoloLens session present"); + return; + } + + RimGridView* activeView = RiaApplication::instance()->activeGridView(); + if (!activeView) + { + RiaLogging::error("No active view"); + return; + } + + + session->updateSessionDataFromView(*activeView); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensExportToSharingServerFeature::setupActionLook(QAction* actionToSetup) +{ + QPixmap pixmap(":/hololens.png"); + QPixmap overlayPixmap(":/arrow-right-green.png"); + + QPixmap combinedPixmap = RiaQIconTools::appendPixmapUpperLeft(pixmap, overlayPixmap); + actionToSetup->setIcon(QIcon(combinedPixmap)); + + actionToSetup->setText("Export to Sharing Server"); +} diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToSharingServerFeature.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToSharingServerFeature.h new file mode 100644 index 0000000000..31eb82beba --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensExportToSharingServerFeature.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicHoloLensExportToSharingServerFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +private: + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensRestClient.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensRestClient.cpp new file mode 100644 index 0000000000..d6667addda --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensRestClient.cpp @@ -0,0 +1,360 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensRestClient.h" + +#include "cvfBase.h" +#include "cvfTrace.h" + +#include +#include + + +#ifndef QT_NO_OPENSSL +// Uncomment to enable experimental SSL support +// The experimental support must be revised before shipping +#define EXPERIMENTAL_SSL_SUPPORT +#endif + + +//================================================================================================== +// +// +// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensRestClient::RicHoloLensRestClient(QString serverUrl, QString sessionName, RicHoloLensRestResponseHandler* responseHandler) +: m_serverUrl(serverUrl), + m_sessionName(sessionName), + m_responseHandler(responseHandler) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensRestClient::clearResponseHandler() +{ + m_responseHandler = nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensRestClient::createSession() +{ + const QString url = m_serverUrl + "/sessions/create/" + m_sessionName; + cvf::Trace::show("createSession: POST on url: %s", url.toLatin1().constData()); + + QNetworkRequest request(url); + //request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream")); + request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded")); + +#ifdef EXPERIMENTAL_SSL_SUPPORT + // NOTE !!! + // Apparently something like this is currently needed in order to get SSL/HTTPS going + // Still, can't quite figure it out since it appears to be sufficient to do this on the first request + // This will have to be investigated further, SP 20181924 + QSslConfiguration sslConf = request.sslConfiguration(); + + // Needed this one to be able to connect to sharing server + sslConf.setProtocol(QSsl::AnyProtocol); + + // !!MUST!! remove this code in production + sslConf.setPeerVerifyMode(QSslSocket::VerifyNone); + + request.setSslConfiguration(sslConf); +#endif + + QNetworkReply* reply = m_accessManager.post(request, QByteArray()); + connect(reply, SIGNAL(finished()), SLOT(slotCreateSessionFinished())); + +#ifdef EXPERIMENTAL_SSL_SUPPORT + connect(reply, SIGNAL(sslErrors(const QList&)), SLOT(slotSslErrors(const QList&))); +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensRestClient::slotCreateSessionFinished() +{ + QNetworkReply* reply = dynamic_cast(sender()); + if (!reply) + { + return; + } + + if (detectAndHandleErrorReply("createSession", reply)) + { + reply->deleteLater(); + return; + } + + reply->deleteLater(); + + cvf::Trace::show("createSession OK"); + if (m_responseHandler) + { + m_responseHandler->handleSuccessfulCreateSession(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensRestClient::deleteSession() +{ + const QString url = m_serverUrl + "/sessions/delete/" + m_sessionName; + cvf::Trace::show("deleteSession: DELETE on url: %s", url.toLatin1().constData()); + + QNetworkRequest request(url); + //request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream")); + request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/x-www-form-urlencoded")); + + QNetworkReply* reply = m_accessManager.deleteResource(request); + connect(reply, SIGNAL(finished()), SLOT(slotDeleteSessionFinished())); + +#ifdef EXPERIMENTAL_SSL_SUPPORT + connect(reply, SIGNAL(sslErrors(const QList&)), SLOT(slotSslErrors(const QList&))); +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensRestClient::slotDeleteSessionFinished() +{ + QNetworkReply* reply = dynamic_cast(sender()); + if (!reply) + { + return; + } + + if (detectAndHandleErrorReply("deleteSession", reply)) + { + reply->deleteLater(); + return; + } + + reply->deleteLater(); + + cvf::Trace::show("deleteSession OK"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensRestClient::sendMetaData(int metaDataSequenceNumber, const QString& jsonMetaDataString) +{ + const QString url = m_serverUrl + "/sessions/" + m_sessionName + "/metadata"; + cvf::Trace::show("sendMetaData (metaDataSequenceNumber=%d): POST on url: %s", metaDataSequenceNumber, url.toLatin1().constData()); + + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json")); + + const QByteArray jsonByteArr = jsonMetaDataString.toLatin1(); + + QNetworkReply* reply = m_accessManager.post(request, jsonByteArr); + reply->setProperty("metaDataSequenceNumber", QVariant(metaDataSequenceNumber)); + + connect(reply, SIGNAL(finished()), SLOT(slotSendMetaDataFinished())); + +#ifdef EXPERIMENTAL_SSL_SUPPORT + connect(reply, SIGNAL(sslErrors(const QList&)), SLOT(slotSslErrors(const QList&))); +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensRestClient::slotSendMetaDataFinished() +{ + QNetworkReply* reply = dynamic_cast(sender()); + if (!reply) + { + return; + } + + if (detectAndHandleErrorReply("sendMetaData", reply)) + { + reply->deleteLater(); + return; + } + + int metaDataSequenceNumber = -1; + { + QVariant var = reply->property("metaDataSequenceNumber"); + if (var.type() == QVariant::Int) + { + metaDataSequenceNumber = var.toInt(); + } + } + + reply->deleteLater(); + + cvf::Trace::show("sendMetaData (metaDataSequenceNumber=%d) OK", metaDataSequenceNumber); + if (m_responseHandler) + { + m_responseHandler->handleSuccessfulSendMetaData(metaDataSequenceNumber); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensRestClient::sendBinaryData(const QByteArray& binaryDataArr) +{ + const QString url = m_serverUrl + "/sessions/" + m_sessionName + "/data"; + cvf::Trace::show("sendBinaryData: POST on url: %s", url.toLatin1().constData()); + + QNetworkRequest request(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream")); + + QNetworkReply* reply = m_accessManager.post(request, binaryDataArr); + connect(reply, SIGNAL(finished()), SLOT(slotSendBinaryDataFinished())); + +#ifdef EXPERIMENTAL_SSL_SUPPORT + connect(reply, SIGNAL(sslErrors(const QList&)), SLOT(slotSslErrors(const QList&))); +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensRestClient::slotSendBinaryDataFinished() +{ + QNetworkReply* reply = dynamic_cast(sender()); + if (!reply) + { + return; + } + + if (detectAndHandleErrorReply("sendBinaryData", reply)) + { + reply->deleteLater(); + return; + } + + reply->deleteLater(); + + cvf::Trace::show("sendBinaryData OK"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensRestClient::slotSslErrors(const QList& errors) +{ +#ifdef EXPERIMENTAL_SSL_SUPPORT + cvf::Trace::show("RicHoloLensRestClient::slotSslErrors()"); + for (int i = 0; i < errors.size(); i++) + { + cvf::Trace::show(" %s", errors[i].errorString().toLatin1().constData()); + } +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensRestClient::detectAndHandleErrorReply(QString operationName, QNetworkReply* reply) +{ + CVF_ASSERT(reply); + + const QNetworkReply::NetworkError nwErrCode = reply->error(); + const int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + if (nwErrCode == QNetworkReply::NoError && httpStatusCode == 200) + { + // No error detected + return false; + } + + QString mainErrMsg = operationName + " FAILED"; + if (nwErrCode != QNetworkReply::NoError) + { + const QString nwErrCodeAsString = networkErrorCodeAsString(nwErrCode); + const QString errText = reply->errorString(); + mainErrMsg += QString(" [nwErr='%1'(%2) httpStatus=%3]: %4").arg(nwErrCodeAsString).arg(nwErrCode).arg(httpStatusCode).arg(errText); + } + else + { + mainErrMsg += QString(" [httpStatus=%1]").arg(httpStatusCode); + } + + cvf::Trace::show(mainErrMsg.toLatin1().constData()); + + reply->errorString(); + + const QString url = reply->url().toString(); + cvf::Trace::show(" url: %s", url.toLatin1().constData()); + + const QByteArray serverData = reply->readAll(); + cvf::Trace::show(" serverResponse: %s", serverData.constData()); + + if (m_responseHandler) + { + m_responseHandler->handleError(mainErrMsg, url, serverData); + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicHoloLensRestClient::networkErrorCodeAsString(QNetworkReply::NetworkError nwErr) +{ + switch (nwErr) + { + case QNetworkReply::NoError: return "NoError"; + + case QNetworkReply::ConnectionRefusedError: return "ConnectionRefusedError"; + case QNetworkReply::RemoteHostClosedError: return "RemoteHostClosedError"; + case QNetworkReply::HostNotFoundError: return "HostNotFoundError"; + case QNetworkReply::TimeoutError: return "TimeoutError"; + case QNetworkReply::OperationCanceledError: return "OperationCanceledError"; + case QNetworkReply::SslHandshakeFailedError: return "SslHandshakeFailedError"; + //case QNetworkReply::TemporaryNetworkFailureError: return "TemporaryNetworkFailureError"; + case QNetworkReply::UnknownNetworkError: return "UnknownNetworkError"; + + case QNetworkReply::ProxyConnectionRefusedError: return "ProxyConnectionRefusedError"; + case QNetworkReply::ProxyConnectionClosedError: return "ProxyConnectionClosedError"; + case QNetworkReply::ProxyNotFoundError: return "ProxyNotFoundError"; + case QNetworkReply::ProxyTimeoutError: return "ProxyTimeoutError"; + case QNetworkReply::ProxyAuthenticationRequiredError: return "ProxyAuthenticationRequiredError"; + case QNetworkReply::UnknownProxyError: return "UnknownProxyError"; + + case QNetworkReply::ContentAccessDenied: return "ContentAccessDenied"; + case QNetworkReply::ContentOperationNotPermittedError: return "ContentOperationNotPermittedError"; + case QNetworkReply::ContentNotFoundError: return "ContentNotFoundError"; + case QNetworkReply::AuthenticationRequiredError: return "AuthenticationRequiredError"; + case QNetworkReply::ContentReSendError: return "ContentReSendError"; + case QNetworkReply::UnknownContentError: return "UnknownContentError"; + + case QNetworkReply::ProtocolUnknownError: return "ProtocolUnknownError"; + case QNetworkReply::ProtocolInvalidOperationError: return "ProtocolInvalidOperationError"; + case QNetworkReply::ProtocolFailure: return "ProtocolFailure"; + }; + + return "UnknownErrorCode"; +} + diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensRestClient.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensRestClient.h new file mode 100644 index 0000000000..d378b68556 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensRestClient.h @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include + + + + +//================================================================================================== +// +// +// +//================================================================================================== +class RicHoloLensRestResponseHandler +{ +public: + virtual void handleSuccessfulCreateSession() = 0; + virtual void handleSuccessfulSendMetaData(int metaDataSequenceNumber) = 0; + + virtual void handleError(const QString& errMsg, const QString& url, const QString& serverData) = 0; +}; + + +//================================================================================================== +// +// +// +//================================================================================================== +class RicHoloLensRestClient : public QObject +{ + Q_OBJECT + +public: + RicHoloLensRestClient(QString serverUrl, QString sessionName, RicHoloLensRestResponseHandler* responseHandler); + + void clearResponseHandler(); + + void createSession(); + void deleteSession(); + void sendMetaData(int metaDataSequenceNumber, const QString& jsonMetaDataString); + void sendBinaryData(const QByteArray& binaryDataArr); + +private: + bool detectAndHandleErrorReply(QString operationName, QNetworkReply* reply); + static QString networkErrorCodeAsString(QNetworkReply::NetworkError nwErr); + +private slots: + void slotCreateSessionFinished(); + void slotDeleteSessionFinished(); + void slotSendMetaDataFinished(); + void slotSendBinaryDataFinished(); + + void slotSslErrors(const QList& errors); + +private: + QNetworkAccessManager m_accessManager; + QString m_serverUrl; + QString m_sessionName; + RicHoloLensRestResponseHandler* m_responseHandler; +}; diff --git a/ApplicationCode/FileInterface/RifEnsembleParametersReader.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensServerSettings.cpp similarity index 58% rename from ApplicationCode/FileInterface/RifEnsembleParametersReader.cpp rename to ApplicationCode/Commands/HoloLensCommands/RicHoloLensServerSettings.cpp index b91be08d0b..e1d9e8c283 100644 --- a/ApplicationCode/FileInterface/RifEnsembleParametersReader.cpp +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensServerSettings.cpp @@ -1,56 +1,41 @@ ///////////////////////////////////////////////////////////////////////////////// // -// Copyright (C) Statoil ASA -// +// 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// -#include "RifEnsembleParametersReader.h" -#include "RifCaseRealizationParametersReader.h" -#include "RifFileParseTools.h" +#include "RicHoloLensServerSettings.h" -#include "RiaLogging.h" -#include "RiaStdStringTools.h" - -#include -#include -#include +CAF_PDM_SOURCE_INIT(RicHoloLensServerSettings, "RicHoloLensServerSettings"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RifEnsembleParametersReader::RifEnsembleParametersReader(const QString& modelDirectory) +RicHoloLensServerSettings::RicHoloLensServerSettings() { - m_modelDirectory = modelDirectory; + CAF_PDM_InitObject("HoloLens Server Settings", "", "", ""); + + CAF_PDM_InitField(&m_serverAddress, "ServerAddress", QString(), "Server Address", "", "", ""); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifEnsembleParametersReader::~RifEnsembleParametersReader() +QString RicHoloLensServerSettings::serverUrl() const { + return m_serverAddress; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -//RifEnsembleParameters RifEnsembleParametersReader::import() -//{ -// RifEnsembleParameters parameters; -// -// -// return ; -//} - diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensServerSettings.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensServerSettings.h new file mode 100644 index 0000000000..7efa626dd6 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensServerSettings.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" + +class RimGridView; + +//================================================================================================== +/// +//================================================================================================== +class RicHoloLensServerSettings : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RicHoloLensServerSettings(); + + QString serverUrl() const; + +private: + caf::PdmField m_serverAddress; +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSession.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSession.cpp new file mode 100644 index 0000000000..5155b3f433 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSession.cpp @@ -0,0 +1,233 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensSession.h" +#include "RicHoloLensSessionManager.h" + +#include "RiaLogging.h" +#include "RiaPreferences.h" + +#include "VdeVizDataExtractor.h" +#include "VdeFileExporter.h" +#include "VdePacketDirectory.h" +#include "VdeArrayDataPacket.h" + +#include "cvfAssert.h" + +#include + + + +//================================================================================================== +// +// +// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensSession::RicHoloLensSession() +: m_isSessionValid(false), + m_lastExtractionMetaDataSequenceNumber(-1), + m_dbgEnableFileExport(false) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensSession::~RicHoloLensSession() +{ + destroySession(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensSession* RicHoloLensSession::createSession(const QString& serverUrl, const QString& sessionName) +{ + RicHoloLensSession* newSession = new RicHoloLensSession; + + newSession->m_restClient = new RicHoloLensRestClient(serverUrl, sessionName, newSession); + newSession->m_restClient->createSession(); + + // For now, leave this on!!! + // We probably want to export this as a preference parameter + newSession->m_dbgEnableFileExport = true; + + return newSession; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensSession* RicHoloLensSession::createDummyFileBackedSession() +{ + RicHoloLensSession* newSession = new RicHoloLensSession; + + newSession->m_isSessionValid = true; + + newSession->m_dbgEnableFileExport = true; + + return newSession; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensSession::destroySession() +{ + if (m_restClient) + { + if (m_isSessionValid) + { + m_restClient->deleteSession(); + } + + m_restClient->clearResponseHandler(); + m_restClient->deleteLater(); + m_restClient = nullptr; + } + + m_isSessionValid = false; + + m_lastExtractionMetaDataSequenceNumber = -1; + m_lastExtractionAllReferencedPacketIdsArr.clear(); + m_packetDirectory.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensSession::isSessionValid() const +{ + return m_isSessionValid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensSession::updateSessionDataFromView(const RimGridView& activeView) +{ + RiaLogging::info("HoloLens: Updating visualization data"); + + QString modelMetaJsonStr; + std::vector allReferencedPacketIds; + m_packetDirectory.clear(); + + VdeVizDataExtractor extractor(activeView); + extractor.extractViewContents(&modelMetaJsonStr, &allReferencedPacketIds, &m_packetDirectory); + + m_lastExtractionMetaDataSequenceNumber++; + m_lastExtractionAllReferencedPacketIdsArr = allReferencedPacketIds; + + if (m_restClient) + { + RiaLogging::info(QString("HoloLens: Sending updated meta data to sharing server (sequenceNumber=%1)").arg(m_lastExtractionMetaDataSequenceNumber)); + m_restClient->sendMetaData(m_lastExtractionMetaDataSequenceNumber, modelMetaJsonStr); + } + + // Debug export to file + if (m_dbgEnableFileExport) + { + const QString folderName = RiaApplication::instance()->preferences()->holoLensExportFolder(); + if (folderName.isEmpty()) + { + RiaLogging::warning("HoloLens: Debug export to file enabled, but no export folder has been set"); + return; + } + + const QDir outputDir(folderName); + const QString absOutputFolder = outputDir.absolutePath(); + + if (!outputDir.mkpath(".")) + { + RiaLogging::error(QString("HoloLens: Could not create debug file export folder: %1").arg(absOutputFolder)); + return; + } + + RiaLogging::info(QString("HoloLens: Doing debug export of data to folder: %1").arg(absOutputFolder)); + VdeFileExporter fileExporter(absOutputFolder); + if (!fileExporter.exportToFile(modelMetaJsonStr, m_packetDirectory, allReferencedPacketIds)) + { + RiaLogging::error("HoloLens: Error exporting debug data to folder"); + } + + RiaLogging::info("HoloLens: Done exporting debug data"); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensSession::handleSuccessfulCreateSession() +{ + RiaLogging::info("HoloLens: Session successfully created"); + m_isSessionValid = true; + + // Slight hack here - reaching out to the manager to update GUI + // We should really just be notifying the manager that our state has changed + RicHoloLensSessionManager::refreshToolbarState(); +} + +//-------------------------------------------------------------------------------------------------- +/// Handle the server response we receive after sending new meta data +//-------------------------------------------------------------------------------------------------- +void RicHoloLensSession::handleSuccessfulSendMetaData(int metaDataSequenceNumber) +{ + RiaLogging::info(QString("HoloLens: Processing server response to meta data (sequenceNumber=%1)").arg(metaDataSequenceNumber)); + + if (m_lastExtractionMetaDataSequenceNumber != metaDataSequenceNumber) + { + RiaLogging::warning(QString("HoloLens: Ignoring server response, the sequenceNumber(%1) has been superseded").arg(metaDataSequenceNumber)); + return; + } + + if (m_lastExtractionAllReferencedPacketIdsArr.size() > 0) + { + QByteArray combinedPacketArr; + if (!m_packetDirectory.getPacketsAsCombinedBuffer(m_lastExtractionAllReferencedPacketIdsArr, &combinedPacketArr)) + { + RiaLogging::warning("HoloLens: Error gathering the requested packets, no data will be sent"); + return; + } + + RiaLogging::info(QString("HoloLens: Sending new data to sharing server (%1 packets)").arg(m_lastExtractionAllReferencedPacketIdsArr.size())); + + m_restClient->sendBinaryData(combinedPacketArr); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensSession::handleError(const QString& errMsg, const QString& url, const QString& serverData) +{ + QString fullMsg = "HoloLens communication error: " + errMsg; + + if (!serverData.isEmpty()) + { + fullMsg += "\n serverMsg: " + serverData; + } + + fullMsg += "\n url: " + url; + + RiaLogging::error(fullMsg); +} + diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSession.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSession.h new file mode 100644 index 0000000000..09a75dbe13 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSession.h @@ -0,0 +1,71 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicHoloLensRestClient.h" + +#include "VdePacketDirectory.h" + +#include +#include + +#include + +class RimGridView; + + + +//================================================================================================== +// +// +// +//================================================================================================== +class RicHoloLensSession : public QObject, private RicHoloLensRestResponseHandler +{ +public: + ~RicHoloLensSession(); + + static RicHoloLensSession* createSession(const QString& serverUrl, const QString& sessionName); + static RicHoloLensSession* createDummyFileBackedSession(); + void destroySession(); + + bool isSessionValid() const; + + void updateSessionDataFromView(const RimGridView& activeView); + +private: + RicHoloLensSession(); + + virtual void handleSuccessfulCreateSession() override; + virtual void handleSuccessfulSendMetaData(int metaDataSequenceNumber) override; + virtual void handleError(const QString& errMsg, const QString& url, const QString& serverData) override; + +private: + bool m_isSessionValid; + QPointer m_restClient; + + int m_lastExtractionMetaDataSequenceNumber; + std::vector m_lastExtractionAllReferencedPacketIdsArr; + VdePacketDirectory m_packetDirectory; + + bool m_dbgEnableFileExport; +}; + + + diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSessionManager.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSessionManager.cpp new file mode 100644 index 0000000000..45ffe49646 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSessionManager.cpp @@ -0,0 +1,127 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensSessionManager.h" +#include "RicHoloLensSession.h" + +#include "RiaLogging.h" + +#include "cafCmdFeatureManager.h" + + + +//================================================================================================== +// +// +// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensSessionManager::RicHoloLensSessionManager() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensSessionManager* RicHoloLensSessionManager::instance() +{ + static RicHoloLensSessionManager theInstance; + return &theInstance; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensSessionManager::createSession(const QString& serverUrl, const QString& sessionName, const QString& /*sessionPinCode*/) +{ + if (m_session) + { + RiaLogging::error("Terminate existing session before creating a new session"); + return false; + } + + RiaLogging::info(QString("Creating HoloLens session: '%1', server url: %2").arg(sessionName).arg(serverUrl)); + m_session = RicHoloLensSession::createSession(serverUrl, sessionName); + + refreshToolbarState(); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensSessionManager::createDummyFileBackedSession() +{ + if (m_session) + { + RiaLogging::error("Terminate existing session before creating a new session"); + return false; + } + + m_session = RicHoloLensSession::createDummyFileBackedSession(); + RiaLogging::info("Created dummy file-backed HoloLens session"); + + refreshToolbarState(); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensSessionManager::terminateSession() +{ + if (!m_session) + { + return; + } + + RiaLogging::info("Terminating HoloLens session"); + m_session->destroySession(); + m_session->deleteLater(); + m_session = nullptr; + + refreshToolbarState(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensSession* RicHoloLensSessionManager::session() +{ + return m_session; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensSessionManager::refreshToolbarState() +{ + QStringList commandIds; + + commandIds << "RicHoloLensCreateSessionFeature"; + commandIds << "RicHoloLensExportToSharingServerFeature"; + commandIds << "RicHoloLensTerminateSessionFeature"; + + caf::CmdFeatureManager::instance()->refreshEnabledState(commandIds); +} + diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSessionManager.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSessionManager.h new file mode 100644 index 0000000000..afc0766716 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensSessionManager.h @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicHoloLensRestClient.h" + +#include + +class RicHoloLensSession; + + + +//================================================================================================== +// +// +// +//================================================================================================== +class RicHoloLensSessionManager +{ +public: + static RicHoloLensSessionManager* instance(); + + bool createSession(const QString& serverUrl, const QString& sessionName, const QString& sessionPinCode); + bool createDummyFileBackedSession(); + void terminateSession(); + + RicHoloLensSession* session(); + + static void refreshToolbarState(); + +private: + RicHoloLensSessionManager(); + +private: + QPointer m_session; +}; + diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensTerminateSessionFeature.cpp b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensTerminateSessionFeature.cpp new file mode 100644 index 0000000000..b01e19d5e3 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensTerminateSessionFeature.cpp @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicHoloLensTerminateSessionFeature.h" + +#include "RicHoloLensSessionManager.h" + +#include "RiaLogging.h" +#include "RiaQIconTools.h" + +#include + +CAF_CMD_SOURCE_INIT(RicHoloLensTerminateSessionFeature, "RicHoloLensTerminateSessionFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicHoloLensTerminateSessionFeature::isCommandEnabled() +{ + return RicHoloLensSessionManager::instance()->session() ? true : false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensTerminateSessionFeature::onActionTriggered(bool isChecked) +{ + RicHoloLensSessionManager::instance()->terminateSession(); + + RicHoloLensSessionManager::refreshToolbarState(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicHoloLensTerminateSessionFeature::setupActionLook(QAction* actionToSetup) +{ + QPixmap pixmap(":/hololens.png"); + QPixmap overlayPixmap(":/minus-sign-red.png"); + + QPixmap combinedPixmap = RiaQIconTools::appendPixmapUpperLeft(pixmap, overlayPixmap); + actionToSetup->setIcon(QIcon(combinedPixmap)); + + actionToSetup->setText("Terminate Session"); +} diff --git a/ApplicationCode/Commands/HoloLensCommands/RicHoloLensTerminateSessionFeature.h b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensTerminateSessionFeature.h new file mode 100644 index 0000000000..24cff2f896 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/RicHoloLensTerminateSessionFeature.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicHoloLensTerminateSessionFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +private: + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/VdeArrayDataPacket.cpp b/ApplicationCode/Commands/HoloLensCommands/VdeArrayDataPacket.cpp new file mode 100644 index 0000000000..111e84a389 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/VdeArrayDataPacket.cpp @@ -0,0 +1,414 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "VdeArrayDataPacket.h" + +#include +#include + + + +//================================================================================================== +// +// +// +//================================================================================================== + +// Binary package format/layout +// +// packetVersion: 2 bytes +// arrayId: 4 bytes ID of this array +// elementCount: 4 bytes number of elements in array +// elementType: 1 byte data type of each element in the array(float32=1, uint32=2, uint8=4, int8=?) +// imageComponentCount: 1 byte number of image components per pixel for texture image (currently always 0 or 3) +// imageWidth: 2 bytes only used for texture images, otherwise 0 +// imageHeight: 2 bytes : +// arrayData: ... + + +// Header offsets in bytes +static const size_t VDE_BYTEOFFSET_PACKET_VERSION = 0; +static const size_t VDE_BYTEOFFSET_ARRAY_ID = 2; +static const size_t VDE_BYTEOFFSET_ELEMENT_COUNT = 6; +static const size_t VDE_BYTEOFFSET_ELEMENT_TYPE = 10; +static const size_t VDE_BYTEOFFSET_IMAGE_COMPONENT_COUNT= 11; +static const size_t VDE_BYTEOFFSET_IMAGE_WIDTH = 12; +static const size_t VDE_BYTEOFFSET_IMAGE_HEIGHT = 14; + +// Header size in bytes +static const size_t VDE_HEADER_SIZE = 2 + 4 + 4 + 1 + 1 + 2 + 2; + +static const size_t VDE_PACKET_VERSION = 1; + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeArrayDataPacket::VdeArrayDataPacket() +: m_arrayId(-1), + m_elementType(Unknown), + m_elementCount(0), + m_imageWidth(0), + m_imageHeight(0), + m_imageComponentCount(0) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool VdeArrayDataPacket::isValid() const +{ + if (m_elementType != Unknown && + m_packetBytes.size() >= VDE_HEADER_SIZE && + m_arrayId >= 0) + { + return true; + } + else + { + return false; + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int VdeArrayDataPacket::arrayId() const +{ + return m_arrayId; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeArrayDataPacket::ElementType VdeArrayDataPacket::elementType() const +{ + return m_elementType; +} + +//-------------------------------------------------------------------------------------------------- +/// Size of each element in bytes +//-------------------------------------------------------------------------------------------------- +size_t VdeArrayDataPacket::elementSize() const +{ + return sizeOfElement(m_elementType); +} + +//-------------------------------------------------------------------------------------------------- +/// Size of specified element type in bytes +//-------------------------------------------------------------------------------------------------- +size_t VdeArrayDataPacket::sizeOfElement(ElementType elementType) +{ + switch (elementType) + { + case Unknown: return 0; + case Float32: return sizeof(float); + case Uint32: return sizeof(unsigned int); + case Uint8: return sizeof(unsigned char); + } + + return 0; +} + +//-------------------------------------------------------------------------------------------------- +/// Return number of elements in the array +//-------------------------------------------------------------------------------------------------- +size_t VdeArrayDataPacket::elementCount() const +{ + return m_elementCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const char* VdeArrayDataPacket::arrayData() const +{ + if (m_packetBytes.size() > VDE_HEADER_SIZE) + { + const char* ptr = m_packetBytes.data(); + return ptr + VDE_HEADER_SIZE; + } + else + { + return nullptr; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +unsigned short VdeArrayDataPacket::imageWidth() const +{ + return m_imageWidth; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +unsigned short VdeArrayDataPacket::imageHeight() const +{ + return m_imageHeight; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +unsigned char VdeArrayDataPacket::imageComponentCount() const +{ + return m_imageComponentCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeArrayDataPacket VdeArrayDataPacket::fromFloat32Arr(int arrayId, const float* srcArr, size_t srcArrElementCount) +{ + size_t payloadByteCount = srcArrElementCount*sizeof(float); + const char* rawSrcPtr = reinterpret_cast(srcArr); + + VdeArrayDataPacket packet; + packet.assign(arrayId, Float32, srcArrElementCount, 0, 0, 0, rawSrcPtr, payloadByteCount); + return packet; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeArrayDataPacket VdeArrayDataPacket::fromUint32Arr(int arrayId, const unsigned int* srcArr, size_t srcArrElementCount) +{ + size_t payloadByteCount = srcArrElementCount*sizeof(unsigned int); + const char* rawSrcPtr = reinterpret_cast(srcArr); + + VdeArrayDataPacket packet; + packet.assign(arrayId, Uint32, srcArrElementCount, 0, 0, 0, rawSrcPtr, payloadByteCount); + return packet; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeArrayDataPacket VdeArrayDataPacket::fromUint8ImageRGBArr(int arrayId, unsigned short imageWidth, unsigned short imageHeight, const unsigned char* srcArr, size_t srcArrElementCount) +{ + const char* rawSrcPtr = reinterpret_cast(srcArr); + + assert(3*imageWidth*imageHeight == srcArrElementCount); + + VdeArrayDataPacket packet; + packet.assign(arrayId, Uint8, srcArrElementCount, imageWidth, imageHeight, 3, rawSrcPtr, srcArrElementCount); + return packet; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeArrayDataPacket VdeArrayDataPacket::fromRawPacketBuffer(const char* rawPacketBuffer, size_t bufferSize, std::string* errString) +{ + if (bufferSize < VDE_HEADER_SIZE) + { + if (errString) *errString = "Buffer size is less than fixed header size"; + return VdeArrayDataPacket(); + } + + VdeBufferReader bufferReader(rawPacketBuffer, bufferSize); + const unsigned short packetVersion = bufferReader.getUint16(VDE_BYTEOFFSET_PACKET_VERSION); + if (packetVersion != VDE_PACKET_VERSION) + { + if (errString) *errString = "Wrong packet version"; + return VdeArrayDataPacket(); + } + + const int packetId = bufferReader.getUint32(VDE_BYTEOFFSET_ARRAY_ID); + const ElementType elementType = static_cast(bufferReader.getUint8(VDE_BYTEOFFSET_ELEMENT_TYPE)); + const size_t elementCount = bufferReader.getUint32(VDE_BYTEOFFSET_ELEMENT_COUNT); + + const unsigned char imageCompCount = bufferReader.getUint8(VDE_BYTEOFFSET_IMAGE_COMPONENT_COUNT); + const unsigned short imageWidth = bufferReader.getUint16(VDE_BYTEOFFSET_IMAGE_WIDTH); + const unsigned short imageHeight = bufferReader.getUint16(VDE_BYTEOFFSET_IMAGE_HEIGHT); + + const char* payloadPtr = rawPacketBuffer + VDE_HEADER_SIZE; + const size_t payloadSizeInBytes = bufferSize - VDE_HEADER_SIZE; + + const size_t payloadSizeInBytesFromPacketFields = elementCount*sizeOfElement(elementType); + assert(payloadSizeInBytes == payloadSizeInBytesFromPacketFields); + + VdeArrayDataPacket packet; + packet.assign(packetId, elementType, elementCount, imageWidth, imageHeight, imageCompCount, payloadPtr, payloadSizeInBytes); + + return packet; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool VdeArrayDataPacket::assign(int arrayId, ElementType elementType, size_t elementCount, unsigned short imageWidth, unsigned short imageHeight, unsigned char imageCompCount, const char* arrayDataPtr, size_t arrayDataSizeInBytes) +{ + assert(arrayDataSizeInBytes > 0); + + const size_t totalSizeBytes = VDE_HEADER_SIZE + arrayDataSizeInBytes; + m_packetBytes.resize(totalSizeBytes); + + VdeBufferWriter bufferWriter(m_packetBytes.data(), m_packetBytes.size()); + bufferWriter.setUint16(VDE_BYTEOFFSET_PACKET_VERSION, VDE_PACKET_VERSION); + bufferWriter.setUint32(VDE_BYTEOFFSET_ARRAY_ID, arrayId); + bufferWriter.setUint32(VDE_BYTEOFFSET_ELEMENT_COUNT, static_cast(elementCount)); + bufferWriter.setUint8( VDE_BYTEOFFSET_ELEMENT_TYPE, static_cast(elementType)); + bufferWriter.setUint16(VDE_BYTEOFFSET_IMAGE_COMPONENT_COUNT, imageCompCount); + bufferWriter.setUint16(VDE_BYTEOFFSET_IMAGE_WIDTH, imageWidth); + bufferWriter.setUint16(VDE_BYTEOFFSET_IMAGE_HEIGHT, imageHeight); + + const size_t calcArraySizeInBytes = elementCount*sizeOfElement(elementType); + assert(arrayDataSizeInBytes == calcArraySizeInBytes); + + std::copy(arrayDataPtr, arrayDataPtr + arrayDataSizeInBytes, m_packetBytes.begin() + VDE_HEADER_SIZE); + assert(m_packetBytes.size() == totalSizeBytes); + + m_arrayId = arrayId; + m_elementType = elementType; + m_elementCount = elementCount; + + m_imageComponentCount = imageCompCount; + m_imageWidth = imageWidth; + m_imageHeight = imageHeight; + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// Size of the complete packet, including header, in bytes +//-------------------------------------------------------------------------------------------------- +size_t VdeArrayDataPacket::fullPacketSize() const +{ + return m_packetBytes.size(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const char* VdeArrayDataPacket::fullPacketRawPtr() const +{ + return m_packetBytes.data(); +} + + + +//================================================================================================== +// +// +// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeBufferReader::VdeBufferReader(const char* buffer, size_t bufferSize) +: m_buffer(buffer), + m_bufferSize(bufferSize) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +unsigned int VdeBufferReader::getUint32(size_t byteOffset) const +{ + if (byteOffset + sizeof(unsigned int) <= m_bufferSize) + { + return *reinterpret_cast(&m_buffer[byteOffset]); + } + + return 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +unsigned short VdeBufferReader::getUint16(size_t byteOffset) const +{ + if (byteOffset + sizeof(unsigned short) <= m_bufferSize) + { + return *reinterpret_cast(&m_buffer[byteOffset]); + } + + return 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +unsigned char VdeBufferReader::getUint8(size_t byteOffset) const +{ + if (byteOffset + 1 <= m_bufferSize) + { + return *reinterpret_cast(&m_buffer[byteOffset]); + } + + return 0; +} + + + +//================================================================================================== +// +// +// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeBufferWriter::VdeBufferWriter(char* buffer, size_t bufferSize) +: m_buffer(buffer), + m_bufferSize(bufferSize) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeBufferWriter::setUint32(size_t byteOffset, unsigned int val) +{ + if (byteOffset + sizeof(unsigned int) <= m_bufferSize) + { + *reinterpret_cast(&m_buffer[byteOffset]) = val; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeBufferWriter::setUint16(size_t byteOffset, unsigned short val) +{ + if (byteOffset + sizeof(unsigned short) <= m_bufferSize) + { + *reinterpret_cast(&m_buffer[byteOffset]) = val; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeBufferWriter::setUint8(size_t byteOffset, unsigned char val) +{ + if (byteOffset + 1 <= m_bufferSize) + { + *reinterpret_cast(&m_buffer[byteOffset]) = val; + } +} + diff --git a/ApplicationCode/Commands/HoloLensCommands/VdeArrayDataPacket.h b/ApplicationCode/Commands/HoloLensCommands/VdeArrayDataPacket.h new file mode 100644 index 0000000000..dd0847a64d --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/VdeArrayDataPacket.h @@ -0,0 +1,122 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include + + +//================================================================================================== +// +// +// +//================================================================================================== +class VdeArrayDataPacket +{ +public: + enum ElementType + { + Unknown = 0, + Float32 = 1, + Uint32 = 2, + Uint8 = 4, + }; + +public: + VdeArrayDataPacket(); + + bool isValid() const; + int arrayId() const; + + ElementType elementType() const; + size_t elementSize() const; + size_t elementCount() const; + const char* arrayData() const; + + unsigned short imageWidth() const; + unsigned short imageHeight() const; + unsigned char imageComponentCount() const; + + size_t fullPacketSize() const; + const char* fullPacketRawPtr() const; + + static VdeArrayDataPacket fromFloat32Arr(int arrayId, const float* srcArr, size_t srcArrElementCount); + static VdeArrayDataPacket fromUint32Arr(int arrayId, const unsigned int* srcArr, size_t srcArrElementCount); + static VdeArrayDataPacket fromUint8ImageRGBArr(int arrayId, unsigned short imageWidth, unsigned short imageHeight, const unsigned char* srcArr, size_t srcArrElementCount); + + static VdeArrayDataPacket fromRawPacketBuffer(const char* rawPacketBuffer, size_t bufferSize, std::string* errString); + +private: + bool assign(int arrayId, ElementType elementType, size_t elementCount, unsigned short imageWidth, unsigned short imageHeight, unsigned char imageCompCount, const char* arrayDataPtr, size_t arrayDataSizeInBytes); + static size_t sizeOfElement(ElementType elementType); + +private: + int m_arrayId; + ElementType m_elementType; + size_t m_elementCount; + + unsigned short m_imageWidth; + unsigned short m_imageHeight; + unsigned char m_imageComponentCount; + + std::vector m_packetBytes; +}; + + + +//================================================================================================== +// +// +// +//================================================================================================== +class VdeBufferReader +{ +public: + VdeBufferReader(const char* buffer, size_t bufferSize); + + unsigned int getUint32(size_t byteOffset) const; + unsigned short getUint16(size_t byteOffset) const; + unsigned char getUint8(size_t byteOffset) const; + +private: + const char* m_buffer; + const size_t m_bufferSize; +}; + + +//================================================================================================== +// +// +// +//================================================================================================== +class VdeBufferWriter +{ +public: + VdeBufferWriter(char* buffer, size_t bufferSize); + + void setUint32(size_t byteOffset, unsigned int val); + void setUint16(size_t byteOffset, unsigned short val); + void setUint8(size_t byteOffset, unsigned char val); + +private: + char* m_buffer; + const size_t m_bufferSize; +}; + diff --git a/ApplicationCode/Commands/HoloLensCommands/VdeExportPart.cpp b/ApplicationCode/Commands/HoloLensCommands/VdeExportPart.cpp new file mode 100644 index 0000000000..a89544c69b --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/VdeExportPart.cpp @@ -0,0 +1,169 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "VdeExportPart.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeExportPart::VdeExportPart(cvf::Part* part) + : m_part(part) + , m_sourceObjectName("Unnamed Object") + , m_sourceObjectType(OBJ_TYPE_UNKNOWN) + , m_color(cvf::Color3f::MAGENTA) + , m_opacity(1.0) + , m_winding(COUNTERCLOCKWISE) + , m_role(GEOMETRY) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeExportPart::setTextureImage(const cvf::TextureImage* textureImage) +{ + m_textureImage = textureImage; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeExportPart::setSourceObjectType(SourceObjectType sourceObjectType) +{ + m_sourceObjectType = sourceObjectType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeExportPart::setSourceObjectName(const QString& sourceObjectName) +{ + m_sourceObjectName = sourceObjectName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeExportPart::setSourceObjectCellSetType(const QString& sourceObjectCellSetType) +{ + m_sourceObjectCellSetType = sourceObjectCellSetType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeExportPart::setColor(const cvf::Color3f& color) +{ + m_color = color; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeExportPart::setOpacity(float opacity) +{ + m_opacity = opacity; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeExportPart::setWinding(Winding winding) +{ + m_winding = winding; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeExportPart::setRole(Role role) +{ + m_role = role; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString VdeExportPart::sourceObjectName() const +{ + return m_sourceObjectName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString VdeExportPart::sourceObjectCellSetType() const +{ + return m_sourceObjectCellSetType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeExportPart::SourceObjectType VdeExportPart::sourceObjectType() const +{ + return m_sourceObjectType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const cvf::Part* VdeExportPart::part() const +{ + return m_part.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const cvf::TextureImage* VdeExportPart::textureImage() const +{ + return m_textureImage.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f VdeExportPart::color() const +{ + return m_color; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +float VdeExportPart::opacity() const +{ + return m_opacity; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeExportPart::Winding VdeExportPart::winding() const +{ + return m_winding; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeExportPart::Role VdeExportPart::role() const +{ + return m_role; +} diff --git a/ApplicationCode/Commands/HoloLensCommands/VdeExportPart.h b/ApplicationCode/Commands/HoloLensCommands/VdeExportPart.h new file mode 100644 index 0000000000..50fa469a70 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/VdeExportPart.h @@ -0,0 +1,87 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfPart.h" +#include "cvfTextureImage.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class VdeExportPart +{ +public: + enum SourceObjectType + { + OBJ_TYPE_GRID, + OBJ_TYPE_PIPE, + OBJ_TYPE_UNKNOWN + }; + + enum Winding + { + CLOCKWISE, + COUNTERCLOCKWISE + }; + + enum Role + { + GEOMETRY, + MESH_LINES + }; + +public: + VdeExportPart(cvf::Part* part); + + void setTextureImage(const cvf::TextureImage* textureImage); + void setSourceObjectType(SourceObjectType sourceObjectType); + void setSourceObjectName(const QString& sourceObjectName); + void setSourceObjectCellSetType(const QString& sourceObjectCellSetType); + void setColor(const cvf::Color3f& color); + void setOpacity(float opacity); + void setWinding(Winding winding); + void setRole(Role role); + + const cvf::Part* part() const; + const cvf::TextureImage* textureImage() const; + + QString sourceObjectName() const; + QString sourceObjectCellSetType() const; + SourceObjectType sourceObjectType() const; + cvf::Color3f color() const; + float opacity() const; + Winding winding() const; + Role role() const; + +private: + cvf::cref m_part; + cvf::cref m_textureImage; + + QString m_sourceObjectName; + QString m_sourceObjectCellSetType; + SourceObjectType m_sourceObjectType; + cvf::Color3f m_color; + float m_opacity; + Winding m_winding; + Role m_role; +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/VdeFileExporter.cpp b/ApplicationCode/Commands/HoloLensCommands/VdeFileExporter.cpp new file mode 100644 index 0000000000..9bef8b453e --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/VdeFileExporter.cpp @@ -0,0 +1,141 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "VdeFileExporter.h" +#include "VdeArrayDataPacket.h" +#include "VdePacketDirectory.h" + +#include "cvfTrace.h" + +#include +#include + + + +//================================================================================================== +// +// +// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeFileExporter::VdeFileExporter(QString absOutputFolder) +: m_absOutputFolder(absOutputFolder) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool VdeFileExporter::exportToFile(const QString& modelMetaJsonStr, const VdePacketDirectory& packetDirectory, const std::vector& packetIdsToExport) +{ + cvf::Trace::show("Exporting to folder: %s", m_absOutputFolder.toLatin1().constData()); + + QString jsonFileName = m_absOutputFolder + "/modelMeta.json"; + if (!writeModelMetaJsonFile(modelMetaJsonStr, jsonFileName)) + { + cvf::Trace::show("Error writing: %s", jsonFileName.toLatin1().constData()); + return false; + } + + for (const int packetArrayId : packetIdsToExport) + { + const VdeArrayDataPacket* dataPacket = packetDirectory.lookupPacket(packetArrayId); + if (!dataPacket) + { + cvf::Trace::show("Error during export, no data for arrayId %d", packetArrayId); + return false; + } + + CVF_ASSERT(packetArrayId == dataPacket->arrayId()); + if (!writeDataPacketToFile(dataPacket->arrayId(), *dataPacket)) + { + cvf::Trace::show("Error writing packet data to file, arrayId %d", packetArrayId); + return false; + } + } + + cvf::Trace::show("Data exported to folder: %s", m_absOutputFolder.toLatin1().constData()); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool VdeFileExporter::exportViewContents(const RimGridView& view) +{ + QString modelMetaJsonStr; + std::vector allReferencedArrayIds; + VdePacketDirectory packetDirectory; + + VdeVizDataExtractor extractor(view); + extractor.extractViewContents(&modelMetaJsonStr, &allReferencedArrayIds, &packetDirectory); + + if (!exportToFile(modelMetaJsonStr, packetDirectory, allReferencedArrayIds)) + { + return false; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool VdeFileExporter::writeDataPacketToFile(int arrayId, const VdeArrayDataPacket& packet) const +{ + const QString fileName = m_absOutputFolder + QString("/arrayData_%1.bin").arg(arrayId); + + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) + { + return false; + } + + if (file.write(packet.fullPacketRawPtr(), packet.fullPacketSize()) == -1) + { + return false; + } + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool VdeFileExporter::writeModelMetaJsonFile(const QString& modelMetaJsonStr, QString fileName) +{ + const QByteArray jsonByteArr = modelMetaJsonStr.toLatin1(); + + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) + { + return false; + } + + if (file.write(jsonByteArr) == -1) + { + return false; + } + + return true; +} + diff --git a/ApplicationCode/Commands/HoloLensCommands/VdeFileExporter.h b/ApplicationCode/Commands/HoloLensCommands/VdeFileExporter.h new file mode 100644 index 0000000000..e5435e91a0 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/VdeFileExporter.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "VdeVizDataExtractor.h" + +#include + +class VdeArrayDataPacket; +class VdePacketDirectory; + +class RimGridView; + + + +//================================================================================================== +// +// +// +//================================================================================================== +class VdeFileExporter +{ +public: + VdeFileExporter(QString absOutputFolder); + + bool exportToFile(const QString& modelMetaJsonStr, const VdePacketDirectory& packetDirectory, const std::vector& packetIdsToExport); + bool exportViewContents(const RimGridView& view); + +private: + static bool writeModelMetaJsonFile(const QString& modelMetaJsonStr, QString fileName); + bool writeDataPacketToFile(int arrayId, const VdeArrayDataPacket& packet) const; + +private: + QString m_absOutputFolder; + +}; diff --git a/ApplicationCode/Commands/HoloLensCommands/VdePacketDirectory.cpp b/ApplicationCode/Commands/HoloLensCommands/VdePacketDirectory.cpp new file mode 100644 index 0000000000..9db4a0379a --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/VdePacketDirectory.cpp @@ -0,0 +1,87 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "VdePacketDirectory.h" + + + +//================================================================================================== +// +// +// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdePacketDirectory::VdePacketDirectory() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdePacketDirectory::addPacket(const VdeArrayDataPacket& packet) +{ + const int id = packet.arrayId(); + m_idToPacketMap[id] = std::unique_ptr(new VdeArrayDataPacket(packet)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const VdeArrayDataPacket* VdePacketDirectory::lookupPacket(int arrayId) const +{ + IdToPacketMap_T::const_iterator it = m_idToPacketMap.find(arrayId); + if (it == m_idToPacketMap.end()) + { + return nullptr; + } + + return it->second.get(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdePacketDirectory::clear() +{ + m_idToPacketMap.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool VdePacketDirectory::getPacketsAsCombinedBuffer(const std::vector& packetIdsToGet, QByteArray* combinedPacketArr) const +{ + for (const int arrayId : packetIdsToGet) + { + IdToPacketMap_T::const_iterator it = m_idToPacketMap.find(arrayId); + if (it == m_idToPacketMap.end()) + { + return false; + } + + const VdeArrayDataPacket& packet = *it->second; + *combinedPacketArr += QByteArray::fromRawData(packet.fullPacketRawPtr(), static_cast(packet.fullPacketSize())); + } + + return true; +} + + diff --git a/ApplicationCode/Commands/HoloLensCommands/VdePacketDirectory.h b/ApplicationCode/Commands/HoloLensCommands/VdePacketDirectory.h new file mode 100644 index 0000000000..3f5b0123d9 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/VdePacketDirectory.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "VdeArrayDataPacket.h" + +#include + +#include +#include + + +//================================================================================================== +// +// +// +//================================================================================================== +class VdePacketDirectory +{ +public: + VdePacketDirectory(); + + void addPacket(const VdeArrayDataPacket& packet); + const VdeArrayDataPacket* lookupPacket(int arrayId) const; + void clear(); + + bool getPacketsAsCombinedBuffer(const std::vector& packetIdsToGet, QByteArray* combinedPacketArr) const; + +private: + typedef std::map> IdToPacketMap_T; + + IdToPacketMap_T m_idToPacketMap; +}; + diff --git a/ApplicationCode/Commands/HoloLensCommands/VdeVizDataExtractor.cpp b/ApplicationCode/Commands/HoloLensCommands/VdeVizDataExtractor.cpp new file mode 100644 index 0000000000..57d4541ab2 --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/VdeVizDataExtractor.cpp @@ -0,0 +1,331 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "VdeVizDataExtractor.h" +#include "VdeArrayDataPacket.h" +#include "VdePacketDirectory.h" + +#include "RicHoloLensExportImpl.h" + +#include "RifJsonEncodeDecode.h" + +#include "RiaLogging.h" + +#include "cvfDrawableGeo.h" +#include "cvfPrimitiveSet.h" +#include "cvfTransform.h" +#include "cvfTrace.h" + + + + +//================================================================================================== +// +// +// +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +VdeVizDataExtractor::VdeVizDataExtractor(const RimGridView& view) + : m_view(view) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeVizDataExtractor::extractViewContents(QString* modelMetaJsonStr, std::vector* allReferencedArrayIds, VdePacketDirectory* packetDirectory) +{ + // First extract the parts (cvfPart + info) to be exported from from the ResInsight view + const std::vector exportPartsArr = RicHoloLensExportImpl::partsForExport(m_view); + + // Convert this to an array of export ready meshes + const std::vector meshArr = buildMeshArray(exportPartsArr); + const size_t meshCount = meshArr.size(); + cvf::Trace::show("Extracting %d meshes", meshCount); + + std::vector meshArrayIdsArr; + + size_t totNumPrimitives = 0; + int nextArrayId = 0; + for (size_t i = 0; i < meshCount; i++) + { + const VdeMesh& mesh = meshArr[i]; + + const size_t primCount = mesh.connArr.size()/mesh.verticesPerPrimitive; + totNumPrimitives += primCount; + cvf::Trace::show(" %2d: primCount=%d meshSourceObjName='%s'", i, primCount, mesh.meshSourceObjName.toLatin1().constData()); + + VdeMeshArrayIds meshArrayIds; + + { + cvf::Trace::show(" exporting vertices"); + meshArrayIds.vertexArrId = nextArrayId++; + const float* floatArr = reinterpret_cast(mesh.vertexArr->ptr()); + VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromFloat32Arr(meshArrayIds.vertexArrId, floatArr, 3*mesh.vertexArr->size()); + packetDirectory->addPacket(dataPacket); + + // Debug testing of decoding + debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr)); + } + { + cvf::Trace::show(" exporting connectivities"); + meshArrayIds.connArrId = nextArrayId++; + const unsigned int* uintArr = mesh.connArr.data(); + VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromUint32Arr(meshArrayIds.connArrId, uintArr, mesh.connArr.size()); + packetDirectory->addPacket(dataPacket); + + // Debug testing of decoding + debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr)); + } + + if (mesh.texCoordArr.notNull() && mesh.texImage.notNull()) + { + { + cvf::Trace::show(" exporting texture coords"); + meshArrayIds.texCoordsArrId = nextArrayId++; + const float* floatArr = reinterpret_cast(mesh.texCoordArr->ptr()); + VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromFloat32Arr(meshArrayIds.texCoordsArrId, floatArr, 2*mesh.texCoordArr->size()); + packetDirectory->addPacket(dataPacket); + + // Debug testing of decoding + debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr)); + } + { + cvf::Trace::show(" exporting texture image"); + meshArrayIds.texImageArrId = nextArrayId++; + cvf::ref byteArr = mesh.texImage->toRgb(); + VdeArrayDataPacket dataPacket = VdeArrayDataPacket::fromUint8ImageRGBArr(meshArrayIds.texImageArrId, mesh.texImage->width(), mesh.texImage->height(), byteArr->ptr(), byteArr->size()); + packetDirectory->addPacket(dataPacket); + + // Debug testing of decoding + debugComparePackets(dataPacket, VdeArrayDataPacket::fromRawPacketBuffer(dataPacket.fullPacketRawPtr(), dataPacket.fullPacketSize(), nullptr)); + } + } + + meshArrayIdsArr.push_back(meshArrayIds); + } + + cvf::Trace::show("Total number of primitives extracted: %d", totNumPrimitives); + + + *modelMetaJsonStr = createModelMetaJsonString(meshArr, meshArrayIdsArr); + + // Find all unique packet array IDs referenced + std::set referencedIdsSet; + for (const VdeMeshArrayIds& meshArrayIds : meshArrayIdsArr) + { + if (meshArrayIds.vertexArrId != -1) referencedIdsSet.insert(meshArrayIds.vertexArrId); + if (meshArrayIds.connArrId != -1) referencedIdsSet.insert(meshArrayIds.connArrId); + if (meshArrayIds.texImageArrId != -1) referencedIdsSet.insert(meshArrayIds.texImageArrId); + if (meshArrayIds.texCoordsArrId != -1) referencedIdsSet.insert(meshArrayIds.texCoordsArrId); + } + + allReferencedArrayIds->assign(referencedIdsSet.begin(), referencedIdsSet.end()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector VdeVizDataExtractor::buildMeshArray(const std::vector& exportPartsArr) +{ + std::vector meshArr; + for (const VdeExportPart& exportPart : exportPartsArr) + { + VdeMesh mesh; + if (extractMeshFromExportPart(exportPart, &mesh)) + { + meshArr.push_back(mesh); + } + } + + return meshArr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool VdeVizDataExtractor::extractMeshFromExportPart(const VdeExportPart& exportPart, VdeMesh* mesh) +{ + const cvf::Part* cvfPart = exportPart.part(); + const cvf::DrawableGeo* geo = dynamic_cast(cvfPart ? cvfPart->drawable() : nullptr); + if (!geo) + { + return false; + } + + if (geo->primitiveSetCount() != 1) + { + RiaLogging::debug("Only geometries with exactly one primitive set is supported"); + return false; + } + + const cvf::Vec3fArray* vertexArr = geo->vertexArray(); + const cvf::PrimitiveSet* primSet = geo->primitiveSet(0); + if (!vertexArr || !primSet || primSet->faceCount() == 0) + { + return false; + } + + + // Support 2 or 3 vertices per primitive + const cvf::PrimitiveType primType = primSet->primitiveType(); + if (primType != cvf::PT_TRIANGLES && primType != cvf::PT_LINES) + { + RiaLogging::debug(QString("Currently only triangle and line primitive sets are supported (saw primitive type: %1)").arg(primType)); + return false; + } + + const int vertsPerPrimitive = (primType == cvf::PT_TRIANGLES) ? 3 : 2; + + mesh->verticesPerPrimitive = vertsPerPrimitive; + + // Possibly transform the vertices + if (cvfPart->transform()) + { + const size_t vertexCount = vertexArr->size(); + cvf::ref transVertexArr = new cvf::Vec3fArray(vertexArr->size()); + + cvf::Mat4f m = cvf::Mat4f(cvfPart->transform()->worldTransform()); + for (size_t i = 0; i < vertexCount; i++) + { + transVertexArr->set(i, vertexArr->get(i).getTransformedPoint(m)); + } + + mesh->vertexArr = transVertexArr.p(); + } + else + { + mesh->vertexArr = vertexArr; + } + + // Fetch connectivities + // Using getFaceIndices() allows us to access strips and fans in the same way as triangles + // Note that HoloLens visualization wants triangles in clockwise order so we try and fix the winding + // This point might be moot if the HoloLens visualization always has to use two-sideded lighting to get good results + cvf::UIntArray faceConn; + const size_t faceCount = primSet->faceCount(); + for (size_t iface = 0; iface < faceCount; iface++) + { + primSet->getFaceIndices(iface, &faceConn); + + if (vertsPerPrimitive == 3 && exportPart.winding() == VdeExportPart::COUNTERCLOCKWISE) + { + // Reverse the winding + const size_t numConn = faceConn.size(); + for (size_t i = 0; i < numConn; i++) + { + mesh->connArr.push_back(faceConn[numConn - i - 1]); + } + } + else + { + mesh->connArr.insert(mesh->connArr.end(), faceConn.begin(), faceConn.end()); + } + } + + + if (exportPart.textureImage() && geo->textureCoordArray()) + { + mesh->texCoordArr = geo->textureCoordArray(); + mesh->texImage = exportPart.textureImage(); + } + + + QString srcObjType = "unknown"; + if (exportPart.sourceObjectType() == VdeExportPart::OBJ_TYPE_GRID) srcObjType = "grid"; + else if (exportPart.sourceObjectType() == VdeExportPart::OBJ_TYPE_PIPE) srcObjType = "pipe"; + mesh->meshSourceObjTypeStr = srcObjType; + + mesh->meshSourceObjName = exportPart.sourceObjectName(); + + mesh->color = exportPart.color(); + mesh->opacity = exportPart.opacity(); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString VdeVizDataExtractor::createModelMetaJsonString(const std::vector& meshArr, const std::vector& meshContentIdsArr) +{ + QVariantList jsonMeshMetaList; + + for (size_t i = 0; i < meshArr.size(); i++) + { + const VdeMesh& mesh = meshArr[i]; + const VdeMeshArrayIds& meshIds = meshContentIdsArr[i]; + + QMap jsonMeshMeta; + jsonMeshMeta["meshSourceObjType"] = mesh.meshSourceObjTypeStr; + jsonMeshMeta["meshSourceObjName"] = mesh.meshSourceObjName; + + jsonMeshMeta["verticesPerPrimitive"] = mesh.verticesPerPrimitive; + jsonMeshMeta["vertexArrId"] = meshIds.vertexArrId; + jsonMeshMeta["connArrId"] = meshIds.connArrId; + + if (meshIds.texCoordsArrId >= 0 && meshIds.texImageArrId >= 0) + { + jsonMeshMeta["texCoordsArrId"] = meshIds.texCoordsArrId; + jsonMeshMeta["texImageArrId"] = meshIds.texImageArrId; + } + else + { + QMap jsonColor; + jsonColor["r"] = mesh.color.r(); + jsonColor["g"] = mesh.color.g(); + jsonColor["b"] = mesh.color.b(); + + jsonMeshMeta["color"] = jsonColor; + } + + jsonMeshMeta["opacity"] = mesh.opacity; + + jsonMeshMetaList.push_back(jsonMeshMeta); + } + + QMap jsonModelMeta; + jsonModelMeta["modelName"] = "ResInsightExport"; + jsonModelMeta["meshArr"] = jsonMeshMetaList; + + ResInsightInternalJson::Json jsonCodec; + const bool prettifyJson = true; + QString jsonStr = jsonCodec.encode(jsonModelMeta, prettifyJson); + return jsonStr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void VdeVizDataExtractor::debugComparePackets(const VdeArrayDataPacket& packetA, const VdeArrayDataPacket& packetB) +{ + CVF_ASSERT(packetA.elementCount() == packetB.elementCount()); + CVF_ASSERT(packetA.elementSize() == packetB.elementSize()); + CVF_ASSERT(packetA.elementType() == packetB.elementType()); + + const char* arrA = packetA.arrayData(); + const char* arrB = packetB.arrayData(); + for (size_t i = 0; i < packetA.elementCount(); i++) + { + CVF_ASSERT(arrA[i] == arrB[i]); + } +} + diff --git a/ApplicationCode/Commands/HoloLensCommands/VdeVizDataExtractor.h b/ApplicationCode/Commands/HoloLensCommands/VdeVizDataExtractor.h new file mode 100644 index 0000000000..42f6afc3da --- /dev/null +++ b/ApplicationCode/Commands/HoloLensCommands/VdeVizDataExtractor.h @@ -0,0 +1,105 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfColor3.h" +#include "cvfArray.h" +#include "cvfTextureImage.h" + +#include + +class VdeArrayDataPacket; +class VdePacketDirectory; +class VdeExportPart; + +class RimGridView; + + + +//================================================================================================== +// +// +// +//================================================================================================== +struct VdeMesh +{ + QString meshSourceObjTypeStr; + QString meshSourceObjName; + + cvf::Color3f color; + float opacity; + + int verticesPerPrimitive; + cvf::cref vertexArr; + cvf::cref texCoordArr; + std::vector connArr; + cvf::cref texImage; + + VdeMesh() + : color(1,1,1), + opacity(1), + verticesPerPrimitive(-1) + {} +}; + + +//================================================================================================== +// +// +// +//================================================================================================== +struct VdeMeshArrayIds +{ + int vertexArrId; + int connArrId; + int texImageArrId; + int texCoordsArrId; + + VdeMeshArrayIds() + : vertexArrId(-1), + connArrId(-1), + texImageArrId(-1), + texCoordsArrId(-1) + {} +}; + + +//================================================================================================== +// +// +// +//================================================================================================== +class VdeVizDataExtractor +{ +public: + VdeVizDataExtractor(const RimGridView& view); + + void extractViewContents(QString* modelMetaJsonStr, std::vector* allReferencedArrayIds, VdePacketDirectory* packetDirectory); + +private: + static std::vector buildMeshArray(const std::vector& exportPartsArr); + static bool extractMeshFromExportPart(const VdeExportPart& exportPart, VdeMesh* mesh); + static QString createModelMetaJsonString(const std::vector& meshArr, const std::vector& meshContentIdsArr); + static void debugComparePackets(const VdeArrayDataPacket& packetA, const VdeArrayDataPacket& packetB); + +private: + const RimGridView& m_view; + +}; diff --git a/ApplicationCode/Commands/IntersectionBoxCommands/RicAppendIntersectionBoxFeature.h b/ApplicationCode/Commands/IntersectionBoxCommands/RicAppendIntersectionBoxFeature.h index 78ae599703..adc196fcdb 100644 --- a/ApplicationCode/Commands/IntersectionBoxCommands/RicAppendIntersectionBoxFeature.h +++ b/ApplicationCode/Commands/IntersectionBoxCommands/RicAppendIntersectionBoxFeature.h @@ -33,9 +33,9 @@ class RicAppendIntersectionBoxFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static RimIntersectionCollection* intersectionCollection(); diff --git a/ApplicationCode/Commands/IntersectionBoxCommands/RicBoxManipulatorEventHandler.h b/ApplicationCode/Commands/IntersectionBoxCommands/RicBoxManipulatorEventHandler.h index 974b11a579..fcede0b889 100644 --- a/ApplicationCode/Commands/IntersectionBoxCommands/RicBoxManipulatorEventHandler.h +++ b/ApplicationCode/Commands/IntersectionBoxCommands/RicBoxManipulatorEventHandler.h @@ -52,7 +52,7 @@ class RicBoxManipulatorEventHandler : public QObject public: explicit RicBoxManipulatorEventHandler(caf::Viewer* viewer); - ~RicBoxManipulatorEventHandler(); + ~RicBoxManipulatorEventHandler() override; void setOrigin(const cvf::Vec3d& origin); void setSize(const cvf::Vec3d& size); @@ -64,7 +64,7 @@ class RicBoxManipulatorEventHandler : public QObject void notifyUpdate(const cvf::Vec3d& origin, const cvf::Vec3d& size); protected: - bool eventFilter(QObject *obj, QEvent *event); + bool eventFilter(QObject *obj, QEvent *event) override; private: QPointer m_viewer; diff --git a/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxAtPosFeature.h b/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxAtPosFeature.h index 6d19d42db6..3c0a84d65f 100644 --- a/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxAtPosFeature.h +++ b/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxAtPosFeature.h @@ -32,8 +32,8 @@ class RicIntersectionBoxAtPosFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxXSliceFeature.h b/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxXSliceFeature.h index de3fce08a7..70964507f9 100644 --- a/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxXSliceFeature.h +++ b/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxXSliceFeature.h @@ -32,8 +32,8 @@ class RicIntersectionBoxXSliceFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxYSliceFeature.h b/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxYSliceFeature.h index 071db4eb64..e638361d01 100644 --- a/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxYSliceFeature.h +++ b/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxYSliceFeature.h @@ -32,8 +32,8 @@ class RicIntersectionBoxYSliceFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxZSliceFeature.h b/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxZSliceFeature.h index a229089234..2b03793ff5 100644 --- a/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxZSliceFeature.h +++ b/ApplicationCode/Commands/IntersectionBoxCommands/RicIntersectionBoxZSliceFeature.h @@ -32,8 +32,8 @@ class RicIntersectionBoxZSliceFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicAddScriptPathFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicAddScriptPathFeature.h index e436a7b781..093f6c46a2 100644 --- a/ApplicationCode/Commands/OctaveScriptCommands/RicAddScriptPathFeature.h +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicAddScriptPathFeature.h @@ -32,9 +32,9 @@ class RicAddScriptPathFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.cpp b/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.cpp index 745dc7d3ef..a1d1ba84aa 100644 --- a/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.cpp +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.cpp @@ -49,7 +49,7 @@ bool RicDeleteScriptPathFeature::isCommandEnabled() void RicDeleteScriptPathFeature::onActionTriggered(bool isChecked) { std::vector calcScriptCollections = RicScriptFeatureImpl::selectedScriptCollections(); - RimScriptCollection* scriptCollection = calcScriptCollections.size() > 0 ? calcScriptCollections[0] : NULL; + RimScriptCollection* scriptCollection = calcScriptCollections.size() > 0 ? calcScriptCollections[0] : nullptr; if (scriptCollection) { QString toBeRemoved = scriptCollection->directory; diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.h index 236e0de4a6..cb19e0e4eb 100644 --- a/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.h +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicDeleteScriptPathFeature.h @@ -32,9 +32,9 @@ class RicDeleteScriptPathFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicEditScriptFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicEditScriptFeature.h index b9ca5599e0..7d3730ba50 100644 --- a/ApplicationCode/Commands/OctaveScriptCommands/RicEditScriptFeature.h +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicEditScriptFeature.h @@ -32,9 +32,9 @@ class RicEditScriptFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptFeature.h index 82a5d68bed..11328e065f 100644 --- a/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptFeature.h +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptFeature.h @@ -32,9 +32,9 @@ class RicExecuteScriptFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptForCasesFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptForCasesFeature.h index 8f72dabbb5..24d0f740d1 100644 --- a/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptForCasesFeature.h +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicExecuteScriptForCasesFeature.h @@ -32,9 +32,9 @@ class RicExecuteScriptForCasesFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.cpp b/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.cpp index c9a5e480e3..47df7d2f4b 100644 --- a/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.cpp +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.cpp @@ -56,8 +56,8 @@ void RicNewScriptFeature::onActionTriggered(bool isChecked) std::vector calcScripts = RicScriptFeatureImpl::selectedScripts(); std::vector calcScriptCollections = RicScriptFeatureImpl::selectedScriptCollections(); - RimCalcScript* calcScript = calcScripts.size() > 0 ? calcScripts[0] : NULL; - RimScriptCollection* scriptColl = calcScriptCollections.size() > 0 ? calcScriptCollections[0] : NULL; + RimCalcScript* calcScript = calcScripts.size() > 0 ? calcScripts[0] : nullptr; + RimScriptCollection* scriptColl = calcScriptCollections.size() > 0 ? calcScriptCollections[0] : nullptr; QString fullPathNewScript; diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.h index 37f7bda90b..24e2194bb8 100644 --- a/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.h +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicNewScriptFeature.h @@ -32,9 +32,9 @@ class RicNewScriptFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/OctaveScriptCommands/RicRefreshScriptsFeature.h b/ApplicationCode/Commands/OctaveScriptCommands/RicRefreshScriptsFeature.h index 1cc49eab7d..8ed791b6bf 100644 --- a/ApplicationCode/Commands/OctaveScriptCommands/RicRefreshScriptsFeature.h +++ b/ApplicationCode/Commands/OctaveScriptCommands/RicRefreshScriptsFeature.h @@ -34,9 +34,9 @@ class RicRefreshScriptsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicCopyReferencesToClipboardFeature.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicCopyReferencesToClipboardFeature.h index ff1b55f966..57c0b5b2d0 100644 --- a/ApplicationCode/Commands/OperationsUsingObjReferences/RicCopyReferencesToClipboardFeature.h +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicCopyReferencesToClipboardFeature.h @@ -36,9 +36,9 @@ class RicCopyReferencesToClipboardFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static bool isAnyCopyableObjectSelected(); diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicCutReferencesToClipboardFeature.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicCutReferencesToClipboardFeature.h index cb621c4c9b..0f92238733 100644 --- a/ApplicationCode/Commands/OperationsUsingObjReferences/RicCutReferencesToClipboardFeature.h +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicCutReferencesToClipboardFeature.h @@ -34,9 +34,9 @@ class RicCutReferencesToClipboardFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; static bool isAnyCuttableObjectSelected(); static bool isCuttingOfObjectSupported(caf::PdmObject* pdmObject); diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.h index 5a1ed65387..19cc781b43 100644 --- a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.h +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseCasesFeature.h @@ -42,7 +42,7 @@ class RicPasteEclipseCasesFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.cpp b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.cpp index 95036187b7..599ea900d4 100644 --- a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.cpp +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.cpp @@ -92,8 +92,8 @@ void RicPasteEclipseViewsFeature::onActionTriggered(bool isChecked) RimEclipseView* rimReservoirView = dynamic_cast(eclipseViews[i]->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); CVF_ASSERT(rimReservoirView); - QString nameOfCopy = QString("Copy of ") + rimReservoirView->name; - rimReservoirView->name = nameOfCopy; + QString nameOfCopy = QString("Copy of ") + rimReservoirView->name(); + rimReservoirView->setName(nameOfCopy); eclipseCase->reservoirViews().push_back(rimReservoirView); rimReservoirView->setEclipseCase(eclipseCase); diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.h index 3f0b0ca454..598124891e 100644 --- a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.h +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteEclipseViewsFeature.h @@ -33,8 +33,8 @@ CAF_CMD_HEADER_INIT; protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.cpp b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.cpp index 470373dffa..62b273bbd4 100644 --- a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.cpp +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.cpp @@ -84,8 +84,8 @@ void RicPasteGeoMechViewsFeature::onActionTriggered(bool isChecked) for (size_t i = 0; i < geomViews.size(); i++) { RimGeoMechView* rimReservoirView = dynamic_cast(geomViews[i]->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); - QString nameOfCopy = QString("Copy of ") + rimReservoirView->name; - rimReservoirView->name = nameOfCopy; + QString nameOfCopy = QString("Copy of ") + rimReservoirView->name(); + rimReservoirView->setName(nameOfCopy); geomCase->geoMechViews().push_back(rimReservoirView); rimReservoirView->setGeoMechCase(geomCase); diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.h index 143534f8e6..a4f544fc2f 100644 --- a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.h +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteGeoMechViewsFeature.h @@ -31,7 +31,7 @@ CAF_CMD_HEADER_INIT; protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteIntersectionsFeature.h b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteIntersectionsFeature.h index 15a770b7b7..47b749c38b 100644 --- a/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteIntersectionsFeature.h +++ b/ApplicationCode/Commands/OperationsUsingObjReferences/RicPasteIntersectionsFeature.h @@ -32,9 +32,9 @@ class RicPasteIntersectionsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; private: static RimIntersectionCollection* findIntersectionCollection(caf::PdmObjectHandle* objectHandle); diff --git a/ApplicationCode/Commands/RicCloseCaseFeature.cpp b/ApplicationCode/Commands/RicCloseCaseFeature.cpp index 0fb3100b0c..c95cced44f 100644 --- a/ApplicationCode/Commands/RicCloseCaseFeature.cpp +++ b/ApplicationCode/Commands/RicCloseCaseFeature.cpp @@ -60,7 +60,6 @@ bool RicCloseCaseFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicCloseCaseFeature::onActionTriggered(bool isChecked) { - std::vector rimCases = selectedCases(); std::vector eclipseCases; std::vector geoMechCases; for (RimCase* rimCase : selectedCases()) diff --git a/ApplicationCode/Commands/RicCloseCaseFeature.h b/ApplicationCode/Commands/RicCloseCaseFeature.h index fd8224dcb9..e7d370e8f5 100644 --- a/ApplicationCode/Commands/RicCloseCaseFeature.h +++ b/ApplicationCode/Commands/RicCloseCaseFeature.h @@ -41,9 +41,9 @@ class RicCloseCaseFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: std::vector selectedCases() const; diff --git a/ApplicationCode/Commands/RicCloseObservedDataFeature.h b/ApplicationCode/Commands/RicCloseObservedDataFeature.h index e4ee40dcce..815606540d 100644 --- a/ApplicationCode/Commands/RicCloseObservedDataFeature.h +++ b/ApplicationCode/Commands/RicCloseObservedDataFeature.h @@ -35,7 +35,7 @@ class RicCloseObservedDataFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/RicCloseSourSimDataFeature.h b/ApplicationCode/Commands/RicCloseSourSimDataFeature.h index fb46e6f44e..589cb59083 100644 --- a/ApplicationCode/Commands/RicCloseSourSimDataFeature.h +++ b/ApplicationCode/Commands/RicCloseSourSimDataFeature.h @@ -31,9 +31,9 @@ class RicCloseSourSimDataFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static RimEclipseResultCase* getSelectedEclipseCase(); diff --git a/ApplicationCode/Commands/RicCloseSummaryCaseFeature.cpp b/ApplicationCode/Commands/RicCloseSummaryCaseFeature.cpp index 8471ef0cd7..7ac41e2ea1 100644 --- a/ApplicationCode/Commands/RicCloseSummaryCaseFeature.cpp +++ b/ApplicationCode/Commands/RicCloseSummaryCaseFeature.cpp @@ -30,6 +30,7 @@ #include "RiuPlotMainWindow.h" +#include "cafAsyncObjectDeleter.h" #include "cafSelectionManager.h" #include "cvfAssert.h" @@ -50,9 +51,10 @@ void RicCloseSummaryCaseFeature::setupActionLook(QAction* actionToSetup) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicCloseSummaryCaseFeature::deleteSummaryCases(const std::vector& cases) +void RicCloseSummaryCaseFeature::deleteSummaryCases(std::vector& cases) { RimSummaryPlotCollection* summaryPlotColl = RiaSummaryTools::summaryPlotCollection(); + RimSummaryCaseMainCollection* summaryCaseMainCollection = RiaSummaryTools::summaryCaseMainCollection(); for (RimSummaryCase* summaryCase : cases) { @@ -62,17 +64,16 @@ void RicCloseSummaryCaseFeature::deleteSummaryCases(const std::vectorupdateConnectedEditors(); - RimSummaryCaseMainCollection* summaryCaseMainCollection = nullptr; - summaryCase->firstAncestorOrThisOfTypeAsserted(summaryCaseMainCollection); - summaryCaseMainCollection->removeCase(summaryCase); - delete summaryCase; - - summaryCaseMainCollection->updateAllRequiredEditors(); } + summaryCaseMainCollection->updateAllRequiredEditors(); + RiuPlotMainWindow* mainPlotWindow = RiaApplication::instance()->mainPlotWindow(); mainPlotWindow->updateSummaryPlotToolBar(); + + caf::AsyncPdmObjectVectorDeleter summaryCaseDeleter(cases); + CAF_ASSERT(cases.empty()); // vector should be empty immediately. } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/RicCloseSummaryCaseFeature.h b/ApplicationCode/Commands/RicCloseSummaryCaseFeature.h index d987aba447..12937d8387 100644 --- a/ApplicationCode/Commands/RicCloseSummaryCaseFeature.h +++ b/ApplicationCode/Commands/RicCloseSummaryCaseFeature.h @@ -32,11 +32,11 @@ class RicCloseSummaryCaseFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; public: - static void deleteSummaryCases(const std::vector& cases); + static void deleteSummaryCases(std::vector& cases); protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/RicCloseSummaryCaseInCollectionFeature.cpp b/ApplicationCode/Commands/RicCloseSummaryCaseInCollectionFeature.cpp index efe1de1016..7a6429ee31 100644 --- a/ApplicationCode/Commands/RicCloseSummaryCaseInCollectionFeature.cpp +++ b/ApplicationCode/Commands/RicCloseSummaryCaseInCollectionFeature.cpp @@ -22,6 +22,7 @@ #include "RicCloseSummaryCaseFeature.h" +#include "RimDerivedEnsembleCaseCollection.h" #include "RimMainPlotCollection.h" #include "RimProject.h" #include "RimSummaryCase.h" @@ -62,6 +63,11 @@ bool RicCloseSummaryCaseInCollectionFeature::isCommandEnabled() std::vector summaryCaseCollections; caf::SelectionManager::instance()->objectsByType(&summaryCaseCollections); + summaryCaseCollections.erase(std::remove_if(summaryCaseCollections.begin(), summaryCaseCollections.end(), [](RimSummaryCaseCollection* coll) + { + return dynamic_cast(coll) != nullptr; + }), summaryCaseCollections.end()); + return (summaryCaseMainCollections.size() > 0 || summaryCaseCollections.size() > 0); } @@ -75,7 +81,8 @@ void RicCloseSummaryCaseInCollectionFeature::onActionTriggered(bool isChecked) if (summaryCaseMainCollections.size() > 0) { - RicCloseSummaryCaseFeature::deleteSummaryCases(summaryCaseMainCollections[0]->allSummaryCases()); + std::vector allSummaryCases = summaryCaseMainCollections[0]->allSummaryCases(); + RicCloseSummaryCaseFeature::deleteSummaryCases(allSummaryCases); } std::vector summaryCaseCollections; @@ -83,7 +90,8 @@ void RicCloseSummaryCaseInCollectionFeature::onActionTriggered(bool isChecked) for (RimSummaryCaseCollection* summaryCaseCollection : summaryCaseCollections) { - RicCloseSummaryCaseFeature::deleteSummaryCases(summaryCaseCollection->allSummaryCases()); + std::vector collectionSummaryCases = summaryCaseCollection->allSummaryCases(); + RicCloseSummaryCaseFeature::deleteSummaryCases(collectionSummaryCases); } RiuPlotMainWindow* mainPlotWindow = RiaApplication::instance()->mainPlotWindow(); diff --git a/ApplicationCode/Commands/RicCloseSummaryCaseInCollectionFeature.h b/ApplicationCode/Commands/RicCloseSummaryCaseInCollectionFeature.h index 2e28208843..e8de6f88ae 100644 --- a/ApplicationCode/Commands/RicCloseSummaryCaseInCollectionFeature.h +++ b/ApplicationCode/Commands/RicCloseSummaryCaseInCollectionFeature.h @@ -28,7 +28,7 @@ class RicCloseSummaryCaseInCollectionFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/RicContourMapPickEventHandler.cpp b/ApplicationCode/Commands/RicContourMapPickEventHandler.cpp new file mode 100644 index 0000000000..de6b22eedf --- /dev/null +++ b/ApplicationCode/Commands/RicContourMapPickEventHandler.cpp @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicContourMapPickEventHandler.h" +#include "RimContourMapProjection.h" +#include "RimContourMapView.h" +#include "RimEclipseCellColors.h" +#include "Rim3dView.h" + +#include "RiuMainWindow.h" +#include "RivObjectSourceInfo.h" + +#include "cafDisplayCoordTransform.h" + +#include "cvfPart.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicContourMapPickEventHandler* RicContourMapPickEventHandler::instance() +{ + static RicContourMapPickEventHandler* singleton = new RicContourMapPickEventHandler; + return singleton; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicContourMapPickEventHandler::handlePickEvent(const Ric3DPickEvent& eventObject) +{ + if (eventObject.m_pickItemInfos.empty()) return false; + + const RiuPickItemInfo& firstPickedItem = eventObject.m_pickItemInfos.front(); + const cvf::Part* firstPickedPart = firstPickedItem.pickedPart(); + + const RivObjectSourceInfo* sourceInfo = dynamic_cast(firstPickedPart->sourceInfo()); + if (sourceInfo) + { + RimContourMapProjection* contourMap = dynamic_cast(sourceInfo->object()); + if (contourMap) + { + RiuMainWindow::instance()->selectAsCurrentItem(contourMap); + + RimContourMapView* view = nullptr; + contourMap->firstAncestorOrThisOfTypeAsserted(view); + + cvf::Vec2d pickedPoint; + cvf::Vec2ui pickedCell; + double valueAtPoint = 0.0; + if (contourMap->checkForMapIntersection(firstPickedItem.globalPickedPoint(), &pickedPoint, &pickedCell, &valueAtPoint)) + { + QString curveText; + curveText += QString("%1\n").arg(view->createAutoName()); + curveText += QString("Picked Point X, Y: %1, %2\n").arg(pickedPoint.x(), 5, 'f', 0).arg(pickedPoint.y(), 5, 'f', 0); + curveText += QString("Picked Cell I, J: %1, %2\n").arg(pickedCell.x()).arg(pickedCell.y()); + curveText += QString("Result Type: %1\n").arg(contourMap->resultDescriptionText()); + curveText += QString("Aggregated Value: %1\n").arg(valueAtPoint); + + RiuMainWindow::instance()->setResultInfo(curveText); + + contourMap->setPickPoint(pickedPoint); + view->updateCurrentTimeStepAndRedraw(); + return true; + } + contourMap->setPickPoint(cvf::Vec2d::UNDEFINED); + view->updateCurrentTimeStepAndRedraw(); + return true; + } + } + return false; +} + diff --git a/ApplicationCode/Commands/RicContourMapPickEventHandler.h b/ApplicationCode/Commands/RicContourMapPickEventHandler.h new file mode 100644 index 0000000000..cb9c1e6457 --- /dev/null +++ b/ApplicationCode/Commands/RicContourMapPickEventHandler.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicPickEventHandler.h" + +//================================================================================================== +/// +//================================================================================================== +class RicContourMapPickEventHandler : public RicDefaultPickEventHandler +{ +public: + static RicContourMapPickEventHandler* instance(); + +protected: + bool handlePickEvent(const Ric3DPickEvent& eventObject) override; +}; + diff --git a/ApplicationCode/Commands/RicConvertGroupToEnsembleFeature.cpp b/ApplicationCode/Commands/RicConvertGroupToEnsembleFeature.cpp index 628f42bdd4..3f1e64d3eb 100644 --- a/ApplicationCode/Commands/RicConvertGroupToEnsembleFeature.cpp +++ b/ApplicationCode/Commands/RicConvertGroupToEnsembleFeature.cpp @@ -76,7 +76,6 @@ void RicConvertGroupToEnsembleFeature::onActionTriggered(bool isChecked) { if (group->isEnsemble()) continue; - RicImportEnsembleFeature::validateEnsembleCases(group->allSummaryCases()); group->setAsEnsemble(true); } } diff --git a/ApplicationCode/Commands/RicConvertGroupToEnsembleFeature.h b/ApplicationCode/Commands/RicConvertGroupToEnsembleFeature.h index f27f883ac0..33ea70af28 100644 --- a/ApplicationCode/Commands/RicConvertGroupToEnsembleFeature.h +++ b/ApplicationCode/Commands/RicConvertGroupToEnsembleFeature.h @@ -37,9 +37,9 @@ class RicConvertGroupToEnsembleFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicCreateSummaryCaseCollectionFeature.cpp b/ApplicationCode/Commands/RicCreateSummaryCaseCollectionFeature.cpp index 7e0ac8a2e0..5100018ba9 100644 --- a/ApplicationCode/Commands/RicCreateSummaryCaseCollectionFeature.cpp +++ b/ApplicationCode/Commands/RicCreateSummaryCaseCollectionFeature.cpp @@ -36,19 +36,20 @@ CAF_CMD_SOURCE_INIT(RicCreateSummaryCaseCollectionFeature, "RicCreateSummaryCase //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicCreateSummaryCaseCollectionFeature::groupSummaryCases(std::vector cases, const QString& groupName, bool isEnsemble) +RimSummaryCaseCollection* RicCreateSummaryCaseCollectionFeature::groupSummaryCases(std::vector cases, const QString& groupName, bool isEnsemble) { RimSummaryCaseMainCollection* summaryCaseMainCollection = nullptr; if (!cases.empty()) { cases[0]->firstAncestorOrThisOfTypeAsserted(summaryCaseMainCollection); - summaryCaseMainCollection->addCaseCollection(cases, groupName, isEnsemble); + auto newGroup = summaryCaseMainCollection->addCaseCollection(cases, groupName, isEnsemble); summaryCaseMainCollection->updateConnectedEditors(); RiuPlotMainWindowTools::showPlotMainWindow(); - RiuPlotMainWindowTools::selectAsCurrentItem(summaryCaseMainCollection->summaryCaseCollections().back()->allSummaryCases().front()); + return newGroup; } + return nullptr; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/RicCreateSummaryCaseCollectionFeature.h b/ApplicationCode/Commands/RicCreateSummaryCaseCollectionFeature.h index eb8a1fbb78..90f4dc3629 100644 --- a/ApplicationCode/Commands/RicCreateSummaryCaseCollectionFeature.h +++ b/ApplicationCode/Commands/RicCreateSummaryCaseCollectionFeature.h @@ -23,6 +23,7 @@ #include class RimSummaryCase; +class RimSummaryCaseCollection; //================================================================================================== /// @@ -31,10 +32,10 @@ class RicCreateSummaryCaseCollectionFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; - static void groupSummaryCases(std::vector cases, const QString& groupName, bool isEnsemble = false); + static RimSummaryCaseCollection* groupSummaryCases(std::vector cases, const QString& groupName, bool isEnsemble = false); private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.cpp b/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.cpp new file mode 100644 index 0000000000..080d6c3c69 --- /dev/null +++ b/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.cpp @@ -0,0 +1,355 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicCreateTemporaryLgrFeature.h" + +#include "RiaApplication.h" +#include "RiaCellDividingTools.h" +#include "RiaCompletionTypeCalculationScheduler.h" +#include "RiaLogging.h" + +#include "RicDeleteTemporaryLgrsFeature.h" +#include "CompletionExportCommands/RicWellPathExportCompletionDataFeature.h" +#include "ExportCommands/RicExportLgrFeature.h" +#include "ExportCommands/RicExportLgrUi.h" + +#include "RifEclipseDataTableFormatter.h" + +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigCell.h" +#include "RigCellGeometryTools.h" +#include "RigEclipseCaseData.h" +#include "RigMainGrid.h" +#include "RigResultAccessor.h" +#include "RigResultAccessorFactory.h" +#include "RigVirtualPerforationTransmissibilities.h" + +#include "RimDialogData.h" +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimMainPlotCollection.h" +#include "RimProject.h" +#include "RimWellLogPlotCollection.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RimWellPathCompletions.h" + +#include "RiuPlotMainWindow.h" +#include "RiuSelectionManager.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +CAF_CMD_SOURCE_INIT(RicCreateTemporaryLgrFeature, "RicCreateTemporaryLgrFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::createLgrsForWellPaths(std::vector wellPaths, + RimEclipseCase* eclipseCase, + size_t timeStep, + caf::VecIjk lgrCellCounts, + Lgr::SplitType splitType, + const std::set& completionTypes, + QStringList* wellsIntersectingOtherLgrs) +{ + auto eclipseCaseData = eclipseCase->eclipseCaseData(); + RigActiveCellInfo* activeCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::MATRIX_MODEL); + RigActiveCellInfo* fractureActiveCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::FRACTURE_MODEL); + + auto lgrs = RicExportLgrFeature::buildLgrsForWellPaths( + wellPaths, eclipseCase, timeStep, lgrCellCounts, splitType, completionTypes, wellsIntersectingOtherLgrs); + + for (const auto& lgr : lgrs) + { + createLgr(lgr, eclipseCase->eclipseCaseData()->mainGrid()); + + size_t lgrCellCount = lgr.cellCount(); + + activeCellInfo->addLgr(lgrCellCount); + if (fractureActiveCellInfo->reservoirActiveCellCount() > 0) + { + fractureActiveCellInfo->addLgr(lgrCellCount); + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::updateViews(RimEclipseCase* eclipseCase) +{ + RiaApplication::clearAllSelections(); + + deleteAllCachedData(eclipseCase); + RiaApplication::instance()->project()->mainPlotCollection()->deleteAllCachedData(); + computeCachedData(eclipseCase); + + RiaApplication::instance()->project()->mainPlotCollection()->wellLogPlotCollection()->reloadAllPlots(); + + for (const auto& v : eclipseCase->views()) + { + RimEclipseView* eclipseView = dynamic_cast(v); + if (eclipseView) + { + eclipseView->scheduleReservoirGridGeometryRegen(); + } + + v->loadDataAndUpdate(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateTemporaryLgrFeature::isCommandEnabled() +{ + std::vector completions = caf::selectedObjectsByTypeStrict(); + std::vector wellPaths = caf::selectedObjectsByTypeStrict(); + + return !completions.empty() || !wellPaths.empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::onActionTriggered(bool isChecked) +{ + std::vector wellPaths = RicExportLgrFeature::selectedWellPaths(); + if (wellPaths.empty()) return; + + QString dialogTitle = "Create Temporary LGR"; + + RimEclipseCase* defaultEclipseCase = nullptr; + int defaultTimeStep = 0; + auto activeView = dynamic_cast(RiaApplication::instance()->activeGridView()); + if (activeView) + { + defaultEclipseCase = activeView->eclipseCase(); + defaultTimeStep = activeView->currentTimeStep(); + } + + auto dialogData = RicExportLgrFeature::openDialog(dialogTitle, defaultEclipseCase, defaultTimeStep, true); + if (dialogData) + { + auto eclipseCase = dialogData->caseToApply(); + auto lgrCellCounts = dialogData->lgrCellCount(); + size_t timeStep = dialogData->timeStep(); + auto splitType = dialogData->splitType(); + const auto completionTypes = dialogData->completionTypes(); + + RicDeleteTemporaryLgrsFeature::deleteAllTemporaryLgrs(eclipseCase); + + QStringList wellsIntersectingOtherLgrs; + + createLgrsForWellPaths(wellPaths, + eclipseCase, + timeStep, + lgrCellCounts, + splitType, + completionTypes, + &wellsIntersectingOtherLgrs); + + updateViews(eclipseCase); + + if (!wellsIntersectingOtherLgrs.empty()) + { + QMessageBox::warning(nullptr, + "LGR cells intersected", + "At least one completion intersects with an LGR. No LGR(s) for those cells are produced"); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Create Temporary LGR"); + actionToSetup->setIcon(QIcon(":/TempLGR16x16.png")); +} + +//-------------------------------------------------------------------------------------------------- +/// Todo: Guarding, caching LGR corner nodes calculations +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::createLgr(const LgrInfo& lgrInfo, RigMainGrid* mainGrid) +{ + int lgrId = lgrInfo.id; + size_t totalCellCount = mainGrid->globalCellArray().size(); + size_t lgrCellCount = lgrInfo.cellCount(); + + // Create local grid and set properties + RigLocalGrid* localGrid = new RigLocalGrid(mainGrid); + localGrid->setAsTempGrid(true); + localGrid->setAssociatedWellPathName(lgrInfo.associatedWellPathName.toStdString()); + localGrid->setGridId(lgrId); + localGrid->setIndexToStartOfCells(totalCellCount); + localGrid->setGridName(lgrInfo.name.toStdString()); + localGrid->setGridPointDimensions(cvf::Vec3st(lgrInfo.sizes.i() + 1, lgrInfo.sizes.j() + 1, lgrInfo.sizes.k() + 1)); + mainGrid->addLocalGrid(localGrid); + + size_t cellStartIndex = mainGrid->globalCellArray().size(); + size_t nodeStartIndex = mainGrid->nodes().size(); + + // Resize global cell and node arrays + { + RigCell defaultCell; + defaultCell.setHostGrid(localGrid); + mainGrid->globalCellArray().resize(cellStartIndex + lgrCellCount, defaultCell); + mainGrid->nodes().resize(nodeStartIndex + lgrCellCount * 8, cvf::Vec3d(0, 0, 0)); + } + + auto lgrSizePerMainCell = lgrInfo.sizesPerMainGridCell(); + size_t gridLocalCellIndex = 0; + + // Loop through all new LGR cells + for (size_t lgrK = 0; lgrK < lgrInfo.sizes.k(); lgrK++) + { + size_t mainK = lgrInfo.mainGridStartCell.k() + lgrK / lgrSizePerMainCell.k(); + + for (size_t lgrJ = 0; lgrJ < lgrInfo.sizes.j(); lgrJ++) + { + size_t mainJ = lgrInfo.mainGridStartCell.j() + lgrJ / lgrSizePerMainCell.j(); + + for (size_t lgrI = 0; lgrI < lgrInfo.sizes.i(); lgrI++, gridLocalCellIndex++) + { + size_t mainI = lgrInfo.mainGridStartCell.i() + lgrI / lgrSizePerMainCell.i(); + + size_t mainCellIndex = mainGrid->cellIndexFromIJK(mainI, mainJ, mainK); + auto& mainGridCell = mainGrid->globalCellArray()[mainCellIndex]; + mainGridCell.setSubGrid(localGrid); + + RigCell& cell = mainGrid->globalCellArray()[cellStartIndex + gridLocalCellIndex]; + cell.setGridLocalCellIndex(gridLocalCellIndex); + cell.setParentCellIndex(mainCellIndex); + + // Corner coordinates + { + size_t cIdx; + std::array vertices; + mainGrid->cellCornerVertices(mainCellIndex, vertices.data()); + + auto cellCounts = lgrInfo.sizesPerMainGridCell(); + auto lgrCoords = + RiaCellDividingTools::createHexCornerCoords(vertices, cellCounts.i(), cellCounts.j(), cellCounts.k()); + + size_t subI = lgrI % lgrSizePerMainCell.i(); + size_t subJ = lgrJ % lgrSizePerMainCell.j(); + size_t subK = lgrK % lgrSizePerMainCell.k(); + + size_t subIndex = + subI + subJ * lgrSizePerMainCell.i() + subK * lgrSizePerMainCell.i() * lgrSizePerMainCell.j(); + + for (cIdx = 0; cIdx < 8; ++cIdx) + { + auto& node = mainGrid->nodes()[nodeStartIndex + gridLocalCellIndex * 8 + cIdx]; + node.set(lgrCoords[subIndex * 8 + cIdx]); + cell.cornerIndices()[cIdx] = nodeStartIndex + gridLocalCellIndex * 8 + cIdx; + } + } + } + } + } + + localGrid->setParentGrid(mainGrid); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::deleteAllCachedData(RimEclipseCase* eclipseCase) +{ + if (eclipseCase) + { + RigCaseCellResultsData* cellResultsDataMatrix = eclipseCase->results(RiaDefines::MATRIX_MODEL); + if (cellResultsDataMatrix) + { + cellResultsDataMatrix->freeAllocatedResultsData(); + } + + RigCaseCellResultsData* cellResultsDataFracture = eclipseCase->results(RiaDefines::FRACTURE_MODEL); + if (cellResultsDataFracture) + { + cellResultsDataFracture->freeAllocatedResultsData(); + } + + RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); + if (eclipseCaseData) + { + eclipseCaseData->clearWellCellsInGridCache(); + eclipseCaseData->setVirtualPerforationTransmissibilities(nullptr); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::computeCachedData(RimEclipseCase* eclipseCase) +{ + if (eclipseCase) + { + RigCaseCellResultsData* cellResultsDataMatrix = eclipseCase->results(RiaDefines::MATRIX_MODEL); + RigCaseCellResultsData* cellResultsDataFracture = eclipseCase->results(RiaDefines::FRACTURE_MODEL); + + RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); + if (eclipseCaseData) + { + eclipseCaseData->mainGrid()->computeCachedData(); + eclipseCaseData->computeActiveCellBoundingBoxes(); + } + + if (cellResultsDataMatrix) + { + cellResultsDataMatrix->computeDepthRelatedResults(); + cellResultsDataMatrix->computeCellVolumes(); + } + + if (cellResultsDataFracture) + { + cellResultsDataFracture->computeDepthRelatedResults(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateTemporaryLgrFeature::containsAnyNonMainGridCells(const std::vector& cells) +{ + return std::find_if(cells.begin(), cells.end(), [](const RigCompletionDataGridCell& cell) { + return !cell.isMainGridCell(); + }) != cells.end(); +} diff --git a/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.cpp.orig b/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.cpp.orig new file mode 100644 index 0000000000..6f134bdaff --- /dev/null +++ b/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.cpp.orig @@ -0,0 +1,361 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicCreateTemporaryLgrFeature.h" + +#include "RiaApplication.h" +#include "RiaCompletionTypeCalculationScheduler.h" +#include "RiaLogging.h" + +#include "CompletionExportCommands/RicWellPathExportCompletionDataFeature.h" +#include "ExportCommands/RicExportLgrFeature.h" +#include "ExportCommands/RicExportLgrUi.h" + +#include "RifEclipseDataTableFormatter.h" + +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigCell.h" +#include "RigCellGeometryTools.h" +#include "RigEclipseCaseData.h" +#include "RigMainGrid.h" +#include "RigResultAccessor.h" +#include "RigResultAccessorFactory.h" +#include "RigVirtualPerforationTransmissibilities.h" + +#include "RimDialogData.h" +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimMainPlotCollection.h" +#include "RimProject.h" +#include "RimWellLogPlotCollection.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RimWellPathCompletions.h" + +#include "RiuPlotMainWindow.h" +#include "RiuSelectionManager.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +CAF_CMD_SOURCE_INIT(RicCreateTemporaryLgrFeature, "RicCreateTemporaryLgrFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateTemporaryLgrFeature::isCommandEnabled() +{ + std::vector completions = caf::selectedObjectsByTypeStrict(); + std::vector wellPaths = caf::selectedObjectsByTypeStrict(); + + return !completions.empty() || !wellPaths.empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::onActionTriggered(bool isChecked) +{ + std::vector wellPaths = RicExportLgrFeature::selectedWellPaths(); + if (wellPaths.empty()) return; + + QString dialogTitle = "Create Temporary LGR"; + + RimEclipseCase* defaultEclipseCase = nullptr; + int defaultTimeStep = 0; + auto activeView = dynamic_cast(RiaApplication::instance()->activeGridView()); + if (activeView) + { + defaultEclipseCase = activeView->eclipseCase(); + defaultTimeStep = activeView->currentTimeStep(); + } + + auto dialogData = RicExportLgrFeature::openDialog(dialogTitle, defaultEclipseCase, defaultTimeStep, true); + if (dialogData) + { + auto eclipseCase = dialogData->caseToApply(); + auto lgrCellCounts = dialogData->lgrCellCount(); + size_t timeStep = dialogData->timeStep(); + auto splitType = dialogData->splitType(); + auto completionTypes = dialogData->completionTypes(); + + auto eclipseCaseData = eclipseCase->eclipseCaseData(); + RigActiveCellInfo* activeCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::MATRIX_MODEL); + RigActiveCellInfo* fractureActiveCellInfo = eclipseCaseData->activeCellInfo(RiaDefines::FRACTURE_MODEL); + + bool intersectingOtherLgr = false; + for (const auto& wellPath : wellPaths) + { +<<<<<<< HEAD + try + { + std::vector lgrs = RicExportLgrFeature::buildLgrsForWellPath( + wellPath, eclipseCase, timeStep, lgrCellCounts, splitType, completionTypes); +======= + std::vector lgrs; + bool intersectingLgrs = false; + + lgrs = RicExportLgrFeature::buildLgrsForWellPath(wellPath, + eclipseCase, + timeStep, + lgrCellCounts, + splitType, + completionTypes, + &intersectingLgrs); +>>>>>>> TEMP + + if (intersectingLgrs) intersectingOtherLgr = true; + + auto mainGrid = eclipseCase->eclipseCaseData()->mainGrid(); + + for (auto lgr : lgrs) + { + createLgr(lgr, eclipseCase->eclipseCaseData()->mainGrid()); + + size_t lgrCellCount = lgr.cellCount(); + +<<<<<<< HEAD + mainGrid->calculateFaults(activeCellInfo, true); + } + catch (CreateLgrException& e) + { + RiaLogging::error(e.message); + + intersectsExistingLgr = true; +======= + activeCellInfo->addLgr(lgrCellCount); + if (fractureActiveCellInfo->reservoirActiveCellCount() > 0) + { + fractureActiveCellInfo->addLgr(lgrCellCount); + } +>>>>>>> TEMP + } + + mainGrid->calculateFaults(activeCellInfo, true); + } + + RiuSelectionManager::instance()->deleteAllItems(RiuSelectionManager::RUI_APPLICATION_GLOBAL); + RiuSelectionManager::instance()->deleteAllItems(RiuSelectionManager::RUI_TEMPORARY); + caf::SelectionManager::instance()->clearAll(); + + deleteAllCachedData(eclipseCase); + RiaApplication::instance()->project()->mainPlotCollection()->deleteAllCachedData(); + computeCachedData(eclipseCase); + + RiaApplication::instance()->project()->mainPlotCollection()->wellLogPlotCollection()->reloadAllPlots(); + + for (const auto& v : eclipseCase->views()) + { + RimEclipseView* eclipseView = dynamic_cast(v); + if (eclipseView) + { + eclipseView->scheduleReservoirGridGeometryRegen(); + eclipseView->loadDataAndUpdate(); + } + } + + if (intersectingOtherLgr) + { + QMessageBox::warning(nullptr, + "LGR cells intersected", + "At least one completion intersects with an LGR. No LGR(s) for those cells are produced"); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Create Temporary LGR"); +} + +//-------------------------------------------------------------------------------------------------- +/// Todo: Guarding, caching LGR corner nodes calculations +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::createLgr(const LgrInfo& lgrInfo, RigMainGrid* mainGrid) +{ + auto app = RiaApplication::instance(); + auto eclipseView = dynamic_cast(app->activeReservoirView()); + if (!eclipseView) return; + + int lgrId = lgrInfo.id; + size_t totalCellCount = mainGrid->globalCellArray().size(); + size_t lgrCellCount = lgrInfo.cellCount(); + + // Create local grid and set properties + RigLocalGrid* localGrid = new RigLocalGrid(mainGrid); + localGrid->setAsTempGrid(true); + localGrid->setGridId(lgrId); + localGrid->setIndexToStartOfCells(totalCellCount); + localGrid->setGridName(lgrInfo.name.toStdString()); + localGrid->setGridPointDimensions(cvf::Vec3st(lgrInfo.sizes.i() + 1, lgrInfo.sizes.j() + 1, lgrInfo.sizes.k() + 1)); + mainGrid->addLocalGrid(localGrid); + + size_t cellStartIndex = mainGrid->globalCellArray().size(); + size_t nodeStartIndex = mainGrid->nodes().size(); + + // Resize global cell and node arrays + { + RigCell defaultCell; + defaultCell.setHostGrid(localGrid); + mainGrid->globalCellArray().resize(cellStartIndex + lgrCellCount, defaultCell); + mainGrid->nodes().resize(nodeStartIndex + lgrCellCount * 8, cvf::Vec3d(0, 0, 0)); + } + + auto lgrSizePerMainCell = lgrInfo.sizesPerMainGridCell(); + size_t gridLocalCellIndex = 0; + + // Loop through all new LGR cells + for (size_t lgrK = 0; lgrK < lgrInfo.sizes.k(); lgrK++) + { + size_t mainK = lgrInfo.mainGridStartCell.k() + lgrK / lgrSizePerMainCell.k(); + + for (size_t lgrJ = 0; lgrJ < lgrInfo.sizes.j(); lgrJ++) + { + size_t mainJ = lgrInfo.mainGridStartCell.j() + lgrJ / lgrSizePerMainCell.j(); + + for (size_t lgrI = 0; lgrI < lgrInfo.sizes.i(); lgrI++, gridLocalCellIndex++) + { + size_t mainI = lgrInfo.mainGridStartCell.i() + lgrI / lgrSizePerMainCell.i(); + + size_t mainCellIndex = mainGrid->cellIndexFromIJK(mainI, mainJ, mainK); + auto mainGridCell = mainGrid->globalCellArray()[mainCellIndex]; + + if (mainGridCell.subGrid()) + { + continue; + } + mainGridCell.setSubGrid(localGrid); + + RigCell& cell = mainGrid->globalCellArray()[cellStartIndex + gridLocalCellIndex]; + cell.setGridLocalCellIndex(gridLocalCellIndex); + cell.setParentCellIndex(mainCellIndex); + + // Corner coordinates + { + size_t cIdx; + std::array vertices; + mainGrid->cellCornerVertices(mainCellIndex, vertices.data()); + + auto cellCounts = lgrInfo.sizesPerMainGridCell(); + auto lgrCoords = + RigCellGeometryTools::createHexCornerCoords(vertices, cellCounts.i(), cellCounts.j(), cellCounts.k()); + + size_t subI = lgrI % lgrSizePerMainCell.i(); + size_t subJ = lgrJ % lgrSizePerMainCell.j(); + size_t subK = lgrK % lgrSizePerMainCell.k(); + + size_t subIndex = + subI + subJ * lgrSizePerMainCell.i() + subK * lgrSizePerMainCell.i() * lgrSizePerMainCell.j(); + + for (cIdx = 0; cIdx < 8; ++cIdx) + { + auto& node = mainGrid->nodes()[nodeStartIndex + gridLocalCellIndex * 8 + cIdx]; + node.set(lgrCoords[subIndex * 8 + cIdx]); + cell.cornerIndices()[cIdx] = nodeStartIndex + gridLocalCellIndex * 8 + cIdx; + } + } + } + } + } + + localGrid->setParentGrid(mainGrid); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::deleteAllCachedData(RimEclipseCase* eclipseCase) +{ + if (eclipseCase) + { + RigCaseCellResultsData* cellResultsDataMatrix = eclipseCase->results(RiaDefines::MATRIX_MODEL); + if (cellResultsDataMatrix) + { + cellResultsDataMatrix->freeAllocatedResultsData(); + } + + RigCaseCellResultsData* cellResultsDataFracture = eclipseCase->results(RiaDefines::FRACTURE_MODEL); + if (cellResultsDataFracture) + { + cellResultsDataFracture->freeAllocatedResultsData(); + } + + RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); + if (eclipseCaseData) + { + eclipseCaseData->clearWellCellsInGridCache(); + eclipseCaseData->setVirtualPerforationTransmissibilities(nullptr); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateTemporaryLgrFeature::computeCachedData(RimEclipseCase* eclipseCase) +{ + if (eclipseCase) + { + RigCaseCellResultsData* cellResultsDataMatrix = eclipseCase->results(RiaDefines::MATRIX_MODEL); + RigCaseCellResultsData* cellResultsDataFracture = eclipseCase->results(RiaDefines::FRACTURE_MODEL); + + RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); + if (eclipseCaseData) + { + eclipseCaseData->mainGrid()->computeCachedData(); + eclipseCaseData->computeActiveCellBoundingBoxes(); + } + + if (cellResultsDataMatrix) + { + cellResultsDataMatrix->computeDepthRelatedResults(); + } + + if (cellResultsDataFracture) + { + cellResultsDataFracture->computeDepthRelatedResults(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateTemporaryLgrFeature::containsAnyNonMainGridCells(const std::vector& cells) +{ + return std::find_if(cells.begin(), cells.end(), [](const RigCompletionDataGridCell& cell) { + return !cell.isMainGridCell(); + }) != cells.end(); +} diff --git a/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.h b/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.h new file mode 100644 index 0000000000..0d3864cebd --- /dev/null +++ b/ApplicationCode/Commands/RicCreateTemporaryLgrFeature.h @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "ExportCommands/RicLgrSplitType.h" +#include "RigCompletionDataGridCell.h" +#include "RigCompletionData.h" + +#include "cafCmdFeature.h" +#include "cafVecIjk.h" + +#include +#include + +class LgrInfo; +class RigMainGrid; +class RigCell; +class RimEclipseCase; +class RimSimWellInView; +class RimWellPath; +class RicExportLgrUi; +class QFile; +class QTextStream; + +//================================================================================================== +/// +//================================================================================================== +class RicCreateTemporaryLgrFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +public: + void createLgrsForWellPaths(std::vector wellPaths, + RimEclipseCase* eclipseCase, + size_t timeStep, + caf::VecIjk lgrCellCounts, + Lgr::SplitType splitType, + const std::set& completionTypes, + QStringList* wellsIntersectingOtherLgrs); + + void updateViews(RimEclipseCase* eclipseCase); + +protected: + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + +private: + void createLgr(const LgrInfo& lgrInfo, RigMainGrid* mainGrid); + void computeCachedData(RimEclipseCase* eclipseCase); + void deleteAllCachedData(RimEclipseCase* eclipseCase); + bool containsAnyNonMainGridCells(const std::vector& cells); +}; diff --git a/ApplicationCode/Commands/RicDeleteItemExec.cpp b/ApplicationCode/Commands/RicDeleteItemExec.cpp index 356955e036..9c16e4f55f 100644 --- a/ApplicationCode/Commands/RicDeleteItemExec.cpp +++ b/ApplicationCode/Commands/RicDeleteItemExec.cpp @@ -28,6 +28,8 @@ #include "RimCellRangeFilterCollection.h" #include "RimEclipsePropertyFilterCollection.h" #include "RimEclipseView.h" +#include "RimEnsembleCurveFilterCollection.h" +#include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSetCollection.h" #include "RimFormationNamesCollection.h" #include "RimGeoMechPropertyFilterCollection.h" @@ -158,16 +160,16 @@ void RicDeleteItemExec::redo() parentObj->firstAncestorOrThisOfType(proj); if (proj) { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } std::vector views; proj->allVisibleViews(views); - for (Rim3dView* view : views) + for (Rim3dView* visibleView : views) { - if (dynamic_cast(view)) + if (dynamic_cast(visibleView)) { - view->updateConnectedEditors(); + visibleView->updateConnectedEditors(); } } } @@ -200,13 +202,17 @@ void RicDeleteItemExec::redo() { wellLogPlot->calculateAvailableDepthRange(); wellLogPlot->updateDepthZoom(); + RiuPlotMainWindow* mainPlotWindow = RiaApplication::instance()->mainPlotWindow(); + mainPlotWindow->updateWellLogPlotToolBar(); } RimWellLogTrack* wellLogPlotTrack; parentObj->firstAncestorOrThisOfType(wellLogPlotTrack); if (wellLogPlotTrack) { - wellLogPlotTrack->updateXZoom(); + wellLogPlotTrack->calculateXZoomRangeAndUpdateQwt(); + RiuPlotMainWindow* mainPlotWindow = RiaApplication::instance()->mainPlotWindow(); + mainPlotWindow->updateWellLogPlotToolBar(); } // Update due to delete plots @@ -224,6 +230,8 @@ void RicDeleteItemExec::redo() project->updateConnectedEditors(); } } + RiuPlotMainWindow* mainPlotWindow = RiaApplication::instance()->mainPlotWindow(); + mainPlotWindow->updateWellLogPlotToolBar(); } // Linked views @@ -283,6 +291,15 @@ void RicDeleteItemExec::redo() ensembleCurveSetColl->firstAncestorOrThisOfType(plot); if (plot) plot->updateConnectedEditors(); } + + RimEnsembleCurveFilterCollection* ensembleCurveFilterColl = nullptr; + parentObj->firstAncestorOrThisOfType(ensembleCurveFilterColl); + if (ensembleCurveFilterColl) + { + RimSummaryPlot* plot = nullptr; + ensembleCurveFilterColl->firstAncestorOrThisOfType(plot); + if (plot) plot->loadDataAndUpdate(); + } } } diff --git a/ApplicationCode/Commands/RicDeleteItemExec.h b/ApplicationCode/Commands/RicDeleteItemExec.h index 38bef07d1e..1608c1c0d7 100644 --- a/ApplicationCode/Commands/RicDeleteItemExec.h +++ b/ApplicationCode/Commands/RicDeleteItemExec.h @@ -34,9 +34,9 @@ class RicDeleteItemExec : public caf::CmdExecuteCommand RicDeleteItemExecData* commandData(); - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: RicDeleteItemExecData* m_commandData; diff --git a/ApplicationCode/Commands/RicDeleteItemFeature.cpp b/ApplicationCode/Commands/RicDeleteItemFeature.cpp index 5f3b678afb..911ca76857 100644 --- a/ApplicationCode/Commands/RicDeleteItemFeature.cpp +++ b/ApplicationCode/Commands/RicDeleteItemFeature.cpp @@ -22,9 +22,11 @@ #include "RicDeleteItemExecData.h" #include "RimCellRangeFilter.h" +#include "RimDerivedEnsembleCaseCollection.h" #include "RimEclipseInputProperty.h" #include "RimEclipsePropertyFilter.h" #include "RimEclipseView.h" +#include "RimEnsembleCurveFilter.h" #include "RimEnsembleCurveSet.h" #include "RimFishbonesMultipleSubs.h" #include "RimFormationNames.h" @@ -50,6 +52,7 @@ #include "RimAsciiDataCurve.h" #include "RimWellLogRftCurve.h" #include "RimWellRftPlot.h" +#include "RimWellPathValve.h" #include "RimEllipseFractureTemplate.h" #include "RimSimWellFracture.h" @@ -119,6 +122,9 @@ bool isDeletable(caf::PdmUiItem* uiItem) if (dynamic_cast(uiItem)) return true; if (dynamic_cast(uiItem)) return true; if (dynamic_cast(uiItem)) return true; + if (dynamic_cast(uiItem)) return true; + if (dynamic_cast(uiItem)) return true; + if (dynamic_cast(uiItem)) return true; return false; } diff --git a/ApplicationCode/Commands/RicDeleteItemFeature.h b/ApplicationCode/Commands/RicDeleteItemFeature.h index 466b2bcf17..6aab4b83d9 100644 --- a/ApplicationCode/Commands/RicDeleteItemFeature.h +++ b/ApplicationCode/Commands/RicDeleteItemFeature.h @@ -30,7 +30,7 @@ class RicDeleteItemFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicDeleteSubItemsFeature.cpp b/ApplicationCode/Commands/RicDeleteSubItemsFeature.cpp index 8c0d668543..217c4085c7 100644 --- a/ApplicationCode/Commands/RicDeleteSubItemsFeature.cpp +++ b/ApplicationCode/Commands/RicDeleteSubItemsFeature.cpp @@ -1,56 +1,55 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RicDeleteSubItemsFeature.h" +#include "RimProject.h" #include "RimSummaryPlotCollection.h" #include "RimWellPathCollection.h" +#include "RimWellPathFractureCollection.h" #include "cafPdmUiItem.h" #include "cafSelectionManager.h" #include - CAF_CMD_SOURCE_INIT(RicDeleteSubItemsFeature, "RicDeleteSubItemsFeature"); - - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -bool RicDeleteSubItemsFeature::isCommandEnabled() +bool RicDeleteSubItemsFeature::isCommandEnabled() { std::vector items; caf::SelectionManager::instance()->selectedItems(items); - + if (items.empty()) return false; for (auto* item : items) { if (!RicDeleteSubItemsFeature::hasDeletableSubItems(item)) return false; } - + return true; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicDeleteSubItemsFeature::onActionTriggered(bool isChecked) { @@ -63,27 +62,45 @@ void RicDeleteSubItemsFeature::onActionTriggered(bool isChecked) { if (!RicDeleteSubItemsFeature::hasDeletableSubItems(item)) continue; - RimSummaryPlotCollection* summaryPlotColl = dynamic_cast(item); - if (summaryPlotColl) { - summaryPlotColl->summaryPlots.deleteAllChildObjects(); + auto collection = dynamic_cast(item); + if (collection) + { + collection->summaryPlots.deleteAllChildObjects(); - summaryPlotColl->updateConnectedEditors(); + collection->updateConnectedEditors(); + } + } + + { + auto collection = dynamic_cast(item); + if (collection) + { + collection->deleteAllWellPaths(); + + collection->updateConnectedEditors(); + collection->scheduleRedrawAffectedViews(); + } } - RimWellPathCollection* wellPathColl = dynamic_cast(item); - if (wellPathColl) { - wellPathColl->deleteAllWellPaths(); + auto collection = dynamic_cast(item); + if (collection) + { + collection->deleteFractures(); - wellPathColl->updateConnectedEditors(); - wellPathColl->scheduleRedrawAffectedViews(); + collection->updateConnectedEditors(); + + RimProject* proj = nullptr; + collection->firstAncestorOrThisOfType(proj); + if (proj) proj->reloadCompletionTypeResultsInAllViews(); + } } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicDeleteSubItemsFeature::setupActionLook(QAction* actionToSetup) { @@ -92,20 +109,32 @@ void RicDeleteSubItemsFeature::setupActionLook(QAction* actionToSetup) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RicDeleteSubItemsFeature::hasDeletableSubItems(caf::PdmUiItem* uiItem) { - RimSummaryPlotCollection* summaryPlotColl = dynamic_cast(uiItem); - if (summaryPlotColl && summaryPlotColl->summaryPlots().size() > 0) { - return true; + auto collection = dynamic_cast(uiItem); + if (collection && !collection->summaryPlots().empty()) + { + return true; + } + } + + { + auto collection = dynamic_cast(uiItem); + if (collection && !collection->wellPaths().empty()) + { + return true; + } } - RimWellPathCollection* wellPathColl = dynamic_cast(uiItem); - if (wellPathColl && wellPathColl->wellPaths().size() > 0) { - return true; + auto collection = dynamic_cast(uiItem); + if (collection && !collection->allFractures().empty()) + { + return true; + } } return false; diff --git a/ApplicationCode/Commands/RicDeleteSubItemsFeature.h b/ApplicationCode/Commands/RicDeleteSubItemsFeature.h index 72c80b7583..177e0bc8cc 100644 --- a/ApplicationCode/Commands/RicDeleteSubItemsFeature.h +++ b/ApplicationCode/Commands/RicDeleteSubItemsFeature.h @@ -33,9 +33,9 @@ class RicDeleteSubItemsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static bool hasDeletableSubItems(caf::PdmUiItem* uiItem); diff --git a/ApplicationCode/Commands/RicDeleteSummaryCaseCollectionFeature.cpp b/ApplicationCode/Commands/RicDeleteSummaryCaseCollectionFeature.cpp index 3181e20f48..22451728ae 100644 --- a/ApplicationCode/Commands/RicDeleteSummaryCaseCollectionFeature.cpp +++ b/ApplicationCode/Commands/RicDeleteSummaryCaseCollectionFeature.cpp @@ -21,6 +21,8 @@ #include "RiaApplication.h" #include "RiaSummaryTools.h" + +#include "RimDerivedEnsembleCaseCollection.h" #include "RimMainPlotCollection.h" #include "RimProject.h" #include "RimSummaryCase.h" @@ -65,6 +67,10 @@ bool RicDeleteSummaryCaseCollectionFeature::isCommandEnabled() std::vector selection; caf::SelectionManager::instance()->objectsByType(&selection); + selection.erase(std::remove_if(selection.begin(), selection.end(), [](RimSummaryCaseCollection* coll) + { + return dynamic_cast(coll) != nullptr; + }), selection.end()); return (selection.size() > 0); } diff --git a/ApplicationCode/Commands/RicDeleteSummaryCaseCollectionFeature.h b/ApplicationCode/Commands/RicDeleteSummaryCaseCollectionFeature.h index 8c44a36ff6..8afce8760c 100644 --- a/ApplicationCode/Commands/RicDeleteSummaryCaseCollectionFeature.h +++ b/ApplicationCode/Commands/RicDeleteSummaryCaseCollectionFeature.h @@ -32,9 +32,9 @@ class RicDeleteSummaryCaseCollectionFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; static void deleteSummaryCaseCollection(RimSummaryCaseCollection* caseCollection); static void moveAllCasesToMainSummaryCollection(RimSummaryCaseCollection* summaryCaseCollection); diff --git a/ApplicationCode/Commands/RicDeleteTemporaryLgrsFeature.cpp b/ApplicationCode/Commands/RicDeleteTemporaryLgrsFeature.cpp new file mode 100644 index 0000000000..93c4c0bfa3 --- /dev/null +++ b/ApplicationCode/Commands/RicDeleteTemporaryLgrsFeature.cpp @@ -0,0 +1,80 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicDeleteTemporaryLgrsFeature.h" + +#include "RiaApplication.h" + +#include "RimEclipseCase.h" +#include "RimGridCollection.h" + +#include "cafPdmObject.h" +#include "cafSelectionManagerTools.h" + +#include + +CAF_CMD_SOURCE_INIT(RicDeleteTemporaryLgrsFeature, "RicDeleteTemporaryLgrsFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteTemporaryLgrsFeature::deleteAllTemporaryLgrs(RimEclipseCase* eclipseCase) +{ + RiaApplication::clearAllSelections(); + + if (eclipseCase) eclipseCase->reloadDataAndUpdate(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicDeleteTemporaryLgrsFeature::isCommandEnabled() +{ + std::vector selGridInfos = caf::selectedObjectsByTypeStrict(); + if (selGridInfos.size() == 1 && selGridInfos.front()->uiName() == RimGridCollection::temporaryGridUiName()) + { + return !selGridInfos[0]->gridInfos().empty(); + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteTemporaryLgrsFeature::onActionTriggered(bool isChecked) +{ + std::vector selGridInfos = caf::selectedObjectsByTypeStrict(); + if (selGridInfos.size() == 1 && selGridInfos.front()->uiName() == RimGridCollection::temporaryGridUiName()) + { + RimEclipseCase* eclipseCase; + selGridInfos.front()->firstAncestorOrThisOfType(eclipseCase); + + deleteAllTemporaryLgrs(eclipseCase); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteTemporaryLgrsFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete Temporary LGRs"); + actionToSetup->setIcon(QIcon(":/Erase.png")); +} diff --git a/ApplicationCode/Commands/RicDeleteTemporaryLgrsFeature.h b/ApplicationCode/Commands/RicDeleteTemporaryLgrsFeature.h new file mode 100644 index 0000000000..bcb1411a5e --- /dev/null +++ b/ApplicationCode/Commands/RicDeleteTemporaryLgrsFeature.h @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimEclipseCase; + +class RicDeleteTemporaryLgrsFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + + static void deleteAllTemporaryLgrs(RimEclipseCase* eclipseCase); + +protected: + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; +}; diff --git a/ApplicationCode/Commands/RicFileHierarchyDialog.cpp b/ApplicationCode/Commands/RicFileHierarchyDialog.cpp index f4dbe65eb9..c941f3a709 100644 --- a/ApplicationCode/Commands/RicFileHierarchyDialog.cpp +++ b/ApplicationCode/Commands/RicFileHierarchyDialog.cpp @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include #include @@ -57,6 +59,7 @@ #define NO_FILES_FOUND_TEXT "No files found" #define SCANNING_DIRS_TEXT "Scanning Directories" #define FINDING_FILES_TEXT "Finding Files" +#define FILES_FOUND_TEXT "Files found" //-------------------------------------------------------------------------------------------------- /// Internal variables @@ -69,7 +72,7 @@ static const QChar SEPARATOR = RiaFilePathTools::SEPARATOR; static QStringList prefixStrings(const QStringList& strings, const QString& prefix); static QStringList trimLeftStrings(const QStringList& strings, const QString& trimText); static void sortStringsByLength(QStringList& strings, bool ascending = true); - +static QString effectivePathFilter(const QString& enteredPathFilter); //-------------------------------------------------------------------------------------------------- /// @@ -202,7 +205,7 @@ QStringList RicFileHierarchyDialog::files() const //-------------------------------------------------------------------------------------------------- QString RicFileHierarchyDialog::rootDir() const { - QString rootDir = RiaFilePathTools::toInternalSeparator(m_rootDir->text()); + QString rootDir = RiaFilePathTools::toInternalSeparator(m_rootDir->text().trimmed()); return RiaFilePathTools::appendSeparatorIfNo(rootDir); } @@ -211,7 +214,7 @@ QString RicFileHierarchyDialog::rootDir() const //-------------------------------------------------------------------------------------------------- QString RicFileHierarchyDialog::pathFilter() const { - return RiaFilePathTools::toInternalSeparator(m_pathFilter->text()); + return RiaFilePathTools::toInternalSeparator(m_pathFilter->text().trimmed()); } //-------------------------------------------------------------------------------------------------- @@ -219,7 +222,7 @@ QString RicFileHierarchyDialog::pathFilter() const //-------------------------------------------------------------------------------------------------- QString RicFileHierarchyDialog::fileNameFilter() const { - return m_fileFilter->text(); + return m_fileFilter->text().trimmed(); } //-------------------------------------------------------------------------------------------------- @@ -290,6 +293,7 @@ void RicFileHierarchyDialog::clearFileList() { m_files.clear(); m_fileList->clear(); + m_fileListLabel->setText(FILES_FOUND_TEXT); setOkButtonEnabled(false); } @@ -299,8 +303,11 @@ void RicFileHierarchyDialog::clearFileList() void RicFileHierarchyDialog::updateStatus(Status status, const QString& extraText) { static int progressLoopStep = 0; - static time_t lastStatusUpdate = 0; - time_t now = time(nullptr); + static QTime lastStatusUpdate; + QTime now = QTime::currentTime(); + + // Do not update dialog more often than twice per second to avoid text update from slowing down search progress + if (status != NO_FILES_FOUND && lastStatusUpdate.msecsTo(now) < 500) return; QString newStatus; if (status == SEARCHING_FOR_DIRS || status == SEARCHING_FOR_FILES ) @@ -316,9 +323,7 @@ void RicFileHierarchyDialog::updateStatus(Status status, const QString& extraTex newStatus += " ."; } - if (now != lastStatusUpdate) progressLoopStep++; // If less than one second since last update, do not increment - - if (progressLoopStep >= 5) progressLoopStep = 0; + if (++progressLoopStep >= 5) progressLoopStep = 0; if (!extraText.isEmpty()) newStatus += "\n" + extraText; } @@ -333,14 +338,6 @@ void RicFileHierarchyDialog::updateStatus(Status status, const QString& extraTex new QListWidgetItem(newStatus, m_fileList); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RicFileHierarchyDialog::currentStatus() const -{ - return m_fileList->item(0) ? m_fileList->item(0)->text() : ""; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -352,8 +349,6 @@ QStringList RicFileHierarchyDialog::findMatchingFiles() QStringList dirs; - if ( this->pathFilter().isEmpty() ) dirs.append(this->rootDir()); - buildDirectoryListRecursiveSimple(this->rootDir(), this->pathFilter(), &dirs); const QStringList& files = findFilesInDirs(dirs); @@ -419,120 +414,57 @@ QStringList RicFileHierarchyDialog::buildDirectoryListRecursive(const QString& c //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicFileHierarchyDialog::buildDirectoryListRecursiveSimple(const QString& rootDir, - const QString& remainingPathFilter, +void RicFileHierarchyDialog::buildDirectoryListRecursiveSimple(const QString& currentDir, + const QString& currentPathFilter, QStringList* accumulatedDirs) { - if (cancelPressed()) return; + QString currDir = currentDir; + QString pathFilter = currentPathFilter; + if (pathFilter.startsWith(SEPARATOR)) pathFilter.remove(0, 1); + if (pathFilter.endsWith(SEPARATOR)) pathFilter.chop(1); + if (currDir.endsWith(SEPARATOR)) currDir.chop(1); - QString currentRemainingpathFilter = remainingPathFilter; + if (cancelPressed()) { - // Remove prefixing or trailing path separators from filter - - int pathSepIdx = currentRemainingpathFilter.indexOf(SEPARATOR); - while ( pathSepIdx == 0 ) - { - currentRemainingpathFilter.remove(pathSepIdx, 1); - pathSepIdx = currentRemainingpathFilter.indexOf(SEPARATOR); - } - - if ( currentRemainingpathFilter.endsWith(SEPARATOR) ) - { - currentRemainingpathFilter.chop(1); - } + accumulatedDirs->clear(); + return; } - QString effectiveRootDir = rootDir; - { - // Remove trailing path separator from root - if ( effectiveRootDir.endsWith(SEPARATOR) ) - { - effectiveRootDir.chop(1); - } - } + updateStatus(SEARCHING_FOR_DIRS, currDir); + QApplication::processEvents(); - // Search pathfilter for the first wildcard. - // Use the path up to that directory directly, short-cutting the search + if (pathFilter.isEmpty()) { - std::set sortedWildCardPositions; - sortedWildCardPositions.insert(currentRemainingpathFilter.indexOf("*")); - sortedWildCardPositions.insert(currentRemainingpathFilter.indexOf("?")); - sortedWildCardPositions.insert(currentRemainingpathFilter.indexOf("[")); - - int minWildCardPos = -1; - for ( int wildCardPos : sortedWildCardPositions ) - { - if ( wildCardPos == -1 ) continue; - - minWildCardPos = wildCardPos; - break; - } - - if ( minWildCardPos == -1 ) - { - effectiveRootDir += SEPARATOR + currentRemainingpathFilter; - currentRemainingpathFilter = ""; - } - else - { - int pathSepPos = currentRemainingpathFilter.indexOf(SEPARATOR); - while ( pathSepPos != -1 && pathSepPos < minWildCardPos ) - { - effectiveRootDir += SEPARATOR + currentRemainingpathFilter.left(pathSepPos); - currentRemainingpathFilter.remove(0, pathSepPos + 1); // include the separator - minWildCardPos -= (pathSepPos + 1); - pathSepPos = currentRemainingpathFilter.indexOf(SEPARATOR); - } - } + accumulatedDirs->push_back(currentDir); + return; } - // Find the filter to use for this directory level - // Assumes no prefixed path separator + QStringList pathFilters = pathFilter.split(SEPARATOR); + QDir qdir(currDir, pathFilters[0], QDir::NoSort, QDir::Dirs | QDir::NoDotAndDotDot); + QStringList subDirs = qdir.entryList(); - QStringList subDirsFullPath; + if (pathFilters.size() == 1 && pathFilters[0] == "*") { - int pathSepIdx = currentRemainingpathFilter.indexOf(SEPARATOR); - QString currentDirNameFilter = currentRemainingpathFilter.left(pathSepIdx); - - if ( pathSepIdx == -1 ) - { - currentRemainingpathFilter = ""; - } - else - { - currentRemainingpathFilter.remove(0, pathSepIdx); - } - - if ( currentDirNameFilter.isEmpty() ) currentDirNameFilter = "*"; - - + accumulatedDirs->push_back(currDir); + } - QDir qdir(effectiveRootDir, currentDirNameFilter, QDir::NoSort, QDir::Dirs | QDir::NoDotAndDotDot); + for (const QString& subDir : subDirs) + { + QString fullPath = qdir.absoluteFilePath(subDir); + QString nextPathFilter; - // Add effectiveRoot if current dir name filter =""or"*" or "?" and currentRemainingpathFilter = "" - // and remainingPathFilter not empty - if ( (currentDirNameFilter == "*" || currentDirNameFilter == "?") - && currentRemainingpathFilter.isEmpty() - && !remainingPathFilter.isEmpty()) + if (pathFilters.size() == 1 && pathFilters[0] == "*") { - (*accumulatedDirs) += qdir.absolutePath(); + nextPathFilter = "*"; } - - QStringList subDirs = qdir.entryList(); - - for ( const QString& subDir : subDirs ) + else { - QString fullPath = qdir.absoluteFilePath(subDir); - subDirsFullPath += fullPath; - (*accumulatedDirs) += fullPath; + auto pf = pathFilters; + pf.removeFirst(); + nextPathFilter = pf.join(SEPARATOR); } - } - for (const QString& subDir : subDirsFullPath) - { - updateStatus(SEARCHING_FOR_DIRS, subDir); - QApplication::processEvents(); - buildDirectoryListRecursiveSimple(subDir, currentRemainingpathFilter, accumulatedDirs); + buildDirectoryListRecursiveSimple(fullPath, nextPathFilter, accumulatedDirs); } } @@ -550,6 +482,8 @@ QStringList RicFileHierarchyDialog::findFilesInDirs(const QStringList& dirs) QDir qdir(dir); QStringList files = qdir.entryList(filters, QDir::Files); + if (cancelPressed()) return QStringList(); + updateStatus(SEARCHING_FOR_FILES, qdir.absolutePath()); QApplication::processEvents(); @@ -602,7 +536,7 @@ void RicFileHierarchyDialog::updateEffectiveFilter() { QString effFilter = QString("%1/%2/%3%4") .arg(m_rootDir->text()) - .arg(!m_pathFilter->text().isEmpty() ? m_pathFilter->text() : "*") + .arg(effectivePathFilter(m_pathFilter->text())) .arg(fileNameFilter()) .arg(fileExtensionsText()); @@ -628,6 +562,22 @@ void RicFileHierarchyDialog::setOkButtonEnabled(bool enabled) m_buttons->button(QDialogButtonBox::Ok)->setEnabled(enabled); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicFileHierarchyDialog::warningIfInvalidCharacters() +{ + if (m_fileFilter->text().contains(QRegExp("[\\\\/:]"))) + { + QToolTip::showText(m_fileFilter->mapToGlobal(QPoint(0, 0)), "File pattern contains invalid characters"); + m_effectiveFilter->setText("(Invalid filter)"); + } + else + { + QToolTip::hideText(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -635,6 +585,7 @@ void RicFileHierarchyDialog::slotFilterChanged(const QString& text) { clearFileList(); updateEffectiveFilter(); + warningIfInvalidCharacters(); } //-------------------------------------------------------------------------------------------------- @@ -736,6 +687,10 @@ void RicFileHierarchyDialog::slotFindOrCancelButtonClicked() { updateStatus(NO_FILES_FOUND); } + else + { + m_fileListLabel->setText(QString("%1\n(%2)").arg(FILES_FOUND_TEXT).arg(m_files.size())); + } setOkButtonEnabled(!m_files.isEmpty()); } @@ -853,3 +808,12 @@ void sortStringsByLength(QStringList& strings, bool ascending /*= true*/) } + +QString effectivePathFilter(const QString& enteredPathFilter) +{ + QString p = RiaFilePathTools::toInternalSeparator(enteredPathFilter); + + if (p == "*" || p.endsWith(QString(SEPARATOR) + "*")) return p + "*"; + else return p; +} + diff --git a/ApplicationCode/Commands/RicFileHierarchyDialog.h b/ApplicationCode/Commands/RicFileHierarchyDialog.h index 0e42e23b4c..e0052e801a 100644 --- a/ApplicationCode/Commands/RicFileHierarchyDialog.h +++ b/ApplicationCode/Commands/RicFileHierarchyDialog.h @@ -44,7 +44,7 @@ class RicFileHierarchyDialog : public QDialog public: RicFileHierarchyDialog(QWidget* parent); - ~RicFileHierarchyDialog(); + ~RicFileHierarchyDialog() override; static RicFileHierarchyDialogResult runRecursiveSearchDialog(QWidget *parent = nullptr, const QString& caption = QString(), @@ -66,15 +66,14 @@ class RicFileHierarchyDialog : public QDialog void appendToFileList(const QString& fileName); void clearFileList(); void updateStatus(Status status, const QString& extraText = ""); - QString currentStatus() const; QStringList findMatchingFiles(); QStringList buildDirectoryListRecursive(const QString& currentDir, int level = 0); - void buildDirectoryListRecursiveSimple(const QString& rootDir, - const QString& remainingPathFilter, - QStringList* accumulatedDirs); + void buildDirectoryListRecursiveSimple(const QString& currentDir, + const QString& currentPathFilter, + QStringList* accumulatedDirs); QStringList findFilesInDirs(const QStringList& dirs); @@ -87,6 +86,8 @@ class RicFileHierarchyDialog : public QDialog void setOkButtonEnabled(bool enabled); + void warningIfInvalidCharacters(); + private slots: void slotFilterChanged(const QString& text); void slotFileListCustomMenuRequested(const QPoint& point); diff --git a/ApplicationCode/Commands/RicFlyToObjectFeature.h b/ApplicationCode/Commands/RicFlyToObjectFeature.h index f8028c44d9..a0d2322cf8 100644 --- a/ApplicationCode/Commands/RicFlyToObjectFeature.h +++ b/ApplicationCode/Commands/RicFlyToObjectFeature.h @@ -35,9 +35,9 @@ class RicFlyToObjectFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual void onActionTriggered( bool isChecked ) override; - virtual bool isCommandEnabled() override; - virtual void setupActionLook( QAction* actionToSetup ) override; + void onActionTriggered( bool isChecked ) override; + bool isCommandEnabled() override; + void setupActionLook( QAction* actionToSetup ) override; private: static cvf::BoundingBox boundingBoxForSelectedObjects(); diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertExec.h b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertExec.h index 9eb488cafe..16202e1fbf 100644 --- a/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertExec.h +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertExec.h @@ -31,11 +31,11 @@ class RicGeoMechPropertyFilterInsertExec : public caf::CmdExecuteCommand { public: explicit RicGeoMechPropertyFilterInsertExec(RimGeoMechPropertyFilter* propertyFilter); - virtual ~RicGeoMechPropertyFilterInsertExec(); + ~RicGeoMechPropertyFilterInsertExec() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: caf::PdmPointer m_propertyFilter; diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertFeature.h b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertFeature.h index fa4730b9cc..6c201b3877 100644 --- a/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertFeature.h +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterInsertFeature.h @@ -31,9 +31,9 @@ class RicGeoMechPropertyFilterInsertFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterNewExec.h b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewExec.h index 32d77f2d51..678b410b0a 100644 --- a/ApplicationCode/Commands/RicGeoMechPropertyFilterNewExec.h +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewExec.h @@ -31,11 +31,11 @@ class RicGeoMechPropertyFilterNewExec : public caf::CmdExecuteCommand { public: explicit RicGeoMechPropertyFilterNewExec(RimGeoMechPropertyFilterCollection* propertyFilterCollection); - virtual ~RicGeoMechPropertyFilterNewExec(); + ~RicGeoMechPropertyFilterNewExec() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: caf::PdmPointer m_propertyFilterCollection; diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterNewFeature.h b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewFeature.h index 26114b98ec..e87d6645c3 100644 --- a/ApplicationCode/Commands/RicGeoMechPropertyFilterNewFeature.h +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewFeature.h @@ -31,9 +31,9 @@ class RicGeoMechPropertyFilterNewFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicGeoMechPropertyFilterNewInViewFeature.h b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewInViewFeature.h index b13b78e1ea..2b07a40c0e 100644 --- a/ApplicationCode/Commands/RicGeoMechPropertyFilterNewInViewFeature.h +++ b/ApplicationCode/Commands/RicGeoMechPropertyFilterNewInViewFeature.h @@ -29,9 +29,9 @@ class RicGeoMechPropertyFilterNewInViewFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicGridStatisticsDialog.cpp b/ApplicationCode/Commands/RicGridStatisticsDialog.cpp index 69479cf6cb..3fe3f8beb6 100644 --- a/ApplicationCode/Commands/RicGridStatisticsDialog.cpp +++ b/ApplicationCode/Commands/RicGridStatisticsDialog.cpp @@ -136,9 +136,10 @@ QImage RicGridStatisticsDialog::screenShotImage() //-------------------------------------------------------------------------------------------------- void RicGridStatisticsDialog::setInfoText(RimGridView* view) { - Rim3dOverlayInfoConfig* overlayInfo = view->overlayInfoConfig(); - if (view && overlayInfo) + if (view && view->overlayInfoConfig()) { + Rim3dOverlayInfoConfig* overlayInfo = view->overlayInfoConfig(); + QString text; text = overlayInfo->timeStepText(); text += overlayInfo->caseInfoText(); @@ -156,9 +157,10 @@ void RicGridStatisticsDialog::setHistogramData(RimGridView* view) deletePlotItems(m_historgramPlot); deletePlotItems(m_aggregatedPlot); - Rim3dOverlayInfoConfig* overlayInfo = view->overlayInfoConfig(); - if (view && overlayInfo) + if (view && view->overlayInfoConfig()) { + Rim3dOverlayInfoConfig* overlayInfo = view->overlayInfoConfig(); + auto hist = new QwtPlotHistogram("Histogram"); auto aggr = new QwtPlotCurve("Aggregated"); diff --git a/ApplicationCode/Commands/RicGridStatisticsDialog.h b/ApplicationCode/Commands/RicGridStatisticsDialog.h index b71d369845..ca36ffb689 100644 --- a/ApplicationCode/Commands/RicGridStatisticsDialog.h +++ b/ApplicationCode/Commands/RicGridStatisticsDialog.h @@ -44,7 +44,7 @@ class RicGridStatisticsDialog : public QDialog public: RicGridStatisticsDialog(QWidget* parent); - ~RicGridStatisticsDialog(); + ~RicGridStatisticsDialog() override; void setLabel(const QString& labelText); void updateFromRimView(RimGridView* rimView); diff --git a/ApplicationCode/Commands/RicHideIntersectionBoxFeature.h b/ApplicationCode/Commands/RicHideIntersectionBoxFeature.h index 0b7ef7508d..700ebacc3f 100644 --- a/ApplicationCode/Commands/RicHideIntersectionBoxFeature.h +++ b/ApplicationCode/Commands/RicHideIntersectionBoxFeature.h @@ -29,7 +29,7 @@ class RicHideIntersectionBoxFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicHideIntersectionFeature.h b/ApplicationCode/Commands/RicHideIntersectionFeature.h index 478eac695d..008ccf4218 100644 --- a/ApplicationCode/Commands/RicHideIntersectionFeature.h +++ b/ApplicationCode/Commands/RicHideIntersectionFeature.h @@ -29,7 +29,7 @@ class RicHideIntersectionFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicImportElementPropertyFeature.h b/ApplicationCode/Commands/RicImportElementPropertyFeature.h index 781af3fc47..848dda6a1d 100644 --- a/ApplicationCode/Commands/RicImportElementPropertyFeature.h +++ b/ApplicationCode/Commands/RicImportElementPropertyFeature.h @@ -28,7 +28,7 @@ class RicImportElementPropertyFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicImportEnsembleFeature.cpp b/ApplicationCode/Commands/RicImportEnsembleFeature.cpp index f07f96d69d..ea8e82a40d 100644 --- a/ApplicationCode/Commands/RicImportEnsembleFeature.cpp +++ b/ApplicationCode/Commands/RicImportEnsembleFeature.cpp @@ -49,60 +49,6 @@ CAF_CMD_SOURCE_INIT(RicImportEnsembleFeature, "RicImportEnsembleFeature"); -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RicImportEnsembleFeature::validateEnsembleCases(std::vector cases) -{ - // Validate ensemble parameters - try - { - QString errors; - std::hash paramsHasher; - size_t paramsHash = 0; - - for (RimSummaryCase* rimCase : cases) - { - if (rimCase->caseRealizationParameters() == nullptr || rimCase->caseRealizationParameters()->parameters().empty()) - { - errors.append(QString("The case %1 has no ensemble parameters\n").arg(QFileInfo(rimCase->summaryHeaderFilename()).fileName())); - } - else - { - QString paramNames; - for (std::pair paramPair : rimCase->caseRealizationParameters()->parameters()) - { - paramNames.append(paramPair.first); - } - - size_t currHash = paramsHasher(paramNames.toStdString()); - if (paramsHash == 0) - { - paramsHash = currHash; - } - else if (paramsHash != currHash) - { - throw QString("Ensemble parameters differ between cases"); - } - } - } - - if (!errors.isEmpty()) - { - throw errors; - } - return true; - } - catch (QString errorMessage) - { - QMessageBox mbox; - mbox.setIcon(QMessageBox::Icon::Warning); - mbox.setInformativeText(errorMessage); - mbox.exec(); - return false; - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -125,18 +71,15 @@ void RicImportEnsembleFeature::onActionTriggered(bool isChecked) if (ensembleName.isEmpty()) return; std::vector cases; - RicImportSummaryCasesFeature::createSummaryCasesFromFiles(fileNames, &cases); - - validateEnsembleCases(cases); + RicImportSummaryCasesFeature::createSummaryCasesFromFiles(fileNames, &cases, true); RicImportSummaryCasesFeature::addSummaryCases(cases); - RicCreateSummaryCaseCollectionFeature::groupSummaryCases(cases, ensembleName, true); + auto newGroup = RicCreateSummaryCaseCollectionFeature::groupSummaryCases(cases, ensembleName, true); RiuPlotMainWindow* mainPlotWindow = app->getOrCreateAndShowMainPlotWindow(); - if (mainPlotWindow && !cases.empty()) + if (mainPlotWindow && newGroup) { - mainPlotWindow->selectAsCurrentItem(cases.back()); - + mainPlotWindow->selectAsCurrentItem(newGroup); mainPlotWindow->updateSummaryPlotToolBar(); } diff --git a/ApplicationCode/Commands/RicImportEnsembleFeature.h b/ApplicationCode/Commands/RicImportEnsembleFeature.h index 62a7a80366..ea287b3f49 100644 --- a/ApplicationCode/Commands/RicImportEnsembleFeature.h +++ b/ApplicationCode/Commands/RicImportEnsembleFeature.h @@ -35,14 +35,11 @@ class RicImportEnsembleFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; -public: - static bool validateEnsembleCases(std::vector cases); - protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; QString askForEnsembleName(); }; diff --git a/ApplicationCode/Commands/RicImportFormationNamesFeature.h b/ApplicationCode/Commands/RicImportFormationNamesFeature.h index 45fa429425..cb24e3ddf3 100644 --- a/ApplicationCode/Commands/RicImportFormationNamesFeature.h +++ b/ApplicationCode/Commands/RicImportFormationNamesFeature.h @@ -29,9 +29,9 @@ class RicImportFormationNamesFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicImportGeoMechCaseFeature.h b/ApplicationCode/Commands/RicImportGeoMechCaseFeature.h index 8fe509c9de..e311408031 100644 --- a/ApplicationCode/Commands/RicImportGeoMechCaseFeature.h +++ b/ApplicationCode/Commands/RicImportGeoMechCaseFeature.h @@ -29,9 +29,9 @@ class RicImportGeoMechCaseFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.cpp b/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.cpp new file mode 100644 index 0000000000..a29077cc76 --- /dev/null +++ b/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.cpp @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicImportGeoMechCaseTimeStepFilterFeature.h" + +#include "RiaApplication.h" +#include "RiaImportEclipseCaseTools.h" + +#include "Riu3DMainWindowTools.h" + +#include +#include +#include + +CAF_CMD_SOURCE_INIT(RicImportGeoMechCaseTimeStepFilterFeature, "RicImportGeoMechCaseTimeStepFilterFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportGeoMechCaseTimeStepFilterFeature::onActionTriggered(bool isChecked) +{ + RiaApplication* app = RiaApplication::instance(); + + QString defaultDir = app->lastUsedDialogDirectory("GEOMECH_MODEL"); + QStringList fileNames = QFileDialog::getOpenFileNames(nullptr, "Import Geo-Mechanical Model", defaultDir, "Abaqus results (*.odb)"); + if (fileNames.size()) defaultDir = QFileInfo(fileNames.last()).absolutePath(); + for (QString fileName : fileNames) + { + if (!fileName.isEmpty()) + { + defaultDir = QFileInfo(fileName).absolutePath(); + app->setLastUsedDialogDirectory("GEOMECH_MODEL", defaultDir); + if (app->openOdbCaseFromFile(fileName, true)) + { + app->addToRecentFiles(fileName); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicImportGeoMechCaseTimeStepFilterFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setIcon(QIcon(":/GeoMechCase48x48.png")); + actionToSetup->setText("Import Geo Mechanical Model (Time Step Filtered)"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicImportGeoMechCaseTimeStepFilterFeature::isCommandEnabled() +{ + return true; +} diff --git a/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.h b/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.h new file mode 100644 index 0000000000..5e913eaa83 --- /dev/null +++ b/ApplicationCode/Commands/RicImportGeoMechCaseTimeStepFilterFeature.h @@ -0,0 +1,38 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +#include + +//================================================================================================== +/// +//================================================================================================== +class RicImportGeoMechCaseTimeStepFilterFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; +}; + + diff --git a/ApplicationCode/Commands/RicImportObservedDataFeature.h b/ApplicationCode/Commands/RicImportObservedDataFeature.h index 918bfca24c..bcf0f1508b 100644 --- a/ApplicationCode/Commands/RicImportObservedDataFeature.h +++ b/ApplicationCode/Commands/RicImportObservedDataFeature.h @@ -36,7 +36,7 @@ class RicImportObservedDataFeature : public caf::CmdFeature static void selectObservedDataFileInDialog(); private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/RicImportObservedDataInMenuFeature.h b/ApplicationCode/Commands/RicImportObservedDataInMenuFeature.h index 69e65f1817..691ca57243 100644 --- a/ApplicationCode/Commands/RicImportObservedDataInMenuFeature.h +++ b/ApplicationCode/Commands/RicImportObservedDataInMenuFeature.h @@ -35,7 +35,7 @@ class RicImportObservedDataInMenuFeature : public caf::CmdFeature RicImportObservedDataInMenuFeature(); private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/RicImportSummaryCaseFeature.cpp b/ApplicationCode/Commands/RicImportSummaryCaseFeature.cpp index b7384398d2..50726cbb97 100644 --- a/ApplicationCode/Commands/RicImportSummaryCaseFeature.cpp +++ b/ApplicationCode/Commands/RicImportSummaryCaseFeature.cpp @@ -54,7 +54,6 @@ bool RicImportSummaryCaseFeature::isCommandEnabled() void RicImportSummaryCaseFeature::onActionTriggered(bool isChecked) { RiaApplication* app = RiaApplication::instance(); - RiaPreferences* prefs = app->preferences(); QString defaultDir = app->lastUsedDialogDirectory("INPUT_FILES"); QStringList fileNames_ = QFileDialog::getOpenFileNames(nullptr, "Import Summary Case", defaultDir, "Eclipse Summary File (*.SMSPEC);;All Files (*.*)"); diff --git a/ApplicationCode/Commands/RicImportSummaryCaseFeature.h b/ApplicationCode/Commands/RicImportSummaryCaseFeature.h index 22171cb8b9..f24f7405e5 100644 --- a/ApplicationCode/Commands/RicImportSummaryCaseFeature.h +++ b/ApplicationCode/Commands/RicImportSummaryCaseFeature.h @@ -31,9 +31,9 @@ class RicImportSummaryCaseFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicImportSummaryCasesFeature.cpp b/ApplicationCode/Commands/RicImportSummaryCasesFeature.cpp index 82f162376c..173d79c0e9 100644 --- a/ApplicationCode/Commands/RicImportSummaryCasesFeature.cpp +++ b/ApplicationCode/Commands/RicImportSummaryCasesFeature.cpp @@ -127,10 +127,10 @@ bool RicImportSummaryCasesFeature::createAndAddSummaryCasesFromFiles(const QStri mainPlotWindow->updateSummaryPlotToolBar(); // Close main window if there are no eclipse cases imported - std::vector cases; - app->project()->allCases(cases); + std::vector allCases; + app->project()->allCases(allCases); - if (cases.size() == 0) + if (allCases.size() == 0) { RiuMainWindow::instance()->close(); } @@ -145,7 +145,8 @@ bool RicImportSummaryCasesFeature::createAndAddSummaryCasesFromFiles(const QStri /// //-------------------------------------------------------------------------------------------------- bool RicImportSummaryCasesFeature::createSummaryCasesFromFiles(const QStringList& fileNames, - std::vector* newCases) + std::vector* newCases, + bool ensembleOrGroup) { RiaApplication* app = RiaApplication::instance(); RimProject* proj = app->project(); @@ -155,6 +156,7 @@ bool RicImportSummaryCasesFeature::createSummaryCasesFromFiles(const QStringList if (!sumCaseColl) return false; RifSummaryCaseRestartSelector fileSelector; + fileSelector.setEnsembleOrGroupMode(ensembleOrGroup); fileSelector.determineFilesToImportFromSummaryFiles(fileNames); std::vector importFileInfos = fileSelector.summaryFileInfos(); @@ -169,7 +171,7 @@ bool RicImportSummaryCasesFeature::createSummaryCasesFromFiles(const QStringList { QString errorMessage = fileSelector.createCombinedErrorMessage(); RiaLogging::error(errorMessage); - QMessageBox::warning(NULL, QString("Problem Importing Summary Case File(s)"), errorMessage); + QMessageBox::warning(nullptr, QString("Problem Importing Summary Case File(s)"), errorMessage); } return true; diff --git a/ApplicationCode/Commands/RicImportSummaryCasesFeature.h b/ApplicationCode/Commands/RicImportSummaryCasesFeature.h index 15c6f18a00..3efc668cc8 100644 --- a/ApplicationCode/Commands/RicImportSummaryCasesFeature.h +++ b/ApplicationCode/Commands/RicImportSummaryCasesFeature.h @@ -39,7 +39,7 @@ class RicImportSummaryCasesFeature : public caf::CmdFeature RicImportSummaryCasesFeature() { } static bool createAndAddSummaryCasesFromFiles(const QStringList& fileName, std::vector* newCases = nullptr); - static bool createSummaryCasesFromFiles(const QStringList& fileName, std::vector* newCases); + static bool createSummaryCasesFromFiles(const QStringList& fileName, std::vector* newCases, bool ensembleOrGroup = false); static void addSummaryCases(const std::vector cases); static void addCasesToGroupIfRelevant(const std::vector cases); @@ -47,9 +47,9 @@ class RicImportSummaryCasesFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static QString m_pathFilter; diff --git a/ApplicationCode/Commands/RicImportSummaryGroupFeature.cpp b/ApplicationCode/Commands/RicImportSummaryGroupFeature.cpp index fb3c3f9647..24f899cef0 100644 --- a/ApplicationCode/Commands/RicImportSummaryGroupFeature.cpp +++ b/ApplicationCode/Commands/RicImportSummaryGroupFeature.cpp @@ -66,7 +66,7 @@ void RicImportSummaryGroupFeature::onActionTriggered(bool isChecked) if (fileNames.isEmpty()) return; std::vector cases; - RicImportSummaryCasesFeature::createSummaryCasesFromFiles(fileNames, &cases); + RicImportSummaryCasesFeature::createSummaryCasesFromFiles(fileNames, &cases, true); RicImportSummaryCasesFeature::addSummaryCases(cases); RicCreateSummaryCaseCollectionFeature::groupSummaryCases(cases, "", false); diff --git a/ApplicationCode/Commands/RicImportSummaryGroupFeature.h b/ApplicationCode/Commands/RicImportSummaryGroupFeature.h index c75b1a89c2..1c96f0fbbc 100644 --- a/ApplicationCode/Commands/RicImportSummaryGroupFeature.h +++ b/ApplicationCode/Commands/RicImportSummaryGroupFeature.h @@ -37,9 +37,9 @@ class RicImportSummaryGroupFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicNewContourMapViewFeature.cpp b/ApplicationCode/Commands/RicNewContourMapViewFeature.cpp new file mode 100644 index 0000000000..8f579cd1e6 --- /dev/null +++ b/ApplicationCode/Commands/RicNewContourMapViewFeature.cpp @@ -0,0 +1,196 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewContourMapViewFeature.h" + +#include "RimContourMapView.h" +#include "RimContourMapViewCollection.h" +#include "RimCellEdgeColors.h" +#include "RimEclipseView.h" +#include "RimEclipseCase.h" +#include "RimEclipseCellColors.h" +#include "Rim3dView.h" + +#include "Riu3DMainWindowTools.h" + +#include "RiaApplication.h" +#include "RiaLogging.h" +#include "RiaPreferences.h" + +#include "cafPdmDocument.h" +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicNewContourMapViewFeature, "RicNewContourMapViewFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewContourMapViewFeature::isCommandEnabled() +{ + bool selectedView = caf::SelectionManager::instance()->selectedItemOfType() != nullptr; + bool selectedCase = caf::SelectionManager::instance()->selectedItemOfType() != nullptr; + bool selectedMapCollection = caf::SelectionManager::instance()->selectedItemOfType(); + return selectedView || selectedCase || selectedMapCollection; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewContourMapViewFeature::onActionTriggered(bool isChecked) +{ + RimEclipseView* reservoirView = caf::SelectionManager::instance()->selectedItemOfType(); + RimContourMapView* existingContourMap = caf::SelectionManager::instance()->selectedItemOfType(); + RimEclipseCase* eclipseCase = caf::SelectionManager::instance()->selectedItemAncestorOfType(); + RimContourMapView* contourMap = nullptr; + + // Find case to insert into + if (existingContourMap) + { + contourMap = create2dContourMapFromExistingContourMap(eclipseCase, existingContourMap); + } + else if (reservoirView) + { + contourMap = create2dContourMapFrom3dView(eclipseCase, reservoirView); + } + else if (eclipseCase) + { + contourMap = create2dContourMap(eclipseCase); + } + + if (contourMap) + { + // Must be run before buildViewItems, as wells are created in this function + contourMap->loadDataAndUpdate(); + + if (eclipseCase) + { + eclipseCase->updateConnectedEditors(); + } + caf::SelectionManager::instance()->setSelectedItem(contourMap); + + contourMap->createDisplayModelAndRedraw(); + contourMap->zoomAll(); + + Riu3DMainWindowTools::setExpanded(contourMap); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewContourMapViewFeature::setupActionLook(QAction* actionToSetup) +{ + RimContourMapView* contourMap = caf::SelectionManager::instance()->selectedItemOfType(); + RimEclipseView* eclipseView = caf::SelectionManager::instance()->selectedItemOfType(); + if (contourMap) + { + actionToSetup->setText("Duplicate Contour Map"); + } + else if (eclipseView) + { + actionToSetup->setText("New Contour Map From 3d View"); + } + else + { + actionToSetup->setText("New Contour Map"); + } + actionToSetup->setIcon(QIcon(":/2DMap16x16.png")); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapView* RicNewContourMapViewFeature::create2dContourMapFromExistingContourMap(RimEclipseCase* eclipseCase, RimContourMapView* existingContourMap) +{ + RimContourMapView* contourMap = + dynamic_cast(existingContourMap->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); + CVF_ASSERT(contourMap); + + contourMap->setEclipseCase(eclipseCase); + contourMap->setBackgroundColor(cvf::Color3f(1.0f, 1.0f, 0.98f)); // Ignore original view background + + caf::PdmDocument::updateUiIconStateRecursively(contourMap); + + size_t i = eclipseCase->contourMapCollection()->views().size(); + contourMap->setName(QString("Contour Map %1").arg(i + 1)); + eclipseCase->contourMapCollection()->push_back(contourMap); + + // Resolve references after contour map has been inserted into Rim structures + contourMap->resolveReferencesRecursively(); + contourMap->initAfterReadRecursively(); + + return contourMap; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapView* RicNewContourMapViewFeature::create2dContourMapFrom3dView(RimEclipseCase* eclipseCase, const RimEclipseView* sourceView) +{ + RimContourMapView* contourMap = dynamic_cast(sourceView->xmlCapability()->copyAndCastByXmlSerialization( + RimContourMapView::classKeywordStatic(), sourceView->classKeyword(), caf::PdmDefaultObjectFactory::instance())); + CVF_ASSERT(contourMap); + + contourMap->setEclipseCase(eclipseCase); + contourMap->setBackgroundColor(cvf::Color3f(1.0f, 1.0f, 0.98f)); // Ignore original view background + + caf::PdmDocument::updateUiIconStateRecursively(contourMap); + + size_t i = eclipseCase->contourMapCollection()->views().size(); + contourMap->setName(QString("Contour Map %1").arg(i + 1)); + eclipseCase->contourMapCollection()->push_back(contourMap); + + // Resolve references after contour map has been inserted into Rim structures + contourMap->resolveReferencesRecursively(); + contourMap->initAfterReadRecursively(); + + return contourMap; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapView* RicNewContourMapViewFeature::create2dContourMap(RimEclipseCase* eclipseCase) +{ + RimContourMapView* contourMap = new RimContourMapView(); + contourMap->setEclipseCase(eclipseCase); + + // Set default values + { + contourMap->cellResult()->setResultType(RiaDefines::DYNAMIC_NATIVE); + + if (RiaApplication::instance()->preferences()->loadAndShowSoil) + { + contourMap->cellResult()->setResultVariable("SOIL"); + } + } + + caf::PdmDocument::updateUiIconStateRecursively(contourMap); + + size_t i = eclipseCase->contourMapCollection()->views().size(); + contourMap->setName(QString("Contour Map %1").arg(i + 1)); + eclipseCase->contourMapCollection()->push_back(contourMap); + + contourMap->hasUserRequestedAnimation = true; + contourMap->setBackgroundColor(cvf::Color3f(1.0f, 1.0f, 0.98f)); + contourMap->initAfterReadRecursively(); + + return contourMap; +} diff --git a/ApplicationCode/Commands/RicNewContourMapViewFeature.h b/ApplicationCode/Commands/RicNewContourMapViewFeature.h new file mode 100644 index 0000000000..9338249b4d --- /dev/null +++ b/ApplicationCode/Commands/RicNewContourMapViewFeature.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimEclipseCase; +class RimContourMapView; +class RimEclipseView; + +//================================================================================================== +/// +//================================================================================================== +class RicNewContourMapViewFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; + + static RimContourMapView* create2dContourMapFromExistingContourMap(RimEclipseCase* eclipseCase, RimContourMapView* existingContourMap); + static RimContourMapView* create2dContourMapFrom3dView(RimEclipseCase* eclipseCase, const RimEclipseView* reservoirView); + static RimContourMapView* create2dContourMap(RimEclipseCase* eclipseCase); + +}; diff --git a/ApplicationCode/Commands/RicNewSliceRangeFilterFeature.h b/ApplicationCode/Commands/RicNewSliceRangeFilterFeature.h index 2562c1a1b1..0d1919b80e 100644 --- a/ApplicationCode/Commands/RicNewSliceRangeFilterFeature.h +++ b/ApplicationCode/Commands/RicNewSliceRangeFilterFeature.h @@ -28,7 +28,7 @@ class RicNewSliceRangeFilterFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicNewViewFeature.cpp b/ApplicationCode/Commands/RicNewViewFeature.cpp index ad7410c283..775ec094ea 100644 --- a/ApplicationCode/Commands/RicNewViewFeature.cpp +++ b/ApplicationCode/Commands/RicNewViewFeature.cpp @@ -19,6 +19,7 @@ #include "RicNewViewFeature.h" +#include "RimContourMapView.h" #include "RimEclipseCase.h" #include "RimEclipseView.h" #include "RimGeoMechCase.h" @@ -158,9 +159,12 @@ RimEclipseView* RicNewViewFeature::selectedEclipseView() std::vector selection; caf::SelectionManager::instance()->objectsByType(&selection); - if (selection.size() > 0) + for (RimEclipseView* view : selection) { - return selection[0]; + if (dynamic_cast(view) == nullptr) + { + return view; + } } return nullptr; diff --git a/ApplicationCode/Commands/RicNewViewFeature.h b/ApplicationCode/Commands/RicNewViewFeature.h index b94dbc1dae..0f34a54607 100644 --- a/ApplicationCode/Commands/RicNewViewFeature.h +++ b/ApplicationCode/Commands/RicNewViewFeature.h @@ -39,9 +39,9 @@ class RicNewViewFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static Rim3dView* createReservoirView(RimEclipseCase* eclipseCase, RimGeoMechCase* geomCase); diff --git a/ApplicationCode/Commands/RicViewerEventInterface.h b/ApplicationCode/Commands/RicPickEventHandler.h similarity index 60% rename from ApplicationCode/Commands/RicViewerEventInterface.h rename to ApplicationCode/Commands/RicPickEventHandler.h index 690597e7a5..34f828df79 100644 --- a/ApplicationCode/Commands/RicViewerEventInterface.h +++ b/ApplicationCode/Commands/RicPickEventHandler.h @@ -24,6 +24,7 @@ #include "cvfBase.h" #include "cvfObject.h" #include "cvfVector3.h" +#include "RiuPickItemInfo.h" namespace cvf { class Part; @@ -34,28 +35,37 @@ class Rim3dView; //================================================================================================== /// //================================================================================================== -class RicViewerEventObject +class Ric3DPickEvent { public: - RicViewerEventObject(cvf::Vec3d globalIntersectionPoint, const std::vector>& partAndTriangleIndexPairs, Rim3dView* view) - : m_globalIntersectionPoint(globalIntersectionPoint), - m_partAndTriangleIndexPairs(partAndTriangleIndexPairs), - m_view(view) + Ric3DPickEvent(const std::vector& pickItemInfos, + Rim3dView* view) + : m_pickItemInfos(pickItemInfos) + , m_view(view) { } - cvf::Vec3d m_globalIntersectionPoint; - std::vector> m_partAndTriangleIndexPairs; - Rim3dView* m_view; + std::vector m_pickItemInfos; + Rim3dView* m_view; }; //================================================================================================== -/// +/// A static always-on pick handler used in the RiuViewerCommand +//================================================================================================== +class RicDefaultPickEventHandler +{ +public: + virtual bool handlePickEvent(const Ric3DPickEvent& eventObject) = 0; +}; + +//================================================================================================== +/// A temporary, dynamic pick handler that overrides the default ones //================================================================================================== -class RicViewerEventInterface +class RicPickEventHandler { public: - virtual bool handleEvent(const RicViewerEventObject& eventObject) = 0; + virtual bool handlePickEvent(const Ric3DPickEvent& eventObject) = 0; + virtual void notifyUnregistered() = 0; }; diff --git a/ApplicationCode/Commands/RicRangeFilterExecImpl.cpp b/ApplicationCode/Commands/RicRangeFilterExecImpl.cpp index 6e1315ec3b..d6aef01621 100644 --- a/ApplicationCode/Commands/RicRangeFilterExecImpl.cpp +++ b/ApplicationCode/Commands/RicRangeFilterExecImpl.cpp @@ -64,7 +64,7 @@ RimCellRangeFilter* RicRangeFilterExecImpl::createRangeFilter() size_t flterIndex = m_cellRangeFilterCollection->rangeFilters().size() + 1; - rangeFilter->gridIndex = m_gridIndex; + rangeFilter->setGridIndex(m_gridIndex); rangeFilter->name = QString("New Filter (%1)").arg(flterIndex); @@ -91,7 +91,7 @@ RimCellRangeFilter* RicRangeFilterExecImpl::createRangeFilter() //-------------------------------------------------------------------------------------------------- void RicRangeFilterExecImpl::applyCommandDataOnFilter(RimCellRangeFilter* rangeFilter) { - rangeFilter->gridIndex = m_gridIndex; + rangeFilter->setGridIndex(m_gridIndex); if (m_iSlice) { rangeFilter->cellCountI = 1; diff --git a/ApplicationCode/Commands/RicRangeFilterExecImpl.h b/ApplicationCode/Commands/RicRangeFilterExecImpl.h index c63a21edc0..b54eea1717 100644 --- a/ApplicationCode/Commands/RicRangeFilterExecImpl.h +++ b/ApplicationCode/Commands/RicRangeFilterExecImpl.h @@ -33,11 +33,11 @@ class RicRangeFilterExecImpl : public caf::CmdExecuteCommand public: RicRangeFilterExecImpl(RimCellRangeFilterCollection* rangeFilterCollection, RimCellRangeFilter* insertBeforeCellRangeFilter = nullptr); - virtual ~RicRangeFilterExecImpl(); + ~RicRangeFilterExecImpl() override; - virtual QString name() = 0; - virtual void redo() = 0; - virtual void undo() = 0; + QString name() override = 0; + void redo() override = 0; + void undo() override = 0; public: bool m_iSlice; diff --git a/ApplicationCode/Commands/RicRangeFilterInsertExec.h b/ApplicationCode/Commands/RicRangeFilterInsertExec.h index 392cddd5fe..256565e011 100644 --- a/ApplicationCode/Commands/RicRangeFilterInsertExec.h +++ b/ApplicationCode/Commands/RicRangeFilterInsertExec.h @@ -31,11 +31,11 @@ class RicRangeFilterInsertExec : public RicRangeFilterExecImpl { public: RicRangeFilterInsertExec(RimCellRangeFilterCollection* rangeFilterCollection, RimCellRangeFilter* rangeFilter = nullptr); - virtual ~RicRangeFilterInsertExec(); + ~RicRangeFilterInsertExec() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; }; diff --git a/ApplicationCode/Commands/RicRangeFilterInsertFeature.h b/ApplicationCode/Commands/RicRangeFilterInsertFeature.h index 9f47055d74..4eb6d8fc62 100644 --- a/ApplicationCode/Commands/RicRangeFilterInsertFeature.h +++ b/ApplicationCode/Commands/RicRangeFilterInsertFeature.h @@ -34,9 +34,9 @@ class RicRangeFilterInsertFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static std::vector selectedCellRangeFilters(); diff --git a/ApplicationCode/Commands/RicRangeFilterNewExec.cpp b/ApplicationCode/Commands/RicRangeFilterNewExec.cpp index c116de9ec4..a70783f329 100644 --- a/ApplicationCode/Commands/RicRangeFilterNewExec.cpp +++ b/ApplicationCode/Commands/RicRangeFilterNewExec.cpp @@ -77,11 +77,10 @@ void RicRangeFilterNewExec::redo() Riu3DMainWindowTools::selectAsCurrentItem(rangeFilter); + // Trigger update of view following the range filter update RimGridView* view = nullptr; m_cellRangeFilterCollection->firstAncestorOrThisOfTypeAsserted(view); - - //Enable display of grid cells, to be able to show generated range filter - view->showGridCells(true); + view->rangeFiltersUpdated(); } } diff --git a/ApplicationCode/Commands/RicRangeFilterNewExec.h b/ApplicationCode/Commands/RicRangeFilterNewExec.h index ee9c41a058..3415695635 100644 --- a/ApplicationCode/Commands/RicRangeFilterNewExec.h +++ b/ApplicationCode/Commands/RicRangeFilterNewExec.h @@ -28,11 +28,11 @@ class RicRangeFilterNewExec : public RicRangeFilterExecImpl { public: RicRangeFilterNewExec(RimCellRangeFilterCollection* rangeFilterCollection, RimCellRangeFilter* rangeFilter = nullptr); - virtual ~RicRangeFilterNewExec(); + ~RicRangeFilterNewExec() override; - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; }; diff --git a/ApplicationCode/Commands/RicRangeFilterNewFeature.h b/ApplicationCode/Commands/RicRangeFilterNewFeature.h index e1fb158788..5b30d46405 100644 --- a/ApplicationCode/Commands/RicRangeFilterNewFeature.h +++ b/ApplicationCode/Commands/RicRangeFilterNewFeature.h @@ -30,9 +30,9 @@ class RicRangeFilterNewFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicRangeFilterNewSliceIFeature.h b/ApplicationCode/Commands/RicRangeFilterNewSliceIFeature.h index 3d74f5c4a6..cfd556a1e9 100644 --- a/ApplicationCode/Commands/RicRangeFilterNewSliceIFeature.h +++ b/ApplicationCode/Commands/RicRangeFilterNewSliceIFeature.h @@ -31,9 +31,9 @@ class RicRangeFilterNewSliceIFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicRangeFilterNewSliceJFeature.h b/ApplicationCode/Commands/RicRangeFilterNewSliceJFeature.h index 38c3190a7d..6869349426 100644 --- a/ApplicationCode/Commands/RicRangeFilterNewSliceJFeature.h +++ b/ApplicationCode/Commands/RicRangeFilterNewSliceJFeature.h @@ -31,9 +31,9 @@ class RicRangeFilterNewSliceJFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicRangeFilterNewSliceKFeature.h b/ApplicationCode/Commands/RicRangeFilterNewSliceKFeature.h index 4bcbc28ec2..4c1560794e 100644 --- a/ApplicationCode/Commands/RicRangeFilterNewSliceKFeature.h +++ b/ApplicationCode/Commands/RicRangeFilterNewSliceKFeature.h @@ -31,9 +31,9 @@ class RicRangeFilterNewSliceKFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicReloadCaseFeature.cpp b/ApplicationCode/Commands/RicReloadCaseFeature.cpp index 7519b4c719..1c9ae9328c 100644 --- a/ApplicationCode/Commands/RicReloadCaseFeature.cpp +++ b/ApplicationCode/Commands/RicReloadCaseFeature.cpp @@ -2,25 +2,29 @@ // // Copyright (C) 2015- Statoil ASA // Copyright (C) 2015- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RicReloadCaseFeature.h" +#include "RiaApplication.h" + #include "RimEclipseCase.h" +#include "RiuSelectionManager.h" + #include "cafPdmObject.h" #include "cafSelectionManager.h" @@ -29,13 +33,14 @@ CAF_CMD_SOURCE_INIT(RicReloadCaseFeature, "RicReloadCaseFeature"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RicReloadCaseFeature::isCommandEnabled() { std::vector selectedFormationNamesCollObjs; caf::SelectionManager::instance()->objectsByType(&selectedFormationNamesCollObjs); - for (caf::PdmObject* pdmObject : selectedFormationNamesCollObjs) { + for (caf::PdmObject* pdmObject : selectedFormationNamesCollObjs) + { if (dynamic_cast(pdmObject)) { return true; @@ -46,13 +51,15 @@ bool RicReloadCaseFeature::isCommandEnabled() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicReloadCaseFeature::onActionTriggered(bool isChecked) { std::vector selectedEclipseCases; caf::SelectionManager::instance()->objectsByType(&selectedEclipseCases); + RiaApplication::clearAllSelections(); + for (RimEclipseCase* selectedCase : selectedEclipseCases) { selectedCase->reloadDataAndUpdate(); @@ -60,7 +67,7 @@ void RicReloadCaseFeature::onActionTriggered(bool isChecked) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicReloadCaseFeature::setupActionLook(QAction* actionToSetup) { diff --git a/ApplicationCode/Commands/RicReloadCaseFeature.h b/ApplicationCode/Commands/RicReloadCaseFeature.h index 95bf4b7752..de49b40abc 100644 --- a/ApplicationCode/Commands/RicReloadCaseFeature.h +++ b/ApplicationCode/Commands/RicReloadCaseFeature.h @@ -26,7 +26,7 @@ class RicReloadCaseFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled(); - virtual void onActionTriggered(bool isChecked); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/RicReloadFormationNamesFeature.h b/ApplicationCode/Commands/RicReloadFormationNamesFeature.h index 2cb07e72f2..77b9c9609e 100644 --- a/ApplicationCode/Commands/RicReloadFormationNamesFeature.h +++ b/ApplicationCode/Commands/RicReloadFormationNamesFeature.h @@ -29,9 +29,9 @@ class RicReloadFormationNamesFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicReloadSummaryCaseFeature.h b/ApplicationCode/Commands/RicReloadSummaryCaseFeature.h index 76dc459f20..8d751621bd 100644 --- a/ApplicationCode/Commands/RicReloadSummaryCaseFeature.h +++ b/ApplicationCode/Commands/RicReloadSummaryCaseFeature.h @@ -29,9 +29,9 @@ class RicReloadSummaryCaseFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled(); - virtual void onActionTriggered(bool isChecked); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; private: static std::vector selectedSummaryCases(); diff --git a/ApplicationCode/Commands/RicReloadWellPathFormationNamesFeature.h b/ApplicationCode/Commands/RicReloadWellPathFormationNamesFeature.h index be72688abe..def1da4a34 100644 --- a/ApplicationCode/Commands/RicReloadWellPathFormationNamesFeature.h +++ b/ApplicationCode/Commands/RicReloadWellPathFormationNamesFeature.h @@ -28,9 +28,9 @@ class RicReloadWellPathFormationNamesFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicResampleDialog.cpp b/ApplicationCode/Commands/RicResampleDialog.cpp new file mode 100644 index 0000000000..a184584952 --- /dev/null +++ b/ApplicationCode/Commands/RicResampleDialog.cpp @@ -0,0 +1,140 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicResampleDialog.h" + +#include "RiaApplication.h" + +#include "RiuTools.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DEFAULT_DIALOG_WIDTH 250 +#define DEFAULT_DIALOG_HEIGHT 100 +#define DEFAULT_DIALOG_TITLE "Export Plot Data" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicResampleDialog::RicResampleDialog(QWidget* parent) + : QDialog(parent, RiuTools::defaultDialogFlags()) +{ + // Create widgets + m_label = new QLabel(); + m_timePeriodCombo = new QComboBox(); + + m_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + // Connect to signals + connect(m_buttons, SIGNAL(accepted()), this, SLOT(slotDialogOkClicked())); + connect(m_buttons, SIGNAL(rejected()), this, SLOT(slotDialogCancelClicked())); + + // Set widget properties + m_label->setText("Resampling Period"); + + // Define layout + QVBoxLayout* dialogLayout = new QVBoxLayout(); + + QHBoxLayout* periodLayout = new QHBoxLayout(); + periodLayout->addWidget(m_label); + periodLayout->addWidget(m_timePeriodCombo); + + dialogLayout->addLayout(periodLayout); + dialogLayout->addWidget(m_buttons); + + setLayout(dialogLayout); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicResampleDialog::~RicResampleDialog() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicResampleDialogResult RicResampleDialog::openDialog(QWidget *parent /*= 0*/, + const QString &caption /*= QString()*/) +{ + RicResampleDialog dialog(parent); + + if(!caption.isEmpty()) dialog.setWindowTitle(caption); + else dialog.setWindowTitle(DEFAULT_DIALOG_TITLE); + + dialog.setPeriodOptions(RiaQDateTimeTools::dateTimePeriods()); + + dialog.resize(DEFAULT_DIALOG_WIDTH, DEFAULT_DIALOG_HEIGHT); + dialog.exec(); + + return RicResampleDialogResult(dialog.result() == QDialog::Accepted, dialog.selectedDateTimePeriod()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicResampleDialog::setPeriodOptions(const std::vector& dateTimePeriods) +{ + QStringList s; + for (auto& period : dateTimePeriods) + { + QString text = period != DateTimePeriod::NONE ? RiaQDateTimeTools::dateTimePeriodName(period) : "No Resampling"; + m_timePeriodCombo->addItem(text, QVariant((int)period)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +DateTimePeriod RicResampleDialog::selectedDateTimePeriod() const +{ + int currIndex = m_timePeriodCombo->currentIndex(); + return (DateTimePeriod)m_timePeriodCombo->itemData(currIndex).toInt(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicResampleDialog::slotDialogOkClicked() +{ + accept(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicResampleDialog::slotDialogCancelClicked() +{ + reject(); +} diff --git a/ApplicationCode/Commands/RicResampleDialog.h b/ApplicationCode/Commands/RicResampleDialog.h new file mode 100644 index 0000000000..8da195d24c --- /dev/null +++ b/ApplicationCode/Commands/RicResampleDialog.h @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaQDateTimeTools.h" + +#include "cafPdmPointer.h" + +#include + +class QLabel; +class QComboBox; +class QLineEdit; +class QTextEdit; +class QDialogButtonBox; +class QPushButton; +class QMainWindow; +class QListWidget; +class RicResampleDialogResult; +class DateTimePeriodInfo; + +//================================================================================================== +/// +//================================================================================================== +class RicResampleDialog : public QDialog +{ + Q_OBJECT + +public: + RicResampleDialog(QWidget* parent); + ~RicResampleDialog() override; + + static RicResampleDialogResult openDialog(QWidget *parent = nullptr, + const QString& caption = QString()); + +private: + void setPeriodOptions(const std::vector& dateTimePeriods); + DateTimePeriod selectedDateTimePeriod() const; + +private slots: + void slotDialogOkClicked(); + void slotDialogCancelClicked(); + +private: + QLabel* m_label; + QComboBox* m_timePeriodCombo; + + QDialogButtonBox* m_buttons; +}; + + +//================================================================================================== +/// +//================================================================================================== +class RicResampleDialogResult +{ +public: + RicResampleDialogResult(bool ok, DateTimePeriod period) : + ok(ok), period(period) {} + + bool ok; + DateTimePeriod period; +}; \ No newline at end of file diff --git a/ApplicationCode/Commands/RicSelectColorResult.h b/ApplicationCode/Commands/RicSelectColorResult.h index d46ec5e87e..94954ab9e1 100644 --- a/ApplicationCode/Commands/RicSelectColorResult.h +++ b/ApplicationCode/Commands/RicSelectColorResult.h @@ -28,7 +28,7 @@ class RicSelectColorResult : public caf::CmdFeature CAF_CMD_HEADER_INIT; private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/RicSelectOrCreateViewFeatureImpl.cpp b/ApplicationCode/Commands/RicSelectOrCreateViewFeatureImpl.cpp index 629c067807..a63eff9d59 100644 --- a/ApplicationCode/Commands/RicSelectOrCreateViewFeatureImpl.cpp +++ b/ApplicationCode/Commands/RicSelectOrCreateViewFeatureImpl.cpp @@ -56,7 +56,7 @@ RimEclipseView* RicSelectOrCreateViewFeatureImpl::showViewSelection(RimEclipseRe if (featureUi.createNewView()) { RimEclipseView* createdView = resultCase->createAndAddReservoirView(); - createdView->name = featureUi.newViewName(); + createdView->setName(featureUi.newViewName()); // Must be run before buildViewItems, as wells are created in this function createdView->loadDataAndUpdate(); diff --git a/ApplicationCode/Commands/RicShowGridStatisticsFeature.h b/ApplicationCode/Commands/RicShowGridStatisticsFeature.h index 70009ecd17..528c45016e 100644 --- a/ApplicationCode/Commands/RicShowGridStatisticsFeature.h +++ b/ApplicationCode/Commands/RicShowGridStatisticsFeature.h @@ -30,7 +30,7 @@ class RicShowGridStatisticsFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/RicSummaryCaseRestartDialog.cpp b/ApplicationCode/Commands/RicSummaryCaseRestartDialog.cpp index ecc1b08d56..5a227b6eee 100644 --- a/ApplicationCode/Commands/RicSummaryCaseRestartDialog.cpp +++ b/ApplicationCode/Commands/RicSummaryCaseRestartDialog.cpp @@ -64,38 +64,6 @@ #define DEFAULT_DIALOG_INIT_HEIGHT 150 -//-------------------------------------------------------------------------------------------------- -/// Internal functions -//-------------------------------------------------------------------------------------------------- -std::vector>> removeCommonRootPath(const std::vector>& fileInfoLists) -{ - // Find common root path among all paths - QStringList allPaths; - for (const auto& fileInfoList : fileInfoLists) - { - for (const auto fi : fileInfoList) allPaths.push_back(fi.fileName); - } - QString commonRoot = RiaFilePathTools::commonRootPath(allPaths); - int commonRootSize = commonRoot.size(); - - // Build output lists - std::vector>> output; - for (const auto& fileInfoList : fileInfoLists) - { - std::vector> currList; - - for (auto& fi : fileInfoList) - { - std::pair newFi; - newFi = std::make_pair(fi, fi.fileName); - newFi.first.fileName.remove(0, commonRootSize); - currList.push_back(newFi); - } - output.push_back(currList); - } - return output; -} - //-------------------------------------------------------------------------------------------------- /// Internal functions //-------------------------------------------------------------------------------------------------- @@ -246,11 +214,24 @@ RicSummaryCaseRestartDialogResult RicSummaryCaseRestartDialog::openDialog(const const QString& initialGridFile, bool failOnSummaryImportError, bool showApplyToAllWidget, + bool useFirstSummaryCaseAsTemplate, ImportOptions defaultSummaryImportOption, ImportOptions defaultGridImportOption, RicSummaryCaseRestartDialogResult* lastResult, QWidget* parent) { + RicSummaryCaseRestartDialogResult dialogResult; + if (lastResult && lastResult->applyToAll && lastResult->summaryImportOption != SEPARATE_CASES) + { + dialogResult = *lastResult; + dialogResult.summaryFiles.clear(); + dialogResult.gridFiles.clear(); + + if (!initialSummaryFile.isEmpty()) dialogResult.summaryFiles.push_back(initialSummaryFile); + if (!initialGridFile.isEmpty()) dialogResult.gridFiles.push_back(initialGridFile); + return dialogResult; + } + RicSummaryCaseRestartDialog dialog(parent); bool handleSummaryFile = false; @@ -288,11 +269,9 @@ RicSummaryCaseRestartDialogResult RicSummaryCaseRestartDialog::openDialog(const defaultGridImportOption, {}, QStringList({ initialGridFile }), - lastResult && lastResult->applyToAll); + useFirstSummaryCaseAsTemplate || (lastResult && lastResult->applyToAll)); } - - RifReaderEclipseSummary reader; bool hasWarnings = false; std::vector originFileInfos = reader.getRestartFiles(initialSummaryFile, &hasWarnings); @@ -303,10 +282,9 @@ RicSummaryCaseRestartDialogResult RicSummaryCaseRestartDialog::openDialog(const return RicSummaryCaseRestartDialogResult(RicSummaryCaseRestartDialogResult::SUMMARY_OK, NOT_IMPORT, NOT_IMPORT, QStringList({ initialSummaryFile }), QStringList({ initialGridFile }), - lastResult->applyToAll); + useFirstSummaryCaseAsTemplate || lastResult->applyToAll); } - RicSummaryCaseRestartDialogResult dialogResult; if (lastResult && lastResult->applyToAll) { dialogResult = *lastResult; @@ -385,7 +363,7 @@ RicSummaryCaseRestartDialogResult RicSummaryCaseRestartDialog::openDialog(const // Set properties and show dialog dialog.setWindowTitle("Origin Files"); - dialog.m_buttons->button(QDialogButtonBox::Apply)->setVisible(showApplyToAllWidget); + dialog.m_buttons->button(QDialogButtonBox::Apply)->setVisible(!useFirstSummaryCaseAsTemplate && showApplyToAllWidget); dialog.resize(DEFAULT_DIALOG_WIDTH, DEFAULT_DIALOG_INIT_HEIGHT); QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); @@ -404,7 +382,7 @@ RicSummaryCaseRestartDialogResult RicSummaryCaseRestartDialog::openDialog(const dialog.selectedGridImportOption(), {}, {}, - dialog.okToAllSelected()); + useFirstSummaryCaseAsTemplate || dialog.okToAllSelected()); } if (dialogResult.status != RicSummaryCaseRestartDialogResult::SUMMARY_OK) @@ -599,7 +577,6 @@ void RicSummaryCaseRestartDialog::slotShowFullPathToggled(int state) //-------------------------------------------------------------------------------------------------- void RicSummaryCaseRestartDialog::slotDialogButtonClicked(QAbstractButton* button) { - bool okButtonClicked = m_buttons->button(QDialogButtonBox::Ok) == button; bool cancelButtonClicked = m_buttons->button(QDialogButtonBox::Cancel) == button; bool okToAllButtonClicked = m_buttons->button(QDialogButtonBox::Apply) == button; diff --git a/ApplicationCode/Commands/RicSummaryCaseRestartDialog.h b/ApplicationCode/Commands/RicSummaryCaseRestartDialog.h index 56ead54171..4fd16ae581 100644 --- a/ApplicationCode/Commands/RicSummaryCaseRestartDialog.h +++ b/ApplicationCode/Commands/RicSummaryCaseRestartDialog.h @@ -59,12 +59,13 @@ class RicSummaryCaseRestartDialog : public QDialog enum ImportOptions { IMPORT_ALL, SEPARATE_CASES, NOT_IMPORT }; RicSummaryCaseRestartDialog(QWidget* parent); - ~RicSummaryCaseRestartDialog(); + ~RicSummaryCaseRestartDialog() override; static RicSummaryCaseRestartDialogResult openDialog(const QString& initialSummaryFile, const QString& initialGridFile, bool failOnSummaryImportError, bool showApplyToAllWidget, + bool useFirstSummaryCaseAsTemplate, ImportOptions defaultSummaryImportOption, ImportOptions defaultGridImportOption, RicSummaryCaseRestartDialogResult *lastResult = nullptr, diff --git a/ApplicationCode/Commands/RicTogglePerspectiveViewFeature.cpp b/ApplicationCode/Commands/RicTogglePerspectiveViewFeature.cpp index 404c8a46bc..2058516e33 100644 --- a/ApplicationCode/Commands/RicTogglePerspectiveViewFeature.cpp +++ b/ApplicationCode/Commands/RicTogglePerspectiveViewFeature.cpp @@ -20,7 +20,9 @@ #include "RicTogglePerspectiveViewFeature.h" #include "RiuViewer.h" +#include "RimContourMapView.h" #include "Rim3dView.h" +#include "RimGridView.h" #include "RiuMainWindow.h" #include "RiaApplication.h" @@ -34,7 +36,9 @@ CAF_CMD_SOURCE_INIT(RicTogglePerspectiveViewFeature, "RicTogglePerspectiveViewFe bool RicTogglePerspectiveViewFeature::isCommandEnabled() { this->action(); // Retrieve the action to update the looks - return RiaApplication::instance()->activeGridView() && RiaApplication::instance()->activeReservoirView()->viewer(); + RimGridView* activeGridView = RiaApplication::instance()->activeGridView(); + RimContourMapView* view2d = dynamic_cast(activeGridView); + return !view2d && activeGridView && RiaApplication::instance()->activeReservoirView()->viewer(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/RicTogglePerspectiveViewFeature.h b/ApplicationCode/Commands/RicTogglePerspectiveViewFeature.h index c0a02c7002..7346091da6 100644 --- a/ApplicationCode/Commands/RicTogglePerspectiveViewFeature.h +++ b/ApplicationCode/Commands/RicTogglePerspectiveViewFeature.h @@ -31,9 +31,9 @@ class RicTogglePerspectiveViewFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/RicWellLogTools.cpp b/ApplicationCode/Commands/RicWellLogTools.cpp index 3eaa5e3c8e..242af85174 100644 --- a/ApplicationCode/Commands/RicWellLogTools.cpp +++ b/ApplicationCode/Commands/RicWellLogTools.cpp @@ -42,17 +42,6 @@ #include "cafSelectionManager.h" - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellLogTrack* RicWellLogTools::selectedWellLogPlotTrack() -{ - std::vector selection; - caf::SelectionManager::instance()->objectsByType(&selection); - return selection.size() > 0 ? selection[0] : nullptr; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -74,35 +63,6 @@ RimSimWellInView* RicWellLogTools::selectedSimulationWell(int *branchIndex) } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPath* RicWellLogTools::selectedWellPath() -{ - std::vector selection; - caf::SelectionManager::instance()->objectsByType(&selection); - return selection.size() > 0 ? selection[0] : nullptr; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPath* RicWellLogTools::findWellPathFromSelection() -{ - std::vector selection; - caf::SelectionManager::instance()->objectsByType(&selection); - if (selection.size() > 0) - { - caf::PdmObject* firstSelection = selection[0]; - RimWellPath* wellPath; - firstSelection->firstAncestorOrThisOfType(wellPath); - if (wellPath) - { - return wellPath; - } - } - return nullptr; -} //-------------------------------------------------------------------------------------------------- /// @@ -195,7 +155,7 @@ RimWellPath* RicWellLogTools::selectedWellPathWithLogFile() //-------------------------------------------------------------------------------------------------- RimWellPath* RicWellLogTools::findWellPathWithLogFileFromSelection() { - RimWellPath* wellPath = findWellPathFromSelection(); + RimWellPath* wellPath = caf::SelectionManager::instance()->selectedItemAncestorOfType(); if (wellPath->wellLogFiles().size() > 0) { return wellPath; @@ -206,7 +166,13 @@ RimWellPath* RicWellLogTools::findWellPathWithLogFileFromSelection() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellLogExtractionCurve* RicWellLogTools::addExtractionCurve(RimWellLogTrack* plotTrack, Rim3dView* view, RimWellPath* wellPath, const RimSimWellInView* simWell, int branchIndex, bool useBranchDetection) +RimWellLogExtractionCurve* RicWellLogTools::addExtractionCurve(RimWellLogTrack* plotTrack, + Rim3dView* view, + RimWellPath* wellPath, + const RimSimWellInView* simWell, + int branchIndex, + bool useBranchDetection, + bool showPlotWindow) { CVF_ASSERT(plotTrack); RimWellLogExtractionCurve* curve = new RimWellLogExtractionCurve(); @@ -238,20 +204,23 @@ RimWellLogExtractionCurve* RicWellLogTools::addExtractionCurve(RimWellLogTrack* plotTrack->updateConnectedEditors(); - // Make sure the summary plot window is created and visible - RiuPlotMainWindowTools::showPlotMainWindow(); - RiaApplication::instance()->project()->updateConnectedEditors(); - + RiaApplication::instance()->getOrCreateMainPlotWindow(); RiuPlotMainWindowTools::selectAsCurrentItem(curve); + if (showPlotWindow) + { + // Make sure the summary plot window is visible + RiuPlotMainWindowTools::showPlotMainWindow(); + } + return curve; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellLogRftCurve* RicWellLogTools::addRftCurve(RimWellLogTrack* plotTrack, const RimSimWellInView* simWell) +RimWellLogRftCurve* RicWellLogTools::addRftCurve(RimWellLogTrack* plotTrack, const RimSimWellInView* simWell, bool showPlotWindow) { CVF_ASSERT(plotTrack); @@ -287,19 +256,23 @@ RimWellLogRftCurve* RicWellLogTools::addRftCurve(RimWellLogTrack* plotTrack, con plotTrack->setFormationTrajectoryType(RimWellLogTrack::SIMULATION_WELL); plotTrack->updateConnectedEditors(); - RiuPlotMainWindowTools::showPlotMainWindow(); - RiaApplication::instance()->project()->updateConnectedEditors(); - + RiaApplication::instance()->getOrCreateMainPlotWindow(); RiuPlotMainWindowTools::selectAsCurrentItem(curve); + if (showPlotWindow) + { + // Make sure the summary plot window is visible + RiuPlotMainWindowTools::showPlotMainWindow(); + } + return curve; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellLogFileCurve* RicWellLogTools::addFileCurve(RimWellLogTrack* plotTrack) +RimWellLogFileCurve* RicWellLogTools::addFileCurve(RimWellLogTrack* plotTrack, bool showPlotWindow) { CVF_ASSERT(plotTrack); @@ -312,8 +285,15 @@ RimWellLogFileCurve* RicWellLogTools::addFileCurve(RimWellLogTrack* plotTrack) plotTrack->updateConnectedEditors(); - RiuPlotMainWindowTools::showPlotMainWindow(); + RiaApplication::instance()->project()->updateConnectedEditors(); + RiaApplication::instance()->getOrCreateMainPlotWindow(); RiuPlotMainWindowTools::selectAsCurrentItem(curve); + if (showPlotWindow) + { + // Make sure the summary plot window is visible + RiuPlotMainWindowTools::showPlotMainWindow(); + } + return curve; } diff --git a/ApplicationCode/Commands/RicWellLogTools.h b/ApplicationCode/Commands/RicWellLogTools.h index e9f671288c..a84ee40ffc 100644 --- a/ApplicationCode/Commands/RicWellLogTools.h +++ b/ApplicationCode/Commands/RicWellLogTools.h @@ -38,10 +38,7 @@ class RimWellPath; class RicWellLogTools { public: - static RimWellLogTrack* selectedWellLogPlotTrack(); static RimSimWellInView* selectedSimulationWell(int* branchIndex); - static RimWellPath* selectedWellPath(); - static RimWellPath* findWellPathFromSelection(); static bool wellHasRftData(const QString& wellName); static bool isWellPathOrSimWellSelectedInView(); static void addWellLogChannelsToPlotTrack(RimWellLogTrack* plotTrack, @@ -50,7 +47,8 @@ class RicWellLogTools static RimWellPath* findWellPathWithLogFileFromSelection(); static RimWellLogExtractionCurve* addExtractionCurve(RimWellLogTrack* plotTrack, Rim3dView* view, RimWellPath* wellPath, const RimSimWellInView* simWell, int branchIndex, - bool useBranchDetection); - static RimWellLogRftCurve* addRftCurve(RimWellLogTrack* plotTrack, const RimSimWellInView* simWell); - static RimWellLogFileCurve* addFileCurve(RimWellLogTrack* plotTrack); + bool useBranchDetection, + bool showPlotWindow = true); + static RimWellLogRftCurve* addRftCurve(RimWellLogTrack* plotTrack, const RimSimWellInView* simWell, bool showPlotWindow = true); + static RimWellLogFileCurve* addFileCurve(RimWellLogTrack* plotTrack, bool showPlotWindow = true); }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/SummaryPlotCommands/CMakeLists_files.cmake index ff9d3e59fc..3a6d690770 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/SummaryPlotCommands/CMakeLists_files.cmake @@ -34,6 +34,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculator.h ${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryCrossPlotCurveFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryEnsembleCurveSetFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicPasteEnsembleCurveSetFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicNewEnsembleCurveFilterFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicNewDerivedEnsembleFeature.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -71,6 +73,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculator.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryCrossPlotCurveFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryEnsembleCurveSetFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicPasteEnsembleCurveSetFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicNewEnsembleCurveFilterFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicNewDerivedEnsembleFeature.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicAsciiExportSummaryPlotFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicAsciiExportSummaryPlotFeature.cpp index 42800378a9..52385fb5dd 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicAsciiExportSummaryPlotFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicAsciiExportSummaryPlotFeature.cpp @@ -21,6 +21,8 @@ #include "RiaApplication.h" #include "RiaLogging.h" +#include "RicResampleDialog.h" + #include "RimSummaryPlot.h" #include "RiuMainWindow.h" @@ -57,26 +59,24 @@ void RicAsciiExportSummaryPlotFeature::onActionTriggered(bool isChecked) { this->disableModelChangeContribution(); - RiaApplication* app = RiaApplication::instance(); - QString projectFolder = app->currentProjectPath(); - - RimProject* project = RiaApplication::instance()->project(); - CVF_ASSERT(project); - std::vector selectedSummaryPlots; caf::SelectionManager::instance()->objectsByType(&selectedSummaryPlots); - QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallback("PLOT_ASCIIEXPORT_DIR", projectFolder); + QString defaultDir = defaultExportDir(); - caf::ProgressInfo pi(selectedSummaryPlots.size(), QString("Exporting plot data to ASCII")); - size_t progress = 0; + // Ask user about resampling + auto result = RicResampleDialog::openDialog(); + if (!result.ok) return; if (selectedSummaryPlots.size() == 1) { RimSummaryPlot* summaryPlot = selectedSummaryPlots.at(0); - QString defaultFileName = defaultDir + "/" + caf::Utils::makeValidFileBasename((summaryPlot->description())) + ".ascii"; - QString fileName = QFileDialog::getSaveFileName(nullptr, "Select File for Summary Plot Export", defaultFileName, "Text File(*.ascii);;All files(*.*)"); + QString fileName = getFileNameFromUserDialog(summaryPlot->description(), defaultDir); if (fileName.isEmpty()) return; - RicAsciiExportSummaryPlotFeature::exportAsciiForSummaryPlot(fileName, summaryPlot); + + caf::ProgressInfo pi(selectedSummaryPlots.size(), QString("Exporting plot data to ASCII")); + size_t progress = 0; + + RicAsciiExportSummaryPlotFeature::exportAsciiForSummaryPlot(fileName, summaryPlot, result.period); progress++; pi.setProgress(progress); @@ -94,11 +94,14 @@ void RicAsciiExportSummaryPlotFeature::onActionTriggered(bool isChecked) bool writeFiles = caf::Utils::getSaveDirectoryAndCheckOverwriteFiles(defaultDir, fileNames, &saveDir); if (!writeFiles) return; + caf::ProgressInfo pi(selectedSummaryPlots.size(), QString("Exporting plot data to ASCII")); + size_t progress = 0; + RiaLogging::info(QString("Writing to directory %1").arg(saveDir)); for (RimSummaryPlot* summaryPlot : selectedSummaryPlots) { QString fileName = saveDir + "/" + caf::Utils::makeValidFileBasename(summaryPlot->description()) + ".ascii"; - RicAsciiExportSummaryPlotFeature::exportAsciiForSummaryPlot(fileName, summaryPlot); + RicAsciiExportSummaryPlotFeature::exportAsciiForSummaryPlot(fileName, summaryPlot, result.period); progress++; pi.setProgress(progress); } @@ -117,7 +120,25 @@ void RicAsciiExportSummaryPlotFeature::setupActionLook(QAction* actionToSetup) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RicAsciiExportSummaryPlotFeature::exportAsciiForSummaryPlot(const QString& fileName, const RimSummaryPlot* summaryPlot) +QString RicAsciiExportSummaryPlotFeature::defaultExportDir() +{ + return RiaApplication::instance()->lastUsedDialogDirectoryWithFallbackToProjectFolder("PLOT_ASCIIEXPORT_DIR"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RicAsciiExportSummaryPlotFeature::getFileNameFromUserDialog(const QString& fileNameCandidate, const QString& defaultDir) +{ + QString defaultFileName = defaultDir + "/" + caf::Utils::makeValidFileBasename(fileNameCandidate) + ".ascii"; + QString fileName = QFileDialog::getSaveFileName(nullptr, "Select File for Summary Plot Export", defaultFileName, "Text File(*.ascii);;All files(*.*)"); + return fileName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicAsciiExportSummaryPlotFeature::exportTextToFile(const QString& fileName, const QString& text) { QFile file(fileName); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) @@ -128,13 +149,25 @@ bool RicAsciiExportSummaryPlotFeature::exportAsciiForSummaryPlot(const QString& RiaLogging::info(QString("Writing values for summary plot(s) to file: %1").arg(fileName)); QTextStream out(&file); - - out << summaryPlot->description(); - out << summaryPlot->asciiDataForPlotExport(); - out << "\n\n"; + + out << text; RiaLogging::info(QString("Competed writing values for summary plot(s) to file %1").arg(fileName)); return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicAsciiExportSummaryPlotFeature::exportAsciiForSummaryPlot(const QString& fileName, + const RimSummaryPlot* summaryPlot, + DateTimePeriod resamplingPeriod) +{ + QString text = summaryPlot->description(); + text.append(summaryPlot->asciiDataForPlotExport(resamplingPeriod)); + text.append("\n\n"); + + return exportTextToFile(fileName, text); +} + diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicAsciiExportSummaryPlotFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicAsciiExportSummaryPlotFeature.h index b603b23777..df0e622c32 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicAsciiExportSummaryPlotFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicAsciiExportSummaryPlotFeature.h @@ -18,6 +18,8 @@ #pragma once +#include "RiaQDateTimeTools.h" + #include "cafCmdFeature.h" class RimSummaryPlot; @@ -29,11 +31,18 @@ class RicAsciiExportSummaryPlotFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; +public: + static QString defaultExportDir(); + static QString getFileNameFromUserDialog(const QString& fileNameCandidate, const QString& defaultDir); + static bool exportTextToFile(const QString& fileName, const QString& text); + protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: - static bool exportAsciiForSummaryPlot(const QString& fileName, const RimSummaryPlot* selectedSummaryPlots); + static bool exportAsciiForSummaryPlot(const QString& fileName, + const RimSummaryPlot* selectedSummaryPlots, + DateTimePeriod resamplingPeriod); }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCrossPlotCurveFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCrossPlotCurveFeature.h index 58438cad7b..b6eaf3994f 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCrossPlotCurveFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCrossPlotCurveFeature.h @@ -35,6 +35,6 @@ class RicDuplicateSummaryCrossPlotCurveFeature : public RicDuplicateSummaryCurve protected: // Overrides - virtual bool isCommandEnabled(); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCrossPlotFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCrossPlotFeature.h index a247fa562f..657a752cc7 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCrossPlotFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCrossPlotFeature.h @@ -33,7 +33,7 @@ class RicDuplicateSummaryCrossPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCurveFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCurveFeature.h index 03c9862bc0..09932838cb 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCurveFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryCurveFeature.h @@ -32,7 +32,7 @@ class RicDuplicateSummaryCurveFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryPlotFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryPlotFeature.h index aa1e0bba11..085dae8ede 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryPlotFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicDuplicateSummaryPlotFeature.h @@ -33,7 +33,7 @@ class RicDuplicateSummaryPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCrossPlotFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCrossPlotFeature.cpp index 38c67c532c..8927943274 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCrossPlotFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCrossPlotFeature.cpp @@ -81,9 +81,6 @@ bool RicEditSummaryCrossPlotFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicEditSummaryCrossPlotFeature::onActionTriggered(bool isChecked) { - RimProject* project = RiaApplication::instance()->project(); - CVF_ASSERT(project); - auto dialog = RicEditSummaryCrossPlotFeature::curveCreatorDialog(); if (!dialog->isVisible()) diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCrossPlotFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCrossPlotFeature.h index f7e393d61b..033f216e5e 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCrossPlotFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCrossPlotFeature.h @@ -38,9 +38,9 @@ class RicEditSummaryCrossPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCurveCalculationFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCurveCalculationFeature.h index 951687fcf8..c4b28f070e 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCurveCalculationFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryCurveCalculationFeature.h @@ -32,7 +32,7 @@ class RicEditSummaryCurveCalculationFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryPlotFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryPlotFeature.cpp index 6b8c47a56b..84a3ebb320 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryPlotFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryPlotFeature.cpp @@ -83,9 +83,6 @@ bool RicEditSummaryPlotFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicEditSummaryPlotFeature::onActionTriggered(bool isChecked) { - RimProject* project = RiaApplication::instance()->project(); - CVF_ASSERT(project); - auto dialog = RicEditSummaryPlotFeature::curveCreatorDialog(); if (!dialog->isVisible()) diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryPlotFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryPlotFeature.h index b595e4f2bf..41c55f1884 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryPlotFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicEditSummaryPlotFeature.h @@ -38,9 +38,9 @@ class RicEditSummaryPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewDerivedEnsembleFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicNewDerivedEnsembleFeature.cpp new file mode 100644 index 0000000000..ffa32e1e06 --- /dev/null +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewDerivedEnsembleFeature.cpp @@ -0,0 +1,119 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewDerivedEnsembleFeature.h" + +#include "RiaApplication.h" + +#include "RimDerivedEnsembleCaseCollection.h" +#include "RimProject.h" +#include "RimSummaryCaseMainCollection.h" + +#include "RiuPlotMainWindowTools.h" + +#include "cafSelectionManagerTools.h" + +#include +#include + +#include + + +CAF_CMD_SOURCE_INIT(RicNewDerivedEnsembleFeature, "RicNewDerivedEnsembleFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewDerivedEnsembleFeature::showWarningDialog() +{ + QMessageBox::warning(nullptr, "Ensemble Matching", "None of the cases in the ensembles match"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewDerivedEnsembleFeature::showWarningDialogWithQuestion() +{ + QMessageBox msgBox; + msgBox.setIcon(QMessageBox::Question); + msgBox.setWindowTitle("Ensemble Matching"); + msgBox.setText("None of the cases in the ensembles match"); + msgBox.setInformativeText("Do you want to keep the derived ensemble?"); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + + int ret = msgBox.exec(); + return ret == QMessageBox::Yes; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewDerivedEnsembleFeature::isCommandEnabled() +{ + std::vector mainColls = caf::selectedObjectsByTypeStrict(); + std::vector ensembles = caf::selectedObjectsByTypeStrict(); + + return mainColls.size() == 1 || ensembles.size() == 1 || ensembles.size() == 2; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewDerivedEnsembleFeature::onActionTriggered(bool isChecked) +{ + if (isCommandEnabled()) + { + auto project = RiaApplication::instance()->project(); + auto mainColl = project->firstSummaryCaseMainCollection(); + + auto newColl = mainColl->addCaseCollection({}, "", true, []() {return new RimDerivedEnsembleCaseCollection(); }); + auto newEnsemble = dynamic_cast(newColl); + + { + std::vector ensembles = caf::selectedObjectsByType(); + + if (ensembles.size() >= 1) newEnsemble->setEnsemble1(ensembles[0]); + if (ensembles.size() == 2) + { + newEnsemble->setEnsemble2(ensembles[1]); + newEnsemble->updateDerivedEnsembleCases(); + + if (newEnsemble->allSummaryCases().empty()) + { + if(!showWarningDialogWithQuestion()) + { + mainColl->removeCaseCollection(newEnsemble); + } + } + } + } + + mainColl->updateConnectedEditors(); + RiuPlotMainWindowTools::selectAsCurrentItem(newEnsemble); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewDerivedEnsembleFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Derived Ensemble"); + actionToSetup->setIcon(QIcon(":/SummaryEnsemble16x16.png")); +} + diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewDerivedEnsembleFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicNewDerivedEnsembleFeature.h new file mode 100644 index 0000000000..57defa8352 --- /dev/null +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewDerivedEnsembleFeature.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimSummaryPlotCollection; +class RimSummaryCase; +class RimSummaryPlot; + +//================================================================================================== +/// +//================================================================================================== +class RicNewDerivedEnsembleFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +public: + static void showWarningDialog(); + static bool showWarningDialogWithQuestion(); + +protected: + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; +}; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewEnsembleCurveFilterFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicNewEnsembleCurveFilterFeature.cpp new file mode 100644 index 0000000000..50f1eeca92 --- /dev/null +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewEnsembleCurveFilterFeature.cpp @@ -0,0 +1,68 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewEnsembleCurveFilterFeature.h" + +#include "RiaApplication.h" + +#include "RimEnsembleCurveFilter.h" +#include "RimEnsembleCurveFilterCollection.h" +#include "RimEnsembleCurveSet.h" + +#include "RiuPlotMainWindowTools.h" + +#include "cafSelectionManagerTools.h" + +#include + +CAF_CMD_SOURCE_INIT(RicNewEnsembleCurveFilterFeature, "RicNewEnsembleCurveFilterFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewEnsembleCurveFilterFeature::isCommandEnabled() +{ + std::vector filterColls = caf::selectedObjectsByType(); + + return filterColls.size() == 1; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewEnsembleCurveFilterFeature::onActionTriggered(bool isChecked) +{ + std::vector filterColls = caf::selectedObjectsByType(); + + if (filterColls.size() == 1) + { + filterColls[0]->addFilter(); + filterColls[0]->updateConnectedEditors(); + RiuPlotMainWindowTools::selectAsCurrentItem(filterColls.front()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewEnsembleCurveFilterFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Ensemble Curve Filter"); + actionToSetup->setIcon(QIcon(":/SummaryCurveFilter16x16.png")); +} + diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewEnsembleCurveFilterFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicNewEnsembleCurveFilterFeature.h new file mode 100644 index 0000000000..8f1dfd46cd --- /dev/null +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewEnsembleCurveFilterFeature.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimSummaryPlotCollection; +class RimSummaryCase; +class RimSummaryPlot; + +//================================================================================================== +/// +//================================================================================================== +class RicNewEnsembleCurveFilterFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; +}; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewGridTimeHistoryCurveFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicNewGridTimeHistoryCurveFeature.h index e165e3a6ee..08fcfc7a61 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicNewGridTimeHistoryCurveFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewGridTimeHistoryCurveFeature.h @@ -32,9 +32,9 @@ class RicNewGridTimeHistoryCurveFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static void createCurveFromSelectionItem(const RiuSelectionItem* selectionItem, RimSummaryPlot* plot); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.h index bb44bc3a4f..8a00569540 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotCurveFeature.h @@ -31,9 +31,9 @@ class RicNewSummaryCrossPlotCurveFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: RimSummaryCrossPlot* selectedCrossPlot() const; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotFeature.cpp index 55803c2e12..f47408e3a3 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotFeature.cpp @@ -65,7 +65,11 @@ bool RicNewSummaryCrossPlotFeature::isCommandEnabled() for (auto item : selectedItems) { - if (!dynamic_cast(item) && !dynamic_cast(item)) + RimSummaryCase* sumCase = dynamic_cast(item); + RimSummaryCaseCollection* sumGroup = dynamic_cast(item); + + if (sumGroup && sumGroup->isEnsemble()) sumGroup = nullptr; + if (!sumCase && !sumGroup) return false; } return true; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotFeature.h index 6ae446eba0..c4958a0d36 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCrossPlotFeature.h @@ -33,7 +33,7 @@ class RicNewSummaryCrossPlotFeature : public caf::CmdFeature private: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCurveFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCurveFeature.cpp index 3d040f8929..1d5d324280 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCurveFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCurveFeature.cpp @@ -73,7 +73,7 @@ void RicNewSummaryCurveFeature::onActionTriggered(bool isChecked) defaultCase = project->activeOilField()->summaryCaseMainCollection()->summaryCase(0); newCurve->setSummaryCaseY(defaultCase); - newCurve->setSummaryAddressY(RifEclipseSummaryAddress::fieldVarAddress("FOPT")); + newCurve->setSummaryAddressY(RifEclipseSummaryAddress::fieldAddress("FOPT")); newCurve->loadDataAndUpdate(true); } diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCurveFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCurveFeature.h index b2c675d6f6..fc752e4cd2 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCurveFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryCurveFeature.h @@ -32,9 +32,9 @@ class RicNewSummaryCurveFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: RimSummaryPlot* selectedSummaryPlot() const; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp index 17c7954952..d9d8039433 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp @@ -67,7 +67,12 @@ void RicNewSummaryEnsembleCurveSetFeature::onActionTriggered(bool isChecked) { RimEnsembleCurveSet* curveSet = new RimEnsembleCurveSet(); - size_t colorIndex = plot->ensembleCurveSetCollection()->curveSetCount(); + // Set single curve set color + auto allCurveSets = plot->ensembleCurveSetCollection()->curveSets(); + size_t colorIndex = std::count_if(allCurveSets.begin(), allCurveSets.end(), [](RimEnsembleCurveSet* curveSet) + { + return curveSet->colorMode() == RimEnsembleCurveSet::SINGLE_COLOR; + }); curveSet->setColor(RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f(colorIndex)); curveSet->legendConfig()->setColorRange(RimEnsembleCurveSetColorManager::cycledEnsembleColorRange(static_cast(colorIndex))); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.h index 23fd99166f..9460b44534 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.h @@ -32,9 +32,9 @@ class RicNewSummaryEnsembleCurveSetFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: RimSummaryPlot* selectedSummaryPlot() const; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryPlotFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryPlotFeature.cpp index 6a95c1067e..73f5724800 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryPlotFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryPlotFeature.cpp @@ -26,17 +26,21 @@ #include "RicSummaryCurveCreator.h" #include "RicSummaryCurveCreatorDialog.h" +#include "RimEnsembleCurveFilter.h" +#include "RimEnsembleCurveFilterCollection.h" +#include "RimRegularLegendConfig.h" #include "RimSummaryCurveFilter.h" #include "RimSummaryPlot.h" #include "RimSummaryPlotCollection.h" #include "RimSummaryCase.h" #include "RimSummaryCaseCollection.h" +#include "RimProject.h" +#include "RimSummaryCaseMainCollection.h" #include "RiuPlotMainWindow.h" #include "cvfAssert.h" #include "cafSelectionManagerTools.h" -//#include "cafPdmUiItem.h" #include @@ -56,6 +60,11 @@ bool RicNewSummaryPlotFeature::isCommandEnabled() sumPlotColl = RiaSummaryTools::parentSummaryPlotCollection(selObj); } + auto ensembleFilter = dynamic_cast(selObj); + auto ensembleFilterColl = dynamic_cast(selObj); + auto legendConfig = dynamic_cast(selObj); + + if (ensembleFilter || ensembleFilterColl || legendConfig) return false; if (sumPlotColl) return true; // Multiple case selections @@ -80,11 +89,37 @@ void RicNewSummaryPlotFeature::onActionTriggered(bool isChecked) std::vector selectedCases = caf::selectedObjectsByType(); std::vector selectedGroups = caf::selectedObjectsByType(); + std::vector sourcesToSelect(selectedCases.begin(), selectedCases.end()); + + if (sourcesToSelect.empty() && selectedGroups.empty()) + { + const auto allSingleCases = project->firstSummaryCaseMainCollection()->topLevelSummaryCases(); + const auto allGroups = project->summaryGroups(); + std::vector allEnsembles; + for (const auto group : allGroups) if (group->isEnsemble()) allEnsembles.push_back(group); + + if (!allSingleCases.empty()) + { + sourcesToSelect.push_back(allSingleCases.front()); + } + else if (!allEnsembles.empty()) + { + sourcesToSelect.push_back(allEnsembles.front()); + } + } + // Append grouped cases for (auto group : selectedGroups) { - auto groupCases = group->allSummaryCases(); - selectedCases.insert(selectedCases.end(), groupCases.begin(), groupCases.end()); + if (group->isEnsemble()) + { + sourcesToSelect.push_back(group); + } + else + { + auto groupCases = group->allSummaryCases(); + sourcesToSelect.insert(sourcesToSelect.end(), groupCases.begin(), groupCases.end()); + } } auto dialog = RicEditSummaryPlotFeature::curveCreatorDialog(); @@ -98,7 +133,7 @@ void RicNewSummaryPlotFeature::onActionTriggered(bool isChecked) dialog->raise(); } - dialog->updateFromDefaultCases(selectedCases); + dialog->updateFromDefaultCases(sourcesToSelect); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryPlotFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryPlotFeature.h index a038dde3a1..d936e2ac10 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryPlotFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicNewSummaryPlotFeature.h @@ -33,7 +33,7 @@ class RicNewSummaryPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataCurveFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataCurveFeature.h index f1e48dff5d..aa864ebc08 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataCurveFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataCurveFeature.h @@ -34,9 +34,9 @@ class RicPasteAsciiDataCurveFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: static std::vector > asciiDataCurves(); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeature.cpp index 94bd772344..f866b41d36 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeature.cpp @@ -184,7 +184,7 @@ std::vector RicPasteAsciiDataToSummaryPlotFeature::parseCurv if (col->dataType != Column::NUMERIC) continue; RimAsciiDataCurve* curve = new RimAsciiDataCurve(); - curve->setTimeSteps(parser.dateTimeColumn()->dateTimeValues); + curve->setTimeSteps(parser.dateTimeColumn()->qDateTimeValues()); curve->setValues(parser.columnInfo(i)->values); if (curvePrefix.isEmpty()) { @@ -197,7 +197,7 @@ std::vector RicPasteAsciiDataToSummaryPlotFeature::parseCurv // Appearance curve->setSymbol(parseOptions.curveSymbol); curve->setLineStyle(parseOptions.curveLineStyle); - curve->setSymbolSkipDinstance(parseOptions.curveSymbolSkipDistance); + curve->setSymbolSkipDistance(parseOptions.curveSymbolSkipDistance); curveToTypeMap[guessCurveType(QString::fromStdString(col->columnName()))].push_back(curve); curves.push_back(curve); } diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeature.h index e670fcfad5..d1ac79315e 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeature.h @@ -47,9 +47,9 @@ class RicPasteAsciiDataToSummaryPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: static QString getPastedData(); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeatureUi.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeatureUi.cpp index 631f6c8054..ff79605f53 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeatureUi.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeatureUi.cpp @@ -53,10 +53,11 @@ namespace caf { template<> void RicPasteAsciiDataToSummaryPlotFeatureUi::TimeFormatEnum::setUp() { + addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_NONE, "", "None"); addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_HHMM, "hh:mm", "Hour:Minute (hh:mm)"); addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_HHMMSS, "hh:mm:ss", "Hour:Minute:Second (hh:mm:ss)"); addItem(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_HHMMSSZZZ, "hh:mm:ss.zzz", "Hour:Minute:Second.Millisecond (hh:mm:ss.zzz)"); - setDefault(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_HHMM); + setDefault(RicPasteAsciiDataToSummaryPlotFeatureUi::TIME_NONE); } template<> @@ -166,8 +167,8 @@ RicPasteAsciiDataToSummaryPlotFeatureUi::RicPasteAsciiDataToSummaryPlotFeatureUi CAF_PDM_InitField(&m_useCustomDateFormat, "UseCustomDateFormat", false, "Use Custom Date Time Format", "", "", ""); CAF_PDM_InitField(&m_customDateTimeFormat,"CustomDateTimeFormat", QString(), "Custom Date Time Format", "", DATETIME_FORMAT_TOOLTIP, ""); - CAF_PDM_InitField(&m_curveLineStyle, "LineStyle", caf::AppEnum(RimPlotCurve::STYLE_NONE), "Line Style", "", "", ""); - CAF_PDM_InitField(&m_curveSymbol, "Symbol", caf::AppEnum(RimPlotCurve::SYMBOL_ELLIPSE), "Symbol", "", "", ""); + CAF_PDM_InitField(&m_curveLineStyle, "LineStyle", caf::AppEnum(RiuQwtPlotCurve::STYLE_NONE), "Line Style", "", "", ""); + CAF_PDM_InitField(&m_curveSymbol, "Symbol", caf::AppEnum(RiuQwtSymbol::SYMBOL_ELLIPSE), "Symbol", "", "", ""); CAF_PDM_InitField(&m_curveSymbolSkipDistance, "SymbolSkipDinstance", 0.0f, "Symbol Skip Distance", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_cellSeparator, "CellSeparator", "Cell Separator", "", "", ""); @@ -187,10 +188,17 @@ RicPasteAsciiDataToSummaryPlotFeatureUi::RicPasteAsciiDataToSummaryPlotFeatureUi //-------------------------------------------------------------------------------------------------- void RicPasteAsciiDataToSummaryPlotFeatureUi::setUiModeImport(const QString& fileName) { - m_uiMode = UI_MODE_IMPORT; - m_parser = std::unique_ptr(new RifCsvUserDataFileParser(fileName)); - initialize(m_parser.get()); + + if (m_parser->determineCsvLayout() != RifCsvUserDataParser::LineBased) + { + m_uiMode = UI_MODE_IMPORT; + initialize(m_parser.get()); + } + else + { + m_uiMode = UI_MODE_SILENT; + } } //-------------------------------------------------------------------------------------------------- @@ -204,6 +212,14 @@ void RicPasteAsciiDataToSummaryPlotFeatureUi::setUiModePasteText(const QString& initialize(m_parser.get()); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicPasteAsciiDataToSummaryPlotFeatureUi::UiMode RicPasteAsciiDataToSummaryPlotFeatureUi::uiModeImport() const +{ + return m_uiMode; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -211,6 +227,7 @@ const AsciiDataParseOptions RicPasteAsciiDataToSummaryPlotFeatureUi::parseOption { AsciiDataParseOptions parseOptions; + parseOptions.assumeNumericDataColumns = true; parseOptions.plotTitle = m_plotTitle(); parseOptions.curvePrefix = m_curvePrefix(); @@ -242,7 +259,13 @@ const AsciiDataParseOptions RicPasteAsciiDataToSummaryPlotFeatureUi::parseOption parseOptions.useCustomDateTimeFormat = false; parseOptions.dateFormat = m_dateFormat().text(); parseOptions.timeFormat = m_timeFormat().text(); - parseOptions.dateTimeFormat = parseOptions.dateFormat + " " + parseOptions.timeFormat; + parseOptions.dateTimeFormat = parseOptions.dateFormat + + (m_timeFormat() != TimeFormat::TIME_NONE ? " " + parseOptions.timeFormat : ""); + } + if (m_timeFormat() == TimeFormat::TIME_NONE) + { + parseOptions.fallbackDateTimeFormat = parseOptions.dateFormat + " " + + RicPasteAsciiDataToSummaryPlotFeatureUi::TimeFormatEnum::text(TIME_HHMM); } } diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeatureUi.h b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeatureUi.h index 0983ead177..bae4818f80 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeatureUi.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeatureUi.h @@ -38,7 +38,7 @@ class AsciiDataParseOptions { public: - AsciiDataParseOptions() : useCustomDateTimeFormat(false) { } + AsciiDataParseOptions() : useCustomDateTimeFormat(false), assumeNumericDataColumns(false) { } QString plotTitle; QString curvePrefix; @@ -48,12 +48,15 @@ class AsciiDataParseOptions bool useCustomDateTimeFormat; QString dateFormat; QString timeFormat; + QString fallbackDateTimeFormat; QString dateTimeFormat; QString cellSeparator; QString timeSeriesColumnName; - RimPlotCurve::LineStyleEnum curveLineStyle; - RimPlotCurve::PointSymbolEnum curveSymbol; + bool assumeNumericDataColumns; + + RiuQwtPlotCurve::LineStyleEnum curveLineStyle; + RiuQwtSymbol::PointSymbolEnum curveSymbol; float curveSymbolSkipDistance; }; @@ -70,7 +73,8 @@ class RicPasteAsciiDataToSummaryPlotFeatureUi : public caf::PdmObject { UI_MODE_NONE, UI_MODE_IMPORT, - UI_MODE_PASTE + UI_MODE_PASTE, + UI_MODE_SILENT }; enum DecimalSeparator @@ -97,6 +101,7 @@ class RicPasteAsciiDataToSummaryPlotFeatureUi : public caf::PdmObject enum TimeFormat { + TIME_NONE, TIME_HHMM, TIME_HHMMSS, TIME_HHMMSSZZZ, @@ -119,14 +124,15 @@ class RicPasteAsciiDataToSummaryPlotFeatureUi : public caf::PdmObject void setUiModeImport(const QString& fileName); void setUiModePasteText(const QString& text); + UiMode uiModeImport() const; const AsciiDataParseOptions parseOptions() const; void createNewPlot(); protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: void initialize(RifCsvUserDataParser* parser); @@ -144,8 +150,8 @@ class RicPasteAsciiDataToSummaryPlotFeatureUi : public caf::PdmObject caf::PdmField m_cellSeparator; caf::PdmField m_timeSeriesColumnName; - caf::PdmField> m_curveLineStyle; - caf::PdmField> m_curveSymbol; + caf::PdmField> m_curveLineStyle; + caf::PdmField> m_curveSymbol; caf::PdmField m_curveSymbolSkipDistance; bool m_createNewPlot; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteEnsembleCurveSetFeature.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteEnsembleCurveSetFeature.cpp index 5a8ef7a69e..c045fc80c5 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteEnsembleCurveSetFeature.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteEnsembleCurveSetFeature.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2016- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -24,10 +24,7 @@ #include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSetCollection.h" -//#include "RimSummaryCurve.h" -//#include "RimSummaryCurveFilter.h" #include "RimSummaryPlot.h" -//#include "RimSummaryCrossPlot.h" #include "cafPdmDefaultObjectFactory.h" #include "cafPdmDocument.h" @@ -38,73 +35,89 @@ #include - CAF_CMD_SOURCE_INIT(RicPasteEnsembleCurveSetFeature, "RicPasteEnsembleCurveSetFeature"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimEnsembleCurveSet* RicPasteEnsembleCurveSetFeature::copyCurveSetAndAddToCollection(RimEnsembleCurveSet *sourceCurveSet) +RimEnsembleCurveSet* + RicPasteEnsembleCurveSetFeature::copyCurveSetAndAddToCollection(RimEnsembleCurveSetCollection* curveSetCollection, + const RimEnsembleCurveSet* sourceCurveSet) { - RimSummaryPlot* plot = caf::firstAncestorOfTypeFromSelectedObject(); - RimEnsembleCurveSetCollection* coll = caf::firstAncestorOfTypeFromSelectedObject(); + CVF_ASSERT(curveSetCollection); - RimEnsembleCurveSet* newCurveSet = dynamic_cast(sourceCurveSet->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); + RimEnsembleCurveSet* newCurveSet = dynamic_cast( + sourceCurveSet->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); CVF_ASSERT(newCurveSet); - if (!coll) coll = plot->ensembleCurveSetCollection(); - - coll->addCurveSet(newCurveSet); + curveSetCollection->addCurveSet(newCurveSet); // Resolve references after object has been inserted into the project data model newCurveSet->resolveReferencesRecursively(); newCurveSet->initAfterReadRecursively(); - newCurveSet->loadDataAndUpdate(true); + newCurveSet->loadDataAndUpdate(false); newCurveSet->updateConnectedEditors(); - coll->updateConnectedEditors(); - return newCurveSet; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RicPasteEnsembleCurveSetFeature::isCommandEnabled() { caf::PdmObject* destinationObject = dynamic_cast(caf::SelectionManager::instance()->selectedItem()); - RimSummaryPlot* plot; + RimSummaryPlot* plot = nullptr; RimEnsembleCurveSetCollection* coll = nullptr; destinationObject->firstAncestorOrThisOfType(plot); destinationObject->firstAncestorOrThisOfType(coll); - if(!coll && !plot) + if (!coll && !plot) { return false; } - if (ensembleCurveSetsOnClipboard().size() == 0) + if (ensembleCurveSetsOnClipboard().empty()) { return false; } + return true; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicPasteEnsembleCurveSetFeature::onActionTriggered(bool isChecked) { - std::vector > sourceObjects = RicPasteEnsembleCurveSetFeature::ensembleCurveSetsOnClipboard(); + std::vector> sourceObjects = + RicPasteEnsembleCurveSetFeature::ensembleCurveSetsOnClipboard(); + if (sourceObjects.empty()) return; - for (size_t i = 0; i < sourceObjects.size(); i++) + RimSummaryPlot* plot = caf::firstAncestorOfTypeFromSelectedObject(); + RimEnsembleCurveSetCollection* coll = caf::firstAncestorOfTypeFromSelectedObject(); + if (!coll && plot) { - copyCurveSetAndAddToCollection(sourceObjects[i]); + coll = plot->ensembleCurveSetCollection(); } + + if (!coll) return; + + for (const auto& sourceObject : sourceObjects) + { + copyCurveSetAndAddToCollection(coll, sourceObject); + } + + if (plot) + { + plot->updateAll(); + } + + coll->updateConnectedEditors(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RicPasteEnsembleCurveSetFeature::setupActionLook(QAction* actionToSetup) { @@ -114,14 +127,14 @@ void RicPasteEnsembleCurveSetFeature::setupActionLook(QAction* actionToSetup) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector > RicPasteEnsembleCurveSetFeature::ensembleCurveSetsOnClipboard() +std::vector> RicPasteEnsembleCurveSetFeature::ensembleCurveSetsOnClipboard() { caf::PdmObjectGroup objectGroup; RicPasteFeatureImpl::findObjectsFromClipboardRefs(&objectGroup); - std::vector > typedObjects; + std::vector> typedObjects; objectGroup.objectsByType(&typedObjects); return typedObjects; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteEnsembleCurveSetFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteEnsembleCurveSetFeature.h index c4511b0cc4..d2b1bd1d07 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteEnsembleCurveSetFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteEnsembleCurveSetFeature.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2016- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -24,22 +24,22 @@ #include class RimEnsembleCurveSet; +class RimEnsembleCurveSetCollection; //================================================================================================== -/// +/// //================================================================================================== class RicPasteEnsembleCurveSetFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; -public: - static RimEnsembleCurveSet* copyCurveSetAndAddToCollection(RimEnsembleCurveSet *sourceCurveSet); +private: + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; -protected: - // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + static RimEnsembleCurveSet* copyCurveSetAndAddToCollection(RimEnsembleCurveSetCollection* coll, + const RimEnsembleCurveSet* sourceCurveSet); - static std::vector > ensembleCurveSetsOnClipboard(); + static std::vector> ensembleCurveSetsOnClipboard(); }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCaseFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCaseFeature.h index d87778e769..b0ae5666a5 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCaseFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCaseFeature.h @@ -33,9 +33,9 @@ class RicPasteSummaryCaseFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* action) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* action) override; static std::vector > summaryCases(); static void removeFromSourceCollection(RimSummaryCase* summaryCase); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCrossPlotCurveFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCrossPlotCurveFeature.h index 278ff6521e..7420ae4051 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCrossPlotCurveFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCrossPlotCurveFeature.h @@ -37,7 +37,7 @@ class RicPasteSummaryCrossPlotCurveFeature : public RicPasteSummaryCurveFeature protected: // Overrides - virtual bool isCommandEnabled() override; + bool isCommandEnabled() override; //virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCrossPlotFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCrossPlotFeature.h index 78a751a623..413b5420f2 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCrossPlotFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCrossPlotFeature.h @@ -37,9 +37,9 @@ class RicPasteSummaryCrossPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: static std::vector > summaryPlots(); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCurveFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCurveFeature.h index e73c87e907..d33f56d513 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCurveFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryCurveFeature.h @@ -38,9 +38,9 @@ class RicPasteSummaryCurveFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; static std::vector > summaryCurvesOnClipboard(); }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryPlotFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryPlotFeature.h index fabd9844f0..c62fafd5d2 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryPlotFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteSummaryPlotFeature.h @@ -37,9 +37,9 @@ class RicPasteSummaryPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: static std::vector > summaryPlots(); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteTimeHistoryCurveFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteTimeHistoryCurveFeature.h index b02c490b00..3ec0c236d7 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicPasteTimeHistoryCurveFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicPasteTimeHistoryCurveFeature.h @@ -34,9 +34,9 @@ class RicPasteTimeHistoryCurveFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: static std::vector > timeHistoryCurves(); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSelectSummaryPlotUI.h b/ApplicationCode/Commands/SummaryPlotCommands/RicSelectSummaryPlotUI.h index 5b0135d420..8dc304921f 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSelectSummaryPlotUI.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSelectSummaryPlotUI.h @@ -42,10 +42,10 @@ class RicSelectSummaryPlotUI : public caf::PdmObject bool isCreateNewPlotChecked() const; QString newPlotName() const; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: caf::PdmPtrField m_selectedSummaryPlot; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicShowSummaryCurveCalculatorFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicShowSummaryCurveCalculatorFeature.h index 1e4607d1a9..4beb2d720f 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicShowSummaryCurveCalculatorFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicShowSummaryCurveCalculatorFeature.h @@ -34,7 +34,7 @@ class RicShowSummaryCurveCalculatorFeature : public caf::CmdFeature static void hideCurveCalculatorDialog(); protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculator.h b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculator.h index 6aa420d59b..ed3e488029 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculator.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculator.h @@ -49,11 +49,11 @@ class RicSummaryCurveCalculator : public caf::PdmObject static RimSummaryCalculationCollection* calculationCollection(); private: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual void onEditorWidgetsCreated(); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void onEditorWidgetsCreated() override; private: // TODO : Move to a common caf helper class diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorDialog.h b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorDialog.h index 94430996c9..791a795aab 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorDialog.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorDialog.h @@ -34,7 +34,7 @@ class RicSummaryCurveCalculatorDialog : public QDialog public: RicSummaryCurveCalculatorDialog(QWidget* parent); - ~RicSummaryCurveCalculatorDialog(); + ~RicSummaryCurveCalculatorDialog() override; void setCalculationAndUpdateUi(RimSummaryCalculation* calculation); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorEditor.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorEditor.cpp index 38f4e8fd1d..82ea501134 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorEditor.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorEditor.cpp @@ -36,6 +36,7 @@ /// //-------------------------------------------------------------------------------------------------- RicSummaryCurveCalculatorEditor::RicSummaryCurveCalculatorEditor() + : m_pdmTableView(nullptr) { m_calculator = std::unique_ptr(new RicSummaryCurveCalculator); @@ -49,7 +50,7 @@ RicSummaryCurveCalculatorEditor::~RicSummaryCurveCalculatorEditor() { if (m_pdmTableView) { - m_pdmTableView->setListField(nullptr); + m_pdmTableView->setChildArrayField(nullptr); delete m_pdmTableView; m_pdmTableView = nullptr; @@ -61,10 +62,12 @@ RicSummaryCurveCalculatorEditor::~RicSummaryCurveCalculatorEditor() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicSummaryCurveCalculatorEditor::recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, const QString& uiConfigName) +void RicSummaryCurveCalculatorEditor::recursivelyConfigureAndUpdateTopLevelUiOrdering(const caf::PdmUiOrdering& topLevelUiOrdering, const QString& uiConfigName) { if (!m_firstRowLeftLayout || !m_firstRowRightLayout) return; + const std::vector& topLevelUiItems = topLevelUiOrdering.uiItems(); + int layoutItemIndex = 0; for (size_t i = 0; i < topLevelUiItems.size(); ++i) { @@ -94,10 +97,10 @@ void RicSummaryCurveCalculatorEditor::recursivelyConfigureAndUpdateTopLevelUiIte if (m_calculator->currentCalculation()) { - m_pdmTableView->setListField(m_calculator->currentCalculation()->variables()); + m_pdmTableView->setChildArrayField(m_calculator->currentCalculation()->variables()); } else - m_pdmTableView->setListField(nullptr); + m_pdmTableView->setChildArrayField(nullptr); m_firstRowRightLayout->insertWidget(layoutItemIndex++, m_pdmTableView); @@ -184,8 +187,7 @@ QMinimizePanel* RicSummaryCurveCalculatorEditor::updateGroupBoxWithContent(caf:: { QMinimizePanel* groupBox = findOrCreateGroupBox(this->widget(), group, uiConfigName); - const std::vector& groupChildren = group->uiItems(); - recursivelyConfigureAndUpdateUiItemsInGridLayoutColumn(groupChildren, groupBox->contentFrame(), uiConfigName); + recursivelyConfigureAndUpdateUiOrderingInGridLayoutColumn(*group, groupBox->contentFrame(), uiConfigName); return groupBox; } diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorEditor.h b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorEditor.h index d2aa5d38b8..2633486e2b 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorEditor.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCalculatorEditor.h @@ -18,7 +18,7 @@ #pragma once -#include "cafPdmUiWidgetBasedObjectEditor.h" +#include "cafPdmUiFormLayoutObjectEditor.h" #include #include @@ -41,21 +41,21 @@ namespace caf { /// /// //================================================================================================== -class RicSummaryCurveCalculatorEditor : public caf::PdmUiWidgetBasedObjectEditor +class RicSummaryCurveCalculatorEditor : public caf::PdmUiFormLayoutObjectEditor { Q_OBJECT public: RicSummaryCurveCalculatorEditor(); - ~RicSummaryCurveCalculatorEditor(); + ~RicSummaryCurveCalculatorEditor() override; RicSummaryCurveCalculator* calculator() const; private: - virtual void recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, - const QString& uiConfigName) override; + void recursivelyConfigureAndUpdateTopLevelUiOrdering(const caf::PdmUiOrdering& topLevelUiItems, + const QString& uiConfigName) override; - virtual QWidget* createWidget(QWidget* parent) override; + QWidget* createWidget(QWidget* parent) override; QMinimizePanel* updateGroupBoxWithContent(caf::PdmUiGroup* group, const QString& uiConfigName); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreator.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreator.cpp index fba1f1dcdc..ef83dfb2ab 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreator.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreator.cpp @@ -20,6 +20,7 @@ #include "RiaApplication.h" #include "RiaColorTables.h" +#include "RiaCurveSetDefinition.h" #include "RiaSummaryCurveDefinition.h" #include "RicSelectSummaryPlotUI.h" @@ -27,6 +28,7 @@ #include "RifReaderEclipseSummary.h" +#include "RimDerivedEnsembleCaseCollection.h" #include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSetCollection.h" #include "RimEnsembleCurveSetColorManager.h" @@ -45,6 +47,7 @@ #include "RimSummaryPlot.h" #include "RimSummaryPlotCollection.h" +#include "RiuPlotMainWindow.h" #include "RiuPlotMainWindowTools.h" #include "RiuSummaryCurveDefSelection.h" #include "RiuSummaryQwtPlot.h" @@ -74,7 +77,9 @@ const QString RicSummaryCurveCreator::CONFIGURATION_NAME = "CurveCreatorCfg"; //-------------------------------------------------------------------------------------------------- /// Internal functions //-------------------------------------------------------------------------------------------------- -int ensembleCurveCount(const std::set& allCurveDefs); +int ensembleCurveCount(const std::set& allCurveDefs); +template +std::vector toVector(const std::set& set); //-------------------------------------------------------------------------------------------------- /// @@ -144,7 +149,7 @@ RimSummaryPlot* RicSummaryCurveCreator::previewPlot() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicSummaryCurveCreator::updateFromSummaryPlot(RimSummaryPlot* targetPlot, const std::vector& defaultCases) +void RicSummaryCurveCreator::updateFromSummaryPlot(RimSummaryPlot* targetPlot, const std::vector& defaultSources) { if (targetPlot == nullptr || m_targetPlot != targetPlot) { @@ -163,7 +168,7 @@ void RicSummaryCurveCreator::updateFromSummaryPlot(RimSummaryPlot* targetPlot, c } else { - setDefaultCurveSelection(defaultCases); + setDefaultCurveSelection(defaultSources); m_previewPlot->enableAutoPlotTitle(true); syncPreviewCurvesFromUiSelection(); } @@ -334,7 +339,7 @@ void RicSummaryCurveCreator::syncPreviewCurvesFromUiSelection() std::set(allCurveDefinitionsVector.begin(), allCurveDefinitionsVector.end()); std::vector currentCurvesInPreviewPlot = m_previewPlot->summaryAndEnsembleCurves(); - if (allCurveDefinitions.size() != currentCurvesInPreviewPlot.size()) + { std::set currentCurveDefs; std::set newCurveDefs; @@ -343,10 +348,10 @@ void RicSummaryCurveCreator::syncPreviewCurvesFromUiSelection() for (const auto& curve : currentCurvesInPreviewPlot) { RimSummaryCase* sumCase = curve->summaryCaseY(); - currentCurveDefs.insert(RiaSummaryCurveDefinition(sumCase, curve->summaryAddressY(), sumCase ? sumCase->ensemble() : nullptr)); + currentCurveDefs.insert( + RiaSummaryCurveDefinition(sumCase, curve->summaryAddressY(), sumCase ? sumCase->ensemble() : nullptr)); } - if (allCurveDefinitions.size() < currentCurvesInPreviewPlot.size()) { // Determine which curves to delete from plot std::set deleteCurveDefs; @@ -359,11 +364,13 @@ void RicSummaryCurveCreator::syncPreviewCurvesFromUiSelection() for (const auto& curve : currentCurvesInPreviewPlot) { RimSummaryCase* sumCase = curve->summaryCaseY(); - RiaSummaryCurveDefinition curveDef = RiaSummaryCurveDefinition(sumCase, curve->summaryAddressY(), sumCase ? sumCase->ensemble() : nullptr); + if (sumCase && sumCase->ensemble()) continue; + + RiaSummaryCurveDefinition curveDef = RiaSummaryCurveDefinition(sumCase, curve->summaryAddressY()); if (deleteCurveDefs.count(curveDef) > 0) curvesToDelete.insert(curve); } } - else + { // Determine which curves are new since last time std::set_difference(allCurveDefinitions.begin(), @@ -373,7 +380,42 @@ void RicSummaryCurveCreator::syncPreviewCurvesFromUiSelection() std::inserter(newCurveDefs, newCurveDefs.end())); } - updatePreviewCurvesFromCurveDefinitions(allCurveDefinitions, newCurveDefs, curvesToDelete); + // Curve sets to delete + std::set curveSetsToDelete; + { + std::vector allCurveSetDefinitionsVector = + m_summaryCurveSelectionEditor->summaryAddressSelection()->allCurveSetDefinitionsFromSelections(); + std::set allCurveSetDefinitions = + std::set(allCurveSetDefinitionsVector.begin(), allCurveSetDefinitionsVector.end()); + std::vector currentCurveSetsInPreviewPlot = m_previewPlot->curveSets(); + std::set currentCurveSetDefs; + + for (const auto& curveSet : currentCurveSetsInPreviewPlot) + { + RimSummaryCaseCollection* ensemble = curveSet->summaryCaseCollection(); + currentCurveSetDefs.insert(RiaCurveSetDefinition(ensemble, curveSet->summaryAddress())); + } + + if (allCurveSetDefinitions.size() < currentCurveSetsInPreviewPlot.size()) + { + // Determine which curves to delete from plot + std::set deleteCurveSetDefs; + std::set_difference(currentCurveSetDefs.begin(), + currentCurveSetDefs.end(), + allCurveSetDefinitions.begin(), + allCurveSetDefinitions.end(), + std::inserter(deleteCurveSetDefs, deleteCurveSetDefs.end())); + + for (const auto& curveSet : currentCurveSetsInPreviewPlot) + { + RimSummaryCaseCollection* ensemble = curveSet->summaryCaseCollection(); + RiaCurveSetDefinition curveSetDef = RiaCurveSetDefinition(ensemble, curveSet->summaryAddress()); + if (deleteCurveSetDefs.count(curveSetDef) > 0) curveSetsToDelete.insert(curveSet); + } + } + } + + updatePreviewCurvesFromCurveDefinitions(allCurveDefinitions, newCurveDefs, curvesToDelete, curveSetsToDelete); } } @@ -383,11 +425,11 @@ void RicSummaryCurveCreator::syncPreviewCurvesFromUiSelection() void RicSummaryCurveCreator::updatePreviewCurvesFromCurveDefinitions( const std::set& allCurveDefsToDisplay, const std::set& curveDefsToAdd, - const std::set& curvesToDelete) + const std::set& curvesToDelete, + const std::set& curveSetsToDelete) { - static bool warningDisplayed = false; + static bool warningDisplayed = false; - RimSummaryCase* prevCase = nullptr; std::set summaryCurveDefsToDisplay; // Ignore curve sets when assigning colors to singe summary curves @@ -401,9 +443,13 @@ void RicSummaryCurveCreator::updatePreviewCurvesFromCurveDefinitions( initCurveAppearanceCalculator(curveLookCalc); // Delete curves - for (const auto& curve : curvesToDelete) + if (!curveSetsToDelete.empty()) { - m_previewPlot->deleteCurve(curve); + m_previewPlot->ensembleCurveSetCollection()->deleteCurveSets(toVector(curveSetsToDelete)); + } + if (!curvesToDelete.empty()) + { + m_previewPlot->deleteCurves(toVector(curvesToDelete)); } size_t ensembleCurveCnt = ensembleCurveCount(allCurveDefsToDisplay); @@ -416,6 +462,7 @@ void RicSummaryCurveCreator::updatePreviewCurvesFromCurveDefinitions( curve->setSummaryCaseY(currentCase); curve->setSummaryAddressY(curveDef.summaryAddress()); curve->applyCurveAutoNameSettings(*m_curveNameConfig()); + if (currentCase->isObservedData()) curve->setSymbolSkipDistance(0); if (curveDef.isEnsembleCurve()) { @@ -432,15 +479,22 @@ void RicSummaryCurveCreator::updatePreviewCurvesFromCurveDefinitions( if (!curveSet) { curveSet = new RimEnsembleCurveSet(); + curveSet->disableStatisticCurves(); curveSet->setSummaryCaseCollection(curveDef.ensemble()); curveSet->setSummaryAddress(curveDef.summaryAddress()); - m_previewPlot->ensembleCurveSetCollection()->addCurveSet(curveSet); // Set single curve set color - size_t colorIndex = m_previewPlot->ensembleCurveSetCollection()->curveSetCount(); + auto allCurveSets = m_previewPlot->ensembleCurveSetCollection()->curveSets(); + size_t colorIndex = std::count_if(allCurveSets.begin(), allCurveSets.end(), [](RimEnsembleCurveSet* curveSet) { + return curveSet->colorMode() == RimEnsembleCurveSet::SINGLE_COLOR; + }); curveSet->setColor(RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f(colorIndex)); - if (m_previewPlot->ensembleCurveSetCollection()->curveSets().size() > 1 && ensembleCurveCnt > ENSEMBLE_CURVE_COUNT_THRESHOLD) + // Add curve to plot + m_previewPlot->ensembleCurveSetCollection()->addCurveSet(curveSet); + + if (m_previewPlot->ensembleCurveSetCollection()->curveSets().size() > 1 && + ensembleCurveCnt > ENSEMBLE_CURVE_COUNT_THRESHOLD) { // Toggle off new curve set and display warning curveSet->showCurves(false); @@ -507,13 +561,13 @@ std::set RicSummaryCurveCreator::getAllSummaryWellNames() if (reader) { - const std::vector allAddresses = reader->allResultAddresses(); + const std::set allAddresses = reader->allResultAddresses(); - for (size_t i = 0; i < allAddresses.size(); i++) + for (auto& address : allAddresses) { - if (allAddresses[i].category() == RifEclipseSummaryAddress::SUMMARY_WELL) + if (address.category() == RifEclipseSummaryAddress::SUMMARY_WELL) { - summaryWellNames.insert(allAddresses[i].wellName()); + summaryWellNames.insert(address.wellName()); } } } @@ -592,6 +646,7 @@ void RicSummaryCurveCreator::populateCurveCreator(const RimSummaryPlot& sourceSu for (const auto& curveSet : sourceSummaryPlot.ensembleCurveSetCollection()->curveSets()) { RimEnsembleCurveSet* newCurveSet = curveSet->clone(); + newCurveSet->disableStatisticCurves(); previewCurveSetColl->addCurveSet(newCurveSet); RimSummaryCaseCollection* ensemble = curveSet->summaryCaseCollection(); @@ -705,9 +760,9 @@ void RicSummaryCurveCreator::copyEnsembleCurveAndAddToCurveSet(const RimSummaryC //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicSummaryCurveCreator::setDefaultCurveSelection(const std::vector& defaultCases) +void RicSummaryCurveCreator::setDefaultCurveSelection(const std::vector& defaultSources) { - m_summaryCurveSelectionEditor->summaryAddressSelection()->setDefaultSelection(defaultCases); + m_summaryCurveSelectionEditor->summaryAddressSelection()->setDefaultSelection(defaultSources); } //-------------------------------------------------------------------------------------------------- @@ -763,11 +818,20 @@ void RicSummaryCurveCreator::applyAppearanceToAllPreviewCurves() RimSummaryCurveAppearanceCalculator curveLookCalc(allCurveDefs, getAllSummaryCaseNames(), getAllSummaryWellNames()); initCurveAppearanceCalculator(curveLookCalc); + // Summary curves for (auto& curve : m_previewPlot->summaryCurves()) { curve->resetAppearance(); curveLookCalc.setupCurveLook(curve); } + + // Ensemble curve sets + int colorIndex = 0; + for (auto& curveSet : m_previewPlot->ensembleCurveSetCollection()->curveSets()) + { + if (curveSet->colorMode() != RimEnsembleCurveSet::SINGLE_COLOR) continue; + curveSet->setColor(RiaColorTables::summaryCurveDefaultPaletteColors().cycledColor3f(colorIndex++)); + } } //-------------------------------------------------------------------------------------------------- @@ -844,6 +908,9 @@ void RicSummaryCurveCreator::createNewPlot() m_targetPlot = newSummaryPlot; updateTargetPlot(); + + RiuPlotMainWindow* mainPlotWindow = RiaApplication::instance()->mainPlotWindow(); + mainPlotWindow->updateSummaryPlotToolBar(); } } } @@ -952,3 +1019,12 @@ int ensembleCurveCount(const std::set& allCurveDefs) return std::count_if( allCurveDefs.begin(), allCurveDefs.end(), [](const RiaSummaryCurveDefinition& def) { return def.isEnsembleCurve(); }); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +std::vector toVector(const std::set& set) +{ + return std::vector(set.begin(), set.end()); +} diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreator.h b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreator.h index ff11e78fa5..7c065dda8e 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreator.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreator.h @@ -36,6 +36,11 @@ #define OBSERVED_DATA_AVALUE_POSTFIX "_OBSDATA" +namespace caf +{ + class PdmObject; +}; + class RimSummaryCase; class RimSummaryCurveAutoName; class RimSummaryPlot; @@ -58,11 +63,11 @@ class RicSummaryCurveCreator : public caf::PdmObject public: RicSummaryCurveCreator(); - virtual ~RicSummaryCurveCreator(); + ~RicSummaryCurveCreator() override; RimSummaryPlot* previewPlot() const; void updateFromSummaryPlot(RimSummaryPlot* targetPlot, - const std::vector& defaultCases = std::vector()); + const std::vector& defaultSources = std::vector()); QWidget* addressSelectionWidget(QWidget* parent); @@ -71,18 +76,19 @@ class RicSummaryCurveCreator : public caf::PdmObject void updateCurveNames(); private: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, - const QVariant& newValue); - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, + const QVariant& newValue) override; + QList 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; void syncPreviewCurvesFromUiSelection(); void updatePreviewCurvesFromCurveDefinitions(const std::set& allCurveDefsToDisplay, const std::set& curveDefsToAdd, - const std::set& curvesToDelete); + const std::set& curvesToDelete, + const std::set& curveSetsToDelete); std::set getAllSummaryCaseNames(); std::set getAllSummaryWellNames(); @@ -90,7 +96,7 @@ class RicSummaryCurveCreator : public caf::PdmObject void updateTargetPlot(); static void copyCurveAndAddToPlot(const RimSummaryCurve *curve, RimSummaryPlot *plot, bool forceVisible = false); static void copyEnsembleCurveAndAddToCurveSet(const RimSummaryCurve *curve, RimEnsembleCurveSet* curveSet, bool forceVisible = false); - void setDefaultCurveSelection(const std::vector& defaultCases); + void setDefaultCurveSelection(const std::vector& defaultCases); void resetAllFields(); void initCurveAppearanceCalculator(RimSummaryCurveAppearanceCalculator& curveAppearanceCalc); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorDialog.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorDialog.cpp index 4ccfd05e8f..e15fd2c1ff 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorDialog.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorDialog.cpp @@ -23,6 +23,8 @@ #include "RicSummaryCurveCreator.h" #include "RicSummaryCurveCreatorSplitterUi.h" +#include "RifReaderEclipseSummary.h" + #include "RiuPlotMainWindow.h" #include "RiuTools.h" @@ -68,9 +70,9 @@ void RicSummaryCurveCreatorDialog::updateFromSummaryPlot(RimSummaryPlot* summary //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicSummaryCurveCreatorDialog::updateFromDefaultCases(const std::vector defaultCases) +void RicSummaryCurveCreatorDialog::updateFromDefaultCases(const std::vector defaultSources) { - m_curveCreatorSplitterUi->updateFromDefaultCases(defaultCases); + m_curveCreatorSplitterUi->updateFromDefaultSources(defaultSources); m_curveCreatorSplitterUi->updateUi(); } @@ -84,4 +86,5 @@ void RicSummaryCurveCreatorDialog::slotDialogFinished() { plotwindow->cleanUpTemporaryWidgets(); } + RifReaderEclipseSummary::purgeCache(); } diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorDialog.h b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorDialog.h index 7ffb7194f0..e6610bf194 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorDialog.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorDialog.h @@ -20,6 +20,11 @@ #include +namespace caf +{ + class PdmObject; +}; + class RicSummaryCurveCreatorSplitterUi; class RimSummaryPlot; class RimSummaryCase; @@ -33,10 +38,10 @@ class RicSummaryCurveCreatorDialog : public QDialog Q_OBJECT public: RicSummaryCurveCreatorDialog(QWidget* parent); - ~RicSummaryCurveCreatorDialog(); + ~RicSummaryCurveCreatorDialog() override; void updateFromSummaryPlot(RimSummaryPlot* summaryPlot); - void updateFromDefaultCases(const std::vector defaultCases); + void updateFromDefaultCases(const std::vector defaultSources); private slots: void slotDialogFinished(); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp index 2f63189fd9..c3e429fea8 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.cpp @@ -70,16 +70,17 @@ void RicSummaryCurveCreatorSplitterUi::updateFromSummaryPlot(RimSummaryPlot* sum //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicSummaryCurveCreatorSplitterUi::updateFromDefaultCases(const std::vector defaultCases) +void RicSummaryCurveCreatorSplitterUi::updateFromDefaultSources(const std::vector defaultSources) { - m_summaryCurveCreator->updateFromSummaryPlot(nullptr, defaultCases); + m_summaryCurveCreator->updateFromSummaryPlot(nullptr, defaultSources); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RicSummaryCurveCreatorSplitterUi::recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, const QString& uiConfigName) +void RicSummaryCurveCreatorSplitterUi::recursivelyConfigureAndUpdateTopLevelUiOrdering(const caf::PdmUiOrdering& topLevelUiOrdering, const QString& uiConfigName) { + const std::vector& topLevelUiItems = topLevelUiOrdering.uiItems(); if (m_summaryCurveCreator->isCloseButtonPressed()) { m_summaryCurveCreator->clearCloseButton(); @@ -242,7 +243,7 @@ void RicSummaryCurveCreatorSplitterUi::configureAndUpdateFields(int widgetStartI if (fieldEditor) { - fieldEditor->setField(field); + fieldEditor->setUiField(field); // Place the widget(s) into the correct parent and layout QWidget* fieldCombinedWidget = fieldEditor->combinedWidget(); @@ -298,7 +299,6 @@ QMinimizePanel* RicSummaryCurveCreatorSplitterUi::createGroupBoxWithContent(caf: { QMinimizePanel* groupBox = findOrCreateGroupBox(this->widget(), group, uiConfigName); - const std::vector& groupChildren = group->uiItems(); - recursivelyConfigureAndUpdateUiItemsInGridLayoutColumn(groupChildren, groupBox->contentFrame(), uiConfigName); + recursivelyConfigureAndUpdateUiOrderingInGridLayoutColumn(*group, groupBox->contentFrame(), uiConfigName); return groupBox; } diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.h b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.h index b7872fbbc2..856fc38881 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveCreatorSplitterUi.h @@ -18,7 +18,7 @@ #pragma once -#include "cafPdmUiWidgetBasedObjectEditor.h" +#include "cafPdmUiFormLayoutObjectEditor.h" #include #include @@ -35,6 +35,7 @@ class QHBoxLayout; class QBoxLayout; namespace caf { + class PdmObject; class PdmUiItem; class PdmUiTreeView; } @@ -44,22 +45,22 @@ namespace caf { /// /// //================================================================================================== -class RicSummaryCurveCreatorSplitterUi : public caf::PdmUiWidgetBasedObjectEditor +class RicSummaryCurveCreatorSplitterUi : public caf::PdmUiFormLayoutObjectEditor { Q_OBJECT public: RicSummaryCurveCreatorSplitterUi(QWidget* parent); - ~RicSummaryCurveCreatorSplitterUi(); + ~RicSummaryCurveCreatorSplitterUi() override; void updateFromSummaryPlot(RimSummaryPlot* summaryPlot); - void updateFromDefaultCases(const std::vector defaultCases); + void updateFromDefaultSources(const std::vector defaultSources); private: - virtual void recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, - const QString& uiConfigName) override; + void recursivelyConfigureAndUpdateTopLevelUiOrdering(const caf::PdmUiOrdering& topLevelUiOrdering, + const QString& uiConfigName) override; - virtual QWidget* createWidget(QWidget* parent) override; + QWidget* createWidget(QWidget* parent) override; QWidget* getOrCreateCurveTreeWidget(); QWidget* getOrCreatePlotWidget(); diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveSwitchAxisFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveSwitchAxisFeature.h index 93e5bc3e9f..a363ee59c0 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveSwitchAxisFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicSummaryCurveSwitchAxisFeature.h @@ -36,9 +36,9 @@ class RicSummaryCurveSwitchAxisFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static void extractSelectedCurves(std::vector* summaryCurves, diff --git a/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.h b/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.h index c7a4a1a85e..ba0b525d5a 100644 --- a/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.h +++ b/ApplicationCode/Commands/SummaryPlotCommands/RicViewZoomAllFeature.h @@ -30,7 +30,7 @@ class RicViewZoomAllFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.cpp b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.cpp index 24023e0790..28d7c7ac59 100644 --- a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.cpp +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.cpp @@ -52,4 +52,6 @@ void RicToggleItemsFeature::setupActionLook(QAction* actionToSetup) actionToSetup->setText("Toggle Sub Items"); else actionToSetup->setText("Toggle"); + + actionToSetup->setIcon(QIcon(":/ToggleOnOff16x16.png")); } diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.h b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.h index 13aac4e39d..93a9e962d9 100644 --- a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.h +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsFeature.h @@ -30,7 +30,7 @@ class RicToggleItemsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.cpp b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.cpp index 027e33d5ca..f7524d0a7d 100644 --- a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.cpp +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.cpp @@ -52,4 +52,7 @@ void RicToggleItemsOffFeature::setupActionLook(QAction* actionToSetup) actionToSetup->setText("Sub Items Off"); else actionToSetup->setText("Off"); + + actionToSetup->setIcon(QIcon(":/ToggleOff16x16.png")); + } diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.h b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.h index 0f9b77f87a..dc7a22e051 100644 --- a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.h +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOffFeature.h @@ -30,7 +30,7 @@ class RicToggleItemsOffFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.cpp b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.cpp index 0f2467c5ff..524607a1e3 100644 --- a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.cpp +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.cpp @@ -52,4 +52,7 @@ void RicToggleItemsOnFeature::setupActionLook(QAction* actionToSetup) actionToSetup->setText("Sub Items On"); else actionToSetup->setText("On"); + + actionToSetup->setIcon(QIcon(":/ToggleOn16x16.png")); + } diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.h b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.h index 97d8c3fed1..9312d20237 100644 --- a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.h +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnFeature.h @@ -30,7 +30,7 @@ class RicToggleItemsOnFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnOthersOffFeature.cpp b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnOthersOffFeature.cpp index f076ebc17a..b6b348928f 100644 --- a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnOthersOffFeature.cpp +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnOthersOffFeature.cpp @@ -83,6 +83,9 @@ void RicToggleItemsOnOthersOffFeature::onActionTriggered(bool isChecked) void RicToggleItemsOnOthersOffFeature::setupActionLook(QAction* actionToSetup) { actionToSetup->setText("On - Others Off"); + + actionToSetup->setIcon(QIcon(":/ToggleOnOthersOff16x16.png")); + } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnOthersOffFeature.h b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnOthersOffFeature.h index 9b0e8fa750..9af1d23f97 100644 --- a/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnOthersOffFeature.h +++ b/ApplicationCode/Commands/ToggleCommands/RicToggleItemsOnOthersOffFeature.h @@ -38,9 +38,9 @@ class RicToggleItemsOnOthersOffFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: caf::PdmFieldHandle* commonParentForAllSelections(const std::vector& selectedObjects); diff --git a/ApplicationCode/Commands/ViewLink/RicDeleteAllLinkedViewsFeature.h b/ApplicationCode/Commands/ViewLink/RicDeleteAllLinkedViewsFeature.h index ff16037666..6f8921a2a8 100644 --- a/ApplicationCode/Commands/ViewLink/RicDeleteAllLinkedViewsFeature.h +++ b/ApplicationCode/Commands/ViewLink/RicDeleteAllLinkedViewsFeature.h @@ -32,7 +32,7 @@ class RicDeleteAllLinkedViewsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.cpp b/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.cpp index 4da5f3ca79..e304e812b1 100644 --- a/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.cpp +++ b/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.cpp @@ -23,8 +23,10 @@ #include "RicLinkVisibleViewsFeature.h" -#include "RimProject.h" #include "Rim3dView.h" +#include "RimContourMapView.h" +#include "RimGridView.h" +#include "RimProject.h" #include "RimViewLinkerCollection.h" #include "RimViewLinker.h" @@ -39,31 +41,42 @@ CAF_CMD_SOURCE_INIT(RicLinkViewFeature, "RicLinkViewFeature"); //-------------------------------------------------------------------------------------------------- bool RicLinkViewFeature::isCommandEnabled() { - Rim3dView* activeView = RiaApplication::instance()->activeReservoirView(); - if (!activeView) return false; + std::vector allSelectedItems; + std::vector selectedGridViews; + std::vector selectedContourMaps; - RimProject* proj = RiaApplication::instance()->project(); - RimViewLinker* viewLinker = proj->viewLinkerCollection->viewLinker(); - - if(!viewLinker) return false; + caf::SelectionManager::instance()->selectedItems(allSelectedItems); + caf::SelectionManager::instance()->objectsByType(&selectedGridViews); + caf::SelectionManager::instance()->objectsByType(&selectedContourMaps); + size_t selectedRegularGridViews = selectedGridViews.size() - selectedContourMaps.size(); - RimViewController* viewController = activeView->viewController(); - - if(viewController) + if (selectedGridViews.size() > 1u && selectedRegularGridViews >= 1u && allSelectedItems.size() == selectedGridViews.size()) { - return false; + return true; } else { - if (!activeView->isMasterView()) + // Link only the active view to an existing view link collection. + Rim3dView* activeView = RiaApplication::instance()->activeReservoirView(); + if (!activeView) return false; + + RimProject* proj = RiaApplication::instance()->project(); + RimViewLinker* viewLinker = proj->viewLinkerCollection->viewLinker(); + + if (!viewLinker) return false; + + RimViewController* viewController = activeView->viewController(); + + if (viewController) { - return true; + return false; } - else + else if (!activeView->isMasterView()) { - return false; + return true; } } + return false; } //-------------------------------------------------------------------------------------------------- @@ -71,13 +84,27 @@ bool RicLinkViewFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicLinkViewFeature::onActionTriggered(bool isChecked) { - RimGridView* activeView = RiaApplication::instance()->activeGridView(); - if (!activeView) return; + std::vector allSelectedItems; + std::vector selectedGridViews; - std::vector views; - views.push_back(activeView); + caf::SelectionManager::instance()->selectedItems(allSelectedItems); + caf::SelectionManager::instance()->objectsByType(&selectedGridViews); - RicLinkVisibleViewsFeature::linkViews(views); + if (selectedGridViews.size() > 1u && allSelectedItems.size() == selectedGridViews.size()) + { + RicLinkVisibleViewsFeature::linkViews(selectedGridViews); + } + else + { + Rim3dView* activeView = RiaApplication::instance()->activeReservoirView(); + RimGridView* gridView = dynamic_cast(activeView); + if (gridView) + { + std::vector views; + views.push_back(gridView); + RicLinkVisibleViewsFeature::linkViews(views); + } + } } //-------------------------------------------------------------------------------------------------- @@ -85,7 +112,16 @@ void RicLinkViewFeature::onActionTriggered(bool isChecked) //-------------------------------------------------------------------------------------------------- void RicLinkViewFeature::setupActionLook(QAction* actionToSetup) { - actionToSetup->setText("Link View"); + std::vector selectedGridViews; + caf::SelectionManager::instance()->objectsByType(&selectedGridViews); + if (selectedGridViews.size() > 1u) + { + actionToSetup->setText("Link Selected Views"); + } + else + { + actionToSetup->setText("Link View"); + } actionToSetup->setIcon(QIcon(":/chain.png")); } diff --git a/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.h b/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.h index aa912bbe77..be44a5a2ad 100644 --- a/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.h +++ b/ApplicationCode/Commands/ViewLink/RicLinkViewFeature.h @@ -32,7 +32,7 @@ class RicLinkViewFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.cpp b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.cpp index 8081f13df7..ee891554a2 100644 --- a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.cpp +++ b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.cpp @@ -23,9 +23,10 @@ #include "RicLinkVisibleViewsFeatureUi.h" -#include "RimViewController.h" -#include "RimProject.h" +#include "RimContourMapView.h" #include "RimGridView.h" +#include "RimProject.h" +#include "RimViewController.h" #include "RimViewLinker.h" #include "RimViewLinkerCollection.h" @@ -63,7 +64,14 @@ bool RicLinkVisibleViewsFeature::isCommandEnabled() } - if (visibleGridViews.size() >= 2 && (linkedviews.size() < visibleGridViews.size())) return true; + if (visibleGridViews.size() >= 2 && (linkedviews.size() < visibleGridViews.size())) + { + std::vector views; + findNotLinkedVisibleViews(views); + RicLinkVisibleViewsFeatureUi testUi; + testUi.setViews(views); + return !testUi.masterViewCandidates().empty(); + } return false; } @@ -140,6 +148,15 @@ void RicLinkVisibleViewsFeature::linkViews(std::vector& views) RimProject* proj = RiaApplication::instance()->project(); RimViewLinker* viewLinker = proj->viewLinkerCollection->viewLinker(); + std::vector masterCandidates; + for (RimGridView* view : views) + { + if (dynamic_cast(view) == nullptr) + { + masterCandidates.push_back(view); + } + } + if (!viewLinker) { // Create a new view linker @@ -148,15 +165,20 @@ void RicLinkVisibleViewsFeature::linkViews(std::vector& views) { return; } + CVF_ASSERT(!masterCandidates.empty()); - RicLinkVisibleViewsFeatureUi featureUi; - featureUi.setViews(views); + RimGridView* masterView = masterCandidates.front(); + if (masterCandidates.size() > 1u) + { + RicLinkVisibleViewsFeatureUi featureUi; + featureUi.setViews(masterCandidates); - caf::PdmUiPropertyViewDialog propertyDialog(nullptr, &featureUi, "Select Master View", ""); - propertyDialog.setWindowIcon(QIcon(":/chain.png")); - if (propertyDialog.exec() != QDialog::Accepted) return; + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, &featureUi, "Select Master View", ""); + propertyDialog.setWindowIcon(QIcon(":/chain.png")); + if (propertyDialog.exec() != QDialog::Accepted) return; - RimGridView* masterView = featureUi.masterView(); + masterView = featureUi.masterView(); + } viewLinker = new RimViewLinker; proj->viewLinkerCollection()->viewLinker = viewLinker; viewLinker->setMasterView(masterView); diff --git a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.h b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.h index 255e86b837..5edecbd71a 100644 --- a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.h +++ b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeature.h @@ -37,11 +37,11 @@ class RicLinkVisibleViewsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup); + void setupActionLook(QAction* actionToSetup) override; private: void findNotLinkedVisibleViews(std::vector &views); diff --git a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.cpp b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.cpp index 1862ec6021..f5abbfd666 100644 --- a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.cpp +++ b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.cpp @@ -20,7 +20,9 @@ #include "RicLinkVisibleViewsFeatureUi.h" #include "RiaApplication.h" +#include "RiaOptionItemFactory.h" +#include "RimContourMapView.h" #include "RimCase.h" #include "RimGridView.h" #include "RimViewLinker.h" @@ -46,19 +48,21 @@ void RicLinkVisibleViewsFeatureUi::setViews(const std::vector& all RimGridView* activeView = RiaApplication::instance()->activeGridView(); - // Set Active view as master view - for (size_t i = 0; i < allViews.size(); i++) + std::vector masterCandidates = masterViewCandidates(); + + // Set Active view as master view if the active view isn't a contour map. + for (size_t i = 0; i < masterCandidates.size(); i++) { - if (activeView == allViews[i]) + if (activeView == masterCandidates[i]) { m_masterView = allViews[i]; } } // Fallback to use first view if no active view is present - if (!m_masterView && allViews.size() > 0) + if (!m_masterView && masterCandidates.size() > 0) { - m_masterView = allViews[0]; + m_masterView = masterCandidates[0]; } } @@ -70,6 +74,24 @@ RimGridView* RicLinkVisibleViewsFeatureUi::masterView() return m_masterView; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RicLinkVisibleViewsFeatureUi::masterViewCandidates() const +{ + std::vector masterCandidates; + // Set Active view as master view if the active view isn't a contour map. + for (size_t i = 0; i < m_allViews.size(); i++) + { + RimContourMapView* contourMap = dynamic_cast(m_allViews[i]); + if (contourMap == nullptr) + { + masterCandidates.push_back(m_allViews[i]); + } + } + return masterCandidates; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -80,18 +102,9 @@ QList RicLinkVisibleViewsFeatureUi::calculateValueOption if (fieldNeedingOptions == &m_masterView) { - for (RimGridView* v : m_allViews) + for (RimGridView* v : masterViewCandidates()) { - RimCase* rimCase = nullptr; - v->firstAncestorOrThisOfType(rimCase); - - QIcon icon; - if (rimCase) - { - icon = rimCase->uiCapability()->uiIcon(); - } - - options.push_back(caf::PdmOptionItemInfo(RimViewLinker::displayNameForView(v), v, false, icon)); + RiaOptionItemFactory::appendOptionItemFromViewNameAndCaseName(v, &options); } } diff --git a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.h b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.h index 5ba94f305f..9a7ac7c896 100644 --- a/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.h +++ b/ApplicationCode/Commands/ViewLink/RicLinkVisibleViewsFeatureUi.h @@ -37,12 +37,13 @@ class RicLinkVisibleViewsFeatureUi : public caf::PdmObject public: RicLinkVisibleViewsFeatureUi(void); - void setViews(const std::vector& allViews); - RimGridView* masterView(); + void setViews(const std::vector& allViews); + RimGridView* masterView(); + std::vector masterViewCandidates() const; protected: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, - bool * useOptionsOnly); + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool * useOptionsOnly) override; private: caf::PdmPtrField m_masterView; diff --git a/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.cpp b/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.cpp index 1bed9c55c6..a6643c3cd9 100644 --- a/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.cpp +++ b/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.cpp @@ -21,8 +21,9 @@ #include "RiaApplication.h" -#include "RimProject.h" +#include "RimContourMapView.h" #include "RimGridView.h" +#include "RimProject.h" #include "RimViewController.h" #include "RimViewLinker.h" #include "RimViewLinkerCollection.h" @@ -54,6 +55,11 @@ bool RicSetMasterViewFeature::isCommandEnabled() return false; } + if (dynamic_cast(activeView) != nullptr) + { + return false; + } + return true; } diff --git a/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.h b/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.h index 0288b94a03..a27a941963 100644 --- a/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.h +++ b/ApplicationCode/Commands/ViewLink/RicSetMasterViewFeature.h @@ -32,7 +32,7 @@ class RicSetMasterViewFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/ViewLink/RicShowAllLinkedViewsFeature.h b/ApplicationCode/Commands/ViewLink/RicShowAllLinkedViewsFeature.h index 920a8f9596..d405953d71 100644 --- a/ApplicationCode/Commands/ViewLink/RicShowAllLinkedViewsFeature.h +++ b/ApplicationCode/Commands/ViewLink/RicShowAllLinkedViewsFeature.h @@ -32,7 +32,7 @@ class RicShowAllLinkedViewsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/ViewLink/RicShowLinkOptionsFeature.h b/ApplicationCode/Commands/ViewLink/RicShowLinkOptionsFeature.h index e80551dd21..e470a7bb72 100644 --- a/ApplicationCode/Commands/ViewLink/RicShowLinkOptionsFeature.h +++ b/ApplicationCode/Commands/ViewLink/RicShowLinkOptionsFeature.h @@ -32,7 +32,7 @@ class RicShowLinkOptionsFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/ViewLink/RicUnLinkViewFeature.h b/ApplicationCode/Commands/ViewLink/RicUnLinkViewFeature.h index 9b01e73473..08683dd531 100644 --- a/ApplicationCode/Commands/ViewLink/RicUnLinkViewFeature.h +++ b/ApplicationCode/Commands/ViewLink/RicUnLinkViewFeature.h @@ -32,7 +32,7 @@ class RicUnLinkViewFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook(QAction* actionToSetup); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake index 2d98f85c33..888789b513 100644 --- a/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/WellLogCommands/CMakeLists_files.cmake @@ -19,7 +19,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RicPasteWellLogCurveFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicPasteWellLogTrackFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicPasteWellLogPlotFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicChangeDataSourceFeature.h -${CMAKE_CURRENT_LIST_DIR}/RicChangeDataSourceFeatureUi.h ${CMAKE_CURRENT_LIST_DIR}/RicAsciiExportWellLogPlotFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicWellLogFileCloseFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicMoveWellLogFilesFeature.h @@ -27,7 +26,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogCurveFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogFileCurveFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogRftCurveFeature.h ${CMAKE_CURRENT_LIST_DIR}/Ric3dWellLogCurveDeleteFeature.h -${CMAKE_CURRENT_LIST_DIR}/Ric3dWellLogCurveViewerEventHandler.h +${CMAKE_CURRENT_LIST_DIR}/Ric3dWellLogCurvePickEventHandler.h +${CMAKE_CURRENT_LIST_DIR}/RicNewWellBoreStabilityPlotFeature.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -50,7 +50,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RicPasteWellLogCurveFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicPasteWellLogTrackFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicPasteWellLogPlotFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicChangeDataSourceFeature.cpp -${CMAKE_CURRENT_LIST_DIR}/RicChangeDataSourceFeatureUi.cpp ${CMAKE_CURRENT_LIST_DIR}/RicAsciiExportWellLogPlotFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellLogFileCloseFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicMoveWellLogFilesFeature.cpp @@ -58,7 +57,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogCurveFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogFileCurveFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicAdd3dWellLogRftCurveFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/Ric3dWellLogCurveDeleteFeature.cpp -${CMAKE_CURRENT_LIST_DIR}/Ric3dWellLogCurveViewerEventHandler.cpp +${CMAKE_CURRENT_LIST_DIR}/Ric3dWellLogCurvePickEventHandler.cpp +${CMAKE_CURRENT_LIST_DIR}/RicNewWellBoreStabilityPlotFeature.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveDeleteFeature.h b/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveDeleteFeature.h index 6dc5bb9cec..bf576efee6 100644 --- a/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveDeleteFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveDeleteFeature.h @@ -30,7 +30,7 @@ class Ric3dWellLogCurveDeleteFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered(bool isChecked) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered(bool isChecked) override; + void setupActionLook(QAction* actionToSetup) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.cpp b/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurvePickEventHandler.cpp similarity index 74% rename from ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.cpp rename to ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurvePickEventHandler.cpp index a9434787a6..e43983be88 100644 --- a/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.cpp +++ b/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurvePickEventHandler.cpp @@ -17,7 +17,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "Ric3dWellLogCurveViewerEventHandler.h" +#include "Ric3dWellLogCurvePickEventHandler.h" #include "Rim3dWellLogCurve.h" #include "Rim3dWellLogCurveCollection.h" @@ -30,25 +30,23 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Ric3dWellLogCurveViewerEventHandler* Ric3dWellLogCurveViewerEventHandler::instance() +Ric3dWellLogCurvePickEventHandler* Ric3dWellLogCurvePickEventHandler::instance() { - static Ric3dWellLogCurveViewerEventHandler* singleton = new Ric3dWellLogCurveViewerEventHandler; + static Ric3dWellLogCurvePickEventHandler* singleton = new Ric3dWellLogCurvePickEventHandler; return singleton; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool Ric3dWellLogCurveViewerEventHandler::handleEvent(const RicViewerEventObject& eventObject) +bool Ric3dWellLogCurvePickEventHandler::handlePickEvent(const Ric3DPickEvent& eventObject) { - if (eventObject.m_partAndTriangleIndexPairs.empty()) return false; + if (eventObject.m_pickItemInfos.empty()) return false; - cvf::uint triangleIndex = cvf::UNDEFINED_UINT; + const auto& firstPickedItem = eventObject.m_pickItemInfos.front(); + const cvf::Part* firstPickedPart = firstPickedItem.pickedPart(); - const auto& partAndTriangleIndexPair = eventObject.m_partAndTriangleIndexPairs.front(); - const cvf::Part* part = partAndTriangleIndexPair.first; - - const RivObjectSourceInfo* sourceInfo = dynamic_cast(part->sourceInfo()); + const RivObjectSourceInfo* sourceInfo = dynamic_cast(firstPickedPart->sourceInfo()); if (sourceInfo) { Rim3dWellLogCurveCollection* curveCollection = dynamic_cast(sourceInfo->object()); @@ -60,8 +58,10 @@ bool Ric3dWellLogCurveViewerEventHandler::handleEvent(const RicViewerEventObject cvf::Vec3d closestPoint; double measuredDepthAtPoint; double valueAtPoint; - Rim3dWellLogCurve* curve = curveCollection->checkForCurveIntersection( - eventObject.m_globalIntersectionPoint, &closestPoint, &measuredDepthAtPoint, &valueAtPoint); + Rim3dWellLogCurve* curve = curveCollection->checkForCurveIntersection( firstPickedItem.globalPickedPoint(), + &closestPoint, + &measuredDepthAtPoint, + &valueAtPoint); if (curve) { RiuMainWindow::instance()->selectAsCurrentItem(curve); diff --git a/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.h b/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurvePickEventHandler.h similarity index 81% rename from ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.h rename to ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurvePickEventHandler.h index 8299a191d7..b7d5a3717c 100644 --- a/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurveViewerEventHandler.h +++ b/ApplicationCode/Commands/WellLogCommands/Ric3dWellLogCurvePickEventHandler.h @@ -19,15 +19,15 @@ #pragma once -#include "RicViewerEventInterface.h" +#include "RicPickEventHandler.h" //================================================================================================== /// //================================================================================================== -class Ric3dWellLogCurveViewerEventHandler : public RicViewerEventInterface +class Ric3dWellLogCurvePickEventHandler : public RicDefaultPickEventHandler { public: - static Ric3dWellLogCurveViewerEventHandler* instance(); + static Ric3dWellLogCurvePickEventHandler* instance(); - bool handleEvent(const RicViewerEventObject& eventObject) override; + bool handlePickEvent(const Ric3DPickEvent& eventObject) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogCurveFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogCurveFeature.cpp index af045fc8c4..8adb77b6c3 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogCurveFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogCurveFeature.cpp @@ -29,6 +29,8 @@ #include "Riu3DMainWindowTools.h" +#include "cafSelectionManager.h" + #include CAF_CMD_SOURCE_INIT(RicAdd3dWellLogCurveFeature, "RicAdd3dWellLogCurveFeature"); @@ -42,7 +44,7 @@ bool RicAdd3dWellLogCurveFeature::isCommandEnabled() RiaApplication::instance()->project()->allCases(cases); if (cases.empty()) return false; - return RicWellLogTools::findWellPathFromSelection() != nullptr; + return caf::SelectionManager::instance()->selectedItemAncestorOfType(); } //-------------------------------------------------------------------------------------------------- @@ -50,7 +52,7 @@ bool RicAdd3dWellLogCurveFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicAdd3dWellLogCurveFeature::onActionTriggered(bool isChecked) { - RimWellPath* selectedWellPath = RicWellLogTools::findWellPathFromSelection(); + RimWellPath* selectedWellPath = caf::SelectionManager::instance()->selectedItemAncestorOfType(); if (!selectedWellPath) return; Rim3dWellLogExtractionCurve* rim3dWellLogExtractionCurve = new Rim3dWellLogExtractionCurve(); @@ -63,7 +65,7 @@ void RicAdd3dWellLogCurveFeature::onActionTriggered(bool isChecked) selectedWellPath->add3dWellLogCurve(rim3dWellLogExtractionCurve); - RiaApplication::instance()->project()->createDisplayModelAndRedrawAllViews(); + RiaApplication::instance()->project()->scheduleCreateDisplayModelAndRedrawAllViews(); RiaApplication::instance()->project()->updateConnectedEditors(); diff --git a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogCurveFeature.h b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogCurveFeature.h index ddc5cc4f4b..81f6e8b54f 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogCurveFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogCurveFeature.h @@ -28,7 +28,7 @@ class RicAdd3dWellLogCurveFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogFileCurveFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogFileCurveFeature.cpp index 00b1e8d1e9..4aa0d890e0 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogFileCurveFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogFileCurveFeature.cpp @@ -57,7 +57,7 @@ void RicAdd3dWellLogFileCurveFeature::onActionTriggered(bool isChecked) rim3dWellLogFileCurve->setDefaultFileCurveDataInfo(); - RiaApplication::instance()->project()->createDisplayModelAndRedrawAllViews(); + RiaApplication::instance()->project()->scheduleCreateDisplayModelAndRedrawAllViews(); RiaApplication::instance()->project()->updateConnectedEditors(); Riu3DMainWindowTools::selectAsCurrentItem(rim3dWellLogFileCurve); diff --git a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogFileCurveFeature.h b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogFileCurveFeature.h index 7251912f61..6126a99cf9 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogFileCurveFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogFileCurveFeature.h @@ -28,7 +28,7 @@ class RicAdd3dWellLogFileCurveFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogRftCurveFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogRftCurveFeature.cpp index a715d82fe7..190cf5486e 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogRftCurveFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogRftCurveFeature.cpp @@ -28,6 +28,8 @@ #include "Riu3DMainWindowTools.h" +#include "cafSelectionManager.h" + #include CAF_CMD_SOURCE_INIT(RicAdd3dWellLogRftCurveFeature, "RicAdd3dWellLogRftCurveFeature"); @@ -41,7 +43,7 @@ bool RicAdd3dWellLogRftCurveFeature::isCommandEnabled() RiaApplication::instance()->project()->allCases(cases); if (cases.empty()) return false; - RimWellPath* wellPath = RicWellLogTools::findWellPathFromSelection(); + RimWellPath* wellPath = caf::SelectionManager::instance()->selectedItemAncestorOfType(); if (wellPath) { return RicWellLogTools::wellHasRftData(wellPath->name()); @@ -54,13 +56,13 @@ bool RicAdd3dWellLogRftCurveFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicAdd3dWellLogRftCurveFeature::onActionTriggered(bool isChecked) { - RimWellPath* selectedWellPath = RicWellLogTools::findWellPathFromSelection(); + RimWellPath* selectedWellPath = caf::SelectionManager::instance()->selectedItemAncestorOfType(); if (!selectedWellPath) return; Rim3dWellLogRftCurve* rim3dWellLogRftCurve = new Rim3dWellLogRftCurve(); selectedWellPath->add3dWellLogCurve(rim3dWellLogRftCurve); - RiaApplication::instance()->project()->createDisplayModelAndRedrawAllViews(); + RiaApplication::instance()->project()->scheduleCreateDisplayModelAndRedrawAllViews(); RiaApplication::instance()->project()->updateConnectedEditors(); Riu3DMainWindowTools::selectAsCurrentItem(rim3dWellLogRftCurve); diff --git a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogRftCurveFeature.h b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogRftCurveFeature.h index a953f315fc..e60ffd406b 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogRftCurveFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicAdd3dWellLogRftCurveFeature.h @@ -28,7 +28,7 @@ class RicAdd3dWellLogRftCurveFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicAddWellLogToPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicAddWellLogToPlotFeature.h index cd47047e75..811673c2c8 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicAddWellLogToPlotFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicAddWellLogToPlotFeature.h @@ -38,9 +38,9 @@ class RicAddWellLogToPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: std::vector selectedWellLogs(); diff --git a/ApplicationCode/Commands/WellLogCommands/RicAsciiExportWellLogPlotFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicAsciiExportWellLogPlotFeature.cpp index 4e83bcbb78..e7fe643096 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicAsciiExportWellLogPlotFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicAsciiExportWellLogPlotFeature.cpp @@ -55,15 +55,9 @@ void RicAsciiExportWellLogPlotFeature::onActionTriggered(bool isChecked) { this->disableModelChangeContribution(); - RiaApplication* app = RiaApplication::instance(); - QString projectFolder = app->currentProjectPath(); - - RimProject* project = RiaApplication::instance()->project(); - CVF_ASSERT(project); - std::vector selectedWellLogPlots; caf::SelectionManager::instance()->objectsByType(&selectedWellLogPlots); - QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallback("PLOT_ASCIIEXPORT_DIR", projectFolder); + QString defaultDir = RiaApplication::instance()->lastUsedDialogDirectoryWithFallbackToProjectFolder("PLOT_ASCIIEXPORT_DIR"); caf::ProgressInfo pi(selectedWellLogPlots.size(), QString("Exporting plot data to ASCII")); size_t progress = 0; diff --git a/ApplicationCode/Commands/WellLogCommands/RicAsciiExportWellLogPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicAsciiExportWellLogPlotFeature.h index baaad8db8b..32390e03e8 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicAsciiExportWellLogPlotFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicAsciiExportWellLogPlotFeature.h @@ -30,9 +30,9 @@ class RicAsciiExportWellLogPlotFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: static bool exportAsciiForWellLogPlot(const QString& fileName, const RimWellLogPlot* wellLogPlot); diff --git a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.cpp index 13bae55e9d..0082d2cc9b 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.cpp @@ -18,18 +18,24 @@ #include "RicChangeDataSourceFeature.h" -#include "RicChangeDataSourceFeatureUi.h" #include "RicWellLogPlotCurveFeatureImpl.h" #include "RimCase.h" #include "RimWellLogCurve.h" +#include "RimWellLogCurveCommonDataSource.h" #include "RimWellLogExtractionCurve.h" +#include "RimWellLogFileCurve.h" +#include "RimWellLogPlot.h" +#include "RimWellLogTrack.h" #include "RimWellPath.h" #include "cafPdmUiPropertyViewDialog.h" +#include "cafSelectionManager.h" #include +#include + CAF_CMD_SOURCE_INIT(RicChangeDataSourceFeature, "RicChangeDataSourceFeature"); //-------------------------------------------------------------------------------------------------- @@ -40,9 +46,10 @@ bool RicChangeDataSourceFeature::isCommandEnabled() if (RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot()) return false; if (RicWellLogPlotCurveFeatureImpl::parentWellRftPlot()) return false; - std::vector extrCurves = extractionCurves(); + std::vector curves; + std::vector tracks; - return extrCurves.size() > 0; + return selectedTracksAndCurves(&curves, &tracks); } //-------------------------------------------------------------------------------------------------- @@ -50,27 +57,25 @@ bool RicChangeDataSourceFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicChangeDataSourceFeature::onActionTriggered(bool isChecked) { - if (RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot()) return; - - std::vector extrCurves = extractionCurves(); - if (extrCurves.size() == 0) return; + std::vector selectedObjects; + caf::SelectionManager::instance()->objectsByType(&selectedObjects); - RicChangeDataSourceFeatureUi featureUi; - featureUi.wellPathToApply = extrCurves[0]->wellPath(); - featureUi.caseToApply = extrCurves[0]->rimCase(); + std::vector curves; + std::vector tracks; - caf::PdmUiPropertyViewDialog propertyDialog(nullptr, &featureUi, "Change Data Source for Selected Curves", ""); - propertyDialog.resize(QSize(500, 200)); - if (propertyDialog.exec() == QDialog::Accepted) + if (selectedTracksAndCurves(&curves, &tracks)) { - for (RimWellLogExtractionCurve* extractionCurve : extrCurves) - { - extractionCurve->setWellPath(featureUi.wellPathToApply); - extractionCurve->setCase(featureUi.caseToApply); + RimWellLogCurveCommonDataSource featureUi; + featureUi.updateDefaultOptions(curves, tracks); - extractionCurve->loadDataAndUpdate(true); + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, &featureUi, "Change Data Source for Multiple Curves", ""); + propertyDialog.resize(QSize(500, 200)); + + if (propertyDialog.exec() == QDialog::Accepted) + { + featureUi.updateCurvesAndTracks(curves, tracks); } - } + } } //-------------------------------------------------------------------------------------------------- @@ -82,22 +87,35 @@ void RicChangeDataSourceFeature::setupActionLook(QAction* actionToSetup) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RicChangeDataSourceFeature::extractionCurves() +bool RicChangeDataSourceFeature::selectedTracksAndCurves(std::vector* curves, std::vector* tracks) { - std::vector extrCurves; + CVF_ASSERT(curves && tracks); + std::vector selectedObjects; + caf::SelectionManager::instance()->objectsByType(&selectedObjects); - std::vector curves = RicWellLogPlotCurveFeatureImpl::selectedWellLogCurves(); + if (selectedObjects.empty()) return false; - for (RimWellLogCurve* c : curves) + for (caf::PdmObject* selectedObject : selectedObjects) { - if (dynamic_cast(c)) + RimWellLogTrack* wellLogTrack = dynamic_cast(selectedObject); + RimWellLogExtractionCurve* wellLogExtractionCurve = dynamic_cast(selectedObject); + RimWellLogFileCurve* wellLogFileCurve = dynamic_cast(selectedObject); + if (wellLogTrack) + { + tracks->push_back(wellLogTrack); + } + else if (wellLogExtractionCurve) + { + curves->push_back(wellLogExtractionCurve); + } + else if (wellLogFileCurve) { - extrCurves.push_back(dynamic_cast(c)); + curves->push_back(wellLogFileCurve); } } - return extrCurves; + return selectedObjects.size() == (curves->size() + tracks->size()); } diff --git a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.h b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.h index 83cff04e9a..9ca6784c4e 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicChangeDataSourceFeature.h @@ -22,20 +22,19 @@ #include -class RimWellLogExtractionCurve; - +class RimWellLogCurve; +class RimWellLogTrack; //================================================================================================== /// //================================================================================================== class RicChangeDataSourceFeature : public caf::CmdFeature { - CAF_CMD_HEADER_INIT; - + CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook(QAction* actionToSetup) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook(QAction* actionToSetup) override; private: - static std::vector extractionCurves(); + static bool selectedTracksAndCurves(std::vector* curves, std::vector* tracks); }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicDeletePltPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicDeletePltPlotFeature.h index 77f5078983..b05fb54144 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicDeletePltPlotFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicDeletePltPlotFeature.h @@ -30,7 +30,7 @@ class RicDeletePltPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicDeleteRftPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicDeleteRftPlotFeature.h index 46c435d42c..ec3931522c 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicDeleteRftPlotFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicDeleteRftPlotFeature.h @@ -30,7 +30,7 @@ class RicDeleteRftPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp index e83a591ea1..26ea915fe4 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp @@ -18,9 +18,13 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RicDeleteWellLogPlotTrackFeature.h" - #include "RicWellLogPlotCurveFeatureImpl.h" +#include "RiaApplication.h" +#include "RiuPlotMainWindow.h" +#include "RiuWellLogPlot.h" +#include "RiuWellLogTrack.h" + #include "RimWellLogTrack.h" #include "RimWellLogPlot.h" @@ -63,6 +67,8 @@ void RicDeleteWellLogPlotTrackFeature::onActionTriggered(bool isChecked) std::vector selection; caf::SelectionManager::instance()->objectsByType(&selection); + RiuPlotMainWindow* plotWindow = RiaApplication::instance()->getOrCreateMainPlotWindow(); + std::set alteredWellLogPlots; for (size_t i = 0; i < selection.size(); i++) { @@ -72,15 +78,23 @@ void RicDeleteWellLogPlotTrackFeature::onActionTriggered(bool isChecked) track->firstAncestorOrThisOfType(wellLogPlot); if (wellLogPlot && wellLogPlot->trackCount() > 1) { + alteredWellLogPlots.insert(wellLogPlot); wellLogPlot->removeTrack(track); caf::SelectionManager::instance()->removeObjectFromAllSelections(track); - delete track; - wellLogPlot->calculateAvailableDepthRange(); - wellLogPlot->updateDepthZoom(); - wellLogPlot->uiCapability()->updateConnectedEditors(); + wellLogPlot->updateConnectedEditors(); + delete track; } } + + for (RimWellLogPlot* wellLogPlot : alteredWellLogPlots) + { + RiuWellLogPlot* viewWidget = dynamic_cast(wellLogPlot->viewWidget()); + plotWindow->setWidthOfMdiWindow(viewWidget, viewWidget->preferredSize().width()); + wellLogPlot->calculateAvailableDepthRange(); + wellLogPlot->updateDepthZoom(); + wellLogPlot->uiCapability()->updateConnectedEditors(); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.h b/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.h index cb5ebca9a0..e67ec9fdee 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.h @@ -30,7 +30,7 @@ class RicDeleteWellLogPlotTrackFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicMoveWellLogFilesFeature.h b/ApplicationCode/Commands/WellLogCommands/RicMoveWellLogFilesFeature.h index f2b4d35997..6e6d9da01e 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicMoveWellLogFilesFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicMoveWellLogFilesFeature.h @@ -31,7 +31,7 @@ class RicMoveWellLogFilesFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.cpp index 2e87c701c3..31f57f0475 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.cpp @@ -101,7 +101,7 @@ void RicNewPltPlotFeature::onActionTriggered(bool isChecked) } else if ((eclipseWell = caf::firstAncestorOfTypeFromSelectedObject()) != nullptr) { - RimWellPath* wellPath = proj->wellPathFromSimWellName(eclipseWell->name()); + wellPath = proj->wellPathFromSimWellName(eclipseWell->name()); if (!wellPath ) return; wellPathName = wellPath->name(); @@ -138,15 +138,6 @@ void RicNewPltPlotFeature::setupActionLook(QAction* actionToSetup) actionToSetup->setIcon(QIcon(":/WellFlowPlot16x16.png")); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellLogTrack* RicNewPltPlotFeature::selectedWellLogPlotTrack() const -{ - auto selection = caf::selectedObjectsByType(); - return selection.size() > 0 ? selection[0] : nullptr; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.h index 28137d38a9..f940b31f72 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.h @@ -39,12 +39,11 @@ class RicNewPltPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: - RimWellLogTrack* selectedWellLogPlotTrack() const; RimWellPath* selectedWellPath() const; RimSimWellInView* selectedSimulationWell(int * branchIndex) const; bool caseAvailable() const; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewRftPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewRftPlotFeature.h index 1650d03610..2ad26650fa 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewRftPlotFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicNewRftPlotFeature.h @@ -28,9 +28,9 @@ class RicNewRftPlotFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; static QString selectedWellName(); }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp new file mode 100644 index 0000000000..f9f78f7856 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp @@ -0,0 +1,261 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicNewWellBoreStabilityPlotFeature.h" + +#include "RicNewWellLogPlotFeatureImpl.h" +#include "RicNewWellLogFileCurveFeature.h" +#include "RicNewWellLogCurveExtractionFeature.h" +#include "RicWellLogTools.h" + +#include "RigFemResultAddress.h" +#include "RigFemPartResultsCollection.h" +#include "RigGeoMechCaseData.h" +#include "RigWellPath.h" +#include "RimGeoMechCase.h" +#include "RimGeoMechView.h" +#include "RimProject.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotCollection.h" +#include "RimWellLogTrack.h" +#include "RimWellLogExtractionCurve.h" +#include "RimWellLogFile.h" +#include "RimWellLogFileCurve.h" +#include "RimWellLogFileChannel.h" +#include "RimWellPath.h" + +#include "RicWellLogTools.h" +#include "RiuPlotMainWindowTools.h" + +#include "RiaApplication.h" + +#include "cvfAssert.h" +#include "cvfMath.h" +#include "cafProgressInfo.h" +#include "cafSelectionManager.h" + +#include +#include +#include + +#include + +CAF_CMD_SOURCE_INIT(RicNewWellBoreStabilityPlotFeature, "RicNewWellBoreStabilityPlotFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewWellBoreStabilityPlotFeature::isCommandEnabled() +{ + Rim3dView* view = RiaApplication::instance()->activeReservoirView(); + if (!view) return false; + RimGeoMechView* geoMechView = dynamic_cast(view); + return geoMechView != nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellBoreStabilityPlotFeature::onActionTriggered(bool isChecked) +{ + RimWellPath* wellPath = caf::SelectionManager::instance()->selectedItemAncestorOfType(); + RimWellLogPlotCollection* plotCollection = caf::SelectionManager::instance()->selectedItemOfType(); + if (!wellPath) + { + if (plotCollection) + { + RimProject* project = nullptr; + plotCollection->firstAncestorOrThisOfTypeAsserted(project); + std::vector allWellPaths; + project->descendantsIncludingThisOfType(allWellPaths); + if (!allWellPaths.empty()) + { + wellPath = allWellPaths.front(); + } + } + } + + if (!wellPath) + { + return; + } + + Rim3dView* view = RiaApplication::instance()->activeReservoirView(); + if (!view) return; + + RimGeoMechView* geoMechView = dynamic_cast(view); + if (!geoMechView) return; + + caf::ProgressInfo progInfo(100, "Creating Well Bore Stability Plot"); + progInfo.setProgressDescription("Creating plot and formation track"); + progInfo.setNextProgressIncrement(2); + RimGeoMechCase* geoMechCase = geoMechView->geoMechCase(); + + QString plotName("Well Bore Stability"); + RimWellLogPlot* plot = RicNewWellLogPlotFeatureImpl::createWellLogPlot(false, plotName); + createFormationTrack(plot, wellPath, geoMechCase); + progInfo.incrementProgressAndUpdateNextStep(3, "Creating well design track"); + createCasingShoeTrack(plot, wellPath, geoMechCase); + progInfo.incrementProgressAndUpdateNextStep(75, "Creating stability curves track"); + createStabilityCurvesTrack(plot, wellPath, geoMechView); + progInfo.incrementProgressAndUpdateNextStep(15, "Creating angles track"); + createAnglesTrack(plot, wellPath, geoMechView); + progInfo.incrementProgressAndUpdateNextStep(5, "Updating all tracks"); + plot->enableAllAutoNameTags(true); + plot->setPlotTitleVisible(true); + plot->setTrackLegendsVisible(true); + plot->setTrackLegendsHorizontal(true); + plot->setDepthType(RimWellLogPlot::TRUE_VERTICAL_DEPTH); + plot->setDepthAutoZoom(true); + + RicNewWellLogPlotFeatureImpl::updateAfterCreation(plot); + progInfo.incrementProgress(); + + RiuPlotMainWindowTools::selectAsCurrentItem(plot); + + // Make sure the summary plot window is visible + RiuPlotMainWindowTools::showPlotMainWindow(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellBoreStabilityPlotFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Well Bore Stability Plot"); + actionToSetup->setIcon(QIcon(":/WellLogPlot16x16.png")); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellBoreStabilityPlotFeature::createFormationTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase) +{ + RimWellLogTrack* formationTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(false, "Formations", plot); + formationTrack->setFormationWellPath(wellPath); + formationTrack->setFormationCase(geoMechCase); + formationTrack->setShowFormations(true); + formationTrack->setVisibleXRange(0.0, 0.0); + formationTrack->setWidthScaleFactor(RimWellLogTrack::NARROW_TRACK); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellBoreStabilityPlotFeature::createCasingShoeTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase) +{ + RimWellLogTrack* casingShoeTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(false, "Well Design", plot); + casingShoeTrack->setWidthScaleFactor(RimWellLogTrack::NARROW_TRACK); + casingShoeTrack->setFormationWellPath(wellPath); + casingShoeTrack->setFormationCase(geoMechCase); + casingShoeTrack->setShowFormations(true); + casingShoeTrack->setShowFormationLabels(false); + casingShoeTrack->setShowWellPathAttributes(true); + casingShoeTrack->setWellPathAttributesSource(wellPath); + casingShoeTrack->setVisibleXRange(0.0, 0.0); + casingShoeTrack->setAutoScaleXEnabled(true); + casingShoeTrack->loadDataAndUpdate(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView) +{ + RimWellLogTrack* stabilityCurvesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(false, "Stability Curves", plot); + stabilityCurvesTrack->setWidthScaleFactor(RimWellLogTrack::EXTRA_WIDE_TRACK); + stabilityCurvesTrack->setAutoScaleXEnabled(true); + stabilityCurvesTrack->setTickIntervals(0.5, 0.05); + stabilityCurvesTrack->setXAxisGridVisibility(RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR); + stabilityCurvesTrack->setFormationWellPath(wellPath); + stabilityCurvesTrack->setFormationCase(geoMechView->geoMechCase()); + stabilityCurvesTrack->setShowFormations(true); + stabilityCurvesTrack->setShowFormationLabels(false); + + std::vector resultNames = RiaDefines::wellPathStabilityResultNames(); + + std::vector colors = { cvf::Color3f::RED, cvf::Color3f::PURPLE, cvf::Color3f::GREEN, cvf::Color3f::BLUE, cvf::Color3f::ORANGE }; + std::vector lineStyles = { RiuQwtPlotCurve::STYLE_SOLID, RiuQwtPlotCurve::STYLE_DASH, RiuQwtPlotCurve::STYLE_DASH_DOT, RiuQwtPlotCurve::STYLE_SOLID, RiuQwtPlotCurve::STYLE_DASH}; + + for (size_t i = 0; i < resultNames.size(); ++i) + { + const QString& resultName = resultNames[i]; + RigFemResultAddress resAddr(RIG_WELLPATH_DERIVED, resultName.toStdString(), ""); + RimWellLogExtractionCurve* curve = RicWellLogTools::addExtractionCurve(stabilityCurvesTrack, geoMechView, wellPath, nullptr, 0, false, false); + curve->setGeoMechResultAddress(resAddr); + curve->setCurrentTimeStep(geoMechView->currentTimeStep()); + curve->setCustomName(resultName); + curve->setColor(colors[i % colors.size()]); + curve->setLineStyle(lineStyles[i % lineStyles.size()]); + curve->setLineThickness(2); + curve->loadDataAndUpdate(false); + } + stabilityCurvesTrack->calculateXZoomRangeAndUpdateQwt(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellBoreStabilityPlotFeature::createAnglesTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView) +{ + RimWellLogTrack* wellPathAnglesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(false, "Well Path Angles", plot); + double minValue = 360.0, maxValue = 0.0; + const double angleIncrement = 90.0; + std::vector resultNames = RiaDefines::wellPathAngleResultNames(); + + std::vector colors = { cvf::Color3f::DARK_RED, cvf::Color3f::BLUE }; + + std::vector lineStyles = { RiuQwtPlotCurve::STYLE_SOLID, RiuQwtPlotCurve::STYLE_DASH }; + + for (size_t i = 0; i < resultNames.size(); ++i) + { + const QString& resultName = resultNames[i]; + RigFemResultAddress resAddr(RIG_WELLPATH_DERIVED, resultName.toStdString(), ""); + RimWellLogExtractionCurve* curve = RicWellLogTools::addExtractionCurve(wellPathAnglesTrack, geoMechView, wellPath, nullptr, 0, false, false); + curve->setGeoMechResultAddress(resAddr); + curve->setCurrentTimeStep(geoMechView->currentTimeStep()); + curve->setCustomName(resultName); + + curve->setColor(colors[i % colors.size()]); + curve->setLineStyle(lineStyles[i % lineStyles.size()]); + curve->setLineThickness(2); + + curve->loadDataAndUpdate(false); + + double actualMinValue = minValue, actualMaxValue = maxValue; + curve->valueRange(&actualMinValue, &actualMaxValue); + while (maxValue < actualMaxValue) + { + maxValue += angleIncrement; + } + while (minValue > actualMinValue) + { + minValue -= angleIncrement; + } + maxValue = cvf::Math::clamp(maxValue, angleIncrement, 360.0); + minValue = cvf::Math::clamp(minValue, 0.0, maxValue - 90.0); + } + wellPathAnglesTrack->setWidthScaleFactor(RimWellLogTrack::NORMAL_TRACK); + wellPathAnglesTrack->setVisibleXRange(minValue, maxValue); + wellPathAnglesTrack->setTickIntervals(90.0, 30.0); + wellPathAnglesTrack->setXAxisGridVisibility(RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR); + wellPathAnglesTrack->setFormationWellPath(wellPath); + wellPathAnglesTrack->setFormationCase(geoMechView->geoMechCase()); + wellPathAnglesTrack->setShowFormations(true); + wellPathAnglesTrack->setShowFormationLabels(false); +} diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.h new file mode 100644 index 0000000000..c8931efec8 --- /dev/null +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.h @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +class RimGeoMechCase; +class RimGeoMechView; +class RimWellLogPlot; +class RimWellPath; + +//================================================================================================== +/// +//================================================================================================== +class RicNewWellBoreStabilityPlotFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; + +private: + void createFormationTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase); + void createCasingShoeTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase); + void createStabilityCurvesTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechCase); + void createAnglesTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView); +}; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.cpp index c75fe4711a..e4700459ed 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.cpp @@ -57,7 +57,7 @@ bool RicNewWellLogCurveExtractionFeature::isCommandEnabled() if (RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot()) return false; if (RicWellLogPlotCurveFeatureImpl::parentWellRftPlot()) return false; int branchIndex; - return (RicWellLogTools::selectedWellLogPlotTrack() != nullptr || RicWellLogTools::selectedWellPath() != nullptr || RicWellLogTools::selectedSimulationWell(&branchIndex) != nullptr) && caseAvailable(); + return (caf::SelectionManager::instance()->selectedItemOfType() != nullptr || caf::SelectionManager::instance()->selectedItemOfType() != nullptr || RicWellLogTools::selectedSimulationWell(&branchIndex) != nullptr) && caseAvailable(); } //-------------------------------------------------------------------------------------------------- @@ -67,14 +67,14 @@ void RicNewWellLogCurveExtractionFeature::onActionTriggered(bool isChecked) { if (RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot()) return; - RimWellLogTrack* wellLogPlotTrack = RicWellLogTools::selectedWellLogPlotTrack(); + RimWellLogTrack* wellLogPlotTrack = caf::SelectionManager::instance()->selectedItemOfType(); if (wellLogPlotTrack) { RicWellLogTools::addExtractionCurve(wellLogPlotTrack, nullptr, nullptr, nullptr, -1, true); } else { - RimWellPath* wellPath = RicWellLogTools::selectedWellPath(); + RimWellPath* wellPath = caf::SelectionManager::instance()->selectedItemOfType(); int branchIndex = -1; RimSimWellInView* simWell = RicWellLogTools::selectedSimulationWell(&branchIndex); @@ -88,16 +88,16 @@ void RicNewWellLogCurveExtractionFeature::onActionTriggered(bool isChecked) if (wellPath || simWell) { - RimWellLogTrack* wellLogPlotTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(); + RimWellLogTrack* newWellLogPlotTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(); RimWellLogExtractionCurve* plotCurve = - RicWellLogTools::addExtractionCurve(wellLogPlotTrack, RiaApplication::instance()->activeReservoirView(), wellPath, + RicWellLogTools::addExtractionCurve(newWellLogPlotTrack, RiaApplication::instance()->activeReservoirView(), wellPath, simWell, branchIndex, useBranchDetection); plotCurve->loadDataAndUpdate(true); RimWellLogPlot* plot = nullptr; - wellLogPlotTrack->firstAncestorOrThisOfType(plot); + newWellLogPlotTrack->firstAncestorOrThisOfType(plot); if (plot && plotCurve->curveData()) { plot->setDepthUnit(plotCurve->curveData()->depthUnit()); diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.h index 3be92931d6..df8093b8de 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogCurveExtractionFeature.h @@ -29,9 +29,9 @@ class RicNewWellLogCurveExtractionFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; static bool caseAvailable(); }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp index 5aa90c4cd7..fcd3018290 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp @@ -19,22 +19,21 @@ #include "RicNewWellLogFileCurveFeature.h" -#include "RicWellLogPlotCurveFeatureImpl.h" #include "RicNewWellLogPlotFeatureImpl.h" +#include "RicWellLogPlotCurveFeatureImpl.h" +#include "RicWellLogTools.h" #include "RiaApplication.h" -#include "RimOilField.h" -#include "RimProject.h" +#include "RimTools.h" #include "RimWellLogFile.h" #include "RimWellLogFileChannel.h" #include "RimWellLogFileCurve.h" #include "RimWellLogTrack.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" -#include "RiuPlotMainWindow.h" -#include "RicWellLogTools.h" +#include "RiuPlotMainWindow.h" #include "cafSelectionManager.h" @@ -51,7 +50,7 @@ CAF_CMD_SOURCE_INIT(RicNewWellLogFileCurveFeature, "RicNewWellLogFileCurveFeatur bool RicNewWellLogFileCurveFeature::isCommandEnabled() { if (RicWellLogPlotCurveFeatureImpl::parentWellRftPlot()) return false; - return (RicWellLogTools::selectedWellLogPlotTrack() != nullptr && wellLogFilesAvailable()) || RicWellLogTools::selectedWellPathWithLogFile() != nullptr; + return (caf::SelectionManager::instance()->selectedItemAncestorOfType() != nullptr && wellLogFilesAvailable()) || RicWellLogTools::selectedWellPathWithLogFile() != nullptr; } //-------------------------------------------------------------------------------------------------- @@ -59,7 +58,7 @@ bool RicNewWellLogFileCurveFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicNewWellLogFileCurveFeature::onActionTriggered(bool isChecked) { - RimWellLogTrack* wellLogPlotTrack = RicWellLogTools::selectedWellLogPlotTrack(); + RimWellLogTrack* wellLogPlotTrack = caf::SelectionManager::instance()->selectedItemAncestorOfType(); if (wellLogPlotTrack) { RicWellLogTools::addFileCurve(wellLogPlotTrack); @@ -69,8 +68,8 @@ void RicNewWellLogFileCurveFeature::onActionTriggered(bool isChecked) RimWellPath* wellPath = RicWellLogTools::selectedWellPathWithLogFile(); if (wellPath) { - RimWellLogTrack* wellLogPlotTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(); - RimWellLogFileCurve* plotCurve = RicWellLogTools::addFileCurve(wellLogPlotTrack); + RimWellLogTrack* newWellLogPlotTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(); + RimWellLogFileCurve* plotCurve = RicWellLogTools::addFileCurve(newWellLogPlotTrack); plotCurve->setWellPath(wellPath); if (wellPath->wellLogFiles().size() == 1) @@ -96,10 +95,10 @@ void RicNewWellLogFileCurveFeature::setupActionLook(QAction* actionToSetup) //-------------------------------------------------------------------------------------------------- bool RicNewWellLogFileCurveFeature::wellLogFilesAvailable() { - RimProject* project = RiaApplication::instance()->project(); - if (project->activeOilField()->wellPathCollection()) + auto wellPathCollection = RimTools::wellPathCollection(); + if (wellPathCollection) { - caf::PdmChildArrayField& wellPaths = project->activeOilField()->wellPathCollection()->wellPaths; + caf::PdmChildArrayField& wellPaths = wellPathCollection->wellPaths; for (size_t i = 0; i < wellPaths.size(); i++) { diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.h index 0a686babe4..37f87995fa 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.h @@ -31,9 +31,9 @@ class RicNewWellLogFileCurveFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static bool wellLogFilesAvailable(); diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeature.h index 061c0d99e6..ca203a9032 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeature.h @@ -30,7 +30,7 @@ class RicNewWellLogPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.cpp index c568d2a5ab..09e7ce1e6c 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.cpp @@ -29,23 +29,37 @@ #include "cvfAssert.h" +#include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellLogPlot* RicNewWellLogPlotFeatureImpl::createWellLogPlot() +RimWellLogPlot* RicNewWellLogPlotFeatureImpl::createWellLogPlot(bool showAfterCreation, const QString& plotDescription) { RimWellLogPlotCollection* wellLogPlotColl = wellLogPlotCollection(); CVF_ASSERT(wellLogPlotColl); + // Make sure the summary plot window is created + RiaApplication::instance()->getOrCreateMainPlotWindow(); + RimWellLogPlot* plot = new RimWellLogPlot(); plot->setAsPlotMdiWindow(); + wellLogPlotColl->wellLogPlots().push_back(plot); - // Make sure the summary plot window is created and visible - RiaApplication::instance()->getOrCreateAndShowMainPlotWindow(); + if (!plotDescription.isEmpty()) + { + plot->setDescription(plotDescription); + } + else + { + plot->setDescription(QString("Well Log Plot %1").arg(wellLogPlotCollection()->wellLogPlots.size())); + } - plot->setDescription(QString("Well Log Plot %1").arg(wellLogPlotCollection()->wellLogPlots.size())); + if (showAfterCreation) + { + RiaApplication::instance()->getOrCreateAndShowMainPlotWindow(); + } return plot; } @@ -53,19 +67,43 @@ RimWellLogPlot* RicNewWellLogPlotFeatureImpl::createWellLogPlot() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellLogTrack* RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack() +RimWellLogTrack* RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(bool updateAfter, const QString& trackDescription, RimWellLogPlot* existingPlot) { - RimWellLogPlot* plot = createWellLogPlot(); + RimWellLogPlot* plot = existingPlot; + if (plot == nullptr) + { + plot = createWellLogPlot(); + } RimWellLogTrack* plotTrack = new RimWellLogTrack(); plot->addTrack(plotTrack); - plotTrack->setDescription(QString("Track %1").arg(plot->trackCount())); + if (!trackDescription.isEmpty()) + { + plotTrack->setDescription(trackDescription); + } + else + { + plotTrack->setDescription(QString("Track %1").arg(plot->trackCount())); + } + + if (updateAfter) + { + updateAfterCreation(plot); + } + return plotTrack; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellLogPlotFeatureImpl::updateAfterCreation(RimWellLogPlot* plot) +{ + CVF_ASSERT(plot); plot->loadDataAndUpdate(); + plot->updateDepthZoom(); plot->updateConnectedEditors(); RiaApplication::instance()->project()->updateConnectedEditors(); - - return plotTrack; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.h index 48ebdecfd8..092aedb7f3 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.h +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotFeatureImpl.h @@ -19,6 +19,8 @@ #pragma once +#include + class RimWellLogPlotCollection; class RimWellLogPlot; class RimWellLogTrack; @@ -29,9 +31,9 @@ class RimWellLogTrack; class RicNewWellLogPlotFeatureImpl { public: - static RimWellLogPlot* createWellLogPlot(); - static RimWellLogTrack* createWellLogPlotTrack(); - + static RimWellLogPlot* createWellLogPlot(bool showAfterCreation = true, const QString& plotDescription = QString("")); + static RimWellLogTrack* createWellLogPlotTrack(bool updateAfterCreation = true, const QString& trackDescription = QString(""), RimWellLogPlot* existingPlot = nullptr); + static void updateAfterCreation(RimWellLogPlot* plot); private: static RimWellLogPlotCollection* wellLogPlotCollection(); }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp index f8f94e7002..8ff17fb6d4 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp @@ -19,6 +19,11 @@ #include "RicNewWellLogPlotTrackFeature.h" +#include "RiaApplication.h" +#include "RiuPlotMainWindow.h" +#include "RiuWellLogPlot.h" +#include "RiuWellLogTrack.h" + #include "RicNewWellLogCurveExtractionFeature.h" #include "RicWellLogPlotCurveFeatureImpl.h" #include "RicWellLogTools.h" @@ -26,6 +31,7 @@ #include "RimWellLogPlot.h" #include "RimWellLogTrack.h" + #include "cafSelectionManager.h" #include @@ -60,9 +66,13 @@ void RicNewWellLogPlotTrackFeature::onActionTriggered(bool isChecked) RimWellLogTrack* plotTrack = new RimWellLogTrack; wellLogPlot->addTrack(plotTrack); plotTrack->setDescription(QString("Track %1").arg(wellLogPlot->trackCount())); - - wellLogPlot->updateConnectedEditors(); + RiuPlotMainWindow* plotWindow = RiaApplication::instance()->getOrCreateMainPlotWindow(); + RiuWellLogPlot* viewWidget = dynamic_cast(wellLogPlot->viewWidget()); RicWellLogTools::addExtractionCurve(plotTrack, nullptr, nullptr, nullptr, -1, true); + + plotWindow->setWidthOfMdiWindow(viewWidget, viewWidget->preferredSize().width()); + wellLogPlot->updateConnectedEditors(); + wellLogPlot->loadDataAndUpdate(); } } @@ -81,5 +91,5 @@ RimWellLogPlot* RicNewWellLogPlotTrackFeature::selectedWellLogPlot() { std::vector selection; caf::SelectionManager::instance()->objectsByType(&selection); - return selection.size() > 0 ? selection[0] : NULL; + return selection.size() > 0 ? selection[0] : nullptr; } diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.h index 92d78de7c2..29ed8ebe78 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.h @@ -32,9 +32,9 @@ class RicNewWellLogPlotTrackFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: RimWellLogPlot* selectedWellLogPlot(); diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogRftCurveFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogRftCurveFeature.cpp index de127dd677..c7451876e3 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogRftCurveFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogRftCurveFeature.cpp @@ -37,6 +37,8 @@ #include #include +#include "cafSelectionManager.h" + #include @@ -48,7 +50,7 @@ CAF_CMD_SOURCE_INIT(RicNewWellLogRftCurveFeature, "RicNewWellLogRftCurveFeature" bool RicNewWellLogRftCurveFeature::isCommandEnabled() { if (RicWellLogPlotCurveFeatureImpl::parentWellRftPlot()) return false; - if (RicWellLogTools::selectedWellLogPlotTrack() != nullptr) + if (caf::SelectionManager::instance()->selectedItemOfType() != nullptr) { return true; } @@ -69,7 +71,7 @@ bool RicNewWellLogRftCurveFeature::isCommandEnabled() //-------------------------------------------------------------------------------------------------- void RicNewWellLogRftCurveFeature::onActionTriggered(bool isChecked) { - RimWellLogTrack* wellLogPlotTrack = RicWellLogTools::selectedWellLogPlotTrack(); + RimWellLogTrack* wellLogPlotTrack = caf::SelectionManager::instance()->selectedItemOfType(); if (wellLogPlotTrack) { int branchIdx; @@ -81,13 +83,13 @@ void RicNewWellLogRftCurveFeature::onActionTriggered(bool isChecked) RimSimWellInView* simWell = RicWellLogTools::selectedSimulationWell(&branchIndex); if (simWell) { - RimWellLogTrack* wellLogPlotTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(); - RimWellLogRftCurve* plotCurve = RicWellLogTools::addRftCurve(wellLogPlotTrack, simWell); + RimWellLogTrack* newWellLogPlotTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(); + RimWellLogRftCurve* plotCurve = RicWellLogTools::addRftCurve(newWellLogPlotTrack, simWell); plotCurve->loadDataAndUpdate(true); RimWellLogPlot* plot = nullptr; - wellLogPlotTrack->firstAncestorOrThisOfType(plot); + newWellLogPlotTrack->firstAncestorOrThisOfType(plot); if (plot && plotCurve->curveData()) { plot->setDepthUnit(plotCurve->curveData()->depthUnit()); diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogRftCurveFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogRftCurveFeature.h index 30ef986af7..27749032a6 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogRftCurveFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogRftCurveFeature.h @@ -28,7 +28,7 @@ class RicNewWellLogRftCurveFeature : public caf::CmdFeature CAF_CMD_HEADER_INIT; private: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogCurveFeature.h b/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogCurveFeature.h index f25950cdd6..4172a74e10 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogCurveFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogCurveFeature.h @@ -34,9 +34,9 @@ class RicPasteWellLogCurveFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static std::vector > curves(); diff --git a/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogPlotFeature.h index 25f4e1e752..010fd0d9cd 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogPlotFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogPlotFeature.h @@ -34,9 +34,9 @@ class RicPasteWellLogPlotFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static std::vector > plots(); diff --git a/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogTrackFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogTrackFeature.cpp index 034753a42b..5c39666c0d 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogTrackFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogTrackFeature.cpp @@ -64,10 +64,7 @@ void RicPasteWellLogTrackFeature::onActionTriggered(bool isChecked) { if (RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot()) return; - caf::PdmObjectHandle* destinationObject = dynamic_cast(caf::SelectionManager::instance()->selectedItem()); - - RimWellLogPlot* wellLogPlot = nullptr; - destinationObject->firstAncestorOrThisOfType(wellLogPlot); + RimWellLogPlot* wellLogPlot = caf::SelectionManager::instance()->selectedItemAncestorOfType(); if (!wellLogPlot) { return; diff --git a/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogTrackFeature.h b/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogTrackFeature.h index 56dd6fe954..7d343dc695 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogTrackFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicPasteWellLogTrackFeature.h @@ -34,9 +34,9 @@ class RicPasteWellLogTrackFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; private: static std::vector > tracks(); diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.cpp index 7cbde19541..58c27b6184 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.cpp @@ -60,7 +60,7 @@ void RicWellLogFileCloseFeature::onActionTriggered(bool isChecked) RimWellPath* parentWellPath; wellLogFile->firstAncestorOrThisOfType(parentWellPath); - if (parentWellPath != nullptr) + if (parentWellPath) { std::set referringPlots = referringWellLogPlots(wellLogFile); parentWellPath->deleteWellLogFile(wellLogFile); @@ -69,8 +69,9 @@ void RicWellLogFileCloseFeature::onActionTriggered(bool isChecked) { plot->loadDataAndUpdate(); } + + parentWellPath->updateConnectedEditors(); } - parentWellPath->updateConnectedEditors(); } caf::PdmUiObjectEditorHandle::updateUiAllObjectEditors(); diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.h b/ApplicationCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.h index 4cbeb753d5..241a11cec1 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogFileCloseFeature.h @@ -34,9 +34,9 @@ class RicWellLogFileCloseFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; std::set referringWellLogPlots(const RimWellLogFile* wellLogFile); }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp index 1884f87fea..8494551d41 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp @@ -19,6 +19,11 @@ #include "RicWellLogPlotTrackFeatureImpl.h" +#include "RiaApplication.h" +#include "RiuPlotMainWindow.h" +#include "RiuWellLogPlot.h" +#include "RiuWellLogTrack.h" + #include "RimWellLogCurve.h" #include "RimWellLogPlot.h" #include "RimWellLogTrack.h" @@ -70,11 +75,13 @@ void RicWellLogPlotTrackFeatureImpl::moveCurvesToWellLogPlotTrack(RimWellLogTrac for (std::set::iterator tIt = srcTracks.begin(); tIt != srcTracks.end(); ++tIt) { - (*tIt)->updateXZoomAndParentPlotDepthZoom(); + (*tIt)->updateParentPlotZoom(); + (*tIt)->calculateXZoomRangeAndUpdateQwt(); } destTrack->loadDataAndUpdate(); - destTrack->updateXZoomAndParentPlotDepthZoom(); + destTrack->updateParentPlotZoom(); + destTrack->calculateXZoomRangeAndUpdateQwt(); destTrack->updateConnectedEditors(); } @@ -87,6 +94,8 @@ void RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot(RimWellLogPlot* dst { CVF_ASSERT(dstWellLogPlot); + RiuPlotMainWindow* plotWindow = RiaApplication::instance()->getOrCreateMainPlotWindow(); + std::set srcPlots; for (size_t tIdx = 0; tIdx < tracksToMove.size(); tIdx++) @@ -98,13 +107,16 @@ void RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot(RimWellLogPlot* dst if (srcPlot) { srcPlot->removeTrack(track); - + srcPlots.insert(srcPlot); } } for (std::set::iterator pIt = srcPlots.begin(); pIt != srcPlots.end(); ++pIt) { + RiuWellLogPlot* viewWidget = dynamic_cast((*pIt)->viewWidget()); + plotWindow->setWidthOfMdiWindow(viewWidget, viewWidget->preferredSize().width()); + (*pIt)->calculateAvailableDepthRange(); (*pIt)->updateTrackNames(); (*pIt)->updateDepthZoom(); @@ -118,7 +130,10 @@ void RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot(RimWellLogPlot* dst for (size_t tIdx = 0; tIdx < tracksToMove.size(); tIdx++) { dstWellLogPlot->insertTrack(tracksToMove[tIdx], insertionStartIndex + tIdx); + } + RiuWellLogPlot* viewWidget = dynamic_cast(dstWellLogPlot->viewWidget()); + plotWindow->setWidthOfMdiWindow(viewWidget, viewWidget->preferredSize().width()); dstWellLogPlot->updateTrackNames(); dstWellLogPlot->updateTracks(); diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogsImportFileFeature.h b/ApplicationCode/Commands/WellLogCommands/RicWellLogsImportFileFeature.h index 11eaec4b12..900ad6d141 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicWellLogsImportFileFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogsImportFileFeature.h @@ -31,7 +31,7 @@ class RicWellLogsImportFileFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake b/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake index 67a87c1d8c..7af02e103f 100644 --- a/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake +++ b/ApplicationCode/Commands/WellPathCommands/CMakeLists_files.cmake @@ -3,22 +3,38 @@ set (SOURCE_GROUP_HEADER_FILES ${CMAKE_CURRENT_LIST_DIR}/RicWellPathDeleteFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathsImportFileFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathsImportSsihubFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicNewEditableWellPathFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicShowWellPlanFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathListTargetFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathAttributeFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathTargetFeature.h +${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathAttributeFeature.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsImpl.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsUi.h -${CMAKE_CURRENT_LIST_DIR}/RicWellPathViewerEventHandler.h -${CMAKE_CURRENT_LIST_DIR}/RicIntersectionViewerEventHandler.h +${CMAKE_CURRENT_LIST_DIR}/RicWellPathPickEventHandler.h +${CMAKE_CURRENT_LIST_DIR}/RicCreateWellTargetsPickEventHandler.h +${CMAKE_CURRENT_LIST_DIR}/RicIntersectionPickEventHandler.h ${CMAKE_CURRENT_LIST_DIR}/RicWellPathFormationsImportFileFeature.h +${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPointTangentManipulator.h ) set (SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RicWellPathDeleteFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathsImportFileFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathsImportSsihubFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicNewEditableWellPathFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicShowWellPlanFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathListTargetFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicNewWellPathAttributeFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathTargetFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/RicDeleteWellPathAttributeFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsImpl.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathsUnitSystemSettingsUi.cpp -${CMAKE_CURRENT_LIST_DIR}/RicWellPathViewerEventHandler.cpp -${CMAKE_CURRENT_LIST_DIR}/RicIntersectionViewerEventHandler.cpp +${CMAKE_CURRENT_LIST_DIR}/RicWellPathPickEventHandler.cpp +${CMAKE_CURRENT_LIST_DIR}/RicCreateWellTargetsPickEventHandler.cpp +${CMAKE_CURRENT_LIST_DIR}/RicIntersectionPickEventHandler.cpp ${CMAKE_CURRENT_LIST_DIR}/RicWellPathFormationsImportFileFeature.cpp +${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPointTangentManipulator.cpp ) list(APPEND CODE_HEADER_FILES @@ -29,4 +45,8 @@ list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES} ) +list(APPEND QT_MOC_HEADERS +${CMAKE_CURRENT_LIST_DIR}/PointTangentManipulator/RicPointTangentManipulator.h +) + source_group( "CommandFeature\\WellPath" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake ) diff --git a/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.cpp b/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.cpp new file mode 100644 index 0000000000..10a8fa81f0 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.cpp @@ -0,0 +1,914 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2013- Statoil ASA +// Copyright (C) 2013- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicPointTangentManipulator.h" + +#include "cafViewer.h" + +#include "cvfCamera.h" +#include "cvfDrawableGeo.h" +#include "cvfHitItemCollection.h" +#include "cvfModelBasicList.h" +#include "cvfPart.h" +#include "cvfRay.h" + +#include +#include +#include "RivPartPriority.h" +#include "cafPdmUiCommandSystemProxy.h" +#include "RimModeledWellPath.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicPointTangentManipulator::RicPointTangentManipulator(caf::Viewer* viewer) + : m_viewer(viewer) +{ + m_partManager = new RicPointTangentManipulatorPartMgr; + + m_viewer->installEventFilter(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicPointTangentManipulator::~RicPointTangentManipulator() +{ + if (m_viewer) m_viewer->removeEventFilter(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulator::setOrigin(const cvf::Vec3d& origin) +{ + m_partManager->setOrigin(origin); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulator::setTangent(const cvf::Vec3d& tangent) +{ + m_partManager->setTangent(tangent); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulator::setHandleSize(double handleSize) +{ + m_partManager->setHandleSize(handleSize); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulator::appendPartsToModel(cvf::ModelBasicList* model) +{ + m_partManager->appendPartsToModel(model); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicPointTangentManipulator::eventFilter(QObject *obj, QEvent* inputEvent) +{ + if (inputEvent->type() == QEvent::MouseButtonPress) + { + QMouseEvent* mouseEvent = static_cast(inputEvent); + + if (mouseEvent->button() == Qt::LeftButton) + { + cvf::HitItemCollection hitItems; + if (m_viewer->rayPick(mouseEvent->x(), mouseEvent->y(), &hitItems)) + { + m_partManager->tryToActivateManipulator(hitItems.firstItem()); + + if(m_partManager->isManipulatorActive()) + { + emit notifySelected(); + + return true; + } + } + } + } + else if (inputEvent->type() == QEvent::MouseMove) + { + if (m_partManager->isManipulatorActive()) + { + QMouseEvent* mouseEvent = static_cast(inputEvent); + + //qDebug() << "Inside mouse move"; + //qDebug() << mouseEvent->pos(); + + int translatedMousePosX = mouseEvent->pos().x(); + int translatedMousePosY = m_viewer->height() - mouseEvent->pos().y(); + + cvf::ref ray = m_viewer->mainCamera()->rayFromWindowCoordinates(translatedMousePosX, translatedMousePosY); + if (!ray.isNull()) + { + m_partManager->updateManipulatorFromRay(ray.p()); + + cvf::Vec3d origin; + cvf::Vec3d tangent; + m_partManager->originAndTangent(&origin, &tangent); + + emit notifyUpdate(origin, tangent); + + return true; + } + } + } + else if (inputEvent->type() == QEvent::MouseButtonRelease) + { + if (m_partManager->isManipulatorActive()) + { + m_partManager->endManipulator(); + + cvf::Vec3d origin; + cvf::Vec3d tangent; + m_partManager->originAndTangent(&origin, &tangent); + + emit notifyUpdate(origin, tangent); + emit notifyDragFinished(); + + return true; + } + } + + return false; +} + + + +//================================================================================================== +/// +/// +//================================================================================================== + + + +#include "RicPointTangentManipulator.h" + +#include "cafBoxManipulatorGeometryGenerator.h" +#include "cafEffectGenerator.h" +#include "cafLine.h" +#include "cafSelectionManager.h" + +#include "cvfBoxGenerator.h" +#include "cvfDrawableGeo.h" +#include "cvfGeometryBuilderFaceList.h" +#include "cvfModelBasicList.h" +#include "cvfPart.h" +#include "cvfPrimitiveSetIndexedUInt.h" +#include "cvfPrimitiveSetIndexedUShort.h" +#include "cvfRay.h" +#include "cvfPrimitiveSetDirect.h" +#include "cvfHitItem.h" +#include + +#include "cvfGeometryBuilderTriangles.h" +#include "cvfGeometryUtils.h" +// + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicPointTangentManipulatorPartMgr::RicPointTangentManipulatorPartMgr() + : m_tangentOnStartManipulation(cvf::Vec3d::UNDEFINED), + m_originOnStartManipulation(cvf::Vec3d::UNDEFINED), + m_currentHandleIndex(cvf::UNDEFINED_SIZE_T), + m_handleSize(1.0) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicPointTangentManipulatorPartMgr::~RicPointTangentManipulatorPartMgr() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::setOrigin(const cvf::Vec3d& origin) +{ + if (isManipulatorActive()) return; + + m_origin = origin; + if (m_originOnStartManipulation.isUndefined()) m_originOnStartManipulation = origin; + + clearAllGeometryAndParts(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::setTangent(const cvf::Vec3d& tangent) +{ + if(isManipulatorActive()) return; + + m_tangent = tangent; + if (m_tangentOnStartManipulation.isUndefined()) m_tangentOnStartManipulation = m_tangent; + + clearAllGeometryAndParts(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::setHandleSize(double handleSize) +{ + m_handleSize = handleSize; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::originAndTangent(cvf::Vec3d* origin, cvf::Vec3d* tangent) +{ + *origin = m_origin; + *tangent = m_tangent; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicPointTangentManipulatorPartMgr::isManipulatorActive() const +{ + return m_currentHandleIndex != cvf::UNDEFINED_SIZE_T; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::appendPartsToModel(cvf::ModelBasicList* model) +{ + if (!m_handleParts.size()) + { + recreateAllGeometryAndParts(); + } + + for (size_t i = 0; i < m_handleParts.size(); i++) + { + model->addPart(m_handleParts.at(i)); + } + + for (auto activeModePart: m_activeDragModeParts) + { + model->addPart(activeModePart.p()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::tryToActivateManipulator(const cvf::HitItem* hitItem) +{ + endManipulator(); + + if (!hitItem) return; + + const cvf::Part* pickedPart = hitItem->part(); + const cvf::Vec3d intersectionPoint = hitItem->intersectionPoint(); + + if (!pickedPart) return; + + for (size_t i = 0; i < m_handleParts.size(); i++) + { + if (pickedPart == m_handleParts.at(i)) + { + m_initialPickPoint = intersectionPoint; + m_tangentOnStartManipulation = m_tangent; + m_originOnStartManipulation = m_origin; + m_currentHandleIndex = i; + } + } + +} + + +//-------------------------------------------------------------------------------------------------- +/// Calculate new origin and tangent based on the new ray position +/// Clear geometry to trigger regeneration +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::updateManipulatorFromRay(const cvf::Ray* newMouseRay) +{ + if (!isManipulatorActive()) return; + + if ( m_handleIds[m_currentHandleIndex] == HORIZONTAL_PLANE ) + { + cvf::Plane plane; + plane.setFromPointAndNormal(m_origin, cvf::Vec3d::Z_AXIS); + cvf::Vec3d newIntersection; + newMouseRay->planeIntersect(plane, &newIntersection); + + cvf::Vec3d newOrigin = m_originOnStartManipulation + (newIntersection - m_initialPickPoint); + + m_origin = newOrigin; + } + else if ( m_handleIds[m_currentHandleIndex] == VERTICAL_AXIS ) + { + cvf::Plane plane; + cvf::Vec3d planeNormal = (newMouseRay->direction() ^ cvf::Vec3d::Z_AXIS) ^ cvf::Vec3d::Z_AXIS; + double length = planeNormal.length(); + + if (length < 1e-5) return; + + planeNormal /= length; + plane.setFromPointAndNormal(m_initialPickPoint, planeNormal ); + cvf::Vec3d newIntersection; + newMouseRay->planeIntersect(plane, &newIntersection); + + cvf::Vec3d newOrigin = m_originOnStartManipulation; + newOrigin.z() += (newIntersection.z() - m_initialPickPoint.z()); + + m_origin = newOrigin; + } + //m_tangent = newTangent; + + clearAllGeometryAndParts(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::endManipulator() +{ + m_currentHandleIndex = cvf::UNDEFINED_SIZE_T; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::clearAllGeometryAndParts() +{ + m_handleIds.clear(); + m_handleParts.clear(); + m_activeDragModeParts.clear(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::recreateAllGeometryAndParts() +{ + createAllHandleParts(); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::createAllHandleParts() +{ + createHorizontalPlaneHandle(); + createVerticalAxisHandle(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::createHorizontalPlaneHandle() +{ + using namespace cvf; + cvf::ref vertexArray = new cvf::Vec3fArray(6); + + vertexArray->set(0, {-1, -1, 0} ); + vertexArray->set(1, { 1, -1, 0}); + vertexArray->set(2, { 1, 1, 0}); + vertexArray->set(3, {-1, -1, 0}); + vertexArray->set(4, { 1, 1, 0}); + vertexArray->set(5, {-1, 1, 0}); + + Vec3f origin(m_origin); + for (cvf::Vec3f& vx: *vertexArray) + { + vx *= 0.5*m_handleSize; + vx += origin; + } + + ref geo = createTriangelDrawableGeo(vertexArray.p()); + + HandleType handleId = HORIZONTAL_PLANE; + cvf::Color4f color = cvf::Color4f(1.0f, 0.0f, 1.0f, 0.5f); + cvf::String partName("PointTangentManipulator Horizontal Plane Handle"); + + addHandlePart(geo.p(), color, handleId, partName); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::createVerticalAxisHandle() +{ + using namespace cvf; + + cvf::ref< cvf::GeometryBuilderTriangles> geomBuilder = new cvf::GeometryBuilderTriangles; + cvf::GeometryUtils::createBox({-0.3f, -0.3f, -1.0f}, { 0.3f, 0.3f, 1.0f}, geomBuilder.p()); + + cvf::ref vertexArray = geomBuilder->vertices(); + cvf::ref indexArray = geomBuilder->triangles(); + + Vec3f origin(m_origin); + for (cvf::Vec3f& vx: *vertexArray) + { + vx *= 0.5*m_handleSize; + vx += origin; + } + + ref geo = createIndexedTriangelDrawableGeo(vertexArray.p(), indexArray.p()); + + HandleType handleId = VERTICAL_AXIS; + cvf::Color4f color = cvf::Color4f(0.0f, 0.2f, 0.8f, 0.5f); + cvf::String partName("PointTangentManipulator Vertical Axis Handle"); + + addHandlePart(geo.p(), color, handleId, partName); +} + +#if 0 +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::createAzimuthHandle() +{ + using namespace cvf; + + cvf::ref< cvf::GeometryBuilderTriangles> geomBuilder = new cvf::GeometryBuilderTriangles; + cvf::GeometryUtils::createDisc(1.3, 1.1, 16, geomBuilder.p()); + + cvf::ref vertexArray = geomBuilder->vertices(); + cvf::ref indexArray = geomBuilder->triangles(); + + Vec3f origin(m_origin); + for (cvf::Vec3f& vx: *vertexArray) + { + vx *= 0.5*m_handleSize; + vx += origin; + } + + ref geo = createIndexedTriangelDrawableGeo(vertexArray.p(), indexArray.p()); + + HandleType handleId = AZIMUTH; + cvf::Color4f color = cvf::Color4f(0.0f, 0.2f, 0.8f, 0.5f); + cvf::String partName("PointTangentManipulator Azimuth Handle"); + + addHandlePart(geo.p(), color, handleId, partName); +} + +#endif + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RicPointTangentManipulatorPartMgr::createIndexedTriangelDrawableGeo(cvf::Vec3fArray* triangleVertexArray, + cvf::UIntArray* triangleIndices) +{ + using namespace cvf; + ref geo = new DrawableGeo; + ref primSet = new PrimitiveSetIndexedUInt(PT_TRIANGLES, triangleIndices); + + geo->setVertexArray(triangleVertexArray); + geo->addPrimitiveSet(primSet.p()); + geo->computeNormals(); + + return geo; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RicPointTangentManipulatorPartMgr::createTriangelDrawableGeo(cvf::Vec3fArray* triangleVertexArray) +{ + using namespace cvf; + ref geo = new DrawableGeo; + + geo->setVertexArray(triangleVertexArray); + ref primSet = new cvf::PrimitiveSetDirect(cvf::PT_TRIANGLES); + primSet->setIndexCount(triangleVertexArray->size()); + + geo->addPrimitiveSet(primSet.p()); + geo->computeNormals(); + + return geo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::addHandlePart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + HandleType handleId, + const cvf::String& partName) +{ + cvf::ref handlePart = createPart(geo, color, partName); + + m_handleParts.push_back(handlePart.p()); + m_handleIds.push_back(handleId); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicPointTangentManipulatorPartMgr::addActiveModePart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + HandleType handleId, + const cvf::String& partName) +{ + cvf::ref handlePart = createPart(geo, color, partName); + + m_activeDragModeParts.push_back(handlePart.p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RicPointTangentManipulatorPartMgr::createPart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + const cvf::String& partName) +{ + cvf::ref part = new cvf::Part; + part->setName(partName); + part->setDrawable(geo); + part->updateBoundingBox(); + + caf::SurfaceEffectGenerator surfaceGen(color, caf::PO_1); + cvf::ref eff = surfaceGen.generateCachedEffect(); + part->setEffect(eff.p()); + if (color.a() < 1.0) part->setPriority(RivPartPriority::Transparent); + + return part; +} + +//================================================================================================== +/// +/// +/// +//================================================================================================== +namespace caf +{ +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUi3dObjectEditorHandle::PdmUi3dObjectEditorHandle() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUi3dObjectEditorHandle::~PdmUi3dObjectEditorHandle() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUi3dObjectEditorHandle::setViewer(caf::Viewer* ownerViewer) +{ + // Not allowed to change viewer. Should be constructor argument, but makes factory stuff difficult. + CAF_ASSERT(m_ownerViewer.isNull()); + m_ownerViewer = ownerViewer; +} +} + +//================================================================================================== +/// +/// +/// +//================================================================================================== + +#include "cafSelectionManager.h" +#include "RimWellPathGeometryDef.h" + +namespace caf +{ +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiSelectionVisualizer3d::PdmUiSelectionVisualizer3d(caf::Viewer* ownerViewer) + : m_ownerViewer(ownerViewer) +{ + this->setParent(ownerViewer); // Makes this owned by the viewer. +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiSelectionVisualizer3d::~PdmUiSelectionVisualizer3d() +{ + for (auto editor: m_active3DEditors) + { + delete editor; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiSelectionVisualizer3d::updateVisibleEditors() +{ + for (auto editor: m_active3DEditors) + { + if (editor) editor->updateUi(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiSelectionVisualizer3d::onSelectionManagerSelectionChanged( const std::set& changedSelectionLevels ) +{ + if (!changedSelectionLevels.count(0)) return; + + for (auto editor: m_active3DEditors) + { + delete editor; + } + + m_active3DEditors.clear(); + + if (!m_ownerViewer) return; + + // Todo: How do we deduce the editor from the selected object ? + // Alt 1: Register the rim object type name as key in the factory as well + // Alt 2: Set the editor type name as PdmUiItem::setUiEditorTypeName + // Alt 3: Use a specific config-name in alt 2. + // Alt 4: Introduce a PdmUiItem::editorTypeName3d + + std::vector wellPathGeomDefs; + caf::SelectionManager::instance()->objectsByType(&wellPathGeomDefs); + + for (auto geomDef: wellPathGeomDefs) + { + auto editor = new RicWellPathGeometry3dEditor(); + editor->setViewer(m_ownerViewer); + editor->setPdmObject(geomDef); + m_active3DEditors.push_back(editor); + editor->updateUi(); + } + m_ownerViewer->update(); +} + +} // caf + +//================================================================================================== +/// +/// +/// +//================================================================================================== + +#include "RimWellPathTarget.h" + +CAF_PDM_UI_3D_OBJECT_EDITOR_SOURCE_INIT(RicWellPathGeometry3dEditor); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicWellPathGeometry3dEditor::RicWellPathGeometry3dEditor() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicWellPathGeometry3dEditor::~RicWellPathGeometry3dEditor() +{ + for (auto targetEditor: m_targetEditors) + { + delete targetEditor; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellPathGeometry3dEditor::configureAndUpdateUi(const QString& uiConfigName) +{ + RimWellPathGeometryDef* geomDef = dynamic_cast(this->pdmObject()); + + for (auto targetEditor: m_targetEditors) + { + delete targetEditor; + } + m_targetEditors.clear(); + + if (!geomDef) return; + + + std::vector targets = geomDef->activeWellTargets(); + + for (auto target: targets) + { + auto targetEditor = new RicWellTarget3dEditor; + targetEditor->setViewer(m_ownerViewer); + targetEditor->setPdmObject(target); + m_targetEditors.push_back(targetEditor); + targetEditor->updateUi(); + } +} + +//================================================================================================== +/// +/// +/// +//================================================================================================== + + +#include "RimWellPathTarget.h" +#include "RiuViewer.h" +#include "cafDisplayCoordTransform.h" +#include "Rim3dView.h" +#include "RimCase.h" + +CAF_PDM_UI_3D_OBJECT_EDITOR_SOURCE_INIT(RicWellTarget3dEditor); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicWellTarget3dEditor::RicWellTarget3dEditor() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicWellTarget3dEditor::~RicWellTarget3dEditor() +{ + if (m_cvfModel.notNull() && m_ownerViewer) + { + // Could result in some circularities .... + m_ownerViewer->removeStaticModel(m_cvfModel.p()); + } + + RimWellPathTarget* oldTarget = dynamic_cast(this->pdmObject()); + if (oldTarget) + { + oldTarget->m_targetType.uiCapability()->removeFieldEditor(this); + oldTarget->m_targetPoint.uiCapability()->removeFieldEditor(this); + oldTarget->m_azimuth.uiCapability()->removeFieldEditor(this); + oldTarget->m_inclination.uiCapability()->removeFieldEditor(this); + } + + delete m_manipulator; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellTarget3dEditor::configureAndUpdateUi(const QString& uiConfigName) +{ + RimWellPathTarget* target = dynamic_cast(this->pdmObject()); + + if ( !target || !target->isEnabled()) + { + m_cvfModel->removeAllParts(); + return; + } + + RimWellPathGeometryDef* geomDef; + target->firstAncestorOrThisOfTypeAsserted(geomDef); + + target->m_targetType.uiCapability()->addFieldEditor(this); + target->m_targetPoint.uiCapability()->addFieldEditor(this); + target->m_azimuth.uiCapability()->addFieldEditor(this); + target->m_inclination.uiCapability()->addFieldEditor(this); + + if (m_manipulator.isNull()) + { + m_manipulator = new RicPointTangentManipulator(m_ownerViewer); + QObject::connect(m_manipulator, + SIGNAL( notifyUpdate(const cvf::Vec3d& , const cvf::Vec3d& ) ), + this, + SLOT( slotUpdated(const cvf::Vec3d& , const cvf::Vec3d& ) ) ); + QObject::connect(m_manipulator, + SIGNAL( notifySelected() ), + this, + SLOT( slotSelectedIn3D() ) ); + QObject::connect(m_manipulator, + SIGNAL( notifyDragFinished() ), + this, + SLOT( slotDragFinished() ) ); + m_cvfModel = new cvf::ModelBasicList; + m_ownerViewer->addStaticModelOnce(m_cvfModel.p()); + } + + cvf::ref dispXf; + double handleSize = 1.0; + { + RiuViewer* viewer = dynamic_cast(m_ownerViewer.data()); + dispXf = viewer->ownerReservoirView()->displayCoordTransform(); + Rim3dView* view = dynamic_cast(viewer->ownerReservoirView()); + handleSize = 0.7 * view->ownerCase()->characteristicCellSize(); + } + + m_manipulator->setOrigin(dispXf->transformToDisplayCoord( target->targetPointXYZ() + geomDef->referencePointXyz())); + m_manipulator->setTangent(target->tangent()); + m_manipulator->setHandleSize(handleSize); + m_cvfModel->removeAllParts(); + m_manipulator->appendPartsToModel(m_cvfModel.p()); + + m_cvfModel->updateBoundingBoxesRecursive(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellTarget3dEditor::cleanupBeforeSettingPdmObject() +{ + RimWellPathTarget* oldTarget = dynamic_cast(this->pdmObject()); + if (oldTarget) + { + oldTarget->m_targetType.uiCapability()->removeFieldEditor(this); + oldTarget->m_targetPoint.uiCapability()->removeFieldEditor(this); + oldTarget->m_azimuth.uiCapability()->removeFieldEditor(this); + oldTarget->m_inclination.uiCapability()->removeFieldEditor(this); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellTarget3dEditor::slotUpdated(const cvf::Vec3d& origin, const cvf::Vec3d& tangent) +{ + RimWellPathTarget* target = dynamic_cast(this->pdmObject()); + + if ( !target) + { + return; + } + + cvf::ref dispXf; + { + RiuViewer* viewer = dynamic_cast(m_ownerViewer.data()); + dispXf = viewer->ownerReservoirView()->displayCoordTransform(); + } + + RimWellPathGeometryDef* geomDef; + target->firstAncestorOrThisOfTypeAsserted(geomDef); + + cvf::Vec3d domainOrigin = dispXf->transformToDomainCoord( origin) - geomDef->referencePointXyz(); + domainOrigin.z() = -domainOrigin.z(); + QVariant originVariant = caf::PdmValueFieldSpecialization < cvf::Vec3d >::convert(domainOrigin); + + target->enableFullUpdate(false); + caf::PdmUiCommandSystemProxy::instance()->setUiValueToField(target->m_targetPoint.uiCapability(), originVariant); + target->enableFullUpdate(true); +} + +void RicWellTarget3dEditor::slotSelectedIn3D() +{ + RimWellPathTarget* target = dynamic_cast(this->pdmObject()); + if ( !target) + { + return; + } + + caf::SelectionManager::instance()->setSelectedItemAtLevel(target, caf::SelectionManager::FIRST_LEVEL); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicWellTarget3dEditor::slotDragFinished() +{ + RimWellPathTarget* target = dynamic_cast(this->pdmObject()); + if ( !target) + { + return; + } + + RimModeledWellPath* wellpath; + target->firstAncestorOrThisOfTypeAsserted(wellpath); + wellpath->scheduleUpdateOfDependentVisualization(); +} diff --git a/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.h b/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.h new file mode 100644 index 0000000000..0326cd7fcd --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.h @@ -0,0 +1,299 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cvfMatrix4.h" +#include "cvfVector3.h" + +#include +#include + +namespace cvf { + class Model; + class ModelBasicList; +}; + + +namespace caf { + class Viewer; +}; + +class QMouseEvent; + +class RicPointTangentManipulatorPartMgr; + +//================================================================================================== +// +// +//================================================================================================== +class RicPointTangentManipulator : public QObject +{ + Q_OBJECT + +public: + explicit RicPointTangentManipulator(caf::Viewer* viewer); + ~RicPointTangentManipulator() override; + + void setOrigin(const cvf::Vec3d& origin); + void setTangent(const cvf::Vec3d& tangent); + void setHandleSize(double handleSize); + + void appendPartsToModel(cvf::ModelBasicList* model); + +signals: + void notifySelected(); + void notifyDragFinished(); + void notifyUpdate(const cvf::Vec3d& origin, const cvf::Vec3d& tangent); + +protected: + bool eventFilter(QObject *obj, QEvent *event) override; + +private: + QPointer m_viewer; + + cvf::ref m_partManager; +}; + + +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" + +#include "cvfVector3.h" +#include "cvfCollection.h" +#include "cvfMatrix4.h" +#include "cvfString.h" +#include "cvfColor4.h" + +namespace cvf +{ +class ModelBasicList; +class Part; +class DrawableGeo; +class Ray; +class HitItem; + +template class Array; +typedef Array Vec3fArray; +typedef Array UIntArray; + +} + +class RicPointTangentManipulatorPartMgr : public cvf::Object +{ +public: + enum HandleType + { + HORIZONTAL_PLANE, + VERTICAL_AXIS, + AZIMUTH, + INCLINATION + }; + +public: + RicPointTangentManipulatorPartMgr(); + ~RicPointTangentManipulatorPartMgr() override; + + void setOrigin(const cvf::Vec3d& origin); + void setTangent(const cvf::Vec3d& tangent); + void setHandleSize(double handleSize); + void originAndTangent(cvf::Vec3d* origin, cvf::Vec3d* tangent); + + bool isManipulatorActive() const; + void tryToActivateManipulator(const cvf::HitItem* hitItem); + void updateManipulatorFromRay(const cvf::Ray* ray); + void endManipulator(); + + void appendPartsToModel(cvf::ModelBasicList* model); + +private: + void createAllHandleParts(); + void clearAllGeometryAndParts(); + void recreateAllGeometryAndParts(); + + void createHorizontalPlaneHandle(); + void createVerticalAxisHandle(); + + void addHandlePart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + HandleType handleId, + const cvf::String& partName); + + void addActiveModePart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + HandleType handleId, + const cvf::String& partName); + + static cvf::ref createTriangelDrawableGeo(cvf::Vec3fArray* triangleVertexArray); + static cvf::ref createIndexedTriangelDrawableGeo(cvf::Vec3fArray* triangleVertexArray, + cvf::UIntArray* triangleIndices); + static cvf::ref createPart(cvf::DrawableGeo* geo, + const cvf::Color4f& color, + const cvf::String& partName); +private: + size_t m_currentHandleIndex; + std::vector< HandleType > m_handleIds; // These arrays have the same length + cvf::Collection m_handleParts; // These arrays have the same length + cvf::Collection m_activeDragModeParts; + + cvf::Vec3d m_origin; + cvf::Vec3d m_tangent; + double m_handleSize; + + cvf::Vec3d m_initialPickPoint; + cvf::Vec3d m_tangentOnStartManipulation; + cvf::Vec3d m_originOnStartManipulation; + +}; + + +//================================================================================================== +/// +/// +/// +//================================================================================================== + + +#include "cafSelectionChangedReceiver.h" +#include "cafPdmUiObjectEditorHandle.h" +#include "cafFactory.h" +// PdmUiObjectEditorHandle -<| PdmUiWidgetObjectEditorHandle --<| PdmUiFormLayoutObjectEditor +// -<| PdmUi3dObjectEditorHandle +namespace caf +{ + +//================================================================================================== +/// Macros helping in development of PDM UI 3d editors +//================================================================================================== + +/// CAF_PDM_UI_3D_OBJECT_EDITOR_HEADER_INIT assists the factory used when creating editors +/// Place this in the header file inside the class definition of your PdmUiEditor + +#define CAF_PDM_UI_3D_OBJECT_EDITOR_HEADER_INIT \ +public: \ + static QString uiEditorTypeName() + +/// CAF_PDM_UI_3D_OBJECT_EDITOR_SOURCE_INIT implements editorTypeName() and registers the field editor in the field editor factory +/// Place this in the cpp file, preferably above the constructor + +#define CAF_PDM_UI_3D_OBJECT_EDITOR_SOURCE_INIT(EditorClassName) \ + QString EditorClassName::uiEditorTypeName() { return #EditorClassName; } \ + CAF_FACTORY_REGISTER(caf::PdmUi3dObjectEditorHandle, EditorClassName, QString, EditorClassName::uiEditorTypeName()) + + +class PdmUi3dObjectEditorHandle : public caf::PdmUiObjectEditorHandle +{ +public: + PdmUi3dObjectEditorHandle(); + ~PdmUi3dObjectEditorHandle() override; + + void setViewer(caf::Viewer* ownerViewer); + +protected: + // To be removed when splitting the PdmUiObjectEditorHandle + QWidget* createWidget(QWidget* parent) override { return nullptr;} + + QPointer m_ownerViewer; +}; + +//================================================================================================== +/// +/// +/// +//================================================================================================== + + +// Selected object 3D editor visualizer +class PdmUiSelectionVisualizer3d : public QObject, caf::SelectionChangedReceiver +{ + Q_OBJECT +public: + PdmUiSelectionVisualizer3d(caf::Viewer* ownerViewer); + ~PdmUiSelectionVisualizer3d() override; + + void updateVisibleEditors(); +protected: + void onSelectionManagerSelectionChanged( const std::set& changedSelectionLevels ) override; + + std::vector< QPointer > m_active3DEditors; + + QPointer m_ownerViewer; +}; + + +} + +//================================================================================================== +/// +/// +/// +//================================================================================================== + +class RicWellTarget3dEditor; + +class RicWellPathGeometry3dEditor : public caf::PdmUi3dObjectEditorHandle +{ + CAF_PDM_UI_3D_OBJECT_EDITOR_HEADER_INIT; + Q_OBJECT +public: + RicWellPathGeometry3dEditor(); + ~RicWellPathGeometry3dEditor() override; + +protected: + void configureAndUpdateUi(const QString& uiConfigName) override; + +private: + + std::vector m_targetEditors; +}; + +//================================================================================================== +/// +/// +/// +//================================================================================================== + + +class RicWellTarget3dEditor : public caf::PdmUi3dObjectEditorHandle +{ + CAF_PDM_UI_3D_OBJECT_EDITOR_HEADER_INIT; + Q_OBJECT +public: + RicWellTarget3dEditor(); + ~RicWellTarget3dEditor() override; + +protected: + void configureAndUpdateUi(const QString& uiConfigName) override; + void cleanupBeforeSettingPdmObject() override; + +private slots: + void slotUpdated(const cvf::Vec3d& origin, const cvf::Vec3d& tangent); + void slotSelectedIn3D(); + void slotDragFinished(); +private: + QPointer m_manipulator; + cvf::ref m_cvfModel; +}; + +class RiuViewer; + +// 3D editor manager diff --git a/ApplicationCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.cpp b/ApplicationCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.cpp new file mode 100644 index 0000000000..f901d5f825 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.cpp @@ -0,0 +1,198 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicCreateWellTargetsPickEventHandler.h" + +#include "RiaOffshoreSphericalCoords.h" + +#include "RigWellPath.h" + +#include "Rim3dView.h" +#include "RimModeledWellPath.h" +#include "RimWellPath.h" +#include "RimWellPathGeometryDef.h" +#include "RimWellPathTarget.h" + +#include "RiuViewerCommands.h" + +#include "RivWellPathSourceInfo.h" + +#include "cafDisplayCoordTransform.h" +#include "cafSelectionManager.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicCreateWellTargetsPickEventHandler::RicCreateWellTargetsPickEventHandler(RimWellPathGeometryDef* wellGeometryDef) + : m_geometryToAddTargetsTo(wellGeometryDef) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicCreateWellTargetsPickEventHandler::~RicCreateWellTargetsPickEventHandler() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicCreateWellTargetsPickEventHandler::notifyUnregistered() +{ + m_geometryToAddTargetsTo->enableTargetPointPicking(false); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateWellTargetsPickEventHandler::handlePickEvent(const Ric3DPickEvent& eventObject) +{ + if (!caf::SelectionManager::instance()->isSelected(m_geometryToAddTargetsTo.p(), 0)) + { + m_geometryToAddTargetsTo->enableTargetPointPicking(false); + + return false; + } + + if (m_geometryToAddTargetsTo) + { + Rim3dView* rimView = eventObject.m_view; + cvf::Vec3d targetPointInDomain = cvf::Vec3d::ZERO; + + // If clicked on an other well path, snap target point to well path center line + auto firstPickItem = eventObject.m_pickItemInfos.front(); + auto wellPathSourceInfo = dynamic_cast(firstPickItem.sourceInfo()); + + auto intersectionPointInDomain = + rimView->displayCoordTransform()->transformToDomainCoord(firstPickItem.globalPickedPoint()); + bool doSetAzimuthAndInclination = false; + double azimuth = 0.0; + double inclination = 0.0; + + if (wellPathSourceInfo) + { + targetPointInDomain = + wellPathSourceInfo->closestPointOnCenterLine(firstPickItem.faceIdx(), intersectionPointInDomain); + + double md = wellPathSourceInfo->measuredDepth(firstPickItem.faceIdx(), intersectionPointInDomain); + doSetAzimuthAndInclination = calculateAzimuthAndInclinationAtMd( + md, wellPathSourceInfo->wellPath()->wellPathGeometry(), &azimuth, &inclination); + } + else + { + targetPointInDomain = intersectionPointInDomain; + doSetAzimuthAndInclination = false; + } + + if (!m_geometryToAddTargetsTo->firstActiveTarget()) + { + m_geometryToAddTargetsTo->setReferencePointXyz(targetPointInDomain); + + if (wellPathSourceInfo) + { + double mdrkbAtFirstTarget = wellPathSourceInfo->measuredDepth(firstPickItem.faceIdx(), intersectionPointInDomain); + + RimModeledWellPath* modeledWellPath = dynamic_cast(wellPathSourceInfo->wellPath()); + if (modeledWellPath) + { + mdrkbAtFirstTarget += modeledWellPath->geometryDefinition()->mdrkbAtFirstTarget(); + } + + m_geometryToAddTargetsTo->setMdrkbAtFirstTarget(mdrkbAtFirstTarget); + } + } + + cvf::Vec3d referencePoint = m_geometryToAddTargetsTo->referencePointXyz(); + cvf::Vec3d relativeTagetPoint = targetPointInDomain - referencePoint; + + RimWellPathTarget* newTarget = new RimWellPathTarget; + + if (doSetAzimuthAndInclination) + { + newTarget->setAsPointXYZAndTangentTarget( + cvf::Vec3d(relativeTagetPoint.x(), relativeTagetPoint.y(), relativeTagetPoint.z()), azimuth, inclination); + } + else + { + newTarget->setAsPointTargetXYD(cvf::Vec3d(relativeTagetPoint.x(), relativeTagetPoint.y(), -relativeTagetPoint.z())); + } + + m_geometryToAddTargetsTo->insertTarget(nullptr, newTarget); + + m_geometryToAddTargetsTo->updateConnectedEditors(); + m_geometryToAddTargetsTo->updateWellPathVisualization(); + + return true; // Todo: See if we really should eat the event instead + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicCreateWellTargetsPickEventHandler::calculateAzimuthAndInclinationAtMd(double measuredDepth, + const RigWellPath* wellPathGeometry, + double* azimuth, + double* inclination) const +{ + int mdIndex = -1; + auto mdList = wellPathGeometry->measureDepths(); + + for (int i = 0; i < (int)mdList.size(); i++) + { + if (mdList[i] > measuredDepth) + { + mdIndex = i - 1; + break; + } + } + + auto ptList = wellPathGeometry->wellPathPoints(); + if (mdIndex > 0 && mdIndex < (int)ptList.size() - 2) + { + auto v1 = cvf::Vec3d(ptList[mdIndex - 1]); + auto v2 = cvf::Vec3d(ptList[mdIndex]); + auto v3 = cvf::Vec3d(ptList[mdIndex + 1]); + auto v4 = cvf::Vec3d(ptList[mdIndex + 2]); + + auto v21 = v2 - v1; + auto v32 = v3 - v2; + auto v43 = v4 - v3; + + v21.normalize(); + v32.normalize(); + v43.normalize(); + + auto v13mean = (v21 + v32) / 2; + auto v24mean = (v32 + v43) / 2; + + double weight = (measuredDepth - mdList[mdIndex]) / (mdList[mdIndex + 1] - mdList[mdIndex]); + auto vTan = v13mean * weight + v24mean * (1 - weight); + + RiaOffshoreSphericalCoords coords(vTan); + *azimuth = coords.azi(); + *inclination = coords.inc(); + return true; + } + + *azimuth = 0.0; + *inclination = 0.0; + return false; +} diff --git a/ApplicationCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.h b/ApplicationCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.h new file mode 100644 index 0000000000..3e3ebf60de --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicCreateWellTargetsPickEventHandler.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RicPickEventHandler.h" + +#include "cafPdmPointer.h" + +class RimWellPathGeometryDef; +class RigWellPath; + +//================================================================================================== +/// +//================================================================================================== +class RicCreateWellTargetsPickEventHandler : public RicPickEventHandler +{ +public: + RicCreateWellTargetsPickEventHandler(RimWellPathGeometryDef* wellGeometryDef); + ~RicCreateWellTargetsPickEventHandler(); + +protected: + bool handlePickEvent(const Ric3DPickEvent& eventObject) override; + void notifyUnregistered() override; + +private: + bool calculateAzimuthAndInclinationAtMd(double measuredDepth, + const RigWellPath* wellPathGeometry, + double* azimuth, + double* inclination) const; + +private: + caf::PdmPointer m_geometryToAddTargetsTo; +}; diff --git a/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathAttributeFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathAttributeFeature.cpp new file mode 100644 index 0000000000..e702e53271 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathAttributeFeature.cpp @@ -0,0 +1,118 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RicDeleteWellPathAttributeFeature.h" + +#include "RimProject.h" +#include "RimWellPath.h" +#include "RimWellPathAttribute.h" +#include "RimWellPathAttributeCollection.h" +#include "Riu3DMainWindowTools.h" + +#include "cafSelectionManager.h" +#include + +CAF_CMD_SOURCE_INIT(RicDeleteWellPathAttributeFeature, "RicDeleteWellPathAttributeFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicDeleteWellPathAttributeFeature::isCommandEnabled() +{ + { + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects, caf::SelectionManager::FIRST_LEVEL); + + if ( objects.size() > 0 ) + { + return true; + } + } + { + if (caf::SelectionManager::instance()->selectedItemOfType()) + { + return true; + } + + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteWellPathAttributeFeature::onActionTriggered(bool isChecked) +{ + std::vector attributes; + caf::SelectionManager::instance()->objectsByType(&attributes, caf::SelectionManager::FIRST_LEVEL); + RimWellPathAttributeCollection* wellPathAttributeCollection = nullptr; + if (attributes.size() > 0) + { + attributes[0]->firstAncestorOrThisOfTypeAsserted(wellPathAttributeCollection); + for (RimWellPathAttribute* attributeToDelete : attributes) + { + wellPathAttributeCollection->deleteAttribute(attributeToDelete); + } + wellPathAttributeCollection->updateAllRequiredEditors(); + } + else + { + wellPathAttributeCollection = caf::SelectionManager::instance()->selectedItemOfType(); + if (wellPathAttributeCollection) + { + wellPathAttributeCollection->deleteAllAttributes(); + } + } + + if (wellPathAttributeCollection) + { + if (wellPathAttributeCollection->attributes().empty()) + { + RimWellPath* wellPath = nullptr; + wellPathAttributeCollection->firstAncestorOrThisOfTypeAsserted(wellPath); + wellPath->updateConnectedEditors(); + Riu3DMainWindowTools::selectAsCurrentItem(wellPath); + } + + RimProject* proj = nullptr; + wellPathAttributeCollection->firstAncestorOrThisOfType(proj); + if (proj) + { + proj->scheduleCreateDisplayModelAndRedrawAllViews(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteWellPathAttributeFeature::setupActionLook(QAction* actionToSetup) +{ + std::vector attributes; + caf::SelectionManager::instance()->objectsByType(&attributes, caf::SelectionManager::FIRST_LEVEL); + if (attributes.size() > 0) + { + actionToSetup->setText("Delete Attribute"); + actionToSetup->setIcon(QIcon(":/Erase.png")); + } + else if (caf::SelectionManager::instance()->selectedItemOfType()) + { + actionToSetup->setText("Delete Casing Design"); + actionToSetup->setIcon(QIcon(":/Erase.png")); + } +} diff --git a/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathAttributeFeature.h b/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathAttributeFeature.h new file mode 100644 index 0000000000..5627d9af99 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathAttributeFeature.h @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicDeleteWellPathAttributeFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; diff --git a/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathTargetFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathTargetFeature.cpp new file mode 100644 index 0000000000..747846eeb3 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathTargetFeature.cpp @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RicDeleteWellPathTargetFeature.h" + +CAF_CMD_SOURCE_INIT(RicDeleteWellPathTargetFeature, "RicDeleteWellPathTargetFeature"); + +#include "RimWellPathGeometryDef.h" +#include "RimWellPathTarget.h" +#include "RimModeledWellPath.h" +#include "cafSelectionManager.h" +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicDeleteWellPathTargetFeature::isCommandEnabled() +{ + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects, caf::SelectionManager::FIRST_LEVEL); + + if ( objects.size() > 0 ) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteWellPathTargetFeature::onActionTriggered(bool isChecked) +{ + std::vector targets; + caf::SelectionManager::instance()->objectsByType(&targets, caf::SelectionManager::FIRST_LEVEL); + + if (targets.size() > 0) + { + + RimWellPathGeometryDef* wellGeomDef = nullptr; + targets[0]->firstAncestorOrThisOfTypeAsserted(wellGeomDef); + + for ( auto target: targets ) + { + wellGeomDef->deleteTarget(target); + } + + wellGeomDef->updateConnectedEditors(); + wellGeomDef->updateWellPathVisualization(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicDeleteWellPathTargetFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Delete Target"); + actionToSetup->setIcon(QIcon(":/Erase.png")); +} + + diff --git a/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathTargetFeature.h b/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathTargetFeature.h new file mode 100644 index 0000000000..6f47905070 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicDeleteWellPathTargetFeature.h @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicDeleteWellPathTargetFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; diff --git a/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.cpp b/ApplicationCode/Commands/WellPathCommands/RicIntersectionPickEventHandler.cpp similarity index 88% rename from ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.cpp rename to ApplicationCode/Commands/WellPathCommands/RicIntersectionPickEventHandler.cpp index 4c75202084..cb8f2dfe05 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.cpp +++ b/ApplicationCode/Commands/WellPathCommands/RicIntersectionPickEventHandler.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RicIntersectionViewerEventHandler.h" +#include "RicIntersectionPickEventHandler.h" #include "RimIntersection.h" #include "Rim3dView.h" @@ -28,16 +28,16 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicIntersectionViewerEventHandler* RicIntersectionViewerEventHandler::instance() +RicIntersectionPickEventHandler* RicIntersectionPickEventHandler::instance() { - static RicIntersectionViewerEventHandler* singleton = new RicIntersectionViewerEventHandler; + static RicIntersectionPickEventHandler* singleton = new RicIntersectionPickEventHandler; return singleton; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RicIntersectionViewerEventHandler::handleEvent(const RicViewerEventObject& eventObject) +bool RicIntersectionPickEventHandler::handlePickEvent(const Ric3DPickEvent& eventObject) { std::vector selection; caf::SelectionManager::instance()->objectsByType(&selection); @@ -52,7 +52,7 @@ bool RicIntersectionViewerEventHandler::handleEvent(const RicViewerEventObject& CVF_ASSERT(rimView); cvf::ref transForm = rimView->displayCoordTransform(); - cvf::Vec3d domainCoord = transForm->transformToDomainCoord(eventObject.m_globalIntersectionPoint); + cvf::Vec3d domainCoord = transForm->transformToDomainCoord(eventObject.m_pickItemInfos.front().globalPickedPoint()); if (intersection->inputPolyLineFromViewerEnabled()) { diff --git a/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.h b/ApplicationCode/Commands/WellPathCommands/RicIntersectionPickEventHandler.h similarity index 80% rename from ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.h rename to ApplicationCode/Commands/WellPathCommands/RicIntersectionPickEventHandler.h index 721d61b169..1881ebafa8 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicIntersectionViewerEventHandler.h +++ b/ApplicationCode/Commands/WellPathCommands/RicIntersectionPickEventHandler.h @@ -18,17 +18,17 @@ #pragma once -#include "RicViewerEventInterface.h" +#include "RicPickEventHandler.h" //================================================================================================== /// //================================================================================================== -class RicIntersectionViewerEventHandler : public RicViewerEventInterface +class RicIntersectionPickEventHandler : public RicDefaultPickEventHandler { public: - static RicIntersectionViewerEventHandler* instance(); + static RicIntersectionPickEventHandler* instance(); protected: - virtual bool handleEvent(const RicViewerEventObject& eventObject) override; + bool handlePickEvent(const Ric3DPickEvent& eventObject) override; }; diff --git a/ApplicationCode/Commands/WellPathCommands/RicNewEditableWellPathFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicNewEditableWellPathFeature.cpp new file mode 100644 index 0000000000..28d3831917 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicNewEditableWellPathFeature.cpp @@ -0,0 +1,105 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RicNewEditableWellPathFeature.h" + +CAF_CMD_SOURCE_INIT(RicNewEditableWellPathFeature, "RicNewEditableWellPathFeature"); + +#include "cafSelectionManager.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" +#include "RiaApplication.h" +#include "RimProject.h" +#include "RimModeledWellPath.h" +#include +#include "RimOilField.h" +#include "Riu3DMainWindowTools.h" +#include "RimWellPathGeometryDef.h" +#include "RiaColorTables.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewEditableWellPathFeature::isCommandEnabled() +{ + { + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects); + + if ( objects.size() > 0 ) + { + return true; + } + } + { + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects); + + if ( objects.size() > 0 ) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewEditableWellPathFeature::onActionTriggered(bool isChecked) +{ + RimProject* project = RiaApplication::instance()->project(); + if (project && RiaApplication::instance()->project()->activeOilField() ) + { + RimWellPathCollection* wellPathCollection = RiaApplication::instance()->project()->activeOilField()->wellPathCollection(); + + if ( wellPathCollection ) + { + std::vector newWellPaths; + auto newModeledWellPath = new RimModeledWellPath(); + newWellPaths.push_back(newModeledWellPath); + + newModeledWellPath->setUnitSystem(project->commonUnitSystemForAllCases()); + + size_t modelledWellpathCount = wellPathCollection->modelledWellPathCount(); + + newWellPaths.back()->setName("UWell-" + QString::number(modelledWellpathCount+1)); + newModeledWellPath->setWellPathColor(RiaColorTables::editableWellPathsPaletteColors().cycledColor3f(modelledWellpathCount)); + + wellPathCollection->addWellPaths(newWellPaths); + wellPathCollection->uiCapability()->updateConnectedEditors(); + + newModeledWellPath->geometryDefinition()->enableTargetPointPicking(true); + + project->scheduleCreateDisplayModelAndRedrawAllViews(); + + Riu3DMainWindowTools::selectAsCurrentItem(newModeledWellPath->geometryDefinition()); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewEditableWellPathFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Create Well Path"); + actionToSetup->setIcon(QIcon(":/Well.png")); +} + + diff --git a/ApplicationCode/Commands/WellPathCommands/RicNewEditableWellPathFeature.h b/ApplicationCode/Commands/WellPathCommands/RicNewEditableWellPathFeature.h new file mode 100644 index 0000000000..df7ac9a613 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicNewEditableWellPathFeature.h @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicNewEditableWellPathFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; diff --git a/ApplicationCode/Commands/WellPathCommands/RicNewWellPathAttributeFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicNewWellPathAttributeFeature.cpp new file mode 100644 index 0000000000..5613dfa1c3 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicNewWellPathAttributeFeature.cpp @@ -0,0 +1,123 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RicNewWellPathAttributeFeature.h" + +#include "RimProject.h" +#include "RimWellPath.h" +#include "RimWellPathAttribute.h" +#include "RimWellPathAttributeCollection.h" +#include "Riu3DMainWindowTools.h" + +#include "cafSelectionManager.h" + +#include + +CAF_CMD_SOURCE_INIT(RicNewWellPathAttributeFeature, "RicNewWellPathAttributeFeature"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewWellPathAttributeFeature::isCommandEnabled() +{ + { + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects, caf::SelectionManager::FIRST_LEVEL); + + if (objects.size() > 0) + { + return true; + } + } + + { + if (caf::SelectionManager::instance()->selectedItemAncestorOfType()) + { + return true; + } + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellPathAttributeFeature::onActionTriggered(bool isChecked) +{ + std::vector attributes; + caf::SelectionManager::instance()->objectsByType(&attributes, caf::SelectionManager::FIRST_LEVEL); + if (attributes.size() == 1u) + { + RimWellPathAttributeCollection* attributeCollection = nullptr; + attributes[0]->firstAncestorOrThisOfTypeAsserted(attributeCollection); + + RimWellPathAttribute* attribute = new RimWellPathAttribute; + RimWellPath* wellPath = nullptr; + attributeCollection->firstAncestorOrThisOfTypeAsserted(wellPath); + + attribute->setDepthsFromWellPath(wellPath); + attributeCollection->insertAttribute(attributes[0], attribute); + + attributeCollection->updateAllRequiredEditors(); + return; + } + + RimWellPath* wellPath = caf::SelectionManager::instance()->selectedItemAncestorOfType(); + if (wellPath) + { + std::vector attributeCollections; + wellPath->descendantsIncludingThisOfType(attributeCollections); + if (!attributeCollections.empty()) + { + RimWellPathAttribute* attribute = new RimWellPathAttribute; + attribute->setDepthsFromWellPath(wellPath); + + attributeCollections[0]->insertAttribute(nullptr, attribute); + attributeCollections[0]->updateAllRequiredEditors(); + + wellPath->updateConnectedEditors(); + Riu3DMainWindowTools::selectAsCurrentItem(attributeCollections[0]); + + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellPathAttributeFeature::setupActionLook(QAction* actionToSetup) +{ + std::vector attributes; + caf::SelectionManager::instance()->objectsByType(&attributes, caf::SelectionManager::FIRST_LEVEL); + if (attributes.size() == 1u) + { + actionToSetup->setText(QString("Insert New Attribute before %1").arg(attributes[0]->componentTypeLabel())); + actionToSetup->setIcon(QIcon(":/CasingDesign16x16.png")); + } + else if (caf::SelectionManager::instance()->selectedItemOfType()) + { + actionToSetup->setText("Append New Attribute"); + actionToSetup->setIcon(QIcon(":/CasingDesign16x16.png")); + } + else if(caf::SelectionManager::instance()->selectedItemOfType()) + { + actionToSetup->setText("Create Casing Design"); + actionToSetup->setIcon(QIcon(":/CasingDesign16x16.png")); + } +} + + diff --git a/ApplicationCode/Commands/WellPathCommands/RicNewWellPathAttributeFeature.h b/ApplicationCode/Commands/WellPathCommands/RicNewWellPathAttributeFeature.h new file mode 100644 index 0000000000..956819d63e --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicNewWellPathAttributeFeature.h @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicNewWellPathAttributeFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; diff --git a/ApplicationCode/Commands/WellPathCommands/RicNewWellPathListTargetFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicNewWellPathListTargetFeature.cpp new file mode 100644 index 0000000000..9a431197e0 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicNewWellPathListTargetFeature.cpp @@ -0,0 +1,154 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RicNewWellPathListTargetFeature.h" + +CAF_CMD_SOURCE_INIT(RicNewWellPathListTargetFeature, "RicNewWellPathListTargetFeature"); + +#include "RimWellPathGeometryDef.h" +#include "RimWellPathTarget.h" +#include "RimModeledWellPath.h" +#include "cafSelectionManager.h" +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RicNewWellPathListTargetFeature::isCommandEnabled() +{ + { + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects); + + if ( objects.size() > 0 ) + { + return true; + } + } + { + std::vector objects; + caf::SelectionManager::instance()->objectsByType(&objects, caf::SelectionManager::FIRST_LEVEL); + + if ( objects.size() > 0 ) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellPathListTargetFeature::onActionTriggered(bool isChecked) +{ + std::vector selectedTargets; + caf::SelectionManager::instance()->objectsByType(&selectedTargets, caf::SelectionManager::FIRST_LEVEL); + if (selectedTargets.size() > 0) + { + auto firstTarget = selectedTargets.front(); + RimWellPathGeometryDef* wellGeomDef = nullptr; + firstTarget->firstAncestorOrThisOfTypeAsserted(wellGeomDef); + + auto afterBeforePair = wellGeomDef->findActiveTargetsAroundInsertionPoint(firstTarget); + + cvf::Vec3d newPos = cvf::Vec3d::ZERO; + + if (!afterBeforePair.first && afterBeforePair.second) + { + newPos = afterBeforePair.second->targetPointXYZ(); + newPos.z() = -wellGeomDef->referencePointXyz().z(); + } + else if (afterBeforePair.first && afterBeforePair.second) + { + newPos = 0.5*(afterBeforePair.first->targetPointXYZ() + afterBeforePair.second->targetPointXYZ()); + } + else if (afterBeforePair.first && !afterBeforePair.second) + { + std::vector activeTargets = wellGeomDef->activeWellTargets(); + size_t targetCount = activeTargets.size(); + if (targetCount > 1) + { + newPos = activeTargets[targetCount-1]->targetPointXYZ(); + cvf::Vec3d nextLastToLast = newPos - activeTargets[targetCount-2]->targetPointXYZ(); + newPos += 0.5*nextLastToLast; + } + else + { + newPos = afterBeforePair.first->targetPointXYZ() + cvf::Vec3d(0, 0, 200); + } + } + + RimWellPathTarget* newTarget = new RimWellPathTarget; + newTarget->setAsPointTargetXYD({ newPos[0], newPos[1], -newPos[2] }); + + wellGeomDef->insertTarget(firstTarget, newTarget); + wellGeomDef->updateConnectedEditors(); + wellGeomDef->updateWellPathVisualization(); + + return; + } + + std::vector geomDefs; + caf::SelectionManager::instance()->objectsByType(&geomDefs); + if (geomDefs.size() > 0) + { + RimWellPathGeometryDef* wellGeomDef = geomDefs[0]; + std::vector activeTargets = wellGeomDef->activeWellTargets(); + + size_t targetCount = activeTargets.size(); + + if ( targetCount == 0 ) + { + wellGeomDef->appendTarget(); + } + else + { + cvf::Vec3d newPos = cvf::Vec3d::ZERO; + + if ( targetCount > 1 ) + { + newPos = activeTargets[targetCount-1]->targetPointXYZ(); + cvf::Vec3d nextLastToLast = newPos - activeTargets[targetCount-2]->targetPointXYZ(); + newPos += 0.5*nextLastToLast; + } + else if ( targetCount > 0 ) + { + newPos = activeTargets[targetCount-1]->targetPointXYZ() + cvf::Vec3d(0, 0, 200); + } + + RimWellPathTarget* newTarget = new RimWellPathTarget; + newTarget->setAsPointTargetXYD({ newPos[0], newPos[1], -newPos[2] }); + wellGeomDef->insertTarget(nullptr, newTarget); + } + + wellGeomDef->updateConnectedEditors(); + wellGeomDef->updateWellPathVisualization(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellPathListTargetFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("New Target"); + actionToSetup->setIcon(QIcon(":/Well.png")); +} + + diff --git a/ApplicationCode/Commands/WellPathCommands/RicNewWellPathListTargetFeature.h b/ApplicationCode/Commands/WellPathCommands/RicNewWellPathListTargetFeature.h new file mode 100644 index 0000000000..e52f65220e --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicNewWellPathListTargetFeature.h @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicNewWellPathListTargetFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; +protected: + + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; diff --git a/ApplicationCode/Commands/WellPathCommands/RicShowWellPlanFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicShowWellPlanFeature.cpp new file mode 100644 index 0000000000..b1551e135c --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicShowWellPlanFeature.cpp @@ -0,0 +1,84 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RicShowWellPlanFeature.h" +#include "RimModeledWellPath.h" +#include "../ApplicationCommands/RicShowPlotDataFeature.h" + +#include "cafSelectionManagerTools.h" + +#include +#include "RiuTextDialog.h" + + +CAF_CMD_SOURCE_INIT(RicShowWellPlanFeature, "RicShowWellPlanFeature"); + + +//-------------------------------------------------------------------------------------------------- +/// +/// +/// RicShowPlotDataFeature +/// +/// +//-------------------------------------------------------------------------------------------------- +bool RicShowWellPlanFeature::isCommandEnabled() +{ + auto selectedWellPaths = caf::selectedObjectsByType(); + if (selectedWellPaths.size() > 0) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicShowWellPlanFeature::onActionTriggered(bool isChecked) +{ + this->disableModelChangeContribution(); + + std::vector selectedWellPaths = caf::selectedObjectsByType(); + + if (selectedWellPaths.size() == 0 ) + { + return; + } + + for (auto wellPath : selectedWellPaths) + { + QString title = "Well Plan for " + wellPath->name(); + + RiuTextDialog* textDialog = new RiuTextDialog(); + textDialog->setMinimumSize(800, 600); + textDialog->setWindowTitle(title); + textDialog->setText(wellPath->wellPlanText()); + textDialog->show(); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicShowWellPlanFeature::setupActionLook(QAction* actionToSetup) +{ + actionToSetup->setText("Show Well Plan"); + actionToSetup->setIcon(QIcon(":/PlotWindow24x24.png")); +} diff --git a/ApplicationCode/Commands/WellPathCommands/RicShowWellPlanFeature.h b/ApplicationCode/Commands/WellPathCommands/RicShowWellPlanFeature.h new file mode 100644 index 0000000000..b5973e4ca1 --- /dev/null +++ b/ApplicationCode/Commands/WellPathCommands/RicShowWellPlanFeature.h @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafCmdFeature.h" + +//================================================================================================== +/// +//================================================================================================== +class RicShowWellPlanFeature : public caf::CmdFeature +{ + CAF_CMD_HEADER_INIT; + +protected: + // Overrides + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; +}; + + diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathDeleteFeature.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathDeleteFeature.h index 6f8e0bc97b..364c067e56 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathDeleteFeature.h +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathDeleteFeature.h @@ -30,7 +30,7 @@ class RicWellPathDeleteFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathFormationsImportFileFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicWellPathFormationsImportFileFeature.cpp index 68225e2276..874aeb52f9 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathFormationsImportFileFeature.cpp +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathFormationsImportFileFeature.cpp @@ -65,7 +65,7 @@ void RicWellPathFormationsImportFileFeature::onActionTriggered(bool isChecked) if (project) { - project->createDisplayModelAndRedrawAllViews(); + project->scheduleCreateDisplayModelAndRedrawAllViews(); if (project->mainPlotCollection()) { project->mainPlotCollection->updatePlotsWithFormations(); diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathFormationsImportFileFeature.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathFormationsImportFileFeature.h index 55d3be06bb..78eb1b2969 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathFormationsImportFileFeature.h +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathFormationsImportFileFeature.h @@ -27,7 +27,7 @@ class RicWellPathFormationsImportFileFeature : public caf::CmdFeature { CAF_CMD_HEADER_INIT; protected: - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.cpp b/ApplicationCode/Commands/WellPathCommands/RicWellPathPickEventHandler.cpp similarity index 62% rename from ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.cpp rename to ApplicationCode/Commands/WellPathCommands/RicWellPathPickEventHandler.cpp index a1646279af..3dd08505e5 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.cpp +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathPickEventHandler.cpp @@ -17,7 +17,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RicWellPathViewerEventHandler.h" +#include "RicWellPathPickEventHandler.h" #include "RiaApplication.h" @@ -41,62 +41,67 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RicWellPathViewerEventHandler* RicWellPathViewerEventHandler::instance() +RicWellPathPickEventHandler* RicWellPathPickEventHandler::instance() { - static RicWellPathViewerEventHandler* singleton = new RicWellPathViewerEventHandler; + static RicWellPathPickEventHandler* singleton = new RicWellPathPickEventHandler; return singleton; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RicWellPathViewerEventHandler::handleEvent(const RicViewerEventObject& eventObject) +bool RicWellPathPickEventHandler::handlePickEvent(const Ric3DPickEvent& eventObject) { - if (eventObject.m_partAndTriangleIndexPairs.empty()) return false; + if (eventObject.m_pickItemInfos.empty()) return false; const caf::PdmObject* objectToSelect = nullptr; cvf::uint wellPathTriangleIndex = cvf::UNDEFINED_UINT; const RivWellPathSourceInfo* wellPathSourceInfo = nullptr; - if(!eventObject.m_partAndTriangleIndexPairs.empty()) + if(!eventObject.m_pickItemInfos.empty()) { - const auto & partAndTriangleIndexPair = eventObject.m_partAndTriangleIndexPairs.front(); - const cvf::Part* part = partAndTriangleIndexPair.first; - - const RivObjectSourceInfo* sourceInfo = dynamic_cast(part->sourceInfo()); - if (sourceInfo) + const auto & firstPickedItem = eventObject.m_pickItemInfos.front(); + const cvf::Part* firstPickedPart = firstPickedItem.pickedPart(); + + if (firstPickedPart) { - if (dynamic_cast(sourceInfo->object())) + const RivObjectSourceInfo* sourceInfo = dynamic_cast(firstPickedPart->sourceInfo()); + if (sourceInfo) { - objectToSelect = sourceInfo->object(); - - if (eventObject.m_partAndTriangleIndexPairs.size() > 1) + if (dynamic_cast(sourceInfo->object())) { - const auto& secondPair = eventObject.m_partAndTriangleIndexPairs[1]; - const cvf::Part* secondPickedPart = secondPair.first; - if (secondPickedPart) + objectToSelect = sourceInfo->object(); + + if (eventObject.m_pickItemInfos.size() > 1) { - auto wellPathSourceCandidate = dynamic_cast(secondPickedPart->sourceInfo()); - if (wellPathSourceCandidate) + const auto& secondPickedItem = eventObject.m_pickItemInfos[1]; + const cvf::Part* secondPickedPart = secondPickedItem.pickedPart(); + if (secondPickedPart) { - RimWellPath* perforationWellPath = nullptr; - objectToSelect->firstAncestorOrThisOfType(perforationWellPath); - if (perforationWellPath == wellPathSourceCandidate->wellPath()) + auto wellPathSourceCandidate = + dynamic_cast(secondPickedPart->sourceInfo()); + if (wellPathSourceCandidate) { - wellPathSourceInfo = dynamic_cast(secondPickedPart->sourceInfo()); - wellPathTriangleIndex = secondPair.second; + RimWellPath* perforationWellPath = nullptr; + objectToSelect->firstAncestorOrThisOfType(perforationWellPath); + if (perforationWellPath == wellPathSourceCandidate->wellPath()) + { + wellPathSourceInfo = + dynamic_cast(secondPickedPart->sourceInfo()); + wellPathTriangleIndex = secondPickedItem.faceIdx(); + } } } } } } - } - if (part && dynamic_cast(part->sourceInfo())) - { - wellPathSourceInfo = dynamic_cast(part->sourceInfo()); - wellPathTriangleIndex = partAndTriangleIndexPair.second; + if (dynamic_cast(firstPickedPart->sourceInfo())) + { + wellPathSourceInfo = dynamic_cast(firstPickedPart->sourceInfo()); + wellPathTriangleIndex = firstPickedItem.faceIdx(); + } } } @@ -106,7 +111,7 @@ bool RicWellPathViewerEventHandler::handleEvent(const RicViewerEventObject& even if (!rimView) return false; cvf::ref transForm = rimView->displayCoordTransform(); - cvf::Vec3d pickedPositionInUTM = transForm->transformToDomainCoord(eventObject.m_globalIntersectionPoint); + cvf::Vec3d pickedPositionInUTM = transForm->transformToDomainCoord(eventObject.m_pickItemInfos.front().globalPickedPoint()); if (auto intersectionView = dynamic_cast(rimView)) { diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathPickEventHandler.h similarity index 82% rename from ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.h rename to ApplicationCode/Commands/WellPathCommands/RicWellPathPickEventHandler.h index a60d598229..905aaf355d 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathViewerEventHandler.h +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathPickEventHandler.h @@ -19,17 +19,17 @@ #pragma once -#include "RicViewerEventInterface.h" +#include "RicPickEventHandler.h" //================================================================================================== /// //================================================================================================== -class RicWellPathViewerEventHandler : public RicViewerEventInterface +class RicWellPathPickEventHandler : public RicDefaultPickEventHandler { public: - static RicWellPathViewerEventHandler* instance(); + static RicWellPathPickEventHandler* instance(); - bool handleEvent(const RicViewerEventObject& eventObject) override; + bool handlePickEvent(const Ric3DPickEvent& eventObject) override; }; diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.cpp index b3a19f0721..0538139de2 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.cpp +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.cpp @@ -49,7 +49,8 @@ void RicWellPathsImportFileFeature::onActionTriggered(bool isChecked) { // Open dialog box to select well path files RiaApplication* app = RiaApplication::instance(); - QString defaultDir = app->lastUsedDialogDirectory("WELLPATH_DIR"); + QString lastUsedGridFolder = app->lastUsedDialogDirectory("BINARY_GRID"); + QString defaultDir = app->lastUsedDialogDirectoryWithFallback("WELLPATH_DIR", lastUsedGridFolder); QStringList wellPathFilePaths = QFileDialog::getOpenFileNames(Riu3DMainWindowTools::mainWindowWidget(), "Import Well Paths", defaultDir, "Well Paths (*.json *.asc *.asci *.ascii *.dev);;All Files (*.*)"); if (wellPathFilePaths.size() < 1) return; @@ -63,7 +64,7 @@ void RicWellPathsImportFileFeature::onActionTriggered(bool isChecked) if (project) { - project->createDisplayModelAndRedrawAllViews(); + project->scheduleCreateDisplayModelAndRedrawAllViews(); RimOilField* oilField = project->activeOilField(); if (!oilField) return; diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.h index 08d3650e0d..0c5a43f225 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.h +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportFileFeature.h @@ -30,7 +30,7 @@ class RicWellPathsImportFileFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.cpp b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.cpp index 88a4e99bf3..fe26085444 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.cpp +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.cpp @@ -100,7 +100,7 @@ void RicWellPathsImportSsihubFeature::onActionTriggered(bool isChecked) if (wellPaths.size() > 0) { app->addWellPathsToModel(wellPaths); - app->project()->createDisplayModelAndRedrawAllViews(); + app->project()->scheduleCreateDisplayModelAndRedrawAllViews(); } app->setCacheDataObject("ssihub_username", wellImportwizard.field("username")); diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.h index ae107e2571..cc79cb6bff 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.h +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsImportSsihubFeature.h @@ -30,7 +30,7 @@ class RicWellPathsImportSsihubFeature : public caf::CmdFeature protected: // Overrides - virtual bool isCommandEnabled() override; - virtual void onActionTriggered( bool isChecked ) override; - virtual void setupActionLook( QAction* actionToSetup ) override; + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/ApplicationCode/Commands/WellPathCommands/RicWellPathsUnitSystemSettingsUi.h b/ApplicationCode/Commands/WellPathCommands/RicWellPathsUnitSystemSettingsUi.h index 0f66801142..ebfb624a28 100644 --- a/ApplicationCode/Commands/WellPathCommands/RicWellPathsUnitSystemSettingsUi.h +++ b/ApplicationCode/Commands/WellPathCommands/RicWellPathsUnitSystemSettingsUi.h @@ -37,5 +37,5 @@ class RicWellPathsUnitSystemSettingsUi : public caf::PdmObject caf::PdmField unitSystem; protected: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; }; diff --git a/ApplicationCode/FileInterface/CMakeLists_files.cmake b/ApplicationCode/FileInterface/CMakeLists_files.cmake index 99a41a6bbe..c2a01d4dce 100644 --- a/ApplicationCode/FileInterface/CMakeLists_files.cmake +++ b/ApplicationCode/FileInterface/CMakeLists_files.cmake @@ -39,9 +39,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RifElementPropertyTableReader.h ${CMAKE_CURRENT_LIST_DIR}/RifElementPropertyReader.h ${CMAKE_CURRENT_LIST_DIR}/RifStimPlanXmlReader.h ${CMAKE_CURRENT_LIST_DIR}/RifSummaryCaseRestartSelector.h -${CMAKE_CURRENT_LIST_DIR}/RifEnsembleParametersReader.h ${CMAKE_CURRENT_LIST_DIR}/RifCaseRealizationParametersReader.h ${CMAKE_CURRENT_LIST_DIR}/RifFileParseTools.h +${CMAKE_CURRENT_LIST_DIR}/RifEnsembleStatisticsReader.h +${CMAKE_CURRENT_LIST_DIR}/RifDerivedEnsembleReader.h # HDF5 file reader is directly included in ResInsight main CmakeList.txt #${CMAKE_CURRENT_LIST_DIR}/RifHdf5Reader.h @@ -85,9 +86,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RifElementPropertyTableReader.cpp ${CMAKE_CURRENT_LIST_DIR}/RifElementPropertyReader.cpp ${CMAKE_CURRENT_LIST_DIR}/RifStimPlanXmlReader.cpp ${CMAKE_CURRENT_LIST_DIR}/RifSummaryCaseRestartSelector.cpp -${CMAKE_CURRENT_LIST_DIR}/RifEnsembleParametersReader.cpp ${CMAKE_CURRENT_LIST_DIR}/RifCaseRealizationParametersReader.cpp ${CMAKE_CURRENT_LIST_DIR}/RifFileParseTools.cpp +${CMAKE_CURRENT_LIST_DIR}/RifEnsembleStatisticsReader.cpp +${CMAKE_CURRENT_LIST_DIR}/RifDerivedEnsembleReader.cpp # HDF5 file reader is directly included in ResInsight main CmakeList.txt #${CMAKE_CURRENT_LIST_DIR}/RifHdf5Reader.cpp diff --git a/ApplicationCode/FileInterface/RifCaseRealizationParametersReader.cpp b/ApplicationCode/FileInterface/RifCaseRealizationParametersReader.cpp index 8ef6f884a2..e34193dc72 100644 --- a/ApplicationCode/FileInterface/RifCaseRealizationParametersReader.cpp +++ b/ApplicationCode/FileInterface/RifCaseRealizationParametersReader.cpp @@ -26,53 +26,106 @@ #include #include +#include //-------------------------------------------------------------------------------------------------- /// Constants //-------------------------------------------------------------------------------------------------- #define PARAMETERS_FILE_NAME "parameters.txt" - +#define RUNSPEC_FILE_NAME "runspecification.xml" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifCaseRealizationParametersReader::RifCaseRealizationParametersReader(const QString& fileName) +RifCaseRealizationReader::RifCaseRealizationReader(const QString& fileName) { m_parameters = std::shared_ptr(new RigCaseRealizationParameters()); m_fileName = fileName; m_file = nullptr; - m_textStream = nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifCaseRealizationParametersReader::RifCaseRealizationParametersReader() +RifCaseRealizationReader::~RifCaseRealizationReader() { - m_parameters = std::shared_ptr(new RigCaseRealizationParameters()); - m_fileName = ""; - m_file = nullptr; - m_textStream = nullptr; + closeFile(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifCaseRealizationParametersReader::~RifCaseRealizationParametersReader() +const std::shared_ptr RifCaseRealizationReader::parameters() const { - if (m_textStream) + return m_parameters; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::shared_ptr RifCaseRealizationReader::createReaderFromFileName(const QString& fileName) +{ + std::shared_ptr reader; + + if (fileName.endsWith(PARAMETERS_FILE_NAME)) { - delete m_textStream; + reader.reset(new RifCaseRealizationParametersReader(fileName)); } - closeFile(); + else if (fileName.endsWith(RUNSPEC_FILE_NAME)) + { + reader.reset(new RifCaseRealizationRunspecificationReader(fileName)); + } + return reader; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifCaseRealizationParametersReader::setFileName(const QString& fileName) +QFile* RifCaseRealizationReader::openFile() { - m_fileName = fileName; + if (!m_file) + { + m_file = new QFile(m_fileName); + if (!m_file->open(QIODevice::ReadOnly | QIODevice::Text)) + { + closeFile(); + throw FileParseException(QString("Failed to open %1").arg(m_fileName)); + } + } + return m_file; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifCaseRealizationReader::closeFile() +{ + if (m_file) + { + m_file->close(); + delete m_file; + m_file = nullptr; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifCaseRealizationParametersReader::RifCaseRealizationParametersReader(const QString& fileName) : + RifCaseRealizationReader(fileName) +{ + m_textStream = nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifCaseRealizationParametersReader::~RifCaseRealizationParametersReader() +{ + if (m_textStream) + { + delete m_textStream; + } } //-------------------------------------------------------------------------------------------------- @@ -90,7 +143,7 @@ void RifCaseRealizationParametersReader::parse() QString line = dataStream->readLine(); lineNo++; - QStringList cols = RifFileParseTools::splitLineAndTrim(line, " "); + QStringList cols = RifFileParseTools::splitLineAndTrim(line, QRegExp("[ \t]"), true); if (cols.size() != 2) { @@ -136,9 +189,9 @@ void RifCaseRealizationParametersReader::parse() //-------------------------------------------------------------------------------------------------- QTextStream* RifCaseRealizationParametersReader::openDataStream() { - openFile(); + auto file = openFile(); - m_textStream = new QTextStream(m_file); + m_textStream = new QTextStream(file); return m_textStream; } @@ -158,40 +211,107 @@ void RifCaseRealizationParametersReader::closeDataStream() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifCaseRealizationParametersReader::openFile() +RifCaseRealizationRunspecificationReader::RifCaseRealizationRunspecificationReader(const QString& fileName) : + RifCaseRealizationReader(fileName) { - if (!m_file) + m_xmlStream = nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifCaseRealizationRunspecificationReader::~RifCaseRealizationRunspecificationReader() +{ + if (m_xmlStream) { - m_file = new QFile(m_fileName); - if (!m_file->open(QIODevice::ReadOnly | QIODevice::Text)) - { - closeFile(); - //delete m_file; - //m_file = nullptr; - throw FileParseException(QString("Failed to open %1").arg(m_fileName)); - } + delete m_xmlStream; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifCaseRealizationParametersReader::closeFile() +void RifCaseRealizationRunspecificationReader::parse() { - if (m_file) + auto xml = openDataStream(); + QString paramName; + + while (!xml->atEnd()) { - m_file->close(); - delete m_file; - m_file = nullptr; + xml->readNext(); + + if (xml->isStartElement()) + { + if (xml->name() == "modifier") + { + paramName = ""; + } + + if (xml->name() == "id") + { + paramName = xml->readElementText(); + } + + if(xml->name() == "value") + { + QString paramStrValue = xml->readElementText(); + + if (paramName.isEmpty()) continue; + + if (RiaStdStringTools::startsWithAlphabetic(paramStrValue.toStdString())) + { + m_parameters->addParameter(paramName, paramStrValue); + } + else + { + if (!RiaStdStringTools::isNumber(paramStrValue.toStdString(), QLocale::c().decimalPoint().toAscii())) + { + throw FileParseException(QString("RifEnsembleParametersReader: Invalid number format in line %1").arg(xml->lineNumber())); + } + + bool parseOk = true; + double value = QLocale::c().toDouble(paramStrValue, &parseOk); + if (!parseOk) + { + throw FileParseException(QString("RifEnsembleParametersReader: Invalid number format in line %1").arg(xml->lineNumber())); + } + + m_parameters->addParameter(paramName, value); + } + } + } + else if (xml->isEndElement()) + { + if (xml->name() == "modifier") + { + paramName = ""; + } + } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::shared_ptr RifCaseRealizationParametersReader::parameters() const +QXmlStreamReader * RifCaseRealizationRunspecificationReader::openDataStream() { - return m_parameters; + auto file = openFile(); + + m_xmlStream = new QXmlStreamReader(file); + return m_xmlStream; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifCaseRealizationRunspecificationReader::closeDataStream() +{ + if (m_xmlStream) + { + delete m_xmlStream; + m_xmlStream = nullptr; + } + closeFile(); } //-------------------------------------------------------------------------------------------------- @@ -199,7 +319,7 @@ const std::shared_ptr RifCaseRealizationParameters //-------------------------------------------------------------------------------------------------- QString RifCaseRealizationParametersFileLocator::locate(const QString& modelPath) { - int MAX_LEVELS_UP = 2; + int MAX_LEVELS_UP = 3; int dirLevel = 0; QDir qdir(modelPath); @@ -213,7 +333,8 @@ QString RifCaseRealizationParametersFileLocator::locate(const QString& modelPath QStringList files = qdir.entryList(QDir::Files | QDir::NoDotAndDotDot); for (const QString& file : files) { - if (QString::compare(file, PARAMETERS_FILE_NAME, Qt::CaseInsensitive) == 0) + if (QString::compare(file, PARAMETERS_FILE_NAME, Qt::CaseInsensitive) == 0 || + QString::compare(file, RUNSPEC_FILE_NAME, Qt::CaseInsensitive) == 0) { return qdir.absoluteFilePath(file); } diff --git a/ApplicationCode/FileInterface/RifCaseRealizationParametersReader.h b/ApplicationCode/FileInterface/RifCaseRealizationParametersReader.h index 5b2c65da72..f4f2ec09e8 100644 --- a/ApplicationCode/FileInterface/RifCaseRealizationParametersReader.h +++ b/ApplicationCode/FileInterface/RifCaseRealizationParametersReader.h @@ -34,36 +34,75 @@ class QStringList; class QTextStream; +class QXmlStreamReader; class QFile; //================================================================================================== // // //================================================================================================== -class RifCaseRealizationParametersReader +class RifCaseRealizationReader { public: - RifCaseRealizationParametersReader(); - RifCaseRealizationParametersReader(const QString& fileName); - ~RifCaseRealizationParametersReader(); + RifCaseRealizationReader(const QString& fileName); + virtual ~RifCaseRealizationReader(); - void setFileName(const QString& fileName); - void parse(); + virtual void parse() = 0; const std::shared_ptr parameters() const; -private: - QTextStream* openDataStream(); - void closeDataStream(); - void openFile(); + static std::shared_ptr createReaderFromFileName(const QString& fileName); + +protected: + QFile* openFile(); void closeFile(); -private: + std::shared_ptr m_parameters; +private: QString m_fileName; QFile* m_file; - QTextStream* m_textStream; }; +//================================================================================================== +// +// +//================================================================================================== +class RifCaseRealizationParametersReader : public RifCaseRealizationReader +{ +public: + RifCaseRealizationParametersReader(const QString& fileName); + ~RifCaseRealizationParametersReader() override; + + void parse() override; + +private: + QTextStream* openDataStream(); + void closeDataStream(); + +private: + QTextStream* m_textStream; +}; + + +//================================================================================================== +// +// +//================================================================================================== +class RifCaseRealizationRunspecificationReader : public RifCaseRealizationReader +{ +public: + RifCaseRealizationRunspecificationReader(const QString& fileName); + ~RifCaseRealizationRunspecificationReader() override; + + void parse() override; + +private: + QXmlStreamReader * openDataStream(); + void closeDataStream(); + +private: + QXmlStreamReader* m_xmlStream; +}; //================================================================================================== // diff --git a/ApplicationCode/FileInterface/RifColumnBasedUserData.cpp b/ApplicationCode/FileInterface/RifColumnBasedUserData.cpp index 7ddca9752e..b1117d672e 100644 --- a/ApplicationCode/FileInterface/RifColumnBasedUserData.cpp +++ b/ApplicationCode/FileInterface/RifColumnBasedUserData.cpp @@ -163,7 +163,7 @@ void RifColumnBasedUserData::buildTimeStepsAndMappings() { RifEclipseSummaryAddress sumAddress = ci.summaryAddress; - m_allResultAddresses.push_back(sumAddress); + m_allResultAddresses.insert(sumAddress); m_mapFromAddressToTimeStepIndex[sumAddress] = m_timeSteps.size() - 1; m_mapFromAddressToResultIndex[sumAddress] = std::make_pair(tableIndex, columIndex); diff --git a/ApplicationCode/FileInterface/RifColumnBasedUserData.h b/ApplicationCode/FileInterface/RifColumnBasedUserData.h index 537a0da77d..4057064c6c 100644 --- a/ApplicationCode/FileInterface/RifColumnBasedUserData.h +++ b/ApplicationCode/FileInterface/RifColumnBasedUserData.h @@ -39,13 +39,13 @@ class RifColumnBasedUserData : public RifSummaryReaderInterface { public: RifColumnBasedUserData(); - ~RifColumnBasedUserData(); + ~RifColumnBasedUserData() override; bool parse(const QString& data, QString* errorText = nullptr); - virtual const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; + const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; - virtual bool values(const RifEclipseSummaryAddress& resultAddress, + bool values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const override; std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; diff --git a/ApplicationCode/FileInterface/RifCsvUserData.cpp b/ApplicationCode/FileInterface/RifCsvUserData.cpp index a07ddbe757..0c20a3ffcd 100644 --- a/ApplicationCode/FileInterface/RifCsvUserData.cpp +++ b/ApplicationCode/FileInterface/RifCsvUserData.cpp @@ -54,8 +54,6 @@ RifCsvUserData::~RifCsvUserData() bool RifCsvUserData::parse(const QString& fileName, const AsciiDataParseOptions& parseOptions, QString* errorText) { m_allResultAddresses.clear(); - m_timeSteps.clear(); - m_mapFromAddressToTimeStepIndex.clear(); m_mapFromAddressToResultIndex.clear(); m_parser = std::unique_ptr(new RifCsvUserDataFileParser(fileName, errorText)); @@ -100,14 +98,25 @@ bool RifCsvUserData::values(const RifEclipseSummaryAddress& resultAddress, std:: //-------------------------------------------------------------------------------------------------- const std::vector& RifCsvUserData::timeSteps(const RifEclipseSummaryAddress& resultAddress) const { - auto search = m_mapFromAddressToTimeStepIndex.find(resultAddress); - if (search != m_mapFromAddressToTimeStepIndex.end()) + // First, check whether date time values exist for the current address + auto search = m_mapFromAddressToResultIndex.find(resultAddress); + if (search != m_mapFromAddressToResultIndex.end()) + { + size_t index = m_mapFromAddressToResultIndex.at(resultAddress); + if (!m_parser->tableData().columnInfos()[index].dateTimeValues.empty()) + { + return m_parser->tableData().columnInfos()[index].dateTimeValues; + } + } + + // Then check for a separate date time column + int index = m_parser->tableData().dateTimeColumnIndex(); + if (index >= 0) { - return m_timeSteps; + return m_parser->tableData().columnInfos()[index].dateTimeValues; } static std::vector emptyVector; - return emptyVector; } @@ -138,19 +147,6 @@ void RifCsvUserData::buildTimeStepsAndMappings() { auto tableData = m_parser->tableData(); - std::vector timeStepsForTable = createTimeSteps(tableData); - - if (timeStepsForTable.empty()) - { - RiaLogging::warning(QString("Failed to find time data for table in file")); - RiaLogging::warning(QString("No data for this table is imported")); - - return; - } - - m_timeSteps = timeStepsForTable; - - for (size_t columnIndex = 0; columnIndex < tableData.columnInfos().size(); columnIndex++) { const Column& ci = tableData.columnInfos()[columnIndex]; @@ -158,28 +154,10 @@ void RifCsvUserData::buildTimeStepsAndMappings() { RifEclipseSummaryAddress sumAddress = ci.summaryAddress; - m_allResultAddresses.push_back(sumAddress); + m_allResultAddresses.insert(sumAddress); + if (sumAddress.isErrorResult()) m_allErrorAddresses.insert(sumAddress); - m_mapFromAddressToTimeStepIndex[sumAddress] = m_timeSteps.size() - 1; m_mapFromAddressToResultIndex[sumAddress] = columnIndex; } } } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RifCsvUserData::createTimeSteps(const TableData& tableData) -{ - std::vector tsVector; - - const Column& col = tableData.columnInfos()[0]; - - tsVector.reserve(col.dateTimeValues.size()); - for (const QDateTime& qdt : col.dateTimeValues) - { - tsVector.push_back(qdt.toTime_t()); - } - - return tsVector; -} diff --git a/ApplicationCode/FileInterface/RifCsvUserData.h b/ApplicationCode/FileInterface/RifCsvUserData.h index 7267fd26b7..ffdc2e9b87 100644 --- a/ApplicationCode/FileInterface/RifCsvUserData.h +++ b/ApplicationCode/FileInterface/RifCsvUserData.h @@ -41,25 +41,22 @@ class RifCsvUserData : public RifSummaryReaderInterface { public: RifCsvUserData(); - ~RifCsvUserData(); + ~RifCsvUserData() override; bool parse(const QString& fileName, const AsciiDataParseOptions& parseOptions, QString* errorText = nullptr); - virtual const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; + const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; - virtual bool values(const RifEclipseSummaryAddress& resultAddress, + bool values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const override; std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; private: void buildTimeStepsAndMappings(); - static std::vector createTimeSteps(const TableData& table); private: std::unique_ptr m_parser; - std::vector m_timeSteps; - std::map m_mapFromAddressToTimeStepIndex; std::map m_mapFromAddressToResultIndex; }; diff --git a/ApplicationCode/FileInterface/RifCsvUserDataParser.cpp b/ApplicationCode/FileInterface/RifCsvUserDataParser.cpp index 4b8f283620..56cbd8cd41 100644 --- a/ApplicationCode/FileInterface/RifCsvUserDataParser.cpp +++ b/ApplicationCode/FileInterface/RifCsvUserDataParser.cpp @@ -25,6 +25,7 @@ #include "RiaDateStringParser.h" #include "RiaLogging.h" #include "RiaStdStringTools.h" +#include "RiaTextStringTools.h" #include "RiaQDateTimeTools.h" #include "../Commands/SummaryPlotCommands/RicPasteAsciiDataToSummaryPlotFeatureUi.h" @@ -36,6 +37,26 @@ #include #include +#include +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// Internal constants +//-------------------------------------------------------------------------------------------------- +#define DOUBLE_INF std::numeric_limits::infinity() + +#define ISO_DATE_FORMAT "yyyy-MM-dd" +#define TIME_FORMAT "hh:mm:ss" + +using Sample = std::pair; +using SampleList = std::vector; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +enum class CsvLineBasedColumnType { DATE, VECTOR, VALUE, ERROR_VALUE, COMMENTS }; +const std::vector CSV_LINE_BASED_COL_NAMES = { "DATE", "VECTOR", "VALUE", "ERROR", "COMMENTS" }; //-------------------------------------------------------------------------------------------------- /// @@ -58,7 +79,8 @@ RifCsvUserDataParser::~RifCsvUserDataParser() //-------------------------------------------------------------------------------------------------- bool RifCsvUserDataParser::parse(const AsciiDataParseOptions& parseOptions) { - return parseData(parseOptions); + if (determineCsvLayout() == LineBased) return parseLineBasedData(); + return parseColumnBasedData(parseOptions); } //-------------------------------------------------------------------------------------------------- @@ -95,6 +117,29 @@ const Column* RifCsvUserDataParser::dateTimeColumn() const return nullptr; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifCsvUserDataParser::parseLineBasedHeader(QStringList headerCols) +{ + std::vector colIndexes; + + for (int i = 0; i < (int)CSV_LINE_BASED_COL_NAMES.size(); i++) + { + for (int j = 0; j < (int)headerCols.size(); j++) + { + if (headerCols[j] == CSV_LINE_BASED_COL_NAMES[i]) + { + colIndexes.push_back(j); + break; + } + } + + if (i < 3 && (int)colIndexes.size() < i + 1) return {}; + } + return colIndexes; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -173,6 +218,31 @@ QString RifCsvUserDataParser::previewText(int lineCount, const AsciiDataParseOpt return preview; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifCsvUserDataParser::CsvLayout RifCsvUserDataParser::determineCsvLayout() +{ + QTextStream* dataStream = openDataStream(); + QString firstLine; + + QStringList headers; + while (!dataStream->atEnd()) + { + firstLine = dataStream->readLine(); + if (firstLine.isEmpty()) continue; + headers = firstLine.split(';'); + if (headers.size() < 3 || headers.size() > 5) continue; + break; + } + closeDataStream(); + + if (headers.contains(CSV_LINE_BASED_COL_NAMES[(size_t)CsvLineBasedColumnType::DATE]) + && headers.contains(CSV_LINE_BASED_COL_NAMES[(size_t)CsvLineBasedColumnType::VECTOR]) + && headers.contains(CSV_LINE_BASED_COL_NAMES[(size_t)CsvLineBasedColumnType::VALUE])) return LineBased; + return ColumnBased; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -194,8 +264,8 @@ bool RifCsvUserDataParser::parseColumnInfo(QTextStream* dataStream, const AsciiD for (int iCol = 0; iCol < colCount; iCol++) { - QString colName = lineColumns[iCol]; - RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::importedAddress(colName.toStdString()); + QString colName = RiaTextStringTools::trimAndRemoveDoubleSpaces(lineColumns[iCol]); + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(colName.toStdString()); Column col = Column::createColumnInfoFromCsvData(addr, ""); columnInfoList->push_back(col); @@ -209,7 +279,7 @@ bool RifCsvUserDataParser::parseColumnInfo(QTextStream* dataStream, const AsciiD //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions) +bool RifCsvUserDataParser::parseColumnBasedData(const AsciiDataParseOptions& parseOptions) { bool errors = false; enum { FIRST_DATA_ROW, DATA_ROW } parseState = FIRST_DATA_ROW; @@ -221,7 +291,7 @@ bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions) // Parse header if (!parseColumnInfo(dataStream, parseOptions, &columnInfoList)) { - m_errorText->append("CSV import: Failed to parse header columns"); + if (m_errorText) m_errorText->append("CSV import: Failed to parse header columns"); return false; } @@ -235,7 +305,7 @@ bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions) if(lineColumns.size() != colCount) { - m_errorText->append("CSV import: Varying number of columns"); + if (m_errorText) m_errorText->append("CSV import: Varying number of columns"); errors = true; break; } @@ -255,7 +325,7 @@ bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions) } else { - if (RiaStdStringTools::isNumber(colData, parseOptions.locale.decimalPoint().toAscii())) + if (parseOptions.assumeNumericDataColumns || RiaStdStringTools::isNumber(colData, parseOptions.locale.decimalPoint().toAscii())) { col.dataType = Column::NUMERIC; } @@ -289,11 +359,11 @@ bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions) // Find the error reason, wrong decimal sign or something else if (RiaStdStringTools::isNumber(colData.toStdString(), '.') || RiaStdStringTools::isNumber(colData.toStdString(), ',')) { - m_errorText->append(QString("CSV import: Failed to parse numeric value in column %1\n").arg(QString::number(iCol + 1))); + if (m_errorText) m_errorText->append(QString("CSV import: Failed to parse numeric value in column %1\n").arg(QString::number(iCol + 1))); throw 0; } - // Add NULL value + // Add nullptr value value = HUGE_VAL; } col.values.push_back(value); @@ -310,15 +380,23 @@ bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions) if (!dt.isValid() && !parseOptions.useCustomDateTimeFormat) { // Try to match date format only - dt = tryParseDateTime(colData.toStdString(), parseOptions.dateFormat); + if (parseOptions.dateFormat != parseOptions.dateTimeFormat) + { + dt = tryParseDateTime(colData.toStdString(), parseOptions.dateFormat); + } + if (!dt.isValid() && !parseOptions.fallbackDateTimeFormat.isEmpty()) + { + dt = tryParseDateTime(colData.toStdString(), parseOptions.fallbackDateTimeFormat); + } } if (!dt.isValid()) { - m_errorText->append("CSV import: Failed to parse date time value"); + if (m_errorText) m_errorText->append("CSV import: Failed to parse date time value"); throw 0; } - col.dateTimeValues.push_back(dt); + col.dateTimeValues.push_back(dt.toTime_t()); + } } catch (...) @@ -340,6 +418,147 @@ bool RifCsvUserDataParser::parseData(const AsciiDataParseOptions& parseOptions) return !errors; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifCsvUserDataParser::parseLineBasedData() +{ + bool errors = false; + QTextStream* dataStream = openDataStream(); + std::map>> addressesAndData; + std::vector colIndexes; + + // Parse header + int lineCount = 0; + bool headerFound = false; + bool expectErrorValue = false; + + while (!dataStream->atEnd() && !errors) + { + lineCount++; + + QString line = dataStream->readLine(); + if (line.trimmed().isEmpty()) continue; + + QStringList dataItems = RifFileParseTools::splitLineAndTrim(line, ";"); + if (dataItems.size() < 3 || dataItems.size() > 5) continue; + + if (!headerFound) + { + colIndexes = parseLineBasedHeader(dataItems); + if (!colIndexes.empty()) + { + headerFound = true; + expectErrorValue = colIndexes.size() > (size_t)CsvLineBasedColumnType::ERROR_VALUE && colIndexes[(size_t)CsvLineBasedColumnType::ERROR_VALUE] >= 0; + } + continue; + } + + if(dataItems.size() != (int)colIndexes.size()) continue; + + { + auto textAddr = dataItems[colIndexes[(size_t)CsvLineBasedColumnType::VECTOR]]; + auto addr = RifEclipseSummaryAddress::fromEclipseTextAddress(textAddr.toStdString()); + auto errAddr = addr; + errAddr.setAsErrorResult(); + + if (!addr.isValid()) continue; + + // VECTOR + { + if (addressesAndData.find(addr) == addressesAndData.end()) + { + addressesAndData.insert(std::make_pair(addr, std::vector())); + } + + // Create error address if error value is expected + if (expectErrorValue) + { + if (addressesAndData.find(errAddr) == addressesAndData.end()) + { + addressesAndData.insert(std::make_pair(errAddr, std::vector())); + } + } + } + + // DATE + QDateTime dateTime; + { + auto dateText = dataItems[colIndexes[(size_t)CsvLineBasedColumnType::DATE]].toStdString(); + + dateTime = tryParseDateTime(dateText, ISO_DATE_FORMAT); + if (!dateTime.isValid()) + { + // Try to match date and time + dateTime = tryParseDateTime(dateText, QString(ISO_DATE_FORMAT) + " " + TIME_FORMAT); + } + + if (!dateTime.isValid()) + { + if (m_errorText) m_errorText->append(QString("CSV import: Failed to parse date time value in line %1").arg(QString::number(lineCount))); + throw 0; + } + } + + // VALUE + { + bool parseOk = true; + double value = QLocale::c().toDouble(dataItems[colIndexes[(size_t)CsvLineBasedColumnType::VALUE]], &parseOk); + + if (!parseOk) + { + if (m_errorText) m_errorText->append(QString("CSV import: Failed to parse numeric value in line %1\n").arg(QString::number(lineCount))); + throw 0; + } + + auto& samples = addressesAndData[addr]; + samples.push_back(std::make_pair(dateTime.toTime_t(), value)); + } + + // ERROR VALUE + if(expectErrorValue) + { + bool parseOk = true; + double value = QLocale::c().toDouble(dataItems[colIndexes[(size_t)CsvLineBasedColumnType::ERROR_VALUE]], &parseOk); + + if (!parseOk) value = DOUBLE_INF; + + auto& samples = addressesAndData[errAddr]; + samples.push_back(std::make_pair(dateTime.toTime_t(), value)); + } + } + } + closeDataStream(); + + if (!errors) + { + std::vector columnInfoList; + for (const auto& item : addressesAndData) + { + auto samples = item.second; + + // Sort samples by time + std::sort(samples.begin(), samples.end(), + [](const Sample& s1, const Sample& s2) {return s1.first < s2.first; }); + + // Copy + Column c = Column::createColumnInfoFromCsvData(item.first, ""); + c.dataType = Column::NUMERIC; + + for (const auto& sample : samples) + { + c.dateTimeValues.push_back(sample.first); + c.values.push_back(sample.second); + } + columnInfoList.push_back(c); + } + + TableData td("", "", columnInfoList); + m_tableData = td; + } + return !errors; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -398,7 +617,6 @@ QString RifCsvUserDataParser::tryDetermineCellSeparator() QString RifCsvUserDataParser::tryDetermineDecimalSeparator(const QString& cellSeparator) { QTextStream* dataStream = openDataStream(); - std::vector lines; int iLine = 0; int successfulParsesDot = 0; @@ -422,6 +640,8 @@ QString RifCsvUserDataParser::tryDetermineDecimalSeparator(const QString& cellSe locale.toDouble(cellData, &parseOk); if (parseOk) successfulParsesComma++; } + + iLine++; } closeDataStream(); diff --git a/ApplicationCode/FileInterface/RifCsvUserDataParser.h b/ApplicationCode/FileInterface/RifCsvUserDataParser.h index 3f88890975..639b00ff23 100644 --- a/ApplicationCode/FileInterface/RifCsvUserDataParser.h +++ b/ApplicationCode/FileInterface/RifCsvUserDataParser.h @@ -39,6 +39,9 @@ class AsciiDataParseOptions; //================================================================================================== class RifCsvUserDataParser { +public: + enum CsvLayout { ColumnBased, LineBased }; + public: RifCsvUserDataParser(QString* errorText = nullptr); virtual ~RifCsvUserDataParser(); @@ -46,12 +49,14 @@ class RifCsvUserDataParser bool parse(const AsciiDataParseOptions& parseOptions); const TableData& tableData() const; - const Column* columnInfo(size_t columnIndex) const; - const Column* dateTimeColumn() const; + const Column* columnInfo(size_t columnIndex) const; + const Column* dateTimeColumn() const; bool parseColumnInfo(const AsciiDataParseOptions& parseOptions); QString previewText(int lineCount, const AsciiDataParseOptions& parseOptions); + CsvLayout determineCsvLayout(); + QString tryDetermineCellSeparator(); QString tryDetermineDecimalSeparator(const QString& cellSeparator); @@ -59,13 +64,16 @@ class RifCsvUserDataParser protected: virtual QTextStream* openDataStream() = 0; - virtual void closeDataStream() = 0; + virtual void closeDataStream() = 0; private: + std::vector parseLineBasedHeader(QStringList headerCols); + bool parseColumnInfo(QTextStream* dataStream, const AsciiDataParseOptions& parseOptions, std::vector* columnInfoList); - bool parseData(const AsciiDataParseOptions& parseOptions); + bool parseColumnBasedData(const AsciiDataParseOptions& parseOptions); + bool parseLineBasedData(); static QDateTime tryParseDateTime(const std::string& colData, const QString& format); private: @@ -80,11 +88,11 @@ class RifCsvUserDataFileParser : public RifCsvUserDataParser { public: RifCsvUserDataFileParser(const QString& fileName, QString* errorText = nullptr); - virtual ~RifCsvUserDataFileParser(); + ~RifCsvUserDataFileParser() override; protected: - virtual QTextStream* openDataStream() override; - virtual void closeDataStream() override; + QTextStream* openDataStream() override; + void closeDataStream() override; private: bool openFile(); @@ -104,11 +112,11 @@ class RifCsvUserDataPastedTextParser : public RifCsvUserDataParser { public: RifCsvUserDataPastedTextParser(const QString& text, QString* errorText = nullptr); - virtual ~RifCsvUserDataPastedTextParser(); + ~RifCsvUserDataPastedTextParser() override; protected: - virtual QTextStream* openDataStream() override; - virtual void closeDataStream() override; + QTextStream* openDataStream() override; + void closeDataStream() override; private: QString m_text; diff --git a/ApplicationCode/FileInterface/RifDerivedEnsembleReader.cpp b/ApplicationCode/FileInterface/RifDerivedEnsembleReader.cpp new file mode 100644 index 0000000000..839bfa1f92 --- /dev/null +++ b/ApplicationCode/FileInterface/RifDerivedEnsembleReader.cpp @@ -0,0 +1,75 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RifDerivedEnsembleReader.h" + +#include "RimDerivedEnsembleCase.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector RifDerivedEnsembleReader::EMPTY_TIME_STEPS_VECTOR; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifDerivedEnsembleReader::RifDerivedEnsembleReader(RimDerivedEnsembleCase* derivedCase) +{ + CVF_ASSERT(derivedCase); + + m_derivedCase = derivedCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RifDerivedEnsembleReader::timeSteps(const RifEclipseSummaryAddress& resultAddress) const +{ + if (!resultAddress.isValid()) return EMPTY_TIME_STEPS_VECTOR; + if (m_derivedCase->needsCalculation(resultAddress)) + { + m_derivedCase->calculate(resultAddress); + } + return m_derivedCase->timeSteps(resultAddress); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifDerivedEnsembleReader::values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const +{ + if (!resultAddress.isValid()) return false; + + if (m_derivedCase->needsCalculation(resultAddress)) + { + m_derivedCase->calculate(resultAddress); + } + auto dataValues = m_derivedCase->values(resultAddress); + values->clear(); + values->reserve(dataValues.size()); + for (auto val : dataValues) values->push_back(val); + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::string RifDerivedEnsembleReader::unitName(const RifEclipseSummaryAddress& resultAddress) const +{ + return ""; +} diff --git a/ApplicationCode/FileInterface/RifDerivedEnsembleReader.h b/ApplicationCode/FileInterface/RifDerivedEnsembleReader.h new file mode 100644 index 0000000000..e54c88c40f --- /dev/null +++ b/ApplicationCode/FileInterface/RifDerivedEnsembleReader.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "RifEclipseSummaryAddress.h" +#include "RifSummaryReaderInterface.h" + +class RimDerivedEnsembleCase; + + +//================================================================================================== +/// +//================================================================================================== +class RifDerivedEnsembleReader : public RifSummaryReaderInterface +{ + static const std::vector EMPTY_TIME_STEPS_VECTOR; + +public: + RifDerivedEnsembleReader(RimDerivedEnsembleCase* derivedCase); + + const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; + bool values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const override; + std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; + +private: + RimDerivedEnsembleCase* m_derivedCase; +}; diff --git a/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.cpp b/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.cpp index 368eb2267d..e41515e47f 100644 --- a/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.cpp +++ b/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.cpp @@ -26,6 +26,9 @@ RifEclipseDataTableFormatter::RifEclipseDataTableFormatter(QTextStream& out) : m_out(out) , m_colSpacing(5) + , m_tableRowPrependText(" ") + , m_tableRowAppendText(" /") + , m_commentPrefix("--") { } @@ -46,14 +49,38 @@ void RifEclipseDataTableFormatter::setColumnSpacing(int spacing) m_colSpacing = spacing; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseDataTableFormatter::setTableRowPrependText(const QString& text) +{ + m_tableRowPrependText = text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseDataTableFormatter::setTableRowLineAppendText(const QString& text) +{ + m_tableRowAppendText = text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseDataTableFormatter::setCommentPrefix(const QString& commentPrefix) +{ + m_commentPrefix = commentPrefix; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifEclipseDataTableFormatter::outputBuffer() { - if (!m_columns.empty()) + if (!m_columns.empty() && !isAllHeadersEmpty(m_columns)) { - m_out << "-- "; + m_out << m_commentPrefix << " "; for (RifEclipseOutputTableColumn& column : m_columns) { m_out << formatColumn(column.title, column); @@ -67,15 +94,20 @@ void RifEclipseDataTableFormatter::outputBuffer() { outputComment(line); } + else if (line.lineType == HORIZONTAL_LINE) + { + outputHorizontalLine(line); + } else if (line.lineType == CONTENTS) { - m_out << " "; + m_out << m_tableRowPrependText; + for (size_t i = 0; i < line.data.size(); ++i) { m_out << formatColumn(line.data[i], m_columns[i]); } - m_out << " /" - << "\n"; + + m_out << (line.appendTextSet ? line.appendText : m_tableRowAppendText) << "\n"; } } m_columns.clear(); @@ -87,7 +119,45 @@ void RifEclipseDataTableFormatter::outputBuffer() //-------------------------------------------------------------------------------------------------- void RifEclipseDataTableFormatter::outputComment(RifEclipseOutputTableLine& comment) { - m_out << "-- " << comment.data[0] << "\n"; + m_out << m_commentPrefix << " " << comment.data[0] << "\n"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseDataTableFormatter::outputHorizontalLine(RifEclipseOutputTableLine& comment) +{ + if (comment.lineType == HORIZONTAL_LINE) + { + int charCount = tableWidth(); + + QChar fillChar = ' '; + if (!comment.data.empty()) + { + QString firstString = comment.data[0]; + if (!firstString.isEmpty()) + { + fillChar = firstString[0]; + } + } + + QString str; + str.fill(fillChar, charCount); + + m_out << m_commentPrefix << str << "\n"; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifEclipseDataTableFormatter::isAllHeadersEmpty(const std::vector& headers) +{ + for (auto& header : headers) + { + if (!header.title.isEmpty()) return false; + } + return true; } //-------------------------------------------------------------------------------------------------- @@ -96,14 +166,52 @@ void RifEclipseDataTableFormatter::outputComment(RifEclipseOutputTableLine& comm void RifEclipseDataTableFormatter::tableCompleted() { outputBuffer(); + // Output an "empty" line after a finished table - m_out << "/\n"; + m_out << m_tableRowPrependText << m_tableRowAppendText << "\n"; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::keyword(const QString keyword) +void RifEclipseDataTableFormatter::tableCompleted(const QString& appendText, bool appendNewline) +{ + outputBuffer(); + + // Output an "empty" line after a finished table + if (!appendText.isEmpty() || appendNewline) + { + m_out << m_tableRowPrependText << appendText << (appendNewline ? "\n" : ""); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseDataTableFormatter::addValueTable(QTextStream& stream, const QString& name, size_t columns, const std::vector& values) +{ + RifEclipseDataTableFormatter subFormatter(stream); + + std::vector cols(columns, RifEclipseOutputTableColumn("")); + + subFormatter.setTableRowPrependText(""); + subFormatter.keyword(name); + subFormatter.header(cols); + + int colCount = 0; + for (size_t i = 0; i < values.size(); i++) + { + subFormatter.add(values[i]); + if (++colCount % columns == 0 && i < values.size() - 1) subFormatter.rowCompleted(""); + } + subFormatter.rowCompleted(); + subFormatter.tableCompleted("", false); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::keyword(const QString& keyword) { CVF_ASSERT(m_buffer.empty()); CVF_ASSERT(m_columns.empty()); @@ -128,11 +236,34 @@ RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::header(const std::ve //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::comment(const QString comment) +RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::comment(const QString& comment) { RifEclipseOutputTableLine line; line.data.push_back(comment); line.lineType = COMMENT; + line.appendTextSet = false; + if (m_columns.empty()) + { + outputComment(line); + } + else + { + m_buffer.push_back(line); + } + return *this; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::addHorizontalLine(const QChar& character) +{ + RifEclipseOutputTableLine line; + QString data; + data += character; + line.data.push_back(data); + line.lineType = HORIZONTAL_LINE; + line.appendTextSet = false; if (m_columns.empty()) { outputComment(line); @@ -147,7 +278,7 @@ RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::comment(const QStrin //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::add(const QString str) +RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::add(const QString& str) { size_t column = m_lineBuffer.size(); CVF_ASSERT(column < m_columns.size()); @@ -195,27 +326,54 @@ RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::add(size_t num) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::addZeroBasedCellIndex(size_t index) +RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::addOneBasedCellIndex(size_t zeroBasedIndex) { size_t column = m_lineBuffer.size(); CVF_ASSERT(column < m_columns.size()); // Increase index by 1 to use Eclipse 1-based cell index instead of ResInsight 0-based - index++; + zeroBasedIndex++; - m_columns[column].width = std::max(measure(index), m_columns[column].width); - m_lineBuffer.push_back(format(index)); + m_columns[column].width = std::max(measure(zeroBasedIndex), m_columns[column].width); + m_lineBuffer.push_back(format(zeroBasedIndex)); return *this; } +//-------------------------------------------------------------------------------------------------- +/// Add default marker if the value equals the defaultValue, otherwise add value. +//-------------------------------------------------------------------------------------------------- +RifEclipseDataTableFormatter& RifEclipseDataTableFormatter::addValueOrDefaultMarker(double value, double defaultValue) +{ + if (value == defaultValue) + { + return add(QString("1*")); + } + return add(value); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifEclipseDataTableFormatter::rowCompleted() +{ + RifEclipseOutputTableLine line; + line.data = m_lineBuffer; + line.lineType = CONTENTS; + line.appendTextSet = false; + m_buffer.push_back(line); + m_lineBuffer.clear(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifEclipseDataTableFormatter::rowCompleted(const QString& appendText) { RifEclipseOutputTableLine line; line.data = m_lineBuffer; line.lineType = CONTENTS; + line.appendTextSet = true; + line.appendText = appendText; m_buffer.push_back(line); m_lineBuffer.clear(); } @@ -252,6 +410,21 @@ int RifEclipseDataTableFormatter::measure(size_t num) return format(num).length(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifEclipseDataTableFormatter::tableWidth() const +{ + int characterCount = 0; + + for (const auto& col : m_columns) + { + characterCount += formatColumn(" ", col).size(); + } + + return characterCount; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -287,7 +460,7 @@ QString RifEclipseDataTableFormatter::format(size_t num) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RifEclipseDataTableFormatter::formatColumn(const QString str, RifEclipseOutputTableColumn column) +QString RifEclipseDataTableFormatter::formatColumn(const QString str, RifEclipseOutputTableColumn column) const { if (column.alignment == LEFT) { @@ -295,6 +468,6 @@ QString RifEclipseDataTableFormatter::formatColumn(const QString str, RifEclipse } else { - return str.rightJustified(column.width, ' ').leftJustified(m_colSpacing, ' '); + return str.rightJustified(column.width + m_colSpacing, ' '); } } diff --git a/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.h b/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.h index 2981149e8e..3b1a680df1 100644 --- a/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.h +++ b/ApplicationCode/FileInterface/RifEclipseDataTableFormatter.h @@ -29,7 +29,8 @@ enum RifEclipseOutputTableLineType { COMMENT, - CONTENTS + CONTENTS, + HORIZONTAL_LINE }; //================================================================================================== @@ -57,6 +58,8 @@ struct RifEclipseOutputTableLine { RifEclipseOutputTableLineType lineType; std::vector data; + bool appendTextSet; + QString appendText; }; //================================================================================================== @@ -106,17 +109,26 @@ class RifEclipseDataTableFormatter virtual ~RifEclipseDataTableFormatter(); void setColumnSpacing(int spacing); + void setTableRowPrependText(const QString& text); + void setTableRowLineAppendText(const QString& text); + void setCommentPrefix(const QString& commentPrefix); - RifEclipseDataTableFormatter& keyword(const QString keyword); + RifEclipseDataTableFormatter& keyword(const QString& keyword); RifEclipseDataTableFormatter& header(std::vector tableHeader); - RifEclipseDataTableFormatter& add(const QString str); - RifEclipseDataTableFormatter& add(double num); + RifEclipseDataTableFormatter& add(const QString& str); + RifEclipseDataTableFormatter& add(double num); RifEclipseDataTableFormatter& add(int num); RifEclipseDataTableFormatter& add(size_t num); - RifEclipseDataTableFormatter& addZeroBasedCellIndex(size_t index); - RifEclipseDataTableFormatter& comment(const QString str); + RifEclipseDataTableFormatter& addOneBasedCellIndex(size_t zeroBasedIndex); + RifEclipseDataTableFormatter& addValueOrDefaultMarker(double value, double defaultValue); + RifEclipseDataTableFormatter& comment(const QString& str); + RifEclipseDataTableFormatter& addHorizontalLine(const QChar& str); void rowCompleted(); + void rowCompleted(const QString& appendText); void tableCompleted(); + void tableCompleted(const QString& appendText, bool appendNewline); + + static void addValueTable(QTextStream& stream, const QString& keyword, size_t columns, const std::vector& values); private: int measure(const QString str); @@ -124,13 +136,18 @@ class RifEclipseDataTableFormatter int measure(int num); int measure(size_t num); + int tableWidth() const; + QString format(double num, RifEclipseOutputTableDoubleFormatting doubleFormat); QString format(int num); QString format(size_t num); - QString formatColumn(const QString str, RifEclipseOutputTableColumn column); + QString formatColumn(const QString str, RifEclipseOutputTableColumn column) const; void outputBuffer(); void outputComment(RifEclipseOutputTableLine& comment); + void outputHorizontalLine(RifEclipseOutputTableLine& comment); + + bool isAllHeadersEmpty(const std::vector& headers); private: std::vector m_columns; @@ -138,4 +155,7 @@ class RifEclipseDataTableFormatter std::vector m_lineBuffer; QTextStream& m_out; int m_colSpacing; + QString m_tableRowPrependText; + QString m_tableRowAppendText; + QString m_commentPrefix; }; diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp index 01f8597e08..455e0118ef 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.cpp @@ -28,7 +28,6 @@ #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" #include "RigMainGrid.h" -#include "RigResultAccessorFactory.h" #include "cafProgressInfo.h" @@ -43,7 +42,7 @@ #include #include -#include "ert/ecl/ecl_box.h" +#include "ert/ecl/ecl_box.hpp" #include "ert/ecl/ecl_kw.h" QString includeKeyword("INCLUDE"); @@ -153,7 +152,7 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigEclipseC allKwReadOk = allKwReadOk && nullptr != (coordKw = ecl_kw_fscanf_alloc_current_grdecl__(gridFilePointer, false , ecl_type_create_from_type(ECL_FLOAT_TYPE))); progress.setProgress(3); - // If ACTNUM is not defined, this pointer will be NULL, which is a valid condition + // If ACTNUM is not defined, this pointer will be nullptr, which is a valid condition if (actnumPos >= 0) { fseek(gridFilePointer, actnumPos, SEEK_SET); @@ -161,7 +160,7 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigEclipseC progress.setProgress(4); } - // If MAPAXES is not defined, this pointer will be NULL, which is a valid condition + // If MAPAXES is not defined, this pointer will be nullptr, which is a valid condition if (mapaxesPos >= 0) { fseek(gridFilePointer, mapaxesPos, SEEK_SET); @@ -214,7 +213,7 @@ bool RifEclipseInputFileTools::openGridFile(const QString& fileName, RigEclipseC ecl_grid_free(inputGrid); - util_fclose(gridFilePointer); + fclose(gridFilePointer); return true; } @@ -264,7 +263,7 @@ std::map RifEclipseInputFileTools::readProperties(const QStrin progress.setProgress(i); } - util_fclose(gridFilePointer); + fclose(gridFilePointer); return newResults; } @@ -291,7 +290,7 @@ bool RifEclipseInputFileTools::readProperty(const QString& fileName, RigEclipseC ecl_kw_free(eclipseKeywordData); } - util_fclose(filePointer); + fclose(filePointer); return isOk; } @@ -471,119 +470,6 @@ const std::vector& RifEclipseInputFileTools::invalidPropertyDataKeyword return keywords; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::writePropertyToTextFile(const QString& fileName, RigEclipseCaseData* eclipseCase, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord) -{ - CVF_ASSERT(eclipseCase); - - size_t resultIndex = eclipseCase->results(RiaDefines::MATRIX_MODEL)->findScalarResultIndex(resultName); - if (resultIndex == cvf::UNDEFINED_SIZE_T) - { - return false; - } - - QFile file(fileName); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - { - return false; - } - - std::vector< std::vector >& resultData = eclipseCase->results(RiaDefines::MATRIX_MODEL)->cellScalarResults(resultIndex); - if (resultData.size() == 0) - { - return false; - } - - std::vector& singleTimeStepData = resultData[timeStep]; - writeDataToTextFile(&file, eclipseKeyWord, singleTimeStepData); - - return true; -} - -//-------------------------------------------------------------------------------------------------- -/// Create and write a result vector with values for all cells. -/// undefinedValue is used for cells with no result -//-------------------------------------------------------------------------------------------------- -bool RifEclipseInputFileTools::writeBinaryResultToTextFile(const QString& fileName, - RigEclipseCaseData* eclipseCase, - size_t timeStep, - RimEclipseResultDefinition* resultDefinition, - const QString& eclipseKeyWord, - const double undefinedValue) -{ - CVF_ASSERT(eclipseCase); - - cvf::ref resultAccessor = RigResultAccessorFactory::createFromResultDefinition(eclipseCase, eclipseCase->mainGrid()->gridIndex(), timeStep, resultDefinition); - if (resultAccessor.isNull()) - { - return false; - } - - QFile file(fileName); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - { - return false; - } - - std::vector resultData; - size_t i, j, k; - for (k = 0; k < eclipseCase->mainGrid()->cellCountK(); k++) - { - for (j = 0; j < eclipseCase->mainGrid()->cellCountJ(); j++) - { - for (i = 0; i < eclipseCase->mainGrid()->cellCountI(); i++) - { - double resultValue = resultAccessor->cellScalar(eclipseCase->mainGrid()->cellIndexFromIJK(i, j, k)); - if (resultValue == HUGE_VAL) - { - resultValue = undefinedValue; - } - - resultData.push_back(resultValue); - } - } - } - - writeDataToTextFile(&file, eclipseKeyWord, resultData); - - return true; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RifEclipseInputFileTools::writeDataToTextFile(QFile* file, const QString& eclipseKeyWord, const std::vector& resultData) -{ - QTextStream out(file); - out << "\n"; - out << "-- Exported from ResInsight" << "\n"; - out << eclipseKeyWord << "\n" << right << qSetFieldWidth(16); - - caf::ProgressInfo pi(resultData.size(), QString("Writing data to file %1").arg(file->fileName()) ); - size_t progressSteps = resultData.size() / 20; - - size_t i; - for (i = 0; i < resultData.size(); i++) - { - out << resultData[i]; - - if ( (i + 1) % 5 == 0) - { - out << "\n"; - } - - if (i % progressSteps == 0) - { - pi.setProgress(i); - } - } - - out << "\n" << "/" << "\n"; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/FileInterface/RifEclipseInputFileTools.h b/ApplicationCode/FileInterface/RifEclipseInputFileTools.h index 65741c08e8..ca6f40b348 100644 --- a/ApplicationCode/FileInterface/RifEclipseInputFileTools.h +++ b/ApplicationCode/FileInterface/RifEclipseInputFileTools.h @@ -36,8 +36,6 @@ class RigEclipseCaseData; class QFile; -class RimEclipseResultDefinition; - //-------------------------------------------------------------------------------------------------- /// Structure used to cache file position of keywords @@ -58,7 +56,7 @@ class RifEclipseInputFileTools : public cvf::Object { public: RifEclipseInputFileTools(); - virtual ~RifEclipseInputFileTools(); + ~RifEclipseInputFileTools() override; static bool openGridFile(const QString& fileName, RigEclipseCaseData* eclipseCase, bool readFaultData); @@ -76,9 +74,6 @@ class RifEclipseInputFileTools : public cvf::Object static void parseAndReadPathAliasKeyword(const QString &fileName, std::vector< std::pair >* pathAliasDefinitions); - static bool writePropertyToTextFile(const QString& fileName, RigEclipseCaseData* eclipseCase, size_t timeStep, const QString& resultName, const QString& eclipseKeyWord); - static bool writeBinaryResultToTextFile(const QString& fileName, RigEclipseCaseData* eclipseCase, size_t timeStep, RimEclipseResultDefinition* resultdefinition, const QString& eclipseKeyWord, const double undefinedValue); - static bool readFaultsAndParseIncludeStatementsRecursively( QFile& file, qint64 startPos, const std::vector< std::pair >& pathAliasDefinitions, @@ -88,7 +83,6 @@ class RifEclipseInputFileTools : public cvf::Object const QString& faultIncludeFileAbsolutePathPrefix); static cvf::StructGridInterface::FaceEnum faceEnumFromText(const QString& faceString); - static void writeDataToTextFile(QFile* file, const QString& eclipseKeyWord, const std::vector& resultData); private: static bool readDataFromKeyword(ecl_kw_type* eclipseKeywordData, RigEclipseCaseData* caseData, const QString& resultName); diff --git a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp index e36114342d..d8d70e4d7b 100644 --- a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.cpp @@ -184,21 +184,26 @@ void RifEclipseOutputFileTools::timeSteps(ecl_file_type* ecl_file, std::vector* values) { - ecl_kw_type* kwData = ecl_file_iget_named_kw(ecl_file, RiaStringEncodingTools::toNativeEncoded(keyword).data(), static_cast(fileKeywordOccurrence)); - if (kwData) + bool result = false; + +#pragma omp critical(critical_section_keywordData_double) { - size_t numValues = ecl_kw_get_size(kwData); + ecl_kw_type* kwData = ecl_file_iget_named_kw(ecl_file, RiaStringEncodingTools::toNativeEncoded(keyword).data(), static_cast(fileKeywordOccurrence)); + if (kwData) + { + size_t numValues = ecl_kw_get_size(kwData); - std::vector doubleData; - doubleData.resize(numValues); + std::vector doubleData; + doubleData.resize(numValues); - ecl_kw_get_data_as_double(kwData, doubleData.data()); - values->insert(values->end(), doubleData.begin(), doubleData.end()); + ecl_kw_get_data_as_double(kwData, doubleData.data()); + values->insert(values->end(), doubleData.begin(), doubleData.end()); - return true; + result = true; + } } - return false; + return result; } //-------------------------------------------------------------------------------------------------- @@ -206,25 +211,30 @@ bool RifEclipseOutputFileTools::keywordData(ecl_file_type* ecl_file, const QStri //-------------------------------------------------------------------------------------------------- bool RifEclipseOutputFileTools::keywordData(ecl_file_type* ecl_file, const QString& keyword, size_t fileKeywordOccurrence, std::vector* values) { - ecl_kw_type* kwData = ecl_file_iget_named_kw(ecl_file, RiaStringEncodingTools::toNativeEncoded(keyword).data(), static_cast(fileKeywordOccurrence)); - if (kwData) + bool result = false; + +#pragma omp critical(critical_section_keywordData_int) { - size_t numValues = ecl_kw_get_size(kwData); + ecl_kw_type* kwData = ecl_file_iget_named_kw(ecl_file, RiaStringEncodingTools::toNativeEncoded(keyword).data(), static_cast(fileKeywordOccurrence)); + if (kwData) + { + size_t numValues = ecl_kw_get_size(kwData); - std::vector integerData; - integerData.resize(numValues); + std::vector integerData; + integerData.resize(numValues); - ecl_kw_get_memcpy_int_data(kwData, integerData.data()); - values->insert(values->end(), integerData.begin(), integerData.end()); + ecl_kw_get_memcpy_int_data(kwData, integerData.data()); + values->insert(values->end(), integerData.begin(), integerData.end()); - return true; + result = true; + } } - return false; + return result; } //-------------------------------------------------------------------------------------------------- -/// Get first occurrence of file of given type in given list of filenames, as filename or NULL if not found +/// Get first occurrence of file of given type in given list of filenames, as filename or nullptr if not found //-------------------------------------------------------------------------------------------------- QString RifEclipseOutputFileTools::firstFileNameOfType(const QStringList& fileSet, ecl_file_enum fileType) { @@ -263,6 +273,14 @@ QStringList RifEclipseOutputFileTools::filterFileNamesOfType(const QStringList& return fileNames; } +//------------------------------------------------------------------------------------------------------- +/// Check if libecl accepts the file name. libecl refuses to open files with mixed case in the file name. +//------------------------------------------------------------------------------------------------------- +bool RifEclipseOutputFileTools::isValidEclipseFileName(const QString& fileName) +{ + QString fileNameBase = QFileInfo(fileName).completeBaseName(); + return ecl_util_valid_basename(RiaStringEncodingTools::toNativeEncoded(fileNameBase).data()); +} //-------------------------------------------------------------------------------------------------- /// Get set of Eclipse files based on an input file and its path @@ -460,6 +478,52 @@ void RifEclipseOutputFileTools::transferNncFluxData(const ecl_grid_type* grid, } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifEclipseOutputFileTools::isExportedFromIntersect(ecl_file_type* ecl_file) +{ + // This code is taken from ecl_file_get_ecl_version() in ecl_file.cpp + + ecl_kw_type* intehead_kw = ecl_file_iget_named_kw(ecl_file, INTEHEAD_KW, 0); + if (!intehead_kw) return false; + + int int_value = ecl_kw_iget_int(intehead_kw, INTEHEAD_IPROG_INDEX); + if (int_value == INTEHEAD_INTERSECT_VALUE) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +ecl_kw_type* RifEclipseOutputFileTools::createActnumFromPorv(ecl_file_type* ecl_file) +{ + std::string porv_kw("PORV"); + + if (ecl_file_has_kw(ecl_file, porv_kw.data())) + { + ecl_file_view_type* fileView = ecl_file_get_global_view(ecl_file); + + int keywordCount = ecl_file_get_num_named_kw(ecl_file, porv_kw.data()); + for (int index = 0; index < keywordCount; index++) + { + ecl_kw_type* fileKeyword = ecl_file_view_iget_named_kw(fileView, porv_kw.data(), index); + if (fileKeyword) + { + float porvLimit = 0.0f; + + return ecl_kw_alloc_actnum(fileKeyword, porvLimit); + } + } + } + + return nullptr; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h index 6678fa95f0..276e051cd4 100644 --- a/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h +++ b/ApplicationCode/FileInterface/RifEclipseOutputFileTools.h @@ -56,6 +56,7 @@ class RifEclipseOutputFileTools static void timeSteps(ecl_file_type* ecl_file, std::vector* timeSteps, std::vector* daysSinceSimulationStart); + static bool isValidEclipseFileName(const QString& fileName); static bool findSiblingFilesWithSameBaseName(const QString& fileName, QStringList* fileSet); static QString firstFileNameOfType(const QStringList& fileSet, ecl_file_enum fileType); @@ -74,6 +75,9 @@ class RifEclipseOutputFileTools static void transferNncFluxData(const ecl_grid_type* grid, ecl_file_view_type* summaryView, std::vector* waterFlux, std::vector* oilFlux, std::vector* gasFlux); + static bool isExportedFromIntersect(ecl_file_type* ecl_file); + + static ecl_kw_type* createActnumFromPorv(ecl_file_type* ecl_file); private: static void createReportStepsMetaData(std::vector ecl_files, std::vector* reportSteps); diff --git a/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.cpp b/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.cpp index 189d91d175..522949db96 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.cpp +++ b/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.cpp @@ -50,39 +50,6 @@ void RifRestartReportKeywords::appendKeyword(const std::string& keyword, size_t m_keywordNameAndItemCount.push_back(RifKeywordLocation(keyword, itemCount, globalIndex)); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RifRestartReportKeywords::keywordsWithItemCountFactorOf(const std::vector& factorCandidates) -{ - std::vector tmp; - - for (auto uni : uniqueKeywords()) - { - size_t sum = 0; - for (auto loc : objectsForKeyword(uni)) - { - sum += loc.itemCount(); - } - - bool foundMatch = false; - size_t i = 0; - - while (i < factorCandidates.size() && !foundMatch) - { - if (sum > 0 && (sum % factorCandidates[i]) == 0) - { - foundMatch = true; - tmp.push_back(uni); - } - - i++; - } - } - - return tmp; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h b/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h index dec26a1e26..b5b0921a04 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseRestartDataAccess.h @@ -28,7 +28,7 @@ #include -#include "ert/ecl_well/well_info.h" +#include "ert/ecl_well/well_info.hpp" #include "RifReaderInterface.h" @@ -60,7 +60,6 @@ class RifRestartReportKeywords void appendKeyword(const std::string& keyword, size_t itemCount, int globalIndex); - std::vector keywordsWithItemCountFactorOf(const std::vector& factorCandidates); std::vector > keywordsWithAggregatedItemCount(); private: @@ -90,7 +89,7 @@ class RifEclipseRestartDataAccess : public cvf::Object { public: RifEclipseRestartDataAccess(); - virtual ~RifEclipseRestartDataAccess(); + ~RifEclipseRestartDataAccess() override; virtual bool open() = 0; virtual void setRestartFiles(const QStringList& fileSet) = 0; diff --git a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp index 7dc6e8c0f2..2713e12d80 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp +++ b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.cpp @@ -50,7 +50,7 @@ RifEclipseRestartFilesetAccess::~RifEclipseRestartFilesetAccess() ecl_file_close(m_ecl_files[i]); } - m_ecl_files[i] = NULL; + m_ecl_files[i] = nullptr; } } @@ -91,7 +91,7 @@ void RifEclipseRestartFilesetAccess::setRestartFiles(const QStringList& fileSet) for (int i = 0; i < m_fileNames.size(); i++) { - m_ecl_files.push_back(NULL); + m_ecl_files.push_back(nullptr); } CVF_ASSERT(m_fileNames.size() == static_cast(m_ecl_files.size())); @@ -269,7 +269,7 @@ void RifEclipseRestartFilesetAccess::openTimeStep(size_t timeStep) { CVF_ASSERT(timeStep < m_ecl_files.size()); - if (m_ecl_files[timeStep] == NULL) + if (m_ecl_files[timeStep] == nullptr) { int index = static_cast(timeStep); ecl_file_type* ecl_file = ecl_file_open(RiaStringEncodingTools::toNativeEncoded(m_fileNames[index]).data(), ECL_FILE_CLOSE_STREAM); diff --git a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h index a5a68101cf..8f13131a0f 100644 --- a/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseRestartFilesetAccess.h @@ -35,26 +35,26 @@ class RifEclipseRestartFilesetAccess : public RifEclipseRestartDataAccess { public: RifEclipseRestartFilesetAccess(); - virtual ~RifEclipseRestartFilesetAccess(); + ~RifEclipseRestartFilesetAccess() override; - bool open(); - void setRestartFiles(const QStringList& fileSet); - void close(); + bool open() override; + void setRestartFiles(const QStringList& fileSet) override; + void close() override; - void setTimeSteps(const std::vector& timeSteps); - size_t timeStepCount(); + void setTimeSteps(const std::vector& timeSteps) override; + size_t timeStepCount() override; void timeSteps(std::vector* timeSteps, std::vector* daysSinceSimulationStart) override; - std::vector reportNumbers(); + std::vector reportNumbers() override; - void resultNames(QStringList* resultNames, std::vector* resultDataItemCounts); - bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values); + void resultNames(QStringList* resultNames, std::vector* resultDataItemCounts) override; + bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values) override; bool dynamicNNCResults(const ecl_grid_type* grid, size_t timeStep, std::vector* waterFlux, std::vector* oilFlux, std::vector* gasFlux) override; - virtual void readWellData(well_info_type* well_info, bool importCompleteMswData); - virtual int readUnitsType(); + void readWellData(well_info_type* well_info, bool importCompleteMswData) override; + int readUnitsType() override; - virtual std::set availablePhases() const override; + std::set availablePhases() const override; private: void openTimeStep(size_t timeStep); diff --git a/ApplicationCode/FileInterface/RifEclipseSummaryAddress.cpp b/ApplicationCode/FileInterface/RifEclipseSummaryAddress.cpp index 3029884d03..6fed115bd3 100644 --- a/ApplicationCode/FileInterface/RifEclipseSummaryAddress.cpp +++ b/ApplicationCode/FileInterface/RifEclipseSummaryAddress.cpp @@ -20,10 +20,14 @@ #include "RiaStdStringTools.h" +#include "RiuSummaryVectorDescriptionMap.h" + #include +#include #include "cvfAssert.h" + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -35,14 +39,16 @@ RifEclipseSummaryAddress::RifEclipseSummaryAddress(SummaryVarCategory category, m_wellSegmentNumber(-1), m_cellI(-1), m_cellJ(-1), - m_cellK(-1) + m_cellK(-1), + m_aquiferNumber(-1), + m_isErrorResult(false) { - std::tuple ijkTuple; - std::pair reg2regPair; + std::tuple ijkTuple; + std::pair reg2regPair; switch (category) { case SUMMARY_REGION: - m_regionNumber = RiaStdStringTools::toInt(identifiers[INPUT_REGION_NUMBER]); + m_regionNumber = RiaStdStringTools::toInt16(identifiers[INPUT_REGION_NUMBER]); break; case SUMMARY_REGION_2_REGION: reg2regPair = regionToRegionPairFromUiText(identifiers[INPUT_REGION_2_REGION]); @@ -99,28 +105,393 @@ RifEclipseSummaryAddress::RifEclipseSummaryAddress(SummaryVarCategory category, m_quantityName = identifiers[INPUT_VECTOR_NAME]; } +//-------------------------------------------------------------------------------------------------- +/// Column header text format: [:]:[:][....] +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::fromEclipseTextAddress(const std::string& textAddress) +{ + QStringList names = QString().fromStdString(textAddress).split(":"); + + bool isErrorResult = false; + + if (names.size() > 1) + { + QString name = names[0].trimmed(); + if (name.compare("ER", Qt::CaseInsensitive) == 0 || + name.compare("ERR", Qt::CaseInsensitive) == 0|| + name.compare("ERROR", Qt::CaseInsensitive) == 0) + { + isErrorResult = true; + names.pop_front(); + } + } + else if (names.empty()) + { + return RifEclipseSummaryAddress(); + } + + std::string quantityName = names[0].trimmed().toStdString(); + names.pop_front(); + + SummaryVarCategory category = identifyCategory(quantityName); + + RifEclipseSummaryAddress address; + switch (category) + { + case SUMMARY_FIELD: + address = fieldAddress(quantityName); + break; + + case SUMMARY_AQUIFER: + if (names.size() > 0) address = aquiferAddress(quantityName, + RiaStdStringTools::toInt(names[0].toStdString())); + break; + + case SUMMARY_NETWORK: + address = networkAddress(quantityName); + break; + + case SUMMARY_MISC: + address = miscAddress(quantityName); + break; + + case SUMMARY_REGION: + if (names.size() > 0) address = regionAddress(quantityName, + RiaStdStringTools::toInt(names[0].toStdString())); + break; + + case SUMMARY_REGION_2_REGION: + if (names.size() > 0) + { + QStringList regions = names[0].trimmed().split("-"); + if (regions.size() == 2) + { + address = regionToRegionAddress(quantityName, + RiaStdStringTools::toInt(regions[0].toStdString()), + RiaStdStringTools::toInt(regions[1].toStdString())); + } + } + break; + + case SUMMARY_WELL_GROUP: + if (names.size() > 0) address = wellGroupAddress(quantityName, + names[0].toStdString()); + break; + + case SUMMARY_WELL: + if (names.size() > 0) address = wellAddress(quantityName, + names[0].toStdString()); + break; + + case SUMMARY_WELL_COMPLETION: + if (names.size() > 1) + { + QStringList ijk = names[1].trimmed().split(","); + if (ijk.size() == 3) + { + address = wellCompletionAddress(quantityName, + names[0].toStdString(), + RiaStdStringTools::toInt(ijk[0].toStdString()), + RiaStdStringTools::toInt(ijk[1].toStdString()), + RiaStdStringTools::toInt(ijk[2].toStdString())); + } + } + break; + + case SUMMARY_WELL_LGR: + if (names.size() > 1) address = wellLgrAddress(quantityName, + names[0].toStdString(), + names[1].toStdString()); + break; + + case SUMMARY_WELL_COMPLETION_LGR: + if (names.size() > 2) + { + QStringList ijk = names[2].trimmed().split(","); + if (ijk.size() == 3) + { + address = wellCompletionLgrAddress(quantityName, + names[0].toStdString(), + names[1].toStdString(), + RiaStdStringTools::toInt(ijk[0].toStdString()), + RiaStdStringTools::toInt(ijk[1].toStdString()), + RiaStdStringTools::toInt(ijk[2].toStdString())); + } + } + break; + + case SUMMARY_WELL_SEGMENT: + if (names.size() > 1) address = wellSegmentAddress(quantityName, + names[0].toStdString(), + RiaStdStringTools::toInt(names[1].toStdString())); + break; + + case SUMMARY_BLOCK: + if (names.size() > 0) + { + QStringList ijk = names[0].trimmed().split(","); + if (ijk.size() == 3) + { + address = blockAddress(quantityName, + RiaStdStringTools::toInt(ijk[0].toStdString()), + RiaStdStringTools::toInt(ijk[1].toStdString()), + RiaStdStringTools::toInt(ijk[2].toStdString())); + } + } + break; + + case SUMMARY_BLOCK_LGR: + if (names.size() > 1) + { + QStringList ijk = names[1].trimmed().split(","); + if (ijk.size() == 3) + { + address = blockLgrAddress(quantityName, + names[0].toStdString(), + RiaStdStringTools::toInt(ijk[0].toStdString()), + RiaStdStringTools::toInt(ijk[1].toStdString()), + RiaStdStringTools::toInt(ijk[2].toStdString())); + } + } + break; + + case SUMMARY_CALCULATED: + address = calculatedAddress(quantityName); + break; + + case SUMMARY_IMPORTED: + case SUMMARY_INVALID: + default: + break; + } + + if (address.category() == SUMMARY_INVALID || address.category() == SUMMARY_IMPORTED) + { + // Address category not recognized, use complete text address + //QString addr = QString::fromStdString(quantityName) + (!names.empty() ? (":" + names.join(":")) : ""); + QStringList addr = names; + addr.push_front(QString::fromStdString(quantityName)); + address = importedAddress(addr.join(":").toStdString()); + } + + if (isErrorResult) address.setAsErrorResult(); + return address; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress::SummaryVarCategory RifEclipseSummaryAddress::identifyCategory(const std::string& quantityName) +{ + if (quantityName.size() < 3 || quantityName.size() > 8) return SUMMARY_INVALID; + + QRegExp regexp("^[A-Za-z0-9_\\-+#]*$"); + if(!regexp.exactMatch(QString::fromStdString(quantityName))) return SUMMARY_INVALID; + + // First, try to lookup vector in vector table + auto vectorInfo = RiuSummaryVectorDescriptionMap::instance()->vectorInfo(quantityName); + if (vectorInfo.category != SUMMARY_INVALID) return vectorInfo.category; + + // Then check LGR categories + std::string firstTwoLetters = quantityName.substr(0, 2); + + if (firstTwoLetters == "LB") return SUMMARY_BLOCK_LGR; + if (firstTwoLetters == "LC") return SUMMARY_WELL_COMPLETION_LGR; + if (firstTwoLetters == "LW") return SUMMARY_WELL_LGR; + + if (quantityName[0] == 'N') return SUMMARY_NETWORK; + return SUMMARY_INVALID; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::fieldAddress(const std::string& quantityName) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_FIELD; + addr.m_quantityName = quantityName; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::aquiferAddress(const std::string& quantityName, int aquiferNumber) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_AQUIFER; + addr.m_quantityName = quantityName; + addr.m_aquiferNumber = aquiferNumber; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::networkAddress(const std::string& quantityName) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_NETWORK; + addr.m_quantityName = quantityName; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::miscAddress(const std::string& quantityName) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_MISC; + addr.m_quantityName = quantityName; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::regionAddress(const std::string& quantityName, int regionNumber) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_REGION; + addr.m_quantityName = quantityName; + addr.m_regionNumber = regionNumber; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::regionToRegionAddress(const std::string& quantityName, int regionNumber, int region2Number) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_REGION_2_REGION; + addr.m_quantityName = quantityName; + addr.m_regionNumber = regionNumber; + addr.m_regionNumber2 = region2Number; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::wellGroupAddress(const std::string& quantityName, const std::string& wellGroupName) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_WELL_GROUP; + addr.m_quantityName = quantityName; + addr.m_wellGroupName = wellGroupName; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::wellAddress(const std::string& quantityName, const std::string& wellName) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_WELL; + addr.m_quantityName = quantityName; + addr.m_wellName = wellName; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::wellCompletionAddress(const std::string& quantityName, const std::string& wellName, int i, int j, int k) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_WELL_COMPLETION; + addr.m_quantityName = quantityName; + addr.m_wellName = wellName; + addr.m_cellI = i; + addr.m_cellJ = j; + addr.m_cellK = k; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::wellLgrAddress(const std::string& quantityName, const std::string& lgrName, const std::string& wellName) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_WELL_LGR; + addr.m_quantityName = quantityName; + addr.m_lgrName = lgrName; + addr.m_wellName = wellName; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::wellCompletionLgrAddress(const std::string& quantityName, const std::string& lgrName, const std::string& wellName, int i, int j, int k) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_WELL_COMPLETION_LGR; + addr.m_quantityName = quantityName; + addr.m_lgrName = lgrName; + addr.m_wellName = wellName; + addr.m_cellI = i; + addr.m_cellJ = j; + addr.m_cellK = k; + return addr; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifEclipseSummaryAddress RifEclipseSummaryAddress::fieldVarAddress(const std::string& fieldVarName) +RifEclipseSummaryAddress RifEclipseSummaryAddress::wellSegmentAddress(const std::string& quantityName, const std::string& wellName, int segmentNumber) { - RifEclipseSummaryAddress fieldAddr; - fieldAddr.m_variableCategory = SUMMARY_FIELD; - fieldAddr.m_quantityName = fieldVarName; + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_WELL_SEGMENT; + addr.m_quantityName = quantityName; + addr.m_wellName = wellName; + addr.m_wellSegmentNumber = segmentNumber; + return addr; +} - return fieldAddr; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::blockAddress(const std::string& quantityName, int i, int j, int k) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_BLOCK; + addr.m_quantityName = quantityName; + addr.m_cellI = i; + addr.m_cellJ = j; + addr.m_cellK = k; + return addr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifEclipseSummaryAddress RifEclipseSummaryAddress::calculatedCurveAddress(const std::string& curveName) +RifEclipseSummaryAddress RifEclipseSummaryAddress::blockLgrAddress(const std::string& quantityName, const std::string& lgrName, int i, int j, int k) { - RifEclipseSummaryAddress fieldAddr; - fieldAddr.m_variableCategory = SUMMARY_CALCULATED; - fieldAddr.m_quantityName = curveName; + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_BLOCK_LGR; + addr.m_quantityName = quantityName; + addr.m_lgrName = lgrName; + addr.m_cellI = i; + addr.m_cellJ = j; + addr.m_cellK = k; + return addr; +} - return fieldAddr; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::calculatedAddress(const std::string& quantityName) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_CALCULATED; + addr.m_quantityName = quantityName; + return addr; } //-------------------------------------------------------------------------------------------------- @@ -128,11 +499,51 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::calculatedCurveAddress(const //-------------------------------------------------------------------------------------------------- RifEclipseSummaryAddress RifEclipseSummaryAddress::importedAddress(const std::string& quantityName) { - RifEclipseSummaryAddress fieldAddr; - fieldAddr.m_variableCategory = SUMMARY_IMPORTED; - fieldAddr.m_quantityName = quantityName; + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_IMPORTED; + addr.m_quantityName = quantityName; + return addr; +} - return fieldAddr; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifEclipseSummaryAddress::ensembleStatisticsAddress(const std::string& quantityName, + const std::string& dataQuantityName) +{ + RifEclipseSummaryAddress addr; + addr.m_variableCategory = SUMMARY_ENSEMBLE_STATISTICS; + addr.m_quantityName = quantityName + ":" + dataQuantityName; + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifEclipseSummaryAddress::isDependentOnWellName(const RifEclipseSummaryAddress& address) +{ + // clang-format off + if (address.category() == SUMMARY_WELL || + address.category() == SUMMARY_WELL_COMPLETION || + address.category() == SUMMARY_WELL_COMPLETION_LGR || + address.category() == SUMMARY_WELL_LGR || + address.category() == SUMMARY_WELL_SEGMENT) + { + return true; + } + + // clang-format on + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::string RifEclipseSummaryAddress::ensembleStatisticsQuantityName() const +{ + QString qName = QString::fromStdString(m_quantityName); + return qName.split(":")[0].toStdString(); } //-------------------------------------------------------------------------------------------------- @@ -141,66 +552,69 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::importedAddress(const std::st std::string RifEclipseSummaryAddress::uiText() const { std::string text; + + if (m_isErrorResult) text += "ERR:"; + text += m_quantityName; switch(this->category()) { - case RifEclipseSummaryAddress::SUMMARY_REGION: + case SUMMARY_REGION: { text += ":" + std::to_string(this->regionNumber()); } break; - case RifEclipseSummaryAddress::SUMMARY_REGION_2_REGION: + case SUMMARY_REGION_2_REGION: { text += ":" + formatUiTextRegionToRegion(); } break; - case RifEclipseSummaryAddress::SUMMARY_WELL_GROUP: + case SUMMARY_WELL_GROUP: { text += ":" + this->wellGroupName(); } break; - case RifEclipseSummaryAddress::SUMMARY_WELL: + case SUMMARY_WELL: { text += ":" + this->wellName(); } break; - case RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION: + case SUMMARY_WELL_COMPLETION: { text += ":" + this->wellName(); text += ":" + formatUiTextIJK(); } break; - case RifEclipseSummaryAddress::SUMMARY_WELL_LGR: + case SUMMARY_WELL_LGR: { text += ":" + this->lgrName(); text += ":" + this->wellName(); } break; - case RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION_LGR: + case SUMMARY_WELL_COMPLETION_LGR: { text += ":" + this->lgrName(); text += ":" + this->wellName(); text += ":" + formatUiTextIJK(); } break; - case RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT: + case SUMMARY_WELL_SEGMENT: { text += ":" + this->wellName(); text += ":" + std::to_string(this->wellSegmentNumber()); } break; - case RifEclipseSummaryAddress::SUMMARY_BLOCK: + case SUMMARY_BLOCK: { text += ":" + formatUiTextIJK(); } break; - case RifEclipseSummaryAddress::SUMMARY_BLOCK_LGR: + case SUMMARY_BLOCK_LGR: { text += ":" + this->lgrName(); text += ":" + formatUiTextIJK(); } break; - case RifEclipseSummaryAddress::SUMMARY_AQUIFER: + case SUMMARY_AQUIFER: { text += ":" + std::to_string(this->aquiferNumber()); } @@ -217,15 +631,15 @@ std::string RifEclipseSummaryAddress::uiText(RifEclipseSummaryAddress::SummaryId { switch (identifierType) { - case RifEclipseSummaryAddress::INPUT_REGION_NUMBER: return std::to_string(regionNumber()); - case RifEclipseSummaryAddress::INPUT_REGION_2_REGION: return formatUiTextRegionToRegion(); - case RifEclipseSummaryAddress::INPUT_WELL_NAME: return wellName(); - case RifEclipseSummaryAddress::INPUT_WELL_GROUP_NAME: return wellGroupName(); - case RifEclipseSummaryAddress::INPUT_CELL_IJK: return formatUiTextIJK(); - case RifEclipseSummaryAddress::INPUT_LGR_NAME: return lgrName(); - case RifEclipseSummaryAddress::INPUT_SEGMENT_NUMBER: return std::to_string(wellSegmentNumber()); - case RifEclipseSummaryAddress::INPUT_AQUIFER_NUMBER: return std::to_string(aquiferNumber()); - case RifEclipseSummaryAddress::INPUT_VECTOR_NAME: return quantityName(); + case INPUT_REGION_NUMBER: return std::to_string(regionNumber()); + case INPUT_REGION_2_REGION: return formatUiTextRegionToRegion(); + case INPUT_WELL_NAME: return wellName(); + case INPUT_WELL_GROUP_NAME: return wellGroupName(); + case INPUT_CELL_IJK: return formatUiTextIJK(); + case INPUT_LGR_NAME: return lgrName(); + case INPUT_SEGMENT_NUMBER: return std::to_string(wellSegmentNumber()); + case INPUT_AQUIFER_NUMBER: return std::to_string(aquiferNumber()); + case INPUT_VECTOR_NAME: return quantityName(); } return ""; } @@ -235,6 +649,8 @@ std::string RifEclipseSummaryAddress::uiText(RifEclipseSummaryAddress::SummaryId //-------------------------------------------------------------------------------------------------- bool RifEclipseSummaryAddress::isValid() const { + if (m_quantityName.empty()) return false; + switch (category()) { case SUMMARY_INVALID: @@ -303,6 +719,54 @@ bool RifEclipseSummaryAddress::isValid() const return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifEclipseSummaryAddress::hasAccumulatedData() const +{ + if (!isValidEclipseCategory()) return false; + + QString qBaseName = QString::fromStdString(baseQuantityName(quantityName())); + return qBaseName.endsWith("T") || qBaseName.endsWith("TH"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifEclipseSummaryAddress::isValidEclipseCategory() const +{ + switch (category()) + { + case SUMMARY_FIELD: + case SUMMARY_AQUIFER: + case SUMMARY_NETWORK: + case SUMMARY_MISC: + case SUMMARY_REGION: + case SUMMARY_REGION_2_REGION: + case SUMMARY_WELL_GROUP: + case SUMMARY_WELL: + case SUMMARY_WELL_COMPLETION: + case SUMMARY_WELL_LGR: + case SUMMARY_WELL_COMPLETION_LGR: + case SUMMARY_WELL_SEGMENT: + case SUMMARY_BLOCK: + case SUMMARY_BLOCK_LGR: + return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::string RifEclipseSummaryAddress::baseQuantityName(const std::string& quantityName) +{ + QString qBaseName = QString::fromStdString(quantityName); + if (qBaseName.size() == 8) qBaseName.chop(3); + while (qBaseName.endsWith("_")) qBaseName.chop(1); + return qBaseName.toStdString(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -318,14 +782,13 @@ std::string RifEclipseSummaryAddress::formatUiTextIJK() const //-------------------------------------------------------------------------------------------------- std::tuple RifEclipseSummaryAddress::ijkTupleFromUiText(const std::string &s) { - auto firstSep = s.find(','); - auto lastSep = s.find(',', firstSep + 1); - CVF_ASSERT(firstSep != std::string::npos && lastSep != std::string::npos); - auto textI = s.substr(0, firstSep); - auto textJ = s.substr(firstSep + 1, lastSep - firstSep - 1); - auto textK = s.substr(lastSep + 1); + QStringList ijk = QString().fromStdString(s).trimmed().split(QRegExp("[,]")); + + if (ijk.size() != 3) return std::make_tuple(-1, -1, -1); - return std::make_tuple(RiaStdStringTools::toInt(textI), RiaStdStringTools::toInt(textJ), RiaStdStringTools::toInt(textK)); + return std::make_tuple(RiaStdStringTools::toInt(ijk[0].trimmed().toStdString()), + RiaStdStringTools::toInt(ijk[1].trimmed().toStdString()), + RiaStdStringTools::toInt(ijk[2].trimmed().toStdString())); } //-------------------------------------------------------------------------------------------------- @@ -333,21 +796,21 @@ std::tuple RifEclipseSummaryAddress::ijkTupleFromUiText(const std //-------------------------------------------------------------------------------------------------- std::string RifEclipseSummaryAddress::formatUiTextRegionToRegion() const { - return std::to_string(this->regionNumber()) + " -> " + return std::to_string(this->regionNumber()) + " - " + std::to_string(this->regionNumber2()); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::pair RifEclipseSummaryAddress::regionToRegionPairFromUiText(const std::string &s) +std::pair RifEclipseSummaryAddress::regionToRegionPairFromUiText(const std::string &s) { - auto sep = s.find("->"); - CVF_ASSERT(sep != std::string::npos ); - auto textReg = s.substr(0, sep); - auto textReg2 = s.substr(sep + 2); - - return std::make_pair(RiaStdStringTools::toInt(textReg), RiaStdStringTools::toInt(textReg2)); + QStringList r2r = QString().fromStdString(s).trimmed().split(QRegExp("[-]")); + + if (r2r.size() != 2) return std::make_pair((int16_t)-1, (int16_t)-1); + + return std::make_pair(RiaStdStringTools::toInt16(r2r[0].trimmed().toStdString()), + RiaStdStringTools::toInt16(r2r[1].trimmed().toStdString())); } //-------------------------------------------------------------------------------------------------- @@ -430,15 +893,23 @@ bool operator==(const RifEclipseSummaryAddress& first, const RifEclipseSummaryAd } break; } + if (first.isErrorResult() != second.isErrorResult()) return false; return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool operator!=(const RifEclipseSummaryAddress& first, const RifEclipseSummaryAddress& second) +{ + return !operator==(first, second); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool operator<(const RifEclipseSummaryAddress& first, const RifEclipseSummaryAddress& second) { - if(first.category() != second.category()) return first.category() < second.category(); if(first.quantityName() != second.quantityName()) return first.quantityName() < second.quantityName(); switch(first.category()) @@ -515,6 +986,7 @@ bool operator<(const RifEclipseSummaryAddress& first, const RifEclipseSummaryAdd break; } + if (first.isErrorResult() != second.isErrorResult()) return first.isErrorResult() < second.isErrorResult(); return false; } diff --git a/ApplicationCode/FileInterface/RifEclipseSummaryAddress.h b/ApplicationCode/FileInterface/RifEclipseSummaryAddress.h index 6f0231eaf7..e898220568 100644 --- a/ApplicationCode/FileInterface/RifEclipseSummaryAddress.h +++ b/ApplicationCode/FileInterface/RifEclipseSummaryAddress.h @@ -19,9 +19,17 @@ #include #include +#include +#include class QTextStream; + +#define ENSEMBLE_STAT_P10_QUANTITY_NAME "P10" +#define ENSEMBLE_STAT_P50_QUANTITY_NAME "P50" +#define ENSEMBLE_STAT_P90_QUANTITY_NAME "P90" +#define ENSEMBLE_STAT_MEAN_QUANTITY_NAME "MEAN" + //================================================================================================== // // @@ -31,7 +39,7 @@ class RifEclipseSummaryAddress public: // Based on list in ecl_smspec.c and list of types taken from Eclipse Reference Manual ecl_rm_2011.1.pdf - enum SummaryVarCategory + enum SummaryVarCategory : int8_t { SUMMARY_INVALID, SUMMARY_FIELD, @@ -49,7 +57,8 @@ class RifEclipseSummaryAddress SUMMARY_BLOCK, SUMMARY_BLOCK_LGR, SUMMARY_CALCULATED, - SUMMARY_IMPORTED + SUMMARY_IMPORTED, + SUMMARY_ENSEMBLE_STATISTICS }; enum SummaryIdentifierType @@ -75,22 +84,24 @@ class RifEclipseSummaryAddress m_cellI(-1), m_cellJ(-1), m_cellK(-1), - m_aquiferNumber(-1) + m_aquiferNumber(-1), + m_isErrorResult(false) { } RifEclipseSummaryAddress(SummaryVarCategory category, const std::string& quantityName, - int regionNumber, - int regionNumber2, + int16_t regionNumber, + int16_t regionNumber2, const std::string& wellGroupName, const std::string& wellName, - int wellSegmentNumber, + int16_t wellSegmentNumber, const std::string& lgrName, - int cellI, - int cellJ, - int cellK, - int aquiferNumber): + int32_t cellI, + int32_t cellJ, + int32_t cellK, + int16_t aquiferNumber, + bool isErrorResult): m_variableCategory(category), m_quantityName(quantityName), m_regionNumber(regionNumber), @@ -102,7 +113,8 @@ class RifEclipseSummaryAddress m_cellI(cellI), m_cellJ(cellJ), m_cellK(cellK), - m_aquiferNumber(aquiferNumber) + m_aquiferNumber(aquiferNumber), + m_isErrorResult(isErrorResult) { } @@ -111,9 +123,28 @@ class RifEclipseSummaryAddress // Static specialized creation methods - static RifEclipseSummaryAddress fieldVarAddress(const std::string& fieldVarName); - static RifEclipseSummaryAddress calculatedCurveAddress(const std::string& curveName); + static RifEclipseSummaryAddress fromEclipseTextAddress(const std::string& textAddress); + static SummaryVarCategory identifyCategory(const std::string& quantityName); + + static RifEclipseSummaryAddress fieldAddress(const std::string& quantityName); + static RifEclipseSummaryAddress aquiferAddress(const std::string& quantityName, int aquiferNumber); + static RifEclipseSummaryAddress networkAddress(const std::string& quantityName); + static RifEclipseSummaryAddress miscAddress(const std::string& quantityName); + static RifEclipseSummaryAddress regionAddress(const std::string& quantityName, int regionNumber); + static RifEclipseSummaryAddress regionToRegionAddress(const std::string& quantityName, int regionNumber, int region2Number); + static RifEclipseSummaryAddress wellGroupAddress(const std::string& quantityName, const std::string& wellGroupName); + static RifEclipseSummaryAddress wellAddress(const std::string& quantityName, const std::string& wellName); + static RifEclipseSummaryAddress wellCompletionAddress(const std::string& quantityName, const std::string& wellName, int i, int j, int k); + static RifEclipseSummaryAddress wellLgrAddress(const std::string& quantityName, const std::string& lgrName, const std::string& wellName); + static RifEclipseSummaryAddress wellCompletionLgrAddress(const std::string& quantityName, const std::string& lgrName, const std::string& wellName, int i, int j, int k); + static RifEclipseSummaryAddress wellSegmentAddress(const std::string& quantityName, const std::string& wellName, int segmentNumber); + static RifEclipseSummaryAddress blockAddress(const std::string& quantityName, int i, int j, int k); + static RifEclipseSummaryAddress blockLgrAddress(const std::string& quantityName, const std::string& lgrName, int i, int j, int k); + static RifEclipseSummaryAddress calculatedAddress(const std::string& quantityName); static RifEclipseSummaryAddress importedAddress(const std::string& quantityName); + static RifEclipseSummaryAddress ensembleStatisticsAddress(const std::string& quantityName, const std::string& dataQuantityName); + + static bool isDependentOnWellName(const RifEclipseSummaryAddress& address); // Access methods @@ -132,6 +163,8 @@ class RifEclipseSummaryAddress int cellK() const { return m_cellK; } int aquiferNumber() const { return m_aquiferNumber; } + const std::string ensembleStatisticsQuantityName() const; + // Derived properties std::string uiText() const; @@ -141,31 +174,38 @@ class RifEclipseSummaryAddress void setQuantityName(const std::string& quantity) { m_quantityName = quantity; } void setWellName(const std::string& wellName) { m_wellName = wellName; } void setWellGroupName(const std::string& wellGroupName) { m_wellGroupName = wellGroupName; } - void setRegion(int region) { m_regionNumber = region; } - void setAquiferNumber(int aquiferNumber) { m_aquiferNumber = aquiferNumber; } + void setRegion(int region) { m_regionNumber = (int16_t)region; } + void setAquiferNumber(int aquiferNumber) { m_aquiferNumber = (int16_t)aquiferNumber; } -private: + void setAsErrorResult() { m_isErrorResult = true; } + bool isErrorResult() const { return m_isErrorResult; } + bool hasAccumulatedData() const; - std::string formatUiTextIJK() const; - std::tuple ijkTupleFromUiText(const std::string &s); - std::string formatUiTextRegionToRegion() const; - std::pair regionToRegionPairFromUiText(const std::string &s); +private: + bool isValidEclipseCategory() const; + static std::string baseQuantityName(const std::string& quantityName); + std::string formatUiTextIJK() const; + static std::tuple ijkTupleFromUiText(const std::string &s); + std::string formatUiTextRegionToRegion() const; + std::pair regionToRegionPairFromUiText(const std::string &s); - SummaryVarCategory m_variableCategory; std::string m_quantityName; - int m_regionNumber; - int m_regionNumber2; std::string m_wellGroupName; std::string m_wellName; - int m_wellSegmentNumber; std::string m_lgrName; - int m_cellI; - int m_cellJ; - int m_cellK; - int m_aquiferNumber; + int32_t m_cellI; + int32_t m_cellJ; + int32_t m_cellK; + int16_t m_regionNumber; + int16_t m_regionNumber2; + int16_t m_wellSegmentNumber; + int16_t m_aquiferNumber; + SummaryVarCategory m_variableCategory; + bool m_isErrorResult; }; bool operator==(const RifEclipseSummaryAddress& first, const RifEclipseSummaryAddress& second); +bool operator!=(const RifEclipseSummaryAddress& first, const RifEclipseSummaryAddress& second); bool operator<(const RifEclipseSummaryAddress& first, const RifEclipseSummaryAddress& second); diff --git a/ApplicationCode/FileInterface/RifEclipseSummaryTools.cpp b/ApplicationCode/FileInterface/RifEclipseSummaryTools.cpp index bf4201a478..59e1b9a1cc 100644 --- a/ApplicationCode/FileInterface/RifEclipseSummaryTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseSummaryTools.cpp @@ -70,7 +70,7 @@ void RifEclipseSummaryTools::findSummaryFiles(const QString& inputFile, if(myHeaderFile) { (*headerFile) = RiaStringEncodingTools::fromNativeEncoded(myHeaderFile); - util_safe_free(myHeaderFile); + free(myHeaderFile); } if(stringlist_get_size(summary_file_list) > 0) @@ -85,51 +85,6 @@ void RifEclipseSummaryTools::findSummaryFiles(const QString& inputFile, return; } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RifEclipseSummaryTools::hasSummaryFiles(const QString& gridFileName) -{ - QString headerFileName; - QStringList dataFileNames; - RifEclipseSummaryTools::findSummaryFiles(gridFileName, &headerFileName, &dataFileNames); - if (!headerFileName.isEmpty() && dataFileNames.size()) return true; - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QStringList RifEclipseSummaryTools::findSummaryDataFiles(const QString& caseFile) -{ - QStringList fileNames; - - QString path; - QString base; - - findSummaryHeaderFileInfo(caseFile, nullptr, &path, &base, nullptr); - if (path.isEmpty() || base.isEmpty()) return fileNames; - - char* header_file = nullptr; - stringlist_type* summary_file_list = stringlist_alloc_new(); - - ecl_util_alloc_summary_files(RiaStringEncodingTools::toNativeEncoded(path).data(), RiaStringEncodingTools::toNativeEncoded(base).data(), nullptr, &header_file, summary_file_list); - if (stringlist_get_size( summary_file_list ) > 0) - { - for (int i = 0; i < stringlist_get_size(summary_file_list); i++) - { - fileNames.push_back(RiaStringEncodingTools::fromNativeEncoded(stringlist_iget(summary_file_list, i))); - } - } - - util_safe_free(header_file); - stringlist_free(summary_file_list); - - return fileNames; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -155,9 +110,9 @@ QString RifEclipseSummaryTools::findGridCaseFileFromSummaryHeaderFile(const QStr if (caseFile) gridCaseFile = caseFile; - util_safe_free(caseFile); - util_safe_free(myBase); - util_safe_free(myPath); + free(caseFile); + free(myBase); + free(myPath); return RiaFilePathTools::toInternalSeparator(gridCaseFile); } @@ -167,7 +122,7 @@ QString RifEclipseSummaryTools::findGridCaseFileFromSummaryHeaderFile(const QStr //-------------------------------------------------------------------------------------------------- void RifEclipseSummaryTools::dumpMetaData(RifSummaryReaderInterface* readerEclipseSummary) { - std::vector addresses = readerEclipseSummary->allResultAddresses(); + std::set addresses = readerEclipseSummary->allResultAddresses(); for (int category = 0; category < RifEclipseSummaryAddress::SUMMARY_BLOCK_LGR; category++) { @@ -224,8 +179,8 @@ void RifEclipseSummaryTools::findSummaryHeaderFileInfo(const QString& inputFile, if (myBase && base) *base = RiaFilePathTools::toInternalSeparator(myBase); if (isFormatted) *isFormatted = formattedFile; - util_safe_free(myHeaderFile); - util_safe_free(myBase); - util_safe_free(myPath); + free(myHeaderFile); + free(myBase); + free(myPath); } diff --git a/ApplicationCode/FileInterface/RifEclipseSummaryTools.h b/ApplicationCode/FileInterface/RifEclipseSummaryTools.h index 85957737b3..dc24df4c41 100644 --- a/ApplicationCode/FileInterface/RifEclipseSummaryTools.h +++ b/ApplicationCode/FileInterface/RifEclipseSummaryTools.h @@ -36,11 +36,9 @@ class RifEclipseSummaryTools { public: static void findSummaryHeaderFile(const QString& inputFile, QString* headerFile, bool* isFormatted); - static QStringList findSummaryDataFiles(const QString& caseFile); static QString findGridCaseFileFromSummaryHeaderFile(const QString& summaryHeaderFile); static void findSummaryFiles(const QString& inputFile, QString* headerFile, QStringList* dataFiles); - static bool hasSummaryFiles(const QString& gridFileName); static void dumpMetaData(RifSummaryReaderInterface* readerEclipseSummary); private: diff --git a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h index ffecdd6c47..4c7d419c0f 100644 --- a/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h +++ b/ApplicationCode/FileInterface/RifEclipseUnifiedRestartFileAccess.h @@ -26,7 +26,7 @@ class RifEclipseOutputFileTools; //typedef struct ecl_file_struct ecl_file_type; -#include "ert/ecl_well/well_info.h" +#include "ert/ecl_well/well_info.hpp" @@ -39,25 +39,25 @@ class RifEclipseUnifiedRestartFileAccess : public RifEclipseRestartDataAccess { public: RifEclipseUnifiedRestartFileAccess(); - virtual ~RifEclipseUnifiedRestartFileAccess(); + ~RifEclipseUnifiedRestartFileAccess() override; - void setRestartFiles(const QStringList& fileSet); - bool open(); - void close(); + void setRestartFiles(const QStringList& fileSet) override; + bool open() override; + void close() override; - size_t timeStepCount(); + size_t timeStepCount() override; void timeSteps(std::vector* timeSteps, std::vector* daysSinceSimulationStart) override; - std::vector reportNumbers(); + std::vector reportNumbers() override; - void resultNames(QStringList* resultNames, std::vector* resultDataItemCounts); - bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values); + void resultNames(QStringList* resultNames, std::vector* resultDataItemCounts) override; + bool results(const QString& resultName, size_t timeStep, size_t gridCount, std::vector* values) override; bool dynamicNNCResults(const ecl_grid_type* grid, size_t timeStep, std::vector* waterFlux, std::vector* oilFlux, std::vector* gasFlux) override; - virtual void readWellData(well_info_type * well_info, bool importCompleteMswData); - virtual int readUnitsType(); + void readWellData(well_info_type * well_info, bool importCompleteMswData) override; + int readUnitsType() override; - virtual std::set availablePhases() const override; + std::set availablePhases() const override; private: bool openFile(); diff --git a/ApplicationCode/FileInterface/RifEclipseUserDataKeywordTools.cpp b/ApplicationCode/FileInterface/RifEclipseUserDataKeywordTools.cpp index f7fdb4fe78..bf0bed64ca 100644 --- a/ApplicationCode/FileInterface/RifEclipseUserDataKeywordTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseUserDataKeywordTools.cpp @@ -23,6 +23,8 @@ #include "RifEclipseUserDataParserTools.h" +#include + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -151,7 +153,7 @@ bool RifEclipseUserDataKeywordTools::isYearX(const std::string& identifier) //-------------------------------------------------------------------------------------------------- RifEclipseSummaryAddress RifEclipseUserDataKeywordTools::makeAndFillAddress(const std::string quantityName, const std::vector& columnHeaderText) { - RifEclipseSummaryAddress::SummaryVarCategory category = RifEclipseUserDataParserTools::identifyCategory(quantityName); + RifEclipseSummaryAddress::SummaryVarCategory category = RifEclipseSummaryAddress::identifyCategory(quantityName); if (category == RifEclipseSummaryAddress::SUMMARY_INVALID) { @@ -168,6 +170,7 @@ RifEclipseSummaryAddress RifEclipseUserDataKeywordTools::makeAndFillAddress(cons int cellJ = -1; int cellK = -1; int aquiferNumber = -1; + bool isErrorResult = false; switch (category) { @@ -276,7 +279,8 @@ RifEclipseSummaryAddress RifEclipseUserDataKeywordTools::makeAndFillAddress(cons cellI, cellJ, cellK, - aquiferNumber); + aquiferNumber, + isErrorResult); } diff --git a/ApplicationCode/FileInterface/RifEclipseUserDataParserTools.cpp b/ApplicationCode/FileInterface/RifEclipseUserDataParserTools.cpp index 765e69e523..6c61050100 100644 --- a/ApplicationCode/FileInterface/RifEclipseUserDataParserTools.cpp +++ b/ApplicationCode/FileInterface/RifEclipseUserDataParserTools.cpp @@ -116,56 +116,6 @@ std::vector RifEclipseUserDataParserTools::splitLineAndRemoveCommen return words; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RifEclipseSummaryAddress::SummaryVarCategory RifEclipseUserDataParserTools::identifyCategory(const std::string& word) -{ - if (word.size() == 0) return RifEclipseSummaryAddress::SUMMARY_INVALID; - - if (word.size() > 2 && word[0] == 'R' && word[2] == 'F') - { - return RifEclipseSummaryAddress::SUMMARY_REGION_2_REGION; - } - - char firstLetter = word.at(0); - - if (firstLetter == 'A') return RifEclipseSummaryAddress::SUMMARY_AQUIFER; - if (firstLetter == 'B') return RifEclipseSummaryAddress::SUMMARY_BLOCK; - if (firstLetter == 'C') return RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION; - if (firstLetter == 'F') return RifEclipseSummaryAddress::SUMMARY_FIELD; - if (firstLetter == 'G') return RifEclipseSummaryAddress::SUMMARY_WELL_GROUP; - if (firstLetter == 'N') return RifEclipseSummaryAddress::SUMMARY_NETWORK; - if (firstLetter == 'R') return RifEclipseSummaryAddress::SUMMARY_REGION; - if (firstLetter == 'S') return RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT; - if (firstLetter == 'W') return RifEclipseSummaryAddress::SUMMARY_WELL; - - if (word.size() < 2) return RifEclipseSummaryAddress::SUMMARY_INVALID; - - std::string firstTwoLetters = word.substr(0, 2); - - if (firstTwoLetters == "LB") return RifEclipseSummaryAddress::SUMMARY_BLOCK_LGR; - if (firstTwoLetters == "LC") return RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION_LGR; - if (firstTwoLetters == "LW") return RifEclipseSummaryAddress::SUMMARY_WELL_LGR; - - return RifEclipseSummaryAddress::SUMMARY_INVALID; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RifEclipseUserDataParserTools::findFirstNonEmptyEntryIndex(std::vector& list) -{ - for (size_t i = 0; i < list.size(); i++) - { - if (!list[i].empty()) - { - return i; - } - } - return list.size(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -530,33 +480,6 @@ bool RifEclipseUserDataParserTools::isFixedWidthHeader(const std::string& lines) return false; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RifEclipseUserDataParserTools::hasCompleteDataForAllHeaderColumns(const std::string& lines) -{ - std::stringstream streamData(lines); - - bool headerDataComplete = true; - { - auto lines = RifEclipseUserDataParserTools::findValidHeaderLines(streamData); - if (lines.size() > 0) - { - size_t wordsFirstLine = lines[0].size(); - - for (auto line : lines) - { - if (wordsFirstLine != line.size()) - { - headerDataComplete = false; - } - } - } - } - - return headerDataComplete; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -920,7 +843,7 @@ bool RifEclipseUserDataParserTools::isScalingText(const std::string& word) //-------------------------------------------------------------------------------------------------- std::string Column::columnName() const { - return summaryAddress.quantityName(); + return summaryAddress.uiText(); } //-------------------------------------------------------------------------------------------------- @@ -940,9 +863,9 @@ size_t Column::itemCount() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Column Column::createColumnInfoFromRsmData(const std::string& quantity, const std::string& unit, const RifEclipseSummaryAddress& adr) +Column Column::createColumnInfoFromRsmData(const std::string& quantity, const std::string& unit, const RifEclipseSummaryAddress& addr) { - Column ci(adr, unit); + Column ci(addr, unit); if (RifEclipseUserDataKeywordTools::isDate(quantity)) { @@ -968,6 +891,24 @@ Column Column::createColumnInfoFromCsvData(const RifEclipseSummaryAddress& addr, return col; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector Column::qDateTimeValues() const +{ + std::vector output; + for (auto t : dateTimeValues) output.push_back(RiaQDateTimeTools::fromTime_t(t)); + return output; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int TableData::dateTimeColumnIndex() const +{ + return m_dateTimeColumnIndex; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/FileInterface/RifEclipseUserDataParserTools.h b/ApplicationCode/FileInterface/RifEclipseUserDataParserTools.h index 3d76c5e812..f73dadfe72 100644 --- a/ApplicationCode/FileInterface/RifEclipseUserDataParserTools.h +++ b/ApplicationCode/FileInterface/RifEclipseUserDataParserTools.h @@ -60,7 +60,7 @@ class Column size_t itemCount() const; public: - static Column createColumnInfoFromRsmData(const std::string& quantity, const std::string& unit, const RifEclipseSummaryAddress& adr); + static Column createColumnInfoFromRsmData(const std::string& quantity, const std::string& unit, const RifEclipseSummaryAddress& addr); static Column createColumnInfoFromCsvData(const RifEclipseSummaryAddress& addr, const std::string& unit); RifEclipseSummaryAddress summaryAddress; @@ -71,7 +71,10 @@ class Column // Data containers std::vector values; std::vector textValues; - std::vector dateTimeValues; + //std::vector dateTimeValues; + std::vector dateTimeValues; + + std::vector qDateTimeValues() const; }; @@ -89,8 +92,17 @@ class TableData const std::vector& columnInfos) : m_origin(origin), m_startDate(startDate), + m_dateTimeColumnIndex(-1), m_columnInfos(columnInfos) { + for (size_t i = 0; i < columnInfos.size(); i++) + { + if (columnInfos[i].dataType == Column::DATETIME) + { + m_dateTimeColumnIndex = (int)i; + break; + } + } } std::string origin() const @@ -113,11 +125,13 @@ class TableData return m_columnInfos; } + int dateTimeColumnIndex() const; QDateTime findFirstDate() const; private: std::string m_origin; std::string m_startDate; + int m_dateTimeColumnIndex; std::vector m_columnInfos; }; @@ -131,9 +145,7 @@ class RifEclipseUserDataParserTools static bool isLineSkippable(const std::string& line); static bool isAComment(const std::string& word); static std::vector splitLineAndRemoveComments(const std::string& line); - static RifEclipseSummaryAddress::SummaryVarCategory identifyCategory(const std::string& word); static std::vector splitLineToDoubles(const std::string& line); - static size_t findFirstNonEmptyEntryIndex(std::vector& list); static bool keywordParser(const std::string& line, std::string& origin, std::string& dateFormat, std::string& startDate); static bool isANumber(const std::string& line); static std::vector headerReader(std::stringstream& streamData, std::string& line); @@ -148,11 +160,10 @@ class RifEclipseUserDataParserTools // Fixed width functions static bool isFixedWidthHeader(const std::string& lines); - static bool hasCompleteDataForAllHeaderColumns(const std::string& lines); - static std::vector columnInfoForFixedColumnWidth(std::stringstream& streamData); + static std::vector columnInfoForFixedColumnWidth(std::stringstream& streamData); static std::vector findValidHeaderLines(std::stringstream& streamData); static std::vector> splitIntoColumnHeaders(const std::vector& headerLines); - static std::vector columnInfoFromColumnHeaders(const std::vector>& columnData); + static std::vector columnInfoFromColumnHeaders(const std::vector>& columnData); static std::vector columnIndexForWords(const std::string& line); static std::vector mergeEqualTimeSteps(const std::vector& tables); diff --git a/ApplicationCode/FileInterface/RifElementPropertyReader.h b/ApplicationCode/FileInterface/RifElementPropertyReader.h index 34b6508d2f..fc9227447b 100644 --- a/ApplicationCode/FileInterface/RifElementPropertyReader.h +++ b/ApplicationCode/FileInterface/RifElementPropertyReader.h @@ -37,7 +37,7 @@ class RifElementPropertyReader : public cvf::Object { public: RifElementPropertyReader(const std::vector& elementIdxToId); - virtual ~RifElementPropertyReader(); + ~RifElementPropertyReader() override; void addFile(const std::string& fileName); void removeFile(const std::string& fileName); diff --git a/ApplicationCode/FileInterface/RifEnsembleStatisticsReader.cpp b/ApplicationCode/FileInterface/RifEnsembleStatisticsReader.cpp new file mode 100644 index 0000000000..8e57ac02bd --- /dev/null +++ b/ApplicationCode/FileInterface/RifEnsembleStatisticsReader.cpp @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RifEnsembleStatisticsReader.h" + +#include "RimEnsembleStatisticsCase.h" + + +static const std::vector EMPTY_TIME_STEPS_VECTOR; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEnsembleStatisticsReader::RifEnsembleStatisticsReader(RimEnsembleStatisticsCase* ensStatCase) +{ + CVF_ASSERT(ensStatCase); + + m_ensembleStatCase = ensStatCase; + + m_allResultAddresses = std::set( + { + RifEclipseSummaryAddress::ensembleStatisticsAddress(ENSEMBLE_STAT_P10_QUANTITY_NAME, ""), + RifEclipseSummaryAddress::ensembleStatisticsAddress(ENSEMBLE_STAT_P50_QUANTITY_NAME, ""), + RifEclipseSummaryAddress::ensembleStatisticsAddress(ENSEMBLE_STAT_P90_QUANTITY_NAME, ""), + RifEclipseSummaryAddress::ensembleStatisticsAddress(ENSEMBLE_STAT_MEAN_QUANTITY_NAME, "") + }); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RifEnsembleStatisticsReader::timeSteps(const RifEclipseSummaryAddress& resultAddress) const +{ + if (!validateAddress(resultAddress)) return EMPTY_TIME_STEPS_VECTOR; + return m_ensembleStatCase->timeSteps(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifEnsembleStatisticsReader::values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const +{ + if (!validateAddress(resultAddress)) return false; + + const std::vector* sourceData = nullptr; + auto quantityName = resultAddress.ensembleStatisticsQuantityName(); + + if (quantityName == ENSEMBLE_STAT_P10_QUANTITY_NAME) sourceData = &m_ensembleStatCase->p10(); + else if (quantityName == ENSEMBLE_STAT_P50_QUANTITY_NAME) sourceData = &m_ensembleStatCase->p50(); + else if (quantityName == ENSEMBLE_STAT_P90_QUANTITY_NAME) sourceData = &m_ensembleStatCase->p90(); + else if (quantityName == ENSEMBLE_STAT_MEAN_QUANTITY_NAME) sourceData = &m_ensembleStatCase->mean(); + + if (!sourceData) return false; + + values->clear(); + values->reserve(sourceData->size()); + for (auto val : *sourceData) values->push_back(val); + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::string RifEnsembleStatisticsReader::unitName(const RifEclipseSummaryAddress& resultAddress) const +{ + return ""; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifEnsembleStatisticsReader::validateAddress(const RifEclipseSummaryAddress& address) const +{ + return address.category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS && + !address.quantityName().empty(); +} diff --git a/ApplicationCode/FileInterface/RifEnsembleStatisticsReader.h b/ApplicationCode/FileInterface/RifEnsembleStatisticsReader.h new file mode 100644 index 0000000000..715754d5bc --- /dev/null +++ b/ApplicationCode/FileInterface/RifEnsembleStatisticsReader.h @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "RifEclipseSummaryAddress.h" +#include "RifSummaryReaderInterface.h" + +class RimEnsembleStatisticsCase; + + +//================================================================================================== +/// +//================================================================================================== +class RifEnsembleStatisticsReader : public RifSummaryReaderInterface +{ +public: + RifEnsembleStatisticsReader(RimEnsembleStatisticsCase* ensStatCase); + + const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; + bool values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const override; + std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; + +private: + bool validateAddress(const RifEclipseSummaryAddress& address) const; + +private: + RimEnsembleStatisticsCase * m_ensembleStatCase; +}; diff --git a/ApplicationCode/FileInterface/RifFileParseTools.cpp b/ApplicationCode/FileInterface/RifFileParseTools.cpp index 9f7e88c966..b83094b4c0 100644 --- a/ApplicationCode/FileInterface/RifFileParseTools.cpp +++ b/ApplicationCode/FileInterface/RifFileParseTools.cpp @@ -22,9 +22,22 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QStringList RifFileParseTools::splitLineAndTrim(const QString& line, const QString& separator) +QStringList RifFileParseTools::splitLineAndTrim(const QString& line, const QString& separator, bool skipEmptyParts) { - QStringList cols = line.split(separator); + QStringList cols = line.trimmed().split(separator, skipEmptyParts ? QString::SkipEmptyParts : QString::KeepEmptyParts); + for (QString& col : cols) + { + col = col.trimmed(); + } + return cols; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RifFileParseTools::splitLineAndTrim(const QString& line, const QRegExp& regexp, bool skipEmptyParts) +{ + QStringList cols = line.trimmed().split(regexp, skipEmptyParts ? QString::SkipEmptyParts : QString::KeepEmptyParts); for (QString& col : cols) { col = col.trimmed(); diff --git a/ApplicationCode/FileInterface/RifFileParseTools.h b/ApplicationCode/FileInterface/RifFileParseTools.h index 1ad6b2724f..68a4da9e8b 100644 --- a/ApplicationCode/FileInterface/RifFileParseTools.h +++ b/ApplicationCode/FileInterface/RifFileParseTools.h @@ -20,7 +20,7 @@ #include #include - +#include //================================================================================================== /// @@ -28,7 +28,8 @@ class RifFileParseTools { public: - static QStringList splitLineAndTrim(const QString& line, const QString& separator); + static QStringList splitLineAndTrim(const QString& line, const QString& separator, bool skipEmptyParts = false); + static QStringList splitLineAndTrim(const QString& line, const QRegExp& regexp, bool skipEmptyParts = false); }; //================================================================================================== diff --git a/ApplicationCode/FileInterface/RifHdf5Reader.cpp b/ApplicationCode/FileInterface/RifHdf5Reader.cpp index 6e52a3d23f..23a7bb5188 100644 --- a/ApplicationCode/FileInterface/RifHdf5Reader.cpp +++ b/ApplicationCode/FileInterface/RifHdf5Reader.cpp @@ -397,30 +397,6 @@ std::vector RifHdf5Reader::getSubGroupNames(H5::H5File file, std::s -//-------------------------------------------------------------------------------------------------- -/// Intended for finding all timesteps of one SourSimRL result file -//-------------------------------------------------------------------------------------------------- -std::vector RifHdf5Reader::getStepTimeValues(H5::H5File file, std::string baseGroupName) const -{ - std::vector subGroupNames = getSubGroupNames(file, baseGroupName); - std::vector stepTimeValues; - - for (std::vector::iterator it = subGroupNames.begin(); it != subGroupNames.end(); it++) - { - if (it->find("Timestep_") != std::string::npos) - { - std::string groupName = baseGroupName + *it; - - double timestep_value = getDoubleAttribute(file, groupName, "timestep"); - - stepTimeValues.push_back(timestep_value); - } - } - - return stepTimeValues; -} - - //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/FileInterface/RifHdf5Reader.h b/ApplicationCode/FileInterface/RifHdf5Reader.h index f3af15f3f2..a8eefef0e8 100644 --- a/ApplicationCode/FileInterface/RifHdf5Reader.h +++ b/ApplicationCode/FileInterface/RifHdf5Reader.h @@ -36,7 +36,7 @@ class RifHdf5Reader : public RifHdf5ReaderInterface virtual ~RifHdf5Reader(); std::vector timeSteps() const override; - virtual QStringList propertyNames() const override; + QStringList propertyNames() const override; bool dynamicResult(const QString& result, size_t stepIndex, std::vector* values) const override; private: @@ -51,7 +51,6 @@ class RifHdf5Reader : public RifHdf5ReaderInterface std::string getStringAttribute(H5::H5File file, std::string groupName, std::string attributeName) const; std::vector getSubGroupNames(H5::H5File file, std::string baseGroupName) const; - std::vector getStepTimeValues(H5::H5File file, std::string baseGroupName) const; std::vector getResultNames(H5::H5File file, std::string baseGroupName) const; void getElementResultValues(H5::H5File file, std::string groupName, std::vector* resultValues) const; diff --git a/ApplicationCode/FileInterface/RifJsonEncodeDecode.cpp b/ApplicationCode/FileInterface/RifJsonEncodeDecode.cpp index 99ddfcacfb..6b6871f3ac 100644 --- a/ApplicationCode/FileInterface/RifJsonEncodeDecode.cpp +++ b/ApplicationCode/FileInterface/RifJsonEncodeDecode.cpp @@ -60,10 +60,17 @@ void JsonReader::dumpToFile(std::vector& points, QString filePath) #endif -QString Json::encode(const QMap &map) +QString Json::encode(const QMap& map, bool prettify) { QScriptEngine engine; - engine.evaluate("function toString() { return JSON.stringify(this) }"); + if (prettify) + { + engine.evaluate("function toString() { return JSON.stringify(this, null, ' ') }"); + } + else + { + engine.evaluate("function toString() { return JSON.stringify(this) }"); + } QScriptValue toString = engine.globalObject().property("toString"); QScriptValue obj = encodeInner(map, &engine); diff --git a/ApplicationCode/FileInterface/RifJsonEncodeDecode.h b/ApplicationCode/FileInterface/RifJsonEncodeDecode.h index 318d09116b..c7f9919149 100644 --- a/ApplicationCode/FileInterface/RifJsonEncodeDecode.h +++ b/ApplicationCode/FileInterface/RifJsonEncodeDecode.h @@ -53,7 +53,7 @@ class Json { public: Json() {}; - QString encode(const QMap &map); + QString encode(const QMap& map, bool prettify); QMap decode(const QString &jsonStr); private: diff --git a/ApplicationCode/FileInterface/RifKeywordVectorUserData.cpp b/ApplicationCode/FileInterface/RifKeywordVectorUserData.cpp index b6c9e6403a..218580f901 100644 --- a/ApplicationCode/FileInterface/RifKeywordVectorUserData.cpp +++ b/ApplicationCode/FileInterface/RifKeywordVectorUserData.cpp @@ -176,9 +176,10 @@ bool RifKeywordVectorUserData::parse(const QString& data, const QString& customW -1, -1, -1, - -1); + -1, + false); - m_allResultAddresses.push_back(addr); + m_allResultAddresses.insert(addr); m_mapFromAddressToTimeIndex[addr] = timeStepIndexIterator->second; m_mapFromAddressToVectorIndex[addr] = i; diff --git a/ApplicationCode/FileInterface/RifKeywordVectorUserData.h b/ApplicationCode/FileInterface/RifKeywordVectorUserData.h index cf1f1fa607..92580839af 100644 --- a/ApplicationCode/FileInterface/RifKeywordVectorUserData.h +++ b/ApplicationCode/FileInterface/RifKeywordVectorUserData.h @@ -40,13 +40,13 @@ class RifKeywordVectorUserData : public RifSummaryReaderInterface { public: RifKeywordVectorUserData(); - ~RifKeywordVectorUserData(); + ~RifKeywordVectorUserData() override; bool parse(const QString& data, const QString& customWellName); - virtual const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; + const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; - virtual bool values(const RifEclipseSummaryAddress& resultAddress, + bool values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const override; std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; diff --git a/ApplicationCode/FileInterface/RifPerforationIntervalReader.cpp b/ApplicationCode/FileInterface/RifPerforationIntervalReader.cpp index 93d70b6210..8b0b9fb868 100644 --- a/ApplicationCode/FileInterface/RifPerforationIntervalReader.cpp +++ b/ApplicationCode/FileInterface/RifPerforationIntervalReader.cpp @@ -80,7 +80,7 @@ void RifPerforationIntervalReader::readFileIntoMap(const QString& filePath, std: if (line.startsWith("WELLNAME")) { // Save current well name - if (parts.size() == 2) + if (parts.size() > 1) { wellName = parts[1].trimmed(); } diff --git a/ApplicationCode/FileInterface/RifReaderEclipseInput.h b/ApplicationCode/FileInterface/RifReaderEclipseInput.h index 7e78c7fe93..3e9f872a16 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseInput.h +++ b/ApplicationCode/FileInterface/RifReaderEclipseInput.h @@ -29,11 +29,11 @@ class RifReaderEclipseInput : public RifReaderInterface { public: RifReaderEclipseInput(); - virtual ~RifReaderEclipseInput(); + ~RifReaderEclipseInput() override; // Virtual interface implementation - virtual bool open(const QString& fileName, RigEclipseCaseData* eclipseCase); + bool open(const QString& fileName, RigEclipseCaseData* eclipseCase) override; - virtual bool staticResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector* values ) { return false; } - virtual bool dynamicResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector* values ) { return false; } + bool staticResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector* values ) override { return false; } + bool dynamicResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector* values ) override { return false; } }; diff --git a/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp b/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp index 35543a58c8..47b434f81f 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp +++ b/ApplicationCode/FileInterface/RifReaderEclipseOutput.cpp @@ -51,6 +51,7 @@ #include "ert/ecl/ecl_nnc_data.h" #include +#include #include // Needed for HUGE_VAL on Linux #include @@ -361,6 +362,14 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigEclipseCaseData* e progInfo.setProgressDescription("Reading Grid"); + if (!RifEclipseOutputFileTools::isValidEclipseFileName(fileName)) + { + QString errorMessage = QFileInfo(fileName).fileName() + QString(" is not a valid Eclipse file name.\n" + "Please make sure the file does not contain a mix of upper and lower case letters."); + RiaLogging::error(errorMessage); + return false; + } + // Get set of files QStringList fileSet; if (!RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(fileName, &fileSet)) return false; @@ -373,9 +382,18 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigEclipseCaseData* e // Keep the set of files of interest m_filesWithSameBaseName = fileSet; + openInitFile(); + // Read geometry // Todo: Needs to check existence of file before calling ert, else it will abort - ecl_grid_type * mainEclGrid = ecl_grid_alloc( RiaStringEncodingTools::toNativeEncoded(fileName).data() ); + ecl_grid_type* mainEclGrid = createMainGrid(); + if (!mainEclGrid) + { + QString errorMessage = QString(" Failed to create a main grid from file\n%1").arg(m_fileName); + RiaLogging::error(errorMessage); + + return false; + } progInfo.incrementProgress(); @@ -405,7 +423,7 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigEclipseCaseData* e // Build results meta data progInfo.setProgressDescription("Reading Result index"); progInfo.setNextProgressIncrement(25); - buildMetaData(); + buildMetaData(mainEclGrid); progInfo.incrementProgress(); if (isNNCsEnabled()) @@ -801,7 +819,7 @@ bool RifReaderEclipseOutput::readActiveCellInfo() //-------------------------------------------------------------------------------------------------- /// Build meta data - get states and results info //-------------------------------------------------------------------------------------------------- -void RifReaderEclipseOutput::buildMetaData() +void RifReaderEclipseOutput::buildMetaData(ecl_grid_type* grid) { CVF_ASSERT(m_eclipseCase); CVF_ASSERT(m_filesWithSameBaseName.size() > 0); @@ -854,30 +872,47 @@ void RifReaderEclipseOutput::buildMetaData() fractureModelResults->setTimeStepInfos(resIndex, timeStepInfos); } } + } + + progInfo.incrementProgress(); + openInitFile(); + + // Unit system + { // Default units type is METRIC RiaEclipseUnitTools::UnitSystem unitsType = RiaEclipseUnitTools::UNITS_METRIC; + int unitsTypeValue; + + if (m_dynamicResultsAccess.notNull()) { - int unitsTypeValue = m_dynamicResultsAccess->readUnitsType(); - if (unitsTypeValue == 2) + unitsTypeValue = m_dynamicResultsAccess->readUnitsType(); + } + else + { + if (m_ecl_init_file) { - unitsType = RiaEclipseUnitTools::UNITS_FIELD; + unitsTypeValue = RifEclipseOutputFileTools::readUnitsType(m_ecl_init_file); } - else if (unitsTypeValue == 3) + else { - unitsType = RiaEclipseUnitTools::UNITS_LAB; + unitsTypeValue = ecl_grid_get_unit_system(grid); } } + if (unitsTypeValue == 2) + { + unitsType = RiaEclipseUnitTools::UNITS_FIELD; + } + else if (unitsTypeValue == 3) + { + unitsType = RiaEclipseUnitTools::UNITS_LAB; + } m_eclipseCase->setUnitsType(unitsType); } progInfo.incrementProgress(); - openInitFile(); - - progInfo.incrementProgress(); - if (m_ecl_init_file) { QStringList resultNames; @@ -1034,7 +1069,7 @@ bool RifReaderEclipseOutput::dynamicResult(const QString& result, RiaDefines::Po size_t indexOnFile = timeStepIndexOnFile(stepIndex); std::vector fileValues; - if (!m_dynamicResultsAccess->results(result, indexOnFile, m_eclipseCase->mainGrid()->gridCount(), &fileValues)) + if (!m_dynamicResultsAccess->results(result, indexOnFile, m_eclipseCase->mainGrid()->gridCountOnFile(), &fileValues)) { return false; } @@ -1323,7 +1358,7 @@ class WellResultPointHasSubCellConnectionCalculator public: explicit WellResultPointHasSubCellConnectionCalculator(const RigMainGrid* mainGrid, well_state_type* ert_well_state): m_mainGrid(mainGrid) { - int lastGridNr = static_cast(m_mainGrid->gridCount()) - 1; + int lastGridNr = static_cast(m_mainGrid->gridCountOnFile()) - 1; for ( int gridNr = lastGridNr; gridNr >= 0; --gridNr ) { @@ -1379,8 +1414,6 @@ class WellResultPointHasSubCellConnectionCalculator { if (gridCellIndex == cvf::UNDEFINED_SIZE_T) return; - size_t reservoirCellIdx = m_mainGrid->reservoirCellIndexByGridAndGridLocalCellIndex(gridIndex, gridCellIndex); - // Traverse parent gridcells, and add them to the map while ( gridIndex > 0 ) // is lgr @@ -2158,6 +2191,36 @@ bool RifReaderEclipseOutput::isEclipseAndSoursimTimeStepsEqual(const QDateTime& return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +ecl_grid_type* RifReaderEclipseOutput::createMainGrid() const +{ + ecl_grid_type* mainEclGrid = nullptr; + + { + if (m_ecl_init_file && RifEclipseOutputFileTools::isExportedFromIntersect(m_ecl_init_file)) + { + ecl_kw_type* actnumFromPorv = RifEclipseOutputFileTools::createActnumFromPorv(m_ecl_init_file); + if (actnumFromPorv) + { + int* actnum_values = ecl_kw_get_int_ptr(actnumFromPorv); + + mainEclGrid = ecl_grid_alloc_ext_actnum(RiaStringEncodingTools::toNativeEncoded(m_fileName).data(), actnum_values); + + ecl_kw_free(actnumFromPorv); + } + } + + if (!mainEclGrid) + { + mainEclGrid = ecl_grid_alloc(RiaStringEncodingTools::toNativeEncoded(m_fileName).data()); + } + } + + return mainEclGrid; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -2179,6 +2242,8 @@ void RifReaderEclipseOutput::extractResultValuesBasedOnPorosityModel(RiaDefines: for (size_t i = 0; i < m_eclipseCase->mainGrid()->gridCount(); i++) { + if(m_eclipseCase->mainGrid()->gridByIndex(i)->isTempGrid()) continue; + size_t matrixActiveCellCount = 0; size_t fractureActiveCellCount = 0; diff --git a/ApplicationCode/FileInterface/RifReaderEclipseOutput.h b/ApplicationCode/FileInterface/RifReaderEclipseOutput.h index 59b28752e9..c0c06044c8 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseOutput.h +++ b/ApplicationCode/FileInterface/RifReaderEclipseOutput.h @@ -51,16 +51,16 @@ class RifReaderEclipseOutput : public RifReaderInterface { public: RifReaderEclipseOutput(); - virtual ~RifReaderEclipseOutput(); + ~RifReaderEclipseOutput() override; - bool open(const QString& fileName, RigEclipseCaseData* eclipseCase); + bool open(const QString& fileName, RigEclipseCaseData* eclipseCase) override; void setHdf5FileName(const QString& fileName); void setFileDataAccess(RifEclipseRestartDataAccess* restartDataAccess); virtual bool openAndReadActiveCellData(const QString& fileName, const std::vector& mainCaseTimeSteps, RigEclipseCaseData* eclipseCase); - bool staticResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector* values); - bool dynamicResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector* values); + bool staticResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector* values) override; + bool dynamicResult(const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector* values) override; void sourSimRlResult(const QString& result, size_t stepIndex, std::vector* values); std::vector allTimeSteps() const; @@ -68,11 +68,11 @@ class RifReaderEclipseOutput : public RifReaderInterface static bool transferGeometry(const ecl_grid_type* mainEclGrid, RigEclipseCaseData* eclipseCase); static void transferCoarseningInfo(const ecl_grid_type* eclGrid, RigGridBase* grid); - virtual std::set availablePhases() const override; + std::set availablePhases() const override; private: bool readActiveCellInfo(); - void buildMetaData(); + void buildMetaData(ecl_grid_type* grid); void readWellCells(const ecl_grid_type* mainEclGrid, bool importCompleteMswData); std::string ertGridName( size_t gridNr ); @@ -95,6 +95,8 @@ class RifReaderEclipseOutput : public RifReaderInterface static bool isEclipseAndSoursimTimeStepsEqual(const QDateTime& eclipseDateTime, const QDateTime& sourSimDateTime); + ecl_grid_type* createMainGrid() const; + private: QString m_fileName; // Name of file used to start accessing Eclipse output files QStringList m_filesWithSameBaseName; // Set of files in filename's path with same base name as filename diff --git a/ApplicationCode/FileInterface/RifReaderEclipseRft.cpp b/ApplicationCode/FileInterface/RifReaderEclipseRft.cpp index 639ed1cb05..2171f8809f 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseRft.cpp +++ b/ApplicationCode/FileInterface/RifReaderEclipseRft.cpp @@ -246,8 +246,8 @@ void RifReaderEclipseRft::cellIndices(const RifEclipseRftAddress& rftAddress, st int i, j, k; ecl_rft_node_iget_ijk(node, cellIdx, &i, &j, &k); - caf::VecIjk index( (size_t)i, (size_t)j, (size_t)k ); - indices->push_back(index); + caf::VecIjk ijk( (size_t)i, (size_t)j, (size_t)k ); + indices->push_back(ijk); } } diff --git a/ApplicationCode/FileInterface/RifReaderEclipseRft.h b/ApplicationCode/FileInterface/RifReaderEclipseRft.h index f082dcac12..373d814ac1 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseRft.h +++ b/ApplicationCode/FileInterface/RifReaderEclipseRft.h @@ -42,7 +42,7 @@ class RifReaderEclipseRft : public cvf::Object { public: RifReaderEclipseRft(const QString& fileName); - ~RifReaderEclipseRft(); + ~RifReaderEclipseRft() override; const std::vector& eclipseRftAddresses(); void values(const RifEclipseRftAddress& rftAddress, std::vector* values); diff --git a/ApplicationCode/FileInterface/RifReaderEclipseSummary.cpp b/ApplicationCode/FileInterface/RifReaderEclipseSummary.cpp index 37a2bda0a3..a7a2eb7b4d 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseSummary.cpp +++ b/ApplicationCode/FileInterface/RifReaderEclipseSummary.cpp @@ -42,10 +42,15 @@ std::vector getTimeSteps(ecl_sum_type* ecl_sum) if (ecl_sum) { - for (int time_index = 0; time_index < ecl_sum_get_data_length(ecl_sum); time_index++) + time_t_vector_type* steps = ecl_sum_alloc_time_vector(ecl_sum, false); + + if (steps) { - time_t sim_time = ecl_sum_iget_sim_time(ecl_sum, time_index); - timeSteps.push_back(sim_time); + for (int i = 0; i < time_t_vector_size(steps); i++) + { + timeSteps.push_back(time_t_vector_iget(steps, i)); + } + free(steps); } } return timeSteps; @@ -72,8 +77,14 @@ ecl_sum_type* openEclSum(const QString& inHeaderFileName, bool includeRestartFil stringlist_append_copy(dataFiles, RiaStringEncodingTools::toNativeEncoded(dataFileNames[i]).data()); } + bool lazyLoad = true; std::string itemSeparatorInVariableNames = ":"; - ecl_sum_type* ecl_sum = ecl_sum_fread_alloc(RiaStringEncodingTools::toNativeEncoded(headerFileName).data(), dataFiles, itemSeparatorInVariableNames.data(), includeRestartFiles); + ecl_sum_type* ecl_sum = ecl_sum_fread_alloc(RiaStringEncodingTools::toNativeEncoded(headerFileName).data(), + dataFiles, + itemSeparatorInVariableNames.data(), + includeRestartFiles, + lazyLoad, + ECL_FILE_CLOSE_STREAM); stringlist_free(dataFiles); @@ -94,7 +105,7 @@ RifReaderEclipseSummary::RifReaderEclipseSummary() : m_ecl_sum(nullptr), m_ecl_SmSpec(nullptr) { - + m_valuesCache.reset(new ValuesCache()); } //-------------------------------------------------------------------------------------------------- @@ -114,7 +125,7 @@ RifReaderEclipseSummary::~RifReaderEclipseSummary() //-------------------------------------------------------------------------------------------------- bool RifReaderEclipseSummary::open(const QString& headerFileName, bool includeRestartFiles) { - assert(m_ecl_sum == NULL); + assert(m_ecl_sum == nullptr); m_ecl_sum = openEclSum(headerFileName, includeRestartFiles); @@ -217,8 +228,7 @@ RifRestartFileInfo RifReaderEclipseSummary::getFileInfo(const QString& headerFil //-------------------------------------------------------------------------------------------------- RifEclipseSummaryAddress addressFromErtSmSpecNode(const smspec_node_type * ertSumVarNode) { - if ( smspec_node_get_var_type(ertSumVarNode) == ECL_SMSPEC_INVALID_VAR - || !smspec_node_is_valid(ertSumVarNode)) + if (smspec_node_get_var_type(ertSumVarNode) == ECL_SMSPEC_INVALID_VAR) { return RifEclipseSummaryAddress(); } @@ -235,6 +245,7 @@ RifEclipseSummaryAddress addressFromErtSmSpecNode(const smspec_node_type * ertSu int cellJ(-1); int cellK(-1); int aquiferNumber(-1); + bool isErrorResult(false); quantityName = smspec_node_get_keyword(ertSumVarNode); @@ -333,6 +344,7 @@ RifEclipseSummaryAddress addressFromErtSmSpecNode(const smspec_node_type * ertSu case ECL_SMSPEC_SEGMENT_VAR: { sumCategory = RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT; + wellName = smspec_node_get_wgname(ertSumVarNode); wellSegmentNumber = smspec_node_get_num(ertSumVarNode); } break; @@ -355,7 +367,8 @@ RifEclipseSummaryAddress addressFromErtSmSpecNode(const smspec_node_type * ertSu wellSegmentNumber, lgrName, cellI, cellJ, cellK, - aquiferNumber); + aquiferNumber, + isErrorResult); } //-------------------------------------------------------------------------------------------------- @@ -363,25 +376,36 @@ RifEclipseSummaryAddress addressFromErtSmSpecNode(const smspec_node_type * ertSu //-------------------------------------------------------------------------------------------------- bool RifReaderEclipseSummary::values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const { - assert(m_ecl_sum != NULL); + assert(m_ecl_sum != nullptr); int variableIndex = indexFromAddress(resultAddress); if ( variableIndex < 0 ) return false; values->clear(); - int tsCount = timeStepCount(); values->reserve(timeStepCount()); - if (m_ecl_SmSpec) + const std::vector& cachedValues = m_valuesCache->getValues(resultAddress); + if (!cachedValues.empty()) + { + values->insert(values->begin(), cachedValues.begin(), cachedValues.end()); + } + else if (m_ecl_SmSpec) { const smspec_node_type* ertSumVarNode = ecl_smspec_iget_node(m_ecl_SmSpec, variableIndex); int paramsIndex = smspec_node_get_params_index(ertSumVarNode); - for(int time_index = 0; time_index < tsCount; time_index++) + double_vector_type* dataValues = ecl_sum_alloc_data_vector(m_ecl_sum, paramsIndex, false); + + if (dataValues) { - double value = ecl_sum_iget(m_ecl_sum, time_index, paramsIndex); - values->push_back(value); + for (int i = 0; i < double_vector_size(dataValues); i++) + { + values->push_back(double_vector_iget(dataValues, i)); + } + free(dataValues); + + m_valuesCache->insertValues(resultAddress, *values); } } @@ -405,7 +429,7 @@ int RifReaderEclipseSummary::timeStepCount() const //-------------------------------------------------------------------------------------------------- const std::vector& RifReaderEclipseSummary::timeSteps(const RifEclipseSummaryAddress& resultAddress) const { - assert(m_ecl_sum != NULL); + assert(m_ecl_sum != nullptr); return m_timeSteps; } @@ -439,29 +463,12 @@ void RifReaderEclipseSummary::buildMetaData() { const smspec_node_type * ertSumVarNode = ecl_smspec_iget_node(m_ecl_SmSpec, i); RifEclipseSummaryAddress addr = addressFromErtSmSpecNode(ertSumVarNode); - m_allResultAddresses.push_back(addr); + m_allResultAddresses.insert(addr); m_resultAddressToErtNodeIdx[addr] = i; } } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -time_t getStartDate(ecl_file_type * header) -{ - time_t startDate = 0; - ecl_kw_type *startdat = ecl_file_iget_named_kw(header, STARTDAT_KW, 0); - if (startdat) - { - int * date = ecl_kw_get_int_ptr(startdat); - startDate = ecl_util_make_date(date[STARTDAT_DAY_INDEX], - date[STARTDAT_MONTH_INDEX], - date[STARTDAT_YEAR_INDEX]); - } - return startDate; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -481,7 +488,7 @@ RifRestartFileInfo RifReaderEclipseSummary::getRestartFile(const QString& header char* smspec_header = ecl_util_alloc_exfilename(path.toStdString().data(), restartBase.toStdString().data(), ECL_SUMMARY_HEADER_FILE, false /*unformatted*/, 0); QString restartFileName = RiaFilePathTools::toInternalSeparator(RiaStringEncodingTools::fromNativeEncoded(smspec_header)); - util_safe_free(smspec_header); + free(smspec_header); return getFileInfo(restartFileName); } @@ -503,6 +510,22 @@ std::string RifReaderEclipseSummary::unitName(const RifEclipseSummaryAddress& re return smspec_node_get_unit(ertSumVarNode); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderEclipseSummary::markForCachePurge(const RifEclipseSummaryAddress& address) +{ + m_valuesCache->markAddressForPurge(address); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderEclipseSummary::purgeCache() +{ + ValuesCache::purge(); +} + #if 0 //-------------------------------------------------------------------------------------------------- /// @@ -518,3 +541,76 @@ void RifReaderEclipseSummary::populateVectorFromStringList(stringlist_type* stri } #endif + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector RifReaderEclipseSummary::ValuesCache::EMPTY_VECTOR; +std::set RifReaderEclipseSummary::ValuesCache::m_instances; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifReaderEclipseSummary::ValuesCache::ValuesCache() +{ + // Register instance + m_instances.insert(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifReaderEclipseSummary::ValuesCache::~ValuesCache() +{ + // Deregister instance + m_instances.erase(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderEclipseSummary::ValuesCache::insertValues(const RifEclipseSummaryAddress& address, const std::vector& values) +{ + m_cachedValues[address] = values; + m_purgeList.erase(address); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RifReaderEclipseSummary::ValuesCache::getValues(const RifEclipseSummaryAddress& address) const +{ + if (m_cachedValues.find(address) != m_cachedValues.end()) + { + return m_cachedValues.at(address); + } + return EMPTY_VECTOR; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderEclipseSummary::ValuesCache::markAddressForPurge(const RifEclipseSummaryAddress& address) +{ + m_purgeList.insert(address); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderEclipseSummary::ValuesCache::purge() +{ + for (auto instance : m_instances) instance->purgeData(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifReaderEclipseSummary::ValuesCache::purgeData() +{ + for (const auto purgeAddr : m_purgeList) + { + m_cachedValues.erase(purgeAddr); + } + m_purgeList.clear(); +} diff --git a/ApplicationCode/FileInterface/RifReaderEclipseSummary.h b/ApplicationCode/FileInterface/RifReaderEclipseSummary.h index 88f0cf228f..9221bca068 100644 --- a/ApplicationCode/FileInterface/RifReaderEclipseSummary.h +++ b/ApplicationCode/FileInterface/RifReaderEclipseSummary.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include //================================================================================================== @@ -54,20 +56,23 @@ class RifReaderEclipseSummary : public RifSummaryReaderInterface { public: RifReaderEclipseSummary(); - ~RifReaderEclipseSummary(); + ~RifReaderEclipseSummary() override; bool open(const QString& headerFileName, bool includeRestartFiles); std::vector getRestartFiles(const QString& headerFileName, bool* hasWarnings); RifRestartFileInfo getFileInfo(const QString& headerFileName); - virtual const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; + const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; - virtual bool values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const override; - virtual std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; + bool values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const override; + std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; QStringList warnings() const { return m_warnings; } + void markForCachePurge(const RifEclipseSummaryAddress& address) override; + static void purgeCache(); + private: int timeStepCount() const; int indexFromAddress(const RifEclipseSummaryAddress& resultAddress) const; @@ -86,5 +91,33 @@ class RifReaderEclipseSummary : public RifSummaryReaderInterface std::map m_resultAddressToErtNodeIdx; QStringList m_warnings; + + + //================================================================================================== + // + //================================================================================================== + class ValuesCache + { + static const std::vector EMPTY_VECTOR; + + public: + ValuesCache(); + ~ValuesCache(); + + void insertValues(const RifEclipseSummaryAddress& address, const std::vector& values); + const std::vector& getValues(const RifEclipseSummaryAddress& address) const; + void markAddressForPurge(const RifEclipseSummaryAddress& address); + static void purge(); + + private: + void purgeData(); + + std::map> m_cachedValues; + std::set m_purgeList; + + static std::set m_instances; + }; + + std::unique_ptr m_valuesCache; }; diff --git a/ApplicationCode/FileInterface/RifReaderInterface.h b/ApplicationCode/FileInterface/RifReaderInterface.h index b92bc526ac..d2e2a1e7f8 100644 --- a/ApplicationCode/FileInterface/RifReaderInterface.h +++ b/ApplicationCode/FileInterface/RifReaderInterface.h @@ -48,7 +48,7 @@ class RifReaderInterface : public cvf::Object { public: RifReaderInterface() { } - virtual ~RifReaderInterface() { } + ~RifReaderInterface() override { } bool isFaultImportEnabled(); bool isImportOfCompleteMswDataEnabled(); diff --git a/ApplicationCode/FileInterface/RifReaderMockModel.h b/ApplicationCode/FileInterface/RifReaderMockModel.h index d011a85f31..ca589ba319 100644 --- a/ApplicationCode/FileInterface/RifReaderMockModel.h +++ b/ApplicationCode/FileInterface/RifReaderMockModel.h @@ -27,7 +27,7 @@ class RifReaderMockModel : public RifReaderInterface { public: RifReaderMockModel(); - virtual ~RifReaderMockModel(); + ~RifReaderMockModel() override; void setWorldCoordinates(cvf::Vec3d minWorldCoordinate, cvf::Vec3d maxWorldCoordinate); void setGridPointDimensions(const cvf::Vec3st& gridPointDimensions); @@ -36,10 +36,10 @@ class RifReaderMockModel : public RifReaderInterface void addLocalGridRefinement(const cvf::Vec3st& minCellPosition, const cvf::Vec3st& maxCellPosition, const cvf::Vec3st& singleCellRefinementFactors); - virtual bool open( const QString& fileName, RigEclipseCaseData* eclipseCase ); + bool open( const QString& fileName, RigEclipseCaseData* eclipseCase ) override; - virtual bool staticResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector* values ); - virtual bool dynamicResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector* values ); + bool staticResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, std::vector* values ) override; + bool dynamicResult( const QString& result, RiaDefines::PorosityModelType matrixOrFracture, size_t stepIndex, std::vector* values ) override; private: void populateReservoir(RigEclipseCaseData* eclipseCase); diff --git a/ApplicationCode/FileInterface/RifReaderObservedData.cpp b/ApplicationCode/FileInterface/RifReaderObservedData.cpp index 7b512a42fe..734f7bc888 100644 --- a/ApplicationCode/FileInterface/RifReaderObservedData.cpp +++ b/ApplicationCode/FileInterface/RifReaderObservedData.cpp @@ -70,16 +70,15 @@ bool RifReaderObservedData::open(const QString& headerFileName, { if (m_asciiParser && m_asciiParser->dateTimeColumn()) { - for (QDateTime timeStep : m_asciiParser->dateTimeColumn()->dateTimeValues) + for (time_t timeStep : m_asciiParser->dateTimeColumn()->dateTimeValues) { - time_t t = timeStep.toTime_t(); - m_timeSteps.push_back(t); + m_timeSteps.push_back(timeStep); } m_allResultAddresses.clear(); for (auto s : m_asciiParser->tableData().columnInfos()) { - m_allResultAddresses.push_back(s.summaryAddress); + m_allResultAddresses.insert(s.summaryAddress); } } @@ -95,12 +94,14 @@ bool RifReaderObservedData::values(const RifEclipseSummaryAddress& resultAddress { size_t columnIndex = m_allResultAddresses.size(); - for (size_t i = 0; i < m_allResultAddresses.size(); i++) + int i = 0; + for(auto& address : m_allResultAddresses) { - if (resultAddress == m_allResultAddresses[i]) + if (address == resultAddress) { columnIndex = i; } + i++; } if (columnIndex != m_allResultAddresses.size()) @@ -144,6 +145,7 @@ RifEclipseSummaryAddress RifReaderObservedData::address(const QString& quantity, int cellJ(-1); int cellK(-1); int aquiferNumber(-1); + bool isErrorResult(false); switch (summaryCategory) { @@ -169,7 +171,8 @@ RifEclipseSummaryAddress RifReaderObservedData::address(const QString& quantity, wellSegmentNumber, lgrName, cellI, cellJ, cellK, - aquiferNumber); + aquiferNumber, + isErrorResult); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/FileInterface/RifReaderObservedData.h b/ApplicationCode/FileInterface/RifReaderObservedData.h index 2d633192a1..54d0177a25 100644 --- a/ApplicationCode/FileInterface/RifReaderObservedData.h +++ b/ApplicationCode/FileInterface/RifReaderObservedData.h @@ -40,15 +40,15 @@ class RifReaderObservedData : public RifSummaryReaderInterface { public: RifReaderObservedData(); - ~RifReaderObservedData(); + ~RifReaderObservedData() override; bool open(const QString& headerFileName, const QString& identifierName, RifEclipseSummaryAddress::SummaryVarCategory summaryCategory); - virtual const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; + const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; - virtual bool values(const RifEclipseSummaryAddress& resultAddress, + bool values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const override; std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; diff --git a/ApplicationCode/FileInterface/RifReaderSettings.h b/ApplicationCode/FileInterface/RifReaderSettings.h index 4380d012e2..58af3b853d 100644 --- a/ApplicationCode/FileInterface/RifReaderSettings.h +++ b/ApplicationCode/FileInterface/RifReaderSettings.h @@ -44,9 +44,9 @@ class RifReaderSettings : public caf::PdmObject caf::PdmField skipWellData; private: - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; }; diff --git a/ApplicationCode/FileInterface/RifStimPlanXmlReader.cpp b/ApplicationCode/FileInterface/RifStimPlanXmlReader.cpp index edff203d97..869587feed 100644 --- a/ApplicationCode/FileInterface/RifStimPlanXmlReader.cpp +++ b/ApplicationCode/FileInterface/RifStimPlanXmlReader.cpp @@ -278,7 +278,7 @@ std::vector> RifStimPlanXmlReader::getAllDepthDataAtTimeSte if (xmlStream.name() == "depth") { - double depth = xmlStream.readElementText().toDouble(); + xmlStream.readElementText().toDouble(); std::vector propertyValuesAtDepth; xmlStream.readNext(); //read end depth token diff --git a/ApplicationCode/FileInterface/RifSummaryCaseRestartSelector.cpp b/ApplicationCode/FileInterface/RifSummaryCaseRestartSelector.cpp index 9cb9c54d82..215b40c220 100644 --- a/ApplicationCode/FileInterface/RifSummaryCaseRestartSelector.cpp +++ b/ApplicationCode/FileInterface/RifSummaryCaseRestartSelector.cpp @@ -72,6 +72,7 @@ RifSummaryCaseRestartSelector::RifSummaryCaseRestartSelector() m_showDialog = prefs->summaryRestartFilesShowImportDialog(); m_defaultSummaryImportMode = mapReadOption(prefs->summaryImportMode()); m_defaultGridImportMode = mapReadOption(prefs->gridImportMode()); + m_ensembleOrGroupMode = false; //m_buildGridFileList = false; m_gridFiles.clear(); @@ -124,6 +125,14 @@ void RifSummaryCaseRestartSelector::showDialog(bool show) m_showDialog = show; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifSummaryCaseRestartSelector::setEnsembleOrGroupMode(bool eogMode) +{ + m_ensembleOrGroupMode = eogMode; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -176,6 +185,7 @@ void RifSummaryCaseRestartSelector::determineFilesToImportByAskingUser(const std initialFile.gridFileName(), initialFile.failOnSummaryFileError(), enableApplyToAllField, + m_ensembleOrGroupMode, m_defaultSummaryImportMode, m_defaultGridImportMode, &lastResult); @@ -237,27 +247,9 @@ void RifSummaryCaseRestartSelector::determineFilesToImportUsingPrefs(const std:: { QString initialSummaryFile = RiaFilePathTools::toInternalSeparator(initialFile.summaryFileName()); QString initialGridFile = RiaFilePathTools::toInternalSeparator(initialFile.gridFileName()); - bool handleSummaryFile = false; + bool handleSummaryFile = !initialSummaryFile.isEmpty(); bool handleGridFile = !initialGridFile.isEmpty(); - RifReaderEclipseSummary reader; - if (!initialSummaryFile.isEmpty()) - { - RifRestartFileInfo fileInfo = reader.getFileInfo(initialSummaryFile); - if (!fileInfo.valid()) - { - m_summaryFileErrors.push_back(initialSummaryFile); - if (initialFile.failOnSummaryFileError()) - { - handleGridFile = false; - } - } - else - { - handleSummaryFile = true; - } - } - if (handleSummaryFile) { if (m_defaultSummaryImportMode == RicSummaryCaseRestartDialog::IMPORT_ALL) @@ -272,6 +264,7 @@ void RifSummaryCaseRestartSelector::determineFilesToImportUsingPrefs(const std:: { m_summaryFileInfos.push_back(RifSummaryCaseFileResultInfo(initialSummaryFile, false)); bool hasWarnings = false; + RifReaderEclipseSummary reader; std::vector restartFileInfos = reader.getRestartFiles(initialSummaryFile, &hasWarnings); for (const auto& rfi : restartFileInfos) { @@ -321,14 +314,6 @@ bool RifSummaryCaseRestartSelector::foundErrors() const return !m_summaryFileErrors.empty(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const QStringList& RifSummaryCaseRestartSelector::summaryFilesWithErrors() const -{ - return m_summaryFileErrors; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -351,25 +336,6 @@ QString RifSummaryCaseRestartSelector::createCombinedErrorMessage() const return errorMessage; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QStringList RifSummaryCaseRestartSelector::getSummaryFilesFromGridFiles(const QStringList& gridFiles) -{ - QStringList summaryFiles; - - // Find summary header file names from eclipse case file names - for (const auto& gridFile : gridFiles) - { - QString sumFile = getSummaryFileFromGridFile(gridFile); - if (!sumFile.isEmpty()) - { - summaryFiles.push_back(sumFile); - } - } - return summaryFiles; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/FileInterface/RifSummaryCaseRestartSelector.h b/ApplicationCode/FileInterface/RifSummaryCaseRestartSelector.h index bf6d1a69ff..7885d5d437 100644 --- a/ApplicationCode/FileInterface/RifSummaryCaseRestartSelector.h +++ b/ApplicationCode/FileInterface/RifSummaryCaseRestartSelector.h @@ -44,13 +44,12 @@ class RifSummaryCaseRestartSelector void determineFilesToImportFromGridFiles(const QStringList& initialGridFiles); void showDialog(bool show); + void setEnsembleOrGroupMode(bool eogMode); std::vector summaryFileInfos() const; QStringList gridCaseFiles() const; bool foundErrors() const; - const QStringList& summaryFilesWithErrors() const; QString createCombinedErrorMessage() const; - static QStringList getSummaryFilesFromGridFiles(const QStringList& gridFiles); static QString getSummaryFileFromGridFile(const QString& gridFile); private: @@ -59,6 +58,7 @@ class RifSummaryCaseRestartSelector void determineFilesToImportUsingPrefs(const std::vector& initialFiles); bool m_showDialog; + bool m_ensembleOrGroupMode; RicSummaryCaseRestartDialog::ImportOptions m_defaultSummaryImportMode; RicSummaryCaseRestartDialog::ImportOptions m_defaultGridImportMode; diff --git a/ApplicationCode/FileInterface/RifSummaryReaderInterface.cpp b/ApplicationCode/FileInterface/RifSummaryReaderInterface.cpp index afd8ea8af2..4beb891517 100644 --- a/ApplicationCode/FileInterface/RifSummaryReaderInterface.cpp +++ b/ApplicationCode/FileInterface/RifSummaryReaderInterface.cpp @@ -26,7 +26,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector& RifSummaryReaderInterface::allResultAddresses() const +const std::set& RifSummaryReaderInterface::allResultAddresses() const { return m_allResultAddresses; } @@ -34,17 +34,12 @@ const std::vector& RifSummaryReaderInterface::allResul //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RifSummaryReaderInterface::fromTimeT(const std::vector& timeSteps) +RifEclipseSummaryAddress RifSummaryReaderInterface::errorAddress(const RifEclipseSummaryAddress& resultAddress) const { - std::vector a; + RifEclipseSummaryAddress errAddr = resultAddress; + errAddr.setAsErrorResult(); - for (size_t i = 0; i < timeSteps.size(); i++) - { - QDateTime dt = QDateTime::fromTime_t(timeSteps[i]); - a.push_back(dt); - } - - return a; + return m_allErrorAddresses.find(errAddr) != m_allErrorAddresses.end() ? errAddr : RifEclipseSummaryAddress(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/FileInterface/RifSummaryReaderInterface.h b/ApplicationCode/FileInterface/RifSummaryReaderInterface.h index e96b6eb4a2..732abdc9d0 100644 --- a/ApplicationCode/FileInterface/RifSummaryReaderInterface.h +++ b/ApplicationCode/FileInterface/RifSummaryReaderInterface.h @@ -25,6 +25,7 @@ #include #include #include +#include class QDateTime; @@ -37,7 +38,8 @@ class RifSummaryReaderInterface : public cvf::Object { public: bool hasAddress(const RifEclipseSummaryAddress& resultAddress) const; - const std::vector& allResultAddresses() const; + const std::set& allResultAddresses() const; + RifEclipseSummaryAddress errorAddress(const RifEclipseSummaryAddress& resultAddress) const; virtual const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const = 0; @@ -46,9 +48,10 @@ class RifSummaryReaderInterface : public cvf::Object virtual std::string unitName(const RifEclipseSummaryAddress& resultAddress) const = 0; - // TODO: Move this to a tools class with static members - static std::vector fromTimeT(const std::vector& timeSteps); - + + virtual void markForCachePurge(const RifEclipseSummaryAddress& address) {} + protected: - std::vector m_allResultAddresses; + std::set m_allResultAddresses; // Result and error addresses + std::set m_allErrorAddresses; // Error addresses }; diff --git a/ApplicationCode/FileInterface/RifWellPathImporter.cpp b/ApplicationCode/FileInterface/RifWellPathImporter.cpp index 46181be233..df0ff43539 100644 --- a/ApplicationCode/FileInterface/RifWellPathImporter.cpp +++ b/ApplicationCode/FileInterface/RifWellPathImporter.cpp @@ -198,28 +198,20 @@ void RifWellPathImporter::readAllAsciiWellData(const QString& filePath) std::vector& fileWellDataArray = m_fileNameToWellDataGroupMap[filePath]; std::ifstream stream(filePath.toLatin1().data()); - double x(HUGE_VAL), y(HUGE_VAL), tvd(HUGE_VAL), md(HUGE_VAL); bool hasReadWellPointInCurrentWell = false; while (stream.good()) { + double x(HUGE_VAL), y(HUGE_VAL), tvd(HUGE_VAL), md(HUGE_VAL); + // First check if we can read a number stream >> x; if (stream.good()) // If we can, assume this line is a well point entry { stream >> y >> tvd >> md; - if (!stream.good()) - { - // -999 or otherwise to few numbers before some word - if (x != -999) - { - // Error in file: missing numbers at this line - } - stream.clear(); - } - else + if (x != HUGE_VAL && y != HUGE_VAL && tvd != HUGE_VAL && md != HUGE_VAL) { if (!fileWellDataArray.size()) { @@ -231,13 +223,19 @@ void RifWellPathImporter::readAllAsciiWellData(const QString& filePath) fileWellDataArray.back().m_wellPathGeometry->m_wellPathPoints.push_back(wellPoint); fileWellDataArray.back().m_wellPathGeometry->m_measuredDepths.push_back(md); - x = HUGE_VAL; - y = HUGE_VAL; - tvd = HUGE_VAL; - md = HUGE_VAL; - hasReadWellPointInCurrentWell = true; } + + if (!stream.good()) + { + // -999 or otherwise to few numbers before some word + if (x != -999) + { + // Error in file: missing numbers at this line + + } + stream.clear(); + } } else { @@ -276,7 +274,8 @@ void RifWellPathImporter::readAllAsciiWellData(const QString& filePath) // name // wellname: std::string lineLowerCase = line; - transform(lineLowerCase.begin(), lineLowerCase.end(), lineLowerCase.begin(), ::tolower); + transform(lineLowerCase.begin(), lineLowerCase.end(), lineLowerCase.begin(), + [](const char c) -> char { return (char)::tolower(c); }); std::string tokenName = "name"; std::size_t foundNameIdx = lineLowerCase.find(tokenName); diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/CMakeLists.txt b/ApplicationCode/GeoMech/GeoMechDataModel/CMakeLists.txt index ed56edb9f3..c082dd9ac3 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/CMakeLists.txt +++ b/ApplicationCode/GeoMech/GeoMechDataModel/CMakeLists.txt @@ -26,8 +26,10 @@ add_library( ${PROJECT_NAME} RigFemPartGrid.cpp RigFemResultAddress.h RigFemResultPosEnum.h - RimGeoMechGeometrySelectionItem.h - RimGeoMechGeometrySelectionItem.cpp + RimFemResultObserver.h + RimFemResultObserver.cpp + RimGeoMechGeometrySelectionItem.h + RimGeoMechGeometrySelectionItem.cpp ) target_include_directories(${PROJECT_NAME} diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp index 2fb9b568f7..55b1e1cc37 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.cpp @@ -71,7 +71,7 @@ void RigFemPart::appendElement(RigElementType elmType, int id, const int* connec //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const RigFemPartGrid* RigFemPart::structGrid() const +const RigFemPartGrid* RigFemPart::getOrCreateStructGrid() const { if (m_structGrid.isNull()) { @@ -98,14 +98,16 @@ void RigFemPart::assertNodeToElmIndicesIsCalculated() void RigFemPart::calculateNodeToElmRefs() { m_nodeToElmRefs.resize(nodes().nodeIds.size()); + m_nodeGlobalToLocalIndices.resize(nodes().nodeIds.size()); for (int eIdx = 0; eIdx < static_cast(m_elementId.size()); ++eIdx) { int elmNodeCount = RigFemTypes::elmentNodeCount(elementType(eIdx)); const int* elmNodes = connectivities(eIdx); - for (int enIdx = 0; enIdx < elmNodeCount; ++enIdx) + for (int localIdx = 0; localIdx < elmNodeCount; ++localIdx) { - m_nodeToElmRefs[elmNodes[enIdx]].push_back(eIdx); + m_nodeToElmRefs[elmNodes[localIdx]].push_back(eIdx); + m_nodeGlobalToLocalIndices[elmNodes[localIdx]].push_back(localIdx); } } } @@ -113,17 +115,17 @@ void RigFemPart::calculateNodeToElmRefs() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const int* RigFemPart::elementsUsingNode(int nodeIndex) +const std::vector& RigFemPart::elementsUsingNode(int nodeIndex) const { - return &(m_nodeToElmRefs[nodeIndex][0]); + return m_nodeToElmRefs[nodeIndex]; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -int RigFemPart::numElementsUsingNode(int nodeIndex) +const std::vector& RigFemPart::elementLocalIndicesForNode(int nodeIndex) const { - return static_cast(m_nodeToElmRefs[nodeIndex].size()); + return m_nodeGlobalToLocalIndices[nodeIndex]; } //-------------------------------------------------------------------------------------------------- @@ -168,24 +170,23 @@ void RigFemPart::calculateElmNeighbors() candidates.clear(); { int firstNodeIdxOfFace = elmNodes[localFaceIndices[0]]; - int candidateCount1 = this->numElementsUsingNode(firstNodeIdxOfFace); - const int* candidates1 = this->elementsUsingNode(firstNodeIdxOfFace); + const std::vector& candidates1 = this->elementsUsingNode(firstNodeIdxOfFace); - if (candidateCount1) + if (!candidates1.empty()) { // Get neighbor candidates from the diagonal node int thirdNodeIdxOfFace = elmNodes[localFaceIndices[3]]; - int candidateCount2 = this->numElementsUsingNode(thirdNodeIdxOfFace); - const int* candidates2 = this->elementsUsingNode(thirdNodeIdxOfFace); + + const std::vector& candidates2 = this->elementsUsingNode(thirdNodeIdxOfFace); // The candidates are sorted from smallest to largest, so we do a linear search to find the // (two) common cells in the two arrays, and leaving this element out, we have one candidate left - int idx1 = 0; - int idx2 = 0; + size_t idx1 = 0; + size_t idx2 = 0; - while (idx1 < candidateCount1 && idx2 < candidateCount2) + while (idx1 < candidates1.size() && idx2 < candidates2.size()) { if (candidates1[idx1] < candidates2[idx2]){ ++idx1; continue; } if (candidates1[idx1] > candidates2[idx2]){ ++idx2; continue; } @@ -385,3 +386,32 @@ size_t RigFemPart::elementNodeResultCount() const return lastElmResultIdx + 1; } +//-------------------------------------------------------------------------------------------------- +/// Generate a sensible index into the result vector based on which result position type is used. +//-------------------------------------------------------------------------------------------------- +size_t RigFemPart::resultValueIdxFromResultPosType(RigFemResultPosEnum resultPosType, int elementIdx, int elmLocalNodeIdx) const +{ + if (resultPosType == RIG_ELEMENT || resultPosType == RIG_FORMATION_NAMES) + { + CVF_ASSERT(elementIdx < static_cast(m_elementId.size())); + return elementIdx; + } + + size_t elementNodeResultIdx = this->elementNodeResultIdx(static_cast(elementIdx), elmLocalNodeIdx); + CVF_ASSERT(elementNodeResultIdx < elementNodeResultCount()); + + if (resultPosType == RIG_ELEMENT_NODAL || resultPosType == RIG_INTEGRATION_POINT) + { + return elementNodeResultIdx; + } + else if (resultPosType == RIG_NODAL) + { + size_t nodeIdx = nodeIdxFromElementNodeResultIdx(elementNodeResultIdx); + CVF_ASSERT(nodeIdx < m_nodes.nodeIds.size()); + return nodeIdx; + } + + CVF_ASSERT(false); + return 0u; +} + diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.h index 09ae8d8dc6..cae026c8e9 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPart.h @@ -22,6 +22,7 @@ #include #include "RigFemTypes.h" +#include "RigFemResultPosEnum.h" #include "cvfObject.h" #include "cvfAssert.h" #include "cvfBoundingBox.h" @@ -63,13 +64,13 @@ class RigFemPart : public cvf::Object size_t elementNodeResultIdx(int elementIdx, int elmLocalNodeIdx) const { return m_elementConnectivityStartIndices[elementIdx] + elmLocalNodeIdx;} size_t elementNodeResultCount() const; int nodeIdxFromElementNodeResultIdx(size_t elmNodeResultIdx) const { return m_allElementConnectivities[elmNodeResultIdx]; } - + size_t resultValueIdxFromResultPosType(RigFemResultPosEnum resultPosType, int elementIdx, int elmLocalNodeIdx) const; RigFemPartNodes& nodes() {return m_nodes;} const RigFemPartNodes& nodes() const {return m_nodes;} - void assertNodeToElmIndicesIsCalculated(); - const int* elementsUsingNode(int nodeIndex); - int numElementsUsingNode(int nodeIndex); + void assertNodeToElmIndicesIsCalculated(); + const std::vector& elementsUsingNode(int nodeIndex) const; + const std::vector& elementLocalIndicesForNode(int nodeIndex) const; void assertElmNeighborsIsCalculated(); int elementNeighbor(int elementIndex, int faceIndex) const @@ -84,7 +85,7 @@ class RigFemPart : public cvf::Object cvf::Vec3f faceNormal(int elmentIndex, int faceIndex) const; - const RigFemPartGrid* structGrid() const; + const RigFemPartGrid* getOrCreateStructGrid() const; const std::vector& elementIdxToId() const { return m_elementId; } private: @@ -100,12 +101,13 @@ class RigFemPart : public cvf::Object mutable cvf::ref m_structGrid; void calculateNodeToElmRefs(); - std::vector > m_nodeToElmRefs; // Needs a more memory friendly structure + std::vector> m_nodeToElmRefs; // Needs a more memory friendly structure + std::vector> m_nodeGlobalToLocalIndices; void calculateElmNeighbors(); struct Neighbors { int indicesToNeighborElms[6]; char faceInNeighborElm[6];}; - std::vector< Neighbors > m_elmNeighbors; - std::vector m_possibleGridCornerElements; + std::vector< Neighbors > m_elmNeighbors; + std::vector m_possibleGridCornerElements; mutable float m_characteristicElementSize; mutable cvf::BoundingBox m_boundingBox; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp index 49c10dcc59..624f2adb21 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.cpp @@ -101,6 +101,7 @@ void RigFemPartGrid::generateStructGridData() int iCoord = 0; while (true) { + CVF_ASSERT(elmIdxInI >= 0 && size_t(elmIdxInI) < m_ijkPrElement.size()); // Assign ijk coordinate m_ijkPrElement[elmIdxInI] = cvf::Vec3i(iCoord, jCoord, kCoord); @@ -180,8 +181,12 @@ void RigFemPartGrid::generateStructGridData() for (int elmIdx = 0; elmIdx < m_femPart->elementCount(); ++elmIdx) { - cvf::Vec3i ijk = m_ijkPrElement[elmIdx]; - m_elmIdxPrIJK.at(ijk[0], ijk[1], ijk[2]) = elmIdx; + size_t i, j, k; + bool validIndex = ijkFromCellIndex(elmIdx, &i, &j, &k); + if (validIndex) + { + m_elmIdxPrIJK.at(i, j, k) = elmIdx; + } } // IJK bounding box @@ -194,7 +199,8 @@ void RigFemPartGrid::generateStructGridData() { RigElementType elementType = m_femPart->elementType(elmIdx); size_t i, j, k; - if (elementType == HEX8P && ijkFromCellIndex(elmIdx, &i, &j, &k)) + bool validIndex = ijkFromCellIndex(elmIdx, &i, &j, &k); + if (elementType == HEX8P && validIndex) { if (i < min.x()) min.x() = i; if (j < min.y()) min.y() = j; @@ -424,11 +430,21 @@ size_t RigFemPartGrid::cellIndexFromIJK(size_t i, size_t j, size_t k) const //-------------------------------------------------------------------------------------------------- bool RigFemPartGrid::ijkFromCellIndex(size_t cellIndex, size_t* i, size_t* j, size_t* k) const { - *i = m_ijkPrElement[cellIndex][0]; - *j = m_ijkPrElement[cellIndex][1]; - *k = m_ijkPrElement[cellIndex][2]; + if (cellIndex < m_ijkPrElement.size()) + { + int signed_i = m_ijkPrElement[cellIndex][0]; + int signed_j = m_ijkPrElement[cellIndex][1]; + int signed_k = m_ijkPrElement[cellIndex][2]; - return true; + if (signed_i >= 0 && signed_j >= 0 && signed_k >= 0) + { + *i = signed_i; + *j = signed_j; + *k = signed_k; + return true; + } + } + return false; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.h index 810f66015d..4a40bf88b6 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartGrid.h @@ -30,12 +30,12 @@ class RigFemPartGrid : public cvf::StructGridInterface explicit RigFemPartGrid(const RigFemPart* femPart); virtual ~RigFemPartGrid(); - virtual bool ijkFromCellIndex(size_t cellIndex, size_t* i, size_t* j, size_t* k) const; - virtual size_t cellIndexFromIJK(size_t i, size_t j, size_t k) const; + bool ijkFromCellIndex(size_t cellIndex, size_t* i, size_t* j, size_t* k) const override; + size_t cellIndexFromIJK(size_t i, size_t j, size_t k) const override; - virtual size_t gridPointCountI() const; - virtual size_t gridPointCountJ() const; - virtual size_t gridPointCountK() const; + size_t gridPointCountI() const override; + size_t gridPointCountJ() const override; + size_t gridPointCountK() const override; cvf::Vec3i findMainIJKFaces(int elementIndex) const; @@ -52,18 +52,18 @@ class RigFemPartGrid : public cvf::StructGridInterface cvf::Vec3st m_elmentIJKCounts; private: // Unused, Not implemented - virtual bool isCellValid(size_t i, size_t j, size_t k) const; - virtual cvf::Vec3d minCoordinate() const; - virtual cvf::Vec3d maxCoordinate() const; - virtual bool cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex) const; + bool isCellValid(size_t i, size_t j, size_t k) const override; + cvf::Vec3d minCoordinate() const override; + cvf::Vec3d maxCoordinate() const override; + bool cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex) const override; - virtual bool cellIJKFromCoordinate(const cvf::Vec3d& coord, size_t* i, size_t* j, size_t* k) const; + bool cellIJKFromCoordinate(const cvf::Vec3d& coord, size_t* i, size_t* j, size_t* k) const override; virtual void cellCornerVertices(size_t cellIndex, cvf::Vec3d vertices[8]) const; - virtual cvf::Vec3d cellCentroid(size_t cellIndex) const; - virtual void cellMinMaxCordinates(size_t cellIndex, cvf::Vec3d* minCoordinate, cvf::Vec3d* maxCoordinate) const; - virtual size_t gridPointIndexFromIJK(size_t i, size_t j, size_t k) const; - virtual cvf::Vec3d gridPointCoordinate(size_t i, size_t j, size_t k) const; + cvf::Vec3d cellCentroid(size_t cellIndex) const override; + void cellMinMaxCordinates(size_t cellIndex, cvf::Vec3d* minCoordinate, cvf::Vec3d* maxCoordinate) const override; + size_t gridPointIndexFromIJK(size_t i, size_t j, size_t k) const override; + cvf::Vec3d gridPointCoordinate(size_t i, size_t j, size_t k) const override; class IJKArray { diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResults.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResults.cpp index bf0ea0250d..3f518a9fac 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResults.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResults.cpp @@ -92,3 +92,16 @@ void RigFemPartResults::deleteScalarResult(const RigFemResultAddress& resVarAddr } } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigFemPartResults::loadedResults() const +{ + std::vector currentResults; + for (const auto& result : resultSets) + { + currentResults.push_back(result.first); + } + return currentResults; +} diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResults.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResults.h index c193f0212f..5df61d0c19 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResults.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResults.h @@ -39,9 +39,10 @@ class RigFemPartResults : public cvf::Object void initResultSteps(const std::vector& stepNames); - RigFemScalarResultFrames* createScalarResult(const RigFemResultAddress& resVarAddr); - RigFemScalarResultFrames* findScalarResult(const RigFemResultAddress& resVarAddr); - void deleteScalarResult(const RigFemResultAddress& resVarAddr); + RigFemScalarResultFrames* createScalarResult(const RigFemResultAddress& resVarAddr); + RigFemScalarResultFrames* findScalarResult(const RigFemResultAddress& resVarAddr); + void deleteScalarResult(const RigFemResultAddress& resVarAddr); + std::vector loadedResults() const; private: diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp index ece1c4d4cc..4a6021ab55 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.cpp @@ -28,6 +28,8 @@ #include "RiaApplication.h" +#include "RiaOffshoreSphericalCoords.h" + #include "RigFemNativeStatCalc.h" #include "RigFemPartCollection.h" #include "RigFemPartGrid.h" @@ -90,11 +92,11 @@ RigFemPartResultsCollection::RigFemPartResultsCollection(RifGeoMechReaderInterfa m_femParts = femPartCollection; m_femPartResults.resize(m_femParts->partCount()); - std::vector stepNames = m_readerInterface->stepNames(); + std::vector filteredStepNames = m_readerInterface->filteredStepNames(); for (auto & femPartResult : m_femPartResults) { femPartResult = new RigFemPartResults; - femPartResult->initResultSteps(stepNames); + femPartResult->initResultSteps(filteredStepNames); } m_cohesion = 10.0; @@ -482,6 +484,19 @@ std::map > RigFemPartResultsCollection::sc fieldCompNames[field]; } } + else if (resPos == RIG_WELLPATH_DERIVED) + { + std::vector angles = RiaDefines::wellPathAngleResultNames(); + for (QString angle : angles) + { + fieldCompNames[angle.toStdString()]; + } + std::vector derivedResults = RiaDefines::wellPathStabilityResultNames(); + for (QString result : derivedResults) + { + fieldCompNames[result.toStdString()]; + } + } } return fieldCompNames; @@ -496,7 +511,8 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateBarConvertedResu frameCountProgress.setProgressDescription("Calculating " + QString::fromStdString(convertedResultAddr.fieldName + ": " + convertedResultAddr.componentName)); frameCountProgress.setNextProgressIncrement(this->frameCount()); - RigFemScalarResultFrames * srcDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(convertedResultAddr.resultPosType, fieldNameToConvert, convertedResultAddr.componentName)); + RigFemResultAddress unconvertedResultAddr(convertedResultAddr.resultPosType, fieldNameToConvert, convertedResultAddr.componentName); + RigFemScalarResultFrames * srcDataFrames = this->findOrLoadScalarResult(partIndex, unconvertedResultAddr); RigFemScalarResultFrames * dstDataFrames = m_femPartResults[partIndex]->createScalarResult(convertedResultAddr); frameCountProgress.incrementProgress(); @@ -517,7 +533,7 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateBarConvertedResu frameCountProgress.incrementProgress(); } - + this->deleteResult(unconvertedResultAddr); return dstDataFrames; } @@ -530,7 +546,8 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateEnIpPorBarResult frameCountProgress.setProgressDescription("Calculating " + QString::fromStdString(convertedResultAddr.fieldName + ": " + convertedResultAddr.componentName)); frameCountProgress.setNextProgressIncrement(this->frameCount()); - RigFemScalarResultFrames * srcDataFrames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(RIG_NODAL, "POR", "")); + RigFemResultAddress unconvertedResultAddr(RIG_NODAL, "POR", ""); + RigFemScalarResultFrames * srcDataFrames = this->findOrLoadScalarResult(partIndex, unconvertedResultAddr); RigFemScalarResultFrames * dstDataFrames = m_femPartResults[partIndex]->createScalarResult(convertedResultAddr); frameCountProgress.incrementProgress(); @@ -571,6 +588,7 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateEnIpPorBarResult frameCountProgress.incrementProgress(); } + this->deleteResult(unconvertedResultAddr); return dstDataFrames; } @@ -597,10 +615,13 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateTimeLapseResult( int baseFrameIdx = resVarAddr.timeLapseBaseFrameIdx; if ( baseFrameIdx >= frameCount ) return dstDataFrames; const std::vector& baseFrameData = srcDataFrames->frameData(baseFrameIdx); + if (baseFrameData.empty()) return dstDataFrames; for ( int fIdx = 0; fIdx < frameCount; ++fIdx ) { const std::vector& srcFrameData = srcDataFrames->frameData(fIdx); + if (srcFrameData.empty()) continue; // Create empty results + std::vector& dstFrameData = dstDataFrames->frameData(fIdx); size_t valCount = srcFrameData.size(); dstFrameData.resize(valCount); @@ -1242,7 +1263,7 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateSurfaceAngles(in quadVxs[3] = (nodeCoordinates[elmNodeIndices[localElmNodeIndicesForFace[3]]]); cvf::Mat3f rotMx = cvf::GeometryTools::computePlaneHorizontalRotationMx(quadVxs[2] -quadVxs[0], quadVxs[3] - quadVxs[1]); - OffshoreSphericalCoords sphCoord(cvf::Vec3f(rotMx.rowCol(0,2), rotMx.rowCol(1,2), rotMx.rowCol(2,2))); // Use Ez from the matrix as plane normal + RiaOffshoreSphericalCoords sphCoord(cvf::Vec3f(rotMx.rowCol(0,2), rotMx.rowCol(1,2), rotMx.rowCol(2,2))); // Use Ez from the matrix as plane normal for ( int qIdx = 0; qIdx < 4; ++qIdx ) { @@ -1350,7 +1371,7 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculatePrincipalStressV if ( principals[0] != std::numeric_limits::infinity() ) { - OffshoreSphericalCoords sphCoord1(principalDirs[0]); + RiaOffshoreSphericalCoords sphCoord1(principalDirs[0]); s1inc[vIdx] = cvf::Math::toDegrees(sphCoord1.inc()); s1azi[vIdx] = cvf::Math::toDegrees(sphCoord1.azi()); } @@ -1362,7 +1383,7 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculatePrincipalStressV if ( principals[1] != std::numeric_limits::infinity() ) { - OffshoreSphericalCoords sphCoord2(principalDirs[1]); + RiaOffshoreSphericalCoords sphCoord2(principalDirs[1]); s2inc[vIdx] = cvf::Math::toDegrees(sphCoord2.inc()); s2azi[vIdx] = cvf::Math::toDegrees(sphCoord2.azi()); } @@ -1374,7 +1395,7 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculatePrincipalStressV if ( principals[2] != std::numeric_limits::infinity() ) { - OffshoreSphericalCoords sphCoord3(principalDirs[2]); + RiaOffshoreSphericalCoords sphCoord3(principalDirs[2]); s3inc[vIdx] = cvf::Math::toDegrees(sphCoord3.inc()); s3azi[vIdx] = cvf::Math::toDegrees(sphCoord3.azi()); } @@ -1495,7 +1516,7 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateCompactionValues part->findIntersectingCells(bb, &refElementCandidates); // Also make sure the struct grid is created, as this is required before using OpenMP - part->structGrid(); + part->getOrCreateStructGrid(); } #pragma omp parallel for @@ -1613,7 +1634,10 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateSE(int partIndex for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) { size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); - dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx]; + if (elmNodResIdx < srcSFrameData.size()) + { + dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx]; + } } } else @@ -1621,8 +1645,10 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateSE(int partIndex for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) { size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); - - dstFrameData[elmNodResIdx] = inf; + if (elmNodResIdx < dstFrameData.size()) + { + dstFrameData[elmNodResIdx] = inf; + } } } } @@ -1680,12 +1706,15 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateST_11_22_33(int for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) { size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); - int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(elmNodResIdx); + if (elmNodResIdx < srcSFrameData.size()) + { + int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(elmNodResIdx); - float por = srcPORFrameData[nodeIdx]; - if (por == inf) por = 0.0f; + float por = srcPORFrameData[nodeIdx]; + if (por == inf) por = 0.0f; - dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx] + por; + dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx] + por; + } } } else @@ -1693,7 +1722,10 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateST_11_22_33(int for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) { size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); - dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx]; + if (elmNodResIdx < srcSFrameData.size()) + { + dstFrameData[elmNodResIdx] = -srcSFrameData[elmNodResIdx]; + } } } } @@ -1800,6 +1832,9 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateFormationIndices if (activeFormNames) { + // Has to be done before the parallel loop because the first call allocates. + const RigFemPartGrid* structGrid = femPart->getOrCreateStructGrid(); + int elementCount = femPart->elementCount(); #pragma omp parallel for @@ -1809,20 +1844,23 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateFormationIndices int elmNodeCount = RigFemTypes::elmentNodeCount(elmType); size_t i, j, k; - femPart->structGrid()->ijkFromCellIndex(elmIdx, &i, &j, &k); - int formNameIdx = activeFormNames->formationIndexFromKLayerIdx(k); - - for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) + bool validIndex = structGrid->ijkFromCellIndex(elmIdx, &i, &j, &k); + if (validIndex) { - size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); + int formNameIdx = activeFormNames->formationIndexFromKLayerIdx(k); - if (formNameIdx != -1) - { - dstFrameData[elmNodResIdx] = formNameIdx; - } - else + for (int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx) { - dstFrameData[elmNodResIdx] = HUGE_VAL; + size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); + + if (formNameIdx != -1) + { + dstFrameData[elmNodResIdx] = formNameIdx; + } + else + { + dstFrameData[elmNodResIdx] = HUGE_VAL; + } } } } @@ -2046,14 +2084,17 @@ void RigFemPartResultsCollection::calculateGammaFromFrames(int partIndex, for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx ) { size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); - int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(elmNodResIdx); + if (elmNodResIdx < srcSTFrameData.size()) + { + int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx(elmNodResIdx); - float por = srcPORFrameData[nodeIdx]; + float por = srcPORFrameData[nodeIdx]; - if ( por == inf || fabs(por) < 0.01e6*1.0e-5 ) - dstFrameData[elmNodResIdx] = inf; - else - dstFrameData[elmNodResIdx] = srcSTFrameData[elmNodResIdx]/por; + if (por == inf || fabs(por) < 0.01e6*1.0e-5) + dstFrameData[elmNodResIdx] = inf; + else + dstFrameData[elmNodResIdx] = srcSTFrameData[elmNodResIdx] / por; + } } } else @@ -2061,7 +2102,10 @@ void RigFemPartResultsCollection::calculateGammaFromFrames(int partIndex, for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx ) { size_t elmNodResIdx = femPart->elementNodeResultIdx(elmIdx, elmNodIdx); - dstFrameData[elmNodResIdx] = inf; + if (elmNodResIdx < dstFrameData.size()) + { + dstFrameData[elmNodResIdx] = inf; + } } } } @@ -2122,10 +2166,10 @@ std::vector< RigFemResultAddress> RigFemPartResultsCollection::getResAddrToCompo //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RigFemPartResultsCollection::stepNames() const +std::vector RigFemPartResultsCollection::filteredStepNames() const { CVF_ASSERT(m_readerInterface.notNull()); - return m_readerInterface->stepNames(); + return m_readerInterface->filteredStepNames(); } //-------------------------------------------------------------------------------------------------- @@ -2133,7 +2177,7 @@ std::vector RigFemPartResultsCollection::stepNames() const //-------------------------------------------------------------------------------------------------- int RigFemPartResultsCollection::frameCount() { - return static_cast(stepNames().size()); + return static_cast(filteredStepNames().size()); } //-------------------------------------------------------------------------------------------------- @@ -2215,6 +2259,20 @@ void RigFemPartResultsCollection::deleteResult(const RigFemResultAddress& resVar } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigFemPartResultsCollection::loadedResults() const +{ + std::vector currentResults; + for (auto & femPartResult : m_femPartResults) + { + std::vector partResults = femPartResult->loadedResults(); + currentResults.insert(currentResults.end(), partResults.begin(), partResults.end()); + } + return currentResults; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -2235,40 +2293,19 @@ std::vector RigFemPartResultsCollection::tensors(const RigFemResultA std::vector outputTensors; - RigFemResultAddress address11(resVarAddr.resultPosType, resVarAddr.fieldName, ""); - RigFemResultAddress address22(resVarAddr.resultPosType, resVarAddr.fieldName, ""); - RigFemResultAddress address33(resVarAddr.resultPosType, resVarAddr.fieldName, ""); - RigFemResultAddress address12(resVarAddr.resultPosType, resVarAddr.fieldName, ""); - RigFemResultAddress address13(resVarAddr.resultPosType, resVarAddr.fieldName, ""); - RigFemResultAddress address23(resVarAddr.resultPosType, resVarAddr.fieldName, ""); + std::vector addresses = tensorComponentAddresses(resVarAddr); - if (resVarAddr.fieldName == "SE" || resVarAddr.fieldName == "ST") + if (addresses.empty()) { - address11.componentName = "S11"; - address22.componentName = "S22"; - address33.componentName = "S33"; - address12.componentName = "S12"; - address13.componentName = "S13"; - address23.componentName = "S23"; - } - else if (resVarAddr.fieldName == "NE") - { - address11.componentName = "E11"; - address22.componentName = "E22"; - address33.componentName = "E33"; - address12.componentName = "E12"; - address13.componentName = "E13"; - address23.componentName = "E23"; - } - else return outputTensors; + } - const std::vector& v11 = resultValues(address11, partIndex, frameIndex); - const std::vector& v22 = resultValues(address22, partIndex, frameIndex); - const std::vector& v33 = resultValues(address33, partIndex, frameIndex); - const std::vector& v12 = resultValues(address12, partIndex, frameIndex); - const std::vector& v13 = resultValues(address13, partIndex, frameIndex); - const std::vector& v23 = resultValues(address23, partIndex, frameIndex); + const std::vector& v11 = resultValues(addresses[caf::Ten3f::SXX], partIndex, frameIndex); + const std::vector& v22 = resultValues(addresses[caf::Ten3f::SYY], partIndex, frameIndex); + const std::vector& v33 = resultValues(addresses[caf::Ten3f::SZZ], partIndex, frameIndex); + const std::vector& v12 = resultValues(addresses[caf::Ten3f::SXY], partIndex, frameIndex); + const std::vector& v13 = resultValues(addresses[caf::Ten3f::SZX], partIndex, frameIndex); + const std::vector& v23 = resultValues(addresses[caf::Ten3f::SYZ], partIndex, frameIndex); size_t valCount = v11.size(); outputTensors.resize(valCount); @@ -2540,6 +2577,38 @@ void RigFemPartResultsCollection::posNegClosestToZeroOverAllTensorComponents(con *globalNegClosestToZero = currentNegClosestToZero; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigFemPartResultsCollection::tensorComponentAddresses(const RigFemResultAddress& resVarAddr) +{ + std::vector addresses(6, RigFemResultAddress(resVarAddr.resultPosType, resVarAddr.fieldName, "")); + + if (resVarAddr.fieldName == "SE" || resVarAddr.fieldName == "ST") + { + addresses[caf::Ten3f::SXX].componentName = "S11"; + addresses[caf::Ten3f::SYY].componentName = "S22"; + addresses[caf::Ten3f::SZZ].componentName = "S33"; + addresses[caf::Ten3f::SXY].componentName = "S12"; + addresses[caf::Ten3f::SZX].componentName = "S13"; + addresses[caf::Ten3f::SYZ].componentName = "S23"; + } + else if (resVarAddr.fieldName == "NE") + { + addresses[caf::Ten3f::SXX].componentName = "E11"; + addresses[caf::Ten3f::SYY].componentName = "E22"; + addresses[caf::Ten3f::SZZ].componentName = "E33"; + addresses[caf::Ten3f::SXY].componentName = "E12"; + addresses[caf::Ten3f::SZX].componentName = "E13"; + addresses[caf::Ten3f::SYZ].componentName = "E23"; + } + else + { + return std::vector(); + } + return addresses; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -2556,7 +2625,7 @@ RigFemClosestResultIndexCalculator::RigFemClosestResultIndexCalculator(RigFemPar RigFemResultPosEnum resultPosition, int elementIndex, int m_face, - const cvf::Vec3d& m_intersectionPoint) + const cvf::Vec3d& intersectionPointInDomain) { m_resultIndexToClosestResult = -1; m_closestNodeId = -1; @@ -2574,8 +2643,8 @@ RigFemClosestResultIndexCalculator::RigFemClosestResultIndexCalculator(RigFemPar for ( int lNodeIdx = 0; lNodeIdx < elmNodeCount; ++lNodeIdx ) { int nodeIdx = elmentConn[lNodeIdx]; - cvf::Vec3f nodePos = femPart->nodes().coordinates[nodeIdx]; - float dist = (nodePos - cvf::Vec3f(m_intersectionPoint)).lengthSquared(); + cvf::Vec3f nodePosInDomain = femPart->nodes().coordinates[nodeIdx]; + float dist = (nodePosInDomain - cvf::Vec3f(intersectionPointInDomain)).lengthSquared(); if ( dist < minDist ) { closestLocalNode = lNodeIdx; @@ -2625,8 +2694,8 @@ RigFemClosestResultIndexCalculator::RigFemClosestResultIndexCalculator(RigFemPar for ( int faceNodIdx = 0; faceNodIdx < faceNodeCount; ++faceNodIdx ) { int nodeIdx = elmNodeIndices[localElmNodeIndicesForFace[faceNodIdx]]; - cvf::Vec3f nodePos = femPart->nodes().coordinates[nodeIdx]; - float dist = (nodePos - cvf::Vec3f(m_intersectionPoint)).lengthSquared(); + cvf::Vec3f nodePosInDomain = femPart->nodes().coordinates[nodeIdx]; + float dist = (nodePosInDomain - cvf::Vec3f(intersectionPointInDomain)).lengthSquared(); if ( dist < minDist ) { closestLocFaceNode = faceNodIdx; @@ -2705,7 +2774,7 @@ void findReferenceElementForNode(const RigFemPart& part, size_t nodeIdx, size_t std::vector refElementCandidates; part.findIntersectingCells(bb, &refElementCandidates); - const RigFemPartGrid* grid = part.structGrid(); + const RigFemPartGrid* grid = part.getOrCreateStructGrid(); const std::vector& nodeCoords = part.nodes().coordinates; refElement->elementIdx = cvf::UNDEFINED_SIZE_T; @@ -2713,8 +2782,8 @@ void findReferenceElementForNode(const RigFemPart& part, size_t nodeIdx, size_t size_t i, j, k; for (const size_t elemIdx : refElementCandidates) { - grid->ijkFromCellIndex(elemIdx, &i, &j, &k); - if (k == kRefLayer) + bool validIndex = grid->ijkFromCellIndex(elemIdx, &i, &j, &k); + if (validIndex && k == kRefLayer) { const std::vector nodeIndices = nodesForElement(part, elemIdx); CVF_ASSERT(nodeIndices.size() == 8); diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h index 63c601c009..8268be176a 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemPartResultsCollection.h @@ -64,10 +64,12 @@ class RigFemPartResultsCollection: public cvf::Object double parameterFrictionAngleRad() const { return m_frictionAngleRad; } std::map > scalarFieldAndComponentNames(RigFemResultPosEnum resPos); - std::vector stepNames() const; + std::vector filteredStepNames() const; bool assertResultsLoaded(const RigFemResultAddress& resVarAddr); void deleteResult(const RigFemResultAddress& resVarAddr); + std::vector loadedResults() const; + const std::vector& resultValues(const RigFemResultAddress& resVarAddr, int partIndex, int frameIndex); std::vector tensors(const RigFemResultAddress& resVarAddr, int partIndex, int frameIndex); int partCount() const; @@ -92,6 +94,10 @@ class RigFemPartResultsCollection: public cvf::Object void minMaxScalarValuesOverAllTensorComponents(const RigFemResultAddress& resVarAddr, double* globalMin, double* globalMax); void posNegClosestToZeroOverAllTensorComponents(const RigFemResultAddress& resVarAddr, int frameIndex, double* localPosClosestToZero, double* localNegClosestToZero); void posNegClosestToZeroOverAllTensorComponents(const RigFemResultAddress& resVarAddr, double* globalPosClosestToZero, double* globalNegClosestToZero); + + static std::vector tensorComponentAddresses(const RigFemResultAddress& resVarAddr); + static std::vector tensorPrincipalComponentAdresses(const RigFemResultAddress& resVarAddr); + private: RigFemScalarResultFrames* findOrLoadScalarResult(int partIndex, const RigFemResultAddress& resVarAddr); @@ -127,9 +133,7 @@ class RigFemPartResultsCollection: public cvf::Object RigFemScalarResultFrames* calculateST_12_13_23(int partIndex, const RigFemResultAddress &resVarAddr); RigFemScalarResultFrames* calculateGamma(int partIndex, const RigFemResultAddress &resVarAddr); RigFemScalarResultFrames* calculateFormationIndices(int partIndex, const RigFemResultAddress &resVarAddr); - - static std::vector tensorPrincipalComponentAdresses(const RigFemResultAddress& resVarAddr); - + private: cvf::Collection m_femPartResults; cvf::ref m_readerInterface; @@ -145,39 +149,6 @@ class RigFemPartResultsCollection: public cvf::Object std::map > m_resultStatistics; }; -#include -#include "cvfVector3.h" -#include - -// 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 - -class OffshoreSphericalCoords -{ -public: - explicit OffshoreSphericalCoords(const cvf::Vec3f& vec) - { - // Azimuth: - if (vec[0] == 0.0f && vec[1] == 0.0 ) 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 (incAziR[2] == 0) incAziR[0] = 0.0f; - else incAziR[0] = acos(-vec[2]/incAziR[2]); - - } - - float inc() const { return incAziR[0];} - float azi() const { return incAziR[1];} - float r() const { return incAziR[2];} - -private: - std::array incAziR; -}; class RigFemPart; @@ -188,7 +159,7 @@ class RigFemClosestResultIndexCalculator RigFemResultPosEnum resultPosition, int elementIndex, int m_face, - const cvf::Vec3d& m_intersectionPoint); + const cvf::Vec3d& intersectionPointInDomain); int resultIndexToClosestResult() { return m_resultIndexToClosestResult; } int closestNodeId() { return m_closestNodeId; } diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultAddress.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultAddress.h index c2717d5a9e..72b1e8cd0d 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultAddress.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultAddress.h @@ -30,22 +30,24 @@ class RigFemResultAddress { public: RigFemResultAddress() + : resultPosType(RIG_NODAL) + , fieldName("") + , componentName("") + , timeLapseBaseFrameIdx(NO_TIME_LAPSE) + , refKLayerIndex(NO_COMPACTION) { - resultPosType = RIG_NODAL; - fieldName = ""; - componentName = ""; } RigFemResultAddress(RigFemResultPosEnum resPosType, - const std::string& aFieldName, - const std::string& aComponentName, - int timeLapseBaseFrameIdx = NO_TIME_LAPSE, - int refKLayerIndex = NO_COMPACTION) - : resultPosType(resPosType), - fieldName(aFieldName), - componentName(aComponentName), - timeLapseBaseFrameIdx(timeLapseBaseFrameIdx), - refKLayerIndex(refKLayerIndex) + const std::string& aFieldName, + const std::string& aComponentName, + int timeLapseBaseFrameIdx = NO_TIME_LAPSE, + int refKLayerIndex = NO_COMPACTION) + : resultPosType(resPosType) + , fieldName(aFieldName) + , componentName(aComponentName) + , timeLapseBaseFrameIdx(timeLapseBaseFrameIdx) + , refKLayerIndex(refKLayerIndex) { } diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultPosEnum.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultPosEnum.h index 242535f750..e5ea0a2b03 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultPosEnum.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigFemResultPosEnum.h @@ -25,5 +25,6 @@ enum RigFemResultPosEnum { RIG_INTEGRATION_POINT, RIG_ELEMENT_NODAL_FACE, RIG_FORMATION_NAMES, - RIG_ELEMENT + RIG_ELEMENT, + RIG_WELLPATH_DERIVED }; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp index a354b73ad0..003ee30269 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.cpp @@ -88,17 +88,48 @@ RigFemPartResultsCollection* RigGeoMechCaseData::femPartResults() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -bool RigGeoMechCaseData::openAndReadFemParts(std::string* errorMessage) +bool RigGeoMechCaseData::open(std::string* errorMessage) { - #ifdef USE_ODB_API m_readerInterface = new RifOdbReader; #endif if (m_readerInterface.notNull() && m_readerInterface->openFile(m_geoMechCaseFileName, errorMessage)) { + return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGeoMechCaseData::readTimeSteps(std::string* errorMessage, std::vector* stepNames) +{ + CVF_ASSERT(stepNames); +#ifdef USE_ODB_API + if (m_readerInterface.notNull() && m_readerInterface->isOpen()) + { + *stepNames = m_readerInterface->allStepNames(); + return true; + } +#endif + *errorMessage = std::string("Could not read time steps"); + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigGeoMechCaseData::readFemParts(std::string* errorMessage, const std::vector& timeStepFilter) +{ + CVF_ASSERT(errorMessage); +#ifdef USE_ODB_API + if (m_readerInterface.notNull() && m_readerInterface->isOpen()) + { + m_readerInterface->setTimeStepFilter(timeStepFilter); m_femParts = new RigFemPartCollection(); caf::ProgressInfo progress(10, ""); // Here because the next call uses progress @@ -117,9 +148,11 @@ bool RigGeoMechCaseData::openAndReadFemParts(std::string* errorMessage) { m_femParts->part(pIdx)->assertNodeToElmIndicesIsCalculated(); m_femParts->part(pIdx)->assertElmNeighborsIsCalculated(); - } + } return true; } } +#endif + *errorMessage = std::string("Could not read FEM parts"); return false; } diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h index c76749e029..27a7ce14c9 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RigGeoMechCaseData.h @@ -39,8 +39,9 @@ class RigGeoMechCaseData: public cvf::Object explicit RigGeoMechCaseData(const std::string& fileName); ~RigGeoMechCaseData(); - bool openAndReadFemParts(std::string* errorMessage); - + bool open(std::string* errorMessage); + bool readTimeSteps(std::string* errorMessage, std::vector* stepNames); + bool readFemParts(std::string* errorMessage, const std::vector& timeStepFilter = std::vector()); RigFemPartCollection* femParts(); const RigFemPartCollection* femParts() const; diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RimFemResultObserver.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RimFemResultObserver.cpp new file mode 100644 index 0000000000..48c6c33a3c --- /dev/null +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RimFemResultObserver.cpp @@ -0,0 +1,4 @@ +#include "RimFemResultObserver.h" + +CAF_PDM_ABSTRACT_SOURCE_INIT(RimFemResultObserver, "RimFemResultObserver"); + diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RimFemResultObserver.h b/ApplicationCode/GeoMech/GeoMechDataModel/RimFemResultObserver.h new file mode 100644 index 0000000000..c91f3ce84d --- /dev/null +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RimFemResultObserver.h @@ -0,0 +1,32 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RigFemResultAddress.h" + +#include "cafPdmObject.h" + +#include + +class RimFemResultObserver : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + virtual std::vector observedResults() const = 0; +}; \ No newline at end of file diff --git a/ApplicationCode/GeoMech/GeoMechDataModel/RimGeoMechGeometrySelectionItem.cpp b/ApplicationCode/GeoMech/GeoMechDataModel/RimGeoMechGeometrySelectionItem.cpp index 2ba10104ad..39bfb88364 100644 --- a/ApplicationCode/GeoMech/GeoMechDataModel/RimGeoMechGeometrySelectionItem.cpp +++ b/ApplicationCode/GeoMech/GeoMechDataModel/RimGeoMechGeometrySelectionItem.cpp @@ -69,7 +69,7 @@ void RimGeoMechGeometrySelectionItem::setFromSelectionItem(const RiuGeoMechSelec m_intersectionTriangle_1 = cvf::Vec3d(selectionItem->m_intersectionTriangle[1]); m_intersectionTriangle_2 = cvf::Vec3d(selectionItem->m_intersectionTriangle[2]); - m_localIntersectionPoint = selectionItem->m_localIntersectionPoint; + m_localIntersectionPoint = selectionItem->m_localIntersectionPointInDisplay; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp index 7b79840584..07eb7bcc6e 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemElmVisibilityCalculator.cpp @@ -57,7 +57,7 @@ void RivFemElmVisibilityCalculator::computeRangeVisibility(cvf::UByteArray* elmV { elmVisibilities->resize(femPart->elementCount()); - const RigFemPartGrid* grid = femPart->structGrid(); + const RigFemPartGrid* grid = femPart->getOrCreateStructGrid(); if (rangeFilter.hasIncludeRanges()) { diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp index c6545d675d..bafaff6b79 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.cpp @@ -234,7 +234,7 @@ void RivFemPartGeometryGenerator::computeArrays() qElmNodeResIdx[2] = m_part->elementNodeResultIdx(elmIdx, localElmNodeIndicesForFace[2]); qElmNodeResIdx[3] = m_part->elementNodeResultIdx(elmIdx, localElmNodeIndicesForFace[3]); - #pragma omp critical + #pragma omp critical(critical_section_RivFemPartGeometryGenerator_computeArrays) { vertices.push_back(quadVxs0); vertices.push_back(quadVxs1); diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h index c123ad8bbd..1d34cd6650 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartGeometryGenerator.h @@ -67,7 +67,7 @@ class RivFemPartGeometryGenerator : public cvf::Object { public: explicit RivFemPartGeometryGenerator(const RigFemPart* part); - ~RivFemPartGeometryGenerator(); + ~RivFemPartGeometryGenerator() override; // Setup methods diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp index 2db16ba7a8..ff1b983fb7 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.cpp @@ -2,17 +2,17 @@ // // Copyright (C) 2015- Statoil ASA // Copyright (C) 2015- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -36,6 +36,7 @@ #include "RimRegularLegendConfig.h" #include "RivFemPickSourceInfo.h" +#include "RivMeshLinesSourceInfo.h" #include "RivPartPriority.h" #include "RivResultToTextureMapper.h" #include "RivScalarMapperUtils.h" @@ -48,9 +49,9 @@ #include "cvfMath.h" #include "cvfModelBasicList.h" #include "cvfPart.h" -#include "cvfRenderState_FF.h" #include "cvfRenderStateBlending.h" #include "cvfRenderStatePolygonOffset.h" +#include "cvfRenderState_FF.h" #include "cvfShaderProgram.h" #include "cvfShaderProgramGenerator.h" #include "cvfShaderSourceProvider.h" @@ -59,25 +60,23 @@ #include "cvfTransform.h" #include "cvfUniform.h" - - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RivFemPartPartMgr::RivFemPartPartMgr(const RigFemPart* grid) -: m_surfaceGenerator(grid), - m_grid(grid), - m_opacityLevel(1.0f), - m_defaultColor(cvf::Color3::WHITE) + : m_surfaceGenerator(grid) + , m_grid(grid) + , m_opacityLevel(1.0f) + , m_defaultColor(cvf::Color3::WHITE) { CVF_ASSERT(grid); - m_gridIdx = grid->elementPartId(); - m_cellVisibility = new cvf::UByteArray; + m_gridIdx = grid->elementPartId(); + m_cellVisibility = new cvf::UByteArray; m_surfaceFacesTextureCoords = new cvf::Vec2fArray; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFemPartPartMgr::setTransform(cvf::Transform* scaleTransform) { @@ -85,7 +84,7 @@ void RivFemPartPartMgr::setTransform(cvf::Transform* scaleTransform) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFemPartPartMgr::setCellVisibility(cvf::UByteArray* cellVisibilities) { @@ -99,11 +98,14 @@ void RivFemPartPartMgr::setCellVisibility(cvf::UByteArray* cellVisibilities) generatePartGeometry(m_surfaceGenerator); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- void RivFemPartPartMgr::generatePartGeometry(RivFemPartGeometryGenerator& geoBuilder) { bool useBufferObjects = true; // Surface geometry - { + { m_surfaceFaces = nullptr; // To possibly free memory before adding the new stuff cvf::ref geo = geoBuilder.generateSurface(); @@ -118,7 +120,7 @@ void RivFemPartPartMgr::generatePartGeometry(RivFemPartGeometryGenerator& geoBui cvf::ref part = new cvf::Part; part->setName("FemPart " + cvf::String(m_gridIdx)); - part->setId(m_gridIdx); // Use grid index as part ID + part->setId(m_gridIdx); // Use grid index as part ID part->setDrawable(geo.p()); part->setTransform(m_scaleTransform.p()); @@ -127,10 +129,10 @@ void RivFemPartPartMgr::generatePartGeometry(RivFemPartGeometryGenerator& geoBui part->setSourceInfo(si.p()); part->updateBoundingBox(); - + // Set default effect caf::SurfaceEffectGenerator geometryEffgen(cvf::Color4f(cvf::Color3f::WHITE), caf::PO_1); - cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); part->setEffect(geometryOnlyEffect.p()); part->setEnableMask(surfaceBit); m_surfaceFaces = part; @@ -158,7 +160,7 @@ void RivFemPartPartMgr::generatePartGeometry(RivFemPartGeometryGenerator& geoBui RiaPreferences* prefs = RiaApplication::instance()->preferences(); - cvf::ref eff; + cvf::ref eff; caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); eff = effGen.generateCachedEffect(); @@ -166,24 +168,27 @@ void RivFemPartPartMgr::generatePartGeometry(RivFemPartGeometryGenerator& geoBui part->setEnableMask(meshSurfaceBit); part->setEffect(eff.p()); + + part->setSourceInfo(new RivMeshLinesSourceInfo(nullptr)); + m_surfaceGridLines = part; } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFemPartPartMgr::appendPartsToModel(cvf::ModelBasicList* model) { CVF_ASSERT(model != nullptr); - if(m_surfaceFaces.notNull() ) model->addPart(m_surfaceFaces.p() ); - if(m_surfaceGridLines.notNull()) model->addPart(m_surfaceGridLines.p()); + if (m_surfaceFaces.notNull()) model->addPart(m_surfaceFaces.p()); + if (m_surfaceGridLines.notNull()) model->addPart(m_surfaceGridLines.p()); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const RivFemPartGeometryGenerator* RivFemPartPartMgr::surfaceGenerator() const { @@ -191,7 +196,7 @@ const RivFemPartGeometryGenerator* RivFemPartPartMgr::surfaceGenerator() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFemPartPartMgr::updateCellColor(cvf::Color4f color) { @@ -199,7 +204,7 @@ void RivFemPartPartMgr::updateCellColor(cvf::Color4f color) // Set default effect caf::SurfaceEffectGenerator geometryEffgen(color, caf::PO_1); - cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); if (m_surfaceFaces.notNull()) m_surfaceFaces->setEffect(geometryOnlyEffect.p()); @@ -225,7 +230,7 @@ void RivFemPartPartMgr::updateCellColor(cvf::Color4f color) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFemPartPartMgr::updateCellResultColor(size_t timeStepIndex, RimGeoMechCellColors* cellResultColors) { @@ -236,34 +241,36 @@ void RivFemPartPartMgr::updateCellResultColor(size_t timeStepIndex, RimGeoMechCe // Outer surface if (m_surfaceFaces.notNull()) { - const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); RigGeoMechCaseData* caseData = cellResultColors->ownerCaseData(); - + if (!caseData) return; RigFemResultAddress resVarAddress = cellResultColors->resultAddress(); // Do a "Hack" to show elm nodal and not nodal POR results - if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") resVarAddress.resultPosType = RIG_ELEMENT_NODAL; + if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") + { + resVarAddress.resultPosType = RIG_ELEMENT_NODAL; + } - const std::vector& resultValues = caseData->femPartResults()->resultValues(resVarAddress, m_gridIdx, (int)timeStepIndex); + const std::vector& resultValues = + caseData->femPartResults()->resultValues(resVarAddress, m_gridIdx, (int)timeStepIndex); const std::vector* vxToResultMapping = nullptr; - int vxCount = 0; + int vxCount = 0; if (resVarAddress.resultPosType == RIG_NODAL) { vxToResultMapping = &(m_surfaceGenerator.quadVerticesToNodeIdxMapping()); } - else if ( resVarAddress.resultPosType == RIG_ELEMENT_NODAL - || resVarAddress.resultPosType == RIG_INTEGRATION_POINT - || resVarAddress.resultPosType == RIG_FORMATION_NAMES) + else if (resVarAddress.resultPosType == RIG_ELEMENT_NODAL || resVarAddress.resultPosType == RIG_INTEGRATION_POINT || + resVarAddress.resultPosType == RIG_FORMATION_NAMES) { vxToResultMapping = &(m_surfaceGenerator.quadVerticesToGlobalElmNodeIdx()); } - else if(resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE) + else if (resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE) { vxToResultMapping = &(m_surfaceGenerator.quadVerticesToGlobalElmFaceNodeIdx()); } @@ -271,9 +278,9 @@ void RivFemPartPartMgr::updateCellResultColor(size_t timeStepIndex, RimGeoMechCe { vxToResultMapping = &(m_surfaceGenerator.quadVerticesToGlobalElmIdx()); } - + if (!vxToResultMapping) return; - + vxCount = static_cast(vxToResultMapping->size()); m_surfaceFacesTextureCoords->resize(vxCount); @@ -285,7 +292,7 @@ void RivFemPartPartMgr::updateCellResultColor(size_t timeStepIndex, RimGeoMechCe { cvf::Vec2f* rawPtr = m_surfaceFacesTextureCoords->ptr(); - #pragma omp parallel for schedule(dynamic) +#pragma omp parallel for schedule(dynamic) for (int quadStartIdx = 0; quadStartIdx < vxCount; quadStartIdx += 4) { float resultValue1 = resultValues[(*vxToResultMapping)[quadStartIdx + 0]]; @@ -293,22 +300,21 @@ void RivFemPartPartMgr::updateCellResultColor(size_t timeStepIndex, RimGeoMechCe float resultValue3 = resultValues[(*vxToResultMapping)[quadStartIdx + 2]]; float resultValue4 = resultValues[(*vxToResultMapping)[quadStartIdx + 3]]; - if ( resultValue1 == HUGE_VAL || resultValue1 != resultValue1 // a != a is true for NAN's - || resultValue2 == HUGE_VAL || resultValue2 != resultValue2 - || resultValue3 == HUGE_VAL || resultValue3 != resultValue3 - || resultValue4 == HUGE_VAL || resultValue4 != resultValue4) + if (resultValue1 == HUGE_VAL || resultValue1 != resultValue1 // a != a is true for NAN's + || resultValue2 == HUGE_VAL || resultValue2 != resultValue2 || resultValue3 == HUGE_VAL || + resultValue3 != resultValue3 || resultValue4 == HUGE_VAL || resultValue4 != resultValue4) { - rawPtr[quadStartIdx][1] = 1.0f; - rawPtr[quadStartIdx + 1][1] = 1.0f; - rawPtr[quadStartIdx + 2][1] = 1.0f; - rawPtr[quadStartIdx + 3][1] = 1.0f; + rawPtr[quadStartIdx][1] = 1.0f; + rawPtr[quadStartIdx + 1][1] = 1.0f; + rawPtr[quadStartIdx + 2][1] = 1.0f; + rawPtr[quadStartIdx + 3][1] = 1.0f; } else { - rawPtr[quadStartIdx] = mapper->mapToTextureCoord(resultValue1); - rawPtr[quadStartIdx + 1] = mapper->mapToTextureCoord(resultValue2); - rawPtr[quadStartIdx + 2] = mapper->mapToTextureCoord(resultValue3); - rawPtr[quadStartIdx + 3] = mapper->mapToTextureCoord(resultValue4); + rawPtr[quadStartIdx] = mapper->mapToTextureCoord(resultValue1); + rawPtr[quadStartIdx + 1] = mapper->mapToTextureCoord(resultValue2); + rawPtr[quadStartIdx + 2] = mapper->mapToTextureCoord(resultValue3); + rawPtr[quadStartIdx + 3] = mapper->mapToTextureCoord(resultValue4); } } } @@ -317,22 +323,16 @@ void RivFemPartPartMgr::updateCellResultColor(size_t timeStepIndex, RimGeoMechCe cellResultColors->firstAncestorOrThisOfType(view); CVF_ASSERT(view); - RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), - m_surfaceFacesTextureCoords.p(), - mapper, - m_opacityLevel, - caf::FC_NONE, + RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), + m_surfaceFacesTextureCoords.p(), + mapper, + m_opacityLevel, + caf::FC_NONE, view->isLightingDisabled()); } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RivFemPartPartMgr::~RivFemPartPartMgr() -{ - -} - - +RivFemPartPartMgr::~RivFemPartPartMgr() {} diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h index 9d49715cc5..031baf60e8 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPartPartMgr.h @@ -48,7 +48,7 @@ class RivFemPartPartMgr: public cvf::Object { public: explicit RivFemPartPartMgr(const RigFemPart* femPart); - ~RivFemPartPartMgr(); + ~RivFemPartPartMgr() override; void setTransform(cvf::Transform* scaleTransform); void setCellVisibility(cvf::UByteArray* cellVisibilities ); cvf::ref cellVisibility() { return m_cellVisibility;} diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPickSourceInfo.h b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPickSourceInfo.h index b1d3a7a89e..c1f9ce29a9 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPickSourceInfo.h +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivFemPickSourceInfo.h @@ -28,7 +28,7 @@ class RivFemPickSourceInfo : public cvf::Object { public: RivFemPickSourceInfo(int partIndex, RivFemPartTriangleToElmMapper * triangleToElmMapper); - ~RivFemPickSourceInfo(); + ~RivFemPickSourceInfo() override; int femPartIndex() const { return m_fempartIndex; } const RivFemPartTriangleToElmMapper* triangleToElmMapper() const { return m_triangleToElmMapper.p(); } diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.h b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.h index ddaad50a0c..228b618709 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.h +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgr.h @@ -19,6 +19,7 @@ #pragma once +#include "cvfBase.h" #include "cvfArray.h" #include "cvfCollection.h" @@ -45,7 +46,7 @@ class RivGeoMechPartMgr: public cvf::Object { public: RivGeoMechPartMgr(); - ~RivGeoMechPartMgr(); + ~RivGeoMechPartMgr() override; int initializedFemPartCount() { return static_cast(m_femPartPartMgrs.size());} void clearAndSetReservoir(const RigGeoMechCaseData* geoMechCase); diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgrCache.h b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgrCache.h index e8c4c52d56..98a94f6d5f 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgrCache.h +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechPartMgrCache.h @@ -20,6 +20,7 @@ #pragma once #include "RivCellSetEnum.h" +#include "RivGeoMechPartMgr.h" #include "cvfBase.h" #include "cvfObject.h" @@ -27,14 +28,13 @@ #include #include -class RivGeoMechPartMgr; class RivGeoMechPartMgrGeneratorInterface; class RivGeoMechPartMgrCache : public cvf::Object { public: RivGeoMechPartMgrCache(); - ~RivGeoMechPartMgrCache(); + ~RivGeoMechPartMgrCache() override; class Key { diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp index 33c489f26c..4ea1db53a3 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.cpp @@ -105,7 +105,8 @@ void RivGeoMechVizLogic::updateStaticCellColors(int timeStepIndex) for (size_t pmIdx = 0; pmIdx < visiblePartMgrs.size(); ++pmIdx) { RivGeoMechPartMgr* partMgr = m_partMgrCache->partMgr(visiblePartMgrs[pmIdx]); - partMgr->updateCellColor(cvf::Color4f(cvf::Color3f::ORANGE)); + auto color = staticCellColor(); + partMgr->updateCellColor(cvf::Color4f(color)); } } @@ -173,6 +174,14 @@ const cvf::ref RivGeoMechVizLogic::partMgrCache() const return m_partMgrCache; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RivGeoMechVizLogic::staticCellColor() +{ + return cvf::Color3f::ORANGE; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h index 189838fe69..0660435b33 100644 --- a/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h +++ b/ApplicationCode/GeoMech/GeoMechVisualization/RivGeoMechVizLogic.h @@ -41,7 +41,7 @@ class RivGeoMechVizLogic : public cvf::Object public: explicit RivGeoMechVizLogic(RimGeoMechView * geomView); - virtual ~RivGeoMechVizLogic(); + ~RivGeoMechVizLogic() override; void appendNoAnimPartsToModel(cvf::ModelBasicList* model); void appendPartsToModel(int timeStepIndex, cvf::ModelBasicList* model); @@ -51,6 +51,8 @@ class RivGeoMechVizLogic : public cvf::Object void calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility, int timeStepIndex); std::vector keysToVisiblePartMgrs(int timeStepIndex) const; const cvf::ref partMgrCache() const; + + static cvf::Color3f staticCellColor(); private: RivGeoMechPartMgr* getUpdatedPartMgr(RivGeoMechPartMgrCache::Key partMgrKey); diff --git a/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.cpp b/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.cpp index 84c784f9fd..e330453867 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.cpp +++ b/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.cpp @@ -36,3 +36,55 @@ RifGeoMechReaderInterface::~RifGeoMechReaderInterface() { } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifGeoMechReaderInterface::setTimeStepFilter(const std::vector& fileTimeStepIndices) +{ + m_fileTimeStepIndices.reserve(fileTimeStepIndices.size()); + for (size_t stepIndex : fileTimeStepIndices) + { + m_fileTimeStepIndices.push_back(static_cast(stepIndex)); + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifGeoMechReaderInterface::isTimeStepIncludedByFilter(int timeStepIndex) const +{ + CVF_ASSERT(timeStepIndex >= 0); + if (m_fileTimeStepIndices.empty()) return true; + + for (auto i : m_fileTimeStepIndices) + { + if (i == static_cast(timeStepIndex)) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RifGeoMechReaderInterface::timeStepIndexOnFile(int timeStepIndex) const +{ + if (m_fileTimeStepIndices.empty()) + { + return timeStepIndex; + } + CVF_ASSERT(timeStepIndex >= 0); + CVF_ASSERT(static_cast(timeStepIndex) < m_fileTimeStepIndices.size()); + + if (static_cast(timeStepIndex) < m_fileTimeStepIndices.size()) + { + return static_cast(m_fileTimeStepIndices[timeStepIndex]); + } + + return timeStepIndex; +} \ No newline at end of file diff --git a/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h b/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h index 6ec6370e65..10ade9ac64 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h +++ b/ApplicationCode/GeoMech/OdbReader/RifGeoMechReaderInterface.h @@ -42,9 +42,10 @@ class RifGeoMechReaderInterface : public cvf::Object virtual ~RifGeoMechReaderInterface(); virtual bool openFile(const std::string& fileName, std::string* errorMessage) = 0; - + virtual bool isOpen() const = 0; virtual bool readFemParts(RigFemPartCollection* geoMechCase) = 0; - virtual std::vector stepNames() const = 0; + virtual std::vector allStepNames() const = 0; + virtual std::vector filteredStepNames() const = 0; virtual std::vector frameTimes(int stepIndex) const = 0; virtual std::vector elementSetNames(int partIndex) = 0; @@ -60,5 +61,9 @@ class RifGeoMechReaderInterface : public cvf::Object virtual void readElementNodeField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) = 0; virtual void readIntegrationPointField(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex, std::vector*>* resultValues) = 0; + void setTimeStepFilter(const std::vector& fileTimeStepIndices); + bool isTimeStepIncludedByFilter(int timeStepIndex) const; + int timeStepIndexOnFile(int timeStepIndex) const; private: + std::vector m_fileTimeStepIndices; }; diff --git a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp index f2844f7c2f..18fc87fdae 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp +++ b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.cpp @@ -234,6 +234,14 @@ bool RifOdbReader::openFile(const std::string& fileName, std::string* errorMessa } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifOdbReader::isOpen() const +{ + return m_odb != NULL; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -422,7 +430,7 @@ bool RifOdbReader::readFemParts(RigFemPartCollection* femParts) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RifOdbReader::stepNames() const +std::vector RifOdbReader::allStepNames() const { CVF_ASSERT(m_odb != NULL); @@ -430,9 +438,34 @@ std::vector RifOdbReader::stepNames() const odb_StepRepository stepRepository = m_odb->steps(); odb_StepRepositoryIT sIter(stepRepository); - for (sIter.first(); !sIter.isDone(); sIter.next()) + for (sIter.first(); !sIter.isDone(); sIter.next()) { - stepNames.push_back(stepRepository[sIter.currentKey()].name().CStr()); + std::string stepName(sIter.currentValue().name().CStr()); + stepNames.push_back(stepName); + } + + return stepNames; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifOdbReader::filteredStepNames() const +{ + CVF_ASSERT(m_odb != NULL); + + std::vector stepNames; + + odb_StepRepository stepRepository = m_odb->steps(); + odb_StepRepositoryIT sIter(stepRepository); + int stepIndex = 0; + for (sIter.first(); !sIter.isDone(); sIter.next()) + { + std::string stepName(sIter.currentValue().name().CStr()); + if (this->isTimeStepIncludedByFilter(stepIndex++)) + { + stepNames.push_back(stepName); + } } return stepNames; @@ -449,7 +482,10 @@ std::vector RifOdbReader::frameTimes(int stepIndex) const odb_StepRepository& stepRepository = m_odb->steps(); odb_StepList stepList = stepRepository.stepList(); - odb_Step& step = stepList.Get(stepIndex); + + int stepFileIndex = this->timeStepIndexOnFile(stepIndex); + + odb_Step& step = stepList.Get(stepFileIndex); odb_SequenceFrame& stepFrames = step.frames(); @@ -573,7 +609,10 @@ const odb_Frame& RifOdbReader::stepFrame(int stepIndex, int frameIndex) const const odb_StepRepository& stepRepository = m_odb->steps(); const odb_StepList& stepList = stepRepository.stepList(); - const odb_Step& step = stepList.ConstGet(stepIndex); + + int stepFileIndex = this->timeStepIndexOnFile(stepIndex); + + const odb_Step& step = stepList.ConstGet(stepFileIndex); const odb_SequenceFrame& stepFrames = step.frames(); return stepFrames.constGet(frameIndex); @@ -640,29 +679,6 @@ size_t RifOdbReader::componentsCount(const std::string& fieldName, ResultPositio } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -int RifOdbReader::componentIndex(const RifOdbResultKey& result, const std::string& componentName) -{ - std::vector compNames = componentNames(result); - - // If there are no component names, we expect the field to be a pure scalar. - // Then an empty string is the valid component name - if (!compNames.size() && componentName == "") return 0; - - for (size_t i = 0; i < compNames.size(); i++) - { - if (compNames[i] == componentName) - { - return static_cast(i); - } - } - - return -1; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h index 6e2df2008d..55fd3f514c 100644 --- a/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h +++ b/ApplicationCode/GeoMech/OdbReader/RifOdbReader.h @@ -42,9 +42,10 @@ class RifOdbReader : public RifGeoMechReaderInterface virtual ~RifOdbReader(); virtual bool openFile(const std::string& fileName, std::string* errorMessage); - + virtual bool isOpen() const; virtual bool readFemParts(RigFemPartCollection* geoMechCase); - virtual std::vector stepNames() const override; + virtual std::vector allStepNames() const override; + virtual std::vector filteredStepNames() const override; virtual std::vector frameTimes(int stepIndex) const override; virtual std::vector elementSetNames(int partIndex); @@ -93,9 +94,8 @@ class RifOdbReader : public RifGeoMechReaderInterface size_t resultItemCount(const std::string& fieldName, int partIndex, int stepIndex, int frameIndex); size_t componentsCount(const std::string& fieldName, ResultPosition position); const odb_Frame& stepFrame(int stepIndex, int frameIndex) const; - odb_Instance* instance(int instanceIndex); + odb_Instance* instance(int instanceIndex); - int componentIndex(const RifOdbResultKey& result, const std::string& componentName); std::vector componentNames(const RifOdbResultKey& result); std::map< std::string, std::vector > fieldAndComponentNames(ResultPosition position); std::map< RifOdbResultKey, std::vector > readResultsMetaData(odb_Odb* odb); diff --git a/ApplicationCode/ModelVisualization/CMakeLists_files.cmake b/ApplicationCode/ModelVisualization/CMakeLists_files.cmake index 16b6117694..2750550fdd 100644 --- a/ApplicationCode/ModelVisualization/CMakeLists_files.cmake +++ b/ApplicationCode/ModelVisualization/CMakeLists_files.cmake @@ -44,6 +44,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionFactorGeometryGenerator.h ${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionSourceInfo.h ${CMAKE_CURRENT_LIST_DIR}/RivSimWellConnectionSourceInfo.h ${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogDrawSurfaceGenerator.h +${CMAKE_CURRENT_LIST_DIR}/RivMeshLinesSourceInfo.h +${CMAKE_CURRENT_LIST_DIR}/RivContourMapProjectionPartMgr.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -86,6 +88,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionFactorGeometryGenerator.cpp ${CMAKE_CURRENT_LIST_DIR}/RivWellConnectionSourceInfo.cpp ${CMAKE_CURRENT_LIST_DIR}/RivSimWellConnectionSourceInfo.cpp ${CMAKE_CURRENT_LIST_DIR}/Riv3dWellLogDrawSurfaceGenerator.cpp +${CMAKE_CURRENT_LIST_DIR}/RivMeshLinesSourceInfo.cpp +${CMAKE_CURRENT_LIST_DIR}/RivContourMapProjectionPartMgr.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ModelVisualization/GridBox/RivGridBoxGenerator.cpp b/ApplicationCode/ModelVisualization/GridBox/RivGridBoxGenerator.cpp index b818027b04..bd029f1fa1 100644 --- a/ApplicationCode/ModelVisualization/GridBox/RivGridBoxGenerator.cpp +++ b/ApplicationCode/ModelVisualization/GridBox/RivGridBoxGenerator.cpp @@ -69,7 +69,7 @@ void RivGridBoxGenerator::setDisplayModelOffset(cvf::Vec3d offset) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivGridBoxGenerator::setGridBoxDomainCoordBoundingBox(const cvf::BoundingBox& bb) +void RivGridBoxGenerator::setGridBoxDomainCoordBoundingBox(const cvf::BoundingBox& incomingBB) { double expandFactor = 0.05; @@ -77,6 +77,16 @@ void RivGridBoxGenerator::setGridBoxDomainCoordBoundingBox(const cvf::BoundingBo // Expand the range for ScalarMapperDiscreteLinear until the geometry bounding box has a generated tick mark coords // both below minimum and above maximum bounding box coords + cvf::BoundingBox bb; + if (incomingBB.isValid()) + { + bb = incomingBB; + } + else + { + bb.add(cvf::Vec3d::ZERO); + } + cvf::Vec3d min = bb.min(); cvf::Vec3d max = bb.max(); @@ -618,10 +628,6 @@ void RivGridBoxGenerator::createLegend(EdgeType edge, cvf::Collection caf::MeshEffectGenerator effGen(m_gridLegendColor); eff = effGen.generateUnCachedEffect(); - cvf::ref depth = new cvf::RenderStateDepth; - depth->enableDepthTest(false); - eff->setRenderState(depth.p()); - part->setPriority(RivPartPriority::PartType::Text); part->setEffect(eff.p()); diff --git a/ApplicationCode/ModelVisualization/GridBox/RivPatchGenerator.cpp b/ApplicationCode/ModelVisualization/GridBox/RivPatchGenerator.cpp index 773603c6a6..1adea52bec 100644 --- a/ApplicationCode/ModelVisualization/GridBox/RivPatchGenerator.cpp +++ b/ApplicationCode/ModelVisualization/GridBox/RivPatchGenerator.cpp @@ -65,23 +65,6 @@ void RivPatchGenerator::setSubdivisions(const std::vector& uValues, cons m_vValues = vValues; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivPatchGenerator::setQuads(bool useQuads) -{ - m_useQuads = useQuads; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivPatchGenerator::setWindingCCW(bool windingCCW) -{ - m_windingCCW = windingCCW; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ModelVisualization/GridBox/RivPatchGenerator.h b/ApplicationCode/ModelVisualization/GridBox/RivPatchGenerator.h index c944c86ea1..55c8390e82 100644 --- a/ApplicationCode/ModelVisualization/GridBox/RivPatchGenerator.h +++ b/ApplicationCode/ModelVisualization/GridBox/RivPatchGenerator.h @@ -45,9 +45,6 @@ class RivPatchGenerator void setAxes(const cvf::Vec3d& axisU, const cvf::Vec3d& axisV); void setSubdivisions(const std::vector& uValues, const std::vector& vValues); - void setQuads(bool useQuads); - void setWindingCCW(bool windingCCW); - void generate(cvf::GeometryBuilder* builder); private: diff --git a/ApplicationCode/ModelVisualization/Intersections/RivHexGridIntersectionTools.cpp b/ApplicationCode/ModelVisualization/Intersections/RivHexGridIntersectionTools.cpp index 778d5df51c..b77964b7e0 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivHexGridIntersectionTools.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivHexGridIntersectionTools.cpp @@ -85,8 +85,12 @@ void RivEclipseIntersectionGrid::cellCornerVertices(size_t cellIndex, cvf::Vec3d //-------------------------------------------------------------------------------------------------- void RivEclipseIntersectionGrid::cellCornerIndices(size_t cellIndex, size_t cornerIndices[8]) const { - const caf::SizeTArray8& cornerIndicesSource = m_mainGrid->globalCellArray()[cellIndex].cornerIndices(); - memcpy(cornerIndices, cornerIndicesSource.data(), 8); + const std::array& cornerIndicesSource = m_mainGrid->globalCellArray()[cellIndex].cornerIndices(); + + for (size_t i = 0; i < 8; i++) + { + cornerIndices[i] = cornerIndicesSource[i]; + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ModelVisualization/Intersections/RivHexGridIntersectionTools.h b/ApplicationCode/ModelVisualization/Intersections/RivHexGridIntersectionTools.h index 5d9b147e27..24271ec944 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivHexGridIntersectionTools.h +++ b/ApplicationCode/ModelVisualization/Intersections/RivHexGridIntersectionTools.h @@ -23,9 +23,11 @@ #include "cvfVector3.h" #include "cvfBoundingBox.h" -#include #include "cvfStructGrid.h" +#include +#include + class RigActiveCellInfo; class RigFemPart; class RigMainGrid; @@ -55,13 +57,13 @@ class RivEclipseIntersectionGrid : public RivIntersectionHexGridInterface public: RivEclipseIntersectionGrid(const RigMainGrid * mainGrid, const RigActiveCellInfo* activeCellInfo, bool showInactiveCells); - virtual cvf::Vec3d displayOffset() const; - virtual cvf::BoundingBox boundingBox() const; - virtual void findIntersectingCells(const cvf::BoundingBox& intersectingBB, std::vector* intersectedCells) const; - virtual bool useCell(size_t cellIndex) const; - virtual void cellCornerVertices(size_t cellIndex, cvf::Vec3d cellCorners[8]) const; - virtual void cellCornerIndices(size_t cellIndex, size_t cornerIndices[8]) const; - virtual const RigFault* findFaultFromCellIndexAndCellFace(size_t reservoirCellIndex, + cvf::Vec3d displayOffset() const override; + cvf::BoundingBox boundingBox() const override; + void findIntersectingCells(const cvf::BoundingBox& intersectingBB, std::vector* intersectedCells) const override; + bool useCell(size_t cellIndex) const override; + void cellCornerVertices(size_t cellIndex, cvf::Vec3d cellCorners[8]) const override; + void cellCornerIndices(size_t cellIndex, size_t cornerIndices[8]) const override; + const RigFault* findFaultFromCellIndexAndCellFace(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const override; private: @@ -78,13 +80,13 @@ class RivFemIntersectionGrid : public RivIntersectionHexGridInterface public: explicit RivFemIntersectionGrid(const RigFemPart * femPart); - virtual cvf::Vec3d displayOffset() const; - virtual cvf::BoundingBox boundingBox() const; - virtual void findIntersectingCells(const cvf::BoundingBox& intersectingBB, std::vector* intersectedCells) const; - virtual bool useCell(size_t cellIndex) const; - virtual void cellCornerVertices(size_t cellIndex, cvf::Vec3d cellCorners[8]) const; - virtual void cellCornerIndices(size_t cellIndex, size_t cornerIndices[8]) const; - virtual const RigFault* findFaultFromCellIndexAndCellFace(size_t reservoirCellIndex, + cvf::Vec3d displayOffset() const override; + cvf::BoundingBox boundingBox() const override; + void findIntersectingCells(const cvf::BoundingBox& intersectingBB, std::vector* intersectedCells) const override; + bool useCell(size_t cellIndex) const override; + void cellCornerVertices(size_t cellIndex, cvf::Vec3d cellCorners[8]) const override; + void cellCornerIndices(size_t cellIndex, size_t cornerIndices[8]) const override; + const RigFault* findFaultFromCellIndexAndCellFace(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const override; private: @@ -187,8 +189,7 @@ Substitution and reorganizing gives the expressions seen below. float weight(int idx)const { return m_weights[idx]; } private: - - size_t m_vxIds[8]; - float m_weights[8]; + std::array m_vxIds; + std::array m_weights; int m_count; }; diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxGeometryGenerator.h b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxGeometryGenerator.h index 5b49d0a129..64d0a512bd 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxGeometryGenerator.h @@ -44,7 +44,7 @@ class RivIntersectionBoxGeometryGenerator : public cvf::Object RivIntersectionBoxGeometryGenerator(RimIntersectionBox* intersectionBox, const RivIntersectionHexGridInterface* grid); - ~RivIntersectionBoxGeometryGenerator(); + ~RivIntersectionBoxGeometryGenerator() override; bool isAnyGeometryPresent() const; diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp index 000d5decf3..3f0aafdaac 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -37,6 +37,7 @@ #include "RivIntersectionBoxSourceInfo.h" #include "RivIntersectionPartMgr.h" +#include "RivMeshLinesSourceInfo.h" #include "RivPartPriority.h" #include "RivResultToTextureMapper.h" #include "RivScalarMapperUtils.h" @@ -47,19 +48,17 @@ #include "cvfModelBasicList.h" #include "cvfPart.h" #include "cvfPrimitiveSetDirect.h" -#include "cvfRenderState_FF.h" #include "cvfRenderStateDepth.h" #include "cvfRenderStatePoint.h" +#include "cvfRenderState_FF.h" #include "cvfStructGridGeometryGenerator.h" - - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RivIntersectionBoxPartMgr::RivIntersectionBoxPartMgr(RimIntersectionBox* intersectionBox) - : m_rimIntersectionBox(intersectionBox), - m_defaultColor(cvf::Color3::WHITE) + : m_rimIntersectionBox(intersectionBox) + , m_defaultColor(cvf::Color3::WHITE) { CVF_ASSERT(m_rimIntersectionBox); @@ -70,20 +69,19 @@ RivIntersectionBoxPartMgr::RivIntersectionBoxPartMgr(RimIntersectionBox* interse } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionBoxPartMgr::applySingleColorEffect() { - m_defaultColor = cvf::Color3f::OLIVE;//m_rimCrossSection->CrossSectionColor(); + m_defaultColor = cvf::Color3f::OLIVE; // m_rimCrossSection->CrossSectionColor(); this->updatePartEffect(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) { - if (!m_intersectionBoxGenerator->isAnyGeometryPresent()) return; RimEclipseView* eclipseView; @@ -94,18 +92,16 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) RimEclipseCellColors* cellResultColors = eclipseView->cellResult(); CVF_ASSERT(cellResultColors); - RigEclipseCaseData* eclipseCase = eclipseView->eclipseCase()->eclipseCaseData(); - // CrossSections if (m_intersectionBoxFaces.notNull()) { if (cellResultColors->isTernarySaturationSelected()) { - RivTernaryTextureCoordsCreator texturer(cellResultColors, - cellResultColors->ternaryLegendConfig()->scalarMapper(), - timeStepIndex); - - texturer.createTextureCoords(m_intersectionBoxFacesTextureCoords.p(), m_intersectionBoxGenerator->triangleToCellIndex()); + RivTernaryTextureCoordsCreator texturer( + cellResultColors, cellResultColors->ternaryLegendConfig()->scalarMapper(), timeStepIndex); + + texturer.createTextureCoords(m_intersectionBoxFacesTextureCoords.p(), + m_intersectionBoxGenerator->triangleToCellIndex()); const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_intersectionBoxFaces.p(), @@ -119,7 +115,7 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) { CVF_ASSERT(m_intersectionBoxGenerator.notNull()); - const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); + const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); cvf::ref resultAccessor; if (RiaDefines::isPerCellFaceResult(cellResultColors->resultVariable())) @@ -128,17 +124,14 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) } else { - resultAccessor = RigResultAccessorFactory::createFromResultDefinition(cellResultColors->reservoirView()->eclipseCase()->eclipseCaseData(), - 0, - timeStepIndex, - cellResultColors); + resultAccessor = RigResultAccessorFactory::createFromResultDefinition( + cellResultColors->reservoirView()->eclipseCase()->eclipseCaseData(), 0, timeStepIndex, cellResultColors); } RivIntersectionPartMgr::calculateEclipseTextureCoordinates(m_intersectionBoxFacesTextureCoords.p(), - m_intersectionBoxGenerator->triangleToCellIndex(), - resultAccessor.p(), - mapper); - + m_intersectionBoxGenerator->triangleToCellIndex(), + resultAccessor.p(), + mapper); RivScalarMapperUtils::applyTextureResultsToPart(m_intersectionBoxFaces.p(), m_intersectionBoxFacesTextureCoords.p(), @@ -146,7 +139,7 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) 1.0, caf::FC_NONE, eclipseView->isLightingDisabled()); - } + } } } @@ -156,23 +149,22 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) if (geoView) { RimGeoMechCellColors* cellResultColors = geoView->cellResult(); - RigGeoMechCaseData* caseData = cellResultColors->ownerCaseData(); - + RigGeoMechCaseData* caseData = cellResultColors->ownerCaseData(); + if (!caseData) return; - RigFemResultAddress resVarAddress = cellResultColors->resultAddress(); + RigFemResultAddress resVarAddress = cellResultColors->resultAddress(); + + const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); - const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); - if (resVarAddress.resultPosType == RIG_ELEMENT) { - const std::vector& resultValues = caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex); - const std::vector& triangleToCellIdx = m_intersectionBoxGenerator->triangleToCellIndex(); + const std::vector& resultValues = + caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex); + const std::vector& triangleToCellIdx = m_intersectionBoxGenerator->triangleToCellIndex(); - RivIntersectionPartMgr::calculateElementBasedGeoMechTextureCoords(m_intersectionBoxFacesTextureCoords.p(), - resultValues, - triangleToCellIdx, - mapper); + RivIntersectionPartMgr::calculateElementBasedGeoMechTextureCoords( + m_intersectionBoxFacesTextureCoords.p(), resultValues, triangleToCellIdx, mapper); } else if (resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE) { @@ -181,15 +173,14 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) if (resVarAddress.componentName == "Pazi" || resVarAddress.componentName == "Pinc") { - RivIntersectionPartMgr::calculatePlaneAngleTextureCoords(m_intersectionBoxFacesTextureCoords.p(), - triangelVxes, - resVarAddress, - mapper); + RivIntersectionPartMgr::calculatePlaneAngleTextureCoords( + m_intersectionBoxFacesTextureCoords.p(), triangelVxes, resVarAddress, mapper); } else { - const std::vector &vertexWeights = m_intersectionBoxGenerator->triangleVxToCellCornerInterpolationWeights(); - + const std::vector& vertexWeights = + m_intersectionBoxGenerator->triangleVxToCellCornerInterpolationWeights(); + RivIntersectionPartMgr::calculateGeoMechTensorXfTextureCoords(m_intersectionBoxFacesTextureCoords.p(), triangelVxes, vertexWeights, @@ -202,37 +193,34 @@ void RivIntersectionBoxPartMgr::updateCellResultColor(size_t timeStepIndex) else { // Do a "Hack" to show elm nodal and not nodal POR results - if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") resVarAddress.resultPosType = RIG_ELEMENT_NODAL; - - const std::vector& resultValues = caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex); - RigFemPart* femPart = caseData->femParts()->part(0); - bool isElementNodalResult = !(resVarAddress.resultPosType == RIG_NODAL); - const std::vector &vertexWeights = m_intersectionBoxGenerator->triangleVxToCellCornerInterpolationWeights(); - - RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords(m_intersectionBoxFacesTextureCoords.p(), - vertexWeights, - resultValues, - isElementNodalResult, - femPart, - mapper); + if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") + resVarAddress.resultPosType = RIG_ELEMENT_NODAL; + + const std::vector& resultValues = + caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex); + RigFemPart* femPart = caseData->femParts()->part(0); + bool isElementNodalResult = !(resVarAddress.resultPosType == RIG_NODAL); + const std::vector& vertexWeights = + m_intersectionBoxGenerator->triangleVxToCellCornerInterpolationWeights(); + + RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords( + m_intersectionBoxFacesTextureCoords.p(), vertexWeights, resultValues, isElementNodalResult, femPart, mapper); } - RivScalarMapperUtils::applyTextureResultsToPart(m_intersectionBoxFaces.p(), - m_intersectionBoxFacesTextureCoords.p(), - mapper, - 1.0, - caf::FC_NONE, + RivScalarMapperUtils::applyTextureResultsToPart(m_intersectionBoxFaces.p(), + m_intersectionBoxFacesTextureCoords.p(), + mapper, + 1.0, + caf::FC_NONE, geoView->isLightingDisabled()); } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionBoxPartMgr::generatePartGeometry() { - bool useBufferObjects = true; // Surface geometry { @@ -280,6 +268,8 @@ void RivIntersectionBoxPartMgr::generatePartGeometry() part->setEnableMask(intersectionCellMeshBit); part->setPriority(RivPartPriority::PartType::MeshLines); + part->setSourceInfo(new RivMeshLinesSourceInfo(m_rimIntersectionBox)); + m_intersectionBoxGridLines = part; } } @@ -287,15 +277,14 @@ void RivIntersectionBoxPartMgr::generatePartGeometry() updatePartEffect(); } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionBoxPartMgr::updatePartEffect() { // Set deCrossSection effect caf::SurfaceEffectGenerator geometryEffgen(m_defaultColor, caf::PO_1); - + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); if (m_intersectionBoxFaces.notNull()) @@ -304,21 +293,20 @@ void RivIntersectionBoxPartMgr::updatePartEffect() } // Update mesh colors as well, in case of change - //RiaPreferences* prefs = RiaApplication::instance()->preferences(); + // RiaPreferences* prefs = RiaApplication::instance()->preferences(); - cvf::ref eff; - caf::MeshEffectGenerator CrossSectionEffGen(cvf::Color3::WHITE);//prefs->defaultCrossSectionGridLineColors()); + cvf::ref eff; + caf::MeshEffectGenerator CrossSectionEffGen(cvf::Color3::WHITE); // prefs->defaultCrossSectionGridLineColors()); eff = CrossSectionEffGen.generateCachedEffect(); if (m_intersectionBoxGridLines.notNull()) { m_intersectionBoxGridLines->setEffect(eff.p()); } - } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionBoxPartMgr::appendNativeCrossSectionFacesToModel(cvf::ModelBasicList* model, cvf::Transform* scaleTransform) { @@ -335,7 +323,7 @@ void RivIntersectionBoxPartMgr::appendNativeCrossSectionFacesToModel(cvf::ModelB } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionBoxPartMgr::appendMeshLinePartsToModel(cvf::ModelBasicList* model, cvf::Transform* scaleTransform) { @@ -351,20 +339,19 @@ void RivIntersectionBoxPartMgr::appendMeshLinePartsToModel(cvf::ModelBasicList* } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::ref RivIntersectionBoxPartMgr::createHexGridInterface() { - RimEclipseView* eclipseView; m_rimIntersectionBox->firstAncestorOrThisOfType(eclipseView); if (eclipseView) { RigMainGrid* grid = eclipseView->mainGrid(); - return new RivEclipseIntersectionGrid(grid, eclipseView->currentActiveCellInfo(), m_rimIntersectionBox->showInactiveCells()); + return new RivEclipseIntersectionGrid( + grid, eclipseView->currentActiveCellInfo(), m_rimIntersectionBox->showInactiveCells()); } RimGeoMechView* geoView; @@ -377,4 +364,3 @@ cvf::ref RivIntersectionBoxPartMgr::createHexGr return nullptr; } - diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.h b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.h index 43a92d5ce0..eb3ac71548 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.h +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionBoxPartMgr.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -23,13 +23,12 @@ #include "cvfBase.h" #include "cvfObject.h" - namespace cvf { - class ModelBasicList; - class Transform; - class Part; -} +class ModelBasicList; +class Transform; +class Part; +} // namespace cvf class RigMainGrid; class RigResultAccessor; @@ -60,13 +59,13 @@ class RivIntersectionBoxPartMgr : public cvf::Object cvf::ref createHexGridInterface(); private: - RimIntersectionBox* m_rimIntersectionBox; + RimIntersectionBox* m_rimIntersectionBox; - cvf::Color3f m_defaultColor; + cvf::Color3f m_defaultColor; - cvf::ref m_intersectionBoxFaces; - cvf::ref m_intersectionBoxGridLines; - cvf::ref m_intersectionBoxFacesTextureCoords; + cvf::ref m_intersectionBoxFaces; + cvf::ref m_intersectionBoxGridLines; + cvf::ref m_intersectionBoxFacesTextureCoords; cvf::ref m_intersectionBoxGenerator; }; diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.cpp index b1ed7216d2..ed8d4ff94b 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.cpp @@ -205,6 +205,8 @@ void RivIntersectionGeometryGenerator::calculateArrays() { if (m_triangleVxes->size()) return; + if (m_hexGrid.isNull()) return; + m_extrusionDirection.normalize(); std::vector triangleVertices; @@ -359,24 +361,24 @@ void RivIntersectionGeometryGenerator::calculateArrays() // Accumulate triangle vertices - cvf::Vec3d p0(clippedTriangleVxes[triVxIdx+0].vx); - cvf::Vec3d p1(clippedTriangleVxes[triVxIdx+1].vx); - cvf::Vec3d p2(clippedTriangleVxes[triVxIdx+2].vx); + cvf::Vec3d point0(clippedTriangleVxes[triVxIdx+0].vx); + cvf::Vec3d point1(clippedTriangleVxes[triVxIdx+1].vx); + cvf::Vec3d point2(clippedTriangleVxes[triVxIdx+2].vx); - p0 = p0.getTransformedPoint(invSectionCS); - p1 = p1.getTransformedPoint(invSectionCS); - p2 = p2.getTransformedPoint(invSectionCS); + point0 = point0.getTransformedPoint(invSectionCS); + point1 = point1.getTransformedPoint(invSectionCS); + point2 = point2.getTransformedPoint(invSectionCS); - triangleVertices.emplace_back(p0); - triangleVertices.emplace_back(p1); - triangleVertices.emplace_back(p2); + triangleVertices.emplace_back(point0); + triangleVertices.emplace_back(point1); + triangleVertices.emplace_back(point2); // Accumulate mesh lines - meshAcc.accumulateMeshLines(cellFaceForEachClippedTriangleEdge, triVxIdx + 0, globalCellIdx, p0, p1); - meshAcc.accumulateMeshLines(cellFaceForEachClippedTriangleEdge, triVxIdx + 1, globalCellIdx, p1, p2); - meshAcc.accumulateMeshLines(cellFaceForEachClippedTriangleEdge, triVxIdx + 2, globalCellIdx, p2, p0); + meshAcc.accumulateMeshLines(cellFaceForEachClippedTriangleEdge, triVxIdx + 0, globalCellIdx, point0, point1); + meshAcc.accumulateMeshLines(cellFaceForEachClippedTriangleEdge, triVxIdx + 1, globalCellIdx, point1, point2); + meshAcc.accumulateMeshLines(cellFaceForEachClippedTriangleEdge, triVxIdx + 2, globalCellIdx, point2, point0); // Mapping to cell index diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.h b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.h index 5c8a08fcea..24954f8e77 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionGeometryGenerator.h @@ -55,7 +55,7 @@ class RivIntersectionGeometryGenerator : public cvf::Object bool isFlattened, const cvf::Vec3d& flattenedPolylineStartPoint); - ~RivIntersectionGeometryGenerator(); + ~RivIntersectionGeometryGenerator() override; bool isAnyGeometryPresent() const; diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp index 4f11900fd8..7caae7a6e8 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.cpp @@ -2,23 +2,27 @@ // // Copyright (C) Statoil ASA // Copyright (C) Ceetron Solutions AS -// +// // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RivIntersectionPartMgr.h" +#include "RiaApplication.h" +#include "RiaOffshoreSphericalCoords.h" +#include "RiaPreferences.h" + #include "RigCaseCellResultsData.h" #include "RigFemPartCollection.h" #include "RigFemPartResultsCollection.h" @@ -27,14 +31,15 @@ #include "RigResultAccessorFactory.h" #include "Rim2dIntersectionView.h" -#include "RimIntersection.h" #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" +#include "RimFaultInView.h" #include "RimFaultInViewCollection.h" #include "RimGeoMechCase.h" #include "RimGeoMechCellColors.h" #include "RimGeoMechView.h" +#include "RimIntersection.h" #include "RimRegularLegendConfig.h" #include "RimSimWellInView.h" #include "RimSimWellInViewCollection.h" @@ -42,10 +47,13 @@ #include "RimWellPath.h" #include "RimWellPathCollection.h" +#include "RiuGeoMechXfTensorResultAccessor.h" + #include "RivHexGridIntersectionTools.h" #include "RivIntersectionGeometryGenerator.h" -#include "RivObjectSourceInfo.h" #include "RivIntersectionSourceInfo.h" +#include "RivMeshLinesSourceInfo.h" +#include "RivObjectSourceInfo.h" #include "RivPartPriority.h" #include "RivPipeGeometryGenerator.h" #include "RivResultToTextureMapper.h" @@ -55,8 +63,6 @@ #include "RivTernaryTextureCoordsCreator.h" #include "RivWellPathSourceInfo.h" -#include "RiuGeoMechXfTensorResultAccessor.h" - #include "cafTensor3.h" #include "cvfDrawableGeo.h" @@ -64,49 +70,41 @@ #include "cvfGeometryTools.h" #include "cvfModelBasicList.h" #include "cvfPart.h" -#include "cvfqtUtils.h" #include "cvfPrimitiveSetDirect.h" -#include "cvfRenderState_FF.h" #include "cvfRenderStateDepth.h" #include "cvfRenderStatePoint.h" +#include "cvfRenderState_FF.h" #include "cvfStructGridGeometryGenerator.h" #include "cvfTransform.h" +#include "cvfqtUtils.h" #include -#include "RiaApplication.h" -#include "RiaPreferences.h" -#include "RimFaultInView.h" - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RivIntersectionPartMgr::RivIntersectionPartMgr(RimIntersection* rimCrossSection, bool isFlattened) - : m_rimCrossSection(rimCrossSection), - m_isFlattened(isFlattened) + : m_rimCrossSection(rimCrossSection) + , m_isFlattened(isFlattened) { CVF_ASSERT(m_rimCrossSection); m_crossSectionFacesTextureCoords = new cvf::Vec2fArray; - + cvf::Vec3d flattenedPolylineStartPoint; - std::vector< std::vector > polyLines = m_rimCrossSection->polyLines(&flattenedPolylineStartPoint); + std::vector> polyLines = m_rimCrossSection->polyLines(&flattenedPolylineStartPoint); if (polyLines.size() > 0) { - cvf::Vec3d direction = m_rimCrossSection->extrusionDirection(); - cvf::ref hexGrid = createHexGridInterface(); - m_crossSectionGenerator = new RivIntersectionGeometryGenerator(m_rimCrossSection, - polyLines, - direction, - hexGrid.p(), - m_isFlattened, - flattenedPolylineStartPoint); + cvf::Vec3d direction = m_rimCrossSection->extrusionDirection(); + cvf::ref hexGrid = createHexGridInterface(); + m_crossSectionGenerator = new RivIntersectionGeometryGenerator( + m_rimCrossSection, polyLines, direction, hexGrid.p(), m_isFlattened, flattenedPolylineStartPoint); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionPartMgr::applySingleColorEffect() { @@ -126,7 +124,7 @@ void RivIntersectionPartMgr::applySingleColorEffect() if (m_crossSectionGridLines.notNull()) { - cvf::ref eff; + cvf::ref eff; caf::MeshEffectGenerator CrossSectionEffGen(prefs->defaultGridLineColors()); eff = CrossSectionEffGen.generateCachedEffect(); @@ -135,7 +133,7 @@ void RivIntersectionPartMgr::applySingleColorEffect() if (m_crossSectionFaultGridLines.notNull()) { - cvf::ref eff; + cvf::ref eff; caf::MeshEffectGenerator CrossSectionEffGen(prefs->defaultFaultGridLineColors()); eff = CrossSectionEffGen.generateCachedEffect(); @@ -144,10 +142,10 @@ void RivIntersectionPartMgr::applySingleColorEffect() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex, - const cvf::ScalarMapper* scalarColorMapper, +void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex, + const cvf::ScalarMapper* scalarColorMapper, const RivTernaryScalarMapper* ternaryColorMapper) { CVF_ASSERT(scalarColorMapper); @@ -165,16 +163,15 @@ void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex, CVF_ASSERT(cellResultColors); CVF_ASSERT(ternaryColorMapper); - RigEclipseCaseData* eclipseCase = eclipseView->eclipseCase()->eclipseCaseData(); - // CrossSections if (m_crossSectionFaces.notNull()) { if (cellResultColors->isTernarySaturationSelected()) { RivTernaryTextureCoordsCreator texturer(cellResultColors, ternaryColorMapper, timeStepIndex); - - texturer.createTextureCoords(m_crossSectionFacesTextureCoords.p(), m_crossSectionGenerator->triangleToCellIndex()); + + texturer.createTextureCoords(m_crossSectionFacesTextureCoords.p(), + m_crossSectionGenerator->triangleToCellIndex()); RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_crossSectionFaces.p(), m_crossSectionFacesTextureCoords.p(), @@ -195,17 +192,14 @@ void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex, } else { - resultAccessor = RigResultAccessorFactory::createFromResultDefinition(cellResultColors->reservoirView()->eclipseCase()->eclipseCaseData(), - 0, - timeStepIndex, - cellResultColors); + resultAccessor = RigResultAccessorFactory::createFromResultDefinition( + cellResultColors->reservoirView()->eclipseCase()->eclipseCaseData(), 0, timeStepIndex, cellResultColors); } RivIntersectionPartMgr::calculateEclipseTextureCoordinates(m_crossSectionFacesTextureCoords.p(), - m_crossSectionGenerator->triangleToCellIndex(), - resultAccessor.p(), - scalarColorMapper); - + m_crossSectionGenerator->triangleToCellIndex(), + resultAccessor.p(), + scalarColorMapper); RivScalarMapperUtils::applyTextureResultsToPart(m_crossSectionFaces.p(), m_crossSectionFacesTextureCoords.p(), @@ -213,7 +207,7 @@ void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex, 1.0, caf::FC_NONE, eclipseView->isLightingDisabled()); - } + } } } @@ -223,38 +217,35 @@ void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex, if (geoView) { RimGeoMechCellColors* cellResultColors = geoView->cellResult(); - RigGeoMechCaseData* caseData = cellResultColors->ownerCaseData(); - + RigGeoMechCaseData* caseData = cellResultColors->ownerCaseData(); + if (!caseData) return; - RigFemResultAddress resVarAddress = cellResultColors->resultAddress(); + RigFemResultAddress resVarAddress = cellResultColors->resultAddress(); if (resVarAddress.resultPosType == RIG_ELEMENT) { - const std::vector& resultValues = caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex); - const std::vector& triangleToCellIdx = m_crossSectionGenerator->triangleToCellIndex(); - - RivIntersectionPartMgr::calculateElementBasedGeoMechTextureCoords(m_crossSectionFacesTextureCoords.p(), - resultValues, - triangleToCellIdx, - scalarColorMapper); + const std::vector& resultValues = + caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex); + const std::vector& triangleToCellIdx = m_crossSectionGenerator->triangleToCellIndex(); + RivIntersectionPartMgr::calculateElementBasedGeoMechTextureCoords( + m_crossSectionFacesTextureCoords.p(), resultValues, triangleToCellIdx, scalarColorMapper); } - else if(resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE) + else if (resVarAddress.resultPosType == RIG_ELEMENT_NODAL_FACE) { // Special direction sensitive result calculation const cvf::Vec3fArray* triangelVxes = m_crossSectionGenerator->triangleVxes(); if (resVarAddress.componentName == "Pazi" || resVarAddress.componentName == "Pinc") { - RivIntersectionPartMgr::calculatePlaneAngleTextureCoords(m_crossSectionFacesTextureCoords.p(), - triangelVxes, - resVarAddress, - scalarColorMapper); + RivIntersectionPartMgr::calculatePlaneAngleTextureCoords( + m_crossSectionFacesTextureCoords.p(), triangelVxes, resVarAddress, scalarColorMapper); } else { - const std::vector &vertexWeights = m_crossSectionGenerator->triangleVxToCellCornerInterpolationWeights(); + const std::vector& vertexWeights = + m_crossSectionGenerator->triangleVxToCellCornerInterpolationWeights(); RivIntersectionPartMgr::calculateGeoMechTensorXfTextureCoords(m_crossSectionFacesTextureCoords.p(), triangelVxes, @@ -268,12 +259,15 @@ void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex, else { // Do a "Hack" to show elm nodal and not nodal POR results - if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") resVarAddress.resultPosType = RIG_ELEMENT_NODAL; + if (resVarAddress.resultPosType == RIG_NODAL && resVarAddress.fieldName == "POR-Bar") + resVarAddress.resultPosType = RIG_ELEMENT_NODAL; - const std::vector& resultValues = caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex); - RigFemPart* femPart = caseData->femParts()->part(0); - bool isElementNodalResult = !(resVarAddress.resultPosType == RIG_NODAL); - const std::vector &vertexWeights = m_crossSectionGenerator->triangleVxToCellCornerInterpolationWeights(); + const std::vector& resultValues = + caseData->femPartResults()->resultValues(resVarAddress, 0, (int)timeStepIndex); + RigFemPart* femPart = caseData->femParts()->part(0); + bool isElementNodalResult = !(resVarAddress.resultPosType == RIG_NODAL); + const std::vector& vertexWeights = + m_crossSectionGenerator->triangleVxToCellCornerInterpolationWeights(); RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords(m_crossSectionFacesTextureCoords.p(), vertexWeights, @@ -283,25 +277,25 @@ void RivIntersectionPartMgr::updateCellResultColor(size_t timeStepIndex, scalarColorMapper); } - RivScalarMapperUtils::applyTextureResultsToPart(m_crossSectionFaces.p(), - m_crossSectionFacesTextureCoords.p(), - scalarColorMapper, - 1.0, - caf::FC_NONE, + RivScalarMapperUtils::applyTextureResultsToPart(m_crossSectionFaces.p(), + m_crossSectionFacesTextureCoords.p(), + scalarColorMapper, + 1.0, + caf::FC_NONE, geoView->isLightingDisabled()); } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords(cvf::Vec2fArray* textureCoords, - const std::vector &vertexWeights, - const std::vector &resultValues, - bool isElementNodalResult, - const RigFemPart* femPart, - const cvf::ScalarMapper* mapper) +void RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords( + cvf::Vec2fArray* textureCoords, + const std::vector& vertexWeights, + const std::vector& resultValues, + bool isElementNodalResult, + const RigFemPart* femPart, + const cvf::ScalarMapper* mapper) { textureCoords->resize(vertexWeights.size()); @@ -318,8 +312,8 @@ void RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords #pragma omp parallel for schedule(dynamic) for (int triangleVxIdx = 0; triangleVxIdx < vxCount; ++triangleVxIdx) { - float resValue = 0; - int weightCount = vertexWeights[triangleVxIdx].size(); + float resValue = 0; + int weightCount = vertexWeights[triangleVxIdx].size(); for (int wIdx = 0; wIdx < weightCount; ++wIdx) { size_t resIdx; @@ -331,13 +325,13 @@ void RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords { resIdx = femPart->nodeIdxFromElementNodeResultIdx(vertexWeights[triangleVxIdx].vxId(wIdx)); } - + resValue += resultValues[resIdx] * vertexWeights[triangleVxIdx].weight(wIdx); } if (resValue == HUGE_VAL || resValue != resValue) // a != a is true for NAN's { - rawPtr[triangleVxIdx][1] = 1.0f; + rawPtr[triangleVxIdx][1] = 1.0f; } else { @@ -348,14 +342,14 @@ void RivIntersectionPartMgr::calculateNodeOrElementNodeBasedGeoMechTextureCoords } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RivIntersectionPartMgr::calculateElementBasedGeoMechTextureCoords(cvf::Vec2fArray* textureCoords, - const std::vector &resultValues, +void RivIntersectionPartMgr::calculateElementBasedGeoMechTextureCoords(cvf::Vec2fArray* textureCoords, + const std::vector& resultValues, const std::vector& triangleToCellIdx, - const cvf::ScalarMapper* mapper) + const cvf::ScalarMapper* mapper) { - textureCoords->resize(triangleToCellIdx.size()*3); + textureCoords->resize(triangleToCellIdx.size() * 3); if (resultValues.size() == 0) { @@ -367,20 +361,20 @@ void RivIntersectionPartMgr::calculateElementBasedGeoMechTextureCoords(cvf::Vec2 for (size_t triangleIdx = 0; triangleIdx < triangleToCellIdx.size(); triangleIdx++) { - size_t resIdx = triangleToCellIdx[triangleIdx]; - float resValue = resultValues[resIdx]; + size_t resIdx = triangleToCellIdx[triangleIdx]; + float resValue = resultValues[resIdx]; size_t triangleVxIdx = triangleIdx * 3; - + if (resValue == HUGE_VAL || resValue != resValue) // a != a is true for NAN's { - rawPtr[triangleVxIdx][1] = 1.0f; + rawPtr[triangleVxIdx][1] = 1.0f; rawPtr[triangleVxIdx + 1][1] = 1.0f; rawPtr[triangleVxIdx + 2][1] = 1.0f; } else { - rawPtr[triangleVxIdx] = mapper->mapToTextureCoord(resValue); + rawPtr[triangleVxIdx] = mapper->mapToTextureCoord(resValue); rawPtr[triangleVxIdx + 1] = mapper->mapToTextureCoord(resValue); rawPtr[triangleVxIdx + 2] = mapper->mapToTextureCoord(resValue); } @@ -389,96 +383,97 @@ void RivIntersectionPartMgr::calculateElementBasedGeoMechTextureCoords(cvf::Vec2 } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RivIntersectionPartMgr::calculateGeoMechTensorXfTextureCoords(cvf::Vec2fArray* textureCoords, +void RivIntersectionPartMgr::calculateGeoMechTensorXfTextureCoords(cvf::Vec2fArray* textureCoords, const cvf::Vec3fArray* triangelVertices, - const std::vector &vertexWeights, - RigGeoMechCaseData* caseData, - const RigFemResultAddress& resVarAddress, - int timeStepIdx, - const cvf::ScalarMapper* mapper) -{ - + const std::vector& vertexWeights, + RigGeoMechCaseData* caseData, + const RigFemResultAddress& resVarAddress, + int timeStepIdx, + const cvf::ScalarMapper* mapper) +{ RiuGeoMechXfTensorResultAccessor accessor(caseData->femPartResults(), resVarAddress, timeStepIdx); textureCoords->resize(vertexWeights.size()); - cvf::Vec2f* rawPtr = textureCoords->ptr(); - int vxCount = static_cast(vertexWeights.size()); - int triCount = vxCount/3; + cvf::Vec2f* rawPtr = textureCoords->ptr(); + int vxCount = static_cast(vertexWeights.size()); + int triCount = vxCount / 3; - #pragma omp parallel for schedule(dynamic) - for ( int triangleIdx = 0; triangleIdx < triCount; ++triangleIdx ) +#pragma omp parallel for schedule(dynamic) + for (int triangleIdx = 0; triangleIdx < triCount; ++triangleIdx) { - int triangleVxStartIdx = triangleIdx*3; + int triangleVxStartIdx = triangleIdx * 3; float values[3]; - accessor.calculateInterpolatedValue(&((*triangelVertices)[triangleVxStartIdx]), &(vertexWeights[triangleVxStartIdx]), values ); + accessor.calculateInterpolatedValue( + &((*triangelVertices)[triangleVxStartIdx]), &(vertexWeights[triangleVxStartIdx]), values); - rawPtr[triangleVxStartIdx + 0] = (values[0] != std::numeric_limits::infinity()) ? mapper->mapToTextureCoord(values[0]) : cvf::Vec2f(0.0f, 1.0f); - rawPtr[triangleVxStartIdx + 1] = (values[1] != std::numeric_limits::infinity()) ? mapper->mapToTextureCoord(values[1]) : cvf::Vec2f(0.0f, 1.0f); - rawPtr[triangleVxStartIdx + 2] = (values[2] != std::numeric_limits::infinity()) ? mapper->mapToTextureCoord(values[2]) : cvf::Vec2f(0.0f, 1.0f); + rawPtr[triangleVxStartIdx + 0] = + (values[0] != std::numeric_limits::infinity()) ? mapper->mapToTextureCoord(values[0]) : cvf::Vec2f(0.0f, 1.0f); + rawPtr[triangleVxStartIdx + 1] = + (values[1] != std::numeric_limits::infinity()) ? mapper->mapToTextureCoord(values[1]) : cvf::Vec2f(0.0f, 1.0f); + rawPtr[triangleVxStartIdx + 2] = + (values[2] != std::numeric_limits::infinity()) ? mapper->mapToTextureCoord(values[2]) : cvf::Vec2f(0.0f, 1.0f); } - } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RivIntersectionPartMgr::calculatePlaneAngleTextureCoords(cvf::Vec2fArray* textureCoords, - const cvf::Vec3fArray* triangelVertices, - const RigFemResultAddress& resVarAddress, - const cvf::ScalarMapper* mapper) +void RivIntersectionPartMgr::calculatePlaneAngleTextureCoords(cvf::Vec2fArray* textureCoords, + const cvf::Vec3fArray* triangelVertices, + const RigFemResultAddress& resVarAddress, + const cvf::ScalarMapper* mapper) { - textureCoords->resize(triangelVertices->size()); - cvf::Vec2f* rawPtr = textureCoords->ptr(); - int vxCount = static_cast(triangelVertices->size()); - int triCount = vxCount/3; + cvf::Vec2f* rawPtr = textureCoords->ptr(); + int vxCount = static_cast(triangelVertices->size()); + int triCount = vxCount / 3; - std::function operation; + std::function operation; if (resVarAddress.componentName == "Pazi") { - operation = [](const OffshoreSphericalCoords& sphCoord) { return sphCoord.azi();}; + operation = [](const RiaOffshoreSphericalCoords& sphCoord) { return (float)sphCoord.azi(); }; } - else if ( resVarAddress.componentName == "Pinc" ) + else if (resVarAddress.componentName == "Pinc") { - operation = [](const OffshoreSphericalCoords& sphCoord) { return sphCoord.inc();}; + operation = [](const RiaOffshoreSphericalCoords& sphCoord) { return (float)sphCoord.inc(); }; } - #pragma omp parallel for schedule(dynamic) - for ( int triangleIdx = 0; triangleIdx < triCount; ++triangleIdx ) +#pragma omp parallel for schedule(dynamic) + for (int triangleIdx = 0; triangleIdx < triCount; ++triangleIdx) { - int triangleVxStartIdx = triangleIdx*3; - + int triangleVxStartIdx = triangleIdx * 3; + const cvf::Vec3f* triangle = &((*triangelVertices)[triangleVxStartIdx]); - cvf::Mat3f rotMx = cvf::GeometryTools::computePlaneHorizontalRotationMx(triangle[1] - triangle[0], triangle[2] - triangle[0]); + cvf::Mat3f rotMx = + cvf::GeometryTools::computePlaneHorizontalRotationMx(triangle[1] - triangle[0], triangle[2] - triangle[0]); - OffshoreSphericalCoords sphCoord(cvf::Vec3f(rotMx.rowCol(0, 2), rotMx.rowCol(1, 2), rotMx.rowCol(2, 2))); // Use Ez from the matrix as plane normal + RiaOffshoreSphericalCoords sphCoord( + cvf::Vec3f(rotMx.rowCol(0, 2), rotMx.rowCol(1, 2), rotMx.rowCol(2, 2))); // Use Ez from the matrix as plane normal - float angle = cvf::Math::toDegrees( operation(sphCoord)); - cvf::Vec2f texCoord = (angle != std::numeric_limits::infinity()) ? mapper->mapToTextureCoord(angle) : cvf::Vec2f(0.0f, 1.0f); + float angle = cvf::Math::toDegrees(operation(sphCoord)); + cvf::Vec2f texCoord = + (angle != std::numeric_limits::infinity()) ? mapper->mapToTextureCoord(angle) : cvf::Vec2f(0.0f, 1.0f); rawPtr[triangleVxStartIdx + 0] = texCoord; rawPtr[triangleVxStartIdx + 1] = texCoord; rawPtr[triangleVxStartIdx + 2] = texCoord; } - } - //-------------------------------------------------------------------------------------------------- -/// Calculates the texture coordinates in a "nearly" one dimensional texture. +/// Calculates the texture coordinates in a "nearly" one dimensional texture. /// Undefined values are coded with a y-texturecoordinate value of 1.0 instead of the normal 0.5 //-------------------------------------------------------------------------------------------------- -void RivIntersectionPartMgr::calculateEclipseTextureCoordinates(cvf::Vec2fArray* textureCoords, - const std::vector& triangleToCellIdxMap, - const RigResultAccessor* resultAccessor, - const cvf::ScalarMapper* mapper) +void RivIntersectionPartMgr::calculateEclipseTextureCoordinates(cvf::Vec2fArray* textureCoords, + const std::vector& triangleToCellIdxMap, + const RigResultAccessor* resultAccessor, + const cvf::ScalarMapper* mapper) { if (!resultAccessor) return; - size_t numVertices = triangleToCellIdxMap.size()*3; + size_t numVertices = triangleToCellIdxMap.size() * 3; textureCoords->resize(numVertices); cvf::Vec2f* rawPtr = textureCoords->ptr(); @@ -488,8 +483,8 @@ void RivIntersectionPartMgr::calculateEclipseTextureCoordinates(cvf::Vec2fArray* #pragma omp parallel for for (int tIdx = 0; tIdx < triangleCount; tIdx++) { - double cellScalarValue = resultAccessor->cellScalarGlobIdx(triangleToCellIdxMap[tIdx]); - cvf::Vec2f texCoord = mapper->mapToTextureCoord(cellScalarValue); + double cellScalarValue = resultAccessor->cellScalarGlobIdx(triangleToCellIdxMap[tIdx]); + cvf::Vec2f texCoord = mapper->mapToTextureCoord(cellScalarValue); if (cellScalarValue == HUGE_VAL || cellScalarValue != cellScalarValue) // a != a is true for NAN's { texCoord[1] = 1.0f; @@ -497,14 +492,14 @@ void RivIntersectionPartMgr::calculateEclipseTextureCoordinates(cvf::Vec2fArray* size_t j; for (j = 0; j < 3; j++) - { - rawPtr[tIdx*3 + j] = texCoord; + { + rawPtr[tIdx * 3 + j] = texCoord; } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionPartMgr::generatePartGeometry() { @@ -557,6 +552,8 @@ void RivIntersectionPartMgr::generatePartGeometry() part->setEnableMask(intersectionCellMeshBit); part->setPriority(RivPartPriority::PartType::MeshLines); + part->setSourceInfo(new RivMeshLinesSourceInfo(m_rimCrossSection)); + m_crossSectionGridLines = part; } } @@ -579,6 +576,8 @@ void RivIntersectionPartMgr::generatePartGeometry() part->setEnableMask(intersectionFaultMeshBit); part->setPriority(RivPartPriority::PartType::FaultMeshLines); + part->setSourceInfo(new RivMeshLinesSourceInfo(m_rimCrossSection)); + m_crossSectionFaultGridLines = part; } } @@ -592,11 +591,11 @@ void RivIntersectionPartMgr::generatePartGeometry() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RivIntersectionPartMgr::createFaultLabelParts(const std::vector >& labelAndAnchors) +void RivIntersectionPartMgr::createFaultLabelParts(const std::vector>& labelAndAnchors) { - m_faultMeshLabels = nullptr; + m_faultMeshLabels = nullptr; m_faultMeshLabelLines = nullptr; if (!labelAndAnchors.size()) return; @@ -606,9 +605,9 @@ void RivIntersectionPartMgr::createFaultLabelParts(const std::vectorfaultCollection(); if (!(eclipseView && faultInViewColl->showFaultLabel())) return; - + cvf::Color3f defWellLabelColor = faultInViewColl->faultLabelColor(); - cvf::Font* font = RiaApplication::instance()->customFont(); + cvf::Font* font = RiaApplication::instance()->customFont(); std::vector lineVertices; @@ -622,18 +621,18 @@ void RivIntersectionPartMgr::createFaultLabelParts(const std::vectorsetTextColor(defWellLabelColor); } - cvf::BoundingBox bb = m_crossSectionFaces->boundingBox(); - double labelZOffset = bb.extent().z() / 10; - int visibleFaultNameCount = 0; + cvf::BoundingBox bb = m_crossSectionFaces->boundingBox(); + double labelZOffset = bb.extent().z() / 10; + int visibleFaultNameCount = 0; for (const auto& labelAndAnchorPair : labelAndAnchors) { RimFaultInView* fault = faultInViewColl->findFaultByName(labelAndAnchorPair.first); if (!(fault && fault->showFault())) continue; - + cvf::String cvfString = cvfqt::Utils::toString(labelAndAnchorPair.first); - cvf::Vec3f textCoord(labelAndAnchorPair.second); + cvf::Vec3f textCoord(labelAndAnchorPair.second); textCoord.z() += labelZOffset; drawableText->addText(cvfString, textCoord); @@ -679,16 +678,15 @@ void RivIntersectionPartMgr::createFaultLabelParts(const std::vectorupdateBoundingBox(); caf::MeshEffectGenerator gen(RiaApplication::instance()->preferences()->defaultFaultGridLineColors()); - cvf::ref eff = gen.generateCachedEffect(); + cvf::ref eff = gen.generateCachedEffect(); part->setEffect(eff.p()); m_faultMeshLabelLines = part; } - } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionPartMgr::createPolyLineParts(bool useBufferObjects) { @@ -716,9 +714,9 @@ void RivIntersectionPartMgr::createPolyLineParts(bool useBufferObjects) part->setPriority(RivPartPriority::PartType::Highlight); // Always show this part, also when mesh is turned off - //part->setEnableMask(meshFaultBit); + // part->setEnableMask(meshFaultBit); - cvf::ref eff; + cvf::ref eff; caf::MeshEffectGenerator lineEffGen(cvf::Color3::MAGENTA); eff = lineEffGen.generateUnCachedEffect(); @@ -748,9 +746,9 @@ void RivIntersectionPartMgr::createPolyLineParts(bool useBufferObjects) part->setPriority(RivPartPriority::PartType::Highlight); // Always show this part, also when mesh is turned off - //part->setEnableMask(meshFaultBit); + // part->setEnableMask(meshFaultBit); - cvf::ref eff; + cvf::ref eff; caf::MeshEffectGenerator lineEffGen(cvf::Color3::MAGENTA); eff = lineEffGen.generateUnCachedEffect(); @@ -758,7 +756,7 @@ void RivIntersectionPartMgr::createPolyLineParts(bool useBufferObjects) depth->enableDepthTest(false); eff->setRenderState(depth.p()); - cvf::ref pointRendState = new cvf::RenderStatePoint(cvf::RenderStatePoint::FIXED_SIZE); + cvf::ref pointRendState = new cvf::RenderStatePoint(cvf::RenderStatePoint::FIXED_SIZE); pointRendState->setSize(5.0f); eff->setRenderState(pointRendState.p()); @@ -770,7 +768,7 @@ void RivIntersectionPartMgr::createPolyLineParts(bool useBufferObjects) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionPartMgr::createExtrusionDirParts(bool useBufferObjects) { @@ -780,7 +778,8 @@ void RivIntersectionPartMgr::createExtrusionDirParts(bool useBufferObjects) if (m_rimCrossSection->direction() == RimIntersection::CS_TWO_POINTS) { { - cvf::ref polylineGeo = m_crossSectionGenerator->createLineAlongExtrusionLineDrawable(m_rimCrossSection->polyLinesForExtrusionDirection()); + cvf::ref polylineGeo = m_crossSectionGenerator->createLineAlongExtrusionLineDrawable( + m_rimCrossSection->polyLinesForExtrusionDirection()); if (polylineGeo.notNull()) { if (useBufferObjects) @@ -796,9 +795,9 @@ void RivIntersectionPartMgr::createExtrusionDirParts(bool useBufferObjects) part->setPriority(RivPartPriority::PartType::Highlight); // Always show this part, also when mesh is turned off - //part->setEnableMask(meshFaultBit); + // part->setEnableMask(meshFaultBit); - cvf::ref eff; + cvf::ref eff; caf::MeshEffectGenerator lineEffGen(cvf::Color3::MAGENTA); eff = lineEffGen.generateUnCachedEffect(); @@ -812,7 +811,8 @@ void RivIntersectionPartMgr::createExtrusionDirParts(bool useBufferObjects) } } - cvf::ref polylinePointsGeo = m_crossSectionGenerator->createPointsFromExtrusionLineDrawable(m_rimCrossSection->polyLinesForExtrusionDirection()); + cvf::ref polylinePointsGeo = + m_crossSectionGenerator->createPointsFromExtrusionLineDrawable(m_rimCrossSection->polyLinesForExtrusionDirection()); if (polylinePointsGeo.notNull()) { if (useBufferObjects) @@ -828,9 +828,9 @@ void RivIntersectionPartMgr::createExtrusionDirParts(bool useBufferObjects) part->setPriority(RivPartPriority::PartType::Highlight); // Always show this part, also when mesh is turned off - //part->setEnableMask(meshFaultBit); + // part->setEnableMask(meshFaultBit); - cvf::ref eff; + cvf::ref eff; caf::MeshEffectGenerator lineEffGen(cvf::Color3::MAGENTA); eff = lineEffGen.generateUnCachedEffect(); @@ -838,7 +838,7 @@ void RivIntersectionPartMgr::createExtrusionDirParts(bool useBufferObjects) depth->enableDepthTest(false); eff->setRenderState(depth.p()); - cvf::ref pointRendState = new cvf::RenderStatePoint(cvf::RenderStatePoint::FIXED_SIZE); + cvf::ref pointRendState = new cvf::RenderStatePoint(cvf::RenderStatePoint::FIXED_SIZE); pointRendState->setSize(5.0f); eff->setRenderState(pointRendState.p()); @@ -850,54 +850,7 @@ void RivIntersectionPartMgr::createExtrusionDirParts(bool useBufferObjects) } //-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref createStdSurfacePart(cvf::DrawableGeo* geometry, - const cvf::Color3f& color, - cvf::String name, - cvf::Object* sourceInfo) -{ - if (!geometry) return nullptr; - - cvf::ref part = new cvf::Part; - part->setName(name); - part->setDrawable(geometry); - - caf::SurfaceEffectGenerator surfaceGen(color, caf::PO_1); - cvf::ref eff = surfaceGen.generateCachedEffect(); - part->setEffect(eff.p()); - - part->setSourceInfo(sourceInfo); - part->updateBoundingBox(); - - return part; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::ref createStdLinePart(cvf::DrawableGeo* geometry, - const cvf::Color3f& color, - cvf::String name) -{ - if ( !geometry ) return nullptr; - - - cvf::ref part = new cvf::Part; - part->setName(name); - part->setDrawable(geometry); - - caf::MeshEffectGenerator gen(color); - cvf::ref eff = gen.generateCachedEffect(); - - part->setEffect(eff.p()); - part->updateBoundingBox(); - - return part; -} - -//-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionPartMgr::appendNativeCrossSectionFacesToModel(cvf::ModelBasicList* model, cvf::Transform* scaleTransform) { @@ -913,9 +866,8 @@ void RivIntersectionPartMgr::appendNativeCrossSectionFacesToModel(cvf::ModelBasi } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivIntersectionPartMgr::appendMeshLinePartsToModel(cvf::ModelBasicList* model, cvf::Transform* scaleTransform) { @@ -947,14 +899,14 @@ void RivIntersectionPartMgr::appendMeshLinePartsToModel(cvf::ModelBasicList* mod m_faultMeshLabels->setTransform(scaleTransform); model->addPart(m_faultMeshLabels.p()); } - } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RivIntersectionPartMgr::appendPolylinePartsToModel(Rim3dView &view, cvf::ModelBasicList* model, cvf::Transform* scaleTransform) +void RivIntersectionPartMgr::appendPolylinePartsToModel(Rim3dView& view, + cvf::ModelBasicList* model, + cvf::Transform* scaleTransform) { Rim2dIntersectionView* curr2dView = dynamic_cast(&view); @@ -1005,7 +957,7 @@ void RivIntersectionPartMgr::appendPolylinePartsToModel(Rim3dView &view, cvf::Mo } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const RimIntersection* RivIntersectionPartMgr::intersection() const { @@ -1013,7 +965,7 @@ const RimIntersection* RivIntersectionPartMgr::intersection() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::Mat4d RivIntersectionPartMgr::unflattenTransformMatrix(const cvf::Vec3d& intersectionPointFlat) { @@ -1021,7 +973,7 @@ cvf::Mat4d RivIntersectionPartMgr::unflattenTransformMatrix(const cvf::Vec3d& in } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::ref RivIntersectionPartMgr::createHexGridInterface() { @@ -1035,12 +987,12 @@ cvf::ref RivIntersectionPartMgr::createHexGridI RimGeoMechView* geoView; m_rimCrossSection->firstAncestorOrThisOfType(geoView); - if (geoView) + if (geoView && geoView->femParts() && geoView->femParts()->partCount()) { RigFemPart* femPart = geoView->femParts()->part(0); + return new RivFemIntersectionGrid(femPart); } return nullptr; } - diff --git a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h index 1e422ec737..1b17779eee 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h +++ b/ApplicationCode/ModelVisualization/Intersections/RivIntersectionPartMgr.h @@ -2,17 +2,17 @@ // // Copyright (C) Statoil ASA // Copyright (C) Ceetron Solutions AS -// +// // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -20,11 +20,11 @@ #pragma once #include "cvfBase.h" -#include "cvfObject.h" -#include "cvfColor4.h" -#include "cvfVector3.h" #include "cvfArray.h" +#include "cvfColor4.h" #include "cvfMatrix4.h" +#include "cvfObject.h" +#include "cvfVector3.h" #include "cafPdmPointer.h" @@ -35,12 +35,12 @@ namespace cvf { - class ModelBasicList; - class Transform; - class Part; - class ScalarMapper; - class DrawableGeo; -} +class ModelBasicList; +class Transform; +class Part; +class ScalarMapper; +class DrawableGeo; +} // namespace cvf class RigFemPart; class RigFemResultAddress; @@ -68,11 +68,10 @@ class RivIntersectionPartMgr : public cvf::Object explicit RivIntersectionPartMgr(RimIntersection* rimCrossSection, bool isFlattened = false); void applySingleColorEffect(); - void updateCellResultColor(size_t timeStepIndex, - const cvf::ScalarMapper* scalarColorMapper, + void updateCellResultColor(size_t timeStepIndex, + const cvf::ScalarMapper* scalarColorMapper, const RivTernaryScalarMapper* ternaryColorMapper); - void appendNativeCrossSectionFacesToModel(cvf::ModelBasicList* model, cvf::Transform* scaleTransform); void appendMeshLinePartsToModel(cvf::ModelBasicList* model, cvf::Transform* scaleTransform); void appendPolylinePartsToModel(Rim3dView& view, cvf::ModelBasicList* model, cvf::Transform* scaleTransform); @@ -82,38 +81,40 @@ class RivIntersectionPartMgr : public cvf::Object cvf::Mat4d unflattenTransformMatrix(const cvf::Vec3d& intersectionPointFlat); public: - static void calculateEclipseTextureCoordinates(cvf::Vec2fArray* textureCoords, - const std::vector& triangleToCellIdxMap, - const RigResultAccessor* resultAccessor, - const cvf::ScalarMapper* mapper); - - static void calculateNodeOrElementNodeBasedGeoMechTextureCoords(cvf::Vec2fArray* textureCoords, - const std::vector &vertexWeights, - const std::vector &resultValues, - bool isElementNodalResult, - const RigFemPart* femPart, - const cvf::ScalarMapper* mapper); - - static void calculateElementBasedGeoMechTextureCoords(cvf::Vec2fArray* textureCoords, - const std::vector &resultValues, + static void calculateEclipseTextureCoordinates(cvf::Vec2fArray* textureCoords, + const std::vector& triangleToCellIdxMap, + const RigResultAccessor* resultAccessor, + const cvf::ScalarMapper* mapper); + + static void + calculateNodeOrElementNodeBasedGeoMechTextureCoords(cvf::Vec2fArray* textureCoords, + const std::vector& vertexWeights, + const std::vector& resultValues, + bool isElementNodalResult, + const RigFemPart* femPart, + const cvf::ScalarMapper* mapper); + + static void calculateElementBasedGeoMechTextureCoords(cvf::Vec2fArray* textureCoords, + const std::vector& resultValues, const std::vector& triangleToCellIdx, - const cvf::ScalarMapper* mapper); - - static void calculateGeoMechTensorXfTextureCoords(cvf::Vec2fArray* textureCoords, - const cvf::Vec3fArray* triangelVertices, - const std::vector &vertexWeights, - RigGeoMechCaseData* caseData, - const RigFemResultAddress& resVarAddress, - int timeStepIdx, - const cvf::ScalarMapper* mapper); - - static void calculatePlaneAngleTextureCoords(cvf::Vec2fArray* textureCoords, - const cvf::Vec3fArray* triangelVertices, - const RigFemResultAddress& resVarAddress, - const cvf::ScalarMapper* mapper); + const cvf::ScalarMapper* mapper); + + static void calculateGeoMechTensorXfTextureCoords(cvf::Vec2fArray* textureCoords, + const cvf::Vec3fArray* triangelVertices, + const std::vector& vertexWeights, + RigGeoMechCaseData* caseData, + const RigFemResultAddress& resVarAddress, + int timeStepIdx, + const cvf::ScalarMapper* mapper); + + static void calculatePlaneAngleTextureCoords(cvf::Vec2fArray* textureCoords, + const cvf::Vec3fArray* triangelVertices, + const RigFemResultAddress& resVarAddress, + const cvf::ScalarMapper* mapper); + private: void generatePartGeometry(); - void createFaultLabelParts(const std::vector >& labelAndAnchors); + void createFaultLabelParts(const std::vector>& labelAndAnchors); void createPolyLineParts(bool useBufferObjects); void createExtrusionDirParts(bool useBufferObjects); @@ -122,30 +123,27 @@ class RivIntersectionPartMgr : public cvf::Object private: caf::PdmPointer m_rimCrossSection; - cvf::ref m_crossSectionGenerator; - cvf::ref m_crossSectionFaces; - cvf::ref m_crossSectionGridLines; - cvf::ref m_crossSectionFaultGridLines; - cvf::ref m_faultMeshLabels; - cvf::ref m_faultMeshLabelLines; - + cvf::ref m_crossSectionGenerator; - cvf::ref m_crossSectionFacesTextureCoords; + cvf::ref m_crossSectionFaces; + cvf::ref m_crossSectionGridLines; + cvf::ref m_crossSectionFaultGridLines; + cvf::ref m_faultMeshLabels; + cvf::ref m_faultMeshLabelLines; + cvf::ref m_highlightLineAlongPolyline; + cvf::ref m_highlightPointsForPolyline; + cvf::ref m_highlightLineAlongExtrusionDir; + cvf::ref m_highlightPointsForExtrusionDir; - cvf::ref m_highlightLineAlongPolyline; - cvf::ref m_highlightPointsForPolyline; - - cvf::ref m_highlightLineAlongExtrusionDir; - cvf::ref m_highlightPointsForExtrusionDir; + cvf::ref m_crossSectionFacesTextureCoords; struct RivPipeBranchData { - cvf::ref m_pipeGeomGenerator; - cvf::ref m_surfacePart; - cvf::ref m_centerLinePart; + cvf::ref m_pipeGeomGenerator; + cvf::ref m_surfacePart; + cvf::ref m_centerLinePart; }; std::list m_wellBranches; - bool m_isFlattened; + bool m_isFlattened; }; - diff --git a/ApplicationCode/ModelVisualization/Intersections/RivSectionFlattner.cpp b/ApplicationCode/ModelVisualization/Intersections/RivSectionFlattner.cpp index de45bd2f07..b189e6ddca 100644 --- a/ApplicationCode/ModelVisualization/Intersections/RivSectionFlattner.cpp +++ b/ApplicationCode/ModelVisualization/Intersections/RivSectionFlattner.cpp @@ -73,7 +73,7 @@ std::vector RivSectionFlattner::calculateFlatteningCSsForPolyline(co cvf::Vec3d p2 = polyLine[1]; cvf::Mat4d sectionLocalCS = calculateSectionLocalFlatteningCS(p1, p2, extrusionDir); - cvf::Mat4d invSectionCS = sectionLocalCS.getInverted(); + invSectionCS = sectionLocalCS.getInverted(); invSectionCS.setTranslation(invSectionCS.translation() + startOffset); } diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeometryGenerator.cpp index 26385a699e..e7687dfc74 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeometryGenerator.cpp @@ -18,12 +18,14 @@ #include "Riv3dWellLogCurveGeometryGenerator.h" +#include "RiaCurveDataTools.h" +#include "RigWellPath.h" +#include "RigWellPathGeometryTools.h" + +#include "Rim3dWellLogCurve.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" -#include "RigCurveDataTools.h" -#include "RigWellPath.h" -#include "RigWellPathGeometryTools.h" #include "cafLine.h" #include "cafDisplayCoordTransform.h" @@ -49,7 +51,8 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveDrawables(const caf::Display const Rim3dWellLogCurve* rim3dWellLogCurve, double planeOffsetFromWellPathCenter, double planeWidth, - const std::vector& drawSurfaceVertices) + const std::vector& drawSurfaceVertices, + int currentTimeStep) { CVF_ASSERT(rim3dWellLogCurve); @@ -66,7 +69,14 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveDrawables(const caf::Display std::vector resultValues; std::vector resultMds; - rim3dWellLogCurve->curveValuesAndMds(&resultValues, &resultMds); + if (rim3dWellLogCurve->followAnimationTimeStep()) + { + rim3dWellLogCurve->curveValuesAndMdsAtTimeStep(&resultValues, &resultMds, currentTimeStep); + } + else + { + rim3dWellLogCurve->curveValuesAndMds(&resultValues, &resultMds); + } m_planeWidth = planeWidth; @@ -95,15 +105,15 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveDrawables(const caf::Display } std::vector wellPathCurveNormals = - RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathPoints, rim3dWellLogCurve->drawPlaneAngle()); + RigWellPathGeometryTools::calculateLineSegmentNormals(wellPathPoints, rim3dWellLogCurve->drawPlaneAngle(rim3dWellLogCurve->drawPlane())); std::vector interpolatedWellPathPoints; std::vector interpolatedCurveNormals; // Iterate from bottom of well path and up to be able to stop at given Z max clipping height for (auto md = resultMds.rbegin(); md != resultMds.rend(); md++) { - cvf::Vec3d point = wellPathGeometry()->interpolatedVectorAlongWellPath(wellPathPoints, *md); - cvf::Vec3d normal = wellPathGeometry()->interpolatedVectorAlongWellPath(wellPathCurveNormals, *md); + cvf::Vec3d point = wellPathGeometry()->interpolatedVectorValuesAlongWellPath(wellPathPoints, *md); + cvf::Vec3d normal = wellPathGeometry()->interpolatedVectorValuesAlongWellPath(wellPathCurveNormals, *md); if (point.z() > clipLocation.z()) break; interpolatedWellPathPoints.push_back(point); @@ -129,7 +139,7 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveDrawables(const caf::Display for (double& result : m_curveValues) { - if (!RigCurveDataTools::isValidValue(result, false)) continue; + if (!RiaCurveDataTools::isValidValue(result, false)) continue; if ((minCurveValue - result) > curveEpsilon * curveUIRange) { @@ -158,7 +168,7 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveDrawables(const caf::Display { double scaledResult = 0; - if (RigCurveDataTools::isValidValue(m_curveValues[i], false)) + if (RiaCurveDataTools::isValidValue(m_curveValues[i], false)) { scaledResult = planeOffsetFromWellPathCenter + (m_curveValues[i] - minCurveValue) * plotRangeToResultRangeFactor; } @@ -174,8 +184,8 @@ void Riv3dWellLogCurveGeometryGenerator::createCurveDrawables(const caf::Display indices.reserve(m_curveVertices.size() * 2); for (size_t i = 0; i < m_curveVertices.size() - 1; ++i) { - if (RigCurveDataTools::isValidValue(m_curveValues[i], false) && - RigCurveDataTools::isValidValue(m_curveValues[i + 1], false)) + if (RiaCurveDataTools::isValidValue(m_curveValues[i], false) && + RiaCurveDataTools::isValidValue(m_curveValues[i + 1], false)) { if (cvf::Math::valueInRange(m_curveValues[i], minCurveValue, maxCurveValue) || cvf::Math::valueInRange(m_curveValues[i + 1], minCurveValue, maxCurveValue)) @@ -246,8 +256,8 @@ bool Riv3dWellLogCurveGeometryGenerator::findClosestPointOnCurve(const cvf::Vec3 CVF_ASSERT(m_curveVertices.size() == m_curveValues.size()); for (size_t i = 1; i < m_curveVertices.size(); ++i) { - bool validCurveSegment = RigCurveDataTools::isValidValue(m_curveValues[i], false) && - RigCurveDataTools::isValidValue(m_curveValues[i - 1], false); + bool validCurveSegment = RiaCurveDataTools::isValidValue(m_curveValues[i], false) && + RiaCurveDataTools::isValidValue(m_curveValues[i - 1], false); if (validCurveSegment) { cvf::Vec3d a = m_curveVertices[i - 1]; @@ -290,8 +300,8 @@ void Riv3dWellLogCurveGeometryGenerator::createNewVerticesAlongTriangleEdges(con for (size_t i = 0; i < m_curveVertices.size() - 1; i += 2) { - if (RigCurveDataTools::isValidValue(m_curveValues[i], false) && - RigCurveDataTools::isValidValue(m_curveValues[i + 1], false)) + if (RiaCurveDataTools::isValidValue(m_curveValues[i], false) && + RiaCurveDataTools::isValidValue(m_curveValues[i + 1], false)) { cvf::Vec3d lastVertex = m_curveVertices[i]; cvf::Vec3d fullSegmentVector = m_curveVertices[i + 1] - m_curveVertices[i]; diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeometryGenerator.h b/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeometryGenerator.h index d53d078640..9eeee18ff8 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogCurveGeometryGenerator.h @@ -52,7 +52,8 @@ class Riv3dWellLogCurveGeometryGenerator : public cvf::Object const Rim3dWellLogCurve* rim3dWellLogCurve, double planeOffsetFromWellPathCenter, double planeWidth, - const std::vector& drawSurfaceVertices); + const std::vector& drawSurfaceVertices, + int currentTimeStep); void clearCurvePointsAndGeometry(); diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogDrawSurfaceGenerator.cpp b/ApplicationCode/ModelVisualization/Riv3dWellLogDrawSurfaceGenerator.cpp index b42245c2de..82fb5a3a98 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogDrawSurfaceGenerator.cpp +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogDrawSurfaceGenerator.cpp @@ -193,7 +193,7 @@ void Riv3dWellLogDrawSurfaceGenerator::createCurveNormalVectors(const caf::Displ { cvf::Vec3d point = wellPathGeometry()->interpolatedPointAlongWellPath(md); point = displayCoordTransform->transformToDisplayCoord(point); - cvf::Vec3d curveNormal = wellPathGeometry()->interpolatedVectorAlongWellPath(segmentNormals, md); + cvf::Vec3d curveNormal = wellPathGeometry()->interpolatedVectorValuesAlongWellPath(segmentNormals, md); interpolatedWellPathPoints.push_back(point); interpolatedWellPathNormals.push_back(curveNormal.getNormalized()); md -= samplingIntervalSize; diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.cpp b/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.cpp index 8eb5f33f26..e4a1c5e7b0 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.cpp +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.cpp @@ -20,15 +20,16 @@ #include "RiaApplication.h" -#include "RiuViewer.h" #include "Rim3dView.h" #include "Rim3dWellLogCurveCollection.h" #include "RimCase.h" #include "RimGridView.h" #include "RimWellPath.h" +#include "RiuViewer.h" #include "Riv3dWellLogCurveGeometryGenerator.h" #include "Riv3dWellLogDrawSurfaceGenerator.h" +#include "RivMeshLinesSourceInfo.h" #include "RivObjectSourceInfo.h" #include "cafDisplayCoordTransform.h" @@ -52,7 +53,6 @@ Riv3dWellLogPlanePartMgr::Riv3dWellLogPlanePartMgr(RimWellPath* wellPath, RimGri , m_gridView(gridView) { CVF_ASSERT(m_wellPath.notNull()); - m_3dWellLogDrawSurfaceGeometryGenerator = new Riv3dWellLogDrawSurfaceGenerator(m_wellPath.p()); } //-------------------------------------------------------------------------------------------------- @@ -60,7 +60,8 @@ Riv3dWellLogPlanePartMgr::Riv3dWellLogPlanePartMgr(RimWellPath* wellPath, RimGri //-------------------------------------------------------------------------------------------------- void Riv3dWellLogPlanePartMgr::appendPlaneToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform, - const cvf::BoundingBox& wellPathClipBoundingBox) + const cvf::BoundingBox& wellPathClipBoundingBox, + bool isStaticResult) { if (m_wellPath.isNull()) return; @@ -70,16 +71,31 @@ void Riv3dWellLogPlanePartMgr::appendPlaneToModel(cvf::ModelBasicList* if (m_wellPath->rim3dWellLogCurveCollection()->vectorOf3dWellLogCurves().empty()) return; + if (isStaticResult) + { + std::set drawPlanes; + for (Rim3dWellLogCurve* rim3dWellLogCurve : m_wellPath->rim3dWellLogCurveCollection()->vectorOf3dWellLogCurves()) + { + if (rim3dWellLogCurve->showInView(m_gridView)) + { + drawPlanes.insert(rim3dWellLogCurve->drawPlane()); + } + } + for (Rim3dWellLogCurve::DrawPlane drawPlane : drawPlanes) + { + m_3dWellLogDrawSurfaceGeometryGenerators[drawPlane] = new Riv3dWellLogDrawSurfaceGenerator(m_wellPath.p()); + appendDrawSurfaceToModel(model, displayCoordTransform, wellPathClipBoundingBox, drawPlane, planeWidth()); + } + } for (Rim3dWellLogCurve* rim3dWellLogCurve : m_wellPath->rim3dWellLogCurveCollection()->vectorOf3dWellLogCurves()) { - if (rim3dWellLogCurve->isShowingCurve()) + if (rim3dWellLogCurve->showInView(m_gridView) && rim3dWellLogCurve->isShowingTimeDependentResult() != isStaticResult) { - appendDrawSurfaceToModel(model, displayCoordTransform, wellPathClipBoundingBox, rim3dWellLogCurve, planeWidth()); append3dWellLogCurveToModel(model, displayCoordTransform, wellPathClipBoundingBox, rim3dWellLogCurve, - m_3dWellLogDrawSurfaceGeometryGenerator->vertices()); + m_3dWellLogDrawSurfaceGeometryGenerators[rim3dWellLogCurve->drawPlane()]->vertices()); } } } @@ -103,13 +119,13 @@ void Riv3dWellLogPlanePartMgr::append3dWellLogCurveToModel(cvf::ModelBasicList* } generator->createCurveDrawables(displayCoordTransform, - wellPathClipBoundingBox, - rim3dWellLogCurve, - wellPathCenterToPlotStartOffset(rim3dWellLogCurve), - planeWidth(), - drawSurfaceVertices); + wellPathClipBoundingBox, + rim3dWellLogCurve, + wellPathCenterToPlotStartOffset(rim3dWellLogCurve->drawPlane()), + planeWidth(), + drawSurfaceVertices, + m_gridView->currentTimeStep()); - cvf::ref curveDrawable = generator->curveDrawable(); if (curveDrawable.notNull() && curveDrawable->boundingBox().isValid()) { @@ -117,14 +133,13 @@ void Riv3dWellLogPlanePartMgr::append3dWellLogCurveToModel(cvf::ModelBasicList* meshEffectGen.setLineWidth(3.0f); cvf::ref effect = meshEffectGen.generateCachedEffect(); - cvf::ref part = new cvf::Part; - part->setDrawable(curveDrawable.p()); - part->setEffect(effect.p()); - - if (part.notNull()) - { - model->addPart(part.p()); - } + cvf::ref part = new cvf::Part; + part->setDrawable(curveDrawable.p()); + part->setEffect(effect.p()); + + part->setSourceInfo(new RivMeshLinesSourceInfo(rim3dWellLogCurve)); + + model->addPart(part.p()); } } @@ -147,16 +162,15 @@ cvf::ref Riv3dWellLogPlanePartMgr::createPart(cvf::Drawable* drawable //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double Riv3dWellLogPlanePartMgr::wellPathCenterToPlotStartOffset(const Rim3dWellLogCurve* curve) const +double Riv3dWellLogPlanePartMgr::wellPathCenterToPlotStartOffset(Rim3dWellLogCurve::DrawPlane drawPlane) const { - if (curve->drawPlane() == Rim3dWellLogCurve::HORIZONTAL_CENTER || - curve->drawPlane() == Rim3dWellLogCurve::VERTICAL_CENTER) + if (drawPlane == Rim3dWellLogCurve::HORIZONTAL_CENTER || drawPlane == Rim3dWellLogCurve::VERTICAL_CENTER) { - return -0.5*planeWidth(); + return -0.5 * planeWidth(); } else { - double cellSize = m_gridView->ownerCase()->characteristicCellSize(); + double cellSize = m_gridView->ownerCase()->characteristicCellSize(); double wellPathOffset = std::min(m_wellPath->wellPathRadius(cellSize), 0.1 * planeWidth()); return m_wellPath->wellPathRadius(cellSize) + wellPathOffset; } @@ -169,32 +183,32 @@ double Riv3dWellLogPlanePartMgr::planeWidth() const { if (!m_gridView) return 0; - double cellSize = m_gridView->ownerCase()->characteristicCellSize(); - const Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection(); + double cellSize = m_gridView->ownerCase()->characteristicCellSize(); + const Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection(); return cellSize * curveCollection->planeWidthScaling(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void Riv3dWellLogPlanePartMgr::appendDrawSurfaceToModel(cvf::ModelBasicList* model, - const caf::DisplayCoordTransform* displayCoordTransform, - const cvf::BoundingBox& wellPathClipBoundingBox, - const Rim3dWellLogCurve* rim3dWellLogCurve, - double samplingInterval) +void Riv3dWellLogPlanePartMgr::appendDrawSurfaceToModel(cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayCoordTransform, + const cvf::BoundingBox& wellPathClipBoundingBox, + Rim3dWellLogCurve::DrawPlane drawPlane, + double samplingInterval) { - Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection(); - cvf::ref sourceInfo = new RivObjectSourceInfo(curveCollection); + Rim3dWellLogCurveCollection* curveCollection = m_wellPath->rim3dWellLogCurveCollection(); + cvf::ref sourceInfo = new RivObjectSourceInfo(curveCollection); - bool showCoordinateSystemMesh = curveCollection->isShowingGrid(); - bool showBackground = curveCollection->isShowingBackground(); + bool showCoordinateSystemMesh = curveCollection->isShowingGrid(); + bool showBackground = curveCollection->isShowingBackground(); - cvf::Color3f borderColor(0.4f, 0.4f, 0.4f); + cvf::Color3f borderColor(0.4f, 0.4f, 0.4f); caf::SurfaceEffectGenerator backgroundEffectGen(cvf::Color4f(1.0, 1.0, 1.0, 1.0), caf::PO_2); caf::MeshEffectGenerator borderEffectGen(borderColor); caf::VectorEffectGenerator curveNormalsEffectGen; backgroundEffectGen.enableLighting(false); - + if (!showBackground) { // Make the background invisible but still present for picking. @@ -203,20 +217,21 @@ void Riv3dWellLogPlanePartMgr::appendDrawSurfaceToModel(cvf::ModelBasicList* backgroundEffectGen.enableDepthWrite(false); } - bool drawSurfaceCreated = m_3dWellLogDrawSurfaceGeometryGenerator->createDrawSurface(displayCoordTransform, - wellPathClipBoundingBox, - rim3dWellLogCurve->drawPlaneAngle(), - wellPathCenterToPlotStartOffset(rim3dWellLogCurve), - planeWidth(), - samplingInterval); + bool drawSurfaceCreated = + m_3dWellLogDrawSurfaceGeometryGenerators[drawPlane]->createDrawSurface(displayCoordTransform, + wellPathClipBoundingBox, + Rim3dWellLogCurve::drawPlaneAngle(drawPlane), + wellPathCenterToPlotStartOffset(drawPlane), + planeWidth(), + samplingInterval); if (!drawSurfaceCreated) return; - cvf::ref backgroundEffect = backgroundEffectGen.generateCachedEffect(); - cvf::ref borderEffect = borderEffectGen.generateCachedEffect(); + cvf::ref backgroundEffect = backgroundEffectGen.generateCachedEffect(); + cvf::ref borderEffect = borderEffectGen.generateCachedEffect(); cvf::ref curveNormalsEffect = curveNormalsEffectGen.generateCachedEffect(); - - cvf::ref background = m_3dWellLogDrawSurfaceGeometryGenerator->background(); - + + cvf::ref background = m_3dWellLogDrawSurfaceGeometryGenerators[drawPlane]->background(); + if (background.notNull()) { cvf::ref part = createPart(background.p(), backgroundEffect.p()); @@ -229,7 +244,7 @@ void Riv3dWellLogPlanePartMgr::appendDrawSurfaceToModel(cvf::ModelBasicList* if (showCoordinateSystemMesh) { - cvf::ref border = m_3dWellLogDrawSurfaceGeometryGenerator->border(); + cvf::ref border = m_3dWellLogDrawSurfaceGeometryGenerators[drawPlane]->border(); if (border.notNull()) { cvf::ref part = createPart(border.p(), borderEffect.p()); @@ -239,7 +254,7 @@ void Riv3dWellLogPlanePartMgr::appendDrawSurfaceToModel(cvf::ModelBasicList* } } - cvf::ref normals = m_3dWellLogDrawSurfaceGeometryGenerator->curveNormalVectors(); + cvf::ref normals = m_3dWellLogDrawSurfaceGeometryGenerators[drawPlane]->curveNormalVectors(); if (normals.notNull()) { normals->setSingleColor(borderColor); diff --git a/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.h b/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.h index bed7b20347..372455e715 100644 --- a/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.h +++ b/ApplicationCode/ModelVisualization/Riv3dWellLogPlanePartMgr.h @@ -54,7 +54,8 @@ class Riv3dWellLogPlanePartMgr : public cvf::Object void appendPlaneToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform, - const cvf::BoundingBox& wellPathClipBoundingBox); + const cvf::BoundingBox& wellPathClipBoundingBox, + bool isStaticResult = false); private: void append3dWellLogCurveToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform, @@ -65,16 +66,16 @@ class Riv3dWellLogPlanePartMgr : public cvf::Object void appendDrawSurfaceToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform, const cvf::BoundingBox& wellPathClipBoundingBox, - const Rim3dWellLogCurve* rim3dWellLogCurve, + Rim3dWellLogCurve::DrawPlane drawPlane, double samplingInterval); cvf::ref createPart(cvf::Drawable* drawable, cvf::Effect* effect); - double wellPathCenterToPlotStartOffset(const Rim3dWellLogCurve* curve) const; + double wellPathCenterToPlotStartOffset(Rim3dWellLogCurve::DrawPlane drawPlane) const; double planeWidth() const; private: - cvf::ref m_3dWellLogDrawSurfaceGeometryGenerator; + std::map> m_3dWellLogDrawSurfaceGeometryGenerators; caf::PdmPointer m_wellPath; caf::PdmPointer m_gridView; diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp index 5af982f9ef..66df45f070 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.cpp @@ -140,10 +140,10 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) cvf::ShaderProgramGenerator shaderGen("CellEdgeFaceShaderProgramGenerator", cvf::ShaderSourceProvider::instance()); { - QFile data(":/Shader/fs_CellFace.glsl"); - if (data.open(QFile::ReadOnly)) + QFile file(":/Shader/fs_CellFace.glsl"); + if (file.open(QFile::ReadOnly)) { - QTextStream in(&data); + QTextStream in(&file); QString data = in.readAll(); cvf::String cvfString = cvfqt::Utils::toString(data); @@ -155,10 +155,10 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) if (m_ternaryCellScalarMapper.notNull()) { { - QFile data(":/Shader/vs_2dTextureCellFace.glsl"); - if (data.open(QFile::ReadOnly)) + QFile file(":/Shader/vs_2dTextureCellFace.glsl"); + if (file.open(QFile::ReadOnly)) { - QTextStream in(&data); + QTextStream in(&file); QString data = in.readAll(); cvf::String cvfString = cvfqt::Utils::toString(data); @@ -170,10 +170,10 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect) else { { - QFile data(":/Shader/vs_CellFace.glsl"); - if (data.open(QFile::ReadOnly)) + QFile file(":/Shader/vs_CellFace.glsl"); + if (file.open(QFile::ReadOnly)) { - QTextStream in(&data); + QTextStream in(&file); QString data = in.readAll(); cvf::String cvfString = cvfqt::Utils::toString(data); diff --git a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h index 80f5c9da24..a0121e1d1a 100644 --- a/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h +++ b/ApplicationCode/ModelVisualization/RivCellEdgeEffectGenerator.h @@ -113,11 +113,11 @@ class CellEdgeEffectGenerator : public caf::EffectGenerator void disableLighting(bool disable) { m_disableLighting = disable; } protected: - virtual bool isEqual( const EffectGenerator* other ) const; - virtual EffectGenerator* copy() const; + bool isEqual( const EffectGenerator* other ) const override; + EffectGenerator* copy() const override; - virtual void updateForShaderBasedRendering(cvf::Effect* effect) const; - virtual void updateForFixedFunctionRendering(cvf::Effect* effect) const; + void updateForShaderBasedRendering(cvf::Effect* effect) const override; + void updateForFixedFunctionRendering(cvf::Effect* effect) const override; private: cvf::cref m_edgeScalarMapper; diff --git a/ApplicationCode/ModelVisualization/RivCompletionTypeResultToTextureMapper.h b/ApplicationCode/ModelVisualization/RivCompletionTypeResultToTextureMapper.h index 9dcf297a4e..e7ab0a6d75 100644 --- a/ApplicationCode/ModelVisualization/RivCompletionTypeResultToTextureMapper.h +++ b/ApplicationCode/ModelVisualization/RivCompletionTypeResultToTextureMapper.h @@ -36,7 +36,7 @@ class RivCompletionTypeResultToTextureMapper : public RivResultToTextureMapper public: using RivResultToTextureMapper::RivResultToTextureMapper; - cvf::Vec2f getTexCoord(double resultValue, size_t cellIndex) const + cvf::Vec2f getTexCoord(double resultValue, size_t cellIndex) const override { cvf::Vec2f texCoord(0, 0); diff --git a/ApplicationCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp b/ApplicationCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp new file mode 100644 index 0000000000..0dfe93034b --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivContourMapProjectionPartMgr.cpp @@ -0,0 +1,232 @@ +#include "RivContourMapProjectionPartMgr.h" + +#include "RiaWeightedMeanCalculator.h" +#include "RivMeshLinesSourceInfo.h" +#include "RivScalarMapperUtils.h" + +#include "RimContourMapView.h" +#include "RimContourMapProjection.h" + +#include "cafEffectGenerator.h" + +#include "cvfGeometryBuilderFaceList.h" +#include "cvfGeometryUtils.h" +#include "cvfMeshEdgeExtractor.h" +#include "cvfPart.h" +#include "cvfPrimitiveSetIndexedUInt.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivContourMapProjectionPartMgr::RivContourMapProjectionPartMgr(RimContourMapProjection* contourMapProjection, RimContourMapView* contourMap) +{ + m_contourMapProjection = contourMapProjection; + m_parentContourMap = contourMap; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivContourMapProjectionPartMgr::appendProjectionToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform) const +{ + cvf::ref drawable = createProjectionMapDrawable(displayCoordTransform); + if (drawable.notNull() && drawable->boundingBox().isValid()) + { + cvf::ref part = new cvf::Part; + part->setDrawable(drawable.p()); + + cvf::ref textureCoords = createTextureCoords(); + cvf::ScalarMapper* mapper = m_contourMapProjection->legendConfig()->scalarMapper(); + RivScalarMapperUtils::applyTextureResultsToPart(part.p(), textureCoords.p(), mapper, 1.0f, caf::FC_NONE, true, m_parentContourMap->backgroundColor()); + + part->setSourceInfo(new RivObjectSourceInfo(m_contourMapProjection.p())); + + model->addPart(part.p()); + } + + if (m_contourMapProjection->showContourLines()) + { + std::vector> contourDrawables = createContourPolygons(displayCoordTransform); + for (cvf::ref contourDrawable : contourDrawables) + { + if (contourDrawable.notNull() && contourDrawable->boundingBox().isValid()) + { + caf::MeshEffectGenerator meshEffectGen(cvf::Color3::BLACK); + meshEffectGen.setLineWidth(1.0f); + meshEffectGen.createAndConfigurePolygonOffsetRenderState(caf::PO_1); + cvf::ref effect = meshEffectGen.generateCachedEffect(); + + cvf::ref part = new cvf::Part; + part->setDrawable(contourDrawable.p()); + part->setEffect(effect.p()); + part->setSourceInfo(new RivMeshLinesSourceInfo(m_contourMapProjection.p())); + + model->addPart(part.p()); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivContourMapProjectionPartMgr::appendPickPointVisToModel(cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayCoordTransform) const +{ + cvf::ref drawable = createPickPointVisDrawable(displayCoordTransform); + if (drawable.notNull() && drawable->boundingBox().isValid()) + { + caf::MeshEffectGenerator meshEffectGen(cvf::Color3::MAGENTA); + meshEffectGen.setLineWidth(1.0f); + meshEffectGen.createAndConfigurePolygonOffsetRenderState(caf::PO_2); + cvf::ref effect = meshEffectGen.generateCachedEffect(); + + cvf::ref part = new cvf::Part; + part->setDrawable(drawable.p()); + part->setEffect(effect.p()); + part->setSourceInfo(new RivMeshLinesSourceInfo(m_contourMapProjection.p())); + + model->addPart(part.p()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivContourMapProjectionPartMgr::createTextureCoords() const +{ + cvf::Vec2ui patchSize = m_contourMapProjection->numberOfVerticesIJ(); + + cvf::ref textureCoords = new cvf::Vec2fArray(m_contourMapProjection->numberOfVertices()); + +#pragma omp parallel for + for (int j = 0; j < static_cast(patchSize.y()); ++j) + { + for (int i = 0; i < static_cast(patchSize.x()); ++i) + { + if (m_contourMapProjection->hasResultAtVertex(i, j)) + { + double value = m_contourMapProjection->valueAtVertex(i, j); + cvf::Vec2f textureCoord = m_contourMapProjection->legendConfig()->scalarMapper()->mapToTextureCoord(value); + textureCoord.y() = 0.0; + (*textureCoords)[i + j * patchSize.x()] = textureCoord; + } + else + { + RiaWeightedMeanCalculator calc; + for (int jj = j - 1; jj <= j + 1; ++jj) + { + for (int ii = i - 1; ii <= i + 1; ++ii) + { + if (jj >= 0 && ii >= 0 && jj < static_cast(patchSize.y()) && ii < static_cast(patchSize.x())) + { + if (!(ii == i && jj == j) && m_contourMapProjection->hasResultAtVertex(ii, jj)) + { + double value = m_contourMapProjection->valueAtVertex(ii, jj); + calc.addValueAndWeight(value, 1. / std::sqrt((i - ii)*(i - ii) + (j - jj)*(j - jj))); + } + } + } + } + if (calc.validAggregatedWeight()) + { + const double maxTheoreticalWeightSum = 4.0 + 4.0 / std::sqrt(2.0); + double value = calc.weightedMean(); + cvf::Vec2f textureCoord = m_contourMapProjection->legendConfig()->scalarMapper()->mapToTextureCoord(value); + textureCoord.y() = 1.0 - calc.aggregatedWeight() / maxTheoreticalWeightSum; + (*textureCoords)[i + j * patchSize.x()] = textureCoord; + } + else + { + (*textureCoords)[i + j * patchSize.x()] = cvf::Vec2f(0.0, 1.0); + } + } + } + } + return textureCoords; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivContourMapProjectionPartMgr::createProjectionMapDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const +{ + cvf::ref vertexArray = new cvf::Vec3fArray; + m_contourMapProjection->generateVertices(vertexArray.p(), displayCoordTransform); + cvf::Vec2ui patchSize = m_contourMapProjection->numberOfVerticesIJ(); + + // Surface + cvf::ref faceList = new cvf::UIntArray; + cvf::GeometryUtils::tesselatePatchAsTriangles(patchSize.x(), patchSize.y(), 0u, true, faceList.p()); + + cvf::ref indexUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_TRIANGLES, faceList.p()); + + cvf::ref geo = new cvf::DrawableGeo; + geo->addPrimitiveSet(indexUInt.p()); + geo->setVertexArray(vertexArray.p()); + return geo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> RivContourMapProjectionPartMgr::createContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) const +{ + RimContourMapProjection::ContourPolygons contourPolygons = m_contourMapProjection->generateContourPolygons(displayCoordTransform); + + std::vector> contourDrawables; + contourDrawables.reserve(contourPolygons.size()); + for (size_t i = 0; i < contourPolygons.size(); ++i) + { + cvf::ref vertexArray = contourPolygons[i]; + std::vector indices; + indices.reserve(contourPolygons[i]->size()); + for (cvf::uint j = 0; j < contourPolygons[i]->size(); ++j) + { + indices.push_back(j); + } + + cvf::ref indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINES); + cvf::ref indexArray = new cvf::UIntArray(indices); + indexedUInt->setIndices(indexArray.p()); + + cvf::ref geo = new cvf::DrawableGeo; + + geo->addPrimitiveSet(indexedUInt.p()); + geo->setVertexArray(vertexArray.p()); + contourDrawables.push_back(geo); + } + return contourDrawables; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref + RivContourMapProjectionPartMgr::createPickPointVisDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const +{ + cvf::ref geo = nullptr; + + cvf::ref pickPointPolygon = m_contourMapProjection->generatePickPointPolygon(displayCoordTransform); + if (pickPointPolygon.notNull() && pickPointPolygon->size() > 0u) + { + std::vector indices; + indices.reserve(pickPointPolygon->size()); + for (cvf::uint j = 0; j < pickPointPolygon->size(); ++j) + { + indices.push_back(j); + } + + cvf::ref indexedUInt = new cvf::PrimitiveSetIndexedUInt(cvf::PrimitiveType::PT_LINES); + cvf::ref indexArray = new cvf::UIntArray(indices); + indexedUInt->setIndices(indexArray.p()); + + geo = new cvf::DrawableGeo; + + geo->addPrimitiveSet(indexedUInt.p()); + geo->setVertexArray(pickPointPolygon.p()); + } + return geo; +} diff --git a/ApplicationCode/ModelVisualization/RivContourMapProjectionPartMgr.h b/ApplicationCode/ModelVisualization/RivContourMapProjectionPartMgr.h new file mode 100644 index 0000000000..af580e391f --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivContourMapProjectionPartMgr.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmPointer.h" +#include "cafDisplayCoordTransform.h" + +#include "cvfBase.h" +#include "cvfDrawableGeo.h" +#include "cvfModelBasicList.h" +#include "cvfObject.h" + +class RimContourMapView; +class RimContourMapProjection; + +class RivContourMapProjectionPartMgr : public cvf::Object +{ +public: + RivContourMapProjectionPartMgr(RimContourMapProjection* contourMapProjection, RimContourMapView* contourMap); + + void appendProjectionToModel(cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayCoordTransform) const; + void appendPickPointVisToModel(cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayCoordTransform) const; + + cvf::ref createTextureCoords() const; + +private: + cvf::ref createProjectionMapDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const; + std::vector> createContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) const; + cvf::ref createPickPointVisDrawable(const caf::DisplayCoordTransform* displayCoordTransform) const; +private: + caf::PdmPointer m_contourMapProjection; + caf::PdmPointer m_parentContourMap; +}; + diff --git a/ApplicationCode/ModelVisualization/RivDefaultResultToTextureMapper.h b/ApplicationCode/ModelVisualization/RivDefaultResultToTextureMapper.h index 3dfe032e03..7d2f9ca0eb 100644 --- a/ApplicationCode/ModelVisualization/RivDefaultResultToTextureMapper.h +++ b/ApplicationCode/ModelVisualization/RivDefaultResultToTextureMapper.h @@ -35,7 +35,7 @@ class RivDefaultResultToTextureMapper : public RivResultToTextureMapper public: using RivResultToTextureMapper::RivResultToTextureMapper; - cvf::Vec2f getTexCoord(double resultValue, size_t cellIndex) const + cvf::Vec2f getTexCoord(double resultValue, size_t cellIndex) const override { cvf::Vec2f texCoord(0,0); diff --git a/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.cpp index b46d76b969..360c110037 100644 --- a/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.cpp @@ -183,7 +183,7 @@ void RivFaultGeometryGenerator::computeArrays() m_grid->cellFaceVertexIndices(face, faceConn); // Critical section to avoid two threads accessing the arrays at the same time. -#pragma omp critical +#pragma omp critical(critical_section_RivFaultGeometryGenerator_computeArrays) { int n; for (n = 0; n < 4; n++) diff --git a/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h b/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h index 948ba2b1cb..416c256064 100644 --- a/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/RivFaultGeometryGenerator.h @@ -44,7 +44,7 @@ class RivFaultGeometryGenerator : public cvf::Object { public: RivFaultGeometryGenerator(const cvf::StructGridInterface* grid, const RigFault* fault, bool computeNativeFaultFaces); - ~RivFaultGeometryGenerator(); + ~RivFaultGeometryGenerator() override; void setCellVisibility(const cvf::UByteArray* cellVisibilities ); diff --git a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp index f2a06238fa..39f054b7ea 100644 --- a/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivFaultPartMgr.cpp @@ -2,17 +2,17 @@ // // Copyright (C) Statoil ASA // Copyright (C) Ceetron Solutions AS -// +// // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -44,6 +44,7 @@ #include "RivTernaryTextureCoordsCreator.h" #include "RivTextureCoordsCreator.h" +#include "RivMeshLinesSourceInfo.h" #include "cvfDrawableGeo.h" #include "cvfDrawableText.h" #include "cvfModelBasicList.h" @@ -51,32 +52,34 @@ #include "cvfPrimitiveSetDirect.h" #include "cvfqtUtils.h" - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RivFaultPartMgr::RivFaultPartMgr(const RigGridBase* grid, const RimFaultInViewCollection* rimFaultCollection, const RimFaultInView* rimFault) - : m_grid(grid), - m_rimFaultCollection(rimFaultCollection), - m_rimFault(rimFault), - m_opacityLevel(1.0f), - m_defaultColor(cvf::Color3::WHITE) +RivFaultPartMgr::RivFaultPartMgr(const RigGridBase* grid, + const RimFaultInViewCollection* rimFaultCollection, + RimFaultInView* rimFault) + : m_grid(grid) + , m_rimFaultCollection(rimFaultCollection) + , m_rimFault(rimFault) + , m_opacityLevel(1.0f) + , m_defaultColor(cvf::Color3::WHITE) { - cvf::ref< cvf::Array > connIdxes = new cvf::Array; + cvf::ref> connIdxes = new cvf::Array; connIdxes->assign(rimFault->faultGeometry()->connectionIndices()); - m_nativeFaultGenerator = new RivFaultGeometryGenerator(grid, rimFault->faultGeometry(), true); - m_oppositeFaultGenerator = new RivFaultGeometryGenerator(grid, rimFault->faultGeometry(), false); + m_nativeFaultGenerator = new RivFaultGeometryGenerator(grid, rimFault->faultGeometry(), true); + m_oppositeFaultGenerator = new RivFaultGeometryGenerator(grid, rimFault->faultGeometry(), false); - m_NNCGenerator = new RivNNCGeometryGenerator(grid->mainGrid()->nncData(), grid->mainGrid()->displayModelOffset(), connIdxes.p()); + m_NNCGenerator = + new RivNNCGeometryGenerator(grid->mainGrid()->nncData(), grid->mainGrid()->displayModelOffset(), connIdxes.p()); - m_nativeFaultFacesTextureCoords = new cvf::Vec2fArray; + m_nativeFaultFacesTextureCoords = new cvf::Vec2fArray; m_oppositeFaultFacesTextureCoords = new cvf::Vec2fArray; - m_NNCTextureCoords = new cvf::Vec2fArray; + m_NNCTextureCoords = new cvf::Vec2fArray; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::setCellVisibility(cvf::UByteArray* cellVisibilities) { @@ -88,7 +91,7 @@ void RivFaultPartMgr::setCellVisibility(cvf::UByteArray* cellVisibilities) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::applySingleColorEffect() { @@ -97,7 +100,7 @@ void RivFaultPartMgr::applySingleColorEffect() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors) { @@ -106,29 +109,32 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCell updateNNCColors(timeStepIndex, cellResultColors); RimEclipseView* eclipseView = cellResultColors->reservoirView(); - RigEclipseCaseData* eclipseCase = eclipseView->eclipseCase()->eclipseCaseData(); // Faults if (m_nativeFaultFaces.notNull()) { if (cellResultColors->isTernarySaturationSelected()) { - RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), - timeStepIndex, - m_grid->gridIndex(), - m_nativeFaultGenerator->quadToCellFaceMapper()); + RivTernaryTextureCoordsCreator texturer(cellResultColors, + cellResultColors->ternaryLegendConfig(), + timeStepIndex, + m_grid->gridIndex(), + m_nativeFaultGenerator->quadToCellFaceMapper()); texturer.createTextureCoords(m_nativeFaultFacesTextureCoords.p()); const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); - RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_nativeFaultFaces.p(), m_nativeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled()); + RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_nativeFaultFaces.p(), + m_nativeFaultFacesTextureCoords.p(), + mapper, + m_opacityLevel, + this->faceCullingMode(), + eclipseView->isLightingDisabled()); } else { - RivTextureCoordsCreator texturer(cellResultColors, - timeStepIndex, - m_grid->gridIndex(), - m_nativeFaultGenerator->quadToCellFaceMapper()); + RivTextureCoordsCreator texturer( + cellResultColors, timeStepIndex, m_grid->gridIndex(), m_nativeFaultGenerator->quadToCellFaceMapper()); if (!texturer.isValid()) { @@ -138,7 +144,12 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCell texturer.createTextureCoords(m_nativeFaultFacesTextureCoords.p()); const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); - RivScalarMapperUtils::applyTextureResultsToPart(m_nativeFaultFaces.p(), m_nativeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled()); + RivScalarMapperUtils::applyTextureResultsToPart(m_nativeFaultFaces.p(), + m_nativeFaultFacesTextureCoords.p(), + mapper, + m_opacityLevel, + this->faceCullingMode(), + eclipseView->isLightingDisabled()); } } @@ -146,22 +157,26 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCell { if (cellResultColors->isTernarySaturationSelected()) { - RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), - timeStepIndex, - m_grid->gridIndex(), - m_oppositeFaultGenerator->quadToCellFaceMapper()); + RivTernaryTextureCoordsCreator texturer(cellResultColors, + cellResultColors->ternaryLegendConfig(), + timeStepIndex, + m_grid->gridIndex(), + m_oppositeFaultGenerator->quadToCellFaceMapper()); texturer.createTextureCoords(m_oppositeFaultFacesTextureCoords.p()); const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); - RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_oppositeFaultFaces.p(), m_oppositeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled()); + RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_oppositeFaultFaces.p(), + m_oppositeFaultFacesTextureCoords.p(), + mapper, + m_opacityLevel, + this->faceCullingMode(), + eclipseView->isLightingDisabled()); } else { - RivTextureCoordsCreator texturer(cellResultColors, - timeStepIndex, - m_grid->gridIndex(), - m_oppositeFaultGenerator->quadToCellFaceMapper()); + RivTextureCoordsCreator texturer( + cellResultColors, timeStepIndex, m_grid->gridIndex(), m_oppositeFaultGenerator->quadToCellFaceMapper()); if (!texturer.isValid()) { @@ -171,15 +186,22 @@ void RivFaultPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCell texturer.createTextureCoords(m_oppositeFaultFacesTextureCoords.p()); const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); - RivScalarMapperUtils::applyTextureResultsToPart(m_oppositeFaultFaces.p(), m_oppositeFaultFacesTextureCoords.p(), mapper, m_opacityLevel, this->faceCullingMode(), eclipseView->isLightingDisabled()); + RivScalarMapperUtils::applyTextureResultsToPart(m_oppositeFaultFaces.p(), + m_oppositeFaultFacesTextureCoords.p(), + mapper, + m_opacityLevel, + this->faceCullingMode(), + eclipseView->isLightingDisabled()); } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors, RimCellEdgeColors* cellEdgeResultColors) +void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors) { updateNNCColors(timeStepIndex, cellResultColors); @@ -188,9 +210,17 @@ void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimEclipse cvf::DrawableGeo* dg = dynamic_cast(m_nativeFaultFaces->drawable()); if (dg) { - cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_nativeFaultGenerator->quadToCellFaceMapper(), - m_grid->gridIndex(), - timeStepIndex, cellResultColors, cellEdgeResultColors, m_opacityLevel, m_defaultColor, this->faceCullingMode(), cellResultColors->reservoirView()->isLightingDisabled()); + cvf::ref eff = + RivScalarMapperUtils::createCellEdgeEffect(dg, + m_nativeFaultGenerator->quadToCellFaceMapper(), + m_grid->gridIndex(), + timeStepIndex, + cellResultColors, + cellEdgeResultColors, + m_opacityLevel, + m_defaultColor, + this->faceCullingMode(), + cellResultColors->reservoirView()->isLightingDisabled()); m_nativeFaultFaces->setEffect(eff.p()); } @@ -201,8 +231,17 @@ void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimEclipse cvf::DrawableGeo* dg = dynamic_cast(m_oppositeFaultFaces->drawable()); if (dg) { - cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_oppositeFaultGenerator->quadToCellFaceMapper(), m_grid->gridIndex(), - timeStepIndex, cellResultColors, cellEdgeResultColors, m_opacityLevel, m_defaultColor, this->faceCullingMode(), cellResultColors->reservoirView()->isLightingDisabled()); + cvf::ref eff = + RivScalarMapperUtils::createCellEdgeEffect(dg, + m_oppositeFaultGenerator->quadToCellFaceMapper(), + m_grid->gridIndex(), + timeStepIndex, + cellResultColors, + cellEdgeResultColors, + m_opacityLevel, + m_defaultColor, + this->faceCullingMode(), + cellResultColors->reservoirView()->isLightingDisabled()); m_oppositeFaultFaces->setEffect(eff.p()); } @@ -210,11 +249,10 @@ void RivFaultPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimEclipse } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::generatePartGeometry() { - bool useBufferObjects = true; // Surface geometry { @@ -233,7 +271,7 @@ void RivFaultPartMgr::generatePartGeometry() part->setDrawable(geo.p()); // Set mapping from triangle face index to cell index - cvf::ref si = new RivSourceInfo(m_grid->gridIndex()); + cvf::ref si = new RivSourceInfo(m_rimFault, m_grid->gridIndex()); si->m_cellFaceFromTriangleMapper = m_nativeFaultGenerator->triangleToCellFaceMapper(); part->setSourceInfo(si.p()); @@ -263,11 +301,12 @@ void RivFaultPartMgr::generatePartGeometry() part->setEnableMask(meshFaultBit); part->setPriority(RivPartPriority::PartType::FaultMeshLines); + part->setSourceInfo(new RivMeshLinesSourceInfo(m_rimFault)); + m_nativeFaultGridLines = part; } } - // Surface geometry { cvf::ref geo = m_oppositeFaultGenerator->generateSurface(); @@ -285,7 +324,7 @@ void RivFaultPartMgr::generatePartGeometry() part->setDrawable(geo.p()); // Set mapping from triangle face index to cell index - cvf::ref si = new RivSourceInfo(m_grid->gridIndex()); + cvf::ref si = new RivSourceInfo(m_rimFault, m_grid->gridIndex()); si->m_cellFaceFromTriangleMapper = m_oppositeFaultGenerator->triangleToCellFaceMapper(); part->setSourceInfo(si.p()); @@ -315,6 +354,8 @@ void RivFaultPartMgr::generatePartGeometry() part->setEnableMask(meshFaultBit); part->setPriority(RivPartPriority::PartType::FaultMeshLines); + part->setSourceInfo(new RivMeshLinesSourceInfo(m_rimFault)); + m_oppositeFaultGridLines = part; } } @@ -335,8 +376,8 @@ void RivFaultPartMgr::generatePartGeometry() part->setDrawable(geo.p()); // Set mapping from triangle face index to cell index - cvf::ref si = new RivSourceInfo(m_grid->gridIndex());; - si->m_NNCIndices = m_NNCGenerator->triangleToNNCIndex().p(); + cvf::ref si = new RivSourceInfo(m_rimFault, m_grid->gridIndex()); + si->m_NNCIndices = m_NNCGenerator->triangleToNNCIndex().p(); part->setSourceInfo(si.p()); part->updateBoundingBox(); @@ -346,22 +387,21 @@ void RivFaultPartMgr::generatePartGeometry() m_NNCFaces = part; } } - + createLabelWithAnchorLine(m_nativeFaultFaces.p()); updatePartEffect(); } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::updatePartEffect() { // Set default effect caf::SurfaceEffectGenerator geometryEffgen(m_defaultColor, caf::PO_1); geometryEffgen.setCullBackfaces(faceCullingMode()); - + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); if (m_nativeFaultFaces.notNull()) @@ -379,7 +419,7 @@ void RivFaultPartMgr::updatePartEffect() // Update mesh colors as well, in case of change RiaPreferences* prefs = RiaApplication::instance()->preferences(); - cvf::ref eff; + cvf::ref eff; caf::MeshEffectGenerator faultEffGen(prefs->defaultFaultGridLineColors()); eff = faultEffGen.generateCachedEffect(); @@ -398,7 +438,7 @@ void RivFaultPartMgr::updatePartEffect() // Set priority to make sure this transparent geometry are rendered last if (m_nativeFaultFaces.notNull()) m_nativeFaultFaces->setPriority(RivPartPriority::PartType::TransparentFault); if (m_oppositeFaultFaces.notNull()) m_oppositeFaultFaces->setPriority(RivPartPriority::PartType::TransparentFault); - if (m_NNCFaces.notNull()) m_NNCFaces->setPriority(RivPartPriority::PartType::TransparentNnc); + if (m_NNCFaces.notNull()) m_NNCFaces->setPriority(RivPartPriority::PartType::TransparentNnc); if (m_nativeFaultGridLines.notNull()) { @@ -413,11 +453,11 @@ void RivFaultPartMgr::updatePartEffect() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::createLabelWithAnchorLine(const cvf::Part* part) { - m_faultLabelPart = nullptr; + m_faultLabelPart = nullptr; m_faultLabelLinePart = nullptr; if (!part) return; @@ -425,7 +465,7 @@ void RivFaultPartMgr::createLabelWithAnchorLine(const cvf::Part* part) cvf::BoundingBox bb = part->boundingBox(); cvf::Vec3d bbTopCenter = bb.center(); - bbTopCenter.z() = bb.max().z(); + bbTopCenter.z() = bb.max().z(); const cvf::DrawableGeo* geo = dynamic_cast(part->drawable()); @@ -448,17 +488,15 @@ void RivFaultPartMgr::createLabelWithAnchorLine(const cvf::Part* part) drawableText->setDrawBorder(false); drawableText->setDrawBackground(false); drawableText->setVerticalAlignment(cvf::TextDrawer::CENTER); - + cvf::Color3f defWellLabelColor = RiaApplication::instance()->preferences()->defaultWellLabelColor(); { - RimFaultInView* noConstRimFault = const_cast(m_rimFault); - if (noConstRimFault) { RimFaultInViewCollection* parentObject; - noConstRimFault->firstAncestorOrThisOfType(parentObject); + m_rimFault->firstAncestorOrThisOfType(parentObject); if (parentObject) { - defWellLabelColor = parentObject->faultLabelColor();; + defWellLabelColor = parentObject->faultLabelColor(); } } } @@ -468,24 +506,23 @@ void RivFaultPartMgr::createLabelWithAnchorLine(const cvf::Part* part) cvf::String cvfString = cvfqt::Utils::toString(m_rimFault->name()); cvf::Vec3f textCoord(labelPosition); - double characteristicCellSize = bb.extent().z() / 20; + double characteristicCellSize = bb.extent().z() / 20; textCoord.z() += characteristicCellSize; drawableText->addText(cvfString, textCoord); - cvf::ref part = new cvf::Part; - part->setName("RivFaultPart : text " + cvfString); - part->setDrawable(drawableText.p()); + cvf::ref labelPart = new cvf::Part; + labelPart->setName("RivFaultPart : text " + cvfString); + labelPart->setDrawable(drawableText.p()); cvf::ref eff = new cvf::Effect; - part->setEffect(eff.p()); - part->setPriority(RivPartPriority::PartType::Text); + labelPart->setEffect(eff.p()); + labelPart->setPriority(RivPartPriority::PartType::Text); - m_faultLabelPart = part; + m_faultLabelPart = labelPart; } - // Line from fault geometry to label { cvf::ref vertices = new cvf::Vec3fArray; @@ -493,34 +530,34 @@ void RivFaultPartMgr::createLabelWithAnchorLine(const cvf::Part* part) vertices->add(faultVertexToAttachLabel); vertices->add(labelPosition); - cvf::ref geo = new cvf::DrawableGeo; - geo->setVertexArray(vertices.p()); + cvf::ref lineGeo = new cvf::DrawableGeo; + lineGeo->setVertexArray(vertices.p()); cvf::ref primSet = new cvf::PrimitiveSetDirect(cvf::PT_LINES); primSet->setStartIndex(0); primSet->setIndexCount(vertices->size()); - geo->addPrimitiveSet(primSet.p()); + lineGeo->addPrimitiveSet(primSet.p()); m_faultLabelLinePart = new cvf::Part; m_faultLabelLinePart->setName("Anchor line for label" + cvf::String(static_cast(m_grid->gridIndex()))); - m_faultLabelLinePart->setDrawable(geo.p()); + m_faultLabelLinePart->setDrawable(lineGeo.p()); m_faultLabelLinePart->updateBoundingBox(); caf::MeshEffectGenerator gen(m_rimFault->faultColor()); - cvf::ref eff = gen.generateCachedEffect(); - + cvf::ref eff = gen.generateCachedEffect(); + m_faultLabelLinePart->setEffect(eff.p()); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::Vec3f RivFaultPartMgr::findClosestVertex(const cvf::Vec3f& point, const cvf::Vec3fArray* vertices) { CVF_ASSERT(vertices); - + if (!vertices) return cvf::Vec3f::UNDEFINED; float closestDiff(HUGE_VAL); @@ -533,7 +570,7 @@ cvf::Vec3f RivFaultPartMgr::findClosestVertex(const cvf::Vec3f& point, const cvf if (diff < closestDiff) { - closestDiff = diff; + closestDiff = diff; closestIndex = i; } } @@ -549,7 +586,7 @@ cvf::Vec3f RivFaultPartMgr::findClosestVertex(const cvf::Vec3f& point, const cvf } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::appendNativeFaultFacesToModel(cvf::ModelBasicList* model) { @@ -560,7 +597,7 @@ void RivFaultPartMgr::appendNativeFaultFacesToModel(cvf::ModelBasicList* model) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::appendOppositeFaultFacesToModel(cvf::ModelBasicList* model) { @@ -571,38 +608,38 @@ void RivFaultPartMgr::appendOppositeFaultFacesToModel(cvf::ModelBasicList* model } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::appendLabelPartsToModel(cvf::ModelBasicList* model) { - if (m_faultLabelPart.notNull()) model->addPart(m_faultLabelPart.p()); - if (m_faultLabelLinePart.notNull()) model->addPart(m_faultLabelLinePart.p()); + if (m_faultLabelPart.notNull()) model->addPart(m_faultLabelPart.p()); + if (m_faultLabelLinePart.notNull()) model->addPart(m_faultLabelLinePart.p()); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::appendMeshLinePartsToModel(cvf::ModelBasicList* model) { - if (m_nativeFaultGridLines.notNull()) model->addPart(m_nativeFaultGridLines.p()); + if (m_nativeFaultGridLines.notNull()) model->addPart(m_nativeFaultGridLines.p()); if (m_oppositeFaultGridLines.notNull()) model->addPart(m_oppositeFaultGridLines.p()); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::appendNNCFacesToModel(cvf::ModelBasicList* model) { - if (m_NNCFaces.notNull()) model->addPart(m_NNCFaces.p()); + if (m_NNCFaces.notNull()) model->addPart(m_NNCFaces.p()); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- caf::FaceCulling RivFaultPartMgr::faceCullingMode() const { bool isShowingGrid = m_rimFaultCollection->isGridVisualizationMode(); - if (!isShowingGrid ) + if (!isShowingGrid) { if (m_rimFaultCollection->faultResult() == RimFaultInViewCollection::FAULT_BACK_FACE_CULLING) { @@ -628,7 +665,7 @@ caf::FaceCulling RivFaultPartMgr::faceCullingMode() const } else { - return caf::FC_NONE; + return caf::FC_NONE; } } else @@ -639,7 +676,7 @@ caf::FaceCulling RivFaultPartMgr::faceCullingMode() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivFaultPartMgr::updateNNCColors(size_t timeStepIndex, RimEclipseCellColors* cellResultColors) { @@ -662,18 +699,19 @@ void RivFaultPartMgr::updateNNCColors(size_t timeStepIndex, RimEclipseCellColors if (showNncsWithScalarMappedColor) { - size_t scalarSetIndex = cellResultColors->scalarResultIndex(); - RiaDefines::ResultCatType resultType = cellResultColors->resultType(); + size_t scalarSetIndex = cellResultColors->scalarResultIndex(); + RiaDefines::ResultCatType resultType = cellResultColors->resultType(); const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); - + if (eclipseView) { RimEclipseCase* eclipseCase = eclipseView->eclipseCase(); if (eclipseCase) { size_t nativeTimeStepIndex = eclipseCase->uiToNativeTimeStepIndex(timeStepIndex); - m_NNCGenerator->textureCoordinates(m_NNCTextureCoords.p(), mapper, resultType, scalarSetIndex, nativeTimeStepIndex); + m_NNCGenerator->textureCoordinates( + m_NNCTextureCoords.p(), mapper, resultType, scalarSetIndex, nativeTimeStepIndex); } } @@ -703,9 +741,9 @@ void RivFaultPartMgr::updateNNCColors(size_t timeStepIndex, RimEclipseCellColors { // NNC faces a bit lighter than the fault for now cvf::Color3f nncColor = m_defaultColor; - nncColor.r() += (1.0 - nncColor.r()) * 0.2; - nncColor.g() += (1.0 - nncColor.g()) * 0.2; - nncColor.b() += (1.0 - nncColor.b()) * 0.2; + nncColor.r() += (1.0 - nncColor.r()) * 0.2; + nncColor.g() += (1.0 - nncColor.g()) * 0.2; + nncColor.b() += (1.0 - nncColor.b()) * 0.2; CVF_ASSERT(nncColor.isValid()); cvf::ref nncEffect; @@ -726,4 +764,3 @@ void RivFaultPartMgr::updateNNCColors(size_t timeStepIndex, RimEclipseCellColors m_NNCFaces->setEffect(nncEffect.p()); } } - diff --git a/ApplicationCode/ModelVisualization/RivFaultPartMgr.h b/ApplicationCode/ModelVisualization/RivFaultPartMgr.h index 44d2956030..38d8685a9b 100644 --- a/ApplicationCode/ModelVisualization/RivFaultPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivFaultPartMgr.h @@ -24,6 +24,7 @@ #include "cvfArray.h" #include "cafEffectGenerator.h" +#include "cafPdmPointer.h" namespace cvf { @@ -51,7 +52,7 @@ class RivNNCGeometryGenerator; class RivFaultPartMgr : public cvf::Object { public: - RivFaultPartMgr(const RigGridBase* grid, const RimFaultInViewCollection* rimFaultCollection, const RimFaultInView* rimFault); + RivFaultPartMgr(const RigGridBase* grid, const RimFaultInViewCollection* rimFaultCollection, RimFaultInView* rimFault); void setCellVisibility(cvf::UByteArray* cellVisibilities); @@ -79,7 +80,7 @@ class RivFaultPartMgr : public cvf::Object static cvf::Vec3f findClosestVertex(const cvf::Vec3f& point, const cvf::Vec3fArray* vertices); private: cvf::cref m_grid; - const RimFaultInView* m_rimFault; + caf::PdmPointer m_rimFault; const RimFaultInViewCollection* m_rimFaultCollection; float m_opacityLevel; diff --git a/ApplicationCode/ModelVisualization/RivFishbonesSubsPartMgr.h b/ApplicationCode/ModelVisualization/RivFishbonesSubsPartMgr.h index 162f01ab8f..6d4d607842 100644 --- a/ApplicationCode/ModelVisualization/RivFishbonesSubsPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivFishbonesSubsPartMgr.h @@ -51,7 +51,7 @@ class RivFishbonesSubsPartMgr : public cvf::Object { public: RivFishbonesSubsPartMgr(RimFishbonesMultipleSubs* subs); - ~RivFishbonesSubsPartMgr(); + ~RivFishbonesSubsPartMgr() override; void appendGeometryPartsToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform, double characteristicCellSize); void clearGeometryCache(); diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp index b4a178c60c..34a9b46018 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.cpp @@ -3,17 +3,17 @@ // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -22,6 +22,7 @@ #include "RiaApplication.h" #include "RiaPreferences.h" +#include "RiaRegressionTestRunner.h" #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" @@ -31,12 +32,14 @@ #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" -#include "RimSimWellInViewCollection.h" #include "RimRegularLegendConfig.h" #include "RimReservoirCellResultsStorage.h" +#include "RimSimWellInViewCollection.h" #include "RimTernaryLegendConfig.h" #include "RivCellEdgeEffectGenerator.h" +#include "RivCompletionTypeResultToTextureMapper.h" +#include "RivMeshLinesSourceInfo.h" #include "RivPartPriority.h" #include "RivResultToTextureMapper.h" #include "RivScalarMapperUtils.h" @@ -44,7 +47,6 @@ #include "RivTernaryScalarMapperEffectGenerator.h" #include "RivTernaryTextureCoordsCreator.h" #include "RivTextureCoordsCreator.h" -#include "RivCompletionTypeResultToTextureMapper.h" #include "cafEffectGenerator.h" #include "cafPdmFieldCvfColor.h" @@ -55,9 +57,9 @@ #include "cvfMath.h" #include "cvfModelBasicList.h" #include "cvfPart.h" -#include "cvfRenderState_FF.h" #include "cvfRenderStateBlending.h" #include "cvfRenderStatePolygonOffset.h" +#include "cvfRenderState_FF.h" #include "cvfShaderProgram.h" #include "cvfShaderProgramGenerator.h" #include "cvfShaderSourceProvider.h" @@ -66,26 +68,26 @@ #include "cvfTransform.h" #include "cvfUniform.h" - - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RivGridPartMgr::RivGridPartMgr(const RigGridBase* grid, size_t gridIdx) -: m_surfaceGenerator(grid), - m_gridIdx(gridIdx), - m_grid(grid), - m_surfaceFaceFilter(grid), - m_opacityLevel(1.0f), - m_defaultColor(cvf::Color3::WHITE) +RivGridPartMgr::RivGridPartMgr(RivCellSetEnum cellSetType, RimEclipseCase* eclipseCase, const RigGridBase* grid, size_t gridIdx) + : m_surfaceGenerator(grid, RiaRegressionTestRunner::instance()->useOpenMPForGeometryCreation()) + , m_gridIdx(gridIdx) + , m_grid(grid) + , m_surfaceFaceFilter(grid) + , m_opacityLevel(1.0f) + , m_defaultColor(cvf::Color3::WHITE) + , m_eclipseCase(eclipseCase) + , m_cellSetType(cellSetType) { CVF_ASSERT(grid); - m_cellVisibility = new cvf::UByteArray; + m_cellVisibility = new cvf::UByteArray; m_surfaceFacesTextureCoords = new cvf::Vec2fArray; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivGridPartMgr::setTransform(cvf::Transform* scaleTransform) { @@ -93,7 +95,7 @@ void RivGridPartMgr::setTransform(cvf::Transform* scaleTransform) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivGridPartMgr::setCellVisibility(cvf::UByteArray* cellVisibilities) { @@ -108,6 +110,9 @@ void RivGridPartMgr::setCellVisibility(cvf::UByteArray* cellVisibilities) generatePartGeometry(m_surfaceGenerator); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder) { bool useBufferObjects = true; @@ -130,16 +135,18 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB part->setTransform(m_scaleTransform.p()); // Set mapping from triangle face index to cell index - cvf::ref si = new RivSourceInfo(m_gridIdx); + cvf::ref si = new RivSourceInfo(m_eclipseCase, m_gridIdx); + si->setCellSetType(m_cellSetType); + si->m_cellFaceFromTriangleMapper = geoBuilder.triangleToCellFaceMapper(); part->setSourceInfo(si.p()); part->updateBoundingBox(); - + // Set default effect caf::SurfaceEffectGenerator geometryEffgen(cvf::Color4f(cvf::Color3f::WHITE), caf::PO_1); - cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); part->setEffect(geometryOnlyEffect.p()); part->setEnableMask(surfaceBit); @@ -171,7 +178,7 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB RiaPreferences* prefs = RiaApplication::instance()->preferences(); - cvf::ref eff; + cvf::ref eff; caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); eff = effGen.generateCachedEffect(); @@ -179,24 +186,27 @@ void RivGridPartMgr::generatePartGeometry(cvf::StructGridGeometryGenerator& geoB part->setEnableMask(meshSurfaceBit); part->setEffect(eff.p()); + + part->setSourceInfo(new RivMeshLinesSourceInfo(m_eclipseCase)); + m_surfaceGridLines = part; } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivGridPartMgr::appendPartsToModel(cvf::ModelBasicList* model) { CVF_ASSERT(model != nullptr); - if(m_surfaceFaces.notNull() ) model->addPart(m_surfaceFaces.p() ); - if(m_surfaceGridLines.notNull()) model->addPart(m_surfaceGridLines.p()); + if (m_surfaceFaces.notNull()) model->addPart(m_surfaceFaces.p()); + if (m_surfaceGridLines.notNull()) model->addPart(m_surfaceGridLines.p()); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivGridPartMgr::updateCellColor(cvf::Color4f color) { @@ -207,24 +217,26 @@ void RivGridPartMgr::updateCellColor(cvf::Color4f color) // Set default effect caf::SurfaceEffectGenerator geometryEffgen(color, caf::PO_1); - cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); + cvf::ref geometryOnlyEffect = geometryEffgen.generateCachedEffect(); m_surfaceFaces->setEffect(geometryOnlyEffect.p()); - if (m_opacityLevel < 1.0f) m_surfaceFaces->setPriority(RivPartPriority::PartType::Transparent); - else m_surfaceFaces->setPriority(RivPartPriority::PartType::BaseLevel); + if (m_opacityLevel < 1.0f) + m_surfaceFaces->setPriority(RivPartPriority::PartType::Transparent); + else + m_surfaceFaces->setPriority(RivPartPriority::PartType::BaseLevel); // Update mesh colors as well, in case of change if (m_surfaceGridLines.notNull()) { - RiaPreferences* prefs = RiaApplication::instance()->preferences(); + RiaPreferences* prefs = RiaApplication::instance()->preferences(); caf::MeshEffectGenerator effGen(prefs->defaultGridLineColors()); - cvf::ref eff = effGen.generateCachedEffect(); + cvf::ref eff = effGen.generateCachedEffect(); m_surfaceGridLines->setEffect(eff.p()); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors) { @@ -237,7 +249,8 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellC if (cellResultColors->isTernarySaturationSelected()) { - RivTernaryTextureCoordsCreator texturer(cellResultColors, cellResultColors->ternaryLegendConfig(), + RivTernaryTextureCoordsCreator texturer(cellResultColors, + cellResultColors->ternaryLegendConfig(), timeStepIndex, m_grid->gridIndex(), m_surfaceGenerator.quadToCellFaceMapper()); @@ -245,19 +258,17 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellC texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); const RivTernaryScalarMapper* mapper = cellResultColors->ternaryLegendConfig()->scalarMapper(); - RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_surfaceFaces.p(), - m_surfaceFacesTextureCoords.p(), - mapper, + RivScalarMapperUtils::applyTernaryTextureResultsToPart(m_surfaceFaces.p(), + m_surfaceFacesTextureCoords.p(), + mapper, effectiveOpacityLevel, - caf::FC_NONE, + caf::FC_NONE, cellResultColors->reservoirView()->isLightingDisabled()); } else { - RivTextureCoordsCreator texturer(cellResultColors, - timeStepIndex, - m_grid->gridIndex(), - m_surfaceGenerator.quadToCellFaceMapper()); + RivTextureCoordsCreator texturer( + cellResultColors, timeStepIndex, m_grid->gridIndex(), m_surfaceGenerator.quadToCellFaceMapper()); if (!texturer.isValid()) { return; @@ -265,7 +276,8 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellC if (cellResultColors->isCompletionTypeSelected()) { - cvf::ref pipeInCellEval = RivTextureCoordsCreator::createPipeInCellEvaluator(cellResultColors, timeStepIndex, m_grid->gridIndex()); + cvf::ref pipeInCellEval = + RivTextureCoordsCreator::createPipeInCellEvaluator(cellResultColors, timeStepIndex, m_grid->gridIndex()); const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); texturer.setResultToTextureMapper(new RivCompletionTypeResultToTextureMapper(mapper, pipeInCellEval.p())); @@ -275,42 +287,57 @@ void RivGridPartMgr::updateCellResultColor(size_t timeStepIndex, RimEclipseCellC texturer.createTextureCoords(m_surfaceFacesTextureCoords.p()); const cvf::ScalarMapper* mapper = cellResultColors->legendConfig()->scalarMapper(); - RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), - m_surfaceFacesTextureCoords.p(), - mapper, - effectiveOpacityLevel, - caf::FC_NONE, + RivScalarMapperUtils::applyTextureResultsToPart(m_surfaceFaces.p(), + m_surfaceFacesTextureCoords.p(), + mapper, + effectiveOpacityLevel, + caf::FC_NONE, cellResultColors->reservoirView()->isLightingDisabled()); } - if (effectiveOpacityLevel < 1.0f) m_surfaceFaces->setPriority(RivPartPriority::PartType::Transparent); - else m_surfaceFaces->setPriority(RivPartPriority::PartType::BaseLevel); + if (effectiveOpacityLevel < 1.0f) + m_surfaceFaces->setPriority(RivPartPriority::PartType::Transparent); + else + m_surfaceFaces->setPriority(RivPartPriority::PartType::BaseLevel); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RivGridPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors, RimCellEdgeColors* cellEdgeResultColors) +void RivGridPartMgr::updateCellEdgeResultColor(size_t timeStepIndex, + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors) { if (m_surfaceFaces.notNull()) { cvf::DrawableGeo* dg = dynamic_cast(m_surfaceFaces->drawable()); if (dg) { - cvf::ref eff = RivScalarMapperUtils::createCellEdgeEffect(dg, m_surfaceGenerator.quadToCellFaceMapper(), m_grid->gridIndex(), - timeStepIndex, cellResultColors, cellEdgeResultColors, m_opacityLevel, m_defaultColor, caf::FC_NONE, cellResultColors->reservoirView()->isLightingDisabled()); + cvf::ref eff = + RivScalarMapperUtils::createCellEdgeEffect(dg, + m_surfaceGenerator.quadToCellFaceMapper(), + m_grid->gridIndex(), + timeStepIndex, + cellResultColors, + cellEdgeResultColors, + m_opacityLevel, + m_defaultColor, + caf::FC_NONE, + cellResultColors->reservoirView()->isLightingDisabled()); m_surfaceFaces->setEffect(eff.p()); - if (m_opacityLevel < 1.0f) m_surfaceFaces->setPriority(RivPartPriority::PartType::Transparent); - else m_surfaceFaces->setPriority(RivPartPriority::PartType::BaseLevel); + if (m_opacityLevel < 1.0f) + m_surfaceFaces->setPriority(RivPartPriority::PartType::Transparent); + else + m_surfaceFaces->setPriority(RivPartPriority::PartType::BaseLevel); } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RivGridPartMgr::~RivGridPartMgr() { @@ -321,5 +348,3 @@ RivGridPartMgr::~RivGridPartMgr() if (m_surfaceFaces.notNull()) m_surfaceFaces->deleteOrReleaseOpenGLResources(); #endif } - - diff --git a/ApplicationCode/ModelVisualization/RivGridPartMgr.h b/ApplicationCode/ModelVisualization/RivGridPartMgr.h index 22ddb00930..49e841f678 100644 --- a/ApplicationCode/ModelVisualization/RivGridPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivGridPartMgr.h @@ -19,11 +19,17 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once + +#include "RigGridBase.h" + +#include "RivCellSetEnum.h" + +#include "cafPdmPointer.h" + #include "cvfBase.h" #include "cvfObject.h" #include "cvfStructGridGeometryGenerator.h" -#include "RigGridBase.h" namespace cvf { @@ -36,6 +42,8 @@ namespace cvf class RimEclipseCellColors; class RimCellEdgeColors; +class RimEclipseCase; +class RivSourceInfo; @@ -50,8 +58,9 @@ class RimCellEdgeColors; class RivGridPartMgr: public cvf::Object { public: - RivGridPartMgr(const RigGridBase* grid, size_t gridIdx); - ~RivGridPartMgr(); + RivGridPartMgr(RivCellSetEnum cellSetType, RimEclipseCase* eclipseCase, const RigGridBase* grid, size_t gridIdx); + ~RivGridPartMgr() override; + void setTransform(cvf::Transform* scaleTransform); void setCellVisibility(cvf::UByteArray* cellVisibilities ); cvf::ref cellVisibility() { return m_cellVisibility;} @@ -59,29 +68,33 @@ class RivGridPartMgr: public cvf::Object void updateCellColor(cvf::Color4f color); void updateCellResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors); - void updateCellEdgeResultColor(size_t timeStepIndex, RimEclipseCellColors* cellResultColors, - RimCellEdgeColors* cellEdgeResultColors); + void updateCellEdgeResultColor(size_t timeStepIndex, + RimEclipseCellColors* cellResultColors, + RimCellEdgeColors* cellEdgeResultColors); void appendPartsToModel(cvf::ModelBasicList* model); private: - void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder); - + void generatePartGeometry(cvf::StructGridGeometryGenerator& geoBuilder); + private: - size_t m_gridIdx; - cvf::cref m_grid; + size_t m_gridIdx; + cvf::cref m_grid; - cvf::ref m_scaleTransform; - float m_opacityLevel; - cvf::Color3f m_defaultColor; + cvf::ref m_scaleTransform; + float m_opacityLevel; + cvf::Color3f m_defaultColor; // Surface visualization - cvf::StructGridGeometryGenerator m_surfaceGenerator; - RigGridCellFaceVisibilityFilter m_surfaceFaceFilter; - cvf::ref m_surfaceFaces; - cvf::ref m_surfaceFacesTextureCoords; + cvf::StructGridGeometryGenerator m_surfaceGenerator; + RigGridCellFaceVisibilityFilter m_surfaceFaceFilter; + cvf::ref m_surfaceFaces; + cvf::ref m_surfaceFacesTextureCoords; + + cvf::ref m_surfaceGridLines; - cvf::ref m_surfaceGridLines; + cvf::ref m_cellVisibility; - cvf::ref m_cellVisibility; + caf::PdmPointer m_eclipseCase; + RivCellSetEnum m_cellSetType; }; diff --git a/ApplicationCode/ModelVisualization/RivMeshLinesSourceInfo.cpp b/ApplicationCode/ModelVisualization/RivMeshLinesSourceInfo.cpp new file mode 100644 index 0000000000..daeb0d43e9 --- /dev/null +++ b/ApplicationCode/ModelVisualization/RivMeshLinesSourceInfo.cpp @@ -0,0 +1,29 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RivMeshLinesSourceInfo.h" + +#include "cafPdmObject.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivMeshLinesSourceInfo::RivMeshLinesSourceInfo(caf::PdmObject* object) + : RivObjectSourceInfo(object) +{ +} diff --git a/ApplicationCode/FileInterface/RifEnsembleParametersReader.h b/ApplicationCode/ModelVisualization/RivMeshLinesSourceInfo.h similarity index 71% rename from ApplicationCode/FileInterface/RifEnsembleParametersReader.h rename to ApplicationCode/ModelVisualization/RivMeshLinesSourceInfo.h index 67c1f78c8d..a6ef9b7131 100644 --- a/ApplicationCode/FileInterface/RifEnsembleParametersReader.h +++ b/ApplicationCode/ModelVisualization/RivMeshLinesSourceInfo.h @@ -1,45 +1,31 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "RifSummaryCaseRestartSelector.h" - -#include - - -class QStringList; -class QTextStream; -class QFile; - +#include "RivObjectSourceInfo.h" //================================================================================================== -// -// UNDER CONSTRUCTION +/// +/// //================================================================================================== -class RifEnsembleParametersReader +class RivMeshLinesSourceInfo : public RivObjectSourceInfo { public: - RifEnsembleParametersReader(const QString& modelDirectory); - ~RifEnsembleParametersReader(); - - //RifEnsembleParameters import(); - -private: - QString m_modelDirectory; + explicit RivMeshLinesSourceInfo(caf::PdmObject* pdmObject); }; diff --git a/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp index 9a275428e5..e233b02813 100644 --- a/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.cpp @@ -123,7 +123,7 @@ void RivNNCGeometryGenerator::computeArrays() { vx2 = vx3; vx3 = cvf::Vec3f( conn.m_polygon[vxIdx] - offset); -#pragma omp critical +#pragma omp critical(critical_section_RivNNCGeometryGenerator_computeArrays) { vertices.push_back(vx1); vertices.push_back(vx2); diff --git a/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.h b/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.h index 3db736126b..bbad9decdd 100644 --- a/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/RivNNCGeometryGenerator.h @@ -43,7 +43,7 @@ class RivNNCGeometryGenerator : public cvf::Object { public: RivNNCGeometryGenerator(const RigNNCData* nncData, const cvf::Vec3d& offset, const cvf::Array* nncIndexes ); - ~RivNNCGeometryGenerator(); + ~RivNNCGeometryGenerator() override; void setCellVisibility( const cvf::UByteArray* cellVisibilities, const RigGridBase * grid); diff --git a/ApplicationCode/ModelVisualization/RivObjectSourceInfo.cpp b/ApplicationCode/ModelVisualization/RivObjectSourceInfo.cpp index d42b13fcd3..964eb13601 100644 --- a/ApplicationCode/ModelVisualization/RivObjectSourceInfo.cpp +++ b/ApplicationCode/ModelVisualization/RivObjectSourceInfo.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -21,16 +21,15 @@ #include "cafPdmObject.h" //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RivObjectSourceInfo::RivObjectSourceInfo(caf::PdmObject* object) : m_object(object) { - } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- caf::PdmObject* RivObjectSourceInfo::object() const { diff --git a/ApplicationCode/ModelVisualization/RivObjectSourceInfo.h b/ApplicationCode/ModelVisualization/RivObjectSourceInfo.h index 837a417e24..b3133fd796 100644 --- a/ApplicationCode/ModelVisualization/RivObjectSourceInfo.h +++ b/ApplicationCode/ModelVisualization/RivObjectSourceInfo.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -23,21 +23,22 @@ #include "cvfBase.h" #include "cvfObject.h" -namespace caf { - class PdmObject; +namespace caf +{ +class PdmObject; } //================================================================================================== -/// -/// +/// +/// //================================================================================================== class RivObjectSourceInfo : public cvf::Object { public: RivObjectSourceInfo(caf::PdmObject* object); - + caf::PdmObject* object() const; -private: +private: caf::PdmPointer m_object; }; diff --git a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp index 6abefded1b..17e937a895 100644 --- a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.cpp @@ -59,26 +59,6 @@ void RivPipeGeometryGenerator::setPipeCenterCoords(const cvf::Vec3dArray* coords clearComputedData(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivPipeGeometryGenerator::setMinimumBendAngle(double degrees) -{ - m_minimumBendAngle = degrees; - - clearComputedData(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RivPipeGeometryGenerator::setBendScalingFactor(double scaleFactor) -{ - m_bendScalingFactor = scaleFactor; - - clearComputedData(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -362,18 +342,17 @@ cvf::ref RivPipeGeometryGenerator::generateExtrudedCylinder(do size_t segmentIdx = 0; for (segmentIdx = 0; segmentIdx < segmentCount; segmentIdx++) { - size_t i; - for (i = 0; i < crossSectionNodeCount - 1; i++) + for (size_t nodeIdx = 0; nodeIdx < crossSectionNodeCount - 1; nodeIdx++) { - quadVertexArray->add(crossSectionVertices[( (segmentIdx + 0) * crossSectionNodeCount) + i + 0]); - quadVertexArray->add(crossSectionVertices[( (segmentIdx + 0) * crossSectionNodeCount) + i + 1]); - quadVertexArray->add(crossSectionVertices[( (segmentIdx + 1) * crossSectionNodeCount) + i + 1]); - quadVertexArray->add(crossSectionVertices[( (segmentIdx + 1) * crossSectionNodeCount) + i + 0]); - - quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + i + 0]); - quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + i + 1]); - quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + i + 1]); - quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + i + 0]); + quadVertexArray->add(crossSectionVertices[( (segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 0]); + quadVertexArray->add(crossSectionVertices[( (segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 1]); + quadVertexArray->add(crossSectionVertices[( (segmentIdx + 1) * crossSectionNodeCount) + nodeIdx + 1]); + quadVertexArray->add(crossSectionVertices[( (segmentIdx + 1) * crossSectionNodeCount) + nodeIdx + 0]); + + quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 0]); + quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 1]); + quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 1]); + quadNormalArray->add(cylinderSegmentNormals[( (segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 0]); } // Last quad closing the cylinder @@ -398,6 +377,176 @@ cvf::ref RivPipeGeometryGenerator::generateExtrudedCylinder(do return geo; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivPipeGeometryGenerator::generateVariableRadiusTube(size_t crossSectionNodeCount, + const cvf::Vec3dArray* cylinderCenterCoords, + const std::vector& radii) +{ + const double epsilon = 1.0e-8; + + CVF_ASSERT(cylinderCenterCoords != nullptr); + + // Calculate first valid pipe direction, to be able to handle centerNodes in the same place + cvf::Vec3d lastValidPipeDirection = cvf::Vec3d::UNDEFINED; + for (size_t i = 0; i < cylinderCenterCoords->size() - 1; i++) + { + cvf::Vec3d candidateDir = (*cylinderCenterCoords)[i + 1] - (*cylinderCenterCoords)[i]; + if (candidateDir.normalize()) + { + lastValidPipeDirection = candidateDir; + break; + } + } + + if (lastValidPipeDirection.isUndefined()) return nullptr; // The pipe coordinates are all the same point + + cvf::Vec3d dir = (*cylinderCenterCoords)[1] - (*cylinderCenterCoords)[0]; + if (!dir.normalize()) + { + dir = lastValidPipeDirection; + } + + cvf::Vec3d orient1 = dir.perpendicularVector(); + orient1.normalize(); + + cvf::Vec3d orient2 = dir ^ orient1; + orient2.normalize(); + + std::vector lastExtrudedNodes; + computeCircle(radii[0], crossSectionNodeCount, (*cylinderCenterCoords)[0], orient1, orient2, &lastExtrudedNodes); + + std::vector crossSectionVertices; + std::vector cylinderSegmentNormals; + + // Insert the first set of vertices + for (size_t i = 0; i < lastExtrudedNodes.size(); i++) + { + crossSectionVertices.push_back(cvf::Vec3f(lastExtrudedNodes[i])); + } + + // Loop along the cylinder center coords and calculate the cross section vertexes in each center vertex + + for (size_t ccIdx = 0; ccIdx < cylinderCenterCoords->size()-1; ccIdx++) + { + size_t nextCcIdx = ccIdx + 1; + + // Calculate this and next pipe direction, and intersection plane + cvf::Vec3d firstCoord = (*cylinderCenterCoords)[ccIdx]; + cvf::Vec3d secondCoord = (*cylinderCenterCoords)[nextCcIdx]; + + cvf::Vec3d nextDir = secondCoord - firstCoord; + if (!nextDir.normalize()) + { + nextDir = lastValidPipeDirection; + } + else + { + lastValidPipeDirection = nextDir; + } + + orient1 = nextDir.perpendicularVector().getNormalized(); + orient2 = (nextDir ^ orient1).getNormalized(); + + std::vector extrudedNodes; + computeCircle(radii[nextCcIdx], crossSectionNodeCount, (*cylinderCenterCoords)[nextCcIdx], orient1, orient2, &extrudedNodes); + + // Insert the next set of vertices and calculate normals for segment + for (size_t i = 0; i < extrudedNodes.size(); i++) + { + cvf::Vec3f nextNodeAlongWellPath = cvf::Vec3f(extrudedNodes[i]); + cvf::Vec3f currentNode = cvf::Vec3f(lastExtrudedNodes[i]); + + cvf::Vec3f wellDirectionDir = nextNodeAlongWellPath - currentNode; + if (!wellDirectionDir.normalize()) + { + wellDirectionDir = cvf::Vec3f(lastValidPipeDirection); + } + + cvf::Vec3f lastNodeAlongCircle; + cvf::Vec3f nextNodeAlongCircle; + if (i > 0) + { + lastNodeAlongCircle = cvf::Vec3f(lastExtrudedNodes[i - 1]); + } + else + { + lastNodeAlongCircle = cvf::Vec3f(lastExtrudedNodes.back()); + } + if (i < extrudedNodes.size() - 1) + { + nextNodeAlongCircle = cvf::Vec3f(lastExtrudedNodes[i + 1]); + } + else + { + nextNodeAlongCircle = cvf::Vec3f(lastExtrudedNodes.front()); + } + + cvf::Vec3f circleDir = (nextNodeAlongCircle - lastNodeAlongCircle).getNormalized(); + cvf::Vec3f segmentNormal = (wellDirectionDir ^ circleDir).getNormalized(); + + crossSectionVertices.push_back(cvf::Vec3f(nextNodeAlongWellPath)); + cylinderSegmentNormals.push_back(segmentNormal); + + } + + lastExtrudedNodes = extrudedNodes; + } + + size_t crossSectionCount = crossSectionVertices.size() / crossSectionNodeCount; + + if (crossSectionCount < 2) return nullptr; + + CVF_ASSERT(crossSectionVertices.size() - crossSectionNodeCount == cylinderSegmentNormals.size()); + + size_t segmentCount = crossSectionCount - 1; + size_t vertexCount = segmentCount * crossSectionNodeCount * 4; + + cvf::ref quadVertexArray = new cvf::Vec3fArray(); + quadVertexArray->reserve(vertexCount); + + cvf::ref quadNormalArray = new cvf::Vec3fArray(); + quadNormalArray->reserve(vertexCount); + + size_t segmentIdx = 0; + for (segmentIdx = 0; segmentIdx < segmentCount; segmentIdx++) + { + for (size_t nodeIdx = 0; nodeIdx < crossSectionNodeCount - 1; nodeIdx++) + { + quadVertexArray->add(crossSectionVertices[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 0]); + quadVertexArray->add(crossSectionVertices[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 1]); + quadVertexArray->add(crossSectionVertices[((segmentIdx + 1) * crossSectionNodeCount) + nodeIdx + 1]); + quadVertexArray->add(crossSectionVertices[((segmentIdx + 1) * crossSectionNodeCount) + nodeIdx + 0]); + + quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 0]); + quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 1]); + quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 1]); + quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + nodeIdx + 0]); + } + + // Last quad closing the cylinder + quadVertexArray->add(crossSectionVertices[((segmentIdx + 0) * crossSectionNodeCount) + crossSectionNodeCount - 1]); + quadVertexArray->add(crossSectionVertices[((segmentIdx + 0) * crossSectionNodeCount) + 0]); + quadVertexArray->add(crossSectionVertices[((segmentIdx + 1) * crossSectionNodeCount) + 0]); + quadVertexArray->add(crossSectionVertices[((segmentIdx + 1) * crossSectionNodeCount) + crossSectionNodeCount - 1]); + + quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + crossSectionNodeCount - 1]); + quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + 0]); + quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + 0]); + quadNormalArray->add(cylinderSegmentNormals[((segmentIdx + 0) * crossSectionNodeCount) + crossSectionNodeCount - 1]); + } + + CVF_ASSERT(vertexCount == quadVertexArray->size()); + CVF_ASSERT(vertexCount == quadNormalArray->size()); + + cvf::ref geo = new cvf::DrawableGeo; + geo->setFromQuadVertexArray(quadVertexArray.p()); + geo->setNormalArray(quadNormalArray.p()); + + return geo; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -648,3 +797,46 @@ void RivPipeGeometryGenerator::cylinderWithCenterLineParts(cvf::Collection* destinationParts, + const std::vector& centerCoords, + const std::vector& radii, + const cvf::Color3f& color) +{ + setCrossSectionVertexCount(12); + + cvf::ref activeCoords = new cvf::Vec3dArray(centerCoords); + setPipeCenterCoords(activeCoords.p()); + + cvf::ref surfaceGeo = generateVariableRadiusTube(m_crossSectionNodeCount, activeCoords.p(), radii); + + if (surfaceGeo.notNull()) + { + cvf::Part* part = new cvf::Part; + part->setDrawable(surfaceGeo.p()); + + caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(color), caf::PO_1); + cvf::ref eff = surfaceGen.generateCachedEffect(); + + part->setEffect(eff.p()); + + destinationParts->push_back(part); + } + + cvf::ref centerLineGeo = createCenterLine(); + if (centerLineGeo.notNull()) + { + cvf::Part* part = new cvf::Part; + part->setDrawable(centerLineGeo.p()); + + caf::SurfaceEffectGenerator surfaceGen(cvf::Color4f(color), caf::PO_1); + cvf::ref eff = surfaceGen.generateCachedEffect(); + + part->setEffect(eff.p()); + + destinationParts->push_back(part); + } +} + diff --git a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h index f4fe97922c..3bb938f311 100644 --- a/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/RivPipeGeometryGenerator.h @@ -39,18 +39,11 @@ class RivPipeGeometryGenerator : public cvf::Object { public: RivPipeGeometryGenerator(); - ~RivPipeGeometryGenerator(); + ~RivPipeGeometryGenerator() override; // Coordinates and orientations void setPipeCenterCoords(const cvf::Vec3dArray* coords); - - // Pipe bends with a opening angle below given angle is modified with extra bend coordinates - void setMinimumBendAngle(double degrees); - // Scaling factor used to control how far from original pipe position the extra bend coordinates are located - // This will affect how sharp or smooth bend will appear - void setBendScalingFactor(double scaleFactor); - // Appearance void setRadius(double radius); void setCrossSectionVertexCount(size_t vertexCount); @@ -64,7 +57,16 @@ class RivPipeGeometryGenerator : public cvf::Object void setFirstVisibleSegmentIndex(size_t segmentIndex); size_t segmentIndexFromTriangleIndex(size_t triangleIndex) const; - void cylinderWithCenterLineParts(cvf::Collection* destinationParts, const std::vector& centerCoords, const cvf::Color3f& color, double radius); + void cylinderWithCenterLineParts(cvf::Collection* destinationParts, + const std::vector& centerCoords, + const cvf::Color3f& color, + double radius); + + void tubeWithCenterLinePartsAndVariableWidth(cvf::Collection* destinationParts, + const std::vector& centerCoords, + const std::vector& radii, + const cvf::Color3f& color); + private: void clearComputedData(); void updateFilteredPipeCenterCoords(); @@ -75,6 +77,7 @@ class RivPipeGeometryGenerator : public cvf::Object static cvf::ref generateLine(const cvf::Vec3dArray* coords); static cvf::ref generateExtrudedCylinder(double radius, size_t crossSectionNodeCount,const cvf::Vec3dArray* cylinderCenterCoords); + static cvf::ref generateVariableRadiusTube(size_t crossSectionNodeCount, const cvf::Vec3dArray* cylinderCenterCoords, const std::vector& radii); static void computeExtrudedCoordsAndNormals(cvf::Vec3d intersectionCoord, cvf::Vec3d intersectionPlaneNormal, @@ -96,7 +99,13 @@ class RivPipeGeometryGenerator : public cvf::Object size_t m_firstVisibleSegmentIndex; double m_radius; + + // Pipe bends with a opening angle below given angle is modified with extra bend coordinates double m_minimumBendAngle; + + // Scaling factor used to control how far from original pipe position the extra bend coordinates are located + // This will affect how sharp or smooth bend will appear double m_bendScalingFactor; + size_t m_crossSectionNodeCount; }; diff --git a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp index 1b61952eab..a030ad9664 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.cpp @@ -101,7 +101,7 @@ void RivReservoirFaultsPartMgr::appendPartsToModel(cvf::ModelBasicList* model) if (!faultCollection) return; - bool isShowingGrid = faultCollection->isGridVisualizationMode(); + bool isShowingGrid = m_reservoirView->isMainGridVisible(); if (!faultCollection->showFaultCollection() && !isShowingGrid) return; // Check match between model fault count and fault parts diff --git a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h index 88cc1996c7..76f881ce0f 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirFaultsPartMgr.h @@ -45,7 +45,7 @@ class RivReservoirFaultsPartMgr : public cvf::Object { public: RivReservoirFaultsPartMgr(const RigMainGrid* grid, RimEclipseView* reservoirView); - ~RivReservoirFaultsPartMgr(); + ~RivReservoirFaultsPartMgr() override; void setTransform(cvf::Transform* scaleTransform); void setCellVisibility(cvf::UByteArray* cellVisibilities); diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp index 4cfe9b7d80..c4a49eadbf 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.cpp @@ -22,6 +22,8 @@ #include "RigEclipseCaseData.h" +#include "RimEclipseCase.h" + #include "RivGridPartMgr.h" #include "RivReservoirFaultsPartMgr.h" @@ -30,17 +32,19 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivReservoirPartMgr::clearAndSetReservoir(const RigEclipseCaseData* eclipseCase, RimEclipseView* reservoirView) +void RivReservoirPartMgr::clearAndSetReservoir(RivCellSetEnum cellSetType, RimEclipseCase* eclipseCase, RimEclipseView* reservoirView) { m_allGrids.clear(); - if (eclipseCase) + if (eclipseCase && eclipseCase->eclipseCaseData()) { + RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); + std::vector grids; - eclipseCase->allGrids(&grids); + eclipseCaseData->allGrids(&grids); for (size_t i = 0; i < grids.size() ; ++i) { - m_allGrids.push_back(new RivGridPartMgr(grids[i], i)); + m_allGrids.push_back(new RivGridPartMgr(cellSetType, eclipseCase, grids[i], i)); } if (eclipseCase->mainGrid()) diff --git a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h index a99b5e150b..1b10818fec 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirPartMgr.h @@ -20,6 +20,8 @@ #pragma once +#include "RivCellSetEnum.h" + #include "cvfBase.h" #include "cvfArray.h" #include "cvfCollection.h" @@ -32,6 +34,7 @@ namespace cvf class RimEclipseCellColors; class RimCellEdgeColors; +class RimEclipseCase; class RigEclipseCaseData; class RimEclipseView; class RivReservoirFaultsPartMgr; @@ -47,7 +50,7 @@ class RivGridPartMgr; class RivReservoirPartMgr: public cvf::Object { public: - void clearAndSetReservoir(const RigEclipseCaseData* eclipseCase, RimEclipseView* reservoirView); + void clearAndSetReservoir(RivCellSetEnum cellSetType, RimEclipseCase* eclipseCase, RimEclipseView* reservoirView); void setTransform(cvf::Transform* scaleTransform); void setCellVisibility(size_t gridIndex, cvf::UByteArray* cellVisibilities ); @@ -72,8 +75,10 @@ class RivReservoirPartMgr: public cvf::Object RimCellEdgeColors* cellEdgeResultColors); void appendFaultPartsToModel(cvf::ModelBasicList* model); void appendFaultLabelPartsToModel(cvf::ModelBasicList* model); -private: +private: cvf::Collection m_allGrids; // Main grid and all LGR's cvf::ref m_faultsPartMgr; + + RivCellSetEnum m_cellSetType; }; diff --git a/ApplicationCode/ModelVisualization/RivReservoirSimWellsPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirSimWellsPartMgr.h index 71bcaac087..c4404449fa 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirSimWellsPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirSimWellsPartMgr.h @@ -43,7 +43,7 @@ class RivReservoirSimWellsPartMgr : public cvf::Object { public: explicit RivReservoirSimWellsPartMgr(RimEclipseView* reservoirView); - ~RivReservoirSimWellsPartMgr(); + ~RivReservoirSimWellsPartMgr() override; void clearGeometryCache(); void scheduleGeometryRegen(); diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp index 74317e8ca0..3d54d14c3a 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.cpp @@ -150,10 +150,11 @@ void RivReservoirViewPartMgr::scheduleGeometryRegen(RivCellSetEnum geometryType) //-------------------------------------------------------------------------------------------------- void RivReservoirViewPartMgr::clearGeometryCache(RivCellSetEnum geomType) { - RigEclipseCaseData* eclipseCase = nullptr; - if (m_reservoirView != nullptr && m_reservoirView->eclipseCase()) + RimEclipseCase* rimEclipseCase = nullptr; + + if (m_reservoirView) { - eclipseCase = m_reservoirView->eclipseCase()->eclipseCaseData(); + m_reservoirView->firstAncestorOrThisOfType(rimEclipseCase); } if (geomType == PROPERTY_FILTERED) @@ -163,7 +164,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(RivCellSetEnum geomType) m_propFilteredGeometryFramesNeedsRegen[i] = true; if (m_propFilteredGeometryFrames[i].notNull()) { - m_propFilteredGeometryFrames[i]->clearAndSetReservoir(eclipseCase, m_reservoirView); + m_propFilteredGeometryFrames[i]->clearAndSetReservoir(geomType, rimEclipseCase, m_reservoirView); m_propFilteredGeometryFrames[i]->setTransform(m_scaleTransform.p()); } } @@ -175,7 +176,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(RivCellSetEnum geomType) m_propFilteredWellGeometryFramesNeedsRegen[i] = true; if (m_propFilteredWellGeometryFrames[i].notNull()) { - m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(eclipseCase, m_reservoirView); + m_propFilteredWellGeometryFrames[i]->clearAndSetReservoir(geomType, rimEclipseCase, m_reservoirView); m_propFilteredWellGeometryFrames[i]->setTransform(m_scaleTransform.p()); } } @@ -183,7 +184,7 @@ void RivReservoirViewPartMgr::clearGeometryCache(RivCellSetEnum geomType) else { m_geometriesNeedsRegen[geomType] = true; - m_geometries[geomType].clearAndSetReservoir(eclipseCase, m_reservoirView); + m_geometries[geomType].clearAndSetReservoir(geomType, rimEclipseCase, m_reservoirView); m_geometries[geomType].setTransform(m_scaleTransform.p()); } } @@ -275,7 +276,8 @@ void RivReservoirViewPartMgr::ensureDynamicGeometryPartsCreated(RivCellSetEnum g void RivReservoirViewPartMgr::createGeometry(RivCellSetEnum geometryType) { RigEclipseCaseData* res = m_reservoirView->eclipseCase()->eclipseCaseData(); - m_geometries[geometryType].clearAndSetReservoir(res, m_reservoirView); + + m_geometries[geometryType].clearAndSetReservoir(geometryType, m_reservoirView->eclipseCase(), m_reservoirView); m_geometries[geometryType].setTransform(m_scaleTransform.p()); std::vector grids; @@ -298,7 +300,7 @@ void RivReservoirViewPartMgr::createGeometry(RivCellSetEnum geometryType) void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, RivCellSetEnum geometryType, RigGridBase* grid, size_t gridIdx) { RigEclipseCaseData* eclipseCase = m_reservoirView->eclipseCase()->eclipseCaseData(); - RigActiveCellInfo* activeCellInfo = m_reservoirView->currentActiveCellInfo(); + auto activeCellInfo = m_reservoirView->currentActiveCellInfo(); switch (geometryType) { @@ -306,7 +308,7 @@ void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, computeOverriddenCellVisibility(cellVisibility, grid); break; case ACTIVE: - computeNativeVisibility(cellVisibility, grid, activeCellInfo, eclipseCase->wellCellsInGrid(gridIdx), false, false, true, m_reservoirView->showMainGrid() ); + computeNativeVisibility(cellVisibility, grid, activeCellInfo, eclipseCase->wellCellsInGrid(gridIdx), false, false, true); break; case ALL_WELL_CELLS: copyByteArray(cellVisibility, eclipseCase->wellCellsInGrid(gridIdx)); @@ -344,7 +346,7 @@ void RivReservoirViewPartMgr::computeVisibility(cvf::UByteArray* cellVisibility, } break; case INACTIVE: - computeNativeVisibility(cellVisibility, grid, activeCellInfo, eclipseCase->wellCellsInGrid(gridIdx), m_reservoirView->showInvalidCells(), true, false, m_reservoirView->showMainGrid()); + computeNativeVisibility(cellVisibility, grid, activeCellInfo, eclipseCase->wellCellsInGrid(gridIdx), m_reservoirView->showInvalidCells(), true, false); break; case RANGE_FILTERED: { @@ -434,7 +436,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredNoneWellCellGeometry(size_t if ( m_propFilteredGeometryFrames[frameIndex].isNull()) m_propFilteredGeometryFrames[frameIndex] = new RivReservoirPartMgr; - m_propFilteredGeometryFrames[frameIndex]->clearAndSetReservoir(res, m_reservoirView); + m_propFilteredGeometryFrames[frameIndex]->clearAndSetReservoir(PROPERTY_FILTERED, m_reservoirView->eclipseCase(), m_reservoirView); m_propFilteredGeometryFrames[frameIndex]->setTransform(m_scaleTransform.p()); std::vector grids; @@ -510,7 +512,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameInd if ( m_propFilteredWellGeometryFrames[frameIndex].isNull()) m_propFilteredWellGeometryFrames[frameIndex] = new RivReservoirPartMgr; - m_propFilteredWellGeometryFrames[frameIndex]->clearAndSetReservoir(res, m_reservoirView); + m_propFilteredWellGeometryFrames[frameIndex]->clearAndSetReservoir(PROPERTY_FILTERED_WELL_CELLS, m_reservoirView->eclipseCase(), m_reservoirView); m_propFilteredWellGeometryFrames[frameIndex]->setTransform(m_scaleTransform.p()); std::vector grids; @@ -585,8 +587,7 @@ void RivReservoirViewPartMgr::createPropertyFilteredWellGeometry(size_t frameInd void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid, const RigActiveCellInfo* activeCellInfo, const cvf::UByteArray* cellIsInWellStatuses, bool invalidCellsIsVisible, bool inactiveCellsIsVisible, - bool activeCellsIsVisible, - bool mainGridIsVisible) + bool activeCellsIsVisible) { CVF_ASSERT(cellVisibility != nullptr); CVF_ASSERT(grid != nullptr); @@ -605,7 +606,6 @@ void RivReservoirViewPartMgr::computeNativeVisibility(cvf::UByteArray* cellVisib if ( !invalidCellsIsVisible && cell.isInvalid() || !inactiveCellsIsVisible && !activeCellInfo->isActive(reservoirCellIndex) || !activeCellsIsVisible && activeCellInfo->isActive(reservoirCellIndex) - //|| mainGridIsVisible && (cell.subGrid() != NULL) // this is handled on global level instead || (*cellIsInWellStatuses)[cellIndex] ) { diff --git a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h index 8a2b5acc36..27a43501df 100644 --- a/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivReservoirViewPartMgr.h @@ -23,13 +23,14 @@ #include "RivCellSetEnum.h" #include "RivReservoirPartMgr.h" // Must include here because of caf::FixedArray -#include "cafFixedArray.h" #include "cvfArray.h" #include "cvfBase.h" #include "cvfTransform.h" #include "cafPdmObject.h" +#include + class RimEclipseView; class RigGridBase; class RimCellRangeFilterCollection; @@ -102,6 +103,12 @@ class RivReservoirViewPartMgr: public cvf::Object void forceWatertightGeometryOnForType(RivCellSetEnum geometryType); void clearWatertightGeometryFlags(); + static void computePropertyVisibility(cvf::UByteArray* cellVisibilities, + const RigGridBase* grid, + size_t timeStepIndex, + const cvf::UByteArray* rangeFilterVisibility, + RimEclipsePropertyFilterCollection* propFilterColl); + private: void createGeometry(RivCellSetEnum geometryType); void computeVisibility(cvf::UByteArray* cellVisibility, @@ -121,18 +128,13 @@ class RivReservoirViewPartMgr: public cvf::Object const cvf::UByteArray* cellIsInWellStatuses, bool invalidCellsIsVisible, bool inactiveCellsIsVisible, - bool activeCellsIsVisible, - bool mainGridIsVisible); + bool activeCellsIsVisible); + void computeRangeVisibility (RivCellSetEnum geometryType, cvf::UByteArray* cellVisibilities, const RigGridBase* grid, const cvf::UByteArray* nativeVisibility, const RimCellRangeFilterCollection* rangeFilterColl); - static void computePropertyVisibility(cvf::UByteArray* cellVisibilities, - const RigGridBase* grid, - size_t timeStepIndex, - const cvf::UByteArray* rangeFilterVisibility, - RimEclipsePropertyFilterCollection* propFilterColl); void computeOverriddenCellVisibility(cvf::UByteArray* cellVisibility, const RigGridBase* grid); @@ -143,8 +145,8 @@ class RivReservoirViewPartMgr: public cvf::Object private: - caf::FixedArray m_geometries; - caf::FixedArray m_geometriesNeedsRegen; + std::array m_geometries; + std::array m_geometriesNeedsRegen; cvf::Collection m_propFilteredGeometryFrames; std::vector m_propFilteredGeometryFramesNeedsRegen; diff --git a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp index 36f83ac76e..ea6bad275b 100644 --- a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp +++ b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.cpp @@ -19,8 +19,6 @@ #include "RivScalarMapperUtils.h" -#include "RiaColorTables.h" - #include "RimCellEdgeColors.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" @@ -41,14 +39,14 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivScalarMapperUtils::applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting) +void RivScalarMapperUtils::applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting, const cvf::Color3f& undefColor) { CVF_ASSERT(part && textureCoords && mapper); cvf::DrawableGeo* dg = dynamic_cast(part->drawable()); if (dg) dg->setTextureCoordArray(textureCoords); - cvf::ref scalarEffect = RivScalarMapperUtils::createScalarMapperEffect(mapper, opacityLevel, faceCulling, disableLighting); + cvf::ref scalarEffect = RivScalarMapperUtils::createScalarMapperEffect(mapper, opacityLevel, faceCulling, disableLighting, undefColor); part->setEffect(scalarEffect.p()); } @@ -122,7 +120,7 @@ cvf::ref RivScalarMapperUtils::createCellEdgeEffect(cvf::DrawableGe //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::ref RivScalarMapperUtils::createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting) +cvf::ref RivScalarMapperUtils::createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting, const cvf::Color3f& undefColor) { CVF_ASSERT(mapper); @@ -130,7 +128,7 @@ cvf::ref RivScalarMapperUtils::createScalarMapperEffect(const cvf:: caf::ScalarMapperEffectGenerator scalarEffgen(mapper, polygonOffset); scalarEffgen.setOpacityLevel(opacityLevel); scalarEffgen.setFaceCulling(faceCulling); - scalarEffgen.setUndefinedColor(RiaColorTables::undefinedCellColor()); + scalarEffgen.setUndefinedColor(undefColor); scalarEffgen.disableLighting(disableLighting); cvf::ref scalarEffect = scalarEffgen.generateCachedEffect(); diff --git a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h index 808c9957d2..5be8f6ad9c 100644 --- a/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h +++ b/ApplicationCode/ModelVisualization/RivScalarMapperUtils.h @@ -19,6 +19,8 @@ #pragma once +#include "RiaColorTables.h" + #include "cafEffectGenerator.h" #include "cvfBase.h" @@ -43,7 +45,7 @@ class RimCellEdgeColors; class RivScalarMapperUtils { public: - static void applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting); + static void applyTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting, const cvf::Color3f& undefColor = cvf::Color3f(RiaColorTables::undefinedCellColor())); static void applyTernaryTextureResultsToPart(cvf::Part* part, cvf::Vec2fArray* textureCoords, const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting); static cvf::ref createCellEdgeEffect(cvf::DrawableGeo* dg, @@ -58,7 +60,7 @@ class RivScalarMapperUtils bool disableLighting); private: - static cvf::ref createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting); + static cvf::ref createScalarMapperEffect(const cvf::ScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting, const cvf::Color3f& undefColor = cvf::Color3f(RiaColorTables::undefinedCellColor())); static cvf::ref createTernaryScalarMapperEffect(const RivTernaryScalarMapper* mapper, float opacityLevel, caf::FaceCulling faceCulling, bool disableLighting); }; diff --git a/ApplicationCode/ModelVisualization/RivSimWellPipesPartMgr.cpp b/ApplicationCode/ModelVisualization/RivSimWellPipesPartMgr.cpp index 29dfef3c0d..1a9759c4ca 100644 --- a/ApplicationCode/ModelVisualization/RivSimWellPipesPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivSimWellPipesPartMgr.cpp @@ -333,8 +333,8 @@ void RivSimWellPipesPartMgr::buildWellPipeParts(const caf::DisplayCoordTransform cvf::ref part = pbd.m_connectionFactorGeometryGenerator->createSurfacePart(scalarMapper, eclipseView->isLightingDisabled()); if (part.notNull()) { - cvf::ref sourceInfo = new RivSimWellConnectionSourceInfo(m_simWellInView, pbd.m_connectionFactorGeometryGenerator.p()); - part->setSourceInfo(sourceInfo.p()); + cvf::ref simWellSourceInfo = new RivSimWellConnectionSourceInfo(m_simWellInView, pbd.m_connectionFactorGeometryGenerator.p()); + part->setSourceInfo(simWellSourceInfo.p()); } pbd.m_connectionFactorsPart = part; diff --git a/ApplicationCode/ModelVisualization/RivSimWellPipesPartMgr.h b/ApplicationCode/ModelVisualization/RivSimWellPipesPartMgr.h index fbe1a485a1..6c70003f5e 100644 --- a/ApplicationCode/ModelVisualization/RivSimWellPipesPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivSimWellPipesPartMgr.h @@ -50,7 +50,7 @@ class RivSimWellPipesPartMgr : public cvf::Object public: RivSimWellPipesPartMgr(RimSimWellInView* well); - ~RivSimWellPipesPartMgr(); + ~RivSimWellPipesPartMgr() override; void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex, diff --git a/ApplicationCode/ModelVisualization/RivSourceInfo.cpp b/ApplicationCode/ModelVisualization/RivSourceInfo.cpp index 4025bd1f9a..85aca07bea 100644 --- a/ApplicationCode/ModelVisualization/RivSourceInfo.cpp +++ b/ApplicationCode/ModelVisualization/RivSourceInfo.cpp @@ -2,27 +2,45 @@ // // Copyright (C) Statoil ASA // Copyright (C) Ceetron Solutions AS -// +// // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RivSourceInfo.h" + #include "cvfStructGridGeometryGenerator.h" +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivSourceInfo::RivSourceInfo(caf::PdmObject* pdmObject, size_t gridIndex) + : RivObjectSourceInfo(pdmObject) + , m_gridIndex(gridIndex) + , m_cellSetType(ALL_CELLS) +{ +} //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +size_t RivSourceInfo::gridIndex() const +{ + return m_gridIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- bool RivSourceInfo::hasCellFaceMapping() const { @@ -30,9 +48,25 @@ bool RivSourceInfo::hasCellFaceMapping() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RivSourceInfo::hasNNCIndices() const { return m_NNCIndices.notNull(); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RivCellSetEnum RivSourceInfo::cellSetType() const +{ + return m_cellSetType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivSourceInfo::setCellSetType(RivCellSetEnum cellSetEnum) +{ + m_cellSetType = cellSetEnum; +} diff --git a/ApplicationCode/ModelVisualization/RivSourceInfo.h b/ApplicationCode/ModelVisualization/RivSourceInfo.h index 5a70203839..233db84d1a 100644 --- a/ApplicationCode/ModelVisualization/RivSourceInfo.h +++ b/ApplicationCode/ModelVisualization/RivSourceInfo.h @@ -2,40 +2,53 @@ // // Copyright (C) Statoil ASA // Copyright (C) Ceetron Solutions AS -// +// // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once +#include "RivCellSetEnum.h" +#include "RivObjectSourceInfo.h" + +#include "cvfArray.h" #include "cvfBase.h" #include "cvfObject.h" -#include "cvfArray.h" + #include "cvfStructGridGeometryGenerator.h" -class RivSourceInfo : public cvf::Object +//================================================================================================== +/// +/// +//================================================================================================== +class RivSourceInfo : public RivObjectSourceInfo { public: - explicit RivSourceInfo(size_t gridIndex) : m_gridIndex(gridIndex) {} + explicit RivSourceInfo(caf::PdmObject* pdmObject, size_t gridIndex); - size_t gridIndex() const { return m_gridIndex; } - bool hasCellFaceMapping() const; - bool hasNNCIndices() const; + size_t gridIndex() const; + bool hasCellFaceMapping() const; + bool hasNNCIndices() const; + + RivCellSetEnum cellSetType() const; + void setCellSetType(RivCellSetEnum cellSetType); public: cvf::cref m_cellFaceFromTriangleMapper; - cvf::ref > m_NNCIndices; -private: - size_t m_gridIndex; + cvf::ref> m_NNCIndices; + +private: + size_t m_gridIndex; + RivCellSetEnum m_cellSetType; }; diff --git a/ApplicationCode/ModelVisualization/RivTensorResultPartMgr.h b/ApplicationCode/ModelVisualization/RivTensorResultPartMgr.h index 7418de6441..5b7c513939 100644 --- a/ApplicationCode/ModelVisualization/RivTensorResultPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivTensorResultPartMgr.h @@ -49,7 +49,7 @@ class RivTensorResultPartMgr : public cvf::Object { public: RivTensorResultPartMgr(RimGeoMechView* reservoirView); - ~RivTensorResultPartMgr(); + ~RivTensorResultPartMgr() override; void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex) const; diff --git a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h index af5db4772e..7d63f1988b 100644 --- a/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h +++ b/ApplicationCode/ModelVisualization/RivTernarySaturationOverlayItem.h @@ -40,7 +40,7 @@ class RivTernarySaturationOverlayItem : public caf::TitledOverlayFrame { public: explicit RivTernarySaturationOverlayItem(cvf::Font* font); - ~RivTernarySaturationOverlayItem(); + ~RivTernarySaturationOverlayItem() override; void setRangeText(const cvf::String& soilRange, const cvf::String& sgasRange, const cvf::String& swatRange); diff --git a/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp index 49206e74d4..133dce5ffe 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp +++ b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.cpp @@ -236,7 +236,7 @@ caf::EffectGenerator* RivTernaryScalarMapperEffectGenerator::copy() const //-------------------------------------------------------------------------------------------------- /// Tests whether two texture images are equal. It might in some rare cases not detect the difference -/// but to make the comparison fast only some sampling points are used. If both pointers are NULL, +/// but to make the comparison fast only some sampling points are used. If both pointers are nullptr, /// they are considered equal. //-------------------------------------------------------------------------------------------------- bool RivTernaryScalarMapperEffectGenerator::isImagesEqual(const cvf::TextureImage* texImg1, const cvf::TextureImage* texImg2) diff --git a/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h index ad6db1ce02..845ae75152 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h +++ b/ApplicationCode/ModelVisualization/RivTernaryScalarMapperEffectGenerator.h @@ -49,11 +49,11 @@ class RivTernaryScalarMapperEffectGenerator : public caf::EffectGenerator static bool isImagesEqual(const cvf::TextureImage* texImg1, const cvf::TextureImage* texImg2); protected: - virtual bool isEqual(const caf::EffectGenerator* other) const; - virtual caf::EffectGenerator* copy() const; + bool isEqual(const caf::EffectGenerator* other) const override; + caf::EffectGenerator* copy() const override; - virtual void updateForShaderBasedRendering(cvf::Effect* effect) const; - virtual void updateForFixedFunctionRendering(cvf::Effect* effect) const; + void updateForShaderBasedRendering(cvf::Effect* effect) const override; + void updateForFixedFunctionRendering(cvf::Effect* effect) const override; private: void updateCommonEffect(cvf::Effect* effect) const; diff --git a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp index 43e54aa833..526572e32f 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp +++ b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.cpp @@ -23,7 +23,7 @@ #include "RigEclipseCaseData.h" #include "RigPipeInCellEvaluator.h" #include "RigResultAccessorFactory.h" -#include "RigTernaryResultAccessor2d.h" +#include "RigTernaryResultAccessor.h" #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" diff --git a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h index b85ea520c0..1ac11e9a0a 100644 --- a/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h +++ b/ApplicationCode/ModelVisualization/RivTernaryTextureCoordsCreator.h @@ -19,7 +19,7 @@ #pragma once -#include "RigTernaryResultAccessor2d.h" +#include "RigTernaryResultAccessor.h" #include "RivTernaryResultToTextureMapper.h" #include "cvfBase.h" diff --git a/ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.h b/ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.h index 9e9535f2cd..2ac0ff01cc 100644 --- a/ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.h +++ b/ApplicationCode/ModelVisualization/RivWellConnectionFactorGeometryGenerator.h @@ -58,7 +58,7 @@ class RivWellConnectionFactorGeometryGenerator : public cvf::Object { public: RivWellConnectionFactorGeometryGenerator(std::vector& completionVizData, float radius); - ~RivWellConnectionFactorGeometryGenerator(); + ~RivWellConnectionFactorGeometryGenerator() override; cvf::ref createSurfacePart(const cvf::ScalarMapper* scalarMapper, bool disableLighting); diff --git a/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.cpp index a2f8d3d269..b7dc4a96cf 100644 --- a/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.cpp @@ -29,6 +29,7 @@ #include "RimEclipseCase.h" #include "RimEclipseView.h" +#include "RimFracture.h" #include "RimRegularLegendConfig.h" #include "RimSimWellInViewCollection.h" #include "RimVirtualPerforationResults.h" @@ -85,9 +86,9 @@ void RivWellConnectionFactorPartMgr::appendDynamicGeometryPartsToModel(cvf::Mode // Remove connection factors for parent grid, they are not supposed to be visualized, but are relevant for export for (auto it = completionsForWellPath.begin(); it != completionsForWellPath.end();) { - size_t gridIndex = it->first.globalCellIndex(); + size_t reservoirCellIndex = it->first; - const RigCell& rigCell = mainGrid->cell(gridIndex); + const RigCell& rigCell = mainGrid->cell(reservoirCellIndex); if (rigCell.subGrid()) { it = completionsForWellPath.erase(it); @@ -121,38 +122,54 @@ void RivWellConnectionFactorPartMgr::appendDynamicGeometryPartsToModel(cvf::Mode } } - size_t gridIndex = completionsForCell.first.globalCellIndex(); + bool showConnectionFactorOnWellPath = true; + { + for (const auto& completion : completionsForCell.second) + { + auto fracture = dynamic_cast(completion.sourcePdmObject()); + if (fracture) + { + showConnectionFactorOnWellPath = false; + } + } + } - const RigCell& rigCell = mainGrid->cell(gridIndex); + size_t reservoirCellIndex = completionsForCell.first; + + const RigCell& rigCell = mainGrid->cell(reservoirCellIndex); cvf::Vec3d locationInDomainCoord = rigCell.center(); cvf::Vec3d direction = cvf::Vec3d::X_AXIS; - bool foundLocation = false; - size_t i = 0; - while (!foundLocation && (i < wellPathCellIntersections.size())) + if (showConnectionFactorOnWellPath) { - const WellPathCellIntersectionInfo& intersectionInfo = wellPathCellIntersections[i]; + size_t i = 0; + bool foundLocation = false; - if (intersectionInfo.globCellIndex == completionsForCell.first.globalCellIndex()) + while (!foundLocation && (i < wellPathCellIntersections.size())) { - double startMD = intersectionInfo.startMD; - double endMD = intersectionInfo.endMD; + const WellPathCellIntersectionInfo& intersectionInfo = wellPathCellIntersections[i]; - double middleMD = (startMD + endMD) / 2.0; + if (intersectionInfo.globCellIndex == completionsForCell.first) + { + double startMD = intersectionInfo.startMD; + double endMD = intersectionInfo.endMD; - locationInDomainCoord = m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(middleMD); + double middleMD = (startMD + endMD) / 2.0; - cvf::Vec3d p1; - cvf::Vec3d p2; - m_rimWellPath->wellPathGeometry()->twoClosestPoints(locationInDomainCoord, &p1, &p2); + locationInDomainCoord = m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(middleMD); - direction = (p2 - p1).getNormalized(); + cvf::Vec3d p1; + cvf::Vec3d p2; + m_rimWellPath->wellPathGeometry()->twoClosestPoints(locationInDomainCoord, &p1, &p2); - foundLocation = true; - } + direction = (p2 - p1).getNormalized(); - i++; + foundLocation = true; + } + + i++; + } } cvf::Vec3d displayCoord = coordTransform->transformToDisplayCoord(locationInDomainCoord); @@ -164,7 +181,7 @@ void RivWellConnectionFactorPartMgr::appendDynamicGeometryPartsToModel(cvf::Mode double transmissibility = completionData.transmissibility(); completionVizDataItems.push_back( - CompletionVizData(displayCoord, direction, transmissibility, completionsForCell.first.globalCellIndex())); + CompletionVizData(displayCoord, direction, transmissibility, completionsForCell.first)); } } diff --git a/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.h b/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.h index 659c9093f3..107addb91d 100644 --- a/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellConnectionFactorPartMgr.h @@ -41,7 +41,7 @@ class RivWellConnectionFactorPartMgr : public cvf::Object { public: RivWellConnectionFactorPartMgr(RimWellPath* well, RimVirtualPerforationResults* virtualPerforationResult); - ~RivWellConnectionFactorPartMgr(); + ~RivWellConnectionFactorPartMgr() override; void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex); diff --git a/ApplicationCode/ModelVisualization/RivWellConnectionsPartMgr.h b/ApplicationCode/ModelVisualization/RivWellConnectionsPartMgr.h index 0f19999a11..6593462b40 100644 --- a/ApplicationCode/ModelVisualization/RivWellConnectionsPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellConnectionsPartMgr.h @@ -47,7 +47,7 @@ class RivWellConnectionsPartMgr : public cvf::Object { public: RivWellConnectionsPartMgr(RimEclipseView* reservoirView, RimSimWellInView* well); - ~RivWellConnectionsPartMgr(); + ~RivWellConnectionsPartMgr() override; void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex); diff --git a/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.cpp index 187306ff3e..5a0596d61a 100644 --- a/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -28,10 +28,12 @@ #include "RigWellPath.h" #include "RimCase.h" +#include "RimEclipseCase.h" #include "RimEclipseView.h" #include "RimEllipseFractureTemplate.h" #include "RimFracture.h" #include "RimFractureContainment.h" +#include "RimFractureContainmentTools.h" #include "RimFractureTemplate.h" #include "RimRegularLegendConfig.h" #include "RimSimWellInView.h" @@ -63,9 +65,8 @@ #include - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RivWellFracturePartMgr::RivWellFracturePartMgr(RimFracture* fracture) : m_rimFracture(fracture) @@ -73,15 +74,12 @@ RivWellFracturePartMgr::RivWellFracturePartMgr(RimFracture* fracture) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RivWellFracturePartMgr::~RivWellFracturePartMgr() -{ - -} +RivWellFracturePartMgr::~RivWellFracturePartMgr() {} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RivWellFracturePartMgr::appendGeometryPartsToModel(cvf::ModelBasicList* model, const RimEclipseView& eclView) { @@ -89,10 +87,13 @@ void RivWellFracturePartMgr::appendGeometryPartsToModel(cvf::ModelBasicList* mod if (!m_rimFracture->fractureTemplate()) return; + m_visibleFracturePolygons.clear(); + double characteristicCellSize = eclView.ownerCase()->characteristicCellSize(); - cvf::Collection parts; - RimStimPlanFractureTemplate* stimPlanFracTemplate = dynamic_cast(m_rimFracture->fractureTemplate()); + cvf::Collection parts; + RimStimPlanFractureTemplate* stimPlanFracTemplate = + dynamic_cast(m_rimFracture->fractureTemplate()); if (stimPlanFracTemplate) { @@ -113,7 +114,7 @@ void RivWellFracturePartMgr::appendGeometryPartsToModel(cvf::ModelBasicList* mod if (part.notNull()) parts.push_back(part.p()); } } - else + else { auto part = createEllipseSurfacePart(eclView); if (part.notNull()) parts.push_back(part.p()); @@ -136,7 +137,6 @@ void RivWellFracturePartMgr::appendGeometryPartsToModel(cvf::ModelBasicList* mod } } - // Make sure the distance is slightly smaller than the pipe radius to make the pipe is visible through the fracture distanceToCenterLine *= 0.1; @@ -147,36 +147,14 @@ void RivWellFracturePartMgr::appendGeometryPartsToModel(cvf::ModelBasicList* mod auto fractureMatrix = m_rimFracture->transformMatrix(); - if (m_rimFracture->fractureTemplate() && m_rimFracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) + if (m_rimFracture->fractureTemplate() && + m_rimFracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) { cvf::Vec3d partTranslation = distanceToCenterLine * cvf::Vec3d(fractureMatrix.col(2)); + for (auto& part : parts) { - cvf::Mat4d m = cvf::Mat4d::fromTranslation(partTranslation); - - cvf::ref partTransform = new cvf::Transform; - partTransform->setLocalTransform(m); - - for (auto& part : parts) - { - part->setTransform(partTransform.p()); - model->addPart(part.p()); - } - } - - { - cvf::Mat4d m = cvf::Mat4d::fromTranslation(-partTranslation); - - cvf::ref partTransform = new cvf::Transform; - partTransform->setLocalTransform(m); - - for (const auto& originalPart : parts) - { - auto part = originalPart->shallowCopy(); - - part->setTransform(partTransform.p()); - model->addPart(part.p()); - } + RivWellFracturePartMgr::addPartAtPositiveAndNegativeTranslation(model, part.p(), partTranslation); } } else @@ -187,41 +165,46 @@ void RivWellFracturePartMgr::appendGeometryPartsToModel(cvf::ModelBasicList* mod } } - if (m_rimFracture->fractureTemplate()->fractureContainment()->isEnabled()) + if (m_rimFracture->fractureTemplate()) { // Position the containment mask outside the fracture parts // Always duplicate the containment mask parts - auto originalPart = createContainmentMaskPart(eclView); - if (originalPart.notNull()) { - double scaleFactor = 0.03; - if (m_rimFracture->fractureTemplate() && m_rimFracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) + auto maskOfFractureAreasOutsideGrid = createMaskOfFractureOutsideGrid(eclView); + if (maskOfFractureAreasOutsideGrid.notNull()) { - scaleFactor = 2 * distanceToCenterLine; - } - - cvf::Vec3d partTranslation = scaleFactor * cvf::Vec3d(fractureMatrix.col(2)); - - { - cvf::Mat4d m = cvf::Mat4d::fromTranslation(partTranslation); + double scaleFactor = 0.03; + if (m_rimFracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) + { + scaleFactor = 2 * distanceToCenterLine; + } - cvf::ref partTransform = new cvf::Transform; - partTransform->setLocalTransform(m); + cvf::Vec3d partTranslation = scaleFactor * cvf::Vec3d(fractureMatrix.col(2)); - originalPart->setTransform(partTransform.p()); - model->addPart(originalPart.p()); + RivWellFracturePartMgr::addPartAtPositiveAndNegativeTranslation( + model, maskOfFractureAreasOutsideGrid.p(), partTranslation); } + } + + if (m_rimFracture->fractureTemplate()->fractureContainment()->isEnabled()) + { + // Position the containment mask outside the fracture parts + // Always duplicate the containment mask parts + auto containmentMask = createContainmentMaskPart(eclView); + if (containmentMask.notNull()) { - cvf::Mat4d m = cvf::Mat4d::fromTranslation(-partTranslation); + double scaleFactor = 0.03; + if (m_rimFracture->fractureTemplate() && + m_rimFracture->fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) + { + scaleFactor = 2 * distanceToCenterLine; + } - cvf::ref partTransform = new cvf::Transform; - partTransform->setLocalTransform(m); + cvf::Vec3d partTranslation = scaleFactor * cvf::Vec3d(fractureMatrix.col(2)); - auto copy = originalPart->shallowCopy(); - copy->setTransform(partTransform.p()); - model->addPart(copy.p()); + RivWellFracturePartMgr::addPartAtPositiveAndNegativeTranslation(model, containmentMask.p(), partTranslation); } } } @@ -230,7 +213,7 @@ void RivWellFracturePartMgr::appendGeometryPartsToModel(cvf::ModelBasicList* mod } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const QString RivWellFracturePartMgr::resultInfoText(const RimEclipseView& activeView, cvf::Vec3d domainIntersectionPoint) const { @@ -238,69 +221,74 @@ const QString RivWellFracturePartMgr::resultInfoText(const RimEclipseView& activ if (m_rimFracture.isNull()) return text; - RimEllipseFractureTemplate* ellipseFractureTemplate = dynamic_cast(m_rimFracture->fractureTemplate()); - RimStimPlanFractureTemplate* stimPlanTemplate = dynamic_cast(m_rimFracture->fractureTemplate()); + auto* ellipseFractureTemplate = dynamic_cast(m_rimFracture->fractureTemplate()); + auto* stimPlanTemplate = dynamic_cast(m_rimFracture->fractureTemplate()); + if (ellipseFractureTemplate) { text.append("Result value: CONDUCTIVITY "); text.append(QString::number(ellipseFractureTemplate->conductivity()) + "\n"); - } else if (stimPlanTemplate) { - const RigFractureCell* cell = getFractureCellAtDomainCoord(domainIntersectionPoint); - RimStimPlanColors* stimPlanColors = activeView.fractureColors(); - - QString resultNameFromColors = activeView.fractureColors()->uiResultName(); - QString resultUnitFromColors = activeView.fractureColors()->unit(); + const RigFractureCell* cell = getFractureCellAtDomainCoord(domainIntersectionPoint); + if (cell) + { + QString resultNameFromColors = activeView.fractureColors()->uiResultName(); + QString resultUnitFromColors = activeView.fractureColors()->unit(); - double resultValue = stimPlanTemplate->resultValueAtIJ( - resultNameFromColors, resultUnitFromColors, stimPlanTemplate->activeTimeStepIndex(), cell->getI(), cell->getJ()); + double resultValue = stimPlanTemplate->resultValueAtIJ( + resultNameFromColors, resultUnitFromColors, stimPlanTemplate->activeTimeStepIndex(), cell->getI(), cell->getJ()); - QString resultValueText = QString("%1").arg(resultValue); + QString resultValueText = QString("%1").arg(resultValue); - QString iText = cell ? QString::number(cell->getI()) : "-"; - QString jText = cell ? QString::number(cell->getJ()) : "-"; + QString iText = QString::number(cell->getI()); + QString jText = QString::number(cell->getJ()); - // Conductivity - text.append("Result value: "); + RimStimPlanColors* stimPlanColors = activeView.fractureColors(); + if (stimPlanColors) + { + // Conductivity + text.append("Result value: "); - QString resultName = stimPlanTemplate->mapUiResultNameToFileResultName(stimPlanColors->uiResultName()); - text.append(resultName + " "); - text.append(resultValueText + "\n"); + QString resultName = stimPlanTemplate->mapUiResultNameToFileResultName(stimPlanColors->uiResultName()); + text.append(resultName + " "); + text.append(resultValueText + "\n"); + } - // Cell index - text.append("Cell Index: "); - text.append(iText + ", " + jText + "\n"); + // Cell index + text.append("Cell Index: "); + text.append(iText + ", " + jText + "\n"); + } } return text; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const RigFractureCell* RivWellFracturePartMgr::getFractureCellAtDomainCoord(cvf::Vec3d domainCoord) const { if (!m_rimFracture) return nullptr; - cvf::Mat4d toFractureXf = m_rimFracture->transformMatrix().getInverted(); + cvf::Mat4d toFractureXf = m_rimFracture->transformMatrix().getInverted(); cvf::Vec3d fractureCoord = domainCoord.getTransformedPoint(toFractureXf); - const RimStimPlanFractureTemplate* stimPlanTempl = dynamic_cast(m_rimFracture->fractureTemplate()); + auto* stimPlanTempl = dynamic_cast(m_rimFracture->fractureTemplate()); if (!stimPlanTempl) return nullptr; - const RigFractureGrid* grid = stimPlanTempl->fractureGrid(); - size_t cellI = cvf::UNDEFINED_SIZE_T; - size_t cellJ = cvf::UNDEFINED_SIZE_T; - const std::vector& cells = grid->fractureCells(); + const RigFractureGrid* grid = stimPlanTempl->fractureGrid(); + size_t cellI = cvf::UNDEFINED_SIZE_T; + size_t cellJ = cvf::UNDEFINED_SIZE_T; + const std::vector& cells = grid->fractureCells(); for (size_t i = 0; i < grid->iCellCount(); i++) { - const RigFractureCell& cell = cells[i * grid->jCellCount()]; + const RigFractureCell& cell = cells[i * grid->jCellCount()]; std::vector polygon = cell.getPolygon(); - double xmin = polygon[0].x(); - double xmax = polygon[2].x(); + double xmin = polygon[0].x(); + double xmax = polygon[2].x(); if (fractureCoord.x() >= xmin && fractureCoord.x() <= xmax) { cellI = cell.getI(); @@ -310,10 +298,10 @@ const RigFractureCell* RivWellFracturePartMgr::getFractureCellAtDomainCoord(cvf: for (size_t j = 0; j < grid->jCellCount(); j++) { - const RigFractureCell& cell = cells[j]; + const RigFractureCell& cell = cells[j]; std::vector polygon = cell.getPolygon(); - double ymin = polygon[2].y(); - double ymax = polygon[0].y(); + double ymin = polygon[2].y(); + double ymax = polygon[0].y(); if (fractureCoord.y() >= ymin && fractureCoord.y() <= ymax) { cellJ = cell.getJ(); @@ -329,7 +317,7 @@ const RigFractureCell* RivWellFracturePartMgr::getFractureCellAtDomainCoord(cvf: } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::ref RivWellFracturePartMgr::createEllipseSurfacePart(const RimEclipseView& activeView) { @@ -338,13 +326,16 @@ cvf::ref RivWellFracturePartMgr::createEllipseSurfacePart(const RimEc if (m_rimFracture) { - std::vector nodeCoords; - std::vector triangleIndices; + std::vector triangleIndices; + std::vector nodeDisplayCoords; - m_rimFracture->fractureTemplate()->fractureTriangleGeometry(&nodeCoords, &triangleIndices); + { + std::vector nodeCoords; + m_rimFracture->fractureTemplate()->fractureTriangleGeometry(&nodeCoords, &triangleIndices); - cvf::Mat4d fractureXf = m_rimFracture->transformMatrix(); - std::vector nodeDisplayCoords = transformToFractureDisplayCoords(nodeCoords, fractureXf, *displayCoordTransform); + cvf::Mat4d fractureXf = m_rimFracture->transformMatrix(); + nodeDisplayCoords = transformToFractureDisplayCoords(nodeCoords, fractureXf, *displayCoordTransform); + } if (triangleIndices.empty() || nodeDisplayCoords.empty()) { @@ -353,38 +344,39 @@ cvf::ref RivWellFracturePartMgr::createEllipseSurfacePart(const RimEc cvf::ref geo = buildDrawableGeoFromTriangles(triangleIndices, nodeDisplayCoords); CVF_ASSERT(geo.notNull()); - + cvf::ref surfacePart = new cvf::Part(0, "FractureSurfacePart_ellipse"); surfacePart->setDrawable(geo.p()); surfacePart->setSourceInfo(new RivObjectSourceInfo(m_rimFracture)); cvf::Color4f fractureColor = cvf::Color4f(activeView.fractureColors()->defaultColor()); - - RimRegularLegendConfig* legendConfig = nullptr; - if (activeView.fractureColors() && activeView.fractureColors()->isChecked()) - { - legendConfig = activeView.fractureColors()->activeLegend(); - } - - if (legendConfig && legendConfig->scalarMapper()) - { + + RimRegularLegendConfig* legendConfig = nullptr; + if (activeView.fractureColors() && activeView.fractureColors()->isChecked()) + { + legendConfig = activeView.fractureColors()->activeLegend(); + } + + if (legendConfig && legendConfig->scalarMapper()) + { cvf::Color3ub resultColor = cvf::Color3ub(RiaColorTables::undefinedCellColor()); if (activeView.fractureColors()->uiResultName() == RiaDefines::conductivityResultName()) { - RimEllipseFractureTemplate* ellipseFractureTemplate = dynamic_cast(m_rimFracture->fractureTemplate()); + RimEllipseFractureTemplate* ellipseFractureTemplate = + dynamic_cast(m_rimFracture->fractureTemplate()); if (ellipseFractureTemplate) { double conductivity = ellipseFractureTemplate->conductivity(); - resultColor = legendConfig->scalarMapper()->mapToColor(conductivity); + resultColor = legendConfig->scalarMapper()->mapToColor(conductivity); } } - fractureColor.set(cvf::Color3f::fromByteColor(resultColor.r(), resultColor.g(), resultColor.b())); - } + fractureColor.set(cvf::Color3f::fromByteColor(resultColor.r(), resultColor.g(), resultColor.b())); + } caf::SurfaceEffectGenerator surfaceGen(fractureColor, caf::PO_1); - cvf::ref eff = surfaceGen.generateCachedEffect(); + cvf::ref eff = surfaceGen.generateCachedEffect(); surfacePart->setEffect(eff.p()); return surfacePart; @@ -393,34 +385,36 @@ cvf::ref RivWellFracturePartMgr::createEllipseSurfacePart(const RimEc return nullptr; } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::ref RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfacePart(const RimEclipseView& activeView) { CVF_ASSERT(m_rimFracture); - RimStimPlanFractureTemplate* stimPlanFracTemplate = dynamic_cast(m_rimFracture->fractureTemplate()); + RimStimPlanFractureTemplate* stimPlanFracTemplate = + dynamic_cast(m_rimFracture->fractureTemplate()); CVF_ASSERT(stimPlanFracTemplate); auto displayCoordTransform = activeView.displayCoordTransform(); if (displayCoordTransform.isNull()) return nullptr; - // Note that the filtering and result mapping code below couples closely to the triangulation and vertex layout returned by triangleGeometry() - // If this ever changes, the entire code must be revisited - std::vector nodeCoords; - std::vector triangleIndices; + // Note that the filtering and result mapping code below couples closely to the triangulation and vertex layout returned by + // triangleGeometry() If this ever changes, the entire code must be revisited + std::vector triangleIndices; + std::vector nodeDisplayCoords; + { + std::vector nodeCoords; + stimPlanFracTemplate->fractureTriangleGeometry(&nodeCoords, &triangleIndices); - stimPlanFracTemplate->fractureTriangleGeometry(&nodeCoords, &triangleIndices); + if (triangleIndices.empty() || nodeCoords.empty()) + { + return nullptr; + } - if (triangleIndices.empty() || nodeCoords.empty()) - { - return nullptr; + cvf::Mat4d fractureXf = m_rimFracture->transformMatrix(); + nodeDisplayCoords = transformToFractureDisplayCoords(nodeCoords, fractureXf, *displayCoordTransform); } - cvf::Mat4d fractureXf = m_rimFracture->transformMatrix(); - std::vector nodeDisplayCoords = transformToFractureDisplayCoords(nodeCoords, fractureXf, *displayCoordTransform); - RimRegularLegendConfig* legendConfig = nullptr; if (activeView.fractureColors() && activeView.fractureColors()->isChecked()) { @@ -435,7 +429,11 @@ cvf::ref RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfa std::vector perNodeResultValues(nodeDisplayCoords.size(), HUGE_VAL); { size_t idx = 0; - const std::vector > dataToPlot = stimPlanFracTemplate->resultValues(activeView.fractureColors()->uiResultName(), activeView.fractureColors()->unit(), stimPlanFracTemplate->activeTimeStepIndex()); + + const std::vector> dataToPlot = + stimPlanFracTemplate->resultValues(activeView.fractureColors()->uiResultName(), + activeView.fractureColors()->unit(), + stimPlanFracTemplate->activeTimeStepIndex()); for (const std::vector& dataAtY : dataToPlot) { for (double val : dataAtY) @@ -473,8 +471,8 @@ cvf::ref RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfa return nullptr; } - cvf::ref geo = buildDrawableGeoFromTriangles(triIndicesToInclude, nodeDisplayCoords); - const cvf::ScalarMapper* scalarMapper = legendConfig->scalarMapper(); + cvf::ref geo = buildDrawableGeoFromTriangles(triIndicesToInclude, nodeDisplayCoords); + const cvf::ScalarMapper* scalarMapper = legendConfig->scalarMapper(); CVF_ASSERT(scalarMapper); cvf::ref textureCoords = new cvf::Vec2fArray(nodeDisplayCoords.size()); @@ -484,30 +482,30 @@ cvf::ref RivWellFracturePartMgr::createStimPlanColorInterpolatedSurfa const double val = perNodeResultValues[i]; if (val < HUGE_VAL && val == val) { - textureCoords->set(i, scalarMapper->mapToTextureCoord(val)); + textureCoords->set(i, scalarMapper->mapToTextureCoord(val)); } } geo->setTextureCoordArray(textureCoords.p()); - cvf::ref surfacePart = createScalarMapperPart(geo.p(), scalarMapper, m_rimFracture, activeView.isLightingDisabled()); + cvf::ref surfacePart = + createScalarMapperPart(geo.p(), scalarMapper, m_rimFracture, activeView.isLightingDisabled()); return surfacePart; } - else + else { // No result is mapped, show the entire StimPlan surface with default color - return createSingleColorSurfacePart(triangleIndices, nodeCoords, activeView.fractureColors()->defaultColor()); + return createSingleColorSurfacePart(triangleIndices, nodeDisplayCoords, activeView.fractureColors()->defaultColor()); } - - return nullptr; } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -cvf::ref RivWellFracturePartMgr::createSingleColorSurfacePart(const std::vector& triangleIndices, const std::vector& nodeCoords, const cvf::Color3f& color) +cvf::ref RivWellFracturePartMgr::createSingleColorSurfacePart(const std::vector& triangleIndices, + const std::vector& nodeCoords, + const cvf::Color3f& color) { cvf::ref geo = buildDrawableGeoFromTriangles(triangleIndices, nodeCoords); @@ -516,21 +514,22 @@ cvf::ref RivWellFracturePartMgr::createSingleColorSurfacePart(const s surfacePart->setPriority(RivPartPriority::PartType::BaseLevel); surfacePart->setSourceInfo(new RivObjectSourceInfo(m_rimFracture)); - cvf::Color4f fractureColor = cvf::Color4f(color); + cvf::Color4f fractureColor = cvf::Color4f(color); caf::SurfaceEffectGenerator surfaceGen(fractureColor, caf::PO_1); - cvf::ref eff = surfaceGen.generateCachedEffect(); + cvf::ref eff = surfaceGen.generateCachedEffect(); surfacePart->setEffect(eff.p()); return surfacePart; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::ref RivWellFracturePartMgr::createStimPlanElementColorSurfacePart(const RimEclipseView& activeView) { CVF_ASSERT(m_rimFracture); - RimStimPlanFractureTemplate* stimPlanFracTemplate = dynamic_cast(m_rimFracture->fractureTemplate()); + RimStimPlanFractureTemplate* stimPlanFracTemplate = + dynamic_cast(m_rimFracture->fractureTemplate()); CVF_ASSERT(stimPlanFracTemplate); if (!stimPlanFracTemplate->fractureGrid()) return nullptr; @@ -538,16 +537,15 @@ cvf::ref RivWellFracturePartMgr::createStimPlanElementColorSurfacePar auto displayCoordTransform = activeView.displayCoordTransform(); if (displayCoordTransform.isNull()) return nullptr; - std::vector stimPlanMeshVertices; + std::vector stimPlanMeshVertices; cvf::ref textureCoords = new cvf::Vec2fArray; - const cvf::ScalarMapper* scalarMapper = nullptr; + const cvf::ScalarMapper* scalarMapper = nullptr; { std::vector stimPlanCells = stimPlanFracTemplate->fractureGrid()->fractureCells(); RimRegularLegendConfig* legendConfig = nullptr; - if (activeView.fractureColors() && - activeView.fractureColors()->isChecked() && + if (activeView.fractureColors() && activeView.fractureColors()->isChecked() && activeView.fractureColors()->activeLegend()) { legendConfig = activeView.fractureColors()->activeLegend(); @@ -557,9 +555,8 @@ cvf::ref RivWellFracturePartMgr::createStimPlanElementColorSurfacePar QString resultNameFromColors = activeView.fractureColors()->uiResultName(); QString resultUnitFromColors = activeView.fractureColors()->unit(); - std::vector prCellResults = stimPlanFracTemplate->fractureGridResults(resultNameFromColors, - resultUnitFromColors, - stimPlanFracTemplate->activeTimeStepIndex()); + std::vector prCellResults = stimPlanFracTemplate->fractureGridResults( + resultNameFromColors, resultUnitFromColors, stimPlanFracTemplate->activeTimeStepIndex()); textureCoords->reserve(prCellResults.size() * 4); @@ -567,12 +564,12 @@ cvf::ref RivWellFracturePartMgr::createStimPlanElementColorSurfacePar { if (prCellResults[cIdx] > 1e-7) { - const RigFractureCell& stimPlanCell = stimPlanCells[cIdx]; + const RigFractureCell& stimPlanCell = stimPlanCells[cIdx]; std::vector stimPlanCellPolygon = stimPlanCell.getPolygon(); for (const cvf::Vec3d& cellCorner : stimPlanCellPolygon) { stimPlanMeshVertices.push_back(static_cast(cellCorner)); - textureCoords->add(scalarMapper->mapToTextureCoord(prCellResults[cIdx])); + textureCoords->add(scalarMapper->mapToTextureCoord(prCellResults[cIdx])); } } } @@ -596,7 +593,7 @@ cvf::ref RivWellFracturePartMgr::createStimPlanElementColorSurfacePar return nullptr; } - cvf::Mat4d fractureXf = m_rimFracture->transformMatrix(); + cvf::Mat4d fractureXf = m_rimFracture->transformMatrix(); std::vector nodeDisplayCoords = transformToFractureDisplayCoords(stimPlanMeshVertices, fractureXf, *displayCoordTransform); @@ -625,11 +622,12 @@ cvf::ref RivWellFracturePartMgr::createStimPlanElementColorSurfacePar cvf::ref geo = buildDrawableGeoFromTriangles(triIndicesToInclude, nodeDisplayCoords); geo->setTextureCoordArray(textureCoords.p()); - cvf::ref surfacePart = createScalarMapperPart(geo.p(), scalarMapper, m_rimFracture, activeView.isLightingDisabled()); + cvf::ref surfacePart = + createScalarMapperPart(geo.p(), scalarMapper, m_rimFracture, activeView.isLightingDisabled()); return surfacePart; } - else + else { // No result is mapped, show the entire StimPlan surface with default color @@ -638,16 +636,16 @@ cvf::ref RivWellFracturePartMgr::createStimPlanElementColorSurfacePar } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::ref RivWellFracturePartMgr::createContainmentMaskPart(const RimEclipseView& activeView) { - std::vector borderPolygonLocalCS = fractureBorderPolygon(); - cvf::Mat4d frMx = m_rimFracture->transformMatrix(); + std::vector borderPolygonLocalCS = fractureBorderPolygon(); + cvf::Mat4d frMx = m_rimFracture->transformMatrix(); - cvf::BoundingBox frBBox; + cvf::BoundingBox frBBox; std::vector borderPolygonLocalCsd; - for (const auto& pv: borderPolygonLocalCS) + for (const auto& pv : borderPolygonLocalCS) { cvf::Vec3d pvd(pv); borderPolygonLocalCsd.push_back(pvd); @@ -662,16 +660,20 @@ cvf::ref RivWellFracturePartMgr::createContainmentMaskPart(const RimE std::vector maskTriangles; + RimEclipseCase* eclipseCase = nullptr; + activeView.firstAncestorOrThisOfType(eclipseCase); + auto reservoirCellIndicesOpenForFlow = RimFractureContainmentTools::reservoirCellIndicesOpenForFlow(eclipseCase, m_rimFracture); + for (size_t resCellIdx : cellCandidates) { - if (!m_rimFracture->isEclipseCellWithinContainment(activeView.mainGrid(), resCellIdx)) + if (!m_rimFracture->isEclipseCellOpenForFlow(activeView.mainGrid(), reservoirCellIndicesOpenForFlow, resCellIdx)) { - // Calculate Eclipse cell intersection with fracture plane + // Calculate Eclipse cell intersection with fracture plane - std::array corners; - activeView.mainGrid()->cellCornerVertices(resCellIdx, corners.data()); + std::array corners; + activeView.mainGrid()->cellCornerVertices(resCellIdx, corners.data()); - std::vector > eclCellPolygons; + std::vector> eclCellPolygons; bool hasIntersection = RigHexIntersectionTools::planeHexIntersectionPolygons(corners, frMx, eclCellPolygons); if (!hasIntersection || eclCellPolygons.empty()) continue; @@ -679,9 +681,9 @@ cvf::ref RivWellFracturePartMgr::createContainmentMaskPart(const RimE // Transform eclCell - plane intersection onto fracture cvf::Mat4d invertedTransformMatrix = frMx.getInverted(); - for ( std::vector& eclCellPolygon : eclCellPolygons ) + for (std::vector& eclCellPolygon : eclCellPolygons) { - for ( cvf::Vec3d& v : eclCellPolygon ) + for (cvf::Vec3d& v : eclCellPolygon) { v.transformPoint(invertedTransformMatrix); } @@ -692,11 +694,11 @@ cvf::ref RivWellFracturePartMgr::createContainmentMaskPart(const RimE { // Clip Eclipse cell polygon with fracture border - std::vector< std::vector > clippedPolygons = RigCellGeometryTools::intersectPolygons(eclCellPolygon, - borderPolygonLocalCsd); + std::vector> clippedPolygons = + RigCellGeometryTools::intersectPolygons(eclCellPolygon, borderPolygonLocalCsd); for (auto& clippedPolygon : clippedPolygons) { - for (auto& v: clippedPolygon) + for (auto& v : clippedPolygon) { v.transformPoint(frMx); } @@ -711,22 +713,23 @@ cvf::ref RivWellFracturePartMgr::createContainmentMaskPart(const RimE cvf::Vec3dArray cvfNodes(clippedPolygon); tess.setGlobalNodeArray(cvfNodes); std::vector polyIndexes; - for (size_t idx = 0; idx < clippedPolygon.size(); ++idx) polyIndexes.push_back(idx); + for (size_t idx = 0; idx < clippedPolygon.size(); ++idx) + polyIndexes.push_back(idx); tess.setPolygonIndices(polyIndexes); std::vector triangleIndices; tess.calculateTriangles(&triangleIndices); - for (size_t idx: triangleIndices) + for (size_t idx : triangleIndices) { - maskTriangles.push_back( cvf::Vec3f( displCoordTrans->transformToDisplayCoord(clippedPolygon[idx]) ) ); + maskTriangles.push_back(cvf::Vec3f(displCoordTrans->transformToDisplayCoord(clippedPolygon[idx]))); } } } } } - if ( maskTriangles.size() >= 3 ) + if (maskTriangles.size() >= 3) { cvf::ref maskTriangleGeo = new cvf::DrawableGeo; maskTriangleGeo->setVertexArray(new cvf::Vec3fArray(maskTriangles)); @@ -743,7 +746,7 @@ cvf::ref RivWellFracturePartMgr::createContainmentMaskPart(const RimE cvf::Color4f maskColor = cvf::Color4f(cvf::Color3f(cvf::Color3::GRAY)); caf::SurfaceEffectGenerator surfaceGen(maskColor, caf::PO_NONE); - cvf::ref eff = surfaceGen.generateCachedEffect(); + cvf::ref eff = surfaceGen.generateCachedEffect(); containmentMaskPart->setEffect(eff.p()); return containmentMaskPart; @@ -753,7 +756,168 @@ cvf::ref RivWellFracturePartMgr::createContainmentMaskPart(const RimE } //-------------------------------------------------------------------------------------------------- -/// +/// Create mask for the parts outside the grid cells of the reservoir +//-------------------------------------------------------------------------------------------------- +cvf::ref RivWellFracturePartMgr::createMaskOfFractureOutsideGrid(const RimEclipseView& activeView) +{ + cvf::Mat4d frMx = m_rimFracture->transformMatrix(); + + std::vector maskTriangles; + + auto displCoordTrans = activeView.displayCoordTransform(); + + for (const auto& visibleFracturePolygon : m_visibleFracturePolygons) + { + std::vector borderOfFractureCellPolygonLocalCsd; + cvf::BoundingBox frBBox; + + for (const auto& pv : visibleFracturePolygon) + { + cvf::Vec3d pvd(pv); + borderOfFractureCellPolygonLocalCsd.push_back(pvd); + pvd.transformPoint(frMx); + frBBox.add(pvd); + } + + std::vector> clippedPolygons; + + std::vector cellCandidates; + activeView.mainGrid()->findIntersectingCells(frBBox, &cellCandidates); + if (cellCandidates.empty()) + { + clippedPolygons.push_back(borderOfFractureCellPolygonLocalCsd); + } + else + { + // Check if fracture polygon is fully inside the grid + + bool allPointsInsideGrid = true; + for (const auto& v : borderOfFractureCellPolygonLocalCsd) + { + auto pointInDomainCoords = v.getTransformedPoint(frMx); + bool pointInsideGrid = false; + RigMainGrid* mainGrid = activeView.mainGrid(); + + std::array corners; + for (size_t cellIndex : cellCandidates) + { + mainGrid->cellCornerVertices(cellIndex, corners.data()); + + if (RigHexIntersectionTools::isPointInCell(pointInDomainCoords, corners.data())) + { + pointInsideGrid = true; + break; + } + } + + if (!pointInsideGrid) + { + allPointsInsideGrid = false; + break; + } + } + + if (!allPointsInsideGrid) + { + std::vector> allEclCellPolygons; + for (size_t resCellIdx : cellCandidates) + { + // Calculate Eclipse cell intersection with fracture plane + + std::array corners; + activeView.mainGrid()->cellCornerVertices(resCellIdx, corners.data()); + + std::vector> eclCellPolygons; + bool hasIntersection = RigHexIntersectionTools::planeHexIntersectionPolygons(corners, frMx, eclCellPolygons); + + if (!hasIntersection || eclCellPolygons.empty()) continue; + + // Transform eclCell - plane intersection onto fracture + + cvf::Mat4d invertedTransformMatrix = frMx.getInverted(); + for (std::vector& eclCellPolygon : eclCellPolygons) + { + for (cvf::Vec3d& v : eclCellPolygon) + { + v.transformPoint(invertedTransformMatrix); + } + + allEclCellPolygons.push_back(eclCellPolygon); + } + } + + { + std::vector> polys = + RigCellGeometryTools::subtractPolygons(borderOfFractureCellPolygonLocalCsd, allEclCellPolygons); + + for (const auto& polygon : polys) + { + clippedPolygons.push_back(polygon); + } + } + } + } + + for (auto& clippedPolygon : clippedPolygons) + { + for (auto& point : clippedPolygon) + { + point.transformPoint(frMx); + } + } + + // Create triangles from the clipped polygons + cvf::Vec3d fractureNormal = cvf::Vec3d(frMx.col(2)); + + for (const auto& clippedPolygon : clippedPolygons) + { + cvf::EarClipTesselator tess; + tess.setNormal(fractureNormal); + cvf::Vec3dArray cvfNodes(clippedPolygon); + tess.setGlobalNodeArray(cvfNodes); + std::vector polyIndexes; + for (size_t idx = 0; idx < clippedPolygon.size(); ++idx) + polyIndexes.push_back(idx); + tess.setPolygonIndices(polyIndexes); + + std::vector triangleIndices; + tess.calculateTriangles(&triangleIndices); + + for (size_t idx : triangleIndices) + { + maskTriangles.push_back(cvf::Vec3f(displCoordTrans->transformToDisplayCoord(clippedPolygon[idx]))); + } + } + } + + if (maskTriangles.size() >= 3) + { + cvf::ref maskTriangleGeo = new cvf::DrawableGeo; + maskTriangleGeo->setVertexArray(new cvf::Vec3fArray(maskTriangles)); + + cvf::ref primitives = new cvf::PrimitiveSetDirect(cvf::PT_TRIANGLES); + primitives->setIndexCount(maskTriangles.size()); + maskTriangleGeo->addPrimitiveSet(primitives.p()); + maskTriangleGeo->computeNormals(); + + cvf::ref containmentMaskPart = new cvf::Part(0, "FractureContainmentMaskPart"); + containmentMaskPart->setDrawable(maskTriangleGeo.p()); + containmentMaskPart->setSourceInfo(new RivObjectSourceInfo(m_rimFracture)); + + cvf::Color4f maskColor = cvf::Color4f(cvf::Color3f(cvf::Color3::GRAY)); + + caf::SurfaceEffectGenerator surfaceGen(maskColor, caf::PO_NONE); + cvf::ref eff = surfaceGen.generateCachedEffect(); + containmentMaskPart->setEffect(eff.p()); + + return containmentMaskPart; + } + + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RivWellFracturePartMgr::appendFracturePerforationLengthParts(const RimEclipseView& activeView, cvf::ModelBasicList* model) { @@ -797,13 +961,14 @@ void RivWellFracturePartMgr::appendFracturePerforationLengthParts(const RimEclip if (!displayCoords.empty()) { - cvf::ref objectSourceInfo = new RivObjectSourceInfo(m_rimFracture); - double perforationRadius = wellPathRadius * 1.2; - cvf::Collection parts; + cvf::ref objectSourceInfo = new RivObjectSourceInfo(m_rimFracture); + double perforationRadius = wellPathRadius * 1.2; + cvf::Collection parts; RivPipeGeometryGenerator geoGenerator; - geoGenerator.cylinderWithCenterLineParts(&parts, displayCoords, RiaColorTables::perforationLengthColor(), perforationRadius); - + geoGenerator.cylinderWithCenterLineParts( + &parts, displayCoords, RiaColorTables::wellPathComponentColors()[RiaDefines::PERFORATION_INTERVAL], perforationRadius); + for (auto part : parts) { part->setSourceInfo(objectSourceInfo.p()); @@ -813,13 +978,14 @@ void RivWellFracturePartMgr::appendFracturePerforationLengthParts(const RimEclip } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::ref RivWellFracturePartMgr::createStimPlanMeshPart(const RimEclipseView& activeView) { if (!m_rimFracture->fractureTemplate()) return nullptr; - RimStimPlanFractureTemplate* stimPlanFracTemplate = dynamic_cast(m_rimFracture->fractureTemplate()); + RimStimPlanFractureTemplate* stimPlanFracTemplate = + dynamic_cast(m_rimFracture->fractureTemplate()); if (!stimPlanFracTemplate) return nullptr; cvf::ref stimPlanMeshGeo = createStimPlanMeshDrawable(stimPlanFracTemplate, activeView); @@ -844,9 +1010,10 @@ cvf::ref RivWellFracturePartMgr::createStimPlanMeshPart(const RimEcli } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -cvf::ref RivWellFracturePartMgr::createStimPlanMeshDrawable(RimStimPlanFractureTemplate* stimPlanFracTemplate, const RimEclipseView& activeView) +cvf::ref RivWellFracturePartMgr::createStimPlanMeshDrawable(RimStimPlanFractureTemplate* stimPlanFracTemplate, + const RimEclipseView& activeView) { if (!stimPlanFracTemplate->fractureGrid()) return nullptr; @@ -854,21 +1021,20 @@ cvf::ref RivWellFracturePartMgr::createStimPlanMeshDrawable(Ri if (displayCoordTransform.isNull()) return nullptr; std::vector stimPlanCells = stimPlanFracTemplate->fractureGrid()->fractureCells(); - std::vector stimPlanMeshVertices; + std::vector stimPlanMeshVertices; QString resultNameFromColors = activeView.fractureColors()->uiResultName(); QString resultUnitFromColors = activeView.fractureColors()->unit(); - std::vector prCellResults = stimPlanFracTemplate->fractureGridResults(resultNameFromColors, - resultUnitFromColors, - stimPlanFracTemplate->activeTimeStepIndex()); + std::vector prCellResults = stimPlanFracTemplate->fractureGridResults( + resultNameFromColors, resultUnitFromColors, stimPlanFracTemplate->activeTimeStepIndex()); m_visibleFracturePolygons.clear(); - for ( size_t cIdx = 0; cIdx < stimPlanCells.size() ; ++cIdx) + for (size_t cIdx = 0; cIdx < stimPlanCells.size(); ++cIdx) { if (prCellResults[cIdx] > 1e-7) { - const RigFractureCell& stimPlanCell = stimPlanCells[cIdx]; + const RigFractureCell& stimPlanCell = stimPlanCells[cIdx]; std::vector stimPlanCellPolygon = stimPlanCell.getPolygon(); for (const cvf::Vec3d& cellCorner : stimPlanCellPolygon) { @@ -883,10 +1049,9 @@ cvf::ref RivWellFracturePartMgr::createStimPlanMeshDrawable(Ri return nullptr; } - cvf::Mat4d fractureXf = m_rimFracture->transformMatrix(); - std::vector stimPlanMeshVerticesDisplayCoords = transformToFractureDisplayCoords(stimPlanMeshVertices, - fractureXf, - *displayCoordTransform); + cvf::Mat4d fractureXf = m_rimFracture->transformMatrix(); + std::vector stimPlanMeshVerticesDisplayCoords = + transformToFractureDisplayCoords(stimPlanMeshVertices, fractureXf, *displayCoordTransform); cvf::Vec3fArray* stimPlanMeshVertexList; stimPlanMeshVertexList = new cvf::Vec3fArray; @@ -904,7 +1069,7 @@ cvf::ref RivWellFracturePartMgr::createStimPlanMeshDrawable(Ri } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::ref RivWellFracturePartMgr::createScalarMapperPart(cvf::DrawableGeo* drawableGeo, const cvf::ScalarMapper* scalarMapper, @@ -926,7 +1091,7 @@ cvf::ref RivWellFracturePartMgr::createScalarMapperPart(cvf::Drawable } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RivWellFracturePartMgr::fractureBorderPolygon() { @@ -934,11 +1099,12 @@ std::vector RivWellFracturePartMgr::fractureBorderPolygon() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RivWellFracturePartMgr::transformToFractureDisplayCoords(const std::vector& coordinatesVector, - cvf::Mat4d m, - const caf::DisplayCoordTransform& displayCoordTransform) +std::vector + RivWellFracturePartMgr::transformToFractureDisplayCoords(const std::vector& coordinatesVector, + cvf::Mat4d m, + const caf::DisplayCoordTransform& displayCoordTransform) { std::vector polygonInDisplayCoords; polygonInDisplayCoords.reserve(coordinatesVector.size()); @@ -955,16 +1121,17 @@ std::vector RivWellFracturePartMgr::transformToFractureDisplayCoords } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -cvf::ref RivWellFracturePartMgr::buildDrawableGeoFromTriangles(const std::vector& triangleIndices, const std::vector& nodeCoords) +cvf::ref RivWellFracturePartMgr::buildDrawableGeoFromTriangles(const std::vector& triangleIndices, + const std::vector& nodeCoords) { CVF_ASSERT(triangleIndices.size() > 0); CVF_ASSERT(nodeCoords.size() > 0); cvf::ref geo = new cvf::DrawableGeo; - cvf::ref indices = new cvf::UIntArray(triangleIndices); + cvf::ref indices = new cvf::UIntArray(triangleIndices); cvf::ref vertices = new cvf::Vec3fArray(nodeCoords); geo->setVertexArray(vertices.p()); @@ -974,3 +1141,41 @@ cvf::ref RivWellFracturePartMgr::buildDrawableGeoFromTriangles return geo; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RivWellFracturePartMgr::createLocalTransformFromTranslation(const cvf::Vec3d& translation) +{ + cvf::Mat4d m = cvf::Mat4d::fromTranslation(translation); + + cvf::ref partTransform = new cvf::Transform; + partTransform->setLocalTransform(m); + + return partTransform; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivWellFracturePartMgr::addPartAtPositiveAndNegativeTranslation(cvf::ModelBasicList* model, + cvf::Part* part, + const cvf::Vec3d& translation) +{ + { + cvf::ref partTransform = RivWellFracturePartMgr::createLocalTransformFromTranslation(translation); + + part->setTransform(partTransform.p()); + model->addPart(part); + } + + { + // Create a copy of the part to be able to assign a transformation matrix representing the translation in the opposite + // direction + + cvf::ref partTransform = RivWellFracturePartMgr::createLocalTransformFromTranslation(-translation); + + auto copy = part->shallowCopy(); + copy->setTransform(partTransform.p()); + model->addPart(copy.p()); + } +} diff --git a/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.h b/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.h index ca1d41b1c2..57cf7bc444 100644 --- a/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellFracturePartMgr.h @@ -35,6 +35,7 @@ namespace cvf class Part; class Color3f; class ScalarMapper; + class Transform; } namespace caf @@ -55,7 +56,7 @@ class RivWellFracturePartMgr : public cvf::Object { public: RivWellFracturePartMgr(RimFracture* well); - ~RivWellFracturePartMgr(); + ~RivWellFracturePartMgr() override; void appendGeometryPartsToModel(cvf::ModelBasicList* model, const RimEclipseView& eclView); @@ -72,6 +73,7 @@ class RivWellFracturePartMgr : public cvf::Object cvf::ref createStimPlanElementColorSurfacePart(const RimEclipseView& activeView); cvf::ref createContainmentMaskPart(const RimEclipseView& activeView); + cvf::ref createMaskOfFractureOutsideGrid(const RimEclipseView& activeView); void appendFracturePerforationLengthParts(const RimEclipseView& activeView, cvf::ModelBasicList* model); @@ -87,6 +89,9 @@ class RivWellFracturePartMgr : public cvf::Object const caf::DisplayCoordTransform& displayCoordTransform); static cvf::ref buildDrawableGeoFromTriangles(const std::vector& triangleIndices, const std::vector& nodeCoords); + + static cvf::ref createLocalTransformFromTranslation(const cvf::Vec3d& translation); + static void addPartAtPositiveAndNegativeTranslation(cvf::ModelBasicList* model, cvf::Part* part, const cvf::Vec3d& translation); private: caf::PdmPointer m_rimFracture; diff --git a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.h b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.h index c44ea15f6d..b8dcf56a3e 100644 --- a/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellHeadPartMgr.h @@ -43,7 +43,7 @@ class RivWellHeadPartMgr : public cvf::Object { public: RivWellHeadPartMgr( RimSimWellInView* well); - ~RivWellHeadPartMgr(); + ~RivWellHeadPartMgr() override; void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex, diff --git a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp index 4a45594996..235348e9c6 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.cpp @@ -38,7 +38,10 @@ #include "RimPerforationCollection.h" #include "RimPerforationInterval.h" #include "RimWellPath.h" +#include "RimWellPathAttribute.h" +#include "RimWellPathAttributeCollection.h" #include "RimWellPathCollection.h" +#include "RimWellPathValve.h" #include "RimWellPathFractureCollection.h" #include "RimWellPathFracture.h" @@ -135,7 +138,7 @@ void RivWellPathPartMgr::appendStaticFracturePartsToModel(cvf::ModelBasicList* if (!isWellPathWithinBoundingBox(wellPathClipBoundingBox)) return; - for (RimWellPathFracture* f : m_rimWellPath->fractureCollection()->fractures()) + for (RimWellPathFracture* f : m_rimWellPath->fractureCollection()->activeFractures()) { CVF_ASSERT(f); @@ -152,13 +155,90 @@ void RivWellPathPartMgr::appendFishboneSubsPartsToModel(cvf::ModelBasicList* mod { if ( !m_rimWellPath || !m_rimWellPath->fishbonesCollection()->isChecked() ) return; - for (const auto& rimFishboneSubs : m_rimWellPath->fishbonesCollection()->fishbonesSubs() ) + for (const auto& rimFishboneSubs : m_rimWellPath->fishbonesCollection()->activeFishbonesSubs() ) { cvf::ref fishbSubPartMgr = new RivFishbonesSubsPartMgr(rimFishboneSubs); fishbSubPartMgr->appendGeometryPartsToModel(model, displayCoordTransform, characteristicCellSize); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivWellPathPartMgr::appendWellPathAttributesToModel(cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayCoordTransform, + double characteristicCellSize) +{ + if (!m_rimWellPath) return; + + RivPipeGeometryGenerator geoGenerator; + std::vector attributes = m_rimWellPath->attributeCollection()->attributes(); + + for (RimWellPathAttribute* attribute : attributes) + { + if (attribute->isEnabled()) + { + if (attribute->componentType() == RiaDefines::CASING) + { + double wellPathRadius = this->wellPathRadius(characteristicCellSize, this->wellPathCollection()); + double endMD = attribute->endMD(); + double shoeLength = wellPathRadius; + double shoeStartMD = endMD - shoeLength; + + std::vector displayCoords; + displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(shoeStartMD))); + displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMD))); + displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMD))); + + std::vector radii; + radii.push_back(wellPathRadius); + radii.push_back(wellPathRadius * 2.5); + radii.push_back(wellPathRadius * 1.1); + + cvf::ref objectSourceInfo = new RivObjectSourceInfo(attribute); + + cvf::Collection parts; + geoGenerator.tubeWithCenterLinePartsAndVariableWidth(&parts, displayCoords, radii, attribute->defaultComponentColor()); + for (auto part : parts) + { + part->setSourceInfo(objectSourceInfo.p()); + model->addPart(part.p()); + } + } + else if (attribute->componentType() == RiaDefines::PACKER) + { + double wellPathRadius = this->wellPathRadius(characteristicCellSize, this->wellPathCollection()); + double startMD = attribute->startMD(); + double endMD = attribute->endMD(); + + std::vector displayCoords; + displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(startMD))); + displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(startMD))); + displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMD))); + displayCoords.push_back(displayCoordTransform->transformToDisplayCoord(m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(endMD))); + + std::vector radii; + radii.push_back(wellPathRadius); + radii.push_back(wellPathRadius * 1.5); + radii.push_back(wellPathRadius * 1.5); + radii.push_back(wellPathRadius); + + cvf::ref objectSourceInfo = new RivObjectSourceInfo(attribute); + + cvf::Collection parts; + geoGenerator.tubeWithCenterLinePartsAndVariableWidth(&parts, displayCoords, radii, attribute->defaultComponentColor()); + for (auto part : parts) + { + part->setSourceInfo(objectSourceInfo.p()); + model->addPart(part.p()); + } + } + } + } +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -282,15 +362,117 @@ void RivWellPathPartMgr::appendPerforationsToModel(cvf::ModelBasicList* model, perfIntervalCLDiplayCS.push_back( displayCoordTransform->transformToDisplayCoord(point)); } } + { + cvf::ref objectSourceInfo = new RivObjectSourceInfo(perforation); - cvf::ref objectSourceInfo = new RivObjectSourceInfo(perforation); + cvf::Collection parts; + geoGenerator.cylinderWithCenterLineParts(&parts, perfIntervalCLDiplayCS, cvf::Color3f::GREEN, perforationRadius); + for (auto part : parts) + { + part->setSourceInfo(objectSourceInfo.p()); + model->addPart(part.p()); + } + } - cvf::Collection parts; - geoGenerator.cylinderWithCenterLineParts(&parts, perfIntervalCLDiplayCS, cvf::Color3f::GREEN, perforationRadius); - for (auto part : parts) + appendPerforationValvesToModel(model, perforation, wellPathRadius, displayCoordTransform, geoGenerator); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivWellPathPartMgr::appendPerforationValvesToModel(cvf::ModelBasicList* model, RimPerforationInterval* perforation, double wellPathRadius, const caf::DisplayCoordTransform* displayCoordTransform, RivPipeGeometryGenerator &geoGenerator) +{ + // Valves + { + for (RimWellPathValve* valve : perforation->valves()) { - part->setSourceInfo(objectSourceInfo.p()); - model->addPart(part.p()); + if (!valve->isChecked()) continue; + + std::vector measuredDepthsRelativeToStartMD; + std::vector radii; + cvf::Color3f valveColor = valve->defaultComponentColor(); + if (valve->componentType() == RiaDefines::ICV) + { + measuredDepthsRelativeToStartMD = { 0.0, 1.0, 1.5, 4.0, 5.0, 5.5, 8.0, 9.0 }; + radii = { wellPathRadius, wellPathRadius * 1.8, wellPathRadius * 2.0, + wellPathRadius * 2.0, wellPathRadius * 1.8, + wellPathRadius * 1.7, wellPathRadius * 1.7, wellPathRadius }; + + double startMD = valve->startMD(); + std::vector displayCoords; + for (double mdRelativeToStart : measuredDepthsRelativeToStartMD) + { + displayCoords.push_back(displayCoordTransform->transformToDisplayCoord( + m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(mdRelativeToStart * 0.333 * wellPathRadius + startMD))); + } + + cvf::ref objectSourceInfo = new RivObjectSourceInfo(valve); + + cvf::Collection parts; + geoGenerator.tubeWithCenterLinePartsAndVariableWidth(&parts, displayCoords, radii, valveColor); + for (auto part : parts) + { + part->setSourceInfo(objectSourceInfo.p()); + model->addPart(part.p()); + } + } + else if (valve->componentType() == RiaDefines::ICD || valve->componentType() == RiaDefines::AICD) + { + std::vector valveLocations = valve->valveLocations(); + for (double startMD : valveLocations) + { + int size = 16; + + measuredDepthsRelativeToStartMD.resize(size); + radii.resize(size); + for (int i = 0; i < size; i += 2) + { + measuredDepthsRelativeToStartMD[i] = double(i / 2); + measuredDepthsRelativeToStartMD[i + 1] = double(i / 2 + 0.5); + } + radii[0] = wellPathRadius; + bool inner = false; + int nInners = 0; + for (int i = 1; i < size - 1; i += 2) + { + if (inner && valve->componentType() == RiaDefines::AICD && nInners > 0) + { + radii[i + 1] = radii[i] = wellPathRadius * 1.7; + nInners = 0; + } + else if (inner) + { + radii[i + 1] = radii[i] = wellPathRadius * 1.9; + nInners++; + } + else + { + radii[i + 1] = radii[i] = wellPathRadius * 2.0; + } + inner = !inner; + } + radii[size - 1] = wellPathRadius; + + std::vector displayCoords; + for (double mdRelativeToStart : measuredDepthsRelativeToStartMD) + { + displayCoords.push_back(displayCoordTransform->transformToDisplayCoord( + m_rimWellPath->wellPathGeometry()->interpolatedPointAlongWellPath(mdRelativeToStart * 0.333 * wellPathRadius + startMD))); + } + + cvf::ref objectSourceInfo = new RivObjectSourceInfo(valve); + + cvf::Collection parts; + geoGenerator.tubeWithCenterLinePartsAndVariableWidth(&parts, displayCoords, radii, valveColor); + for (auto part : parts) + { + part->setSourceInfo(objectSourceInfo.p()); + model->addPart(part.p()); + } + } + } + } } } @@ -502,12 +684,13 @@ void RivWellPathPartMgr::appendStaticGeometryPartsToModel(cvf::ModelBasicList* appendFishboneSubsPartsToModel(model, displayCoordTransform, characteristicCellSize); appendImportedFishbonesToModel(model, displayCoordTransform, characteristicCellSize); + appendWellPathAttributesToModel(model, displayCoordTransform, characteristicCellSize); RimGridView* gridView = dynamic_cast(m_rimView.p()); if (!gridView) return; + m_3dWellLogPlanePartMgr = new Riv3dWellLogPlanePartMgr(m_rimWellPath, gridView); + m_3dWellLogPlanePartMgr->appendPlaneToModel(model, displayCoordTransform, wellPathClipBoundingBox, true); - m_3dWellLogPlanePartMgr = new Riv3dWellLogPlanePartMgr(m_rimWellPath, gridView); - m_3dWellLogPlanePartMgr->appendPlaneToModel(model, displayCoordTransform, wellPathClipBoundingBox); } //-------------------------------------------------------------------------------------------------- @@ -566,6 +749,16 @@ void RivWellPathPartMgr::appendDynamicGeometryPartsToModel(cvf::ModelBasicList* appendPerforationsToModel(model, timeStepIndex, displayCoordTransform, characteristicCellSize, false); appendVirtualTransmissibilitiesToModel(model, timeStepIndex, displayCoordTransform, characteristicCellSize); + + RimGridView* gridView = dynamic_cast(m_rimView.p()); + if (!gridView) return; + + if (m_3dWellLogPlanePartMgr.isNull()) + { + m_3dWellLogPlanePartMgr = new Riv3dWellLogPlanePartMgr(m_rimWellPath, gridView); + } + m_3dWellLogPlanePartMgr->appendPlaneToModel(model, displayCoordTransform, wellPathClipBoundingBox, false); + } //-------------------------------------------------------------------------------------------------- @@ -605,7 +798,7 @@ void RivWellPathPartMgr::clearAllBranchData() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellPathCollection* RivWellPathPartMgr::wellPathCollection() +RimWellPathCollection* RivWellPathPartMgr::wellPathCollection() const { if (!m_rimWellPath) return nullptr; diff --git a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h index 39195027a2..1b8a95ba64 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellPathPartMgr.h @@ -43,6 +43,7 @@ class RivPipeGeometryGenerator; class RimProject; class RimWellPath; class RivFishbonesSubsPartMgr; +class RimPerforationInterval; class RimWellPathCollection; class Rim3dView; class Riv3dWellLogPlanePartMgr; @@ -57,7 +58,7 @@ class RivWellPathPartMgr : public cvf::Object { public: explicit RivWellPathPartMgr(RimWellPath* wellPath, Rim3dView* view); - ~RivWellPathPartMgr(); + ~RivWellPathPartMgr() override; void appendStaticGeometryPartsToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform, @@ -88,6 +89,10 @@ class RivWellPathPartMgr : public cvf::Object const caf::DisplayCoordTransform* displayCoordTransform, double characteristicCellSize); + void appendWellPathAttributesToModel(cvf::ModelBasicList* model, + const caf::DisplayCoordTransform* displayCoordTransform, + double characteristicCellSize); + void appendImportedFishbonesToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform, double characteristicCellSize); @@ -98,6 +103,12 @@ class RivWellPathPartMgr : public cvf::Object double characteristicCellSize, bool doFlatten); + void appendPerforationValvesToModel(cvf::ModelBasicList* model, + RimPerforationInterval* perforation, + double wellPathRadius, + const caf::DisplayCoordTransform* displayCoordTransform, + RivPipeGeometryGenerator& geoGenerator); + void appendVirtualTransmissibilitiesToModel(cvf::ModelBasicList* model, size_t timeStepIndex, const caf::DisplayCoordTransform* displayCoordTransform, @@ -110,7 +121,7 @@ class RivWellPathPartMgr : public cvf::Object void clearAllBranchData(); - inline RimWellPathCollection* wellPathCollection(); + inline RimWellPathCollection* wellPathCollection() const; inline double wellPathRadius(double characteristicCellSize, RimWellPathCollection* wellPathCollection); bool isWellPathWithinBoundingBox(const cvf::BoundingBox& wellPathClipBoundingBox) const; diff --git a/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.cpp b/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.cpp index 1890ad3b90..7c6dffaf08 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.cpp @@ -61,12 +61,12 @@ RimWellPath* RivWellPathSourceInfo::wellPath() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RivWellPathSourceInfo::measuredDepth(size_t triangleIndex, const cvf::Vec3d& globalIntersection) const +double RivWellPathSourceInfo::measuredDepth(size_t triangleIndex, const cvf::Vec3d& globalIntersectionInDomain) const { size_t firstSegmentIndex = cvf::UNDEFINED_SIZE_T; double norm = 0.0; - normalizedIntersection(triangleIndex, globalIntersection, &firstSegmentIndex, &norm); + normalizedIntersection(triangleIndex, globalIntersectionInDomain, &firstSegmentIndex, &norm); double firstDepth = m_wellPath->wellPathGeometry()->m_measuredDepths[firstSegmentIndex]; double secDepth = m_wellPath->wellPathGeometry()->m_measuredDepths[firstSegmentIndex + 1]; @@ -77,12 +77,12 @@ double RivWellPathSourceInfo::measuredDepth(size_t triangleIndex, const cvf::Vec //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::Vec3d RivWellPathSourceInfo::closestPointOnCenterLine(size_t triangleIndex, const cvf::Vec3d& globalIntersection) const +cvf::Vec3d RivWellPathSourceInfo::closestPointOnCenterLine(size_t triangleIndex, const cvf::Vec3d& globalIntersectionInDomain) const { size_t firstSegmentIndex = cvf::UNDEFINED_SIZE_T; double norm = 0.0; - normalizedIntersection(triangleIndex, globalIntersection, &firstSegmentIndex, &norm); + normalizedIntersection(triangleIndex, globalIntersectionInDomain, &firstSegmentIndex, &norm); cvf::Vec3d firstDepth = m_wellPath->wellPathGeometry()->m_wellPathPoints[firstSegmentIndex]; cvf::Vec3d secDepth = m_wellPath->wellPathGeometry()->m_wellPathPoints[firstSegmentIndex + 1]; @@ -93,18 +93,17 @@ cvf::Vec3d RivWellPathSourceInfo::closestPointOnCenterLine(size_t triangleIndex, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RivWellPathSourceInfo::normalizedIntersection(size_t triangleIndex, const cvf::Vec3d& globalIntersection, +void RivWellPathSourceInfo::normalizedIntersection(size_t triangleIndex, const cvf::Vec3d& globalIntersectionInDomain, size_t* firstSegmentIndex, double* normalizedSegmentIntersection) const { size_t segIndex = segmentIndex(triangleIndex); - RigWellPath* rigWellPath = m_wellPath->wellPathGeometry(); cvf::Vec3d segmentStart = rigWellPath->m_wellPathPoints[segIndex]; cvf::Vec3d segmentEnd = rigWellPath->m_wellPathPoints[segIndex + 1]; double norm = 0.0; - cvf::Vec3d pointOnLine = cvf::GeometryTools::projectPointOnLine(segmentStart, segmentEnd, globalIntersection, &norm); + cvf::Vec3d pointOnLine = cvf::GeometryTools::projectPointOnLine(segmentStart, segmentEnd, globalIntersectionInDomain, &norm); norm = cvf::Math::clamp(norm, 0.0, 1.0); *firstSegmentIndex = segIndex; diff --git a/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.h b/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.h index 563a1613a8..e0b3fbb99c 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.h +++ b/ApplicationCode/ModelVisualization/RivWellPathSourceInfo.h @@ -35,17 +35,17 @@ class RivWellPathSourceInfo : public cvf::Object { public: explicit RivWellPathSourceInfo(RimWellPath* wellPath, RivPipeGeometryGenerator* pipeGeomGenerator); - ~RivWellPathSourceInfo(); + ~RivWellPathSourceInfo() override; RimWellPath* wellPath() const; size_t segmentIndex(size_t triangleIndex) const; - double measuredDepth(size_t triangleIndex, const cvf::Vec3d& globalIntersection) const; - cvf::Vec3d closestPointOnCenterLine(size_t triangleIndex, const cvf::Vec3d& globalIntersection) const; + double measuredDepth(size_t triangleIndex, const cvf::Vec3d& globalIntersectionInDomain) const; + cvf::Vec3d closestPointOnCenterLine(size_t triangleIndex, const cvf::Vec3d& globalIntersectionInDomain) const; private: void normalizedIntersection(size_t triangleIndex, - const cvf::Vec3d& globalIntersection, + const cvf::Vec3d& globalIntersectionInDomain, size_t* firstSegmentIndex, double* normalizedSegmentIntersection) const; diff --git a/ApplicationCode/ModelVisualization/RivWellPathsPartMgr.cpp b/ApplicationCode/ModelVisualization/RivWellPathsPartMgr.cpp index 38cac4d069..bd026d013a 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathsPartMgr.cpp +++ b/ApplicationCode/ModelVisualization/RivWellPathsPartMgr.cpp @@ -21,8 +21,8 @@ #include "RiaApplication.h" #include "RimEclipseView.h" -#include "RimOilField.h" #include "RimProject.h" +#include "RimTools.h" #include "RimWellPathCollection.h" #include "RivWellPathPartMgr.h" @@ -129,22 +129,12 @@ void RivWellPathsPartMgr::createPartManagersIfRequired() } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPathCollection* RivWellPathsPartMgr::wellPathCollection() const -{ - RimProject* proj = RiaApplication::instance()->project(); - - return proj->activeOilField()->wellPathCollection(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RivWellPathsPartMgr::isWellPathVisible() const { - auto wellPathColl = wellPathCollection(); + auto wellPathColl = RimTools::wellPathCollection(); if (!wellPathColl->isActive()) return false; if (wellPathColl->wellPathVisibility() == RimWellPathCollection::FORCE_ALL_OFF) return false; diff --git a/ApplicationCode/ModelVisualization/RivWellPathsPartMgr.h b/ApplicationCode/ModelVisualization/RivWellPathsPartMgr.h index c3dbd73d8c..6df0845eb8 100644 --- a/ApplicationCode/ModelVisualization/RivWellPathsPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellPathsPartMgr.h @@ -42,7 +42,6 @@ class DisplayCoordTransform; class Rim3dView; class RivWellPathPartMgr; -class RimWellPathCollection; class RimWellPath; //-------------------------------------------------------------------------------------------------- @@ -52,7 +51,7 @@ class RivWellPathsPartMgr : public cvf::Object { public: explicit RivWellPathsPartMgr(Rim3dView* view); - ~RivWellPathsPartMgr(); + ~RivWellPathsPartMgr() override; void appendStaticGeometryPartsToModel(cvf::ModelBasicList* model, const caf::DisplayCoordTransform* displayCoordTransform, @@ -72,7 +71,6 @@ class RivWellPathsPartMgr : public cvf::Object void clearGeometryCache(); void scheduleGeometryRegen(); void createPartManagersIfRequired(); - RimWellPathCollection* wellPathCollection() const; bool isWellPathVisible() const; private: diff --git a/ApplicationCode/ModelVisualization/RivWellSpheresPartMgr.h b/ApplicationCode/ModelVisualization/RivWellSpheresPartMgr.h index 4f1bb04921..209090c207 100644 --- a/ApplicationCode/ModelVisualization/RivWellSpheresPartMgr.h +++ b/ApplicationCode/ModelVisualization/RivWellSpheresPartMgr.h @@ -50,7 +50,7 @@ class RivWellSpheresPartMgr : public cvf::Object { public: RivWellSpheresPartMgr(RimEclipseView* reservoirView, RimSimWellInView* well); - ~RivWellSpheresPartMgr(); + ~RivWellSpheresPartMgr() override; void appendDynamicGeometryPartsToModel(cvf::ModelBasicList* model, size_t frameIndex); diff --git a/ApplicationCode/ModelVisualization/WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.cpp b/ApplicationCode/ModelVisualization/WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.cpp index 666ccd0cf8..df91fe269e 100644 --- a/ApplicationCode/ModelVisualization/WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.cpp +++ b/ApplicationCode/ModelVisualization/WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.cpp @@ -62,13 +62,15 @@ using namespace cvf; /// Constructor //-------------------------------------------------------------------------------------------------- RivWindowEdgeAxesOverlayItem::RivWindowEdgeAxesOverlayItem(Font* font) -: m_windowSize(600, 600), - m_textColor(Color3::BLACK), - m_lineColor(Color3::BLACK), - m_frameColor(Color3::WHITE), - m_lineWidth(1), - m_font(font), - m_isSwitchingYAxisValueSign(true) + : m_windowSize(600, 600) + , m_textColor(Color3::BLACK) + , m_lineColor(Color3::BLACK) + , m_frameColor(Color3::WHITE) + , m_lineWidth(1) + , m_font(font) + , m_isSwitchingYAxisValueSign(true) + , m_showAxisLines(false) + , m_domainAxes(XZ_AXES) { CVF_ASSERT(font); CVF_ASSERT(!font->isEmpty()); @@ -99,9 +101,9 @@ void RivWindowEdgeAxesOverlayItem::setDisplayCoordTransform(const caf::DisplayCo //-------------------------------------------------------------------------------------------------- void RivWindowEdgeAxesOverlayItem::updateGeomerySizes() { - String str = String::number(99999.0); + String str = String::number(-1.999e-17); m_textSize = m_font->textExtent(str); - m_pixelSpacing = 2.0f; + m_pixelSpacing = 5.0f; m_tickLineLength = m_textSize.y() *0.3f; m_frameBorderHeight = m_pixelSpacing + m_textSize.y() + m_pixelSpacing + m_tickLineLength + m_lineWidth; m_frameBorderWidth = m_pixelSpacing + m_textSize.x() + m_pixelSpacing + m_tickLineLength + m_lineWidth; @@ -137,8 +139,8 @@ void RivWindowEdgeAxesOverlayItem::updateFromCamera(const Camera* camera) double domainMinX = windowOrigoInDomain.x(); double domainMaxX = windowMaxInDomain.x(); - double domainMinY = windowOrigoInDomain.z(); - double domainMaxY = windowMaxInDomain.z(); + double domainMinY = m_domainAxes == XY_AXES ? windowOrigoInDomain.y() : windowOrigoInDomain.z(); + double domainMaxY = m_domainAxes == XY_AXES ? windowMaxInDomain.y() : windowMaxInDomain.z(); int xTickMaxCount = m_windowSize.x()/(2*m_textSize.x()); int yTickMaxCount = m_windowSize.y()/(2*m_textSize.x()); @@ -156,7 +158,15 @@ void RivWindowEdgeAxesOverlayItem::updateFromCamera(const Camera* camera) Vec3d windowPoint; for (double domainX : m_domainCoordsXValues) { - Vec3d displayDomainTick(domainX, 0, domainMinY); + Vec3d displayDomainTick; + if (m_domainAxes == XY_AXES) + { + displayDomainTick = Vec3d(domainX, domainMinY, 0); + } + else + { + displayDomainTick = Vec3d(domainX, 0, domainMinY); + } if ( m_dispalyCoordsTransform.notNull() ) { displayDomainTick = m_dispalyCoordsTransform->transformToDisplayCoord(displayDomainTick); @@ -168,7 +178,17 @@ void RivWindowEdgeAxesOverlayItem::updateFromCamera(const Camera* camera) m_windowTickYValues.clear(); for (double domainY : m_domainCoordsYValues) { - Vec3d displayDomainTick(domainMinX, 0, domainY); + Vec3d displayDomainTick; + + if (m_domainAxes == XY_AXES) + { + displayDomainTick = Vec3d(domainMinX, domainY, 0); + } + else + { + displayDomainTick = Vec3d(domainMinX, 0, domainY); + } + if ( m_dispalyCoordsTransform.notNull() ) { displayDomainTick = m_dispalyCoordsTransform->transformToDisplayCoord(displayDomainTick); @@ -291,7 +311,7 @@ void RivWindowEdgeAxesOverlayItem::addTextToTextDrawer(TextDrawer* textDrawer) double tickValue = m_domainCoordsXValues[i]; String valueString; - valueString = String::number(tickValue); + valueString = String::number(tickValue, 'f', 0); auto labelSize = m_font->textExtent(valueString); Vec2f pos(textX - labelSize.x()*0.5f, textYBott); @@ -315,7 +335,7 @@ void RivWindowEdgeAxesOverlayItem::addTextToTextDrawer(TextDrawer* textDrawer) double tickValue = m_isSwitchingYAxisValueSign ? -m_domainCoordsYValues[i]: m_domainCoordsYValues[i]; String valueString; - valueString = String::number(tickValue); + valueString = String::number(tickValue, 'f', 0); auto labelSize = m_font->textExtent(valueString); Vec2f pos(textXRight, textY); @@ -404,7 +424,8 @@ void RivWindowEdgeAxesOverlayItem::renderSoftwareFrameAndTickLines(OpenGLContext // Render Line around { - glColor3fv(m_lineColor.ptr()); + cvf::Color4f lineColorWithAlpha(m_lineColor, m_showAxisLines ? 0.25f : 1.0f); + glColor4fv(lineColorWithAlpha.ptr()); glBegin(GL_LINES); // Frame lines glVertex3fv(vertexArray[7].ptr()); @@ -419,47 +440,79 @@ void RivWindowEdgeAxesOverlayItem::renderSoftwareFrameAndTickLines(OpenGLContext // X - axis Tick lines for (double txpos : m_windowTickXValues) { - Vec3f p1(Vec3f::ZERO); - Vec3f p2(Vec3f::ZERO); - - p1[0] = (float)txpos; - p1[1] = m_frameBorderHeight; - p2[0] = (float)txpos; - p2[1] = m_frameBorderHeight - m_tickLineLength; - - glVertex3fv(p1.ptr()); - glVertex3fv(p2.ptr()); - - p1[0] = (float)txpos; - p1[1] = m_windowSize.y() - m_frameBorderHeight; - p2[0] = (float)txpos; - p2[1] = m_windowSize.y() - m_frameBorderHeight + m_tickLineLength; - - glVertex3fv(p1.ptr()); - glVertex3fv(p2.ptr()); + if (m_showAxisLines) + { + Vec3f p1(Vec3f::ZERO); + Vec3f p2(Vec3f::ZERO); + + p1[0] = (float)txpos; + p1[1] = m_frameBorderHeight - m_tickLineLength; + p2[0] = (float)txpos; + p2[1] = m_windowSize.y() - m_frameBorderHeight + m_tickLineLength; + + glVertex3fv(p1.ptr()); + glVertex3fv(p2.ptr()); + } + else + { + Vec3f p1(Vec3f::ZERO); + Vec3f p2(Vec3f::ZERO); + + p1[0] = (float)txpos; + p1[1] = m_frameBorderHeight; + p2[0] = (float)txpos; + p2[1] = m_frameBorderHeight - m_tickLineLength; + + glVertex3fv(p1.ptr()); + glVertex3fv(p2.ptr()); + + p1[0] = (float)txpos; + p1[1] = m_windowSize.y() - m_frameBorderHeight; + p2[0] = (float)txpos; + p2[1] = m_windowSize.y() - m_frameBorderHeight + m_tickLineLength; + + glVertex3fv(p1.ptr()); + glVertex3fv(p2.ptr()); + } } // Left Y - axis Tick lines for (double typos : m_windowTickYValues) { - Vec3f p1(Vec3f::ZERO); - Vec3f p2(Vec3f::ZERO); - - p1[0] = m_frameBorderWidth; - p1[1] = (float)typos; - p2[0] = m_frameBorderWidth - m_tickLineLength; - p2[1] = (float)typos; - - glVertex3fv(p1.ptr()); - glVertex3fv(p2.ptr()); - - p1[0] = m_windowSize.x() - m_frameBorderWidth; - p1[1] = (float)typos; - p2[0] = m_windowSize.x() - m_frameBorderWidth + m_tickLineLength; - p2[1] = (float)typos; - - glVertex3fv(p1.ptr()); - glVertex3fv(p2.ptr()); + if (m_showAxisLines) + { + Vec3f p1(Vec3f::ZERO); + Vec3f p2(Vec3f::ZERO); + + p1[0] = m_frameBorderWidth - m_tickLineLength; + p1[1] = (float)typos; + p2[0] = m_windowSize.x() - m_frameBorderWidth + m_tickLineLength; + p2[1] = (float)typos; + + glVertex3fv(p1.ptr()); + glVertex3fv(p2.ptr()); + } + else + { + Vec3f p1(Vec3f::ZERO); + Vec3f p2(Vec3f::ZERO); + + p1[0] = m_frameBorderWidth; + p1[1] = (float)typos; + p2[0] = m_frameBorderWidth - m_tickLineLength; + p2[1] = (float)typos; + + glVertex3fv(p1.ptr()); + glVertex3fv(p2.ptr()); + + p1[0] = m_windowSize.x() - m_frameBorderWidth; + p1[1] = (float)typos; + p2[0] = m_windowSize.x() - m_frameBorderWidth + m_tickLineLength; + p2[1] = (float)typos; + + glVertex3fv(p1.ptr()); + glVertex3fv(p2.ptr()); + } } glEnd(); @@ -528,7 +581,7 @@ void RivWindowEdgeAxesOverlayItem::renderShaderFrameAndTickLines(OpenGLContext* // Draw frame border lines - UniformFloat uniformColor("u_color", Color4f(m_lineColor)); + UniformFloat uniformColor("u_color", Color4f(m_lineColor, m_showAxisLines ? 0.25f : 1.0f)); shaderProgram->applyUniform(oglContext, uniformColor); static const ushort frameLineIndices[] = { 7, 4, @@ -546,38 +599,62 @@ void RivWindowEdgeAxesOverlayItem::renderShaderFrameAndTickLines(OpenGLContext* for (double txpos : m_windowTickXValues) { - vertexArray[0][0] = (float)txpos; - vertexArray[0][1] = m_frameBorderHeight; - vertexArray[1][0] = (float)txpos; - vertexArray[1][1] = m_frameBorderHeight - m_tickLineLength; + if (m_showAxisLines) + { + vertexArray[0][0] = (float)txpos; + vertexArray[0][1] = m_frameBorderHeight - m_tickLineLength; + vertexArray[1][0] = (float)txpos; + vertexArray[1][1] = m_windowSize.y() - m_frameBorderHeight + m_tickLineLength; - glDrawRangeElements(GL_LINES, 0, 1, 2, GL_UNSIGNED_SHORT, tickLineIndices); + glDrawRangeElements(GL_LINES, 0, 1, 2, GL_UNSIGNED_SHORT, tickLineIndices); + } + else + { + vertexArray[0][0] = (float)txpos; + vertexArray[0][1] = m_frameBorderHeight; + vertexArray[1][0] = (float)txpos; + vertexArray[1][1] = m_frameBorderHeight - m_tickLineLength; - vertexArray[0][0] = (float)txpos; - vertexArray[0][1] = m_windowSize.y() - m_frameBorderHeight; - vertexArray[1][0] = (float)txpos; - vertexArray[1][1] = m_windowSize.y() - m_frameBorderHeight + m_tickLineLength; + glDrawRangeElements(GL_LINES, 0, 1, 2, GL_UNSIGNED_SHORT, tickLineIndices); - glDrawRangeElements(GL_LINES, 0, 1, 2, GL_UNSIGNED_SHORT, tickLineIndices); + vertexArray[0][0] = (float)txpos; + vertexArray[0][1] = m_windowSize.y() - m_frameBorderHeight; + vertexArray[1][0] = (float)txpos; + vertexArray[1][1] = m_windowSize.y() - m_frameBorderHeight + m_tickLineLength; + + glDrawRangeElements(GL_LINES, 0, 1, 2, GL_UNSIGNED_SHORT, tickLineIndices); + } } // Left Y - axis Tick lines for (double typos : m_windowTickYValues) { - vertexArray[0][0] = m_frameBorderWidth; - vertexArray[0][1] = (float)typos; - vertexArray[1][0] = m_frameBorderWidth - m_tickLineLength; - vertexArray[1][1] = (float)typos; + if (m_showAxisLines) + { + vertexArray[0][0] = m_frameBorderWidth - m_tickLineLength; + vertexArray[0][1] = (float)typos; + vertexArray[1][0] = m_windowSize.x() - m_frameBorderWidth + m_tickLineLength; + vertexArray[1][1] = (float)typos; + glDrawRangeElements(GL_LINES, 0, 1, 2, GL_UNSIGNED_SHORT, tickLineIndices); + + } + else + { + vertexArray[0][0] = m_frameBorderWidth; + vertexArray[0][1] = (float)typos; + vertexArray[1][0] = m_frameBorderWidth - m_tickLineLength; + vertexArray[1][1] = (float)typos; - glDrawRangeElements(GL_LINES, 0, 1, 2, GL_UNSIGNED_SHORT, tickLineIndices); + glDrawRangeElements(GL_LINES, 0, 1, 2, GL_UNSIGNED_SHORT, tickLineIndices); - vertexArray[0][0] = m_windowSize.x() - m_frameBorderWidth; - vertexArray[0][1] = (float)typos; - vertexArray[1][0] = m_windowSize.x() - m_frameBorderWidth + m_tickLineLength; - vertexArray[1][1] = (float)typos; + vertexArray[0][0] = m_windowSize.x() - m_frameBorderWidth; + vertexArray[0][1] = (float)typos; + vertexArray[1][0] = m_windowSize.x() - m_frameBorderWidth + m_tickLineLength; + vertexArray[1][1] = (float)typos; - glDrawRangeElements(GL_LINES, 0, 1, 2, GL_UNSIGNED_SHORT, tickLineIndices); + glDrawRangeElements(GL_LINES, 0, 1, 2, GL_UNSIGNED_SHORT, tickLineIndices); + } } glDisableVertexAttribArray(ShaderProgram::VERTEX); @@ -614,3 +691,27 @@ const Color3f& RivWindowEdgeAxesOverlayItem::lineColor() const return m_lineColor; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivWindowEdgeAxesOverlayItem::setDomainAxes(DomainAxes axes) +{ + m_domainAxes = axes; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivWindowEdgeAxesOverlayItem::setIsSwitchingYAxisSign(bool switchSign) +{ + m_isSwitchingYAxisValueSign = switchSign; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RivWindowEdgeAxesOverlayItem::setShowAxisLines(bool showAxisLines) +{ + m_showAxisLines = showAxisLines; +} + diff --git a/ApplicationCode/ModelVisualization/WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.h b/ApplicationCode/ModelVisualization/WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.h index 8aefe6a6b4..e8705bf39c 100644 --- a/ApplicationCode/ModelVisualization/WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.h +++ b/ApplicationCode/ModelVisualization/WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.h @@ -82,8 +82,15 @@ class RivWindowEdgeAxesOverlayItem : public cvf::OverlayItem using TextDrawer = cvf::TextDrawer; using Camera = cvf::Camera; public: + enum DomainAxes + { + XY_AXES, + XZ_AXES + }; +public: + RivWindowEdgeAxesOverlayItem(Font* font); - virtual ~RivWindowEdgeAxesOverlayItem(); + ~RivWindowEdgeAxesOverlayItem() override; void setDisplayCoordTransform(const caf::DisplayCoordTransform* displayCoordTransform); void updateFromCamera(const Camera* camera); @@ -93,10 +100,12 @@ class RivWindowEdgeAxesOverlayItem : public cvf::OverlayItem void setLineColor(const Color3f& lineColor); const Color3f& lineColor() const; void setFrameColor(const Color4f& frameColor); - + void setDomainAxes(DomainAxes axes); + void setIsSwitchingYAxisSign(bool switchSign); int frameBorderWidth() { return static_cast( m_frameBorderWidth); } int frameBorderHeight() { return static_cast( m_frameBorderHeight); } + void setShowAxisLines(bool showAxisLines); protected: Vec2ui sizeHint() override; void render(OpenGLContext* oglContext, const Vec2i& position, const Vec2ui& size) override; @@ -127,6 +136,8 @@ class RivWindowEdgeAxesOverlayItem : public cvf::OverlayItem float m_tickLineLength; float m_pixelSpacing; bool m_isSwitchingYAxisValueSign; + bool m_showAxisLines; + DomainAxes m_domainAxes; std::vector m_domainCoordsXValues; std::vector m_domainCoordsYValues; diff --git a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake index 0851d05385..afcdda6189 100644 --- a/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/CMakeLists_files.cmake @@ -24,7 +24,13 @@ ${CMAKE_CURRENT_LIST_DIR}/RimCellEdgeColors.h ${CMAKE_CURRENT_LIST_DIR}/RimSimWellInView.h ${CMAKE_CURRENT_LIST_DIR}/RimSimWellInViewCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimWellPath.h +${CMAKE_CURRENT_LIST_DIR}/RimFileWellPath.h +${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPath.h +${CMAKE_CURRENT_LIST_DIR}/RimWellPathGeometryDef.h +${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttribute.h +${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttributeCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimWellPathCollection.h +${CMAKE_CURRENT_LIST_DIR}/RimWellPathTarget.h ${CMAKE_CURRENT_LIST_DIR}/RimScriptCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimEclipseStatisticsCase.h ${CMAKE_CURRENT_LIST_DIR}/RimEclipseStatisticsCaseCollection.h @@ -104,7 +110,17 @@ ${CMAKE_CURRENT_LIST_DIR}/Rim3dWellLogExtractionCurve.h ${CMAKE_CURRENT_LIST_DIR}/Rim3dWellLogRftCurve.h ${CMAKE_CURRENT_LIST_DIR}/RimVirtualPerforationResults.h ${CMAKE_CURRENT_LIST_DIR}/RimLegendConfig.h -${CMAKE_CURRENT_LIST_DIR}/RimWellLogCurveNameConfig.h +${CMAKE_CURRENT_LIST_DIR}/RimNameConfig.h +${CMAKE_CURRENT_LIST_DIR}/RimWellLogPlotNameConfig.h +${CMAKE_CURRENT_LIST_DIR}/RimWellLogExtractionCurveNameConfig.h +${CMAKE_CURRENT_LIST_DIR}/RimWellLogFileCurveNameConfig.h +${CMAKE_CURRENT_LIST_DIR}/RimWellLogRftCurveNameConfig.h +${CMAKE_CURRENT_LIST_DIR}/RimDataSourceSteppingTools.h +${CMAKE_CURRENT_LIST_DIR}/RimWellLogCurveCommonDataSource.h +${CMAKE_CURRENT_LIST_DIR}/RimContourMapProjection.h +${CMAKE_CURRENT_LIST_DIR}/RimContourMapView.h +${CMAKE_CURRENT_LIST_DIR}/RimContourMapViewCollection.h +${CMAKE_CURRENT_LIST_DIR}/RimContourMapNameConfig.h ) @@ -133,7 +149,13 @@ ${CMAKE_CURRENT_LIST_DIR}/RimCellEdgeColors.cpp ${CMAKE_CURRENT_LIST_DIR}/RimSimWellInView.cpp ${CMAKE_CURRENT_LIST_DIR}/RimSimWellInViewCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellPath.cpp +${CMAKE_CURRENT_LIST_DIR}/RimFileWellPath.cpp +${CMAKE_CURRENT_LIST_DIR}/RimModeledWellPath.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellPathGeometryDef.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttribute.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellPathAttributeCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellPathCollection.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellPathTarget.cpp ${CMAKE_CURRENT_LIST_DIR}/RimScriptCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimEclipseStatisticsCase.cpp ${CMAKE_CURRENT_LIST_DIR}/RimEclipseStatisticsCaseCollection.cpp @@ -213,7 +235,17 @@ ${CMAKE_CURRENT_LIST_DIR}/Rim3dWellLogExtractionCurve.cpp ${CMAKE_CURRENT_LIST_DIR}/Rim3dWellLogRftCurve.cpp ${CMAKE_CURRENT_LIST_DIR}/RimVirtualPerforationResults.cpp ${CMAKE_CURRENT_LIST_DIR}/RimLegendConfig.cpp -${CMAKE_CURRENT_LIST_DIR}/RimWellLogCurveNameConfig.cpp +${CMAKE_CURRENT_LIST_DIR}/RimNameConfig.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellLogPlotNameConfig.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellLogExtractionCurveNameConfig.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellLogFileCurveNameConfig.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellLogRftCurveNameConfig.cpp +${CMAKE_CURRENT_LIST_DIR}/RimDataSourceSteppingTools.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellLogCurveCommonDataSource.cpp +${CMAKE_CURRENT_LIST_DIR}/RimContourMapProjection.cpp +${CMAKE_CURRENT_LIST_DIR}/RimContourMapView.cpp +${CMAKE_CURRENT_LIST_DIR}/RimContourMapViewCollection.cpp +${CMAKE_CURRENT_LIST_DIR}/RimContourMapNameConfig.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/Completions/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/Completions/CMakeLists_files.cmake index 6255f8499f..318f8f01be 100644 --- a/ApplicationCode/ProjectDataModel/Completions/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/Completions/CMakeLists_files.cmake @@ -12,6 +12,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellPathCompletions.h ${CMAKE_CURRENT_LIST_DIR}/RimEllipseFractureTemplate.h ${CMAKE_CURRENT_LIST_DIR}/RimFracture.h ${CMAKE_CURRENT_LIST_DIR}/RimFractureContainment.h +${CMAKE_CURRENT_LIST_DIR}/RimFractureContainmentTools.h ${CMAKE_CURRENT_LIST_DIR}/RimFractureExportSettings.h ${CMAKE_CURRENT_LIST_DIR}/RimFractureTemplate.h ${CMAKE_CURRENT_LIST_DIR}/RimFractureTemplateCollection.h @@ -21,6 +22,11 @@ ${CMAKE_CURRENT_LIST_DIR}/RimStimPlanFractureTemplate.h ${CMAKE_CURRENT_LIST_DIR}/RimWellPathFracture.h ${CMAKE_CURRENT_LIST_DIR}/RimWellPathFractureCollection.h ${CMAKE_CURRENT_LIST_DIR}/Rim3dWellLogCurveCollection.h +${CMAKE_CURRENT_LIST_DIR}/RimMswCompletionParameters.h +${CMAKE_CURRENT_LIST_DIR}/RimNonDarcyPerforationParameters.h +${CMAKE_CURRENT_LIST_DIR}/RimWellPathComponentInterface.h +${CMAKE_CURRENT_LIST_DIR}/RimWellPathValve.h +${CMAKE_CURRENT_LIST_DIR}/RimMultipleValveLocations.h ) @@ -37,6 +43,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellPathCompletions.cpp ${CMAKE_CURRENT_LIST_DIR}/RimEllipseFractureTemplate.cpp ${CMAKE_CURRENT_LIST_DIR}/RimFracture.cpp ${CMAKE_CURRENT_LIST_DIR}/RimFractureContainment.cpp +${CMAKE_CURRENT_LIST_DIR}/RimFractureContainmentTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RimFractureExportSettings.cpp ${CMAKE_CURRENT_LIST_DIR}/RimFractureTemplate.cpp ${CMAKE_CURRENT_LIST_DIR}/RimFractureTemplateCollection.cpp @@ -46,6 +53,10 @@ ${CMAKE_CURRENT_LIST_DIR}/RimStimPlanFractureTemplate.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellPathFracture.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellPathFractureCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/Rim3dWellLogCurveCollection.cpp +${CMAKE_CURRENT_LIST_DIR}/RimMswCompletionParameters.cpp +${CMAKE_CURRENT_LIST_DIR}/RimNonDarcyPerforationParameters.cpp +${CMAKE_CURRENT_LIST_DIR}/RimWellPathValve.cpp +${CMAKE_CURRENT_LIST_DIR}/RimMultipleValveLocations.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.cpp b/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.cpp index f1709c5f69..68ec1f8a14 100644 --- a/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.cpp @@ -72,7 +72,7 @@ void Rim3dWellLogCurveCollection::add3dWellLogCurve(Rim3dWellLogCurve* curve) size_t index = m_3dWellLogCurves.size(); curve->setColor(RiaColorTables::wellLogPlotPaletteColors().cycledColor3f(index)); m_3dWellLogCurves.push_back(curve); - curve->createCurveAutoName(); + curve->createAutoName(); } } @@ -139,7 +139,7 @@ void Rim3dWellLogCurveCollection::redrawAffectedViewsAndEditors() this->firstAncestorOrThisOfType(proj); if (proj) { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } RimWellPath* path = nullptr; this->firstAncestorOrThisOfType(path); @@ -186,7 +186,7 @@ void Rim3dWellLogCurveCollection::fieldChangedByUi(const caf::PdmFieldHandle* ch { RimProject* proj; this->firstAncestorOrThisOfTypeAsserted(proj); - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.h b/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.h index 1121aefa26..c4d4a60a53 100644 --- a/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.h +++ b/ApplicationCode/ProjectDataModel/Completions/Rim3dWellLogCurveCollection.h @@ -38,7 +38,7 @@ class Rim3dWellLogCurveCollection : public caf::PdmObject public: Rim3dWellLogCurveCollection(); - virtual ~Rim3dWellLogCurveCollection(); + ~Rim3dWellLogCurveCollection() override; bool has3dWellLogCurves() const; void add3dWellLogCurve(Rim3dWellLogCurve* curve); @@ -58,10 +58,10 @@ class Rim3dWellLogCurveCollection : public caf::PdmObject double* valueAtPoint); private: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual caf::PdmFieldHandle* objectToggleField() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* objectToggleField() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; private: caf::PdmField m_showPlot; caf::PdmField m_planeWidthScaling; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.cpp b/ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.cpp index aa0638dfcc..f4d7d455c7 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimCompletionCellIntersectionCalc.cpp @@ -34,9 +34,9 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector fromCompletionData(const std::vector& data) +std::vector fromCompletionData(const std::vector& data) { - std::vector appCompletionTypes; + std::vector appCompletionTypes; for (const auto& d : data) { @@ -92,7 +92,7 @@ void RimCompletionCellIntersectionCalc::calculateCompletionTypeResult(RimEclipse { for (const auto& completionsForWell : completions->multipleCompletionsPerEclipseCell(wellPath, timeStep)) { - RiaDefines::CompletionType appCompletionType = RiaDefines::WELL_PATH; + RiaDefines::WellPathComponentType appCompletionType = RiaDefines::WELL_PATH; auto appCompletionTypes = fromCompletionData(completionsForWell.second); @@ -113,7 +113,7 @@ void RimCompletionCellIntersectionCalc::calculateCompletionTypeResult(RimEclipse appCompletionType = RiaDefines::PERFORATION_INTERVAL; } - completionTypeCellResult[completionsForWell.first.globalCellIndex()] = appCompletionType; + completionTypeCellResult[completionsForWell.first] = appCompletionType; } } } diff --git a/ApplicationCode/ProjectDataModel/Completions/RimEllipseFractureTemplate.cpp b/ApplicationCode/ProjectDataModel/Completions/RimEllipseFractureTemplate.cpp index fd9f9dfb7d..ca3adbec10 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimEllipseFractureTemplate.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimEllipseFractureTemplate.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2016- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -19,6 +19,7 @@ #include "RimEllipseFractureTemplate.h" #include "RiaApplication.h" +#include "RiaCompletionTypeCalculationScheduler.h" #include "RiaEclipseUnitTools.h" #include "RiaFractureDefines.h" #include "RiaLogging.h" @@ -29,6 +30,7 @@ #include "RigStatisticsMath.h" #include "RigTesselatorTools.h" +#include "RimEclipseCase.h" #include "RimEclipseView.h" #include "RimFracture.h" #include "RimFractureContainment.h" @@ -38,91 +40,84 @@ #include "cafPdmObject.h" -#include "cvfVector3.h" #include "cvfGeometryTools.h" - - +#include "cvfVector3.h" CAF_PDM_SOURCE_INIT(RimEllipseFractureTemplate, "RimEllipseFractureTemplate"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimEllipseFractureTemplate::RimEllipseFractureTemplate() { - CAF_PDM_InitObject("Fracture Template", ":/FractureTemplate16x16.png", "", ""); + // clang-format off - CAF_PDM_InitField(&m_halfLength, "HalfLength", 0.0, "Halflength Xf", "", "", ""); + CAF_PDM_InitObject("Fracture Template", ":/FractureTemplate16x16.png", "", ""); + + CAF_PDM_InitField(&m_halfLength, "HalfLength", 0.0, "Half Length Xf", "", "", ""); CAF_PDM_InitField(&m_height, "Height", 0.0, "Height", "", "", ""); CAF_PDM_InitField(&m_width, "Width", 0.0, "Width", "", "", ""); - - CAF_PDM_InitField(&m_userDefinedEffectivePermeability,"Permeability", 0.0, "Permeability [mD]", "", "", ""); + CAF_PDM_InitField(&m_permeability,"Permeability", 0.0, "Permeability [mD]", "", "", ""); m_fractureGrid = new RigFractureGrid(); - assignConductivityToCellsInsideEllipse(); + createFractureGridAndAssignConductivities(); + + // clang-format on } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimEllipseFractureTemplate::~RimEllipseFractureTemplate() -{ -} +RimEllipseFractureTemplate::~RimEllipseFractureTemplate() {} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEllipseFractureTemplate::loadDataAndUpdate() { - assignConductivityToCellsInsideEllipse(); + createFractureGridAndAssignConductivities(); RimEclipseView* activeView = dynamic_cast(RiaApplication::instance()->activeReservoirView()); if (activeView) activeView->loadDataAndUpdate(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimEllipseFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimEllipseFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { RimFractureTemplate::fieldChangedByUi(changedField, oldValue, newValue); - if ( changedField == &m_halfLength - || changedField == &m_height - || changedField == &m_width - || changedField == &m_userDefinedEffectivePermeability - || changedField == &m_scaleApplyButton) + if (changedField == &m_halfLength || changedField == &m_height || changedField == &m_width || + changedField == &m_permeability || changedField == &m_scaleApplyButton) { m_scaleApplyButton = false; - //Changes to one of these parameters should change all fractures with this fracture template attached. - reload(); - } - - if (changedField == &m_width || changedField == &m_userDefinedEffectivePermeability) - { - assignConductivityToCellsInsideEllipse(); + // Changes to one of these parameters should change all fractures with this fracture template attached. + onLoadDataAndUpdateGeometryHasChanged(); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimEllipseFractureTemplate::fractureTriangleGeometry(std::vector* nodeCoords, - std::vector* triangleIndices) +void RimEllipseFractureTemplate::fractureTriangleGeometry(std::vector* nodeCoords, + std::vector* triangleIndices) const { RigEllipsisTesselator tesselator(20); - float a = m_halfLength * m_widthScaleFactor; + float a = m_halfLength * m_halfLengthScaleFactor; float b = m_height / 2.0f * m_heightScaleFactor; tesselator.tesselateEllipsis(a, b, triangleIndices, nodeCoords); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RimEllipseFractureTemplate::fractureBorderPolygon() +std::vector RimEllipseFractureTemplate::fractureBorderPolygon() const { std::vector polygon; @@ -140,7 +135,7 @@ std::vector RimEllipseFractureTemplate::fractureBorderPolygon() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEllipseFractureTemplate::changeUnits() { @@ -157,55 +152,61 @@ void RimEllipseFractureTemplate::changeUnits() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimEllipseFractureTemplate::assignConductivityToCellsInsideEllipse() +void RimEllipseFractureTemplate::createFractureGridAndAssignConductivities() { std::vector fractureCells; int numberOfCellsI = 35; int numberOfCellsJ = 35; - - double height = m_height * m_heightScaleFactor; - double halfLength = m_halfLength * m_widthScaleFactor; - double cellSizeX = (halfLength * 2) / numberOfCellsI * m_widthScaleFactor; + double height = m_height * m_heightScaleFactor; + double halfLength = m_halfLength * m_halfLengthScaleFactor; + + double cellSizeX = (halfLength * 2) / numberOfCellsI * m_halfLengthScaleFactor; double cellSizeZ = height / numberOfCellsJ * m_heightScaleFactor; - double cellArea = cellSizeX * cellSizeZ; + double cellArea = cellSizeX * cellSizeZ; double areaTresholdForIncludingCell = 0.5 * cellArea; - for (int i = 0; i < numberOfCellsI; i++) { for (int j = 0; j < numberOfCellsJ; j++) { - double X1 = - halfLength + i * cellSizeX; - double X2 = - halfLength + (i+1) * cellSizeX; - double Y1 = - height / 2 + j * cellSizeZ; - double Y2 = - height / 2 + (j+1) * cellSizeZ; + double X1 = -halfLength + i * cellSizeX; + double X2 = -halfLength + (i + 1) * cellSizeX; + double Y1 = -height / 2 + j * cellSizeZ; + double Y2 = -height / 2 + (j + 1) * cellSizeZ; std::vector cellPolygon; cellPolygon.push_back(cvf::Vec3d(X1, Y1, 0.0)); cellPolygon.push_back(cvf::Vec3d(X2, Y1, 0.0)); cellPolygon.push_back(cvf::Vec3d(X2, Y2, 0.0)); cellPolygon.push_back(cvf::Vec3d(X1, Y2, 0.0)); - + double cond = conductivity(); std::vector ellipseFracPolygon = fractureBorderPolygon(); std::vector ellipseFracPolygonDouble; - for (const auto& v : ellipseFracPolygon) ellipseFracPolygonDouble.push_back(static_cast(v)); - std::vector >clippedFracturePolygons = RigCellGeometryTools::intersectPolygons(cellPolygon, ellipseFracPolygonDouble); + for (const auto& v : ellipseFracPolygon) + ellipseFracPolygonDouble.push_back(static_cast(v)); + std::vector> clippedFracturePolygons = + RigCellGeometryTools::intersectPolygons(cellPolygon, ellipseFracPolygonDouble); if (!clippedFracturePolygons.empty()) { for (const auto& clippedFracturePolygon : clippedFracturePolygons) { double areaCutPolygon = cvf::GeometryTools::polygonAreaNormal3D(clippedFracturePolygon).length(); - if (areaCutPolygon < areaTresholdForIncludingCell) cond = 0.0; //Cell is excluded from calculation, cond is set to zero. Must be included for indexing to be correct + if (areaCutPolygon < areaTresholdForIncludingCell) + { + cond = 0.0; // Cell is excluded from calculation, cond is set to zero. Must be included for indexing to be + // correct + } } } - else cond = 0.0; + else + cond = 0.0; RigFractureCell fractureCell(cellPolygon, i, j); fractureCell.setConductivityValue(cond); @@ -213,25 +214,25 @@ void RimEllipseFractureTemplate::assignConductivityToCellsInsideEllipse() fractureCells.push_back(fractureCell); } } - + m_fractureGrid->setFractureCells(fractureCells); // Set well intersection to center of ellipse std::pair wellCenterFractureCellIJ = std::make_pair(numberOfCellsI / 2, numberOfCellsJ / 2); m_fractureGrid->setWellCenterFractureCellIJ(wellCenterFractureCellIJ); - + m_fractureGrid->setICellCount(numberOfCellsI); m_fractureGrid->setJCellCount(numberOfCellsJ); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -FractureWidthAndConductivity RimEllipseFractureTemplate::widthAndConductivityAtWellPathIntersection() const +WellFractureIntersectionData RimEllipseFractureTemplate::wellFractureIntersectionData(const RimFracture* fractureInstance) const { - FractureWidthAndConductivity values; - values.m_width = m_width; - values.m_permeability = m_userDefinedEffectivePermeability; + WellFractureIntersectionData values; + values.m_width = m_width; + values.m_permeability = m_permeability; return values; } @@ -239,27 +240,55 @@ FractureWidthAndConductivity RimEllipseFractureTemplate::widthAndConductivityAtW //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- +QList RimEllipseFractureTemplate::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList options; + + if (fieldNeedingOptions == &m_fractureWidthType) + { + options.push_back(caf::PdmOptionItemInfo(caf::AppEnum::uiText(USER_DEFINED_WIDTH), USER_DEFINED_WIDTH)); + options.push_back(caf::PdmOptionItemInfo(caf::AppEnum::uiText(WIDTH_FROM_FRACTURE), WIDTH_FROM_FRACTURE)); + } + + if (fieldNeedingOptions == &m_betaFactorType) + { + options.push_back( + caf::PdmOptionItemInfo(caf::AppEnum::uiText(USER_DEFINED_BETA_FACTOR), USER_DEFINED_BETA_FACTOR)); + + if (isBetaFactorAvailableOnFile()) + { + options.push_back(caf::PdmOptionItemInfo(caf::AppEnum::uiText(BETA_FACTOR_FROM_FRACTURE), + BETA_FACTOR_FROM_FRACTURE)); + } + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- const RigFractureGrid* RimEllipseFractureTemplate::fractureGrid() const { return m_fractureGrid.p(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEllipseFractureTemplate::setDefaultValuesFromUnit() { if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_FIELD) { m_width = 0.5; - m_userDefinedEffectivePermeability = 80000.0; + m_permeability = 80000.0; m_halfLength = 300.0; m_height = 225.0; } else { m_width = 0.01; - m_userDefinedEffectivePermeability = 100000.0; + m_permeability = 100000.0; m_halfLength = 100.0; m_height = 75.0; } @@ -268,29 +297,56 @@ void RimEllipseFractureTemplate::setDefaultValuesFromUnit() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RimEllipseFractureTemplate::conductivity() const { double cond = cvf::UNDEFINED_DOUBLE; if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_METRIC) { - //Conductivity should be md-m, width is in m - cond = m_userDefinedEffectivePermeability * m_width; + // Conductivity should be md-m, width is in m + cond = m_permeability * m_width; } else if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_FIELD) { - //Conductivity should be md-ft, but width is in inches - cond = m_userDefinedEffectivePermeability * RiaEclipseUnitTools::inchToFeet(m_width); + // Conductivity should be md-ft, but width is in inches + cond = m_permeability * RiaEclipseUnitTools::inchToFeet(m_width); } return m_conductivityScaleFactor * cond; } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +double RimEllipseFractureTemplate::halfLength() const +{ + return m_halfLength; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimEllipseFractureTemplate::height() const +{ + return m_height; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- -void RimEllipseFractureTemplate::appendDataToResultStatistics(const QString& uiResultName, const QString& unit, MinMaxAccumulator& minMaxAccumulator, PosNegAccumulator& posNegAccumulator) const +double RimEllipseFractureTemplate::width() const +{ + return m_width; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEllipseFractureTemplate::appendDataToResultStatistics(const QString& uiResultName, + const QString& unit, + MinMaxAccumulator& minMaxAccumulator, + PosNegAccumulator& posNegAccumulator) const { if (uiResultName == RiaDefines::conductivityResultName()) { @@ -300,7 +356,7 @@ void RimEllipseFractureTemplate::appendDataToResultStatistics(const QString& uiR } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector> RimEllipseFractureTemplate::uiResultNamesWithUnit() const { @@ -313,21 +369,26 @@ std::vector> RimEllipseFractureTemplate::uiResultNam } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimEllipseFractureTemplate::reload() +void RimEllipseFractureTemplate::onLoadDataAndUpdateGeometryHasChanged() { - RimProject* proj; - this->firstAncestorOrThisOfType(proj); - if (proj) + loadDataAndUpdate(); + + RimEclipseCase* eclipseCase = nullptr; + this->firstAncestorOrThisOfType(eclipseCase); + if (eclipseCase) { - proj->reloadCompletionTypeResultsInAllViews(); - assignConductivityToCellsInsideEllipse(); + RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews(eclipseCase); + } + else + { + RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews(); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEllipseFractureTemplate::convertToUnitSystem(RiaEclipseUnitTools::UnitSystem neededUnit) { @@ -338,24 +399,23 @@ void RimEllipseFractureTemplate::convertToUnitSystem(RiaEclipseUnitTools::UnitSy if (neededUnit == RiaEclipseUnitTools::UNITS_FIELD) { - m_halfLength = RiaEclipseUnitTools::meterToFeet(m_halfLength); - m_height = RiaEclipseUnitTools::meterToFeet(m_height); - m_width = RiaEclipseUnitTools::meterToInch(m_width); + m_halfLength = RiaEclipseUnitTools::meterToFeet(m_halfLength); + m_height = RiaEclipseUnitTools::meterToFeet(m_height); + m_width = RiaEclipseUnitTools::meterToInch(m_width); } else if (neededUnit == RiaEclipseUnitTools::UNITS_METRIC) { - m_halfLength = RiaEclipseUnitTools::feetToMeter(m_halfLength); - m_height = RiaEclipseUnitTools::feetToMeter(m_height); - m_width = RiaEclipseUnitTools::inchToMeter(m_width); + m_halfLength = RiaEclipseUnitTools::feetToMeter(m_halfLength); + m_height = RiaEclipseUnitTools::feetToMeter(m_height); + m_width = RiaEclipseUnitTools::inchToMeter(m_width); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEllipseFractureTemplate::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { - if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_METRIC) { m_halfLength.uiCapability()->setUiName("Halflenght Xf [m]"); @@ -371,36 +431,43 @@ void RimEllipseFractureTemplate::defineUiOrdering(QString uiConfigName, caf::Pdm if (conductivityType() == FINITE_CONDUCTIVITY) { - m_userDefinedEffectivePermeability.uiCapability()->setUiHidden(false); + m_permeability.uiCapability()->setUiHidden(false); m_width.uiCapability()->setUiHidden(false); } else if (conductivityType() == INFINITE_CONDUCTIVITY) { - m_userDefinedEffectivePermeability.uiCapability()->setUiHidden(true); + m_permeability.uiCapability()->setUiHidden(true); m_width.uiCapability()->setUiHidden(true); } - + uiOrdering.add(&m_name); uiOrdering.add(&m_id); - caf::PdmUiGroup* geometryGroup = uiOrdering.addNewGroup("Geometry"); - geometryGroup->add(&m_halfLength); - geometryGroup->add(&m_height); - geometryGroup->add(&m_orientationType); - geometryGroup->add(&m_azimuthAngle); + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Geometry"); + group->add(&m_halfLength); + group->add(&m_height); + group->add(&m_orientationType); + group->add(&m_azimuthAngle); + } - caf::PdmUiGroup* trGr = uiOrdering.addNewGroup("Fracture Truncation"); - m_fractureContainment()->defineUiOrdering(uiConfigName, *trGr); + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Fracture Truncation"); + group->setCollapsedByDefault(true); - caf::PdmUiGroup* propertyGroup = uiOrdering.addNewGroup("Properties"); - propertyGroup->add(&m_conductivityType); - propertyGroup->add(&m_userDefinedEffectivePermeability); - propertyGroup->add(&m_width); - propertyGroup->add(&m_skinFactor); - propertyGroup->add(&m_perforationLength); - propertyGroup->add(&m_perforationEfficiency); - propertyGroup->add(&m_wellDiameter); + m_fractureContainment()->uiOrdering(uiConfigName, *group); + } + + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Properties"); + group->add(&m_conductivityType); + group->add(&m_permeability); + group->add(&m_width); + group->add(&m_skinFactor); + group->add(&m_perforationLength); + group->add(&m_perforationEfficiency); + group->add(&m_wellDiameter); + } RimFractureTemplate::defineUiOrdering(uiConfigName, uiOrdering); } - diff --git a/ApplicationCode/ProjectDataModel/Completions/RimEllipseFractureTemplate.h b/ApplicationCode/ProjectDataModel/Completions/RimEllipseFractureTemplate.h index 1c86cbef95..9c1a392842 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimEllipseFractureTemplate.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimEllipseFractureTemplate.h @@ -44,15 +44,18 @@ class RimEllipseFractureTemplate : public RimFractureTemplate public: RimEllipseFractureTemplate(); - virtual ~RimEllipseFractureTemplate(); + ~RimEllipseFractureTemplate() override; - void fractureTriangleGeometry(std::vector* nodeCoords, std::vector* polygonIndices) override; + void fractureTriangleGeometry(std::vector* nodeCoords, std::vector* polygonIndices) const override; - std::vector fractureBorderPolygon() override; void changeUnits(); const RigFractureGrid* fractureGrid() const override; void setDefaultValuesFromUnit(); double conductivity() const; + + double halfLength() const; + double height() const; + double width() const; void appendDataToResultStatistics(const QString& uiResultName, const QString& unit, @@ -63,16 +66,18 @@ class RimEllipseFractureTemplate : public RimFractureTemplate void loadDataAndUpdate() override; std::vector> uiResultNamesWithUnit() const override; - virtual void reload() override; -protected: +private: void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; -private: - void assignConductivityToCellsInsideEllipse(); + void onLoadDataAndUpdateGeometryHasChanged() override; + + void createFractureGridAndAssignConductivities(); + std::vector fractureBorderPolygon() const; - FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection() const override; + WellFractureIntersectionData wellFractureIntersectionData(const RimFracture* fractureInstance) const override; private: cvf::ref m_fractureGrid; @@ -80,5 +85,5 @@ class RimEllipseFractureTemplate : public RimFractureTemplate caf::PdmField m_halfLength; caf::PdmField m_height; caf::PdmField m_width; - caf::PdmField m_userDefinedEffectivePermeability; + caf::PdmField m_permeability; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPath.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPath.cpp index 85288c01cd..34c6d9ea57 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPath.cpp @@ -77,7 +77,7 @@ void RimFishboneWellPath::fieldChangedByUi(const caf::PdmFieldHandle* changedFie { RimProject* proj; this->firstAncestorOrThisOfType(proj); - if (proj) proj->createDisplayModelAndRedrawAllViews(); + if (proj) proj->scheduleCreateDisplayModelAndRedrawAllViews(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPath.h b/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPath.h index ee52cb49fe..b459c49f4b 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPath.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPath.h @@ -47,10 +47,10 @@ class RimFishboneWellPath : public RimCheckableNamedObject public: RimFishboneWellPath(); - virtual ~RimFishboneWellPath(); + ~RimFishboneWellPath() override; - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; void setCoordinates(std::vector< cvf::Vec3d > coordinates); void setMeasuredDepths(std::vector< double > measuredDepths); diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp index 59507d5ff0..97c90e330f 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.cpp @@ -90,7 +90,7 @@ void RimFishboneWellPathCollection::fieldChangedByUi(const caf::PdmFieldHandle* { RimProject* proj; this->firstAncestorOrThisOfTypeAsserted(proj); - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.h b/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.h index 071163821e..e2cbd6d19a 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishboneWellPathCollection.h @@ -44,7 +44,7 @@ class RimFishboneWellPathCollection : public RimCheckableNamedObject void importCompletionsFromFile(const QStringList& filePaths); - void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; std::vector wellPaths() const; double holeDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const { return m_pipeProperties->holeDiameter(unitSystem); } @@ -53,7 +53,7 @@ class RimFishboneWellPathCollection : public RimCheckableNamedObject void setUnitSystemSpecificDefaults(); protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: void appendCompletion(RimFishboneWellPath* completion); diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesCollection.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesCollection.cpp index c365d66086..a7afc5bc6d 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesCollection.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -32,29 +32,10 @@ #include #include -namespace caf { - template<> - void RimFishbonesCollection::PressureDropEnum::setUp() - { - addItem(RimFishbonesCollection::HYDROSTATIC, "H--", "Hydrostatic"); - addItem(RimFishbonesCollection::HYDROSTATIC_FRICTION, "HF-", "Hydrostatic + Friction"); - addItem(RimFishbonesCollection::HYDROSTATIC_FRICTION_ACCELERATION, "HFA", "Hydrostatic + Friction + Acceleration"); - setDefault(RimFishbonesCollection::HYDROSTATIC); - } - - template<> - void RimFishbonesCollection::LengthAndDepthEnum::setUp() - { - addItem(RimFishbonesCollection::INC, "INC", "Incremental"); - addItem(RimFishbonesCollection::ABS, "ABS", "Absolute"); - setDefault(RimFishbonesCollection::INC); - } -} - CAF_PDM_SOURCE_INIT(RimFishbonesCollection, "FishbonesCollection"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimFishbonesCollection::RimFishbonesCollection() { @@ -63,28 +44,36 @@ RimFishbonesCollection::RimFishbonesCollection() nameField()->uiCapability()->setUiHidden(true); this->setName("Fishbones"); - CAF_PDM_InitFieldNoDefault(&fishbonesSubs, "FishbonesSubs", "fishbonesSubs", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_fishbonesSubs, "FishbonesSubs", "fishbonesSubs", "", "", ""); - fishbonesSubs.uiCapability()->setUiHidden(true); + m_fishbonesSubs.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_wellPathCollection, "WellPathCollection", "Imported Laterals", "", "", ""); m_wellPathCollection = new RimFishboneWellPathCollection; m_wellPathCollection.uiCapability()->setUiHidden(true); - CAF_PDM_InitField(&m_startMD, "StartMD", HUGE_VAL, "Start MD", "", "", ""); - CAF_PDM_InitField(&m_mainBoreDiameter, "MainBoreDiameter", 0.216, "Main Bore Diameter", "", "", ""); + CAF_PDM_InitField(&m_startMD, "StartMD", HUGE_VAL, "Start MD", "", "", ""); + CAF_PDM_InitField(&m_mainBoreDiameter, "MainBoreDiameter", 0.216, "Main Bore Diameter", "", "", ""); CAF_PDM_InitField(&m_skinFactor, "MainBoreSkinFactor", 0., "Main Bore Skin Factor [0..1]", "", "", ""); - CAF_PDM_InitField(&m_linerDiameter, "LinerDiameter", 0.152, "Liner Inner Diameter", "", "", ""); - CAF_PDM_InitField(&m_roughnessFactor, "RoughnessFactor", 1e-05, "Roughness Factor", "", "", ""); - - CAF_PDM_InitFieldNoDefault(&m_pressureDrop, "PressureDrop", "Pressure Drop", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_lengthAndDepth, "LengthAndDepth", "Length and Depth", "", "", ""); - + CAF_PDM_InitFieldNoDefault(&m_mswParameters, "MswParameters", "Multi Segment Well Parameters", "", "", ""); + m_mswParameters = new RimMswCompletionParameters; + m_mswParameters.uiCapability()->setUiTreeHidden(true); + m_mswParameters.uiCapability()->setUiTreeChildrenHidden(true); manuallyModifiedStartMD = false; + + // Moved to RimMswCompletionParameters and obsoleted + CAF_PDM_InitField(&m_linerDiameter_OBSOLETE, "LinerDiameter", 0.152, "Liner Inner Diameter", "", "", ""); + CAF_PDM_InitField(&m_roughnessFactor_OBSOLETE, "RoughnessFactor", 1e-05, "Roughness Factor", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_pressureDrop_OBSOLETE, "PressureDrop", "Pressure Drop", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_lengthAndDepth_OBSOLETE, "LengthAndDepth", "Length and Depth", "", "", ""); + m_linerDiameter_OBSOLETE.xmlCapability()->setIOWritable(false); + m_roughnessFactor_OBSOLETE.xmlCapability()->setIOWritable(false); + m_pressureDrop_OBSOLETE.xmlCapability()->setIOWritable(false); + m_lengthAndDepth_OBSOLETE.xmlCapability()->setIOWritable(false); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimFishboneWellPathCollection* RimFishbonesCollection::wellPathCollection() const { @@ -94,9 +83,11 @@ RimFishboneWellPathCollection* RimFishbonesCollection::wellPathCollection() cons } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimFishbonesCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimFishbonesCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { if (changedField == &m_startMD) { @@ -111,12 +102,12 @@ void RimFishbonesCollection::fieldChangedByUi(const caf::PdmFieldHandle* changed } else { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFishbonesCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { @@ -129,15 +120,11 @@ void RimFishbonesCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOr { m_startMD.uiCapability()->setUiName("Start MD [m]"); m_mainBoreDiameter.uiCapability()->setUiName("Main Bore Diameter [m]"); - m_linerDiameter.uiCapability()->setUiName("Liner Inner Diameter [m]"); - m_roughnessFactor.uiCapability()->setUiName("Roughness Factor [m]"); } else if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD) { m_startMD.uiCapability()->setUiName("Start MD [ft]"); m_mainBoreDiameter.uiCapability()->setUiName("Main Bore Diameter [ft]"); - m_linerDiameter.uiCapability()->setUiName("Liner Inner Diameter [ft]"); - m_roughnessFactor.uiCapability()->setUiName("Roughness Factor [ft]"); } } } @@ -146,46 +133,103 @@ void RimFishbonesCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOr wellGroup->add(&m_startMD); wellGroup->add(&m_mainBoreDiameter); wellGroup->add(&m_skinFactor); + caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup("Multi Segment Well Options"); + m_mswParameters->uiOrdering(uiConfigName, *mswGroup); + uiOrdering.skipRemainingFields(true); +} - caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup("Multi Segment Wells"); - mswGroup->add(&m_linerDiameter); - mswGroup->add(&m_roughnessFactor); - mswGroup->add(&m_pressureDrop); - mswGroup->add(&m_lengthAndDepth); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFishbonesCollection::initAfterRead() +{ + if (m_linerDiameter_OBSOLETE() != m_linerDiameter_OBSOLETE.defaultValue()) + { + m_mswParameters->setLinerDiameter(m_linerDiameter_OBSOLETE()); + } + if (m_roughnessFactor_OBSOLETE() != m_roughnessFactor_OBSOLETE.defaultValue()) + { + m_mswParameters->setRoughnessFactor(m_roughnessFactor_OBSOLETE()); + } + if (m_pressureDrop_OBSOLETE() != m_pressureDrop_OBSOLETE.defaultValue()) + { + m_mswParameters->setPressureDrop(m_pressureDrop_OBSOLETE()); + } + if (m_lengthAndDepth_OBSOLETE() != m_lengthAndDepth_OBSOLETE.defaultValue()) + { + m_mswParameters->setLengthAndDepth(m_lengthAndDepth_OBSOLETE()); + } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFishbonesCollection::appendFishbonesSubs(RimFishbonesMultipleSubs* subs) { subs->fishbonesColor = nextFishbonesColor(); - fishbonesSubs.push_back(subs); + m_fishbonesSubs.push_back(subs); subs->setUnitSystemSpecificDefaults(); subs->recomputeLateralLocations(); } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +const RimMswCompletionParameters* RimFishbonesCollection::mswParameters() const +{ + return m_mswParameters; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimFishbonesCollection::activeFishbonesSubs() const +{ + std::vector active; + + if (isChecked()) + { + for (const auto& f : allFishbonesSubs()) + { + if (f->isActive()) + { + active.push_back(f); + } + } + } + + return active; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimFishbonesCollection::allFishbonesSubs() const +{ + return m_fishbonesSubs.childObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- cvf::Color3f RimFishbonesCollection::nextFishbonesColor() const { RimWellPath* wellPath; firstAncestorOrThisOfType(wellPath); cvf::Color3ub wellPathColor(wellPath->wellPathColor()); - QColor qWellPathColor = QColor(wellPathColor.r(), wellPathColor.g(), wellPathColor.b()); + QColor qWellPathColor = QColor(wellPathColor.r(), wellPathColor.g(), wellPathColor.b()); if (qWellPathColor.value() == 0) { - // If the color is black, using `lighter` or `darker` will not have any effect, since they multiply `value` by a percentage. - // In this case, `value` is set specifically to make `lighter`/`darker` possible. + // If the color is black, using `lighter` or `darker` will not have any effect, since they multiply `value` by a + // percentage. In this case, `value` is set specifically to make `lighter`/`darker` possible. qWellPathColor.setHsl(qWellPathColor.hue(), qWellPathColor.saturation(), 25); } QColor qFishbonesColor; - int newIndex = static_cast(fishbonesSubs.size()); + int newIndex = static_cast(m_fishbonesSubs.size()); if (qWellPathColor.lightnessF() < 0.5) { @@ -200,13 +244,13 @@ cvf::Color3f RimFishbonesCollection::nextFishbonesColor() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFishbonesCollection::recalculateStartMD() { double minStartMD = HUGE_VAL; - for (const RimFishbonesMultipleSubs* sub : fishbonesSubs()) + for (const RimFishbonesMultipleSubs* sub : m_fishbonesSubs()) { for (auto& index : sub->installedLateralIndices()) { @@ -229,61 +273,33 @@ void RimFishbonesCollection::recalculateStartMD() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RimFishbonesCollection::mainBoreDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const +double RimFishbonesCollection::startMD() const { - RimWellPath* wellPath; - firstAncestorOrThisOfTypeAsserted(wellPath); - if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD && unitSystem == RiaEclipseUnitTools::UNITS_METRIC) - { - return RiaEclipseUnitTools::feetToMeter(m_mainBoreDiameter()); - } - else if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_METRIC && unitSystem == RiaEclipseUnitTools::UNITS_FIELD) - { - return RiaEclipseUnitTools::meterToFeet(m_mainBoreDiameter()); - } - return m_mainBoreDiameter(); + return m_startMD; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RimFishbonesCollection::linerDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const -{ - RimWellPath* wellPath; - firstAncestorOrThisOfTypeAsserted(wellPath); - if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD && unitSystem == RiaEclipseUnitTools::UNITS_METRIC) - { - return RiaEclipseUnitTools::feetToMeter(m_linerDiameter()); - } - else if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_METRIC && unitSystem == RiaEclipseUnitTools::UNITS_FIELD) - { - return RiaEclipseUnitTools::meterToFeet(m_linerDiameter()); - } - return m_linerDiameter(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double RimFishbonesCollection::roughnessFactor(RiaEclipseUnitTools::UnitSystem unitSystem) const +double RimFishbonesCollection::mainBoreDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const { RimWellPath* wellPath; firstAncestorOrThisOfTypeAsserted(wellPath); if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD && unitSystem == RiaEclipseUnitTools::UNITS_METRIC) { - return RiaEclipseUnitTools::feetToMeter(m_roughnessFactor()); + return RiaEclipseUnitTools::feetToMeter(m_mainBoreDiameter()); } else if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_METRIC && unitSystem == RiaEclipseUnitTools::UNITS_FIELD) { - return RiaEclipseUnitTools::meterToFeet(m_roughnessFactor()); + return RiaEclipseUnitTools::meterToFeet(m_mainBoreDiameter()); } - return m_roughnessFactor(); + return m_mainBoreDiameter(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFishbonesCollection::setUnitSystemSpecificDefaults() { @@ -294,17 +310,13 @@ void RimFishbonesCollection::setUnitSystemSpecificDefaults() if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_METRIC) { m_mainBoreDiameter = 0.216; - m_linerDiameter = 0.152; - m_roughnessFactor = 1e-05; } else { m_mainBoreDiameter = 0.708; - m_linerDiameter = 0.5; - m_roughnessFactor = 3.28e-05; } m_wellPathCollection->setUnitSystemSpecificDefaults(); } + m_mswParameters->setUnitSystemSpecificDefaults(); } - diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesCollection.h b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesCollection.h index cb44e95644..4f25dd44e5 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesCollection.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesCollection.h @@ -19,6 +19,7 @@ #pragma once #include "RimCheckableNamedObject.h" +#include "RimMswCompletionParameters.h" #include "RiaEclipseUnitTools.h" @@ -41,58 +42,42 @@ class RimFishbonesCollection : public RimCheckableNamedObject CAF_PDM_HEADER_INIT; public: - enum PressureDropType { - HYDROSTATIC, - HYDROSTATIC_FRICTION, - HYDROSTATIC_FRICTION_ACCELERATION - }; - - typedef caf::AppEnum PressureDropEnum; - - enum LengthAndDepthType { - ABS, - INC - }; - - typedef caf::AppEnum LengthAndDepthEnum; - RimFishbonesCollection(); - RimFishboneWellPathCollection* wellPathCollection() const; - void appendFishbonesSubs(RimFishbonesMultipleSubs* subs); + RimFishboneWellPathCollection* wellPathCollection() const; + void appendFishbonesSubs(RimFishbonesMultipleSubs* subs); + const RimMswCompletionParameters* mswParameters() const; - caf::PdmChildArrayField fishbonesSubs; + std::vector activeFishbonesSubs() const; + std::vector allFishbonesSubs() const; void recalculateStartMD(); - double startMD() const { return m_startMD; } + double startMD() const; double mainBoreSkinFactor() const { return m_skinFactor; } - double mainBoreDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const; - double linerDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const; - double roughnessFactor(RiaEclipseUnitTools::UnitSystem unitSystem) const; - - PressureDropEnum pressureDrop() const { return m_pressureDrop(); } - LengthAndDepthEnum lengthAndDepth() const { return m_lengthAndDepth(); } - + double mainBoreDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const; void setUnitSystemSpecificDefaults(); protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void initAfterRead() override; private: cvf::Color3f nextFishbonesColor() const; private: + caf::PdmChildArrayField m_fishbonesSubs; caf::PdmChildField m_wellPathCollection; caf::PdmField m_startMD; caf::PdmField m_skinFactor; caf::PdmField m_mainBoreDiameter; - caf::PdmField m_linerDiameter; - caf::PdmField m_roughnessFactor; + caf::PdmChildField m_mswParameters; + bool manuallyModifiedStartMD; - caf::PdmField m_pressureDrop; - caf::PdmField m_lengthAndDepth; + caf::PdmField m_linerDiameter_OBSOLETE; + caf::PdmField m_roughnessFactor_OBSOLETE; - bool manuallyModifiedStartMD; + caf::PdmField m_pressureDrop_OBSOLETE; + caf::PdmField m_lengthAndDepth_OBSOLETE; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp index 22903f9c5a..d2a6b65f0f 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.cpp @@ -18,11 +18,13 @@ #include "RimFishbonesMultipleSubs.h" +#include "RiaColorTables.h" #include "RigFishbonesGeometry.h" #include "RigWellPath.h" #include "RimProject.h" #include "RimWellPath.h" #include "RimFishbonesCollection.h" +#include "RimMultipleValveLocations.h" #include "cafPdmUiDoubleValueEditor.h" #include "cafPdmUiListEditor.h" @@ -35,6 +37,7 @@ #include "cvfMath.h" + CAF_PDM_SOURCE_INIT(RimFishbonesMultipleSubs, "FishbonesMultipleSubs"); namespace caf { @@ -71,7 +74,8 @@ RimFishbonesMultipleSubs::RimFishbonesMultipleSubs() m_name.uiCapability()->setUiReadOnly(true); m_name.xmlCapability()->setIOWritable(false); - CAF_PDM_InitField(&fishbonesColor, "Color", cvf::Color3f(0.999f, 0.333f, 0.999f), "Fishbones Color", "", "", ""); + cvf::Color3f defaultColor = RiaColorTables::wellPathComponentColors()[RiaDefines::FISHBONES]; + CAF_PDM_InitField(&fishbonesColor, "Color", defaultColor, "Fishbones Color", "", "", ""); CAF_PDM_InitField(&m_lateralCountPerSub, "LateralCountPerSub", 3, "Laterals Per Sub", "", "", ""); CAF_PDM_InitField(&m_lateralLength, "LateralLength", QString("11.0"), "Length(s) [m]", "", "Specify multiple length values if the sub lengths differ", ""); @@ -90,20 +94,11 @@ RimFishbonesMultipleSubs::RimFishbonesMultipleSubs() CAF_PDM_InitField(&m_icdOrificeDiameter, "IcdOrificeDiameter", 7.0, "ICD Orifice Diameter [mm]", "", "", ""); CAF_PDM_InitField(&m_icdFlowCoefficient, "IcdFlowCoefficient", 1.5, "ICD Flow Coefficient", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_locationOfSubs, "LocationOfSubs", "Measured Depths [m]", "", "", ""); - m_locationOfSubs.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); - - CAF_PDM_InitField(&m_subsLocationMode, "SubsLocationMode", caf::AppEnum(FB_SUB_COUNT_END), "Location Defined By", "", "", ""); - CAF_PDM_InitField(&m_rangeStart, "RangeStart", 100.0, "Start MD [m]", "", "", ""); - m_rangeStart.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleValueEditor::uiEditorTypeName()); - - CAF_PDM_InitField(&m_rangeEnd, "RangeEnd", 250.0, "End MD [m]", "", "", ""); - m_rangeEnd.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleValueEditor::uiEditorTypeName()); - - CAF_PDM_InitFieldNoDefault(&m_rangeSubSpacing, "RangeSubSpacing", "Spacing [m]", "", "", ""); - m_rangeSubSpacing.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleValueEditor::uiEditorTypeName()); - - CAF_PDM_InitField(&m_rangeSubCount, "RangeSubCount", 13, "Number of Subs", "", "", ""); + initialiseObsoleteFields(); + CAF_PDM_InitFieldNoDefault(&m_valveLocations, "ValveLocations", "Valve Locations", "", "", ""); + m_valveLocations = new RimMultipleValveLocations(); + m_valveLocations.uiCapability()->setUiHidden(true); + m_valveLocations.uiCapability()->setUiTreeChildrenHidden(true); CAF_PDM_InitField(&m_subsOrientationMode, "SubsOrientationMode", caf::AppEnum(FB_LATERAL_ORIENTATION_RANDOM), "Orientation", "", "", ""); @@ -152,13 +147,10 @@ QString RimFishbonesMultipleSubs::generatedName() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::setMeasuredDepthAndCount(double measuredDepth, double spacing, int subCount) +void RimFishbonesMultipleSubs::setMeasuredDepthAndCount(double startMD, double spacing, int subCount) { - m_subsLocationMode = FB_SUB_SPACING_END; - - m_rangeStart = measuredDepth; - m_rangeEnd = measuredDepth + spacing * subCount; - m_rangeSubCount = subCount; + double endMD = startMD + spacing * subCount; + m_valveLocations->initFields(RimMultipleValveLocations::VALVE_COUNT, startMD, endMD, spacing, subCount, {}); computeRangesAndLocations(); computeRotationAngles(); @@ -169,9 +161,7 @@ void RimFishbonesMultipleSubs::setMeasuredDepthAndCount(double measuredDepth, do //-------------------------------------------------------------------------------------------------- double RimFishbonesMultipleSubs::measuredDepth(size_t subIndex) const { - CVF_ASSERT(subIndex < m_locationOfSubs().size()); - - return m_locationOfSubs()[subIndex]; + return m_valveLocations->measuredDepth(subIndex); } //-------------------------------------------------------------------------------------------------- @@ -240,6 +230,23 @@ double RimFishbonesMultipleSubs::tubingDiameter(RiaEclipseUnitTools::UnitSystem return 0.0; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFishbonesMultipleSubs::effectiveDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const +{ + double innerRadius = tubingDiameter(unitSystem) / 2; + double outerRadius = holeDiameter(unitSystem) / 2; + + double innerArea = cvf::PI_D * innerRadius * innerRadius; + double outerArea = cvf::PI_D * outerRadius * outerRadius; + + double effectiveArea = outerArea - innerArea; + + double effectiveRadius = cvf::Math::sqrt(effectiveArea / cvf::PI_D); + return effectiveRadius * 2; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -319,6 +326,24 @@ std::vector RimFishbonesMultipleSubs::lateralLengths() const return lengths; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFishbonesMultipleSubs::geometryUpdated() +{ + computeRotationAngles(); + computeSubLateralIndices(); + + RimFishbonesCollection* collection; + this->firstAncestorOrThisOfTypeAsserted(collection); + collection->recalculateStartMD(); + + RimProject* proj; + this->firstAncestorOrThisOfTypeAsserted(proj); + proj->reloadCompletionTypeResultsInAllViews(); + +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -384,82 +409,82 @@ void RimFishbonesMultipleSubs::setUnitSystemSpecificDefaults() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimFishbonesMultipleSubs::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +RiaDefines::WellPathComponentType RimFishbonesMultipleSubs::componentType() const { - bool recomputeLocations = false; + return RiaDefines::FISHBONES; +} - if (changedField == &m_subsLocationMode) - { - if (m_subsLocationMode == FB_SUB_COUNT_END || m_subsLocationMode == FB_SUB_SPACING_END) - { - recomputeLocations = true; - } - } - - if (changedField == &m_rangeStart || - changedField == &m_rangeEnd || - changedField == &m_rangeSubCount || - changedField == &m_rangeSubSpacing) - { - recomputeLocations = true; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimFishbonesMultipleSubs::componentLabel() const +{ + return generatedName(); +} - RimWellPath* wellPath = nullptr; - this->firstAncestorOrThisOfTypeAsserted(wellPath); - - RigWellPath* rigWellPathGeo = wellPath->wellPathGeometry(); - if (rigWellPathGeo && !rigWellPathGeo->m_measuredDepths.empty()) - { - double lastWellPathMD = rigWellPathGeo->m_measuredDepths.back(); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimFishbonesMultipleSubs::componentTypeLabel() const +{ + return "Fishbones"; +} - m_rangeStart = cvf::Math::clamp(m_rangeStart(), 0.0, lastWellPathMD); - m_rangeEnd = cvf::Math::clamp(m_rangeEnd(), m_rangeStart(), lastWellPathMD); - } - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RimFishbonesMultipleSubs::defaultComponentColor() const +{ + return fishbonesColor(); +} - if (changedField == &m_rangeSubSpacing) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFishbonesMultipleSubs::startMD() const +{ + double measuredDepth = 0.0; + if (!m_valveLocations->valveLocations().empty()) { - // Minimum distance between fishbones is 13.0m - // Use 10.0m to allow for some flexibility - - double minimumDistanceMeter = 10.0; - - RimWellPath* wellPath = nullptr; - this->firstAncestorOrThisOfTypeAsserted(wellPath); - if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD) - { - double minimumDistanceFeet = RiaEclipseUnitTools::meterToFeet(minimumDistanceMeter); - m_rangeSubSpacing = cvf::Math::clamp(m_rangeSubSpacing(), minimumDistanceFeet, std::max(m_rangeSubSpacing(), minimumDistanceFeet)); - } - else - { - m_rangeSubSpacing = cvf::Math::clamp(m_rangeSubSpacing(), minimumDistanceMeter, std::max(m_rangeSubSpacing(), minimumDistanceMeter)); - } + measuredDepth = m_valveLocations->valveLocations().front(); } - if (recomputeLocations) + return measuredDepth; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFishbonesMultipleSubs::endMD() const +{ + double measuredDepth = 0.0; + if (!m_valveLocations->valveLocations().empty()) { - computeRangesAndLocations(); + measuredDepth = m_valveLocations->valveLocations().back(); } - if (recomputeLocations || - changedField == &m_locationOfSubs || - changedField == &m_subsOrientationMode) + return measuredDepth; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFishbonesMultipleSubs::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &m_subsOrientationMode) { computeRotationAngles(); } - if (changedField == &m_locationOfSubs || - changedField == &m_lateralInstallSuccessFraction || + if (changedField == &m_lateralInstallSuccessFraction || changedField == &m_lateralCountPerSub) { computeSubLateralIndices(); } - RimProject* proj; - this->firstAncestorOrThisOfTypeAsserted(proj); - proj->reloadCompletionTypeResultsInAllViews(); + geometryUpdated(); } //-------------------------------------------------------------------------------------------------- @@ -483,53 +508,8 @@ caf::PdmFieldHandle* RimFishbonesMultipleSubs::objectToggleField() //-------------------------------------------------------------------------------------------------- void RimFishbonesMultipleSubs::computeRangesAndLocations() { - if (m_subsLocationMode == FB_SUB_COUNT_END) - { - int divisor = 1; - if (m_rangeSubCount > 2) divisor = m_rangeSubCount - 1; - - m_rangeSubSpacing = fabs(m_rangeStart - m_rangeEnd) / divisor; - } - else if (m_subsLocationMode == FB_SUB_SPACING_END) - { - m_rangeSubCount = (fabs(m_rangeStart - m_rangeEnd) / m_rangeSubSpacing) + 1; - - if (m_rangeSubCount < 1) - { - m_rangeSubCount = 1; - } - } - - if (m_subsLocationMode == FB_SUB_COUNT_END || m_subsLocationMode == FB_SUB_SPACING_END) - { - std::vector validMeasuredDepths; - { - RimWellPath* wellPath = nullptr; - this->firstAncestorOrThisOfTypeAsserted(wellPath); - - RigWellPath* rigWellPathGeo = wellPath->wellPathGeometry(); - if (rigWellPathGeo && rigWellPathGeo->m_measuredDepths.size() > 1) - { - double firstWellPathMD = rigWellPathGeo->m_measuredDepths.front(); - double lastWellPathMD = rigWellPathGeo->m_measuredDepths.back(); - - for (auto md : locationsFromStartSpacingAndCount(m_rangeStart, m_rangeSubSpacing, m_rangeSubCount)) - { - if (md > firstWellPathMD && md < lastWellPathMD) - { - validMeasuredDepths.push_back(md); - } - } - } - } - - m_locationOfSubs = validMeasuredDepths; - } - - RimFishbonesCollection* collection; - this->firstAncestorOrThisOfTypeAsserted(collection); - computeSubLateralIndices(); - collection->recalculateStartMD(); + m_valveLocations->computeRangesAndLocations(); + geometryUpdated(); } //-------------------------------------------------------------------------------------------------- @@ -551,11 +531,6 @@ void RimFishbonesMultipleSubs::defineUiOrdering(QString uiConfigName, caf::PdmUi m_lateralTubingRoghnessFactor.uiCapability()->setUiName("Tubing Roughness Factor [m]"); m_icdOrificeDiameter.uiCapability()->setUiName("ICD Orifice Diameter [mm]"); - - m_locationOfSubs.uiCapability()->setUiName("Measured Depths [m]"); - m_rangeStart.uiCapability()->setUiName("Start MD [m]"); - m_rangeEnd.uiCapability()->setUiName("End MD [m]"); - m_rangeSubSpacing.uiCapability()->setUiName("Spacing [m]"); } else if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD) { @@ -566,11 +541,6 @@ void RimFishbonesMultipleSubs::defineUiOrdering(QString uiConfigName, caf::PdmUi m_lateralTubingRoghnessFactor.uiCapability()->setUiName("Tubing Roughness Factor [ft]"); m_icdOrificeDiameter.uiCapability()->setUiName("ICD Orifice Diameter [in]"); - - m_locationOfSubs.uiCapability()->setUiName("Measured Depths [ft]"); - m_rangeStart.uiCapability()->setUiName("Start MD [ft]"); - m_rangeEnd.uiCapability()->setUiName("End MD [ft]"); - m_rangeSubSpacing.uiCapability()->setUiName("Spacing [ft]"); } } } @@ -581,28 +551,9 @@ void RimFishbonesMultipleSubs::defineUiOrdering(QString uiConfigName, caf::PdmUi group->add(&fishbonesColor); } - { + { caf::PdmUiGroup* group = uiOrdering.addNewGroup("Location"); - - group->add(&m_subsLocationMode); - if (m_subsLocationMode() != FB_SUB_USER_DEFINED) - { - group->add(&m_rangeStart); - group->add(&m_rangeEnd); - - if (m_subsLocationMode() == FB_SUB_COUNT_END) - { - group->add(&m_rangeSubCount); - group->add(&m_rangeSubSpacing); - } - else if (m_subsLocationMode() == FB_SUB_SPACING_END) - { - group->add(&m_rangeSubSpacing); - group->add(&m_rangeSubCount); - } - } - - group->add(&m_locationOfSubs); + m_valveLocations->uiOrdering(uiConfigName, *group); } { @@ -641,38 +592,6 @@ void RimFishbonesMultipleSubs::defineUiOrdering(QString uiConfigName, caf::PdmUi mswGroup->add(&m_icdFlowCoefficient); } - // Visibility - - if (m_subsLocationMode == FB_SUB_USER_DEFINED) - { - m_locationOfSubs.uiCapability()->setUiReadOnly(false); - - m_rangeSubSpacing.uiCapability()->setUiReadOnly(true); - m_rangeSubCount.uiCapability()->setUiReadOnly(true); - m_rangeStart.uiCapability()->setUiReadOnly(true); - m_rangeEnd.uiCapability()->setUiReadOnly(true); - } - else - { - m_locationOfSubs.uiCapability()->setUiReadOnly(true); - - m_rangeSubSpacing.uiCapability()->setUiReadOnly(false); - m_rangeSubCount.uiCapability()->setUiReadOnly(false); - m_rangeStart.uiCapability()->setUiReadOnly(false); - m_rangeEnd.uiCapability()->setUiReadOnly(false); - - if (m_subsLocationMode == FB_SUB_COUNT_END) - { - m_rangeSubSpacing.uiCapability()->setUiReadOnly(true); - m_rangeSubCount.uiCapability()->setUiReadOnly(false); - } - else - { - m_rangeSubSpacing.uiCapability()->setUiReadOnly(false); - m_rangeSubCount.uiCapability()->setUiReadOnly(true); - } - } - uiOrdering.skipRemainingFields(); } @@ -681,7 +600,9 @@ void RimFishbonesMultipleSubs::defineUiOrdering(QString uiConfigName, caf::PdmUi //-------------------------------------------------------------------------------------------------- void RimFishbonesMultipleSubs::initAfterRead() { - if (m_locationOfSubs().size() != m_installationRotationAngles().size()) + initValveLocationFromLegacyData(); + + if (m_valveLocations->valveLocations().size() != m_installationRotationAngles().size()) { computeRotationAngles(); } @@ -691,7 +612,7 @@ void RimFishbonesMultipleSubs::initAfterRead() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::BoundingBox RimFishbonesMultipleSubs::boundingBoxInDomainCoords() +cvf::BoundingBox RimFishbonesMultipleSubs::boundingBoxInDomainCoords() const { cvf::BoundingBox bb; @@ -711,6 +632,17 @@ cvf::BoundingBox RimFishbonesMultipleSubs::boundingBoxInDomainCoords() return bb; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFishbonesMultipleSubs::isEnabled() const +{ + RimFishbonesCollection* collection; + this->firstAncestorOrThisOfTypeAsserted(collection); + + return collection->isChecked() && isActive(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -718,7 +650,7 @@ void RimFishbonesMultipleSubs::computeRotationAngles() { std::vector vals; - for (size_t i = 0; i < m_locationOfSubs().size(); i++) + for (size_t i = 0; i < m_valveLocations->valveLocations().size(); i++) { vals.push_back(RimFishbonesMultipleSubs::randomValueFromRange(0, 360)); } @@ -732,7 +664,7 @@ void RimFishbonesMultipleSubs::computeRotationAngles() void RimFishbonesMultipleSubs::computeSubLateralIndices() { m_subLateralIndices.clear(); - for (size_t subIndex = 0; subIndex < m_locationOfSubs().size(); ++subIndex) + for (size_t subIndex = 0; subIndex < m_valveLocations->valveLocations().size(); ++subIndex) { SubLateralIndex subLateralIndex; subLateralIndex.subIndex = subIndex; @@ -743,7 +675,7 @@ void RimFishbonesMultipleSubs::computeSubLateralIndices() } m_subLateralIndices.push_back(subLateralIndex); } - double numLaterals = static_cast(m_locationOfSubs().size() * m_lateralCountPerSub); + double numLaterals = static_cast(m_valveLocations->valveLocations().size() * m_lateralCountPerSub); int numToRemove = static_cast(std::round((1 - m_lateralInstallSuccessFraction) * numLaterals)); srand(m_randomSeed()); while (numToRemove > 0) @@ -758,21 +690,6 @@ void RimFishbonesMultipleSubs::computeSubLateralIndices() } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimFishbonesMultipleSubs::locationsFromStartSpacingAndCount(double start, double spacing, size_t count) -{ - std::vector measuredDepths; - - for (size_t i = 0; i < count; i++) - { - measuredDepths.push_back(start + spacing * i); - } - - return measuredDepths; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -787,3 +704,54 @@ int RimFishbonesMultipleSubs::randomValueFromRange(int min, int max) return randomValue; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFishbonesMultipleSubs::initialiseObsoleteFields() +{ + CAF_PDM_InitField(&m_subsLocationMode_OBSOLETE, "SubsLocationMode", caf::AppEnum(FB_SUB_UNDEFINED), "Location Defined By", "", "", ""); + m_subsLocationMode_OBSOLETE.xmlCapability()->setIOWritable(false); + + CAF_PDM_InitField(&m_rangeStart_OBSOLETE, "RangeStart", std::numeric_limits::infinity(), "Start MD [m]", "", "", ""); + m_rangeStart_OBSOLETE.xmlCapability()->setIOWritable(false); + + CAF_PDM_InitField(&m_rangeEnd_OBSOLETE, "RangeEnd", std::numeric_limits::infinity(), "End MD [m]", "", "", ""); + m_rangeEnd_OBSOLETE.xmlCapability()->setIOWritable(false); + + CAF_PDM_InitField(&m_rangeSubSpacing_OBSOLETE, "RangeSubSpacing", std::numeric_limits::infinity(), "Spacing [m]", "", "", ""); + m_rangeSubSpacing_OBSOLETE.xmlCapability()->setIOWritable(false); + + CAF_PDM_InitField(&m_rangeSubCount_OBSOLETE, "RangeSubCount", -1, "Number of Subs", "", "", ""); + m_rangeSubCount_OBSOLETE.xmlCapability()->setIOWritable(false); + + CAF_PDM_InitFieldNoDefault(&m_locationOfSubs_OBSOLETE, "LocationOfSubs", "Measured Depths [m]", "", "", ""); + m_locationOfSubs_OBSOLETE.xmlCapability()->setIOWritable(false); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFishbonesMultipleSubs::initValveLocationFromLegacyData() +{ + RimMultipleValveLocations::LocationType locationType = RimMultipleValveLocations::VALVE_UNDEFINED; + if (m_subsLocationMode_OBSOLETE() == FB_SUB_COUNT_END) + { + locationType = RimMultipleValveLocations::VALVE_COUNT; + } + else if (m_subsLocationMode_OBSOLETE() == FB_SUB_SPACING_END) + { + locationType = RimMultipleValveLocations::VALVE_SPACING; + } + else if (m_subsLocationMode_OBSOLETE() == FB_SUB_USER_DEFINED) + { + locationType = RimMultipleValveLocations::VALVE_CUSTOM; + } + + m_valveLocations->initFields(locationType, + m_rangeStart_OBSOLETE(), + m_rangeEnd_OBSOLETE(), + m_rangeSubSpacing_OBSOLETE(), + m_rangeSubCount_OBSOLETE(), + m_locationOfSubs_OBSOLETE()); +} diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h index 0fc81fb520..d43a556003 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesMultipleSubs.h @@ -18,11 +18,12 @@ #pragma once +#include "RiaEclipseUnitTools.h" + #include "RimCheckableNamedObject.h" #include "Rim3dPropertiesInterface.h" #include "RimFishbonesPipeProperties.h" - -#include "RiaEclipseUnitTools.h" +#include "RimWellPathComponentInterface.h" #include "cvfBase.h" #include "cvfVector3.h" @@ -37,6 +38,7 @@ #include class RigFisbonesGeometry; +class RimMultipleValveLocations; //================================================================================================== /// @@ -51,7 +53,7 @@ struct SubLateralIndex { /// /// //================================================================================================== -class RimFishbonesMultipleSubs : public caf::PdmObject, public Rim3dPropertiesInterface +class RimFishbonesMultipleSubs : public caf::PdmObject, public Rim3dPropertiesInterface, public RimWellPathComponentInterface { CAF_PDM_HEADER_INIT; @@ -60,7 +62,8 @@ class RimFishbonesMultipleSubs : public caf::PdmObject, public Rim3dPropertiesIn { FB_SUB_COUNT_END, FB_SUB_SPACING_END, - FB_SUB_USER_DEFINED + FB_SUB_USER_DEFINED, + FB_SUB_UNDEFINED }; enum LateralsOrientationType @@ -71,12 +74,12 @@ class RimFishbonesMultipleSubs : public caf::PdmObject, public Rim3dPropertiesIn public: RimFishbonesMultipleSubs(); - virtual ~RimFishbonesMultipleSubs(); + ~RimFishbonesMultipleSubs() override; bool isActive() const; QString generatedName() const; - void setMeasuredDepthAndCount(double measuredDepth, double spacing, int subCount); + void setMeasuredDepthAndCount(double startMD, double spacing, int subCount); double measuredDepth(size_t subIndex) const; double rotationAngle(size_t subIndex) const; @@ -86,6 +89,7 @@ class RimFishbonesMultipleSubs : public caf::PdmObject, public Rim3dPropertiesIn double tubingDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const; double holeDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const { return m_pipeProperties()->holeDiameter(unitSystem); } + double effectiveDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const; double skinFactor() const { return m_pipeProperties()->skinFactor(); } double openHoleRoughnessFactor(RiaEclipseUnitTools::UnitSystem unitSystem) const; double icdOrificeDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const; @@ -93,6 +97,8 @@ class RimFishbonesMultipleSubs : public caf::PdmObject, public Rim3dPropertiesIn size_t icdCount() const { return m_icdCount(); } std::vector lateralLengths() const; + void geometryUpdated(); + const std::vector& installedLateralIndices() const { return m_subLateralIndices; }; std::vector coordsForLateral(size_t subIndex, size_t lateralIndex) const; std::vector> coordsAndMDForLateral(size_t subIndex, size_t lateralIndex) const; @@ -101,27 +107,37 @@ class RimFishbonesMultipleSubs : public caf::PdmObject, public Rim3dPropertiesIn void setUnitSystemSpecificDefaults(); // Override from Rim3dPropertiesInterface - virtual cvf::BoundingBox boundingBoxInDomainCoords() override; + cvf::BoundingBox boundingBoxInDomainCoords() const override; + + // Overrides from RimWellPathCompletionsInterface + bool isEnabled() const override; + RiaDefines::WellPathComponentType componentType() const override; + QString componentLabel() const override; + QString componentTypeLabel() const override; + cvf::Color3f defaultComponentColor() const override; + double startMD() const override; + double endMD() const override; public: caf::PdmField fishbonesColor; protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual caf::PdmFieldHandle* userDescriptionField() override; - virtual caf::PdmFieldHandle* objectToggleField() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* objectToggleField() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void initAfterRead() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void initAfterRead() override; private: void computeRangesAndLocations(); void computeRotationAngles(); void computeSubLateralIndices(); - static std::vector locationsFromStartSpacingAndCount(double start, double spacing, size_t count); static int randomValueFromRange(int min, int max); - + void initialiseObsoleteFields(); + void initValveLocationFromLegacyData(); + private: caf::PdmField m_isActive; caf::PdmProxyValueField m_name; @@ -143,16 +159,9 @@ class RimFishbonesMultipleSubs : public caf::PdmObject, public Rim3dPropertiesIn caf::PdmField m_icdOrificeDiameter; caf::PdmField m_icdFlowCoefficient; - caf::PdmField > m_subsLocationMode; - caf::PdmField m_rangeStart; - caf::PdmField m_rangeEnd; - caf::PdmField m_rangeSubSpacing; - caf::PdmField m_rangeSubCount; - + caf::PdmChildField m_valveLocations; caf::PdmField > m_subsOrientationMode; - caf::PdmField> m_locationOfSubs; // Given in measured depth - caf::PdmField> m_installationRotationAngles; caf::PdmField m_fixedInstallationRotationAngle; @@ -162,4 +171,13 @@ class RimFishbonesMultipleSubs : public caf::PdmObject, public Rim3dPropertiesIn std::unique_ptr m_rigFishbonesGeometry; std::vector m_subLateralIndices; + + // Moved to RimMultipleValveLocations + caf::PdmField > m_subsLocationMode_OBSOLETE; + caf::PdmField m_rangeStart_OBSOLETE; + caf::PdmField m_rangeEnd_OBSOLETE; + caf::PdmField m_rangeSubSpacing_OBSOLETE; + caf::PdmField m_rangeSubCount_OBSOLETE; + caf::PdmField> m_locationOfSubs_OBSOLETE; // Given in measured depth + }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesPipeProperties.h b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesPipeProperties.h index 4a62a15e93..64a3e06ead 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFishbonesPipeProperties.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFishbonesPipeProperties.h @@ -40,7 +40,7 @@ class RimFishbonesPipeProperties : public caf::PdmObject public: RimFishbonesPipeProperties(); - virtual ~RimFishbonesPipeProperties(); + ~RimFishbonesPipeProperties() override; double skinFactor() const { return m_skinFactor(); } double holeDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const; @@ -48,7 +48,7 @@ class RimFishbonesPipeProperties : public caf::PdmObject void setUnitSystemSpecificDefaults(); protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: caf::PdmField m_skinFactor; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFracture.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFracture.cpp index 8edc8a8dc1..126f076068 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFracture.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFracture.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -19,23 +19,14 @@ #include "RimFracture.h" #include "RiaApplication.h" +#include "RiaColorTables.h" #include "RiaCompletionTypeCalculationScheduler.h" #include "RiaEclipseUnitTools.h" #include "RiaLogging.h" -#include "RifReaderInterface.h" - -#include "RigActiveCellInfo.h" -#include "RigCaseCellResultsData.h" -#include "RigCell.h" -#include "RigCellGeometryTools.h" -#include "RigEclipseCaseData.h" -#include "RigHexIntersectionTools.h" #include "RigMainGrid.h" -#include "RigResultAccessor.h" -#include "RigResultAccessorFactory.h" -#include "RigTesselatorTools.h" +#include "Rim3dView.h" #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" @@ -46,9 +37,9 @@ #include "RimOilField.h" #include "RimProject.h" #include "RimReservoirCellResultsStorage.h" -#include "RimStimPlanFractureTemplate.h" #include "RimStimPlanColors.h" -#include "Rim3dView.h" +#include "RimStimPlanFractureTemplate.h" +#include "RimWellPathFractureCollection.h" #include "RivWellFracturePartMgr.h" @@ -57,8 +48,6 @@ #include "cafPdmUiDoubleSliderEditor.h" #include "cafPdmUiTreeOrdering.h" -#include "clipper/clipper.hpp" - #include "cvfBoundingBox.h" #include "cvfGeometryTools.h" #include "cvfMath.h" @@ -73,12 +62,12 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimFracture, "Fracture"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void setDefaultFractureColorResult() { - RiaApplication* app = RiaApplication::instance(); - RimProject* proj = app->project(); + RiaApplication* app = RiaApplication::instance(); + RimProject* proj = app->project(); for (RimEclipseCase* const eclCase : proj->eclipseCases()) { @@ -96,10 +85,12 @@ void setDefaultFractureColorResult() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimFracture::RimFracture(void) +RimFracture::RimFracture() { + // clang-format off + CAF_PDM_InitObject("Fracture", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_fractureTemplate, "FractureDef", "Fracture Template", "", "", ""); @@ -144,17 +135,17 @@ RimFracture::RimFracture(void) m_wellFractureAzimuthAngleWarning.xmlCapability()->disableIO(); m_fracturePartMgr = new RivWellFracturePartMgr(this); + + // clang-format on } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimFracture::~RimFracture() -{ -} +RimFracture::~RimFracture() {} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RimFracture::perforationLength() const { @@ -162,7 +153,7 @@ double RimFracture::perforationLength() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RimFracture::perforationEfficiency() const { @@ -170,7 +161,7 @@ double RimFracture::perforationEfficiency() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFracture::setStimPlanTimeIndexToPlot(int timeIndex) { @@ -178,9 +169,9 @@ void RimFracture::setStimPlanTimeIndexToPlot(int timeIndex) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RimFracture::getPotentiallyFracturedCells(const RigMainGrid* mainGrid) +std::vector RimFracture::getPotentiallyFracturedCells(const RigMainGrid* mainGrid) const { std::vector cellindecies; if (!mainGrid) return cellindecies; @@ -193,7 +184,7 @@ std::vector RimFracture::getPotentiallyFracturedCells(const RigMainGrid* } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { @@ -203,14 +194,15 @@ void RimFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedField, cons { QString fractureUnitText = RiaEclipseUnitTools::UnitSystemType::uiText(fractureUnit()); - QString warningText = QString("Using a fracture template defined in a different unit is not supported.\n\nPlease select a " - "fracture template of unit '%1'") - .arg(fractureUnitText); + QString warningText = + QString("Using a fracture template defined in a different unit is not supported.\n\nPlease select a " + "fracture template of unit '%1'") + .arg(fractureUnitText); QMessageBox::warning(nullptr, "Fracture Template Selection", warningText); - PdmObjectHandle* prevValue = oldValue.value>().rawPtr(); - auto prevTemplate = dynamic_cast(prevValue); + PdmObjectHandle* prevValue = oldValue.value>().rawPtr(); + auto prevTemplate = dynamic_cast(prevValue); m_fractureTemplate = prevTemplate; } @@ -219,37 +211,34 @@ void RimFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedField, cons setDefaultFractureColorResult(); } - if (changedField == &m_azimuth || - changedField == &m_fractureTemplate || - changedField == &m_stimPlanTimeIndexToPlot || - changedField == this->objectToggleField() || - changedField == &m_dip || - changedField == &m_tilt || - changedField == &m_perforationLength) + if ( changedField == &m_azimuth + || changedField == &m_fractureTemplate + || changedField == &m_stimPlanTimeIndexToPlot + || changedField == this->objectToggleField() + || changedField == &m_dip + || changedField == &m_tilt + || changedField == &m_perforationLength) { - RimEclipseView* rimView = nullptr; - this->firstAncestorOrThisOfType(rimView); - if (rimView) + clearCachedNonDarcyProperties(); + + RimEclipseCase* eclipseCase = nullptr; + this->firstAncestorOrThisOfType(eclipseCase); + if ( eclipseCase ) { - RimEclipseCase* eclipseCase = nullptr; - rimView->firstAncestorOrThisOfType(eclipseCase); - if (eclipseCase) - { - RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews(eclipseCase); - } + RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews( + eclipseCase); } else { - // Can be triggered from well path, find active view - RimProject* proj; - this->firstAncestorOrThisOfTypeAsserted(proj); - proj->reloadCompletionTypeResultsInAllViews(); + RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews(); } + + RiaApplication::instance()->project()->scheduleCreateDisplayModelAndRedrawAllViews(); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::Vec3d RimFracture::fracturePosition() const { @@ -257,7 +246,121 @@ cvf::Vec3d RimFracture::fracturePosition() const } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +const NonDarcyData& RimFracture::nonDarcyProperties() const +{ + CVF_ASSERT(!m_cachedFractureProperties.isDirty()); + + return m_cachedFractureProperties; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFracture::ensureValidNonDarcyProperties() +{ + if (m_cachedFractureProperties.isDirty()) + { + NonDarcyData props; + + if (m_fractureTemplate) + { + props.width = m_fractureTemplate->computeFractureWidth(this); + props.conductivity = m_fractureTemplate->computeKh(this); + props.dFactor = m_fractureTemplate->computeDFactor(this); + props.effectivePermeability = m_fractureTemplate->computeEffectivePermeability(this); + props.eqWellRadius = m_fractureTemplate->computeWellRadiusForDFactorCalculation(this); + props.betaFactor = m_fractureTemplate->getOrComputeBetaFactor(this); + + props.isDataDirty = false; + } + m_cachedFractureProperties = props; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFracture::clearCachedNonDarcyProperties() +{ + m_cachedFractureProperties = NonDarcyData(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFracture::isEnabled() const +{ + RimWellPathFractureCollection* fractureCollection = nullptr; + this->firstAncestorOrThisOfTypeAsserted(fractureCollection); + return fractureCollection->isChecked() && isChecked(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::WellPathComponentType RimFracture::componentType() const +{ + return RiaDefines::FRACTURE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimFracture::componentLabel() const +{ + return name(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimFracture::componentTypeLabel() const +{ + return "Fracture"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RimFracture::defaultComponentColor() const +{ + return RiaColorTables::wellPathComponentColors()[componentType()]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFracture::startMD() const +{ + if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) + { + return fractureMD() - 0.5*perforationLength(); + } + else + { + return fractureMD(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFracture::endMD() const +{ + if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) + { + return startMD() + perforationLength(); + } + else + { + return startMD() + fractureTemplate()->computeFractureWidth(this); + } +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- double RimFracture::wellFractureAzimuthDiff() const { @@ -266,7 +369,7 @@ double RimFracture::wellFractureAzimuthDiff() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QString RimFracture::wellFractureAzimuthDiffText() const { @@ -281,24 +384,24 @@ QString RimFracture::wellAzimuthAtFracturePositionText() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -cvf::BoundingBox RimFracture::boundingBoxInDomainCoords() +cvf::BoundingBox RimFracture::boundingBoxInDomainCoords() const { std::vector nodeCoordVec; - std::vector triangleIndices; + std::vector triangleIndices; this->triangleGeometry(&triangleIndices, &nodeCoordVec); cvf::BoundingBox fractureBBox; - for (const auto& nodeCoord : nodeCoordVec) fractureBBox.add(nodeCoord); - + for (const auto& nodeCoord : nodeCoordVec) + fractureBBox.add(nodeCoord); + return fractureBBox; } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RimFracture::wellRadius() const { @@ -315,7 +418,7 @@ double RimFracture::wellRadius() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::Vec3d RimFracture::anchorPosition() const { @@ -323,7 +426,7 @@ cvf::Vec3d RimFracture::anchorPosition() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::Mat4d RimFracture::transformMatrix() const { @@ -335,12 +438,11 @@ cvf::Mat4d RimFracture::transformMatrix() const // Dip (out of XY plane) cvf::Mat4d tiltRotation = cvf::Mat4d::fromRotation(cvf::Vec3d::X_AXIS, cvf::Math::toRadians(m_tilt())); - // Ellipsis geometry is produced in XY-plane, rotate 90 deg around X to get zero azimuth along Y cvf::Mat4d rotationFromTesselator = cvf::Mat4d::fromRotation(cvf::Vec3d::X_AXIS, cvf::Math::toRadians(90.0f)); - + // Azimuth rotation - cvf::Mat4d azimuthRotation = cvf::Mat4d::fromRotation(cvf::Vec3d::Z_AXIS, cvf::Math::toRadians(-m_azimuth()-90)); + cvf::Mat4d azimuthRotation = cvf::Mat4d::fromRotation(cvf::Vec3d::Z_AXIS, cvf::Math::toRadians(-m_azimuth() - 90)); cvf::Mat4d m = azimuthRotation * rotationFromTesselator * dipRotation * tiltRotation; m.setTranslation(center); @@ -349,7 +451,23 @@ cvf::Mat4d RimFracture::transformMatrix() const } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +double RimFracture::dip() const +{ + return m_dip(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFracture::tilt() const +{ + return m_tilt(); +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RimFracture::setFractureTemplateNoUpdate(RimFractureTemplate* fractureTemplate) { @@ -371,9 +489,9 @@ void RimFracture::setFractureTemplateNoUpdate(RimFractureTemplate* fractureTempl } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimFracture::triangleGeometry(std::vector* triangleIndices, std::vector* nodeCoords) +void RimFracture::triangleGeometry(std::vector* triangleIndices, std::vector* nodeCoords) const { RimFractureTemplate* fractureDef = fractureTemplate(); if (fractureDef) @@ -394,7 +512,7 @@ void RimFracture::triangleGeometry(std::vector* triangleIndices, std: } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::Vec3d RimFracture::fracturePositionForUi() const { @@ -406,9 +524,10 @@ cvf::Vec3d RimFracture::fracturePositionForUi() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QList RimFracture::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +QList RimFracture::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) { QList options; @@ -442,15 +561,14 @@ QList RimFracture::calculateValueOptions(const caf::PdmF if (dynamic_cast(fracTemplate)) { RimStimPlanFractureTemplate* fracTemplateStimPlan = dynamic_cast(fracTemplate); - std::vector timeValues = fracTemplateStimPlan->timeSteps(); - int index = 0; + std::vector timeValues = fracTemplateStimPlan->timeSteps(); + int index = 0; for (double value : timeValues) { options.push_back(caf::PdmOptionItemInfo(QString::number(value), index)); index++; } } - } } @@ -458,7 +576,7 @@ QList RimFracture::calculateValueOptions(const caf::PdmF } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFracture::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { @@ -475,8 +593,8 @@ void RimFracture::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiO if (fractureTemplate()) { - if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH - || fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) + if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH || + fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) { m_uiWellPathAzimuth.uiCapability()->setUiHidden(true); m_uiWellFractureAzimuthDiff.uiCapability()->setUiHidden(true); @@ -487,9 +605,8 @@ void RimFracture::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiO { m_uiWellPathAzimuth.uiCapability()->setUiHidden(false); m_uiWellFractureAzimuthDiff.uiCapability()->setUiHidden(false); - if (wellFractureAzimuthDiff() < 10 - || (wellFractureAzimuthDiff() > 170 && wellFractureAzimuthDiff() < 190 ) - || wellFractureAzimuthDiff() > 350) + if (wellFractureAzimuthDiff() < 10 || (wellFractureAzimuthDiff() > 170 && wellFractureAzimuthDiff() < 190) || + wellFractureAzimuthDiff() > 350) { m_wellFractureAzimuthAngleWarning.uiCapability()->setUiHidden(false); } @@ -499,8 +616,8 @@ void RimFracture::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiO } } - if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH - || fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) + if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH || + fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) { m_azimuth.uiCapability()->setUiReadOnly(true); } @@ -548,9 +665,11 @@ void RimFracture::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiO } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimFracture::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) +void RimFracture::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) { if (field == &m_azimuth) { @@ -574,7 +693,7 @@ void RimFracture::defineEditorAttribute(const caf::PdmFieldHandle* field, QStrin } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFracture::setAnchorPosition(const cvf::Vec3d& pos) { @@ -582,7 +701,7 @@ void RimFracture::setAnchorPosition(const cvf::Vec3d& pos) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RiaEclipseUnitTools::UnitSystem RimFracture::fractureUnit() const { @@ -590,7 +709,7 @@ RiaEclipseUnitTools::UnitSystem RimFracture::fractureUnit() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFracture::setFractureUnit(RiaEclipseUnitTools::UnitSystem unitSystem) { @@ -598,55 +717,21 @@ void RimFracture::setFractureUnit(RiaEclipseUnitTools::UnitSystem unitSystem) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -bool RimFracture::isEclipseCellWithinContainment(const RigMainGrid* mainGrid, size_t globalCellIndex) const +bool RimFracture::isEclipseCellOpenForFlow(const RigMainGrid* mainGrid, + const std::set& reservoirCellIndicesOpenForFlow, + size_t globalCellIndex) const { CVF_ASSERT(fractureTemplate()); if (!fractureTemplate()->fractureContainment()->isEnabled()) return true; - size_t anchorEclipseCell = findAnchorEclipseCell(mainGrid); - return fractureTemplate()->fractureContainment()->isEclipseCellWithinContainment(mainGrid, anchorEclipseCell, globalCellIndex); + return fractureTemplate()->fractureContainment()->isEclipseCellOpenForFlow( + mainGrid, globalCellIndex, reservoirCellIndicesOpenForFlow); } //-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -size_t RimFracture::findAnchorEclipseCell(const RigMainGrid* mainGrid ) const -{ - cvf::BoundingBox pointBBox; - pointBBox.add(m_anchorPosition); - - std::vector cellIndices; - mainGrid->findIntersectingCells(pointBBox, &cellIndices); - - size_t cellContainingAchorPoint = cvf::UNDEFINED_SIZE_T; - - for ( size_t cellIndex : cellIndices ) - { - auto cornerIndices = mainGrid->globalCellArray()[cellIndex].cornerIndices(); - cvf::Vec3d vertices[8]; - vertices[0] = (mainGrid->nodes()[cornerIndices[0]]); - vertices[1] = (mainGrid->nodes()[cornerIndices[1]]); - vertices[2] = (mainGrid->nodes()[cornerIndices[2]]); - vertices[3] = (mainGrid->nodes()[cornerIndices[3]]); - vertices[4] = (mainGrid->nodes()[cornerIndices[4]]); - vertices[5] = (mainGrid->nodes()[cornerIndices[5]]); - vertices[6] = (mainGrid->nodes()[cornerIndices[6]]); - vertices[7] = (mainGrid->nodes()[cornerIndices[7]]); - - if ( RigHexIntersectionTools::isPointInCell(m_anchorPosition, vertices) ) - { - cellContainingAchorPoint = cellIndex; - break; - } - } - - return cellContainingAchorPoint; -} - -//-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFracture::setFractureTemplate(RimFractureTemplate* fractureTemplate) { @@ -671,12 +756,14 @@ void RimFracture::setFractureTemplate(RimFractureTemplate* fractureTemplate) { this->updateAzimuthBasedOnWellAzimuthAngle(); } - this->m_wellDiameter = fractureTemplate->wellDiameter(); + this->m_wellDiameter = fractureTemplate->wellDiameter(); this->m_perforationLength = fractureTemplate->perforationLength(); + + clearCachedNonDarcyProperties(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimFractureTemplate* RimFracture::fractureTemplate() const { @@ -684,7 +771,7 @@ RimFractureTemplate* RimFracture::fractureTemplate() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RivWellFracturePartMgr* RimFracture::fracturePartManager() { @@ -692,4 +779,3 @@ RivWellFracturePartMgr* RimFracture::fracturePartManager() return m_fracturePartMgr.p(); } - diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFracture.h b/ApplicationCode/ProjectDataModel/Completions/RimFracture.h index 915822e312..72568c69c4 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFracture.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFracture.h @@ -22,12 +22,12 @@ #include "Rim3dPropertiesInterface.h" #include "RimCheckableNamedObject.h" +#include "RimWellPathComponentInterface.h" #include "cvfBase.h" #include "cvfObject.h" #include "cvfVector3.h" #include "cvfMatrix4.h" -#include "cvfPlane.h" #include "cafPdmChildField.h" #include "cafPdmFieldCvfVec3d.h" @@ -42,18 +42,45 @@ class RimFractureTemplate; class RigFracturedEclipseCellExportData; class RigMainGrid; +class NonDarcyData +{ +public: + NonDarcyData() + : width(std::numeric_limits::infinity()) + , conductivity(std::numeric_limits::infinity()) + , effectivePermeability(std::numeric_limits::infinity()) + , dFactor(std::numeric_limits::infinity()) + , eqWellRadius(std::numeric_limits::infinity()) + , betaFactor(std::numeric_limits::infinity()) + , isDataDirty(true) + { + } + + bool isDirty() const + { + return isDataDirty; + } + + double eqWellRadius; + double width; + double conductivity; + double effectivePermeability; + double dFactor; + double betaFactor; + bool isDataDirty; +}; //================================================================================================== /// /// //================================================================================================== -class RimFracture : public RimCheckableNamedObject, public Rim3dPropertiesInterface +class RimFracture : public RimCheckableNamedObject, public Rim3dPropertiesInterface, public RimWellPathComponentInterface { CAF_PDM_HEADER_INIT; public: RimFracture(void); - virtual ~RimFracture(void); + ~RimFracture(void) override; double perforationLength() const; double perforationEfficiency() const; @@ -61,16 +88,18 @@ class RimFracture : public RimCheckableNamedObject, public Rim3dPropertiesInterf void setStimPlanTimeIndexToPlot(int timeIndex); double wellRadius() const; - cvf::Vec3d anchorPosition() const ; + cvf::Vec3d anchorPosition() const; void setAnchorPosition(const cvf::Vec3d& pos); RiaEclipseUnitTools::UnitSystem fractureUnit() const; void setFractureUnit(RiaEclipseUnitTools::UnitSystem unitSystem); - bool isEclipseCellWithinContainment(const RigMainGrid* mainGrid, - size_t globalCellIndex) const; - size_t findAnchorEclipseCell(const RigMainGrid* mainGrid) const; + bool isEclipseCellOpenForFlow(const RigMainGrid* mainGrid, + const std::set& reservoirCellIndicesOpenForFlow, + size_t globalCellIndex) const; - cvf::Mat4d transformMatrix() const; + cvf::Mat4d transformMatrix() const; + double dip() const; + double tilt() const; void setFractureTemplateNoUpdate(RimFractureTemplate* fractureTemplate); void setFractureTemplate(RimFractureTemplate* fractureTemplate); @@ -78,11 +107,10 @@ class RimFracture : public RimCheckableNamedObject, public Rim3dPropertiesInterf RivWellFracturePartMgr* fracturePartManager(); - void triangleGeometry(std::vector* triangleIndices, std::vector* vxCoords ); - std::vector getPotentiallyFracturedCells(const RigMainGrid* mainGrid); + std::vector getPotentiallyFracturedCells(const RigMainGrid* mainGrid) const; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; cvf::Vec3d fracturePosition() const; virtual void updateAzimuthBasedOnWellAzimuthAngle() = 0; @@ -91,22 +119,38 @@ class RimFracture : public RimCheckableNamedObject, public Rim3dPropertiesInterf virtual void loadDataAndUpdate() = 0; virtual std::vector perforationLengthCenterLineCoords() const = 0; + + + // Fracture properties + const NonDarcyData& nonDarcyProperties() const; + void ensureValidNonDarcyProperties(); + void clearCachedNonDarcyProperties(); friend class RimFractureTemplate; + // RimWellPathCompletionsInterface overrides. + bool isEnabled() const override; + RiaDefines::WellPathComponentType componentType() const override; + QString componentLabel() const override; + QString componentTypeLabel() const override; + cvf::Color3f defaultComponentColor() const override; + double startMD() const override; + double endMD() const override; + protected: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) override; + QList 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: cvf::Vec3d fracturePositionForUi() const; double wellFractureAzimuthDiff() const; + void triangleGeometry(std::vector* triangleIndices, std::vector* vxCoords ) const; QString wellFractureAzimuthDiffText() const; QString wellAzimuthAtFracturePositionText() const; - virtual cvf::BoundingBox boundingBoxInDomainCoords() override; + cvf::BoundingBox boundingBoxInDomainCoords() const override; protected: caf::PdmPtrField m_fractureTemplate; @@ -129,4 +173,6 @@ class RimFracture : public RimCheckableNamedObject, public Rim3dPropertiesInterf caf::PdmField m_anchorPosition; cvf::ref m_fracturePartMgr; + + NonDarcyData m_cachedFractureProperties; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureContainment.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFractureContainment.cpp index 3d303b5e2c..8bc88743ac 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFractureContainment.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureContainment.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -20,104 +20,97 @@ #include "RigMainGrid.h" +#include "RimFractureTemplate.h" #include "RimProject.h" -#include "cafPdmUiSliderEditor.h" - - CAF_PDM_SOURCE_INIT(RimFractureContainment, "FractureContainment"); -namespace caf -{ -template<> -void caf::AppEnum< RimFractureContainment::FaultTruncType>::setUp() -{ - addItem(RimFractureContainment::DISABLED, "DISABLED", "Disable"); - addItem(RimFractureContainment::TRUNCATE_AT_FAULT, "TRUNCATE_AT_FAULT", "Truncate At Faults"); - addItem(RimFractureContainment::CONTINUE_IN_CONTAINMENT_ZONE, "CONTINUE_IN_CONTAINMENT_ZONE", "Continue in Containment Zone"); - - setDefault(RimFractureContainment::DISABLED); -} -} - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimFractureContainment::RimFractureContainment() { CAF_PDM_InitObject("Fracture Containment", "", "", ""); - CAF_PDM_InitField(&m_isUsingFractureContainment, "IsUsingFractureContainment", false, "Fracture Containment", "", "", ""); - CAF_PDM_InitField(&m_topKLayer, "TopKLayer", 0, "Top Layer", "", "", ""); - //m_topKLayer.uiCapability()->setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); - CAF_PDM_InitField(&m_baseKLayer, "BaseKLayer", 0, "Base Layer", "", "", ""); - //m_topKLayer.uiCapability()->setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); - - // This field is not active yet. - CAF_PDM_InitFieldNoDefault(&m_faultTruncation, "FaultTruncationType", "Fault Truncation", "", "", ""); - m_faultTruncation.uiCapability()->setUiHidden(true); - m_faultTruncation.xmlCapability()->setIOWritable(false); // When in operation, remove + CAF_PDM_InitField(&m_useContainment, "IsUsingFractureContainment", false, "Use Containment", "", "", ""); + CAF_PDM_InitField(&m_topKLayer, "TopKLayer", 0, " Top Layer", "", "Do not allow fracture to grow into this layer", ""); + CAF_PDM_InitField(&m_baseKLayer, "BaseKLayer", 0, " Base Layer", "", "Do not allow fracture to grow into this layer", ""); + CAF_PDM_InitField(&m_truncateAtFaults, "TruncateAtFaults", false, "Truncate At Faults", "", "If Fault Throw is larger than limit, truncate at fault", ""); + CAF_PDM_InitField(&m_minimumFaultThrow, "FaultThrowValue", 0.0f, " Minimum Fault Throw", "", "If Fault Throw is larger than limit, truncate at fault", ""); } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +RimFractureContainment::~RimFractureContainment() {} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- -RimFractureContainment::~RimFractureContainment() +double RimFractureContainment::minimumFaultThrow() const { + if (m_truncateAtFaults()) + { + return m_minimumFaultThrow; + } + return -1.0; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QList RimFractureContainment::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, - bool* useOptionsOnly) +bool RimFractureContainment::isEnabled() const { - QList options; - if (fieldNeedingOptions == &m_faultTruncation) - { - options.push_back(caf::PdmOptionItemInfo(caf::AppEnum< FaultTruncType >::uiText(DISABLED), DISABLED)); - options.push_back(caf::PdmOptionItemInfo(caf::AppEnum< FaultTruncType >::uiText(TRUNCATE_AT_FAULT), TRUNCATE_AT_FAULT)); - if (m_isUsingFractureContainment()) - { - options.push_back(caf::PdmOptionItemInfo(caf::AppEnum< FaultTruncType >::uiText(CONTINUE_IN_CONTAINMENT_ZONE), CONTINUE_IN_CONTAINMENT_ZONE)); - } - } - return options; + return (m_useContainment() || m_truncateAtFaults()); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -bool RimFractureContainment::isEclipseCellWithinContainment(const RigMainGrid* mainGrid, size_t anchorEclipseCell, size_t globalCellIndex) const +bool RimFractureContainment::isEclipseCellOpenForFlow(const RigMainGrid* mainGrid, + size_t globalCellIndex, + const std::set& reservoirCellIndicesOpenForFlow) const { - if (!this->m_isUsingFractureContainment()) return true; + if (!isEnabled()) return true; - CVF_ASSERT(mainGrid); + if (m_useContainment()) + { + CVF_ASSERT(mainGrid); - size_t i, j, k; - if (globalCellIndex >= mainGrid->globalCellArray().size()) return false; + if (globalCellIndex >= mainGrid->globalCellArray().size()) return false; - mainGrid->ijkFromCellIndex(globalCellIndex, &i, &j, &k); + auto cell = mainGrid->globalCellArray()[globalCellIndex]; + auto mainGridCellIndex = cell.mainGridCellIndex(); - if (k + 1 < static_cast(m_topKLayer())) - { - return false; + size_t i, j, k; + mainGrid->ijkFromCellIndex(mainGridCellIndex, &i, &j, &k); + + if (k + 1 < static_cast(m_topKLayer())) + { + return false; + } + + if (k + 1 > static_cast(m_baseKLayer())) + { + return false; + } } - if (k + 1 > static_cast(m_baseKLayer())) + if (m_truncateAtFaults()) { - return false; + if (reservoirCellIndicesOpenForFlow.count(globalCellIndex) == 0) + { + return false; + } } - // Todo: use fault propagation mode - return true; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFractureContainment::setTopKLayer(int topKLayer) { @@ -125,7 +118,15 @@ void RimFractureContainment::setTopKLayer(int topKLayer) } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +int RimFractureContainment::topKLayer() const +{ + return m_topKLayer; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RimFractureContainment::setBaseKLayer(int baseKLayer) { @@ -133,23 +134,38 @@ void RimFractureContainment::setBaseKLayer(int baseKLayer) } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +int RimFractureContainment::baseKLayer() const +{ + return m_baseKLayer; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RimFractureContainment::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { - uiOrdering.add(&m_isUsingFractureContainment); + uiOrdering.add(&m_useContainment); uiOrdering.add(&m_topKLayer); uiOrdering.add(&m_baseKLayer); - //uiOrdering.add(&m_faultTruncation); + + m_topKLayer.uiCapability()->setUiReadOnly(!m_useContainment()); + m_baseKLayer.uiCapability()->setUiReadOnly(!m_useContainment()); + + uiOrdering.add(&m_truncateAtFaults); + uiOrdering.add(&m_minimumFaultThrow); + + m_minimumFaultThrow.uiCapability()->setUiReadOnly(!m_truncateAtFaults()); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimFractureContainment::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimFractureContainment::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { - if (changedField == &m_isUsingFractureContainment - || m_isUsingFractureContainment()) { RimProject* proj; this->firstAncestorOrThisOfType(proj); @@ -158,5 +174,14 @@ void RimFractureContainment::fieldChangedByUi(const caf::PdmFieldHandle* changed proj->reloadCompletionTypeResultsInAllViews(); } } -} + if (changedField == &m_useContainment || changedField == &m_truncateAtFaults) + { + RimFractureTemplate* fractureTemplate = nullptr; + this->firstAncestorOrThisOfType(fractureTemplate); + if (fractureTemplate) + { + fractureTemplate->updateConnectedEditors(); + } + } +} diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureContainment.h b/ApplicationCode/ProjectDataModel/Completions/RimFractureContainment.h index c5c3257762..654bf09ca2 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFractureContainment.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureContainment.h @@ -1,65 +1,60 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "cafPdmObject.h" #include "cafPdmField.h" -#include "cafAppEnum.h" +#include "cafPdmObject.h" class RigMainGrid; -class RimFractureContainment : public caf::PdmObject +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RimFractureContainment : public caf::PdmObject { CAF_PDM_HEADER_INIT; public: RimFractureContainment(); - ~RimFractureContainment(); - - enum FaultTruncType - { - DISABLED, - TRUNCATE_AT_FAULT, - CONTINUE_IN_CONTAINMENT_ZONE - }; + ~RimFractureContainment() override; - bool isEnabled() const { return m_isUsingFractureContainment();} - bool isEclipseCellWithinContainment(const RigMainGrid* mainGrid, size_t anchorEclipseCell, size_t globalCellIndex) const; + bool isEnabled() const; + bool isEclipseCellOpenForFlow(const RigMainGrid* mainGrid, + size_t globalCellIndex, + const std::set& reservoirCellIndicesOpenForFlow) const; void setTopKLayer(int topKLayer); - void setBaseKLayer(int baseKLayer); + int topKLayer() const; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - -protected: + void setBaseKLayer(int baseKLayer); + int baseKLayer() const; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + double minimumFaultThrow() const; // Negative value means do not test for fault throw private: - friend caf::AppEnum< FaultTruncType >; - caf::PdmField< caf::AppEnum< FaultTruncType > > m_faultTruncation; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - caf::PdmField m_isUsingFractureContainment; +private: + caf::PdmField m_useContainment; caf::PdmField m_topKLayer; caf::PdmField m_baseKLayer; + caf::PdmField m_truncateAtFaults; + caf::PdmField m_minimumFaultThrow; }; - - - diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureContainmentTools.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFractureContainmentTools.cpp new file mode 100644 index 0000000000..2610d27830 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureContainmentTools.cpp @@ -0,0 +1,283 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimFractureContainmentTools.h" + +#include "RigEclipseCaseData.h" +#include "RigFault.h" +#include "RigHexIntersectionTools.h" +#include "RigMainGrid.h" +#include "RigReservoirGridTools.h" + +#include "RimEclipseCase.h" +#include "RimEclipseView.h" +#include "RimFracture.h" +#include "RimFractureContainment.h" +#include "RimFractureTemplate.h" + +#include "cvfStructGrid.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t findNeighborReservoirCellIndex(const RigMainGrid* mainGrid, + cvf::StructGridInterface::FaceType face, + size_t globalReservoirCellIndex) +{ + size_t neighborGlobalReservoirCellIndex = cvf::UNDEFINED_SIZE_T; + + if (mainGrid) + { + size_t gridLocalCellIndex = cvf::UNDEFINED_SIZE_T; + const RigGridBase* hostGrid = + mainGrid->gridAndGridLocalIdxFromGlobalCellIdx(globalReservoirCellIndex, &gridLocalCellIndex); + + if (hostGrid && gridLocalCellIndex != cvf::UNDEFINED_SIZE_T) + { + size_t i, j, k; + hostGrid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k); + + size_t neighborGridLocalCellIndex; + + bool foundCell = hostGrid->cellIJKNeighbor(i, j, k, face, &neighborGridLocalCellIndex); + if (foundCell) + { + neighborGlobalReservoirCellIndex = hostGrid->reservoirCellIndex(neighborGridLocalCellIndex); + } + } + } + + return neighborGlobalReservoirCellIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFractureContainmentTools::appendNeighborCellForFace(const std::set& allFracturedCells, + const RigMainGrid* mainGrid, + size_t currentCell, + cvf::StructGridInterface::FaceType face, + std::set& connectedCells, + double minimumFaultThrow) +{ + size_t candidate = findNeighborReservoirCellIndex(mainGrid, face, currentCell); + if (candidate != cvf::UNDEFINED_SIZE_T) + { + appendNeighborCells(allFracturedCells, mainGrid, candidate, connectedCells, minimumFaultThrow); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double computeAverageZForTwoDeepestZ(const RigMainGrid* mainGrid, + size_t globalReservoirCellIndex, + cvf::StructGridInterface::FaceType face) +{ + cvf::Vec3d hexCorners[8]; + mainGrid->cellCornerVertices(globalReservoirCellIndex, hexCorners); + + double avgZ = 0.0; + + cvf::ubyte faceVertexIndices[4]; + cvf::StructGridInterface::cellFaceVertexIndices(face, faceVertexIndices); + + for (const auto& faceIdx : faceVertexIndices) + { + // Face indices 0-3 are defined to have deepest Z + // See void StructGridInterface::cellFaceVertexIndices(FaceType face, cvf::ubyte vertexIndices[4]) + + if (faceIdx < 4) + { + avgZ += hexCorners[faceIdx].z(); + } + } + + avgZ /= 2.0; + + return avgZ; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFractureContainmentTools::checkFaultAndAppendNeighborCell(const std::set& allFracturedCells, + const RigMainGrid* mainGrid, + size_t globalReservoirCellIndex, + cvf::StructGridInterface::FaceType face, + std::set& connectedCells, + double minimumFaultThrow) +{ + const RigFault* fault = mainGrid->findFaultFromCellIndexAndCellFace(globalReservoirCellIndex, face); + if (fault) + { + { + // See RigMainGrid::calculateFaults() for reference + + // This function is intended to support fractures in LGR-grids + // Currently, only faults in main grid is supported when reading fault specifications from input text files + // Eclipse 300 supports faults in LGR + // https://github.com/OPM/ResInsight/issues/3019 + + size_t neighborGlobalReservoirCellIndex = findNeighborReservoirCellIndex(mainGrid, face, globalReservoirCellIndex); + if (neighborGlobalReservoirCellIndex == cvf::UNDEFINED_SIZE_T) + { + // This is probably an assert condition, but we return directly to ensure we are robust + return; + } + + double currentCellAvgZ = computeAverageZForTwoDeepestZ(mainGrid, globalReservoirCellIndex, face); + double neighborCellAvgZ = computeAverageZForTwoDeepestZ( + mainGrid, neighborGlobalReservoirCellIndex, cvf::StructGridInterface::oppositeFace(face)); + + double faultThrow = fabs(currentCellAvgZ - neighborCellAvgZ); + if (faultThrow > minimumFaultThrow) + { + return; + } + } + } + + appendNeighborCellForFace(allFracturedCells, mainGrid, globalReservoirCellIndex, face, connectedCells, minimumFaultThrow); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFractureContainmentTools::appendNeighborCells(const std::set& allFracturedCells, + const RigMainGrid* mainGrid, + size_t currentCell, + std::set& connectedCells, + double minimumFaultThrow) +{ + if (std::find(connectedCells.begin(), connectedCells.end(), currentCell) != connectedCells.end()) + { + // currentCell is already handled + return; + } + + if (std::find(allFracturedCells.begin(), allFracturedCells.end(), currentCell) == allFracturedCells.end()) + { + // currentCell is not found among the set of fracture cells + return; + } + + connectedCells.insert(currentCell); + + // Check faults in IJ directions + checkFaultAndAppendNeighborCell( + allFracturedCells, mainGrid, currentCell, cvf::StructGridInterface::NEG_I, connectedCells, minimumFaultThrow); + checkFaultAndAppendNeighborCell( + allFracturedCells, mainGrid, currentCell, cvf::StructGridInterface::POS_I, connectedCells, minimumFaultThrow); + checkFaultAndAppendNeighborCell( + allFracturedCells, mainGrid, currentCell, cvf::StructGridInterface::NEG_J, connectedCells, minimumFaultThrow); + checkFaultAndAppendNeighborCell( + allFracturedCells, mainGrid, currentCell, cvf::StructGridInterface::POS_J, connectedCells, minimumFaultThrow); + + // Append cells without fault check in K direction + appendNeighborCellForFace( + allFracturedCells, mainGrid, currentCell, cvf::StructGridInterface::NEG_K, connectedCells, minimumFaultThrow); + appendNeighborCellForFace( + allFracturedCells, mainGrid, currentCell, cvf::StructGridInterface::POS_K, connectedCells, minimumFaultThrow); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RimFractureContainmentTools::reservoirCellIndicesOpenForFlow(const RimEclipseCase* eclipseCase, + const RimFracture* fracture) +{ + std::set cellsOpenForFlow; + + if (eclipseCase && fracture) + { + auto eclipseCaseData = eclipseCase->eclipseCaseData(); + if (eclipseCaseData) + { + auto mainGrid = eclipseCaseData->mainGrid(); + + if (mainGrid) + { + std::set cellsIntersectingFracturePlane = getCellsIntersectingFracturePlane(mainGrid, fracture); + + // Negative faultThrow disables test on faultThrow + double maximumFaultThrow = -1.0; + if (fracture->fractureTemplate() && fracture->fractureTemplate()->fractureContainment()) + { + maximumFaultThrow = fracture->fractureTemplate()->fractureContainment()->minimumFaultThrow(); + } + + if (maximumFaultThrow > -1.0) + { + size_t anchorCellGlobalIndex = mainGrid->findReservoirCellIndexFromPoint(fracture->anchorPosition()); + appendNeighborCells(cellsIntersectingFracturePlane, + mainGrid, + anchorCellGlobalIndex, + cellsOpenForFlow, + maximumFaultThrow); + } + else + { + cellsOpenForFlow = cellsIntersectingFracturePlane; + } + } + + /* + NB : Please do not delete this code, used to create input to cell based range filter to see the computed fracture + cells + + qDebug() << "FracturedCells - Truncated"; + qDebug() << RigReservoirGridTools::globalCellIndicesToOneBasedIJKText( + fracturedCellsContainedByFaults.begin(), fracturedCellsContainedByFaults.end(), mainGrid); + */ + } + } + + return cellsOpenForFlow; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RimFractureContainmentTools::getCellsIntersectingFracturePlane(const RigMainGrid* mainGrid, + const RimFracture* fracture) +{ + std::set eclipseCellIndices; + + { + const auto indicesToPotentiallyFracturedCells = fracture->getPotentiallyFracturedCells(mainGrid); + + for (const auto& globalCellIndex : indicesToPotentiallyFracturedCells) + { + std::array hexCorners; + mainGrid->cellCornerVertices(globalCellIndex, hexCorners.data()); + std::vector> planeCellPolygons; + + bool isPlanIntersected = + RigHexIntersectionTools::planeHexIntersectionPolygons(hexCorners, fracture->transformMatrix(), planeCellPolygons); + if (isPlanIntersected || !planeCellPolygons.empty()) + { + eclipseCellIndices.insert(globalCellIndex); + } + } + } + + return eclipseCellIndices; +} diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureContainmentTools.h b/ApplicationCode/ProjectDataModel/Completions/RimFractureContainmentTools.h new file mode 100644 index 0000000000..3b7158027d --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureContainmentTools.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfStructGrid.h" + +#include +#include + +class RigMainGrid; +class RimFracture; +class RimEclipseCase; + +class RimFractureContainmentTools +{ +public: + static std::set reservoirCellIndicesOpenForFlow(const RimEclipseCase* eclipseCase, const RimFracture* fracture); + +private: + static std::set getCellsIntersectingFracturePlane(const RigMainGrid* mainGrid, const RimFracture* fracture); + + static void appendNeighborCellForFace(const std::set& allFracturedCells, + const RigMainGrid* mainGrid, + size_t currentCell, + cvf::StructGridInterface::FaceType face, + std::set& connectedCells, + double maximumFaultThrow); + + static void checkFaultAndAppendNeighborCell(const std::set& allFracturedCells, + const RigMainGrid* mainGrid, + size_t currentCell, + cvf::StructGridInterface::FaceType face, + std::set& connectedCells, + double maximumFaultThrow); + + static void appendNeighborCells(const std::set& allFracturedCells, + const RigMainGrid* mainGrid, + size_t currentCell, + std::set& connectedCells, + double maximumFaultThrow); +}; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureExportSettings.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFractureExportSettings.cpp index 0ca4c1a015..2935048cf6 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFractureExportSettings.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureExportSettings.cpp @@ -61,7 +61,7 @@ void RimFractureExportSettings::defineEditorAttribute(const caf::PdmFieldHandle* { if (field == &fileName) { - caf::PdmUiFilePathEditorAttribute* myAttr = static_cast(attribute); + caf::PdmUiFilePathEditorAttribute* myAttr = dynamic_cast(attribute); if (myAttr) { myAttr->m_selectSaveFileName = true; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureExportSettings.h b/ApplicationCode/ProjectDataModel/Completions/RimFractureExportSettings.h index c2adcbdc22..947abff90b 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFractureExportSettings.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureExportSettings.h @@ -39,9 +39,9 @@ class RimFractureExportSettings : public caf::PdmObject caf::PdmField fileName; caf::PdmPtrField caseToApply; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; 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; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplate.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplate.cpp index 1e3e012bba..d38cea8714 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplate.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplate.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -28,13 +28,15 @@ #include "cafPdmObject.h" #include "cafPdmUiDoubleSliderEditor.h" #include "cafPdmUiDoubleValueEditor.h" -#include "cafPdmUiTextEditor.h" #include "cafPdmUiPushButtonEditor.h" +#include "cafPdmUiTextEditor.h" #include "cvfVector3.h" #include +// clang-format off + namespace caf { template<> @@ -83,6 +85,16 @@ namespace caf setDefault(RimFractureTemplate::NON_DARCY_NONE); } + + template<> + void caf::AppEnum< RimFractureTemplate::BetaFactorEnum>::setUp() + { + addItem(RimFractureTemplate::USER_DEFINED_BETA_FACTOR, "UserDefinedBetaFactor", "User Defined"); + addItem(RimFractureTemplate::BETA_FACTOR_FROM_FRACTURE, "FractureBetaFactor", "Use Fracture Beta Factor"); + + setDefault(RimFractureTemplate::USER_DEFINED_BETA_FACTOR); + } + } // TODO Move to cafPdmObject.h @@ -108,7 +120,7 @@ RimFractureTemplate::RimFractureTemplate() m_nameAndUnit.uiCapability()->setUiHidden(true); m_nameAndUnit.xmlCapability()->disableIO(); - CAF_PDM_InitField(&m_fractureTemplateUnit, "UnitSystem", caf::AppEnum(RiaEclipseUnitTools::UNITS_METRIC), "Units System", "", "", ""); + CAF_PDM_InitField(&m_fractureTemplateUnit, "UnitSystem", caf::AppEnum(RiaEclipseUnitTools::UNITS_UNKNOWN), "Units System", "", "", ""); m_fractureTemplateUnit.uiCapability()->setUiReadOnly(true); CAF_PDM_InitField(&m_orientationType, "Orientation", caf::AppEnum(TRANSVERSE_WELL_PATH), "Fracture Orientation", "", "", ""); @@ -136,6 +148,7 @@ RimFractureTemplate::RimFractureTemplate() CAF_PDM_InitFieldNoDefault(&m_fractureWidthType, "FractureWidthType", "Type", "", "", ""); CAF_PDM_InitField_Basic(&m_fractureWidth, "FractureWidth", 0.01, "Fracture Width (h)"); + CAF_PDM_InitFieldNoDefault(&m_betaFactorType, "BetaFactorType", "Type", "", "", ""); CAF_PDM_InitField_Basic(&m_inertialCoefficient, "InertialCoefficient", 0.006083236, "Inertial Coefficient (β) [Forch. unit]"); CAF_PDM_InitFieldNoDefault(&m_permeabilityType, "PermeabilityType", "Type", "", "", ""); @@ -146,7 +159,7 @@ RimFractureTemplate::RimFractureTemplate() CAF_PDM_InitField(&m_gasViscosity, "GasViscosity", 0.02, "Gas Viscosity (μ) [cP]", "", "Gas viscosity at bottom hole pressure", ""); CAF_PDM_InitFieldNoDefault(&m_dFactorDisplayField, "dFactorDisplayField", "D Factor", "", "", ""); - m_dFactorDisplayField.registerGetMethod(this, &RimFractureTemplate::dFactor); + m_dFactorDisplayField.registerGetMethod(this, &RimFractureTemplate::dFactorForTemplate); m_dFactorDisplayField.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleValueEditor::uiEditorTypeName()); m_dFactorDisplayField.uiCapability()->setUiReadOnly(true); m_dFactorDisplayField.xmlCapability()->disableIO(); @@ -159,7 +172,7 @@ RimFractureTemplate::RimFractureTemplate() m_dFactorSummaryText.xmlCapability()->disableIO(); CAF_PDM_InitField(&m_heightScaleFactor, "HeightScaleFactor", 1.0, "Height", "", "", ""); - CAF_PDM_InitField(&m_widthScaleFactor, "WidthScaleFactor", 1.0, "Width", "", "", ""); + CAF_PDM_InitField(&m_halfLengthScaleFactor, "WidthScaleFactor", 1.0, "Half Length", "", "", ""); CAF_PDM_InitField(&m_dFactorScaleFactor, "DFactorScaleFactor", 1.0, "D-factor", "", "", ""); CAF_PDM_InitField(&m_conductivityScaleFactor, "ConductivityFactor", 1.0, "Conductivity", "", "The conductivity values read from file will be scaled with this parameters", ""); CAF_PDM_InitField(&m_scaleApplyButton, "ScaleApplyButton", false, "Apply", "", "", ""); @@ -169,15 +182,15 @@ RimFractureTemplate::RimFractureTemplate() m_scaleApplyButton.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); } +// clang-format on + //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimFractureTemplate::~RimFractureTemplate() -{ -} +RimFractureTemplate::~RimFractureTemplate() {} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- int RimFractureTemplate::id() const { @@ -185,7 +198,7 @@ int RimFractureTemplate::id() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFractureTemplate::setName(const QString& name) { @@ -193,7 +206,7 @@ void RimFractureTemplate::setName(const QString& name) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFractureTemplate::setFractureTemplateUnit(RiaEclipseUnitTools::UnitSystemType unitSystem) { @@ -201,7 +214,7 @@ void RimFractureTemplate::setFractureTemplateUnit(RiaEclipseUnitTools::UnitSyste } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QString RimFractureTemplate::name() const { @@ -209,7 +222,7 @@ QString RimFractureTemplate::name() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimFractureTemplate::FracOrientationEnum RimFractureTemplate::orientationType() const { @@ -217,7 +230,7 @@ RimFractureTemplate::FracOrientationEnum RimFractureTemplate::orientationType() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RiaEclipseUnitTools::UnitSystemType RimFractureTemplate::fractureTemplateUnit() const { @@ -225,7 +238,7 @@ RiaEclipseUnitTools::UnitSystemType RimFractureTemplate::fractureTemplateUnit() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- caf::PdmFieldHandle* RimFractureTemplate::userDescriptionField() { @@ -233,39 +246,31 @@ caf::PdmFieldHandle* RimFractureTemplate::userDescriptionField() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { bool createDisplayModelAndRedraw = false; if (changedField == &m_azimuthAngle || changedField == &m_orientationType) { - //Changes to one of these parameters should change all fractures with this fracture template attached. - RimProject* proj; - this->firstAncestorOrThisOfType(proj); - if (proj) + for (RimFracture* fracture : fracturesUsingThisTemplate()) { - //Regenerate geometry - std::vector fractures; - proj->descendantsIncludingThisOfType(fractures); + if (changedField == &m_azimuthAngle && (fabs(oldValue.toDouble() - fracture->m_azimuth()) < 1e-5)) + { + fracture->m_azimuth = m_azimuthAngle; + } - for (RimFracture* fracture : fractures) + if (changedField == &m_orientationType) { - if (fracture->fractureTemplate() == this) + if (newValue == AZIMUTH) { - if (changedField == &m_azimuthAngle && (fabs(oldValue.toDouble() - fracture->m_azimuth()) < 1e-5)) - { - fracture->m_azimuth = m_azimuthAngle; - } - - if (changedField == &m_orientationType) - { - if (newValue == AZIMUTH) - { - fracture->m_azimuth = m_azimuthAngle; - } - else fracture->updateAzimuthBasedOnWellAzimuthAngle(); - } + fracture->m_azimuth = m_azimuthAngle; + } + else + { + fracture->updateAzimuthBasedOnWellAzimuthAngle(); } } @@ -275,32 +280,29 @@ void RimFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* changedFie if (changedField == &m_perforationLength || changedField == &m_perforationEfficiency || changedField == &m_wellDiameter) { - RimProject* proj; - this->firstAncestorOrThisOfType(proj); - if (!proj) return; - std::vector fractures; - proj->descendantsIncludingThisOfType(fractures); - - for (RimFracture* fracture : fractures) + for (RimFracture* fracture : fracturesUsingThisTemplate()) { - if (fracture->fractureTemplate() == this) + if (changedField == &m_perforationLength && (fabs(oldValue.toDouble() - fracture->m_perforationLength()) < 1e-5)) { - if (changedField == &m_perforationLength && (fabs(oldValue.toDouble() - fracture->m_perforationLength()) < 1e-5)) - { - fracture->m_perforationLength = m_perforationLength; - } - if (changedField == &m_perforationEfficiency && (fabs(oldValue.toDouble() - fracture->m_perforationEfficiency()) < 1e-5)) - { - fracture->m_perforationEfficiency = m_perforationEfficiency; - } - if (changedField == &m_wellDiameter && (fabs(oldValue.toDouble() - fracture->m_wellDiameter()) < 1e-5)) - { - fracture->m_wellDiameter = m_wellDiameter; - } + fracture->m_perforationLength = m_perforationLength; + } + if (changedField == &m_perforationEfficiency && + (fabs(oldValue.toDouble() - fracture->m_perforationEfficiency()) < 1e-5)) + { + fracture->m_perforationEfficiency = m_perforationEfficiency; + } + if (changedField == &m_wellDiameter && (fabs(oldValue.toDouble() - fracture->m_wellDiameter()) < 1e-5)) + { + fracture->m_wellDiameter = m_wellDiameter; } } } + for (RimFracture* fracture : fracturesUsingThisTemplate()) + { + fracture->clearCachedNonDarcyProperties(); + } + if (changedField == &m_perforationLength) { createDisplayModelAndRedraw = true; @@ -318,7 +320,7 @@ void RimFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* changedFie } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFractureTemplate::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { @@ -326,9 +328,9 @@ void RimFractureTemplate::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder { auto group = uiOrdering.addNewGroup("Sensitivity Scale Factors"); - group->setCollapsedByDefault(false); + group->setCollapsedByDefault(true); group->add(&m_heightScaleFactor); - group->add(&m_widthScaleFactor); + group->add(&m_halfLengthScaleFactor); group->add(&m_dFactorScaleFactor); group->add(&m_conductivityScaleFactor); @@ -337,7 +339,7 @@ void RimFractureTemplate::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder auto nonDarcyFlowGroup = uiOrdering.addNewGroup("Non-Darcy Flow"); nonDarcyFlowGroup->add(&m_nonDarcyFlowType); - + if (m_nonDarcyFlowType == RimFractureTemplate::NON_DARCY_USER_DEFINED) { nonDarcyFlowGroup->add(&m_userDefinedDFactor); @@ -345,7 +347,11 @@ void RimFractureTemplate::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder if (m_nonDarcyFlowType == RimFractureTemplate::NON_DARCY_COMPUTED) { - nonDarcyFlowGroup->add(&m_inertialCoefficient); + { + auto group = nonDarcyFlowGroup->addNewGroup("Inertial Coefficient(β-factor)"); + group->add(&m_betaFactorType); + group->add(&m_inertialCoefficient); + } { auto group = nonDarcyFlowGroup->addNewGroup("Effective Permeability"); @@ -362,10 +368,14 @@ void RimFractureTemplate::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder nonDarcyFlowGroup->add(&m_relativeGasDensity); nonDarcyFlowGroup->add(&m_gasViscosity); - nonDarcyFlowGroup->add(&m_dFactorDisplayField); + + if (orientationType() != ALONG_WELL_PATH) + { + nonDarcyFlowGroup->add(&m_dFactorDisplayField); + } { - auto group = nonDarcyFlowGroup->addNewGroup("D Factor Details"); + auto group = nonDarcyFlowGroup->addNewGroup("D Factor Details"); group->setCollapsedByDefault(true); group->add(&m_dFactorSummaryText); } @@ -376,9 +386,11 @@ void RimFractureTemplate::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimFractureTemplate::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +void RimFractureTemplate::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) { if (field == &m_perforationEfficiency) { @@ -396,16 +408,16 @@ void RimFractureTemplate::defineEditorAttribute(const caf::PdmFieldHandle* field if (myAttr) { myAttr->wrapMode = caf::PdmUiTextEditorAttribute::NoWrap; - + QFont font("Monospace", 10); - myAttr->font = font; + myAttr->font = font; myAttr->textMode = caf::PdmUiTextEditorAttribute::HTML; } } if (field == &m_scaleApplyButton) { - caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast (attribute); + caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast(attribute); if (attrib) { attrib->m_buttonText = "Apply"; @@ -413,32 +425,6 @@ void RimFractureTemplate::defineEditorAttribute(const caf::PdmFieldHandle* field } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QList RimFractureTemplate::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, - bool* useOptionsOnly) -{ - QList options; - - if (fieldNeedingOptions == &m_fractureWidthType) - { - options.push_back(caf::PdmOptionItemInfo(caf::AppEnum::uiText(USER_DEFINED_WIDTH), USER_DEFINED_WIDTH)); - - auto widthAndCond = widthAndConductivityAtWellPathIntersection(); - if (widthAndCond.isValid()) - { - options.push_back(caf::PdmOptionItemInfo(caf::AppEnum::uiText(WIDTH_FROM_FRACTURE), WIDTH_FROM_FRACTURE)); - } - else - { - m_fractureWidthType = USER_DEFINED_WIDTH; - } - } - - return options; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -457,8 +443,8 @@ void RimFractureTemplate::prepareFieldsForUiDisplay() m_fractureWidth.uiCapability()->setUiName("Fracture Width [ft]"); } - if (m_orientationType == RimFractureTemplate::ALONG_WELL_PATH - || m_orientationType == RimFractureTemplate::TRANSVERSE_WELL_PATH) + if (m_orientationType == RimFractureTemplate::ALONG_WELL_PATH || + m_orientationType == RimFractureTemplate::TRANSVERSE_WELL_PATH) { m_azimuthAngle.uiCapability()->setUiHidden(true); } @@ -472,7 +458,7 @@ void RimFractureTemplate::prepareFieldsForUiDisplay() m_perforationEfficiency.uiCapability()->setUiHidden(false); m_perforationLength.uiCapability()->setUiHidden(false); } - else + else { m_perforationEfficiency.uiCapability()->setUiHidden(true); m_perforationLength.uiCapability()->setUiHidden(true); @@ -489,21 +475,24 @@ void RimFractureTemplate::prepareFieldsForUiDisplay() // Non Darcy Flow - auto values = widthAndConductivityAtWellPathIntersection(); - if (!values.isValid()) - { - m_fractureWidthType = RimFractureTemplate::USER_DEFINED_WIDTH; - } - - if (m_fractureWidthType == RimFractureTemplate::USER_DEFINED_WIDTH) - { - m_fractureWidth.uiCapability()->setUiReadOnly(false); - } - else { - m_fractureWidth = values.m_width; + if (m_fractureWidthType == RimFractureTemplate::USER_DEFINED_WIDTH) + { + m_fractureWidth.uiCapability()->setUiReadOnly(false); + } + else + { + m_fractureWidth.uiCapability()->setUiReadOnly(true); + } - m_fractureWidth.uiCapability()->setUiReadOnly(true); + if (m_betaFactorType == RimFractureTemplate::USER_DEFINED_BETA_FACTOR) + { + m_inertialCoefficient.uiCapability()->setUiReadOnly(false); + } + else + { + m_inertialCoefficient.uiCapability()->setUiReadOnly(true); + } } if (m_permeabilityType == RimFractureTemplate::USER_DEFINED_PERMEABILITY) @@ -518,52 +507,96 @@ void RimFractureTemplate::prepareFieldsForUiDisplay() } } +QString indentedText(const QString& text) +{ + return QString(" %1\n").arg(text); +} + //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QString RimFractureTemplate::dFactorSummary() const { QString text; - - auto val = dFactor(); - text += QString("D-factor : %1").arg(val); - text += "
"; - text += "
"; - auto alpha = RiaDefines::nonDarcyFlowAlpha(m_fractureTemplateUnit()); - text += QString("α : %1").arg(alpha); + std::vector fracturesToDisplay; + { + auto candidateFractures = fracturesUsingThisTemplate(); + + if (orientationType() != ALONG_WELL_PATH) + { + // D-factor values are identical for all fractures, only show summary for the first fracture + if (!candidateFractures.empty()) + { + fracturesToDisplay.push_back(candidateFractures.front()); + } + } + else + { + fracturesToDisplay = candidateFractures; + } + } + + for (auto f : fracturesToDisplay) + { + f->ensureValidNonDarcyProperties(); + + if (orientationType() == ALONG_WELL_PATH) + { + text += QString("Fracture name : %1").arg(f->name()); + } + + text += "
";
+        {
+            auto val = f->nonDarcyProperties().dFactor;
+            text += indentedText(QString("D-factor : %1").arg(val));
+
+            auto alpha = RiaDefines::nonDarcyFlowAlpha(m_fractureTemplateUnit());
+            text += indentedText(QString("α  : %1").arg(alpha));
 
-    text += "
"; - auto beta = m_inertialCoefficient; - text += QString("β : %1").arg(beta); + auto beta = getOrComputeBetaFactor(f); + text += indentedText(QString("β : %1").arg(beta)); - text += "
"; - double effPerm = effectivePermeability(); - text += QString("Ke : %1").arg(effPerm); + double effPerm = f->nonDarcyProperties().effectivePermeability; + text += indentedText(QString("Ke : %1").arg(effPerm)); - text += "
"; - double gamma = m_relativeGasDensity; - text += QString("γ : %1").arg(gamma); + double gamma = m_relativeGasDensity; + text += indentedText(QString("γ : %1").arg(gamma)); - text += "
"; - auto h = fractureWidth(); - text += QString("h : %1").arg(h); + auto h = f->nonDarcyProperties().width; + text += indentedText(QString("h : %1").arg(h)); - text += "
"; - auto wellRadius = m_wellDiameter / 2.0; - text += QString("rw : %1").arg(wellRadius); + auto wellRadius = f->nonDarcyProperties().eqWellRadius; + text += indentedText(QString("rw : %1").arg(wellRadius)); - text += "
"; - auto mu = m_gasViscosity; - text += QString("μ : %1").arg(mu); + auto mu = m_gasViscosity; + text += indentedText(QString("μ : %1").arg(mu)); + } + text += "
"; + + text += "
"; + } return text; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RimFractureTemplate::effectivePermeability() const +double RimFractureTemplate::dFactorForTemplate() const +{ + if (orientationType() == ALONG_WELL_PATH) + { + return std::numeric_limits::infinity(); + } + + return computeDFactor(nullptr); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFractureTemplate::computeEffectivePermeability(const RimFracture* fractureInstance) const { if (m_permeabilityType() == RimFractureTemplate::USER_DEFINED_PERMEABILITY) { @@ -571,18 +604,51 @@ double RimFractureTemplate::effectivePermeability() const } else { - auto values = widthAndConductivityAtWellPathIntersection(); + double fracPermeability = 0.0; + auto values = wellFractureIntersectionData(fractureInstance); + if (values.isWidthAndPermeabilityDefined()) + { + fracPermeability = values.m_permeability; + } + else + { + auto conductivity = values.m_conductivity; + auto width = computeFractureWidth(fractureInstance); - auto fracPermeability = values.m_permeability; + if (fabs(width) < 1e-10) return std::numeric_limits::infinity(); + + fracPermeability = conductivity / width; + } return fracPermeability * m_relativePermeability; } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RimFractureTemplate::dFactor() const +double RimFractureTemplate::computeWellRadiusForDFactorCalculation(const RimFracture* fractureInstance) const +{ + double radius = 0.0; + + if (m_orientationType == ALONG_WELL_PATH && fractureInstance) + { + auto perforationLength = fractureInstance->perforationLength(); + + radius = perforationLength / cvf::PI_D; + } + else + { + radius = m_wellDiameter / 2.0; + } + + return radius; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimFractureTemplate::computeDFactor(const RimFracture* fractureInstance) const { double d; @@ -592,46 +658,54 @@ double RimFractureTemplate::dFactor() const } else { - auto alpha = RiaDefines::nonDarcyFlowAlpha(m_fractureTemplateUnit()); - auto beta = m_inertialCoefficient; - auto effPerm = effectivePermeability(); - auto gamma = m_relativeGasDensity; + double radius = computeWellRadiusForDFactorCalculation(fractureInstance); + double alpha = RiaDefines::nonDarcyFlowAlpha(m_fractureTemplateUnit()); + double beta = getOrComputeBetaFactor(fractureInstance); + double effPerm = computeEffectivePermeability(fractureInstance); + double gamma = m_relativeGasDensity; - auto radius = m_wellDiameter / 2.0; - auto mu = m_gasViscosity; - auto h = fractureWidth(); + double mu = m_gasViscosity; + double h = computeFractureWidth(fractureInstance); - double numerator = alpha * beta * effPerm * gamma; + double numerator = alpha * beta * effPerm * gamma; double denumerator = h * radius * mu; - if (denumerator < 1e-10) return HUGE_VAL; + if (denumerator < 1e-10) return std::numeric_limits::infinity(); d = numerator / denumerator; + + if (m_orientationType == ALONG_WELL_PATH) + { + // Correction for linear inflow into the well + // Dlinear = cgeometric * Dradial + // Dlinear = 1.2 * Dradial + d *= 1.2; + } } return d * m_dFactorScaleFactor; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RimFractureTemplate::kh() const +double RimFractureTemplate::computeKh(const RimFracture* fractureInstance) const { // kh = permeability * h // conductivity = permeability * h - auto values = widthAndConductivityAtWellPathIntersection(); - if (values.m_conductivity != HUGE_VAL) + auto values = wellFractureIntersectionData(fractureInstance); + if (values.isConductivityDefined()) { // If conductivity is found in stim plan file, use this directly return values.m_conductivity; } - - return effectivePermeability() * fractureWidth(); + + return computeEffectivePermeability(fractureInstance) * computeFractureWidth(fractureInstance); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFractureTemplate::convertToUnitSystem(RiaEclipseUnitTools::UnitSystem neededUnit) { @@ -650,19 +724,15 @@ void RimFractureTemplate::convertToUnitSystem(RiaEclipseUnitTools::UnitSystem ne } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFractureTemplate::disconnectAllFracturesAndRedrawViews() const { // The unit has changed. Disconnect all fractures referencing this fracture template to avoid mix of units between fracture // and template - std::vector referringObjects; - this->objectsWithReferringPtrFields(referringObjects); - - for (auto objHandle : referringObjects) + for (auto fracture : fracturesUsingThisTemplate()) { - RimFracture* fracture = dynamic_cast(objHandle); if (fracture) { fracture->setFractureTemplate(nullptr); @@ -673,12 +743,12 @@ void RimFractureTemplate::disconnectAllFracturesAndRedrawViews() const this->firstAncestorOrThisOfType(proj); if (proj) { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFractureTemplate::setId(int id) { @@ -686,18 +756,42 @@ void RimFractureTemplate::setId(int id) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimFractureTemplate::setScaleFactors(double width, double height, double dFactor, double conductivity) +void RimFractureTemplate::setScaleFactors(double halfLengthScale, + double heightScale, + double dFactorScale, + double conductivityScale) { - m_widthScaleFactor = width; - m_heightScaleFactor = height; - m_dFactorScaleFactor = dFactor; - m_conductivityScaleFactor = conductivity; + m_halfLengthScaleFactor = halfLengthScale; + m_heightScaleFactor = heightScale; + m_dFactorScaleFactor = dFactorScale; + m_conductivityScaleFactor = conductivityScale; + + for (RimFracture* fracture : fracturesUsingThisTemplate()) + { + fracture->clearCachedNonDarcyProperties(); + } } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void RimFractureTemplate::scaleFactors(double* halfLengthScale, + double* heightScale, + double* dFactorScale, + double* conductivityScale) const +{ + CVF_ASSERT(halfLengthScale && heightScale && dFactorScale && conductivityScale); + + *halfLengthScale = m_halfLengthScaleFactor; + *heightScale = m_heightScaleFactor; + *dFactorScale = m_dFactorScaleFactor; + *conductivityScale = m_conductivityScaleFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RimFractureTemplate::setContainmentTopKLayer(int topKLayer) { @@ -705,7 +799,7 @@ void RimFractureTemplate::setContainmentTopKLayer(int topKLayer) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFractureTemplate::setContainmentBaseKLayer(int baseKLayer) { @@ -713,14 +807,14 @@ void RimFractureTemplate::setContainmentBaseKLayer(int baseKLayer) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RimFractureTemplate::fractureWidth() const +double RimFractureTemplate::computeFractureWidth(const RimFracture* fractureInstance) const { if (m_fractureWidthType == RimFractureTemplate::WIDTH_FROM_FRACTURE) { - auto values = widthAndConductivityAtWellPathIntersection(); - + auto values = wellFractureIntersectionData(fractureInstance); + return values.m_width; } @@ -728,7 +822,49 @@ double RimFractureTemplate::fractureWidth() const } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +double RimFractureTemplate::getOrComputeBetaFactor(const RimFracture* fractureInstance) const +{ + if (m_betaFactorType == RimFractureTemplate::BETA_FACTOR_FROM_FRACTURE) + { + auto values = wellFractureIntersectionData(fractureInstance); + + return values.m_betaFactorInForcheimerUnits; + } + + return m_inertialCoefficient; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFractureTemplate::loadDataAndUpdateGeometryHasChanged() +{ + onLoadDataAndUpdateGeometryHasChanged(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimFractureTemplate::fracturesUsingThisTemplate() const +{ + std::vector fractures; + this->objectsWithReferringPtrFieldsOfType(fractures); + + return fractures; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFractureTemplate::isBetaFactorAvailableOnFile() const +{ + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- QString RimFractureTemplate::nameAndUnit() const { @@ -749,31 +885,31 @@ QString RimFractureTemplate::nameAndUnit() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RimFractureTemplate::wellDiameter() +double RimFractureTemplate::wellDiameter() const { return m_wellDiameter; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RimFractureTemplate::perforationLength() +double RimFractureTemplate::perforationLength() const { return m_perforationLength; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const RimFractureContainment * RimFractureTemplate::fractureContainment() +const RimFractureContainment* RimFractureTemplate::fractureContainment() const { return m_fractureContainment(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimFractureTemplate::FracConductivityEnum RimFractureTemplate::conductivityType() const { @@ -781,7 +917,7 @@ RimFractureTemplate::FracConductivityEnum RimFractureTemplate::conductivityType( } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- float RimFractureTemplate::azimuthAngle() const { @@ -789,7 +925,7 @@ float RimFractureTemplate::azimuthAngle() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- float RimFractureTemplate::skinFactor() const { @@ -797,7 +933,7 @@ float RimFractureTemplate::skinFactor() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimFractureTemplate::setDefaultWellDiameterFromUnit() { @@ -812,7 +948,7 @@ void RimFractureTemplate::setDefaultWellDiameterFromUnit() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimFractureTemplate::isNonDarcyFlowEnabled() const { diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplate.h b/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplate.h index af87b73e14..1ea474e8a9 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplate.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplate.h @@ -32,24 +32,26 @@ #include "cvfVector3.h" #include -#include +#include class RigFractureGrid; class RimFractureContainment; class MinMaxAccumulator; class PosNegAccumulator; +class RimFracture; -class FractureWidthAndConductivity +class WellFractureIntersectionData { public: - FractureWidthAndConductivity() + WellFractureIntersectionData() : m_width(0.0) , m_permeability(0.0) - , m_conductivity(HUGE_VAL) + , m_conductivity(std::numeric_limits::infinity()) + , m_betaFactorInForcheimerUnits(std::numeric_limits::infinity()) { } - bool isValid() const + bool isWidthAndPermeabilityDefined() const { if (m_width != 0.0) return true; if (m_permeability != 0.0) return true; @@ -57,6 +59,11 @@ class FractureWidthAndConductivity return false; } + bool isConductivityDefined() const + { + return (m_conductivity != std::numeric_limits::infinity()); + } + // Unit : meter or feet double m_width; @@ -64,6 +71,9 @@ class FractureWidthAndConductivity double m_permeability; double m_conductivity; + + // Unit : Forcheimer unit + double m_betaFactorInForcheimerUnits; }; //================================================================================================== @@ -100,6 +110,12 @@ class RimFractureTemplate : public caf::PdmObject WIDTH_FROM_FRACTURE, }; + enum BetaFactorEnum + { + USER_DEFINED_BETA_FACTOR, + BETA_FACTOR_FROM_FRACTURE, + }; + enum NonDarcyFlowEnum { NON_DARCY_NONE, @@ -109,7 +125,7 @@ class RimFractureTemplate : public caf::PdmObject public: RimFractureTemplate(); - virtual ~RimFractureTemplate(); + ~RimFractureTemplate() override; int id() const; QString name() const; @@ -119,16 +135,15 @@ class RimFractureTemplate : public caf::PdmObject FracOrientationEnum orientationType() const; float azimuthAngle() const; float skinFactor() const; - double wellDiameter(); + double wellDiameter() const; FracConductivityEnum conductivityType() const; - double perforationLength(); + double perforationLength() const; virtual void fractureTriangleGeometry(std::vector* nodeCoords, - std::vector* triangleIndices) = 0; + std::vector* triangleIndices) const = 0; - virtual std::vector fractureBorderPolygon() = 0; virtual const RigFractureGrid* fractureGrid() const = 0; - const RimFractureContainment* fractureContainment(); + const RimFractureContainment* fractureContainment() const; virtual void appendDataToResultStatistics(const QString& resultName, const QString& unit, @@ -142,8 +157,6 @@ class RimFractureTemplate : public caf::PdmObject void setDefaultWellDiameterFromUnit(); bool isNonDarcyFlowEnabled() const; - double dFactor() const; - double kh() const; virtual void convertToUnitSystem(RiaEclipseUnitTools::UnitSystem neededUnit); @@ -151,27 +164,38 @@ class RimFractureTemplate : public caf::PdmObject void disconnectAllFracturesAndRedrawViews() const; void setId(int id); - void setScaleFactors(double width, double height, double dFactor, double conductivity); - virtual void reload() {} + void setScaleFactors(double halfLengthScale, double heightScale, double dFactorScale, double conductivityScale); + void scaleFactors(double* halfLengthScale, double* heightScale, double* dFactorScale, double* conductivityScale) const; void setContainmentTopKLayer(int topKLayer); void setContainmentBaseKLayer(int baseKLayer); + double computeDFactor(const RimFracture* fractureInstance) const; + double computeKh(const RimFracture* fractureInstance) const; + double computeEffectivePermeability(const RimFracture* fractureInstance) const; + double computeWellRadiusForDFactorCalculation(const RimFracture* fractureInstance) const; + double computeFractureWidth(const RimFracture* fractureInstance) const; + double getOrComputeBetaFactor(const RimFracture* fractureInstance) const; + + void loadDataAndUpdateGeometryHasChanged(); + protected: - virtual caf::PdmFieldHandle* userDescriptionField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + caf::PdmFieldHandle* userDescriptionField() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + + std::vector fracturesUsingThisTemplate() const; + virtual void onLoadDataAndUpdateGeometryHasChanged() = 0; + + virtual bool isBetaFactorAvailableOnFile() const; private: void prepareFieldsForUiDisplay(); - virtual FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection() const = 0; + virtual WellFractureIntersectionData wellFractureIntersectionData(const RimFracture* fractureInstance) const = 0; QString dFactorSummary() const; - double effectivePermeability() const; - - double fractureWidth() const; + double dFactorForTemplate() const; protected: caf::PdmField m_id; @@ -193,11 +217,12 @@ class RimFractureTemplate : public caf::PdmObject caf::PdmField> m_fractureWidthType; caf::PdmField m_fractureWidth; + + caf::PdmField> m_betaFactorType; caf::PdmField m_inertialCoefficient; caf::PdmField> m_permeabilityType; caf::PdmField m_relativePermeability; - caf::PdmField m_userDefinedEffectivePermeability; caf::PdmField m_relativeGasDensity; caf::PdmField m_gasViscosity; @@ -206,8 +231,11 @@ class RimFractureTemplate : public caf::PdmObject caf::PdmProxyValueField m_dFactorSummaryText; caf::PdmField m_heightScaleFactor; - caf::PdmField m_widthScaleFactor; + caf::PdmField m_halfLengthScaleFactor; caf::PdmField m_dFactorScaleFactor; caf::PdmField m_conductivityScaleFactor; caf::PdmField m_scaleApplyButton; + +private: + caf::PdmField m_userDefinedEffectivePermeability; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplateCollection.cpp b/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplateCollection.cpp index 46caf585da..93a4ed3b47 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplateCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplateCollection.cpp @@ -19,19 +19,22 @@ #include "RimFractureTemplateCollection.h" #include "RiaLogging.h" +#include "RiaApplication.h" #include "RigStatisticsMath.h" +#include "RigEclipseCaseData.h" #include "RimCase.h" +#include "RimEclipseCase.h" #include "RimEclipseView.h" #include "RimEllipseFractureTemplate.h" #include "RimFracture.h" #include "RimFractureTemplate.h" -#include "RimOilField.h" #include "RimProject.h" #include "RimSimWellInViewCollection.h" #include "RimStimPlanColors.h" #include "RimStimPlanFractureTemplate.h" +#include "RimTools.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" #include "RimWellPathFracture.h" @@ -113,6 +116,20 @@ RiaEclipseUnitTools::UnitSystemType RimFractureTemplateCollection::defaultUnitSy return m_defaultUnitsForFracTemplates; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFractureTemplateCollection::setDefaultUnitSystemBasedOnLoadedCases() +{ + RimProject* proj = RiaApplication::instance()->project(); + + auto commonUnitSystem = proj->commonUnitSystemForAllCases(); + if (commonUnitSystem != RiaEclipseUnitTools::UNITS_UNKNOWN) + { + m_defaultUnitsForFracTemplates = commonUnitSystem; + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -189,12 +206,11 @@ void RimFractureTemplateCollection::createAndAssignTemplateCopyForNonMatchingUni { RimFractureTemplate* templateWithMatchingUnit = nullptr; - std::vector referringObjects; - fractureTemplate->objectsWithReferringPtrFields(referringObjects); + std::vector referringObjects; + fractureTemplate->objectsWithReferringPtrFieldsOfType(referringObjects); - for (auto refObj : referringObjects) + for (auto fracture : referringObjects) { - auto fracture = dynamic_cast(refObj); if (fracture && fracture->fractureUnit() != fractureTemplate->fractureTemplateUnit()) { if (!templateWithMatchingUnit) @@ -291,7 +307,7 @@ void RimFractureTemplateCollection::initAfterRead() bool setAllShowMeshToFalseOnAllEclipseViews = false; std::vector wellPathFractures; - RimWellPathCollection* wellPathCollection = proj->activeOilField()->wellPathCollection(); + RimWellPathCollection* wellPathCollection = RimTools::wellPathCollection(); wellPathCollection->descendantsIncludingThisOfType(wellPathFractures); for (RimWellPathFracture* fracture : wellPathFractures) diff --git a/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplateCollection.h b/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplateCollection.h index 2f677287d6..406fa53820 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplateCollection.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimFractureTemplateCollection.h @@ -36,12 +36,14 @@ class RimFractureTemplateCollection : public caf::PdmObject public: RimFractureTemplateCollection(); - virtual ~RimFractureTemplateCollection(); + ~RimFractureTemplateCollection() override; RimFractureTemplate* fractureTemplate(int id) const; std::vector fractureTemplates() const; void addFractureTemplate(RimFractureTemplate* templ); + RiaEclipseUnitTools::UnitSystemType defaultUnitSystemType() const; + void setDefaultUnitSystemBasedOnLoadedCases(); RimFractureTemplate* firstFractureOfUnit(RiaEclipseUnitTools::UnitSystem unitSet) const; @@ -53,7 +55,7 @@ class RimFractureTemplateCollection : public caf::PdmObject void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath); protected: - virtual void initAfterRead() override; + void initAfterRead() override; private: int nextFractureTemplateId(); diff --git a/ApplicationCode/ProjectDataModel/Completions/RimMswCompletionParameters.cpp b/ApplicationCode/ProjectDataModel/Completions/RimMswCompletionParameters.cpp new file mode 100644 index 0000000000..3190a35a7f --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimMswCompletionParameters.cpp @@ -0,0 +1,264 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RimMswCompletionParameters.h" + +#include "RimWellPath.h" + +#include "cafPdmUiObjectEditorHandle.h" + +#include + +namespace caf { + template<> + void RimMswCompletionParameters::PressureDropEnum::setUp() + { + addItem(RimMswCompletionParameters::HYDROSTATIC, "H--", "Hydrostatic"); + addItem(RimMswCompletionParameters::HYDROSTATIC_FRICTION, "HF-", "Hydrostatic + Friction"); + addItem(RimMswCompletionParameters::HYDROSTATIC_FRICTION_ACCELERATION, "HFA", "Hydrostatic + Friction + Acceleration"); + setDefault(RimMswCompletionParameters::HYDROSTATIC); + } + + template<> + void RimMswCompletionParameters::LengthAndDepthEnum::setUp() + { + addItem(RimMswCompletionParameters::INC, "INC", "Incremental"); + addItem(RimMswCompletionParameters::ABS, "ABS", "Absolute"); + setDefault(RimMswCompletionParameters::INC); + } +} + +CAF_PDM_SOURCE_INIT(RimMswCompletionParameters, "RimMswCompletionParameters"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMswCompletionParameters::RimMswCompletionParameters() +{ + CAF_PDM_InitObject("MSW Completion Parameters", ":/CompletionsSymbol16x16.png", "", ""); + CAF_PDM_InitField(&m_linerDiameter, "LinerDiameter", std::numeric_limits::infinity(), "Liner Inner Diameter", "", "", ""); + CAF_PDM_InitField(&m_roughnessFactor, "RoughnessFactor", std::numeric_limits::infinity(), "Roughness Factor", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_pressureDrop, "PressureDrop", "Pressure Drop", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_lengthAndDepth, "LengthAndDepth", "Length and Depth", "", "", ""); + + CAF_PDM_InitField(&m_enforceMaxSegmentLength, "EnforceMaxSegmentLength", false, "Enforce Max Segment Length", "", "", ""); + CAF_PDM_InitField(&m_maxSegmentLength, "MaxSegmentLength", 200.0, "Max Segment Length", "", "", ""); + m_maxSegmentLength.uiCapability()->setUiHidden(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMswCompletionParameters::~RimMswCompletionParameters() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMswCompletionParameters::linerDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const +{ + RimWellPath* wellPath; + firstAncestorOrThisOfTypeAsserted(wellPath); + if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD && unitSystem == RiaEclipseUnitTools::UNITS_METRIC) + { + return RiaEclipseUnitTools::feetToMeter(m_linerDiameter()); + } + else if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_METRIC && unitSystem == RiaEclipseUnitTools::UNITS_FIELD) + { + return RiaEclipseUnitTools::meterToFeet(m_linerDiameter()); + } + return m_linerDiameter(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMswCompletionParameters::defaultLinerDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) +{ + if (unitSystem == RiaEclipseUnitTools::UNITS_METRIC) + { + return 0.152; + } + else + { + return 0.5; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMswCompletionParameters::roughnessFactor(RiaEclipseUnitTools::UnitSystem unitSystem) const +{ + RimWellPath* wellPath; + firstAncestorOrThisOfTypeAsserted(wellPath); + if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD && unitSystem == RiaEclipseUnitTools::UNITS_METRIC) + { + return RiaEclipseUnitTools::feetToMeter(m_roughnessFactor()); + } + else if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_METRIC && unitSystem == RiaEclipseUnitTools::UNITS_FIELD) + { + return RiaEclipseUnitTools::meterToFeet(m_roughnessFactor()); + } + return m_roughnessFactor(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMswCompletionParameters::defaultRoughnessFactor(RiaEclipseUnitTools::UnitSystem unitSystem) +{ + if (unitSystem == RiaEclipseUnitTools::UNITS_METRIC) + { + return 1.0e-5; + } + else + { + return 3.28e-5; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMswCompletionParameters::PressureDropEnum RimMswCompletionParameters::pressureDrop() const +{ + return m_pressureDrop(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMswCompletionParameters::LengthAndDepthEnum RimMswCompletionParameters::lengthAndDepth() const +{ + return m_lengthAndDepth(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMswCompletionParameters::maxSegmentLength() const +{ + return m_enforceMaxSegmentLength ? m_maxSegmentLength : std::numeric_limits::infinity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMswCompletionParameters::setLinerDiameter(double diameter) +{ + m_linerDiameter = diameter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMswCompletionParameters::setRoughnessFactor(double roughnessFactor) +{ + m_roughnessFactor = roughnessFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMswCompletionParameters::setPressureDrop(PressureDropType pressureDropType) +{ + m_pressureDrop = pressureDropType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMswCompletionParameters::setLengthAndDepth(LengthAndDepthType lengthAndDepthType) +{ + m_lengthAndDepth = lengthAndDepthType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMswCompletionParameters::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &m_enforceMaxSegmentLength) + { + m_maxSegmentLength.uiCapability()->setUiHidden(!m_enforceMaxSegmentLength()); + caf::PdmUiObjectEditorHandle::updateUiAllObjectEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMswCompletionParameters::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + { + RimWellPath* wellPath; + firstAncestorOrThisOfType(wellPath); + if (wellPath) + { + if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_METRIC) + { + m_linerDiameter.uiCapability()->setUiName("Liner Inner Diameter [m]"); + m_roughnessFactor.uiCapability()->setUiName("Roughness Factor [m]"); + } + else if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD) + { + m_linerDiameter.uiCapability()->setUiName("Liner Inner Diameter [ft]"); + m_roughnessFactor.uiCapability()->setUiName("Roughness Factor [ft]"); + } + } + } + + uiOrdering.add(&m_linerDiameter); + uiOrdering.add(&m_roughnessFactor); + uiOrdering.add(&m_pressureDrop); + uiOrdering.add(&m_lengthAndDepth); + uiOrdering.add(&m_enforceMaxSegmentLength); + uiOrdering.add(&m_maxSegmentLength); + + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMswCompletionParameters::initAfterRead() +{ + if (m_linerDiameter() == std::numeric_limits::infinity() && + m_roughnessFactor() == std::numeric_limits::infinity()) + { + setUnitSystemSpecificDefaults(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMswCompletionParameters::setUnitSystemSpecificDefaults() +{ + RimWellPath* wellPath; + firstAncestorOrThisOfType(wellPath); + if (wellPath) + { + m_linerDiameter = defaultLinerDiameter(wellPath->unitSystem()); + m_roughnessFactor = defaultRoughnessFactor(wellPath->unitSystem()); + } +} + diff --git a/ApplicationCode/ProjectDataModel/Completions/RimMswCompletionParameters.h b/ApplicationCode/ProjectDataModel/Completions/RimMswCompletionParameters.h new file mode 100644 index 0000000000..2b15ab8b34 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimMswCompletionParameters.h @@ -0,0 +1,79 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "RiaEclipseUnitTools.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmUiGroup.h" + +class RimMswCompletionParameters : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + enum PressureDropType { + HYDROSTATIC, + HYDROSTATIC_FRICTION, + HYDROSTATIC_FRICTION_ACCELERATION + }; + + typedef caf::AppEnum PressureDropEnum; + + enum LengthAndDepthType { + ABS, + INC + }; + + typedef caf::AppEnum LengthAndDepthEnum; + + RimMswCompletionParameters(); + ~RimMswCompletionParameters() override; + + double linerDiameter(RiaEclipseUnitTools::UnitSystem unitSystem) const; + static double defaultLinerDiameter(RiaEclipseUnitTools::UnitSystem unitSystem); + double roughnessFactor(RiaEclipseUnitTools::UnitSystem unitSystem) const; + static double defaultRoughnessFactor(RiaEclipseUnitTools::UnitSystem unitSystem); + PressureDropEnum pressureDrop() const; + LengthAndDepthEnum lengthAndDepth() const; + double maxSegmentLength() const; + void setLinerDiameter(double diameter); + void setRoughnessFactor(double roughnessFactor); + void setPressureDrop(PressureDropType pressureDropType); + void setLengthAndDepth(LengthAndDepthType lengthAndDepthType); + + + void setUnitSystemSpecificDefaults(); + +protected: + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void initAfterRead() override; + +private: + caf::PdmField m_linerDiameter; + caf::PdmField m_roughnessFactor; + + caf::PdmField m_pressureDrop; + caf::PdmField m_lengthAndDepth; + + caf::PdmField m_enforceMaxSegmentLength; + caf::PdmField m_maxSegmentLength; +}; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimMultipleValveLocations.cpp b/ApplicationCode/ProjectDataModel/Completions/RimMultipleValveLocations.cpp new file mode 100644 index 0000000000..6a351efd2f --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimMultipleValveLocations.cpp @@ -0,0 +1,426 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimMultipleValveLocations.h" + +#include "RigWellPath.h" + +#include "RimFishbonesMultipleSubs.h" +#include "RimPerforationInterval.h" +#include "RimWellPath.h" +#include "RimWellPathValve.h" + +#include "cafPdmUiDoubleValueEditor.h" +#include "cafPdmUiListEditor.h" + +#include + +CAF_PDM_SOURCE_INIT(RimMultipleValveLocations, "RimMultipleValveLocations"); + +namespace caf { + template<> + void AppEnum::setUp() + { + addItem(RimMultipleValveLocations::VALVE_COUNT, "VALVE_COUNT", "Start/End/Number of Subs"); + addItem(RimMultipleValveLocations::VALVE_SPACING, "VALVE_SPACING", "Start/End/Spacing"); + addItem(RimMultipleValveLocations::VALVE_CUSTOM, "VALVE_CUSTOM", "User Specification"); + setDefault(RimMultipleValveLocations::VALVE_COUNT); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMultipleValveLocations::RimMultipleValveLocations() +{ + CAF_PDM_InitObject("RimMultipleValveLocations", ":/FishBoneGroup16x16.png", "", ""); + + + CAF_PDM_InitField(&m_locationType, "LocationMode", caf::AppEnum(VALVE_COUNT), "Location Defined By", "", "", ""); + CAF_PDM_InitField(&m_rangeStart, "RangeStart", 100.0, "Start MD [m]", "", "", ""); + m_rangeStart.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleValueEditor::uiEditorTypeName()); + + CAF_PDM_InitField(&m_rangeEnd, "RangeEnd", 250.0, "End MD [m]", "", "", ""); + m_rangeEnd.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleValueEditor::uiEditorTypeName()); + + CAF_PDM_InitFieldNoDefault(&m_rangeValveSpacing, "ValveSpacing", "Spacing [m]", "", "", ""); + m_rangeValveSpacing.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleValueEditor::uiEditorTypeName()); + + CAF_PDM_InitField(&m_rangeValveCount, "RangeValveCount", 13, "Number of Valves", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_locationOfValves, "LocationOfValves", "Measured Depths [m]", "", "", ""); + m_locationOfValves.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMultipleValveLocations::measuredDepth(size_t valveIndex) const +{ + CVF_ASSERT(valveIndex < m_locationOfValves().size()); + + return m_locationOfValves()[valveIndex]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMultipleValveLocations::rangeStart() const +{ + return m_rangeStart; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMultipleValveLocations::rangeEnd() const +{ + return m_rangeEnd; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RimMultipleValveLocations::valveLocations() const +{ + return m_locationOfValves(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMultipleValveLocations::setLocationType(LocationType locationType) +{ + m_locationType = locationType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMultipleValveLocations::computeRangesAndLocations() +{ + if (m_locationType == VALVE_COUNT) + { + int divisor = 1; + if (m_rangeValveCount > 2) divisor = m_rangeValveCount - 1; + + m_rangeValveSpacing = std::abs(m_rangeStart - m_rangeEnd) / divisor; + if (m_rangeValveSpacing < minimumSpacingMeters()) + { + m_rangeValveSpacing = minimumSpacingMeters(); + m_rangeValveCount = rangeCountFromSpacing(); + } + } + else if (m_locationType == VALVE_SPACING) + { + m_rangeValveCount = rangeCountFromSpacing(); + } + + if (m_locationType == VALVE_COUNT || m_locationType == VALVE_SPACING) + { + std::vector validMeasuredDepths; + { + RimWellPath* wellPath = nullptr; + this->firstAncestorOrThisOfTypeAsserted(wellPath); + + RigWellPath* rigWellPathGeo = wellPath->wellPathGeometry(); + if (rigWellPathGeo && rigWellPathGeo->m_measuredDepths.size() > 1) + { + double firstWellPathMD = rigWellPathGeo->m_measuredDepths.front(); + double lastWellPathMD = rigWellPathGeo->m_measuredDepths.back(); + + for (auto md : locationsFromStartSpacingAndCount(m_rangeStart, m_rangeValveSpacing, m_rangeValveCount)) + { + if (md >= firstWellPathMD && md <= lastWellPathMD) + { + validMeasuredDepths.push_back(md); + } + } + } + } + + m_locationOfValves = validMeasuredDepths; + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMultipleValveLocations::initFields(LocationType locationType, double rangeStart, double rangeEnd, double valveSpacing, int valveCount, const std::vector& locationOfValves) +{ + if (locationType != VALVE_UNDEFINED) + { + m_locationType = locationType; + } + if (rangeStart != std::numeric_limits::infinity()) + { + m_rangeStart = rangeStart; + } + if (rangeEnd!= std::numeric_limits::infinity()) + { + m_rangeEnd = rangeEnd; + } + if (valveSpacing != std::numeric_limits::infinity()) + { + m_rangeValveSpacing = valveSpacing; + } + if (valveCount != -1) + { + m_rangeValveCount = valveCount; + } + if (!locationOfValves.empty()) + { + m_locationOfValves = locationOfValves; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMultipleValveLocations::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + { + RimWellPath* wellPath; + firstAncestorOrThisOfType(wellPath); + if (wellPath) + { + if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_METRIC) + { + m_locationOfValves.uiCapability()->setUiName("Measured Depths [m]"); + m_rangeStart.uiCapability()->setUiName("Start MD [m]"); + m_rangeEnd.uiCapability()->setUiName("End MD [m]"); + m_rangeValveSpacing.uiCapability()->setUiName("Spacing [m]"); + } + else if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD) + { + m_locationOfValves.uiCapability()->setUiName("Measured Depths [ft]"); + m_rangeStart.uiCapability()->setUiName("Start MD [ft]"); + m_rangeEnd.uiCapability()->setUiName("End MD [ft]"); + m_rangeValveSpacing.uiCapability()->setUiName("Spacing [ft]"); + } + } + } + + { + uiOrdering.add(&m_locationType); + if (m_locationType() != VALVE_CUSTOM) + { + uiOrdering.add(&m_rangeStart); + uiOrdering.add(&m_rangeEnd); + + if (m_locationType() == VALVE_COUNT) + { + uiOrdering.add(&m_rangeValveCount); + uiOrdering.add(&m_rangeValveSpacing); + } + else if (m_locationType() == VALVE_SPACING) + { + uiOrdering.add(&m_rangeValveSpacing); + uiOrdering.add(&m_rangeValveCount); + } + } + + uiOrdering.add(&m_locationOfValves); + } + + if (m_locationType() == VALVE_CUSTOM) + { + m_locationOfValves.uiCapability()->setUiReadOnly(false); + + m_rangeValveSpacing.uiCapability()->setUiReadOnly(true); + m_rangeValveCount.uiCapability()->setUiReadOnly(true); + m_rangeStart.uiCapability()->setUiReadOnly(true); + m_rangeEnd.uiCapability()->setUiReadOnly(true); + } + else + { + m_locationOfValves.uiCapability()->setUiReadOnly(true); + + m_rangeValveSpacing.uiCapability()->setUiReadOnly(false); + m_rangeValveCount.uiCapability()->setUiReadOnly(false); + m_rangeStart.uiCapability()->setUiReadOnly(false); + m_rangeEnd.uiCapability()->setUiReadOnly(false); + + if (m_locationType() == VALVE_COUNT) + { + m_rangeValveSpacing.uiCapability()->setUiReadOnly(true); + m_rangeValveCount.uiCapability()->setUiReadOnly(false); + } + else + { + m_rangeValveSpacing.uiCapability()->setUiReadOnly(false); + m_rangeValveCount.uiCapability()->setUiReadOnly(true); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMultipleValveLocations::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + bool recomputeLocations = false; + + if (changedField == &m_locationType) + { + if (m_locationType == VALVE_COUNT || m_locationType == VALVE_SPACING) + { + recomputeLocations = true; + } + } + + if (changedField == &m_rangeStart || + changedField == &m_rangeEnd || + changedField == &m_rangeValveCount || + changedField == &m_rangeValveSpacing) + { + recomputeLocations = true; + m_rangeStart = cvf::Math::clamp(m_rangeStart(), rangeMin(), rangeMax()); + m_rangeEnd = cvf::Math::clamp(m_rangeEnd(), rangeMin(), rangeMax()); + } + + if (changedField == &m_rangeValveSpacing) + { + double minimumDistanceMeter = minimumSpacingMeters(); + + RimWellPath* wellPath = nullptr; + this->firstAncestorOrThisOfTypeAsserted(wellPath); + if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD) + { + double minimumDistanceFeet = RiaEclipseUnitTools::meterToFeet(minimumDistanceMeter); + m_rangeValveSpacing = cvf::Math::clamp(m_rangeValveSpacing(), minimumDistanceFeet, std::max(m_rangeValveSpacing(), minimumDistanceFeet)); + } + else + { + m_rangeValveSpacing = cvf::Math::clamp(m_rangeValveSpacing(), minimumDistanceMeter, std::max(m_rangeValveSpacing(), minimumDistanceMeter)); + } + } + + if (recomputeLocations) + { + computeRangesAndLocations(); + } + + RimWellPathComponentInterface* parentCompletion = nullptr; + this->firstAncestorOrThisOfType(parentCompletion); + caf::PdmObject* pdmParent = dynamic_cast(parentCompletion); + + if (recomputeLocations || changedField == &m_locationOfValves) + { + if (parentCompletion) + { + RimFishbonesMultipleSubs* fishbones = dynamic_cast(parentCompletion); + RimWellPathValve* valve = dynamic_cast(parentCompletion); + if (fishbones) + { + fishbones->recomputeLateralLocations(); + } + else if (valve) + { + valve->geometryUpdated(); + } + + } + } + + if (pdmParent) + { + pdmParent->updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimMultipleValveLocations::rangeCountFromSpacing() const +{ + int rangeCount = (std::fabs(m_rangeStart - m_rangeEnd) / m_rangeValveSpacing) + 1; + + if (rangeCount < 1) + { + rangeCount = 1; + } + return rangeCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMultipleValveLocations::minimumSpacingMeters() const +{ + // Minimum distance between fishbones is 13.0m + // Use 10.0m to allow for some flexibility + return 10.0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMultipleValveLocations::rangeMin() const +{ + const RimPerforationInterval* perfInterval = nullptr; + this->firstAncestorOrThisOfType(perfInterval); + + if (perfInterval) + { + return perfInterval->startMD(); + } + return 0.0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimMultipleValveLocations::rangeMax() const +{ + const RimPerforationInterval* perfInterval = nullptr; + this->firstAncestorOrThisOfType(perfInterval); + + if (perfInterval) + { + return perfInterval->endMD(); + } + + RimWellPath* wellPath = nullptr; + this->firstAncestorOrThisOfTypeAsserted(wellPath); + + RigWellPath* rigWellPathGeo = wellPath->wellPathGeometry(); + if (rigWellPathGeo && !rigWellPathGeo->m_measuredDepths.empty()) + { + double lastWellPathMD = rigWellPathGeo->m_measuredDepths.back(); + return lastWellPathMD; + } + return std::numeric_limits::infinity(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimMultipleValveLocations::locationsFromStartSpacingAndCount(double start, double spacing, size_t count) +{ + std::vector measuredDepths; + + for (size_t i = 0; i < count; i++) + { + measuredDepths.push_back(start + spacing * i); + } + + return measuredDepths; +} diff --git a/ApplicationCode/ProjectDataModel/Completions/RimMultipleValveLocations.h b/ApplicationCode/ProjectDataModel/Completions/RimMultipleValveLocations.h new file mode 100644 index 0000000000..746d56cb23 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimMultipleValveLocations.h @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafAppEnum.h" +#include "cafPdmBase.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cvfBase.h" + + +class RimMultipleValveLocations : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + enum LocationType + { + VALVE_COUNT, + VALVE_SPACING, + VALVE_CUSTOM, + VALVE_UNDEFINED + }; + +public: + RimMultipleValveLocations(); + + double measuredDepth(size_t valveIndex) const; + double rangeStart() const; + double rangeEnd() const; + const std::vector& valveLocations() const; + + void setLocationType(LocationType locationType); + void computeRangesAndLocations(); + + void initFields(LocationType locationType, + double rangeStart, + double rangeEnd, + double valveSpacing, + int valveCount, + const std::vector& locationOfValves); +protected: + virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +private: + int rangeCountFromSpacing() const; + double minimumSpacingMeters() const; + double rangeMin() const; + double rangeMax() const; + static std::vector locationsFromStartSpacingAndCount(double start, double spacing, size_t count); + +private: + caf::PdmField > m_locationType; + caf::PdmField m_rangeStart; + caf::PdmField m_rangeEnd; + caf::PdmField m_rangeValveSpacing; + caf::PdmField m_rangeValveCount; + + caf::PdmField> m_locationOfValves; // Given in measured depth +}; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimNonDarcyPerforationParameters.cpp b/ApplicationCode/ProjectDataModel/Completions/RimNonDarcyPerforationParameters.cpp new file mode 100644 index 0000000000..9d79c4dc43 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimNonDarcyPerforationParameters.cpp @@ -0,0 +1,210 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RimNonDarcyPerforationParameters.h" + +#include "RimWellPath.h" + +#include "cafPdmUiObjectEditorHandle.h" + +#include + +namespace caf +{ +template<> +void caf::AppEnum::setUp() +{ + addItem(RimNonDarcyPerforationParameters::NON_DARCY_NONE, "None", "None"); + addItem(RimNonDarcyPerforationParameters::NON_DARCY_COMPUTED, "Computed", "Compute D-factor"); + addItem(RimNonDarcyPerforationParameters::NON_DARCY_USER_DEFINED, "UserDefined", "User Defined D-factor"); + + setDefault(RimNonDarcyPerforationParameters::NON_DARCY_NONE); +} +} // namespace caf + +CAF_PDM_SOURCE_INIT(RimNonDarcyPerforationParameters, "RimNonDarcyPerforationParameters"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimNonDarcyPerforationParameters::RimNonDarcyPerforationParameters() +{ + CAF_PDM_InitObject("NonDarcyPerforationParameters", ":/CompletionsSymbol16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_nonDarcyFlowType, "NonDarcyFlowType", "Non-Darcy Flow", "", "", ""); + + CAF_PDM_InitField(&m_userDefinedDFactor, "UserDefinedDFactor", 1.0, "D Factor", "", "", ""); + + CAF_PDM_InitField(&m_gridPermeabilityScalingFactor, + "GridPermeabilityScalingFactor", + 1.0, + "Grid Permeability Scaling Factor (Kr) [0..1]", + "", + "", + ""); + + CAF_PDM_InitField(&m_wellRadius, "WellRadius", 0.108, "Well Radius (rw) [m]", "", "", ""); + + CAF_PDM_InitField(&m_relativeGasDensity, + "RelativeGasDensity", + 0.8, + "Relative Gas Density (γ)", + "", + "Relative density of gas at surface conditions with respect to air at STP", + ""); + + CAF_PDM_InitField(&m_gasViscosity, + "GasViscosity", + 0.02, + "Gas Viscosity (μ) [cP]", + "", + "Gas viscosity at bottom hole pressure", + ""); + + CAF_PDM_InitField(&m_inertialCoefficientBeta0, + "InertialCoefficientBeta0", + 883.90, + "Inertial Coefficient (β0) [Forch. unit]", + "", + "", + ""); + CAF_PDM_InitField( + &m_permeabilityScalingFactor, "PermeabilityScalingFactor", -1.1045, "Permeability Scaling Factor (B)", "", "", ""); + + CAF_PDM_InitField(&m_porosityScalingFactor, "PorosityScalingFactor", 0.0, "Porosity Scaling Factor (C)", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimNonDarcyPerforationParameters::~RimNonDarcyPerforationParameters() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimNonDarcyPerforationParameters::NonDarcyFlowEnum RimNonDarcyPerforationParameters::nonDarcyFlowType() const +{ + return m_nonDarcyFlowType(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimNonDarcyPerforationParameters::userDefinedDFactor() const +{ + return m_userDefinedDFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimNonDarcyPerforationParameters::gridPermeabilityScalingFactor() const +{ + return m_gridPermeabilityScalingFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimNonDarcyPerforationParameters::wellRadius() const +{ + return m_wellRadius; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimNonDarcyPerforationParameters::relativeGasDensity() const +{ + return m_relativeGasDensity; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimNonDarcyPerforationParameters::gasViscosity() const +{ + return m_gasViscosity; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimNonDarcyPerforationParameters::inertialCoefficientBeta0() const +{ + return m_inertialCoefficientBeta0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimNonDarcyPerforationParameters::permeabilityScalingFactor() const +{ + return m_permeabilityScalingFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimNonDarcyPerforationParameters::porosityScalingFactor() const +{ + return m_porosityScalingFactor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimNonDarcyPerforationParameters::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) +{ + if (changedField == &m_nonDarcyFlowType) + { + caf::PdmUiObjectEditorHandle::updateUiAllObjectEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimNonDarcyPerforationParameters::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + auto nonDarcyFlowGroup = uiOrdering.addNewGroup("Non-Darcy Flow"); + nonDarcyFlowGroup->add(&m_nonDarcyFlowType); + + if (m_nonDarcyFlowType == NON_DARCY_USER_DEFINED) + { + nonDarcyFlowGroup->add(&m_userDefinedDFactor); + } + else if (m_nonDarcyFlowType == NON_DARCY_COMPUTED) + { + { + auto group = nonDarcyFlowGroup->addNewGroup("Parameters"); + group->add(&m_gridPermeabilityScalingFactor); + group->add(&m_wellRadius); + group->add(&m_relativeGasDensity); + group->add(&m_gasViscosity); + } + { + auto group = nonDarcyFlowGroup->addNewGroup("β Factor"); + group->add(&m_inertialCoefficientBeta0); + group->add(&m_permeabilityScalingFactor); + group->add(&m_porosityScalingFactor); + } + } + uiOrdering.skipRemainingFields(true); +} diff --git a/ApplicationCode/ProjectDataModel/Completions/RimNonDarcyPerforationParameters.h b/ApplicationCode/ProjectDataModel/Completions/RimNonDarcyPerforationParameters.h new file mode 100644 index 0000000000..be92fdc7da --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimNonDarcyPerforationParameters.h @@ -0,0 +1,67 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "RiaEclipseUnitTools.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmUiGroup.h" + +class RimNonDarcyPerforationParameters : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + enum NonDarcyFlowEnum + { + NON_DARCY_NONE, + NON_DARCY_COMPUTED, + NON_DARCY_USER_DEFINED, + }; + + RimNonDarcyPerforationParameters(); + ~RimNonDarcyPerforationParameters() override; + + NonDarcyFlowEnum nonDarcyFlowType() const; + double userDefinedDFactor() const; + double gridPermeabilityScalingFactor() const; + double wellRadius() const; + double relativeGasDensity() const; + double gasViscosity() const; + double inertialCoefficientBeta0() const; + double permeabilityScalingFactor() const; + double porosityScalingFactor() const; + +protected: + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +private: + caf::PdmField> m_nonDarcyFlowType; + caf::PdmField m_userDefinedDFactor; + + caf::PdmField m_gridPermeabilityScalingFactor; + caf::PdmField m_wellRadius; + caf::PdmField m_relativeGasDensity; + caf::PdmField m_gasViscosity; + + caf::PdmField m_inertialCoefficientBeta0; + caf::PdmField m_permeabilityScalingFactor; + caf::PdmField m_porosityScalingFactor; +}; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.cpp b/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.cpp index f67766a70d..303e9f49f3 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.cpp @@ -19,9 +19,14 @@ #include "RimPerforationCollection.h" +#include "RiaApplication.h" + +#include "Rim3dView.h" +#include "RimEclipseCase.h" #include "RimPerforationInterval.h" #include "RimProject.h" -#include "Rim3dView.h" +#include "RimMswCompletionParameters.h" +#include "RimNonDarcyPerforationParameters.h" #include "RigWellPath.h" @@ -44,6 +49,16 @@ RimPerforationCollection::RimPerforationCollection() CAF_PDM_InitFieldNoDefault(&m_perforations, "Perforations", "Perforations", "", "", ""); m_perforations.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_mswParameters, "MswParameters", "Multi Segment Well Parameters", "", "", ""); + m_mswParameters = new RimMswCompletionParameters; + m_mswParameters.uiCapability()->setUiTreeHidden(true); + m_mswParameters.uiCapability()->setUiTreeChildrenHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_nonDarcyParameters, "NonDarcyParameters", "Non-Darcy Parameters", "", "", ""); + m_nonDarcyParameters = new RimNonDarcyPerforationParameters(); + m_nonDarcyParameters.uiCapability()->setUiTreeHidden(true); + m_nonDarcyParameters.uiCapability()->setUiTreeChildrenHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -54,6 +69,42 @@ RimPerforationCollection::~RimPerforationCollection() m_perforations.deleteAllChildObjects(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimMswCompletionParameters* RimPerforationCollection::mswParameters() const +{ + return m_mswParameters; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimNonDarcyPerforationParameters* RimPerforationCollection::nonDarcyParameters() const +{ + return m_nonDarcyParameters; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPerforationCollection::setUnitSystemSpecificDefaults() +{ + m_mswParameters->setUnitSystemSpecificDefaults(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPerforationCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup("Multi Segment Well Options"); + m_mswParameters->uiOrdering(uiConfigName, *mswGroup); + + m_nonDarcyParameters->uiOrdering(uiConfigName, uiOrdering); + uiOrdering.skipRemainingFields(true); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -67,7 +118,7 @@ void RimPerforationCollection::fieldChangedByUi(const caf::PdmFieldHandle* chang } else { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } @@ -76,6 +127,37 @@ void RimPerforationCollection::fieldChangedByUi(const caf::PdmFieldHandle* chang //-------------------------------------------------------------------------------------------------- void RimPerforationCollection::appendPerforation(RimPerforationInterval* perforation) { + QDate firstTimeStepFromCase; + QDate lastTimeStepFromCase; + Rim3dView* activeView = RiaApplication::instance()->activeReservoirView(); + if (activeView) + { + activeView->hasUserRequestedAnimation = true; + + RimEclipseCase* eclipseCase = nullptr; + activeView->firstAncestorOrThisOfType(eclipseCase); + if (eclipseCase) + { + auto dates = eclipseCase->timeStepDates(); + if (!dates.empty()) + { + firstTimeStepFromCase = dates.front().date(); + + lastTimeStepFromCase = dates.back().date(); + } + } + } + + if (firstTimeStepFromCase.isValid()) + { + perforation->setCustomStartDate(firstTimeStepFromCase); + } + + if (lastTimeStepFromCase.isValid()) + { + perforation->setCustomEndDate(lastTimeStepFromCase); + } + m_perforations.push_back(perforation); perforation->setUnitSystemSpecificDefaults(); @@ -95,7 +177,7 @@ std::vector RimPerforationCollection::perforation { std::vector myPerforations; - for (auto perforation : m_perforations) + for (const auto& perforation : m_perforations) { myPerforations.push_back(perforation); } diff --git a/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.h b/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.h index 9ff17ea262..4accf24bac 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimPerforationCollection.h @@ -22,10 +22,13 @@ #include "RimCheckableNamedObject.h" #include "cafPdmObject.h" +#include "cafPdmChildField.h" #include "cafPdmChildArrayField.h" #include "cafPdmField.h" class RimPerforationInterval; +class RimMswCompletionParameters; +class RimNonDarcyPerforationParameters; //================================================================================================== // @@ -38,15 +41,22 @@ class RimPerforationCollection : public RimCheckableNamedObject public: RimPerforationCollection(); - ~RimPerforationCollection(); + ~RimPerforationCollection() override; + const RimMswCompletionParameters* mswParameters() const; + const RimNonDarcyPerforationParameters* nonDarcyParameters() const; + void setUnitSystemSpecificDefaults(); void appendPerforation(RimPerforationInterval* perforation); std::vector perforations() const; - void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); +private: + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; friend class RiuEditPerforationCollectionWidget; private: - caf::PdmChildArrayField m_perforations; + caf::PdmChildArrayField m_perforations; + caf::PdmChildField m_mswParameters; + caf::PdmChildField m_nonDarcyParameters; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.cpp b/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.cpp index 881665cc3a..8ad18b95bb 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.cpp @@ -2,87 +2,123 @@ // // Copyright (C) 2011- Statoil ASA // Copyright (C) 2013- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RimPerforationInterval.h" -#include "RigWellPath.h" +#include "RiaColorTables.h" #include "RigCaseCellResultsData.h" +#include "RigWellPath.h" +#include "RimPerforationCollection.h" #include "RimProject.h" #include "RimWellPath.h" +#include "RimWellPathValve.h" #include "cafPdmUiDateEditor.h" +#include "cafPdmUiDoubleSliderEditor.h" CAF_PDM_SOURCE_INIT(RimPerforationInterval, "Perforation"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimPerforationInterval::RimPerforationInterval() { + // clang-format off CAF_PDM_InitObject("Perforation", ":/PerforationInterval16x16.png", "", ""); - CAF_PDM_InitField(&m_startMD, "StartMeasuredDepth", 0.0, "Start MD", "", "", ""); - CAF_PDM_InitField(&m_endMD, "EndMeasuredDepth", 0.0, "End MD", "", "", ""); - CAF_PDM_InitField(&m_diameter, "Diameter", 0.216, "Diameter", "", "", ""); - CAF_PDM_InitField(&m_skinFactor, "SkinFactor", 0.0, "Skin Factor", "", "", ""); - CAF_PDM_InitField(&m_startOfHistory, "StartOfHistory", true, "All Timesteps", "", "", ""); - CAF_PDM_InitField(&m_date, "StartDate", QDateTime::currentDateTime(), "Start Date", "", "", ""); + CAF_PDM_InitField(&m_startMD, "StartMeasuredDepth", 0.0, "Start MD", "", "", ""); + CAF_PDM_InitField(&m_endMD, "EndMeasuredDepth", 0.0, "End MD", "", "", ""); + CAF_PDM_InitField(&m_diameter, "Diameter", 0.216, "Diameter", "", "", ""); + CAF_PDM_InitField(&m_skinFactor, "SkinFactor", 0.0, "Skin Factor", "", "", ""); + + CAF_PDM_InitField(&m_startOfHistory_OBSOLETE, "StartOfHistory", true, "All Timesteps", "", "", ""); + m_startOfHistory_OBSOLETE.xmlCapability()->setIOWritable(false); + + CAF_PDM_InitField(&m_useCustomStartDate, "UseCustomStartDate", false, "Custom Start Date", "", "", ""); + CAF_PDM_InitField(&m_startDate, "StartDate", QDateTime::currentDateTime(), "Start Date", "", "", ""); + + CAF_PDM_InitField(&m_useCustomEndDate, "UseCustomEndDate", false, "Custom End Date", "", "", ""); + CAF_PDM_InitField(&m_endDate, "EndDate", QDateTime::currentDateTime(), "End Date", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_valves, "Valves", "Valves", "", "", ""); + m_valves.uiCapability()->setUiHidden(true); nameField()->uiCapability()->setUiReadOnly(true); + + m_startMD.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); + m_endMD.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); + // clang-format on } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimPerforationInterval::~RimPerforationInterval() -{ -} +RimPerforationInterval::~RimPerforationInterval() {} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimPerforationInterval::setStartAndEndMD(double startMD, double endMD) { m_startMD = startMD; - m_endMD = endMD; + m_endMD = endMD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPerforationInterval::enableCustomStartDate(bool enable) +{ + m_useCustomStartDate = enable; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimPerforationInterval::setStartOfHistory() +void RimPerforationInterval::setCustomStartDate(const QDate& date) { - m_startOfHistory = true; + if (date.isValid()) + { + m_startDate = QDateTime(date); + } +} - m_date.uiCapability()->setUiReadOnly(m_startOfHistory()); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPerforationInterval::enableCustomEndDate(bool enable) +{ + m_useCustomEndDate = enable; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimPerforationInterval::setDate(const QDate& date) +void RimPerforationInterval::setCustomEndDate(const QDate& date) { - m_startOfHistory = false; - m_date = QDateTime(date); + if (date.isValid()) + { + m_endDate = QDateTime(date); + } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimPerforationInterval::setDiameter(double diameter) { @@ -90,7 +126,7 @@ void RimPerforationInterval::setDiameter(double diameter) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimPerforationInterval::setSkinFactor(double skinFactor) { @@ -98,7 +134,7 @@ void RimPerforationInterval::setSkinFactor(double skinFactor) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RimPerforationInterval::diameter(RiaEclipseUnitTools::UnitSystem unitSystem) const { @@ -112,28 +148,34 @@ double RimPerforationInterval::diameter(RiaEclipseUnitTools::UnitSystem unitSyst { return RiaEclipseUnitTools::meterToFeet(m_diameter()); } + return m_diameter(); } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +double RimPerforationInterval::skinFactor() const +{ + return m_skinFactor(); +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- bool RimPerforationInterval::isActiveOnDate(const QDateTime& date) const { - if (m_startOfHistory()) - { - return true; - } + if (m_useCustomStartDate() && date < m_startDate()) return false; - if (!date.isValid()) return false; + if (m_useCustomEndDate() && date > m_endDate()) return false; - return m_date() < date; + return true; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -cvf::BoundingBox RimPerforationInterval::boundingBoxInDomainCoords() +cvf::BoundingBox RimPerforationInterval::boundingBoxInDomainCoords() const { cvf::BoundingBox bb; @@ -151,7 +193,7 @@ cvf::BoundingBox RimPerforationInterval::boundingBoxInDomainCoords() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimPerforationInterval::setUnitSystemSpecificDefaults() { @@ -171,23 +213,98 @@ void RimPerforationInterval::setUnitSystemSpecificDefaults() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimPerforationInterval::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimPerforationInterval::addValve(RimWellPathValve* valve) { + m_valves.push_back(valve); +} - if (changedField == &m_startOfHistory) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimPerforationInterval::valves() const +{ + std::vector allValves; + for (RimWellPathValve* valve : m_valves()) { - m_date.uiCapability()->setUiReadOnly(m_startOfHistory()); + allValves.push_back(valve); } + return allValves; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimPerforationInterval::isEnabled() const +{ + RimPerforationCollection* perforationCollection; + this->firstAncestorOrThisOfTypeAsserted(perforationCollection); + return perforationCollection->isChecked() && isChecked(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::WellPathComponentType RimPerforationInterval::componentType() const +{ + return RiaDefines::PERFORATION_INTERVAL; +} - RimProject* proj; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimPerforationInterval::componentLabel() const +{ + return QString("Perforation Interval\n%1").arg(name()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimPerforationInterval::componentTypeLabel() const +{ + return "Perforations"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RimPerforationInterval::defaultComponentColor() const +{ + return RiaColorTables::wellPathComponentColors()[componentType()]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimPerforationInterval::startMD() const +{ + return m_startMD(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimPerforationInterval::endMD() const +{ + return m_endMD(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPerforationInterval::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) +{ + RimProject* proj = nullptr; this->firstAncestorOrThisOfTypeAsserted(proj); proj->reloadCompletionTypeResultsInAllViews(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimPerforationInterval::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) { @@ -195,7 +312,7 @@ void RimPerforationInterval::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTree } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimPerforationInterval::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { @@ -218,30 +335,67 @@ void RimPerforationInterval::defineUiOrdering(QString uiConfigName, caf::PdmUiOr } } } - m_date.uiCapability()->setUiReadOnly(m_startOfHistory()); uiOrdering.add(&m_startMD); uiOrdering.add(&m_endMD); uiOrdering.add(&m_diameter); uiOrdering.add(&m_skinFactor); - uiOrdering.add(&m_startOfHistory); - uiOrdering.add(&m_date); + + uiOrdering.add(&m_useCustomStartDate); + uiOrdering.add(&m_startDate); + m_startDate.uiCapability()->setUiReadOnly(!m_useCustomStartDate); + + uiOrdering.add(&m_useCustomEndDate); + uiOrdering.add(&m_endDate); + m_endDate.uiCapability()->setUiReadOnly(!m_useCustomEndDate); uiOrdering.skipRemainingFields(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimPerforationInterval::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +void RimPerforationInterval::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) { - if (field == &m_date) + if (field == &m_startDate || field == &m_endDate) { - caf::PdmUiDateEditorAttribute* myAttr = static_cast(attribute); + caf::PdmUiDateEditorAttribute* myAttr = dynamic_cast(attribute); if (myAttr) { myAttr->dateFormat = "dd MMM yyyy"; } } + else if (field == &m_startMD || field == &m_endMD) + { + caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast(attribute); + + if (myAttr) + { + RimWellPath* rimWellPath = nullptr; + this->firstAncestorOrThisOfType(rimWellPath); + if (!rimWellPath) return; + + RigWellPath* wellPathGeo = rimWellPath->wellPathGeometry(); + if (!wellPathGeo) return; + + if (wellPathGeo->m_measuredDepths.size() > 1) + { + myAttr->m_minimum = wellPathGeo->m_measuredDepths.front(); + myAttr->m_maximum = wellPathGeo->m_measuredDepths.back(); + } + } + } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPerforationInterval::initAfterRead() +{ + if (!m_startOfHistory_OBSOLETE) + { + m_useCustomStartDate = true; + } +} diff --git a/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.h b/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.h index 5d6916d17e..3dfffc3459 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimPerforationInterval.h @@ -21,52 +21,85 @@ #include "RimCheckableNamedObject.h" #include "Rim3dPropertiesInterface.h" +#include "RimWellPathComponentInterface.h" #include "RiaEclipseUnitTools.h" #include "cafPdmField.h" +#include "cafPdmChildArrayField.h" #include "cafPdmObject.h" #include +class RimWellPathValve; + //================================================================================================== /// //================================================================================================== -class RimPerforationInterval : public RimCheckableNamedObject, public Rim3dPropertiesInterface +class RimPerforationInterval : public RimCheckableNamedObject, + public Rim3dPropertiesInterface, + public RimWellPathComponentInterface { CAF_PDM_HEADER_INIT; + public: RimPerforationInterval(); - virtual ~RimPerforationInterval(); + ~RimPerforationInterval() override; void setStartAndEndMD(double startMD, double endMD); - void setStartOfHistory(); - void setDate(const QDate& date); + + void enableCustomStartDate(bool enable); + void setCustomStartDate(const QDate& date); + + void enableCustomEndDate(bool enable); + void setCustomEndDate(const QDate& date); + void setDiameter(double diameter); void setSkinFactor(double skinFactor); - double startMD() const { return m_startMD(); } - double endMD() const { return m_endMD(); } double diameter(RiaEclipseUnitTools::UnitSystem unitSystem) const; - double skinFactor() const { return m_skinFactor(); } + double skinFactor() const; bool isActiveOnDate(const QDateTime& date) const; - virtual cvf::BoundingBox boundingBoxInDomainCoords() override; + cvf::BoundingBox boundingBoxInDomainCoords() const override; void setUnitSystemSpecificDefaults(); + void addValve(RimWellPathValve* valve); + std::vector valves() const; + + // RimWellPathCompletionInterface overrides + bool isEnabled() const override; + RiaDefines::WellPathComponentType componentType() const override; + QString componentLabel() const override; + QString componentTypeLabel() const override; + cvf::Color3f defaultComponentColor() const override; + double startMD() const override; + double endMD() const override; + protected: - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; + void initAfterRead() override; private: caf::PdmField< double > m_startMD; caf::PdmField< double > m_endMD; caf::PdmField< double > m_diameter; caf::PdmField< double > m_skinFactor; - caf::PdmField< bool > m_startOfHistory; - caf::PdmField< QDateTime > m_date; + + caf::PdmField< bool > m_useCustomStartDate; + caf::PdmField< QDateTime > m_startDate; + + caf::PdmField< bool > m_useCustomEndDate; + caf::PdmField< QDateTime > m_endDate; + + caf::PdmChildArrayField m_valves; + + caf::PdmField< bool > m_startOfHistory_OBSOLETE; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimSimWellFracture.cpp b/ApplicationCode/ProjectDataModel/Completions/RimSimWellFracture.cpp index d6f67a8d4b..ca93a9cfe7 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimSimWellFracture.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimSimWellFracture.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2016- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -29,15 +29,13 @@ #include "RimProject.h" #include "RimSimWellInView.h" -#include "cafPdmUiDoubleSliderEditor.h" #include "RigWellPath.h" - - +#include "cafPdmUiDoubleSliderEditor.h" CAF_PDM_SOURCE_INIT(RimSimWellFracture, "SimWellFracture"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimSimWellFracture::RimSimWellFracture(void) { @@ -55,14 +53,12 @@ RimSimWellFracture::RimSimWellFracture(void) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimSimWellFracture::~RimSimWellFracture() -{ -} - +RimSimWellFracture::~RimSimWellFracture() {} + //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimSimWellFracture::setClosestWellCoord(cvf::Vec3d& position, size_t branchIndex) { @@ -77,43 +73,46 @@ void RimSimWellFracture::setClosestWellCoord(cvf::Vec3d& position, size_t branch } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimSimWellFracture::updateAzimuthBasedOnWellAzimuthAngle() { computeSimWellBranchesIfRequired(); - + if (!fractureTemplate()) return; - if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH - || fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) + + if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH || + fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) { double simWellAzimuth = wellAzimuthAtFracturePosition(); - if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH ) + if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) { m_azimuth = simWellAzimuth; } else if (fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) { - if (simWellAzimuth + 90 < 360) m_azimuth = simWellAzimuth + 90; - else m_azimuth = simWellAzimuth - 90; + if (simWellAzimuth + 90 < 360) + m_azimuth = simWellAzimuth + 90; + else + m_azimuth = simWellAzimuth - 90; } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RimSimWellFracture::wellAzimuthAtFracturePosition() const { double simWellAzimuth = m_branchCenterLines[m_branchIndex].simWellAzimuthAngle(fracturePosition()); if (simWellAzimuth < 0) simWellAzimuth += 360; - + return simWellAzimuth; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RimSimWellFracture::wellDipAtFracturePosition() { @@ -123,7 +122,7 @@ double RimSimWellFracture::wellDipAtFracturePosition() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimSimWellFracture::loadDataAndUpdate() { @@ -133,7 +132,7 @@ void RimSimWellFracture::loadDataAndUpdate() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RimSimWellFracture::perforationLengthCenterLineCoords() const { @@ -147,7 +146,7 @@ std::vector RimSimWellFracture::perforationLengthCenterLineCoords() wellPathGeometry.m_measuredDepths = m_branchCenterLines[m_branchIndex].measuredDepths(); double startMd = m_location - perforationLength() / 2.0; - double endMd = m_location + perforationLength() / 2.0; + double endMd = m_location + perforationLength() / 2.0; coords = wellPathGeometry.clippedPointSubset(startMd, endMd).first; } @@ -156,21 +155,23 @@ std::vector RimSimWellFracture::perforationLengthCenterLineCoords() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimSimWellFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimSimWellFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { RimFracture::fieldChangedByUi(changedField, oldValue, newValue); - if ( changedField == &m_location - || changedField == &m_branchIndex - ) + if (changedField == &m_location || changedField == &m_branchIndex) { updateFracturePositionFromLocation(); RimFractureTemplate::FracOrientationEnum orientation; - if (fractureTemplate()) orientation = fractureTemplate()->orientationType(); - else orientation = RimFractureTemplate::AZIMUTH; + if (fractureTemplate()) + orientation = fractureTemplate()->orientationType(); + else + orientation = RimFractureTemplate::AZIMUTH; if (orientation != RimFractureTemplate::AZIMUTH) { @@ -184,7 +185,7 @@ void RimSimWellFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedFiel } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimSimWellFracture::recomputeWellCenterlineCoordinates() { @@ -194,7 +195,7 @@ void RimSimWellFracture::recomputeWellCenterlineCoordinates() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimSimWellFracture::updateFracturePositionFromLocation() { @@ -208,13 +209,12 @@ void RimSimWellFracture::updateFracturePositionFromLocation() RimProject* proj; this->firstAncestorOrThisOfType(proj); - if (proj) proj->createDisplayModelAndRedrawAllViews(); + if (proj) proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimSimWellFracture::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { @@ -246,9 +246,11 @@ void RimSimWellFracture::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderi } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimSimWellFracture::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) +void RimSimWellFracture::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) { RimFracture::defineEditorAttribute(field, uiConfigName, attribute); @@ -264,8 +266,8 @@ void RimSimWellFracture::defineEditorAttribute(const caf::PdmFieldHandle* field, { const RigSimulationWellCoordsAndMD& pointAndMd = m_branchCenterLines[m_branchIndex]; - myAttr->m_minimum = pointAndMd.measuredDepths().front(); - myAttr->m_maximum = pointAndMd.measuredDepths().back(); + myAttr->m_minimum = pointAndMd.measuredDepths().front(); + myAttr->m_maximum = pointAndMd.measuredDepths().back(); myAttr->m_sliderTickCount = pointAndMd.measuredDepths().back(); } } @@ -273,9 +275,10 @@ void RimSimWellFracture::defineEditorAttribute(const caf::PdmFieldHandle* field, } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QList RimSimWellFracture::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +QList RimSimWellFracture::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) { QList options = RimFracture::calculateValueOptions(fieldNeedingOptions, useOptionsOnly); @@ -302,21 +305,21 @@ QList RimSimWellFracture::calculateValueOptions(const ca } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RigMainGrid* RimSimWellFracture::ownerCaseMainGrid() const { RimEclipseView* ownerEclView; this->firstAncestorOrThisOfType(ownerEclView); - if (ownerEclView) + if (ownerEclView) return ownerEclView->mainGrid(); - else + else return nullptr; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimSimWellFracture::computeSimWellBranchesIfRequired() { @@ -327,7 +330,7 @@ void RimSimWellFracture::computeSimWellBranchesIfRequired() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimSimWellFracture::computeSimWellBranchCenterLines() { @@ -337,11 +340,10 @@ void RimSimWellFracture::computeSimWellBranchCenterLines() this->firstAncestorOrThisOfType(rimWell); CVF_ASSERT(rimWell); - std::vector< std::vector > pipeBranchesCLCoords; - std::vector< std::vector > pipeBranchesCellIds; + std::vector> pipeBranchesCLCoords; + std::vector> pipeBranchesCellIds; - rimWell->calculateWellPipeStaticCenterLine(pipeBranchesCLCoords, - pipeBranchesCellIds); + rimWell->calculateWellPipeStaticCenterLine(pipeBranchesCLCoords, pipeBranchesCellIds); for (const auto& branch : pipeBranchesCLCoords) { @@ -352,16 +354,17 @@ void RimSimWellFracture::computeSimWellBranchCenterLines() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QString RimSimWellFracture::createOneBasedIJKText() const { RigMainGrid* mainGrid = ownerCaseMainGrid(); - size_t i,j,k; - size_t anchorCellIdx = findAnchorEclipseCell(mainGrid); + size_t i, j, k; + size_t anchorCellIdx = mainGrid->findReservoirCellIndexFromPoint(anchorPosition()); + if (anchorCellIdx == cvf::UNDEFINED_SIZE_T) return ""; - - size_t gridLocalCellIdx; + + size_t gridLocalCellIdx; const RigGridBase* hostGrid = mainGrid->gridAndGridLocalIdxFromGlobalCellIdx(anchorCellIdx, &gridLocalCellIdx); bool ok = hostGrid->ijkFromCellIndex(gridLocalCellIdx, &i, &j, &k); diff --git a/ApplicationCode/ProjectDataModel/Completions/RimSimWellFracture.h b/ApplicationCode/ProjectDataModel/Completions/RimSimWellFracture.h index 31d559c51c..64535e3332 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimSimWellFracture.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimSimWellFracture.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2016- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -23,54 +23,59 @@ #include "RigSimulationWellCoordsAndMD.h" #include "RimEllipseFractureTemplate.h" - //================================================================================================== -/// -/// +/// +/// //================================================================================================== class RimSimWellFracture : public RimFracture { - CAF_PDM_HEADER_INIT; + CAF_PDM_HEADER_INIT; public: RimSimWellFracture(void); - virtual ~RimSimWellFracture(void); + ~RimSimWellFracture(void) override; - void setClosestWellCoord(cvf::Vec3d& position, size_t branchIndex); + void setClosestWellCoord(cvf::Vec3d& position, size_t branchIndex); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void recomputeWellCenterlineCoordinates(); + void updateFracturePositionFromLocation(); + void updateAzimuthBasedOnWellAzimuthAngle() override; - void recomputeWellCenterlineCoordinates(); - void updateFracturePositionFromLocation(); - void updateAzimuthBasedOnWellAzimuthAngle() override; + double wellAzimuthAtFracturePosition() const override; + double wellDipAtFracturePosition(); + double fractureMD() const override + { + return m_location; + } - double wellAzimuthAtFracturePosition() const override; - double wellDipAtFracturePosition(); - double fractureMD() const override { return m_location; } + int branchIndex() const + { + return m_branchIndex(); + } - int branchIndex() const { return m_branchIndex(); } + void loadDataAndUpdate() override; - virtual void loadDataAndUpdate() override; - - virtual std::vector perforationLengthCenterLineCoords() const override; + std::vector perforationLengthCenterLineCoords() const override; protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - - RigMainGrid* ownerCaseMainGrid() const; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) override; private: - void computeSimWellBranchesIfRequired(); - void computeSimWellBranchCenterLines(); + RigMainGrid* ownerCaseMainGrid() const; + void computeSimWellBranchesIfRequired(); + void computeSimWellBranchCenterLines(); + QString createOneBasedIJKText() const; private: - caf::PdmField m_location; - caf::PdmField m_branchIndex; - std::vector m_branchCenterLines; - - caf::PdmProxyValueField m_displayIJK; - QString createOneBasedIJKText() const; + caf::PdmField m_location; + caf::PdmField m_branchIndex; + std::vector m_branchCenterLines; + caf::PdmProxyValueField m_displayIJK; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimSimWellFractureCollection.h b/ApplicationCode/ProjectDataModel/Completions/RimSimWellFractureCollection.h index 9281fbb92a..d5a585ec11 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimSimWellFractureCollection.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimSimWellFractureCollection.h @@ -34,7 +34,7 @@ class RimSimWellFractureCollection : public caf::PdmObject public: RimSimWellFractureCollection(void); - virtual ~RimSimWellFractureCollection(void); + ~RimSimWellFractureCollection(void) override; caf::PdmChildArrayField simwellFractures; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.cpp b/ApplicationCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.cpp index 921a088887..dbc75013da 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -19,13 +19,18 @@ #include "RimStimPlanFractureTemplate.h" #include "RiaApplication.h" +#include "RiaCompletionTypeCalculationScheduler.h" #include "RiaFractureDefines.h" #include "RiaLogging.h" +#include "RiaWeightedGeometricMeanCalculator.h" +#include "RiaWeightedMeanCalculator.h" #include "RifStimPlanXmlReader.h" -#include "RigStimPlanFractureDefinition.h" #include "RigFractureGrid.h" +#include "RigStimPlanFractureDefinition.h" +#include "RigTransmissibilityEquations.h" +#include "RigWellPathStimplanIntersector.h" #include "RigFractureCell.h" #include "RimEclipseView.h" @@ -42,23 +47,26 @@ #include "cafPdmUiDoubleSliderEditor.h" #include "cafPdmUiFilePathEditor.h" +#include "cvfMath.h" #include "cvfVector3.h" #include #include -#include #include +#include static std::vector EMPTY_DOUBLE_VECTOR; CAF_PDM_SOURCE_INIT(RimStimPlanFractureTemplate, "RimStimPlanFractureTemplate"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimStimPlanFractureTemplate::RimStimPlanFractureTemplate() { + // clang-format off + CAF_PDM_InitObject("Fracture Template", ":/FractureTemplate16x16.png", "", ""); CAF_PDM_InitField(&m_stimPlanFileName, "StimPlanFileName", QString(""), "File Name", "", "", ""); @@ -78,17 +86,17 @@ RimStimPlanFractureTemplate::RimStimPlanFractureTemplate() m_fractureGrid = new RigFractureGrid(); m_readError = false; + + // clang-format on } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimStimPlanFractureTemplate::~RimStimPlanFractureTemplate() -{ -} +RimStimPlanFractureTemplate::~RimStimPlanFractureTemplate() {} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- int RimStimPlanFractureTemplate::activeTimeStepIndex() { @@ -96,9 +104,11 @@ int RimStimPlanFractureTemplate::activeTimeStepIndex() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimStimPlanFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimStimPlanFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { RimFractureTemplate::fieldChangedByUi(changedField, oldValue, newValue); @@ -111,7 +121,7 @@ void RimStimPlanFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* ch if (&m_activeTimeStepIndex == changedField) { - //Changes to this parameters should change all fractures with this fracture template attached. + // Changes to this parameters should change all fractures with this fracture template attached. RimProject* proj; this->firstAncestorOrThisOfType(proj); if (proj) @@ -125,15 +135,13 @@ void RimStimPlanFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* ch fracture->setStimPlanTimeIndexToPlot(m_activeTimeStepIndex); } } - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } - if (&m_wellPathDepthAtFracture == changedField - || &m_borderPolygonResultName == changedField - || &m_activeTimeStepIndex == changedField - || &m_stimPlanFileName == changedField - || &m_conductivityResultNameOnFile == changedField) + if (&m_wellPathDepthAtFracture == changedField || &m_borderPolygonResultName == changedField || + &m_activeTimeStepIndex == changedField || &m_stimPlanFileName == changedField || + &m_conductivityResultNameOnFile == changedField) { updateFractureGrid(); @@ -141,19 +149,19 @@ void RimStimPlanFractureTemplate::fieldChangedByUi(const caf::PdmFieldHandle* ch this->firstAncestorOrThisOfType(proj); if (proj) { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } if (changedField == &m_scaleApplyButton) { m_scaleApplyButton = false; - reload(); + onLoadDataAndUpdateGeometryHasChanged(); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimStimPlanFractureTemplate::setFileName(const QString& fileName) { @@ -161,7 +169,7 @@ void RimStimPlanFractureTemplate::setFileName(const QString& fileName) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const QString& RimStimPlanFractureTemplate::fileName() { @@ -169,7 +177,7 @@ const QString& RimStimPlanFractureTemplate::fileName() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimStimPlanFractureTemplate::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) { @@ -177,20 +185,26 @@ void RimStimPlanFractureTemplate::updateFilePathsFromProjectPath(const QString& } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimStimPlanFractureTemplate::setDefaultsBasedOnXMLfile() { if (m_stimPlanFractureDefinitionData.isNull()) return; - setDepthOfWellPathAtFracture(); - setPerforationLength(); + computeDepthOfWellPathAtFracture(); + computePerforationLength(); + RiaLogging::info(QString("Setting well/fracture intersection depth at %1").arg(m_wellPathDepthAtFracture)); + m_activeTimeStepIndex = static_cast(m_stimPlanFractureDefinitionData->totalNumberTimeSteps() - 1); - bool polygonPropertySet = setBorderPolygonResultNameToDefault(); - if (polygonPropertySet) RiaLogging::info(QString("Calculating polygon outline based on %1 at timestep %2").arg(m_borderPolygonResultName).arg(m_stimPlanFractureDefinitionData->timeSteps()[m_activeTimeStepIndex])); - else RiaLogging::info(QString("Property for polygon calculation not set.")); + bool polygonPropertySet = setBorderPolygonResultNameToDefault(); + if (polygonPropertySet) + RiaLogging::info(QString("Calculating polygon outline based on %1 at timestep %2") + .arg(m_borderPolygonResultName) + .arg(m_stimPlanFractureDefinitionData->timeSteps()[m_activeTimeStepIndex])); + else + RiaLogging::info(QString("Property for polygon calculation not set.")); if (!m_stimPlanFractureDefinitionData->conductivityResultNames().isEmpty()) { @@ -199,7 +213,7 @@ void RimStimPlanFractureTemplate::setDefaultsBasedOnXMLfile() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimStimPlanFractureTemplate::setBorderPolygonResultNameToDefault() { @@ -212,7 +226,7 @@ bool RimStimPlanFractureTemplate::setBorderPolygonResultNameToDefault() return true; } } - + // if width not found, use conductivity if (hasConductivity()) { @@ -230,7 +244,7 @@ bool RimStimPlanFractureTemplate::setBorderPolygonResultNameToDefault() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimStimPlanFractureTemplate::loadDataAndUpdate() { @@ -238,9 +252,9 @@ void RimStimPlanFractureTemplate::loadDataAndUpdate() if (m_readError) return; - m_stimPlanFractureDefinitionData = RifStimPlanXmlReader::readStimPlanXMLFile( m_stimPlanFileName(), + m_stimPlanFractureDefinitionData = RifStimPlanXmlReader::readStimPlanXMLFile(m_stimPlanFileName(), m_conductivityScaleFactor(), - m_widthScaleFactor(), + m_halfLengthScaleFactor(), m_heightScaleFactor(), -m_wellPathDepthAtFracture(), RifStimPlanXmlReader::MIRROR_AUTO, @@ -261,12 +275,22 @@ void RimStimPlanFractureTemplate::loadDataAndUpdate() } else { - setFractureTemplateUnit(RiaEclipseUnitTools::UNITS_UNKNOWN); + setFractureTemplateUnit(RiaEclipseUnitTools::UNITS_UNKNOWN); m_readError = true; } updateFractureGrid(); + for (RimFracture* fracture : fracturesUsingThisTemplate()) + { + fracture->clearCachedNonDarcyProperties(); + } + + if (widthResultValues().empty()) + { + m_fractureWidthType = USER_DEFINED_WIDTH; + } + // Todo: Must update all views using this fracture template RimEclipseView* activeView = dynamic_cast(RiaApplication::instance()->activeReservoirView()); if (activeView) activeView->fractureColors()->loadDataAndUpdate(); @@ -275,13 +299,34 @@ void RimStimPlanFractureTemplate::loadDataAndUpdate() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QList RimStimPlanFractureTemplate::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +QList RimStimPlanFractureTemplate::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) { QList options; - options = RimFractureTemplate::calculateValueOptions(fieldNeedingOptions, useOptionsOnly); + if (fieldNeedingOptions == &m_fractureWidthType) + { + options.push_back(caf::PdmOptionItemInfo(caf::AppEnum::uiText(USER_DEFINED_WIDTH), USER_DEFINED_WIDTH)); + + if (!widthResultValues().empty()) + { + options.push_back(caf::PdmOptionItemInfo(caf::AppEnum::uiText(WIDTH_FROM_FRACTURE), WIDTH_FROM_FRACTURE)); + } + } + + if (fieldNeedingOptions == &m_betaFactorType) + { + options.push_back( + caf::PdmOptionItemInfo(caf::AppEnum::uiText(USER_DEFINED_BETA_FACTOR), USER_DEFINED_BETA_FACTOR)); + + if (isBetaFactorAvailableOnFile()) + { + options.push_back(caf::PdmOptionItemInfo(caf::AppEnum::uiText(BETA_FACTOR_FROM_FRACTURE), + BETA_FACTOR_FROM_FRACTURE)); + } + } if (fieldNeedingOptions == &m_borderPolygonResultName) { @@ -316,14 +361,14 @@ QList RimStimPlanFractureTemplate::calculateValueOptions } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimStimPlanFractureTemplate::setDepthOfWellPathAtFracture() +void RimStimPlanFractureTemplate::computeDepthOfWellPathAtFracture() { if (!m_stimPlanFractureDefinitionData.isNull()) { double firstTvd = m_stimPlanFractureDefinitionData->topPerfTvd(); - double lastTvd = m_stimPlanFractureDefinitionData->bottomPerfTvd(); + double lastTvd = m_stimPlanFractureDefinitionData->bottomPerfTvd(); if (firstTvd != HUGE_VAL && lastTvd != HUGE_VAL) { @@ -331,26 +376,26 @@ void RimStimPlanFractureTemplate::setDepthOfWellPathAtFracture() } else { - firstTvd = m_stimPlanFractureDefinitionData->minDepth(); - lastTvd = m_stimPlanFractureDefinitionData->maxDepth(); + firstTvd = m_stimPlanFractureDefinitionData->minDepth(); + lastTvd = m_stimPlanFractureDefinitionData->maxDepth(); m_wellPathDepthAtFracture = (firstTvd + lastTvd) / 2; } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimStimPlanFractureTemplate::setPerforationLength() +void RimStimPlanFractureTemplate::computePerforationLength() { if (!m_stimPlanFractureDefinitionData.isNull()) { double firstTvd = m_stimPlanFractureDefinitionData->topPerfTvd(); - double lastTvd = m_stimPlanFractureDefinitionData->bottomPerfTvd(); + double lastTvd = m_stimPlanFractureDefinitionData->bottomPerfTvd(); if (firstTvd != HUGE_VAL && lastTvd != HUGE_VAL) { - m_perforationLength = std::round(cvf::Math::abs(firstTvd - lastTvd)); + m_perforationLength = cvf::Math::abs(firstTvd - lastTvd); } } @@ -358,123 +403,273 @@ void RimStimPlanFractureTemplate::setPerforationLength() { m_perforationLength = 10; } - else if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_FIELD && m_perforationLength < RiaEclipseUnitTools::meterToFeet(10)) + else if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_FIELD && + m_perforationLength < RiaEclipseUnitTools::meterToFeet(10)) { m_perforationLength = std::round(RiaEclipseUnitTools::meterToFeet(10)); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QString RimStimPlanFractureTemplate::getUnitForStimPlanParameter(QString parameterName) +std::vector + RimStimPlanFractureTemplate::fractureGridResultsForUnitSystem(const QString& resultName, + const QString& unitName, + size_t timeStepIndex, + RiaEclipseUnitTools::UnitSystem requiredUnitSystem) const { - QString unit; - bool found = false; - bool foundMultiple = false; + auto resultValues = m_stimPlanFractureDefinitionData->fractureGridResults(resultName, unitName, m_activeTimeStepIndex); - for (std::pair nameUnit : uiResultNamesWithUnit()) + if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_METRIC) { - if (nameUnit.first == parameterName) + for (auto& v : resultValues) { - unit = nameUnit.second; - if (found) foundMultiple = true; - found = true; + v = RiaEclipseUnitTools::convertToMeter(v, unitName); + } + } + else if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_FIELD) + { + for (auto& v : resultValues) + { + v = RiaEclipseUnitTools::convertToFeet(v, unitName); } } - if (foundMultiple) RiaLogging::error(QString("Multiple units found for same parameter")); - if (!found) RiaLogging::error(QString("Requested unit / parameter not found for %1 template").arg(name())); - return unit; + return resultValues; } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -FractureWidthAndConductivity RimStimPlanFractureTemplate::widthAndConductivityAtWellPathIntersection() const +WellFractureIntersectionData RimStimPlanFractureTemplate::wellFractureIntersectionData(const RimFracture* fractureInstance) const { - FractureWidthAndConductivity values; + WellFractureIntersectionData values; if (m_fractureGrid.notNull()) { - std::pair wellCellIJ = m_fractureGrid->fractureCellAtWellCenter(); - size_t wellCellIndex = m_fractureGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second); - const RigFractureCell& wellCell = m_fractureGrid->cellFromIndex(wellCellIndex); + if (orientationType() == ALONG_WELL_PATH) + { + CVF_ASSERT(fractureInstance); + + RimWellPath* rimWellPath = nullptr; + fractureInstance->firstAncestorOrThisOfType(rimWellPath); + + if (rimWellPath && rimWellPath->wellPathGeometry()) + { + double totalLength = 0.0; + double weightedConductivity = 0.0; + double weightedWidth = 0.0; + double weightedBetaFactorOnFile = 0.0; + double conversionFactorForBeta = 1.0; + + { + std::vector widthResultValues; + { + auto nameUnit = widthParameterNameAndUnit(); + widthResultValues = fractureGridResultsForUnitSystem( + nameUnit.first, nameUnit.second, m_activeTimeStepIndex, fractureTemplateUnit()); + } + + std::vector conductivityResultValues; + { + auto nameUnit = conductivityParameterNameAndUnit(); + conductivityResultValues = fractureGridResultsForUnitSystem( + nameUnit.first, nameUnit.second, m_activeTimeStepIndex, fractureTemplateUnit()); + } + + std::vector betaFactorResultValues; + { + auto nameUnit = betaFactorParameterNameAndUnit(); + betaFactorResultValues = m_stimPlanFractureDefinitionData->fractureGridResults( + nameUnit.first, nameUnit.second, m_activeTimeStepIndex); + + QString trimmedUnit = nameUnit.second.trimmed().toLower(); + if (trimmedUnit == "/m") + { + conversionFactorForBeta = 1.01325E+08; + } + else if (trimmedUnit == "/cm") + { + conversionFactorForBeta = 1.01325E+06; + } + else if (trimmedUnit == "/ft") + { + conversionFactorForBeta = 3.088386E+07; + } + } - double conductivity = wellCell.getConductivtyValue(); - values.m_conductivity = conductivity; + RiaWeightedMeanCalculator widthCalc; + RiaWeightedMeanCalculator conductivityCalc; + RiaWeightedGeometricMeanCalculator betaFactorCalc; - std::vector > propertyNamesUnitsOnFile = m_stimPlanFractureDefinitionData->getStimPlanPropertyNamesUnits(); + RigWellPathStimplanIntersector intersector(rimWellPath->wellPathGeometry(), fractureInstance); + for (const auto& v : intersector.intersections()) + { + size_t fractureGlobalCellIndex = v.first; + double intersectionLength = v.second.computeLength(); + + if (fractureGlobalCellIndex < widthResultValues.size()) + { + widthCalc.addValueAndWeight(widthResultValues[fractureGlobalCellIndex], intersectionLength); + } + + if (fractureGlobalCellIndex < conductivityResultValues.size()) + { + conductivityCalc.addValueAndWeight(conductivityResultValues[fractureGlobalCellIndex], + intersectionLength); + } - QString propertyNameForFractureWidth; + if (fractureGlobalCellIndex < betaFactorResultValues.size()) + { + betaFactorCalc.addValueAndWeight(betaFactorResultValues[fractureGlobalCellIndex], intersectionLength); + } + } + if (conductivityCalc.validAggregatedWeight()) + { + weightedConductivity = conductivityCalc.weightedMean(); + } + if (widthCalc.validAggregatedWeight()) + { + weightedWidth = widthCalc.weightedMean(); + totalLength = widthCalc.aggregatedWeight(); + } + if (betaFactorCalc.validAggregatedWeight()) + { + weightedBetaFactorOnFile = betaFactorCalc.weightedMean(); + } + } + + if (totalLength > 1e-7) + { + values.m_width = weightedWidth; + values.m_conductivity = weightedConductivity; + + double betaFactorForcheimer = weightedBetaFactorOnFile / conversionFactorForBeta; + values.m_betaFactorInForcheimerUnits = betaFactorForcheimer; + } + + values.m_permeability = RigTransmissibilityEquations::permeability(weightedConductivity, weightedWidth); + } + } + else { - QString widthParameterName; - QString effWidthParameterName; - for (const auto& nameUnit : propertyNamesUnitsOnFile) + std::pair wellCellIJ = m_fractureGrid->fractureCellAtWellCenter(); + size_t wellCellIndex = m_fractureGrid->getGlobalIndexFromIJ(wellCellIJ.first, wellCellIJ.second); + const RigFractureCell& wellCell = m_fractureGrid->cellFromIndex(wellCellIndex); + + double conductivity = wellCell.getConductivityValue(); + values.m_conductivity = conductivity; + + auto nameUnit = widthParameterNameAndUnit(); + if (!nameUnit.first.isEmpty()) { - if (effWidthParameterName.isEmpty() && nameUnit.first.contains("effective width", Qt::CaseInsensitive)) + double widthInRequiredUnit = HUGE_VAL; { - effWidthParameterName = nameUnit.first; + auto resultValues = fractureGridResultsForUnitSystem( + nameUnit.first, nameUnit.second, m_activeTimeStepIndex, fractureTemplateUnit()); + + if (wellCellIndex < resultValues.size()) + { + widthInRequiredUnit = resultValues[wellCellIndex]; + } } - if (widthParameterName.isEmpty() && nameUnit.first.contains("width", Qt::CaseInsensitive)) + if (widthInRequiredUnit != HUGE_VAL && fabs(widthInRequiredUnit) > 1e-20) { - widthParameterName = nameUnit.first; + values.m_width = widthInRequiredUnit; + values.m_permeability = RigTransmissibilityEquations::permeability(conductivity, widthInRequiredUnit); } } + } + } - if (!effWidthParameterName.isEmpty()) + return values; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair RimStimPlanFractureTemplate::widthParameterNameAndUnit() const +{ + if (m_stimPlanFractureDefinitionData.notNull()) + { + std::vector> propertyNamesUnitsOnFile = + m_stimPlanFractureDefinitionData->getStimPlanPropertyNamesUnits(); + + for (const auto& nameUnit : propertyNamesUnitsOnFile) + { + if (nameUnit.first.contains("effective width", Qt::CaseInsensitive)) { - propertyNameForFractureWidth = effWidthParameterName; + return nameUnit; } - else + + if (nameUnit.first.contains("width", Qt::CaseInsensitive)) { - propertyNameForFractureWidth = widthParameterName; + return nameUnit; } } + } - if (!propertyNameForFractureWidth.isEmpty()) - { - for (const auto& nameUnit : propertyNamesUnitsOnFile) - { - if (nameUnit.first == propertyNameForFractureWidth) - { - double widthInRequiredUnit = HUGE_VAL; - { - auto resultValues = m_stimPlanFractureDefinitionData->fractureGridResults(nameUnit.first, nameUnit.second, m_activeTimeStepIndex); + return std::pair(); +} - double widthInFileUnitSystem = resultValues[wellCellIndex]; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair RimStimPlanFractureTemplate::conductivityParameterNameAndUnit() const +{ + if (m_stimPlanFractureDefinitionData.notNull()) + { + std::vector> propertyNamesUnitsOnFile = + m_stimPlanFractureDefinitionData->getStimPlanPropertyNamesUnits(); - if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_METRIC) - { - QString unitText = nameUnit.second; + for (const auto& nameUnit : propertyNamesUnitsOnFile) + { + if (nameUnit.first.contains(m_conductivityResultNameOnFile, Qt::CaseInsensitive)) + { + return nameUnit; + } + } + } - widthInRequiredUnit = RiaEclipseUnitTools::convertToMeter(widthInFileUnitSystem, unitText); - } - else if (fractureTemplateUnit() == RiaEclipseUnitTools::UNITS_FIELD) - { - QString unitText = nameUnit.second; + return std::pair(); +} - widthInRequiredUnit = RiaEclipseUnitTools::convertToFeet(widthInFileUnitSystem, unitText); - } - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair RimStimPlanFractureTemplate::betaFactorParameterNameAndUnit() const +{ + if (m_stimPlanFractureDefinitionData.notNull()) + { + std::vector> propertyNamesUnitsOnFile = + m_stimPlanFractureDefinitionData->getStimPlanPropertyNamesUnits(); - if (widthInRequiredUnit != HUGE_VAL && fabs(widthInRequiredUnit) > 1e-20) - { - values.m_width = widthInRequiredUnit; - values.m_permeability = conductivity / widthInRequiredUnit; - } - } + for (const auto& nameUnit : propertyNamesUnitsOnFile) + { + if (nameUnit.first.contains("beta", Qt::CaseInsensitive)) + { + return nameUnit; } } } - return values; + return std::pair(); } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +bool RimStimPlanFractureTemplate::isBetaFactorAvailableOnFile() const +{ + auto nameAndUnit = betaFactorParameterNameAndUnit(); + + return !nameAndUnit.first.isEmpty(); +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RimStimPlanFractureTemplate::setDefaultConductivityResultIfEmpty() { @@ -488,7 +683,7 @@ void RimStimPlanFractureTemplate::setDefaultConductivityResultIfEmpty() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QString RimStimPlanFractureTemplate::mapUiResultNameToFileResultName(const QString& uiResultName) const { @@ -507,7 +702,7 @@ QString RimStimPlanFractureTemplate::mapUiResultNameToFileResultName(const QStri } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimStimPlanFractureTemplate::showStimPlanMesh() const { @@ -515,7 +710,7 @@ bool RimStimPlanFractureTemplate::showStimPlanMesh() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimStimPlanFractureTemplate::convertToUnitSystem(RiaEclipseUnitTools::UnitSystem neededUnit) { @@ -538,11 +733,15 @@ void RimStimPlanFractureTemplate::convertToUnitSystem(RiaEclipseUnitTools::UnitS m_wellPathDepthAtFracture = RiaEclipseUnitTools::feetToMeter(m_wellPathDepthAtFracture); } - m_activeTimeStepIndex = static_cast(m_stimPlanFractureDefinitionData->totalNumberTimeSteps() - 1); + m_activeTimeStepIndex = static_cast(m_stimPlanFractureDefinitionData->totalNumberTimeSteps() - 1); bool polygonPropertySet = setBorderPolygonResultNameToDefault(); - if (polygonPropertySet) RiaLogging::info(QString("Calculating polygon outline based on %1 at timestep %2").arg(m_borderPolygonResultName).arg(m_stimPlanFractureDefinitionData->timeSteps()[m_activeTimeStepIndex])); - else RiaLogging::info(QString("Property for polygon calculation not set.")); + if (polygonPropertySet) + RiaLogging::info(QString("Calculating polygon outline based on %1 at timestep %2") + .arg(m_borderPolygonResultName) + .arg(m_stimPlanFractureDefinitionData->timeSteps()[m_activeTimeStepIndex])); + else + RiaLogging::info(QString("Property for polygon calculation not set.")); if (!m_stimPlanFractureDefinitionData->conductivityResultNames().isEmpty()) { @@ -551,9 +750,9 @@ void RimStimPlanFractureTemplate::convertToUnitSystem(RiaEclipseUnitTools::UnitS } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimStimPlanFractureTemplate::reload() +void RimStimPlanFractureTemplate::onLoadDataAndUpdateGeometryHasChanged() { loadDataAndUpdate(); @@ -561,13 +760,13 @@ void RimStimPlanFractureTemplate::reload() this->firstAncestorOrThisOfType(proj); if (proj) { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); + RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews(); } - } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RimStimPlanFractureTemplate::timeSteps() { @@ -580,19 +779,20 @@ std::vector RimStimPlanFractureTemplate::timeSteps() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector > RimStimPlanFractureTemplate::uiResultNamesWithUnit() const +std::vector> RimStimPlanFractureTemplate::uiResultNamesWithUnit() const { - std::vector > propertyNamesAndUnits; - + std::vector> propertyNamesAndUnits; + if (m_stimPlanFractureDefinitionData.notNull()) { QString conductivityUnit = "mD/s"; - std::vector > tmp; + std::vector> tmp; - std::vector > propertyNamesUnitsOnFile = m_stimPlanFractureDefinitionData->getStimPlanPropertyNamesUnits(); + std::vector> propertyNamesUnitsOnFile = + m_stimPlanFractureDefinitionData->getStimPlanPropertyNamesUnits(); for (const auto& nameUnitPair : propertyNamesUnitsOnFile) { if (nameUnitPair.first.contains(RiaDefines::conductivityResultName(), Qt::CaseInsensitive)) @@ -617,9 +817,10 @@ std::vector > RimStimPlanFractureTemplate::uiResultN } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector> RimStimPlanFractureTemplate::resultValues(const QString& uiResultName, const QString& unitName, size_t timeStepIndex) const +std::vector> + RimStimPlanFractureTemplate::resultValues(const QString& uiResultName, const QString& unitName, size_t timeStepIndex) const { if (m_stimPlanFractureDefinitionData.notNull()) { @@ -632,9 +833,11 @@ std::vector> RimStimPlanFractureTemplate::resultValues(const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RimStimPlanFractureTemplate::fractureGridResults(const QString& uiResultName, const QString& unitName, size_t timeStepIndex) const +std::vector RimStimPlanFractureTemplate::fractureGridResults(const QString& uiResultName, + const QString& unitName, + size_t timeStepIndex) const { if (m_stimPlanFractureDefinitionData.notNull()) { @@ -643,16 +846,15 @@ std::vector RimStimPlanFractureTemplate::fractureGridResults(const QStri return m_stimPlanFractureDefinitionData->fractureGridResults(fileResultName, unitName, timeStepIndex); } - return std::vector(); + return std::vector(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimStimPlanFractureTemplate::hasConductivity() const { - if (m_stimPlanFractureDefinitionData.notNull() && - !m_stimPlanFractureDefinitionData->conductivityResultNames().isEmpty()) + if (m_stimPlanFractureDefinitionData.notNull() && !m_stimPlanFractureDefinitionData->conductivityResultNames().isEmpty()) { return true; } @@ -661,9 +863,13 @@ bool RimStimPlanFractureTemplate::hasConductivity() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RimStimPlanFractureTemplate::resultValueAtIJ(const QString& uiResultName, const QString& unitName, size_t timeStepIndex, size_t i, size_t j) +double RimStimPlanFractureTemplate::resultValueAtIJ(const QString& uiResultName, + const QString& unitName, + size_t timeStepIndex, + size_t i, + size_t j) { auto values = resultValues(uiResultName, unitName, timeStepIndex); @@ -674,7 +880,6 @@ double RimStimPlanFractureTemplate::resultValueAtIJ(const QString& uiResultName, if (adjustedI >= fractureGrid()->iCellCount() || adjustedJ >= fractureGrid()->jCellCount()) { - return HUGE_VAL; } @@ -684,15 +889,34 @@ double RimStimPlanFractureTemplate::resultValueAtIJ(const QString& uiResultName, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimStimPlanFractureTemplate::appendDataToResultStatistics(const QString& uiResultName, const QString& unit, - MinMaxAccumulator& minMaxAccumulator, - PosNegAccumulator& posNegAccumulator) const +std::vector RimStimPlanFractureTemplate::widthResultValues() const +{ + std::vector resultValues; + + auto nameUnit = widthParameterNameAndUnit(); + if (!nameUnit.first.isEmpty()) + { + resultValues = + fractureGridResultsForUnitSystem(nameUnit.first, nameUnit.second, m_activeTimeStepIndex, fractureTemplateUnit()); + } + + return resultValues; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimStimPlanFractureTemplate::appendDataToResultStatistics(const QString& uiResultName, + const QString& unit, + MinMaxAccumulator& minMaxAccumulator, + PosNegAccumulator& posNegAccumulator) const { if (m_stimPlanFractureDefinitionData.notNull()) { QString fileResultName = mapUiResultNameToFileResultName(uiResultName); - m_stimPlanFractureDefinitionData->appendDataToResultStatistics(fileResultName, unit, minMaxAccumulator, posNegAccumulator); + m_stimPlanFractureDefinitionData->appendDataToResultStatistics( + fileResultName, unit, minMaxAccumulator, posNegAccumulator); } } @@ -705,7 +929,7 @@ const RigFractureGrid* RimStimPlanFractureTemplate::fractureGrid() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimStimPlanFractureTemplate::updateFractureGrid() { @@ -713,80 +937,75 @@ void RimStimPlanFractureTemplate::updateFractureGrid() if (m_stimPlanFractureDefinitionData.notNull()) { - m_fractureGrid = m_stimPlanFractureDefinitionData->createFractureGrid(m_conductivityResultNameOnFile, - m_activeTimeStepIndex, - m_wellPathDepthAtFracture, - m_fractureTemplateUnit()); + m_fractureGrid = m_stimPlanFractureDefinitionData->createFractureGrid( + m_conductivityResultNameOnFile, m_activeTimeStepIndex, m_wellPathDepthAtFracture, m_fractureTemplateUnit()); } } - - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimStimPlanFractureTemplate::fractureTriangleGeometry(std::vector* nodeCoords, - std::vector* triangleIndices) +void RimStimPlanFractureTemplate::fractureTriangleGeometry(std::vector* nodeCoords, + std::vector* triangleIndices) const { - - if (m_stimPlanFractureDefinitionData.isNull()) - { - loadDataAndUpdate(); - } - else + if (m_stimPlanFractureDefinitionData.notNull()) { - m_stimPlanFractureDefinitionData->createFractureTriangleGeometry(m_wellPathDepthAtFracture, - name(), - nodeCoords, - triangleIndices); + m_stimPlanFractureDefinitionData->createFractureTriangleGeometry( + m_wellPathDepthAtFracture, name(), nodeCoords, triangleIndices); } } //-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimStimPlanFractureTemplate::fractureBorderPolygon() -{ - // Not implemented - return std::vector(); -} - - -//-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimStimPlanFractureTemplate::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { uiOrdering.add(&m_name); uiOrdering.add(&m_id); - caf::PdmUiGroup* fileGroup = uiOrdering.addNewGroup("Input"); - fileGroup->add(&m_stimPlanFileName); - fileGroup->add(&m_activeTimeStepIndex); - fileGroup->add(&m_wellPathDepthAtFracture); + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Input"); + group->add(&m_stimPlanFileName); + group->add(&m_activeTimeStepIndex); + group->add(&m_wellPathDepthAtFracture); + } - caf::PdmUiGroup* geometryGroup = uiOrdering.addNewGroup("Geometry"); - geometryGroup->add(&m_orientationType); - geometryGroup->add(&m_azimuthAngle); + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Geometry"); + group->add(&m_orientationType); + group->add(&m_azimuthAngle); + } - caf::PdmUiGroup* trGr = uiOrdering.addNewGroup("Fracture Truncation"); - m_fractureContainment()->defineUiOrdering(uiConfigName, *trGr); + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Fracture Truncation"); + group->setCollapsedByDefault(true); + m_fractureContainment()->uiOrdering(uiConfigName, *group); + } - caf::PdmUiGroup* propertyGroup = uiOrdering.addNewGroup("Properties"); - propertyGroup->add(&m_conductivityResultNameOnFile); - propertyGroup->add(&m_conductivityType); - propertyGroup->add(&m_skinFactor); - propertyGroup->add(&m_perforationLength); - propertyGroup->add(&m_perforationEfficiency); - propertyGroup->add(&m_wellDiameter); + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Properties"); + group->add(&m_conductivityResultNameOnFile); + group->add(&m_conductivityType); + group->add(&m_skinFactor); + group->add(&m_perforationLength); + group->add(&m_perforationEfficiency); + group->add(&m_wellDiameter); + } + + if (widthResultValues().empty()) + { + m_fractureWidthType = USER_DEFINED_WIDTH; + } RimFractureTemplate::defineUiOrdering(uiConfigName, uiOrdering); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimStimPlanFractureTemplate::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) +void RimStimPlanFractureTemplate::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) { RimFractureTemplate::defineEditorAttribute(field, uiConfigName, attribute); @@ -801,10 +1020,10 @@ void RimStimPlanFractureTemplate::defineEditorAttribute(const caf::PdmFieldHandl if (field == &m_wellPathDepthAtFracture) { - if ( !m_stimPlanFractureDefinitionData.isNull() && (m_stimPlanFractureDefinitionData->yCount() > 0) ) + if (!m_stimPlanFractureDefinitionData.isNull() && (m_stimPlanFractureDefinitionData->yCount() > 0)) { caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast(attribute); - if ( myAttr ) + if (myAttr) { myAttr->m_minimum = m_stimPlanFractureDefinitionData->minDepth(); myAttr->m_maximum = m_stimPlanFractureDefinitionData->maxDepth(); diff --git a/ApplicationCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.h b/ApplicationCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.h index 1554eb6718..7b2cbbb123 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimStimPlanFractureTemplate.h @@ -50,7 +50,7 @@ class RimStimPlanFractureTemplate : public RimFractureTemplate public: RimStimPlanFractureTemplate(); - virtual ~RimStimPlanFractureTemplate(); + ~RimStimPlanFractureTemplate() override; int activeTimeStepIndex(); @@ -68,8 +68,7 @@ class RimStimPlanFractureTemplate : public RimFractureTemplate const RigFractureGrid* fractureGrid() const override; void updateFractureGrid(); void fractureTriangleGeometry(std::vector* nodeCoords, - std::vector* triangleIndices) override; - std::vector fractureBorderPolygon() override; + std::vector* triangleIndices) const override; // Result Access @@ -80,6 +79,8 @@ class RimStimPlanFractureTemplate : public RimFractureTemplate bool hasConductivity() const; double resultValueAtIJ(const QString& uiResultName, const QString& unitName, size_t timeStepIndex, size_t i, size_t j); + std::vector widthResultValues() const; + void appendDataToResultStatistics(const QString& uiResultName, const QString& unit, MinMaxAccumulator& minMaxAccumulator, @@ -91,23 +92,27 @@ class RimStimPlanFractureTemplate : public RimFractureTemplate void convertToUnitSystem(RiaEclipseUnitTools::UnitSystem neededUnit) override; - virtual void reload() override; - -protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) override; private: + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + QList 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; + void onLoadDataAndUpdateGeometryHasChanged() override; + void setDefaultConductivityResultIfEmpty(); bool setBorderPolygonResultNameToDefault(); - void setDepthOfWellPathAtFracture(); - void setPerforationLength(); - QString getUnitForStimPlanParameter(QString parameterName); + void computeDepthOfWellPathAtFracture(); + void computePerforationLength(); + + std::vector fractureGridResultsForUnitSystem(const QString& resultName, const QString& unitName, size_t timeStepIndex, RiaEclipseUnitTools::UnitSystem requiredUnitSystem) const; + WellFractureIntersectionData wellFractureIntersectionData(const RimFracture* fractureInstance) const override; - virtual FractureWidthAndConductivity widthAndConductivityAtWellPathIntersection() const override; + std::pair widthParameterNameAndUnit() const; + std::pair conductivityParameterNameAndUnit() const; + std::pair betaFactorParameterNameAndUnit() const; + bool isBetaFactorAvailableOnFile() const override; private: caf::PdmField m_activeTimeStepIndex; diff --git a/ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/3/2/1/dummy.txt b/ApplicationCode/ProjectDataModel/Completions/RimWellPathCompletionInterface similarity index 100% rename from ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/3/2/1/dummy.txt rename to ApplicationCode/ProjectDataModel/Completions/RimWellPathCompletionInterface diff --git a/ApplicationCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp b/ApplicationCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp index 861462bfc1..ba5bae45c6 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimWellPathCompletions.cpp @@ -18,15 +18,44 @@ #include "RimWellPathCompletions.h" +#include "RiaStdStringTools.h" + #include "RimFishbonesCollection.h" #include "RimFishboneWellPathCollection.h" +#include "RimFishbonesMultipleSubs.h" #include "RimPerforationCollection.h" +#include "RimPerforationInterval.h" #include "RimWellPathFractureCollection.h" +#include "RimWellPathFracture.h" +#include "RimWellPathComponentInterface.h" +#include "RimWellPathValve.h" #include "cvfAssert.h" #include "cafPdmUiTreeOrdering.h" +#include + +//-------------------------------------------------------------------------------------------------- +/// Internal constants +//-------------------------------------------------------------------------------------------------- +#define DOUBLE_INF std::numeric_limits::infinity() + + +namespace caf { + + template<> + void RimWellPathCompletions::WellTypeEnum::setUp() + { + addItem(RimWellPathCompletions::OIL, "OIL", "Oil"); + addItem(RimWellPathCompletions::GAS, "GAS", "Gas"); + addItem(RimWellPathCompletions::WATER, "WATER", "Water"); + addItem(RimWellPathCompletions::LIQUID, "LIQUID", "Liquid"); + + setDefault(RimWellPathCompletions::OIL); + } +} + CAF_PDM_SOURCE_INIT(RimWellPathCompletions, "WellPathCompletions"); @@ -50,6 +79,12 @@ RimWellPathCompletions::RimWellPathCompletions() m_fractureCollection.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&m_wellNameForExport, "WellNameForExport", QString(), "Well Name for Completion Export", "", "", ""); + + CAF_PDM_InitField(&m_wellGroupName, "WellGroupNameForExport", QString(), "Well Group Name for Completion Export", "", "", ""); + + CAF_PDM_InitField(&m_referenceDepth, "ReferenceDepthForExport", QString(), "Reference Depth for Completion Export", "", "", ""); + + CAF_PDM_InitField(&m_wellType, "WellTypeForExport", WellTypeEnum(), "Well Type for Completion Export", "", "", ""); } //-------------------------------------------------------------------------------------------------- @@ -77,7 +112,8 @@ RimPerforationCollection* RimWellPathCompletions::perforationCollection() const //-------------------------------------------------------------------------------------------------- void RimWellPathCompletions::setWellNameForExport(const QString& name) { - m_wellNameForExport = name; + auto n = name; + m_wellNameForExport = n.remove(' '); } //-------------------------------------------------------------------------------------------------- @@ -85,7 +121,43 @@ void RimWellPathCompletions::setWellNameForExport(const QString& name) //-------------------------------------------------------------------------------------------------- QString RimWellPathCompletions::wellNameForExport() const { - return m_wellNameForExport(); + return formatStringForExport(m_wellNameForExport()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletions::wellGroupNameForExport() const +{ + return formatStringForExport(m_wellGroupName, "1*"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletions::referenceDepthForExport() const +{ + std::string refDepth = m_referenceDepth.v().toStdString(); + if (RiaStdStringTools::isNumber(refDepth, '.')) + { + return m_referenceDepth.v(); + } + return "1*"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletions::wellTypeNameForExport() const +{ + switch (m_wellType.v()) + { + case OIL: return "OIL"; + case GAS: return "GAS"; + case WATER: return "WATER"; + case LIQUID: return "LIQ"; + } + return ""; } //-------------------------------------------------------------------------------------------------- @@ -98,17 +170,56 @@ RimWellPathFractureCollection* RimWellPathCompletions::fractureCollection() cons return m_fractureCollection; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathCompletions::valves() const +{ + std::vector allValves; + this->descendantsIncludingThisOfType(allValves); + return allValves; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathCompletions::allCompletions() const +{ + std::vector completions; + + for (const RimWellPathFracture* fracture : fractureCollection()->allFractures()) + { + completions.push_back(fracture); + } + for (const RimFishbonesMultipleSubs* fishbones : fishbonesCollection()->allFishbonesSubs()) + { + completions.push_back(fishbones); + } + for (const RimPerforationInterval* perforation : perforationCollection()->perforations()) + { + completions.push_back(perforation); + } + + std::vector allValves = valves(); + for (const RimWellPathValve* valve : allValves) + { + completions.push_back(valve); + } + + return completions; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimWellPathCompletions::hasCompletions() const { - if (!fractureCollection()->fractures().empty()) + if (!fractureCollection()->allFractures().empty()) { return true; } - return !fishbonesCollection()->fishbonesSubs().empty() || + return !fishbonesCollection()->allFishbonesSubs().empty() || !fishbonesCollection()->wellPathCollection()->wellPaths().empty() || !perforationCollection()->perforations().empty(); } @@ -119,6 +230,7 @@ bool RimWellPathCompletions::hasCompletions() const void RimWellPathCompletions::setUnitSystemSpecificDefaults() { m_fishbonesCollection->setUnitSystemSpecificDefaults(); + m_fractureCollection->setUnitSystemSpecificDefaults(); } //-------------------------------------------------------------------------------------------------- @@ -133,14 +245,48 @@ void RimWellPathCompletions::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTree uiTreeOrdering.add(&m_perforationCollection); } - if (!fishbonesCollection()->fishbonesSubs().empty() || + if (!fishbonesCollection()->allFishbonesSubs().empty() || !fishbonesCollection()->wellPathCollection()->wellPaths().empty()) { uiTreeOrdering.add(&m_fishbonesCollection); } - if (!fractureCollection()->fractures().empty()) + if (!fractureCollection()->allFractures().empty()) { uiTreeOrdering.add(&m_fractureCollection); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathCompletions::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &m_referenceDepth) + { + if (!RiaStdStringTools::isNumber(m_referenceDepth.v().toStdString(), '.')) + { + if (!RiaStdStringTools::isNumber(m_referenceDepth.v().toStdString(), ',')) + { + // Remove invalid input text + m_referenceDepth = ""; + } + else + { + // Wrong decimal sign entered, replace , by . + auto text = m_referenceDepth.v(); + m_referenceDepth = text.replace(',', '.'); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathCompletions::formatStringForExport(const QString& text, const QString& defaultValue) const +{ + if (text.isEmpty()) return defaultValue; + if (text.contains(' ')) return QString("'%1'").arg(text); + return text; +} diff --git a/ApplicationCode/ProjectDataModel/Completions/RimWellPathCompletions.h b/ApplicationCode/ProjectDataModel/Completions/RimWellPathCompletions.h index 04ec0c37fd..4ccc47067e 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimWellPathCompletions.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimWellPathCompletions.h @@ -25,6 +25,8 @@ class RimFishbonesCollection; class RimPerforationCollection; class RimWellPathFractureCollection; +class RimWellPathComponentInterface; +class RimWellPathValve; //================================================================================================== /// @@ -34,21 +36,34 @@ class RimWellPathCompletions : public caf::PdmObject { CAF_PDM_HEADER_INIT; + enum WellType {OIL, GAS, WATER, LIQUID}; + typedef caf::AppEnum WellTypeEnum; + public: RimWellPathCompletions(); RimFishbonesCollection* fishbonesCollection() const; RimPerforationCollection* perforationCollection() const; RimWellPathFractureCollection* fractureCollection() const; + std::vector valves() const; + + std::vector allCompletions() const; void setWellNameForExport(const QString& name); QString wellNameForExport() const; + QString wellGroupNameForExport() const; + QString referenceDepthForExport() const; + QString wellTypeNameForExport() const; bool hasCompletions() const; void setUnitSystemSpecificDefaults(); protected: - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + +private: + QString formatStringForExport(const QString& text, const QString& defaultText = "") const; private: caf::PdmChildField m_fishbonesCollection; @@ -56,4 +71,8 @@ class RimWellPathCompletions : public caf::PdmObject caf::PdmChildField m_fractureCollection; caf::PdmField m_wellNameForExport; + caf::PdmField m_wellGroupName; + + caf::PdmField m_referenceDepth; + caf::PdmField m_wellType; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimWellPathComponentInterface.h b/ApplicationCode/ProjectDataModel/Completions/RimWellPathComponentInterface.h new file mode 100644 index 0000000000..950d3e0c84 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimWellPathComponentInterface.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaDefines.h" + +#include "cvfBase.h" +#include "cvfColor3.h" + +//================================================================================================== +// Interface implemented by all well path construction components and completions +// +// +//================================================================================================== +class RimWellPathComponentInterface +{ +public: + virtual bool isEnabled() const = 0; + virtual RiaDefines::WellPathComponentType componentType() const = 0; + virtual QString componentLabel() const = 0; + virtual QString componentTypeLabel() const = 0; + virtual cvf::Color3f defaultComponentColor() const = 0; + virtual double startMD() const = 0; + virtual double endMD() const = 0; +}; + + diff --git a/ApplicationCode/ProjectDataModel/Completions/RimWellPathFracture.cpp b/ApplicationCode/ProjectDataModel/Completions/RimWellPathFracture.cpp index 9284429f6a..23446e484b 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimWellPathFracture.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimWellPathFracture.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2016- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -26,30 +26,34 @@ #include "cafPdmUiDoubleSliderEditor.h" - - CAF_PDM_SOURCE_INIT(RimWellPathFracture, "WellPathFracture"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimWellPathFracture::RimWellPathFracture(void) { CAF_PDM_InitObject("Fracture", ":/FractureSymbol16x16.png", "", ""); - CAF_PDM_InitField( &m_measuredDepth, "MeasuredDepth", 0.0f, "Measured Depth Location", "", "", ""); + CAF_PDM_InitField(&m_measuredDepth, "MeasuredDepth", 0.0f, "Measured Depth Location", "", "", ""); m_measuredDepth.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathFracture::~RimWellPathFracture() {} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- -RimWellPathFracture::~RimWellPathFracture() +double RimWellPathFracture::fractureMD() const { + return m_measuredDepth; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimWellPathFracture::setMeasuredDepth(double mdValue) { @@ -59,9 +63,11 @@ void RimWellPathFracture::setMeasuredDepth(double mdValue) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimWellPathFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimWellPathFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { RimFracture::fieldChangedByUi(changedField, oldValue, newValue); @@ -77,16 +83,15 @@ void RimWellPathFracture::fieldChangedByUi(const caf::PdmFieldHandle* changedFie } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimWellPathFracture::updateAzimuthBasedOnWellAzimuthAngle() { if (!fractureTemplate()) return; - if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH - || fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) + if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH || + fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) { - double wellPathAzimuth = wellAzimuthAtFracturePosition(); if (fractureTemplate()->orientationType() == RimFractureTemplate::ALONG_WELL_PATH) @@ -95,14 +100,16 @@ void RimWellPathFracture::updateAzimuthBasedOnWellAzimuthAngle() } if (fractureTemplate()->orientationType() == RimFractureTemplate::TRANSVERSE_WELL_PATH) { - if (wellPathAzimuth + 90 < 360) m_azimuth = wellPathAzimuth + 90; - else m_azimuth = wellPathAzimuth - 90; + if (wellPathAzimuth + 90 < 360) + m_azimuth = wellPathAzimuth + 90; + else + m_azimuth = wellPathAzimuth - 90; } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RimWellPathFracture::wellAzimuthAtFracturePosition() const { @@ -111,7 +118,7 @@ double RimWellPathFracture::wellAzimuthAtFracturePosition() const if (!wellPath) return cvf::UNDEFINED_DOUBLE; double wellPathAzimuth = 0.0; - + RigWellPath* wellPathGeometry = wellPath->wellPathGeometry(); if (wellPathGeometry) { @@ -124,7 +131,7 @@ double RimWellPathFracture::wellAzimuthAtFracturePosition() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimWellPathFracture::loadDataAndUpdate() { @@ -133,7 +140,7 @@ void RimWellPathFracture::loadDataAndUpdate() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RimWellPathFracture::perforationLengthCenterLineCoords() const { @@ -144,7 +151,7 @@ std::vector RimWellPathFracture::perforationLengthCenterLineCoords() if (wellPath && wellPath->wellPathGeometry()) { double startMd = m_measuredDepth - perforationLength() / 2.0; - double endMd = m_measuredDepth + perforationLength() / 2.0; + double endMd = m_measuredDepth + perforationLength() / 2.0; auto coordsAndMd = wellPath->wellPathGeometry()->clippedPointSubset(startMd, endMd); @@ -155,7 +162,31 @@ std::vector RimWellPathFracture::perforationLengthCenterLineCoords() } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellPathFracture::compareByWellPathNameAndMD(const RimWellPathFracture* lhs, const RimWellPathFracture* rhs) +{ + CVF_TIGHT_ASSERT(lhs && rhs); + + RimWellPath* lhsWellPath = nullptr; + lhs->firstAncestorOrThisOfType(lhsWellPath); + + RimWellPath* rhsWellPath = nullptr; + rhs->firstAncestorOrThisOfType(rhsWellPath); + + if (lhsWellPath && rhsWellPath) + { + if (lhsWellPath->name() != rhsWellPath->name()) + { + return lhsWellPath->name() < rhsWellPath->name(); + } + } + + return lhs->fractureMD() < rhs->fractureMD(); +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RimWellPathFracture::updatePositionFromMeasuredDepth() { @@ -178,7 +209,7 @@ void RimWellPathFracture::updatePositionFromMeasuredDepth() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimWellPathFracture::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { @@ -205,13 +236,14 @@ void RimWellPathFracture::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder caf::PdmUiGroup* fractureCenterGroup = uiOrdering.addNewGroup("Fracture Center Info"); fractureCenterGroup->add(&m_uiAnchorPosition); - } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimWellPathFracture::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) +void RimWellPathFracture::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) { RimFracture::defineEditorAttribute(field, uiConfigName, attribute); @@ -236,4 +268,3 @@ void RimWellPathFracture::defineEditorAttribute(const caf::PdmFieldHandle* field } } } - diff --git a/ApplicationCode/ProjectDataModel/Completions/RimWellPathFracture.h b/ApplicationCode/ProjectDataModel/Completions/RimWellPathFracture.h index 44f0457b17..707ddea581 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimWellPathFracture.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimWellPathFracture.h @@ -35,27 +35,29 @@ class RimWellPathFracture : public RimFracture public: RimWellPathFracture(void); - virtual ~RimWellPathFracture(void); + ~RimWellPathFracture(void) override; - double fractureMD() const override { return m_measuredDepth; } - void setMeasuredDepth(double mdValue); + double fractureMD() const override; + void setMeasuredDepth(double mdValue); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void updateAzimuthBasedOnWellAzimuthAngle() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void updateAzimuthBasedOnWellAzimuthAngle() override; - double wellAzimuthAtFracturePosition() const override; + double wellAzimuthAtFracturePosition() const override; - virtual void loadDataAndUpdate() override; + void loadDataAndUpdate() override; - virtual std::vector perforationLengthCenterLineCoords() const override; + std::vector perforationLengthCenterLineCoords() const override; + + static bool compareByWellPathNameAndMD(const RimWellPathFracture* lhs, const RimWellPathFracture* rhs); protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) override; private: - void updatePositionFromMeasuredDepth(); + void updatePositionFromMeasuredDepth(); private: - caf::PdmField m_measuredDepth; + caf::PdmField m_measuredDepth; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimWellPathFractureCollection.cpp b/ApplicationCode/ProjectDataModel/Completions/RimWellPathFractureCollection.cpp index 53f7f72582..1a7e8d9f17 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimWellPathFractureCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Completions/RimWellPathFractureCollection.cpp @@ -24,6 +24,15 @@ #include "cafPdmObject.h" +namespace caf { + template<> + void RimWellPathFractureCollection::ReferenceMDEnum::setUp() + { + addItem(RimWellPathFractureCollection::AUTO_REFERENCE_MD, "GridIntersectionRefMD", "Grid Entry Point"); + addItem(RimWellPathFractureCollection::MANUAL_REFERENCE_MD, "ManualRefMD", "User Defined"); + setDefault(RimWellPathFractureCollection::AUTO_REFERENCE_MD); + } +} CAF_PDM_SOURCE_INIT(RimWellPathFractureCollection, "WellPathFractureCollection"); @@ -35,11 +44,18 @@ RimWellPathFractureCollection::RimWellPathFractureCollection(void) { CAF_PDM_InitObject("Fractures", ":/FractureLayout16x16.png", "", ""); - CAF_PDM_InitFieldNoDefault(&fractures, "Fractures", "", "", "", ""); - fractures.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_fractures, "Fractures", "", "", "", ""); + m_fractures.uiCapability()->setUiHidden(true); setName("Fractures"); nameField()->uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_refMDType, "RefMDType", "Reference MD", "", "", ""); + CAF_PDM_InitField(&m_refMD, "RefMD", 0.0, "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_mswParameters, "MswParameters", "Multi Segment Well Parameters", "", "", ""); + m_mswParameters = new RimMswCompletionParameters; + m_mswParameters.uiCapability()->setUiTreeHidden(true); + m_mswParameters.uiCapability()->setUiTreeChildrenHidden(true); } //-------------------------------------------------------------------------------------------------- @@ -49,12 +65,99 @@ RimWellPathFractureCollection::~RimWellPathFractureCollection() { } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimMswCompletionParameters* RimWellPathFractureCollection::mswParameters() const +{ + return m_mswParameters; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathFractureCollection::addFracture(RimWellPathFracture* fracture) +{ + m_fractures.push_back(fracture); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPathFractureCollection::deleteFractures() { - fractures.deleteAllChildObjects(); + m_fractures.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathFractureCollection::setUnitSystemSpecificDefaults() +{ + m_mswParameters->setUnitSystemSpecificDefaults(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathFractureCollection::ReferenceMDType RimWellPathFractureCollection::referenceMDType() const +{ + return m_refMDType(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathFractureCollection::manualReferenceMD() const +{ + if (m_refMDType == AUTO_REFERENCE_MD) + { + return std::numeric_limits::infinity(); + } + return m_refMD; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathFractureCollection::allFractures() const +{ + return m_fractures.childObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathFractureCollection::activeFractures() const +{ + std::vector active; + + if (isChecked()) + { + for (const auto& f : allFractures()) + { + if (f->isChecked()) + { + active.push_back(f); + } + } + } + + return active; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathFractureCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* mswGroup = uiOrdering.addNewGroup("Multi Segment Well Options"); + + mswGroup->add(&m_refMDType); + mswGroup->add(&m_refMD); + m_refMD.uiCapability()->setUiHidden(m_refMDType == AUTO_REFERENCE_MD); + + m_mswParameters->uiOrdering(uiConfigName, *mswGroup); } //-------------------------------------------------------------------------------------------------- @@ -70,6 +173,6 @@ void RimWellPathFractureCollection::fieldChangedByUi(const caf::PdmFieldHandle* } else { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } diff --git a/ApplicationCode/ProjectDataModel/Completions/RimWellPathFractureCollection.h b/ApplicationCode/ProjectDataModel/Completions/RimWellPathFractureCollection.h index 4f4501a25f..6aba1118df 100644 --- a/ApplicationCode/ProjectDataModel/Completions/RimWellPathFractureCollection.h +++ b/ApplicationCode/ProjectDataModel/Completions/RimWellPathFractureCollection.h @@ -19,11 +19,15 @@ #pragma once #include "RimCheckableNamedObject.h" +#include "RimMswCompletionParameters.h" +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmChildArrayField.h" +#include + class RimWellPathFracture; //================================================================================================== @@ -33,16 +37,35 @@ class RimWellPathFracture; class RimWellPathFractureCollection : public RimCheckableNamedObject { CAF_PDM_HEADER_INIT; - public: + enum ReferenceMDType + { + AUTO_REFERENCE_MD = 0, + MANUAL_REFERENCE_MD + }; + + typedef caf::AppEnum ReferenceMDEnum; + RimWellPathFractureCollection(void); - virtual ~RimWellPathFractureCollection(void); + ~RimWellPathFractureCollection(void) override; - void deleteFractures(); + const RimMswCompletionParameters* mswParameters() const; + void addFracture(RimWellPathFracture* fracture); + void deleteFractures(); + void setUnitSystemSpecificDefaults(); + ReferenceMDType referenceMDType() const; + double manualReferenceMD() const; + + std::vector allFractures() const; + std::vector activeFractures() const; -public: - caf::PdmChildArrayField fractures; +private: + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmChildArrayField m_fractures; + caf::PdmField m_refMDType; + caf::PdmField m_refMD; + caf::PdmChildField m_mswParameters; }; diff --git a/ApplicationCode/ProjectDataModel/Completions/RimWellPathValve.cpp b/ApplicationCode/ProjectDataModel/Completions/RimWellPathValve.cpp new file mode 100644 index 0000000000..8027fe538b --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimWellPathValve.cpp @@ -0,0 +1,306 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellPathValve.h" + +#include "RiaDefines.h" +#include "RiaColorTables.h" +#include "RiaEclipseUnitTools.h" + +#include "RigWellPath.h" + +#include "RimMultipleValveLocations.h" +#include "RimPerforationInterval.h" +#include "RimProject.h" +#include "RimWellPath.h" + +#include "cafPdmUiDoubleSliderEditor.h" + +CAF_PDM_SOURCE_INIT(RimWellPathValve, "WellPathValve"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathValve::RimWellPathValve() +{ + CAF_PDM_InitObject("WellPathValve", ":/ICDValve16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_type, "CompletionType", "Type ", "", "", ""); + m_type = RiaDefines::ICD; + + CAF_PDM_InitField(&m_measuredDepth, "StartMeasuredDepth", 0.0, "Start MD", "", "", ""); + m_measuredDepth.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); + + CAF_PDM_InitFieldNoDefault(&m_multipleValveLocations, "ValveLocations", "Valve Locations", "", "", ""); + m_multipleValveLocations = new RimMultipleValveLocations; + m_multipleValveLocations.uiCapability()->setUiTreeHidden(true); + m_multipleValveLocations.uiCapability()->setUiTreeChildrenHidden(true); + nameField()->uiCapability()->setUiReadOnly(true); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathValve::~RimWellPathValve() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathValve::setMeasuredDepthAndCount(double startMD, double spacing, int valveCount) +{ + m_measuredDepth = startMD; + double endMD = startMD + spacing * valveCount; + m_multipleValveLocations->initFields(RimMultipleValveLocations::VALVE_COUNT, startMD, endMD, spacing, valveCount, {}); + m_multipleValveLocations->computeRangesAndLocations(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathValve::geometryUpdated() +{ + m_measuredDepth = m_multipleValveLocations->valveLocations().front(); + + RimProject* proj; + this->firstAncestorOrThisOfTypeAsserted(proj); + proj->reloadCompletionTypeResultsInAllViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathValve::valveLocations() const +{ + std::vector valveDepths; + if (m_type() == RiaDefines::ICV) + { + valveDepths.push_back(m_measuredDepth); + } + else + { + valveDepths = m_multipleValveLocations->valveLocations(); + } + return valveDepths; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellPathValve::isEnabled() const +{ + RimPerforationInterval* perforationInterval = nullptr; + this->firstAncestorOrThisOfType(perforationInterval); + return perforationInterval->isEnabled() && isChecked(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::WellPathComponentType RimWellPathValve::componentType() const +{ + return m_type(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathValve::componentLabel() const +{ + return m_type().uiText(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathValve::componentTypeLabel() const +{ + return m_type().uiText(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RimWellPathValve::defaultComponentColor() const +{ + return RiaColorTables::wellPathComponentColors()[componentType()]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathValve::startMD() const +{ + if (m_type() == RiaDefines::ICV) + { + return m_measuredDepth; + } + else if (m_multipleValveLocations()->valveLocations().empty()) + { + return m_multipleValveLocations->rangeStart(); + } + else + { + return m_multipleValveLocations()->valveLocations().front(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathValve::endMD() const +{ + if (m_type() == RiaDefines::ICV) + { + return m_measuredDepth + 0.5; + } + else if (m_multipleValveLocations()->valveLocations().empty()) + { + return m_multipleValveLocations->rangeEnd(); + } + else + { + return m_multipleValveLocations()->valveLocations().back(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimWellPathValve::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList options; + + if (fieldNeedingOptions == &m_type) + { + std::set supportedTypes = { RiaDefines::ICD, RiaDefines::AICD, RiaDefines::ICV }; + for (RiaDefines::WellPathComponentType type : supportedTypes) + { + options.push_back(caf::PdmOptionItemInfo(CompletionTypeEnum::uiText(type), type)); + } + } + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathValve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + RimProject* proj; + this->firstAncestorOrThisOfTypeAsserted(proj); + proj->reloadCompletionTypeResultsInAllViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathValve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + uiOrdering.add(&m_type); + + if (m_type() == RiaDefines::ICV) + { + RimWellPath* wellPath; + firstAncestorOrThisOfType(wellPath); + if (wellPath) + { + if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_METRIC) + { + m_measuredDepth.uiCapability()->setUiName("Measured Depth [m]"); + } + else if (wellPath->unitSystem() == RiaEclipseUnitTools::UNITS_FIELD) + { + m_measuredDepth.uiCapability()->setUiName("Measured Depth [ft]"); + } + } + uiOrdering.add(&m_measuredDepth); + } + else + { + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Multiple Valve Locations"); + m_multipleValveLocations->uiOrdering(uiConfigName, *group); + } + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathValve::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_measuredDepth) + { + caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast(attribute); + + if (myAttr) + { + double minimumValue = 0.0, maximumValue = 0.0; + + RimPerforationInterval* perforationInterval = nullptr; + this->firstAncestorOrThisOfType(perforationInterval); + + if (perforationInterval) + { + minimumValue = perforationInterval->startMD(); + maximumValue = perforationInterval->endMD(); + } + else + { + RimWellPath* rimWellPath = nullptr; + this->firstAncestorOrThisOfTypeAsserted(rimWellPath); + RigWellPath* wellPathGeo = rimWellPath->wellPathGeometry(); + if (!wellPathGeo) return; + + if (wellPathGeo->m_measuredDepths.size() > 2) + { + minimumValue = wellPathGeo->measureDepths().front(); + maximumValue = wellPathGeo->measureDepths().back(); + } + } + myAttr->m_minimum = minimumValue; + myAttr->m_maximum = maximumValue; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathValve::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + QString fullName = componentLabel() + QString(" %1").arg(m_measuredDepth()); + this->setName(fullName); + + if ( m_type() == RiaDefines::ICD ) + { + this->setUiIcon(QIcon(":/ICDValve16x16.png")); + } + else if ( m_type() == RiaDefines::ICV ) + { + this->setUiIcon(QIcon(":/ICVValve16x16.png")); + } + else if ( m_type() == RiaDefines::AICD ) + { + this->setUiIcon(QIcon(":/AICDValve16x16.png")); + } +} diff --git a/ApplicationCode/ProjectDataModel/Completions/RimWellPathValve.h b/ApplicationCode/ProjectDataModel/Completions/RimWellPathValve.h new file mode 100644 index 0000000000..a33a2403bd --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Completions/RimWellPathValve.h @@ -0,0 +1,71 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "RimCheckableNamedObject.h" +#include "RimWellPathComponentInterface.h" + +#include "cafPdmObject.h" + +#include "cafAppEnum.h" +#include "cafPdmChildField.h" +#include "cafPdmField.h" + +#include +#include + +class RimMultipleValveLocations; +class RimWellPath; + +class RimWellPathValve : public RimCheckableNamedObject, public RimWellPathComponentInterface +{ + CAF_PDM_HEADER_INIT; +public: + typedef caf::AppEnum CompletionTypeEnum; + + RimWellPathValve(); + ~RimWellPathValve() override; + + void setMeasuredDepthAndCount(double startMD, double spacing, int valveCount); + void geometryUpdated(); + std::vector valveLocations() const; + + // Overrides from RimWellPathCompletionInterface + bool isEnabled() const override; + RiaDefines::WellPathComponentType componentType() const override; + QString componentLabel() const override; + QString componentTypeLabel() const override; + cvf::Color3f defaultComponentColor() const override; + double startMD() const override; + double endMD() const override; + +private: + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + +private: + caf::PdmField m_type; + caf::PdmField m_measuredDepth; + caf::PdmChildField m_multipleValveLocations; + +}; + + diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h index eee505c912..e5a1df6dcd 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowCharacteristicsPlot.h @@ -54,17 +54,17 @@ class RimFlowCharacteristicsPlot : public RimViewWindow public: RimFlowCharacteristicsPlot(); - virtual ~RimFlowCharacteristicsPlot(); + ~RimFlowCharacteristicsPlot() override; void setFromFlowSolution(RimFlowDiagSolution* flowSolution); void updateCurrentTimeStep(); // RimViewWindow overrides - virtual QWidget* viewWidget() override; - virtual void zoomAll() override; - virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; - virtual void deleteViewWidget() override; + QWidget* viewWidget() override; + void zoomAll() override; + QWidget* createViewWidget(QWidget* mainWindowParent) override; + void deleteViewWidget() override; void viewGeometryUpdated(); enum TimeSelectionType @@ -76,14 +76,14 @@ class RimFlowCharacteristicsPlot : public RimViewWindow protected: // RimViewWindow overrides - virtual QImage snapshotWindowContent() override; + QImage snapshotWindowContent() override; // Overridden PDM methods - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ); - virtual void onLoadDataAndUpdate() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + QList 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; + void onLoadDataAndUpdate() override; private: diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowDiagSolution.cpp b/ApplicationCode/ProjectDataModel/Flow/RimFlowDiagSolution.cpp index 4e5639d818..db8412da42 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowDiagSolution.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowDiagSolution.cpp @@ -126,7 +126,7 @@ std::vector RimFlowDiagSolution::tracerNames() const std::vector tracerNameSet; - if (eclCase) + if (eclCase && eclCase->eclipseCaseData()) { const cvf::Collection& simWellData = eclCase->eclipseCaseData()->wellResults(); @@ -166,7 +166,7 @@ std::map > RimFlowDiagSolution::allTracerActiveCel std::map > tracersWithCells; - if ( eclCase ) + if (eclCase && eclCase->eclipseCaseData()) { const cvf::Collection& simWellData = eclCase->eclipseCaseData()->wellResults(); RigMainGrid* mainGrid = eclCase->eclipseCaseData()->mainGrid(); @@ -227,40 +227,42 @@ RimFlowDiagSolution::TracerStatusType RimFlowDiagSolution::tracerStatusOverall(c this->firstAncestorOrThisOfTypeAsserted(eclCase); TracerStatusType tracerStatus = UNDEFINED; - - const cvf::Collection& simWellData = eclCase->eclipseCaseData()->wellResults(); - - for ( size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx ) + if (eclCase && eclCase->eclipseCaseData()) { - QString wellName = removeCrossFlowEnding(tracerName); - - if ( simWellData[wIdx]->m_wellName != wellName ) continue; + const cvf::Collection& simWellData = eclCase->eclipseCaseData()->wellResults(); - tracerStatus = CLOSED; - for ( const RigWellResultFrame& wellResFrame : simWellData[wIdx]->m_wellCellsTimeSteps ) + for ( size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx ) { - if ( wellResFrame.m_productionType == RigWellResultFrame::GAS_INJECTOR - || wellResFrame.m_productionType == RigWellResultFrame::OIL_INJECTOR - || wellResFrame.m_productionType == RigWellResultFrame::WATER_INJECTOR ) - { - if ( tracerStatus == PRODUCER ) tracerStatus = VARYING; - else tracerStatus = INJECTOR; - } - else if ( wellResFrame.m_productionType == RigWellResultFrame::PRODUCER ) + QString wellName = removeCrossFlowEnding(tracerName); + + if ( simWellData[wIdx]->m_wellName != wellName ) continue; + + tracerStatus = CLOSED; + for ( const RigWellResultFrame& wellResFrame : simWellData[wIdx]->m_wellCellsTimeSteps ) { - if ( tracerStatus == INJECTOR ) tracerStatus = VARYING; - else tracerStatus = PRODUCER; + if ( wellResFrame.m_productionType == RigWellResultFrame::GAS_INJECTOR + || wellResFrame.m_productionType == RigWellResultFrame::OIL_INJECTOR + || wellResFrame.m_productionType == RigWellResultFrame::WATER_INJECTOR ) + { + if ( tracerStatus == PRODUCER ) tracerStatus = VARYING; + else tracerStatus = INJECTOR; + } + else if ( wellResFrame.m_productionType == RigWellResultFrame::PRODUCER ) + { + if ( tracerStatus == INJECTOR ) tracerStatus = VARYING; + else tracerStatus = PRODUCER; + } + if ( tracerStatus == VARYING ) break; } - if ( tracerStatus == VARYING ) break; - } - break; - } + break; + } - if (hasCrossFlowEnding(tracerName)) - { - if (tracerStatus == PRODUCER) tracerStatus = INJECTOR; - else if (tracerStatus == INJECTOR) tracerStatus = PRODUCER; + if (hasCrossFlowEnding(tracerName)) + { + if (tracerStatus == PRODUCER) tracerStatus = INJECTOR; + else if (tracerStatus == INJECTOR) tracerStatus = PRODUCER; + } } return tracerStatus; @@ -274,39 +276,42 @@ RimFlowDiagSolution::TracerStatusType RimFlowDiagSolution::tracerStatusInTimeSte RimEclipseResultCase* eclCase; this->firstAncestorOrThisOfTypeAsserted(eclCase); - const cvf::Collection& simWellData = eclCase->eclipseCaseData()->wellResults(); - - for ( size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx ) + if (eclCase && eclCase->eclipseCaseData()) { - QString wellName = removeCrossFlowEnding(tracerName); + const cvf::Collection& simWellData = eclCase->eclipseCaseData()->wellResults(); - if ( simWellData[wIdx]->m_wellName != wellName ) continue; - if (!simWellData[wIdx]->hasWellResult(timeStepIndex)) return CLOSED; + for ( size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx ) + { + QString wellName = removeCrossFlowEnding(tracerName); - const RigWellResultFrame& wellResFrame = simWellData[wIdx]->wellResultFrame(timeStepIndex); + if ( simWellData[wIdx]->m_wellName != wellName ) continue; + if (!simWellData[wIdx]->hasWellResult(timeStepIndex)) return CLOSED; - if ( wellResFrame.m_productionType == RigWellResultFrame::GAS_INJECTOR - || wellResFrame.m_productionType == RigWellResultFrame::OIL_INJECTOR - || wellResFrame.m_productionType == RigWellResultFrame::WATER_INJECTOR ) - { - if ( hasCrossFlowEnding(tracerName) ) return PRODUCER; + const RigWellResultFrame& wellResFrame = simWellData[wIdx]->wellResultFrame(timeStepIndex); - return INJECTOR; - } - else if ( wellResFrame.m_productionType == RigWellResultFrame::PRODUCER - || wellResFrame.m_productionType == RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE ) - { - if ( hasCrossFlowEnding(tracerName) ) return INJECTOR; + if ( wellResFrame.m_productionType == RigWellResultFrame::GAS_INJECTOR + || wellResFrame.m_productionType == RigWellResultFrame::OIL_INJECTOR + || wellResFrame.m_productionType == RigWellResultFrame::WATER_INJECTOR ) + { + if ( hasCrossFlowEnding(tracerName) ) return PRODUCER; - return PRODUCER; - } - else - { - CVF_ASSERT(false); + return INJECTOR; + } + else if ( wellResFrame.m_productionType == RigWellResultFrame::PRODUCER + || wellResFrame.m_productionType == RigWellResultFrame::UNDEFINED_PRODUCTION_TYPE ) + { + if ( hasCrossFlowEnding(tracerName) ) return INJECTOR; + + return PRODUCER; + } + else + { + CVF_ASSERT(false); + } } - } - CVF_ASSERT(false); + CVF_ASSERT(false); + } return UNDEFINED; } diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowDiagSolution.h b/ApplicationCode/ProjectDataModel/Flow/RimFlowDiagSolution.h index d4dd513b7d..d5ad1d3ac7 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowDiagSolution.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowDiagSolution.h @@ -37,7 +37,7 @@ class RimFlowDiagSolution : public caf::PdmObject public: RimFlowDiagSolution(); - virtual ~RimFlowDiagSolution(); + ~RimFlowDiagSolution() override; QString userDescription() const; RigFlowDiagResults* flowDiagResults(); @@ -65,7 +65,7 @@ class RimFlowDiagSolution : public caf::PdmObject private: std::map > allTracerActiveCellIndices(size_t timeStepIndex, bool useInjectors) const; - virtual caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* userDescriptionField() override; caf::PdmField m_userDescription; cvf::ref m_flowDiagResults; diff --git a/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h b/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h index 4b743df602..8e132e81ed 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimFlowPlotCollection.h @@ -34,7 +34,7 @@ class RimFlowPlotCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimFlowPlotCollection(); - virtual ~RimFlowPlotCollection(); + ~RimFlowPlotCollection() override; void closeDefaultPlotWindowAndDeletePlots(); void loadDataAndUpdate(); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimTofAccumulatedPhaseFractionsPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimTofAccumulatedPhaseFractionsPlot.h index 5c7de82fe3..0b51dc1132 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimTofAccumulatedPhaseFractionsPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimTofAccumulatedPhaseFractionsPlot.h @@ -53,17 +53,17 @@ class RimTofAccumulatedPhaseFractionsPlot : public RimViewWindow public: RimTofAccumulatedPhaseFractionsPlot(); - virtual ~RimTofAccumulatedPhaseFractionsPlot(); + ~RimTofAccumulatedPhaseFractionsPlot() override; void setDescription(const QString& description); QString description() const; // RimViewWindow overrides - virtual QWidget* viewWidget() override; - virtual void zoomAll() override; - virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; - virtual void deleteViewWidget() override; + QWidget* viewWidget() override; + void zoomAll() override; + QWidget* createViewWidget(QWidget* mainWindowParent) override; + void deleteViewWidget() override; void reloadFromWell(); @@ -74,12 +74,12 @@ class RimTofAccumulatedPhaseFractionsPlot : public RimViewWindow protected: // RimViewWindow overrides - virtual void onLoadDataAndUpdate() override; - virtual QImage snapshotWindowContent() override; + void onLoadDataAndUpdate() override; + QImage snapshotWindowContent() override; // Overridden PDM methods - virtual caf::PdmFieldHandle* userDescriptionField() { return &m_userName; } - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* userDescriptionField() override { return &m_userName; } + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: caf::PdmField m_showPlotTitle; diff --git a/ApplicationCode/ProjectDataModel/Flow/RimTotalWellAllocationPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimTotalWellAllocationPlot.h index d842136b0e..15b290cea5 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimTotalWellAllocationPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimTotalWellAllocationPlot.h @@ -52,7 +52,7 @@ class RimTotalWellAllocationPlot : public RimViewWindow public: RimTotalWellAllocationPlot(); - virtual ~RimTotalWellAllocationPlot(); + ~RimTotalWellAllocationPlot() override; void setDescription(const QString& description); QString description() const; @@ -62,20 +62,20 @@ class RimTotalWellAllocationPlot : public RimViewWindow void clearSlices(); // RimViewWindow overrides - virtual QWidget* viewWidget() override; - virtual void zoomAll() override; - virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; - virtual void deleteViewWidget() override; + QWidget* viewWidget() override; + void zoomAll() override; + QWidget* createViewWidget(QWidget* mainWindowParent) override; + void deleteViewWidget() override; protected: // RimViewWindow overrides - virtual void onLoadDataAndUpdate() override; - virtual QImage snapshotWindowContent() override; + void onLoadDataAndUpdate() override; + QImage snapshotWindowContent() override; // Overridden PDM methods - virtual caf::PdmFieldHandle* userDescriptionField() { return &m_userName; } - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* userDescriptionField() override { return &m_userName; } + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: caf::PdmField m_showPlotTitle; diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h index bb9b60aeaa..c19d58d7a5 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlot.h @@ -59,15 +59,15 @@ class RimWellAllocationPlot : public RimViewWindow public: RimWellAllocationPlot(); - virtual ~RimWellAllocationPlot(); + ~RimWellAllocationPlot() override; void setFromSimulationWell(RimSimWellInView* simWell); void setDescription(const QString& description); QString description() const; - virtual QWidget* viewWidget() override; - virtual void zoomAll() override; + QWidget* viewWidget() override; + void zoomAll() override; RimWellLogPlot* accumulatedWellFlowPlot(); RimTotalWellAllocationPlot* totalWellFlowPlot(); @@ -83,18 +83,18 @@ class RimWellAllocationPlot : public RimViewWindow void showPlotLegend(bool doShow); protected: // Overridden PDM methods - virtual caf::PdmFieldHandle* userDescriptionField() { return &m_userName; } - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* userDescriptionField() override { return &m_userName; } + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; std::set findSortedWellNames(); - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual QImage snapshotWindowContent() override; + QImage snapshotWindowContent() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void onLoadDataAndUpdate() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void onLoadDataAndUpdate() override; private: void updateFromWell(); @@ -113,8 +113,8 @@ class RimWellAllocationPlot : public RimViewWindow // RimViewWindow overrides - virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; - virtual void deleteViewWidget() override; + QWidget* createViewWidget(QWidget* mainWindowParent) override; + void deleteViewWidget() override; cvf::Color3f getTracerColor(const QString& tracerName); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlotLegend.h b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlotLegend.h index be6f44870a..7b2847dbe7 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlotLegend.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellAllocationPlotLegend.h @@ -31,14 +31,14 @@ class RimWellAllocationPlotLegend : public caf::PdmObject public: RimWellAllocationPlotLegend(); - virtual ~RimWellAllocationPlotLegend(); + ~RimWellAllocationPlotLegend() override; bool isShowingLegend() { return m_showLegend();} protected: - virtual caf::PdmFieldHandle* objectToggleField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* objectToggleField() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: caf::PdmField m_showLegend; diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.cpp index b15a035f81..c33bb803d7 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.cpp @@ -26,7 +26,7 @@ #include "RimWellLogPlot.h" #include "RimWellLogTrack.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "qwt_plot.h" @@ -113,14 +113,6 @@ void RimWellFlowRateCurve::setDoFillCurve(bool doFill) m_doFillCurve = doFill; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimWellFlowRateCurve::doFillCurve() const -{ - return m_doFillCurve; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.h b/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.h index ef8898f25a..d37964a3b6 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellFlowRateCurve.h @@ -36,26 +36,25 @@ class RimWellFlowRateCurve : public RimWellLogCurve CAF_PDM_HEADER_INIT; public: RimWellFlowRateCurve(); - virtual ~RimWellFlowRateCurve(); + ~RimWellFlowRateCurve() override; void setFlowValuesPrDepthValue(const QString& curveName , const std::vector& depthValues, const std::vector& flowRates); void updateStackedPlotData(); - virtual QString wellName() const override; - virtual QString wellLogChannelName() const override; + QString wellName() const override; + QString wellLogChannelName() const override; void setGroupId(int groupId); int groupId() const; void setDoFillCurve(bool doFill); - bool doFillCurve() const; protected: - virtual QString createCurveAutoName() override; - virtual void onLoadDataAndUpdate(bool updateParentPlot) override; - virtual void updateCurveAppearance() override; + QString createCurveAutoName() override; + void onLoadDataAndUpdate(bool updateParentPlot) override; + void updateCurveAppearance() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: bool isUsingConnectionNumberDepthType() const; diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellPlotTools.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellPlotTools.cpp index 838da84278..8a63a28a6f 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellPlotTools.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellPlotTools.cpp @@ -19,6 +19,7 @@ #include "RimWellPlotTools.h" #include "RiaApplication.h" +#include "RiaQDateTimeTools.h" #include "RiaWellNameComparer.h" #include "RifReaderEclipseRft.h" @@ -31,6 +32,7 @@ #include "RimEclipseResultCase.h" #include "RimOilField.h" #include "RimProject.h" +#include "RimTools.h" #include "RimWellLogExtractionCurve.h" #include "RimWellLogFile.h" #include "RimWellLogFileChannel.h" @@ -39,7 +41,6 @@ #include "RimWellPath.h" #include "RimWellPathCollection.h" -#include "RimTools.h" #include //-------------------------------------------------------------------------------------------------- @@ -406,51 +407,6 @@ std::vector RimWellPlotTools::rftCasesForWell(const QStri return cases; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::set RimWellPlotTools::timeStepsFromRftCase(RimEclipseResultCase* rftCase, const QString& simWellName) -{ - std::set timeSteps; - RifReaderEclipseRft* const reader = rftCase->rftReader(); - if (reader != nullptr) - { - for (const QDateTime& timeStep : reader->availableTimeSteps(simWellName, RifEclipseRftAddress::PRESSURE)) - { - timeSteps.insert(timeStep); - } - } - return timeSteps; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::set RimWellPlotTools::timeStepsFromGridCase(RimEclipseCase* gridCase) -{ - const RigEclipseCaseData* const eclipseCaseData = gridCase->eclipseCaseData(); - std::pair resultDataInfo = pressureResultDataInfo(eclipseCaseData); - - std::set timeSteps; - if (resultDataInfo.first != cvf::UNDEFINED_SIZE_T) - { - for (const QDateTime& timeStep : eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->timeStepDates(resultDataInfo.first)) - { - timeSteps.insert(timeStep); - } - } - return timeSteps; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QDateTime RimWellPlotTools::timeStepFromWellLogFile(RimWellLogFile* wellLogFile) -{ - QDateTime timeStep = wellLogFile->date(); - return timeStep; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -566,7 +522,6 @@ RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve(const RimWellLogCur } else if (wellLogFileCurve != nullptr) { - const RimWellPath* const wellPath = wellLogFileCurve->wellPath(); RimWellLogFile* const wellLogFile = wellLogFileCurve->wellLogFile(); if (wellLogFile != nullptr) @@ -987,7 +942,8 @@ void RimWellPlotTools::calculateValueOptionsForTimeSteps( for (const std::pair>& timeStepPair : timestepsToShowWithSources) { - QString optionText = timeStepPair.first.toString(dateFormatString); + QString optionText = RiaQDateTimeTools::toStringUsingApplicationLocale(timeStepPair.first, dateFormatString); + bool hasObs = false; bool hasRft = false; bool hasGrid = false; diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellPlotTools.h b/ApplicationCode/ProjectDataModel/Flow/RimWellPlotTools.h index 51819d6b60..5a2c1921fa 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellPlotTools.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellPlotTools.h @@ -68,9 +68,6 @@ class RimWellPlotTools static std::vector wellLogFilesContainingPressure(const QString& wellPathNameOrSimWellName); static RimWellLogFileChannel* getPressureChannelFromWellFile(const RimWellLogFile* wellLogFile); static RimWellPath* wellPathFromWellLogFile(const RimWellLogFile* wellLogFile); - static std::set timeStepsFromRftCase(RimEclipseResultCase* rftCase, const QString& simWellName); - static std::set timeStepsFromGridCase(RimEclipseCase* gridCase); - static QDateTime timeStepFromWellLogFile(RimWellLogFile* wellLogFile); static std::map> timeStepsMapFromGridCase(RimEclipseCase* gridCase); static RiaRftPltCurveDefinition curveDefFromCurve(const RimWellLogCurve* curve); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.cpp index 55a1989977..3a598cb48a 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.cpp @@ -21,6 +21,7 @@ #include "RiaApplication.h" #include "RiaColorTables.h" #include "RiaDateStringParser.h" +#include "RiaQDateTimeTools.h" #include "RiaWellNameComparer.h" #include "RifReaderEclipseRft.h" @@ -502,9 +503,6 @@ void RimWellPltPlot::syncCurvesFromUiSelection() int curveGroupId = 0; - RimProject* proj = RiaApplication::instance()->project(); - RimWellPath* wellPath = RimWellPlotTools::wellPathByWellPathNameOrSimWellName(m_wellPathName); - QString dateFormatString; { std::vector allTimeSteps; @@ -531,7 +529,8 @@ void RimWellPltPlot::syncCurvesFromUiSelection() curveName += sourceDef.eclCase() ? sourceDef.eclCase()->caseUserDescription() : ""; curveName += sourceDef.wellLogFile() ? sourceDef.wellLogFile()->name() : ""; if ( sourceDef.sourceType() == RifDataSourceForRftPlt::RFT ) curveName += ", RFT"; - curveName += ", " + timeStep.toString(dateFormatString); + + curveName += ", " + RiaQDateTimeTools::toStringUsingApplicationLocale(timeStep, dateFormatString); } RimEclipseResultCase* rimEclipseResultCase = dynamic_cast(sourceDef.eclCase()); @@ -626,7 +625,6 @@ void RimWellPltPlot::syncCurvesFromUiSelection() } else if ( sourceDef.sourceType() == RifDataSourceForRftPlt::OBSERVED ) { - RimWellLogFile* const wellLogFile = sourceDef.wellLogFile(); if ( sourceDef.wellLogFile() && sourceDef.wellLogFile()->wellLogFileData() ) { RimWellLogFile::WellFlowCondition flowCondition = sourceDef.wellLogFile()->wellFlowRateCondition(); @@ -702,8 +700,7 @@ void RimWellPltPlot::syncCurvesFromUiSelection() updateWidgetTitleWindowTitle(); m_wellLogPlot->loadDataAndUpdate(); - m_wellLogPlot->updateDepthZoom(); - plotTrack->updateXZoom(); + plotTrack->calculateXZoomRange(); } //-------------------------------------------------------------------------------------------------- @@ -726,7 +723,7 @@ void RimWellPltPlot::addStackedCurve(const QString& curveName, if (curveGroupId == 0) { curve->setDoFillCurve(true); - curve->setSymbol(RimPlotCurve::SYMBOL_NONE); + curve->setSymbol(RiuQwtSymbol::SYMBOL_NONE); } else { @@ -734,7 +731,7 @@ void RimWellPltPlot::addStackedCurve(const QString& curveName, curve->setSymbol(RimSummaryCurveAppearanceCalculator::cycledSymbol(curveGroupId)); } - curve->setSymbolSkipDinstance(10); + curve->setSymbolSkipDistance(10); plotTrack->addCurve(curve); } @@ -791,14 +788,6 @@ void RimWellPltPlot::setCurrentWellName(const QString& currWellName) m_wellPathName = currWellName; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPltPlot::currentWellName() const -{ - return m_wellPathName; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -945,6 +934,10 @@ void RimWellPltPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c updateFormationsOnPlot(); syncSourcesIoFieldFromGuiField(); syncCurvesFromUiSelection(); + m_wellLogPlot->updateDepthZoom(); + + RimWellLogTrack* const plotTrack = m_wellLogPlot->trackByIndex(0); + plotTrack->calculateXZoomRangeAndUpdateQwt(); } if ( changedField == &m_useStandardConditionCurves @@ -952,6 +945,11 @@ void RimWellPltPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c || changedField == &m_phases) { syncCurvesFromUiSelection(); + m_wellLogPlot->updateDepthZoom(); + + RimWellLogTrack* const plotTrack = m_wellLogPlot->trackByIndex(0); + plotTrack->calculateXZoomRangeAndUpdateQwt(); + } } @@ -1010,11 +1008,11 @@ void RimWellPltPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& caf::PdmUiGroup* legendAndAxisGroup = uiOrdering.addNewGroup("Legend and Axis"); legendAndAxisGroup->setCollapsedByDefault(true); - m_wellLogPlot->uiOrderingForPlot(*legendAndAxisGroup); + m_wellLogPlot->uiOrderingForPlotSettings(*legendAndAxisGroup); - track->uiOrderingForVisibleXRange(*legendAndAxisGroup); + track->uiOrderingForXAxisSettings(*legendAndAxisGroup); - m_wellLogPlot->uiOrderingForVisibleDepthRange(*legendAndAxisGroup); + m_wellLogPlot->uiOrderingForDepthAxis(*legendAndAxisGroup); } uiOrdering.skipRemainingFields(true); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.h index 50a17b5c9f..2186674528 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.h @@ -68,39 +68,38 @@ class RimWellPltPlot : public RimViewWindow public: RimWellPltPlot(); - virtual ~RimWellPltPlot(); + ~RimWellPltPlot() override; void setDescription(const QString& description); QString description() const; - virtual QWidget* viewWidget() override; - virtual void zoomAll() override; + QWidget* viewWidget() override; + void zoomAll() override; RimWellLogPlot* wellLogPlot() const; void setCurrentWellName(const QString& currWellName); - QString currentWellName() const; static const char* plotNameFormatString(); protected: // Overridden PDM methods - virtual caf::PdmFieldHandle* userDescriptionField() { return &m_userName; } - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; + caf::PdmFieldHandle* userDescriptionField() override { return &m_userName; } + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; void calculateValueOptionsForWells(QList& options); - virtual QImage snapshotWindowContent() override; + QImage snapshotWindowContent() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); - virtual void onLoadDataAndUpdate() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void onLoadDataAndUpdate() override; - virtual void initAfterRead() override; - virtual void setupBeforeSave() override; + void initAfterRead() override; + void setupBeforeSave() override; void initAfterLoad(); private: @@ -122,8 +121,8 @@ class RimWellPltPlot : public RimViewWindow // RimViewWindow overrides void updateWidgetTitleWindowTitle(); - virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; - virtual void deleteViewWidget() override; + QWidget* createViewWidget(QWidget* mainWindowParent) override; + void deleteViewWidget() override; void setPlotXAxisTitles(RimWellLogTrack* plotTrack); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp index 98e0371597..82383f0986 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp @@ -141,25 +141,25 @@ void RimWellRftPlot::applyCurveAppearance(RimWellLogCurve* newCurve) std::vector colorTable; RiaColorTables::summaryCurveDefaultPaletteColors().color3fArray().toStdVector(&colorTable); - std::vector symbolTable = {RimPlotCurve::SYMBOL_ELLIPSE, - RimPlotCurve::SYMBOL_RECT, - RimPlotCurve::SYMBOL_DIAMOND, - RimPlotCurve::SYMBOL_TRIANGLE, - RimPlotCurve::SYMBOL_CROSS, - RimPlotCurve::SYMBOL_XCROSS}; + std::vector symbolTable = {RiuQwtSymbol::SYMBOL_ELLIPSE, + RiuQwtSymbol::SYMBOL_RECT, + RiuQwtSymbol::SYMBOL_DIAMOND, + RiuQwtSymbol::SYMBOL_TRIANGLE, + RiuQwtSymbol::SYMBOL_CROSS, + RiuQwtSymbol::SYMBOL_XCROSS}; // State variables static size_t defaultColorTableIndex = 0; static size_t defaultSymbolTableIndex = 0; cvf::Color3f currentColor; - RimPlotCurve::PointSymbolEnum currentSymbol = symbolTable.front(); - RimPlotCurve::LineStyleEnum currentLineStyle = RimPlotCurve::STYLE_SOLID; + RiuQwtSymbol::PointSymbolEnum currentSymbol = symbolTable.front(); + RiuQwtPlotCurve::LineStyleEnum currentLineStyle = RiuQwtPlotCurve::STYLE_SOLID; bool isCurrentColorSet = false; bool isCurrentSymbolSet = false; std::set assignedColors; - std::set assignedSymbols; + std::set assignedSymbols; // Used colors and symbols for (RimWellLogCurve* const curve : m_wellLogPlot->trackByIndex(0)->curvesVector()) @@ -220,8 +220,8 @@ void RimWellRftPlot::applyCurveAppearance(RimWellLogCurve* newCurve) } // Observed data - currentLineStyle = newCurveDef.address().sourceType() == RifDataSourceForRftPlt::OBSERVED ? RimPlotCurve::STYLE_NONE - : RimPlotCurve::STYLE_SOLID; + currentLineStyle = newCurveDef.address().sourceType() == RifDataSourceForRftPlt::OBSERVED ? RiuQwtPlotCurve::STYLE_NONE + : RiuQwtPlotCurve::STYLE_SOLID; newCurve->setColor(currentColor); newCurve->setSymbol(currentSymbol); @@ -584,14 +584,6 @@ void RimWellRftPlot::setSimWellOrWellPathName(const QString& currWellName) } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellRftPlot::simWellOrWellPathName() const -{ - return m_wellPathNameOrSimWellName; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -781,11 +773,11 @@ void RimWellRftPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& caf::PdmUiGroup* legendAndAxisGroup = uiOrdering.addNewGroup("Legend and Axis"); legendAndAxisGroup->setCollapsedByDefault(true); - m_wellLogPlot->uiOrderingForPlot(*legendAndAxisGroup); + m_wellLogPlot->uiOrderingForPlotSettings(*legendAndAxisGroup); - track->uiOrderingForVisibleXRange(*legendAndAxisGroup); + track->uiOrderingForXAxisSettings(*legendAndAxisGroup); - m_wellLogPlot->uiOrderingForVisibleDepthRange(*legendAndAxisGroup); + m_wellLogPlot->uiOrderingForDepthAxis(*legendAndAxisGroup); } uiOrdering.skipRemainingFields(true); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h index 106d37be79..3e2dbc571e 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h @@ -71,18 +71,17 @@ class RimWellRftPlot : public RimViewWindow public: RimWellRftPlot(); - virtual ~RimWellRftPlot(); + ~RimWellRftPlot() override; void setDescription(const QString& description); QString description() const; - virtual QWidget* viewWidget() override; - virtual void zoomAll() override; + QWidget* viewWidget() override; + void zoomAll() override; RimWellLogPlot* wellLogPlot() const; void setSimWellOrWellPathName(const QString& currWellName); - QString simWellOrWellPathName() const; int branchIndex() const; static const char* plotNameFormatString(); @@ -91,17 +90,17 @@ class RimWellRftPlot : public RimViewWindow protected: // Overridden PDM methods - virtual caf::PdmFieldHandle* userDescriptionField() override { return &m_userName; } - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* userDescriptionField() override { return &m_userName; } + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual QImage snapshotWindowContent() override; + QImage snapshotWindowContent() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void onLoadDataAndUpdate() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void onLoadDataAndUpdate() override; private: void calculateValueOptionsForWells(QList& options); @@ -121,8 +120,8 @@ class RimWellRftPlot : public RimViewWindow // RimViewWindow overrides - virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; - virtual void deleteViewWidget() override; + QWidget* createViewWidget(QWidget* mainWindowParent) override; + void deleteViewWidget() override; void applyCurveAppearance(RimWellLogCurve* newCurve); diff --git a/ApplicationCode/ProjectDataModel/Rim2dIntersectionView.cpp b/ApplicationCode/ProjectDataModel/Rim2dIntersectionView.cpp index 7508c16ae2..dee625562f 100644 --- a/ApplicationCode/ProjectDataModel/Rim2dIntersectionView.cpp +++ b/ApplicationCode/ProjectDataModel/Rim2dIntersectionView.cpp @@ -51,7 +51,7 @@ CAF_PDM_SOURCE_INIT(Rim2dIntersectionView, "Intersection2dView"); -const cvf::Mat4d defaultIntersectinoViewMatrix(1, 0, 0, 0, +const cvf::Mat4d defaultViewMatrix(1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 1000, 0, 0, 0, 1); @@ -79,6 +79,7 @@ Rim2dIntersectionView::Rim2dIntersectionView(void) m_ternaryLegendConfig = new RimTernaryLegendConfig(); CAF_PDM_InitField(&m_showDefiningPoints, "ShowDefiningPoints", true, "Show Points", "", "", ""); + CAF_PDM_InitField(&m_showAxisLines, "ShowAxisLines", false, "Show Axis Lines", "", "", ""); m_showWindow = false; m_scaleTransform = new cvf::Transform(); @@ -86,7 +87,7 @@ Rim2dIntersectionView::Rim2dIntersectionView(void) hasUserRequestedAnimation = true; - ((RiuViewerToViewInterface*)this)->setCameraPosition(defaultIntersectinoViewMatrix ); + ((RiuViewerToViewInterface*)this)->setCameraPosition(defaultViewMatrix ); disableGridBoxField(); disablePerspectiveProjectionField(); @@ -302,7 +303,7 @@ void Rim2dIntersectionView::updateName() { Rim3dView * parentView = nullptr; m_intersection->firstAncestorOrThisOfTypeAsserted(parentView); - name = parentView->name() + ": " + m_intersection->name(); + this->setName(parentView->name() + ": " + m_intersection->name()); } } @@ -513,7 +514,7 @@ void Rim2dIntersectionView::createDisplayModel() updateCurrentTimeStep(); } - if ( this->viewer()->mainCamera()->viewMatrix() == defaultIntersectinoViewMatrix ) + if ( this->viewer()->mainCamera()->viewMatrix() == defaultViewMatrix ) { this->zoomAll(); } @@ -663,7 +664,7 @@ void Rim2dIntersectionView::resetLegendsInViewer() m_viewer->showAnimationProgress(true); m_viewer->showHistogram(false); m_viewer->showInfoText(false); - m_viewer->showEdgeTickMarks(true); + m_viewer->showEdgeTickMarksXZ(true, m_showAxisLines()); m_viewer->setMainScene(new cvf::Scene()); m_viewer->enableNavigationRotation(false); @@ -743,6 +744,12 @@ void Rim2dIntersectionView::fieldChangedByUi(const caf::PdmFieldHandle* changedF { this->loadDataAndUpdate(); } + else if (changedField == &m_showAxisLines) + { + m_viewer->showEdgeTickMarksXZ(true, m_showAxisLines()); + this->loadDataAndUpdate(); + } + } @@ -752,8 +759,14 @@ void Rim2dIntersectionView::fieldChangedByUi(const caf::PdmFieldHandle* changedF void Rim2dIntersectionView::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { Rim3dView::defineUiOrdering(uiConfigName, uiOrdering); - uiOrdering.skipRemainingFields(true); + caf::PdmUiGroup* viewGroup = uiOrdering.findGroup("ViewGroup"); + if (viewGroup) + { + viewGroup->add(&m_showAxisLines); + } + uiOrdering.skipRemainingFields(true); + if (m_intersection->hasDefiningPoints()) { caf::PdmUiGroup* plGroup = uiOrdering.addNewGroup("Defining Points"); diff --git a/ApplicationCode/ProjectDataModel/Rim2dIntersectionView.h b/ApplicationCode/ProjectDataModel/Rim2dIntersectionView.h index 7a06559d66..517fdc4ac2 100644 --- a/ApplicationCode/ProjectDataModel/Rim2dIntersectionView.h +++ b/ApplicationCode/ProjectDataModel/Rim2dIntersectionView.h @@ -44,21 +44,21 @@ class Rim2dIntersectionView : public Rim3dView CAF_PDM_HEADER_INIT; public: Rim2dIntersectionView(void); - virtual ~Rim2dIntersectionView(void); + ~Rim2dIntersectionView(void) override; void setVisible(bool isVisible); void setIntersection(RimIntersection* intersection); RimIntersection* intersection() const; - virtual bool isUsingFormationNames() const override; - virtual void scheduleGeometryRegen(RivCellSetEnum geometryType) override; - virtual RimCase* ownerCase() const override; - virtual void selectOverlayInfoConfig() override {} + bool isUsingFormationNames() const override; + void scheduleGeometryRegen(RivCellSetEnum geometryType) override; + RimCase* ownerCase() const override; + void selectOverlayInfoConfig() override {} - virtual RimViewLinker* assosiatedViewLinker() const override { return nullptr; } - virtual RimViewController* viewController() const override { return nullptr; } + RimViewLinker* assosiatedViewLinker() const override { return nullptr; } + RimViewController* viewController() const override { return nullptr; } - virtual bool isTimeStepDependentDataVisible() const override; + bool isTimeStepDependentDataVisible() const override; void update3dInfo(); void updateName(); @@ -66,7 +66,7 @@ class Rim2dIntersectionView : public Rim3dView cvf::ref flatIntersectionPartMgr() const; cvf::Vec3d transformToUtm(const cvf::Vec3d& unscaledPointInFlatDomain) const; - virtual cvf::ref displayCoordTransform() const override; + cvf::ref displayCoordTransform() const override; bool showDefiningPoints() const; @@ -76,23 +76,23 @@ class Rim2dIntersectionView : public Rim3dView protected: void updateLegends() override; - virtual bool isGridVisualizationMode() const override; - virtual void axisLabels(cvf::String* xLabel, cvf::String* yLabel, cvf::String* zLabel) override; - virtual void createDisplayModel() override; - virtual void createPartCollectionFromSelection(cvf::Collection* parts) override; - virtual void clampCurrentTimestep() override; - virtual void updateCurrentTimeStep() override; - virtual void onTimeStepChanged() override; - virtual void updateStaticCellColors() override; - virtual void updateScaleTransform() override; - virtual cvf::Transform* scaleTransform() override; - virtual void resetLegendsInViewer() override; - virtual void onLoadDataAndUpdate() override; - virtual bool isWindowVisible() override; - - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + bool isGridVisualizationMode() const override; + void axisLabels(cvf::String* xLabel, cvf::String* yLabel, cvf::String* zLabel) override; + void createDisplayModel() override; + void createPartCollectionFromSelection(cvf::Collection* parts) override; + void clampCurrentTimestep() override; + void updateCurrentTimeStep() override; + void onTimeStepChanged() override; + void updateStaticCellColors() override; + void updateScaleTransform() override; + cvf::Transform* scaleTransform() override; + void resetLegendsInViewer() override; + void onLoadDataAndUpdate() override; + bool isWindowVisible() override; + + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; bool hasResults(); int timeStepCount(); @@ -111,6 +111,7 @@ class Rim2dIntersectionView : public Rim3dView cvf::ref m_scaleTransform; caf::PdmField m_showDefiningPoints; + caf::PdmField m_showAxisLines; caf::PdmPointer m_legendObjectToSelect; }; diff --git a/ApplicationCode/ProjectDataModel/Rim2dIntersectionViewCollection.h b/ApplicationCode/ProjectDataModel/Rim2dIntersectionViewCollection.h index ce02db28c1..60dcddfd30 100644 --- a/ApplicationCode/ProjectDataModel/Rim2dIntersectionViewCollection.h +++ b/ApplicationCode/ProjectDataModel/Rim2dIntersectionViewCollection.h @@ -29,7 +29,7 @@ class Rim2dIntersectionViewCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: Rim2dIntersectionViewCollection(); - virtual ~Rim2dIntersectionViewCollection(); + ~Rim2dIntersectionViewCollection() override; void syncFromExistingIntersections( bool doUpdate ); diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index a761bb0175..9d68b66ac2 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -20,6 +20,8 @@ #include "Rim3dOverlayInfoConfig.h" +#include "RiaQDateTimeTools.h" + #include "RicGridStatisticsDialog.h" #include "RigCaseCellResultsData.h" @@ -35,6 +37,8 @@ #include "RigMainGrid.h" #include "RigStatisticsDataCache.h" +#include "RimContourMapView.h" +#include "RimContourMapProjection.h" #include "Rim2dIntersectionView.h" #include "Rim2dIntersectionViewCollection.h" #include "Rim3dView.h" @@ -172,9 +176,11 @@ Rim3dOverlayInfoConfig::HistogramData Rim3dOverlayInfoConfig::histogramData() { auto eclipseView = dynamic_cast(m_viewDef.p()); auto geoMechView = dynamic_cast(m_viewDef.p()); + auto contourMap = dynamic_cast(eclipseView); - if (eclipseView) return histogramData(eclipseView); - if (geoMechView) return histogramData(geoMechView); + if (contourMap) return histogramData(contourMap); + else if (eclipseView) return histogramData(eclipseView); + else if (geoMechView) return histogramData(geoMechView); return HistogramData(); } @@ -261,6 +267,37 @@ bool Rim3dOverlayInfoConfig::isActive() const return m_active; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Rim3dOverlayInfoConfig::setIsActive(bool active) +{ + m_active = active; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +Rim3dOverlayInfoConfig::HistogramData Rim3dOverlayInfoConfig::histogramData(RimContourMapView* contourMap) +{ + HistogramData histData; + + if (contourMap) + { + bool isResultsInfoRelevant = contourMap->contourMapProjection()->numberOfValidCells() > 0u; + + if (isResultsInfoRelevant) + { + histData.min = contourMap->contourMapProjection()->minValue(); + histData.max = contourMap->contourMapProjection()->maxValue(); + histData.mean = contourMap->contourMapProjection()->meanValue(); + histData.sum = contourMap->contourMapProjection()->sumAllValues(); + } + } + return histData; +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -457,35 +494,51 @@ QString Rim3dOverlayInfoConfig::caseInfoText(RimEclipseView* eclipseView) if (eclipseView) { - QString caseName; - QString totCellCount; - QString activeCellCountText; - QString fractureActiveCellCount; - QString iSize, jSize, kSize; - QString zScale; + QString caseName = eclipseView->eclipseCase()->caseUserDescription(); + + RimContourMapView* contourMap = dynamic_cast(eclipseView); + if (contourMap && contourMap->contourMapProjection()) + { + QString totCellCount = QString::number(contourMap->contourMapProjection()->numberOfCells()); + cvf::uint validCellCount = contourMap->contourMapProjection()->numberOfValidCells(); + QString activeCellCountText = QString::number(validCellCount); + QString iSize = QString::number(contourMap->contourMapProjection()->numberOfElementsIJ().x()); + QString jSize = QString::number(contourMap->contourMapProjection()->numberOfElementsIJ().y()); + QString aggregationType = contourMap->contourMapProjection()->resultAggregationText(); + QString weightingParameterString; + if (contourMap->contourMapProjection()->weightingParameter() != "None") + { + weightingParameterString += QString(" (Weight: %1)").arg(contourMap->contourMapProjection()->weightingParameter()); + } - if (eclipseView->mainGrid()) + infoText += QString( + "

-- Contour Map: %1 --

" + "Sample Count. Total: %2 Valid Results: %3
" + "Projection Type: %4%5
").arg(caseName, totCellCount, activeCellCountText, aggregationType, weightingParameterString); + } + else if (eclipseView->mainGrid()) { - caseName = eclipseView->eclipseCase()->caseUserDescription(); - totCellCount = QString::number(eclipseView->mainGrid()->globalCellArray().size()); + QString totCellCount = QString::number(eclipseView->mainGrid()->globalCellArray().size()); size_t mxActCellCount = eclipseView->eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL)->reservoirActiveCellCount(); size_t frActCellCount = eclipseView->eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::FRACTURE_MODEL)->reservoirActiveCellCount(); + + QString activeCellCountText; if (frActCellCount > 0) activeCellCountText += "Matrix : "; activeCellCountText += QString::number(mxActCellCount); if (frActCellCount > 0) activeCellCountText += " Fracture : " + QString::number(frActCellCount); - iSize = QString::number(eclipseView->mainGrid()->cellCountI()); - jSize = QString::number(eclipseView->mainGrid()->cellCountJ()); - kSize = QString::number(eclipseView->mainGrid()->cellCountK()); + QString iSize = QString::number(eclipseView->mainGrid()->cellCountI()); + QString jSize = QString::number(eclipseView->mainGrid()->cellCountJ()); + QString kSize = QString::number(eclipseView->mainGrid()->cellCountK()); - zScale = QString::number(eclipseView->scaleZ()); + QString zScale = QString::number(eclipseView->scaleZ()); + infoText += QString( + "

-- %1 --

" + "Cell count. Total: %2 Active: %3
" + "Main Grid I,J,K: %4, %5, %6 Z-Scale: %7
").arg(caseName, totCellCount, activeCellCountText, iSize, jSize, kSize, zScale); } - infoText += QString( - "

-- %1 --

" - "Cell count. Total: %2 Active: %3
" - "Main Grid I,J,K: %4, %5, %6 Z-Scale: %7
").arg(caseName, totCellCount, activeCellCountText, iSize, jSize, kSize, zScale); } return infoText; @@ -525,7 +578,26 @@ QString Rim3dOverlayInfoConfig::resultInfoText(const HistogramData& histData, Ri { QString infoText; - if (eclipseView) + RimContourMapView* contourMap = dynamic_cast(eclipseView); + + if (contourMap) + { + bool isResultsInfoRelevant = contourMap->contourMapProjection()->numberOfValidCells() > 0u; + if (isResultsInfoRelevant) + { + QString propName = eclipseView->cellResult()->resultVariableUiShortName(); + if (!contourMap->contourMapProjection()->isColumnResult()) + { + infoText += QString("Cell Property: %1 ").arg(propName); + } + infoText += QString("
Statistics: Current Time Step and Visible Cells"); + infoText += QString("" + "" + "" + "
Min Mean Max Sum
%1 %2 %3 %4
").arg(histData.min).arg(histData.mean).arg(histData.max).arg(histData.sum); + } + } + else if (eclipseView) { bool isResultsInfoRelevant = eclipseView->hasUserRequestedAnimation() && eclipseView->cellResult()->hasResult(); @@ -547,7 +619,7 @@ QString Rim3dOverlayInfoConfig::resultInfoText(const HistogramData& histData, Ri infoText += QString("Cell Property: %1 ").arg(propName); infoText += QString("
Statistics: ") + timeRangeText + " and " + m_statisticsCellRange().uiText(); infoText += QString("" - "" + "" "" "
Min P10 Mean P90 Max Sum
Min P90 Mean P10 Max Sum
%1 %2 %3 %4 %5 %6
").arg(histData.min).arg(histData.p10).arg(histData.mean).arg(histData.p90).arg(histData.max).arg(histData.sum); @@ -650,7 +722,7 @@ QString Rim3dOverlayInfoConfig::resultInfoText(const HistogramData& histData, Ri infoText += QString("
Statistics: ") + m_statisticsTimeRange().uiText() + " and " + m_statisticsCellRange().uiText(); infoText += QString("" - "" + "" "" "
Min P10 Mean P90 Max Sum
Min P90 Mean P10 Max Sum
%1 %2 %3 %4 %5 %6
").arg(histData.min).arg(histData.p10).arg(histData.mean).arg(histData.p90).arg(histData.max).arg(histData.sum); } @@ -750,26 +822,38 @@ void Rim3dOverlayInfoConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOr { caf::PdmUiGroup* visGroup = uiOrdering.addNewGroup("Visibility"); + RimEclipseView * eclipseView = dynamic_cast(m_viewDef.p()); + RimContourMapView* contourMap = dynamic_cast(eclipseView); + RimGeoMechView * geoMechView = dynamic_cast(m_viewDef.p()); + visGroup->add(&m_showAnimProgress); visGroup->add(&m_showCaseInfo); visGroup->add(&m_showResultInfo); - RimGeoMechView * geoMechView = dynamic_cast(m_viewDef.p()); - if (!geoMechView) + if (!geoMechView && !contourMap) { visGroup->add(&m_showVolumeWeightedMean); } - visGroup->add(&m_showHistogram); - - caf::PdmUiGroup* statGroup = uiOrdering.addNewGroup("Statistics Options"); - RimEclipseView * eclipseView = dynamic_cast(m_viewDef.p()); + if (!contourMap) + { + visGroup->add(&m_showHistogram); + } - if (!eclipseView || !eclipseView->cellResult()->isFlowDiagOrInjectionFlooding()) + if (contourMap) { - statGroup->add(&m_statisticsTimeRange); + m_statisticsTimeRange = Rim3dOverlayInfoConfig::CURRENT_TIMESTEP; + m_statisticsCellRange = Rim3dOverlayInfoConfig::VISIBLE_CELLS; } - statGroup->add(&m_statisticsCellRange); + else + { + caf::PdmUiGroup* statGroup = uiOrdering.addNewGroup("Statistics Options"); + if (!eclipseView || !eclipseView->cellResult()->isFlowDiagOrInjectionFlooding()) + { + statGroup->add(&m_statisticsTimeRange); + } + statGroup->add(&m_statisticsCellRange); + } uiOrdering.skipRemainingFields(true); } @@ -899,9 +983,12 @@ QString Rim3dOverlayInfoConfig::timeStepText(RimEclipseView* eclipseView) if (currTimeStepIndex >= 0 && currTimeStepIndex < (int)timeSteps.size()) { QString dateFormat = RimTools::createTimeFormatStringFromDates(timeSteps); + + QString dateString = RiaQDateTimeTools::toStringUsingApplicationLocale(timeSteps[currTimeStepIndex], dateFormat); + dateTimeString = QString("Time Step: %1/%2 %3").arg(QString::number(currTimeStepIndex), QString::number(timeSteps.size() - 1), - timeSteps[currTimeStepIndex].toString(dateFormat)); + dateString); } return QString("

-- %1 --
").arg(dateTimeString) + diff --git a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.h b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.h index 9a55f603fd..d87ce75c87 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.h +++ b/ApplicationCode/ProjectDataModel/Rim3dOverlayInfoConfig.h @@ -30,6 +30,7 @@ #include #include +class RimContourMapView; class RimEclipseView; class RimGeoMechView; class RimGridView; @@ -57,13 +58,14 @@ class Rim3dOverlayInfoConfig : public caf::PdmObject double sum; double weightedMean; const std::vector* histogram; + bool isValid(double parameter) { return parameter != HUGE_VAL && parameter != -HUGE_VAL; } - bool isValid() { return histogram && histogram->size() > 0 && min != HUGE_VAL && max != HUGE_VAL; } + bool isValid() { return histogram && histogram->size() > 0 && isValid(min) && isValid(max); } }; public: Rim3dOverlayInfoConfig(); - virtual ~Rim3dOverlayInfoConfig(); + ~Rim3dOverlayInfoConfig() override; void update3DInfo(); @@ -83,6 +85,7 @@ class Rim3dOverlayInfoConfig : public caf::PdmObject bool showCaseInfo() const; bool showResultInfo() const; bool isActive() const; + void setIsActive(bool active); enum StatisticsTimeRangeType { @@ -97,10 +100,10 @@ class Rim3dOverlayInfoConfig : public caf::PdmObject }; protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual caf::PdmFieldHandle* objectToggleField(); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* objectToggleField() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: void updateEclipse3DInfo(RimEclipseView * reservoirView); @@ -110,6 +113,7 @@ class Rim3dOverlayInfoConfig : public caf::PdmObject QString timeStepText(RimEclipseView* eclipseView); QString timeStepText(RimGeoMechView* geoMechView); + HistogramData histogramData(RimContourMapView* contourMap); HistogramData histogramData(RimEclipseView* eclipseView); HistogramData histogramData(RimGeoMechView* geoMechView); QString caseInfoText(RimEclipseView* eclipseView); diff --git a/ApplicationCode/ProjectDataModel/Rim3dPropertiesInterface.h b/ApplicationCode/ProjectDataModel/Rim3dPropertiesInterface.h index b10eed5021..7536a2e253 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dPropertiesInterface.h +++ b/ApplicationCode/ProjectDataModel/Rim3dPropertiesInterface.h @@ -24,5 +24,5 @@ class Rim3dPropertiesInterface { public: - virtual cvf::BoundingBox boundingBoxInDomainCoords() = 0; + virtual cvf::BoundingBox boundingBoxInDomainCoords() const = 0; }; diff --git a/ApplicationCode/ProjectDataModel/Rim3dView.cpp b/ApplicationCode/ProjectDataModel/Rim3dView.cpp index 9bd8c48bb0..e88a0d9013 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dView.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dView.cpp @@ -20,14 +20,16 @@ #include "Rim3dView.h" #include "RiaApplication.h" +#include "RiaFieldHandleTools.h" #include "RiaPreferences.h" #include "RiaViewRedrawScheduler.h" +#include "Rim3dWellLogCurve.h" #include "RimCase.h" #include "RimGridView.h" #include "RimMainPlotCollection.h" -#include "RimOilField.h" #include "RimProject.h" +#include "RimTools.h" #include "RimViewController.h" #include "RimViewLinker.h" #include "RimWellPathCollection.h" @@ -86,7 +88,7 @@ Rim3dView::Rim3dView(void) CVF_ASSERT(preferences); - CAF_PDM_InitField(&name, "UserDescription", QString(""), "Name", "", "", ""); + CAF_PDM_InitField(&m_name, "UserDescription", QString(""), "Name", "", "", ""); CAF_PDM_InitField(&m_cameraPosition, "CameraPosition", cvf::Mat4d::IDENTITY, "", "", "", ""); m_cameraPosition.uiCapability()->setUiHidden(true); @@ -146,11 +148,27 @@ Rim3dView::~Rim3dView(void) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RiuViewer* Rim3dView::viewer() +RiuViewer* Rim3dView::viewer() const { return m_viewer; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Rim3dView::setName(const QString& name) +{ + m_name = name; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString Rim3dView::name() const +{ + return m_name; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -207,11 +225,11 @@ void Rim3dView::updateMdiWindowTitle() QString windowTitle; if (ownerCase()) { - windowTitle = QString("%1 - %2").arg(ownerCase()->caseUserDescription()).arg(name); + windowTitle = QString("%1 - %2").arg(ownerCase()->caseUserDescription()).arg(m_name); } else { - windowTitle = name; + windowTitle = m_name; } m_viewer->layoutWidget()->setWindowTitle(windowTitle); @@ -235,8 +253,9 @@ void Rim3dView::deleteViewWidget() //-------------------------------------------------------------------------------------------------- void Rim3dView::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { - caf::PdmUiGroup* viewGroup = uiOrdering.addNewGroup("Viewer"); - viewGroup->add(&name); + caf::PdmUiGroup* viewGroup = uiOrdering.addNewGroupWithKeyword("Viewer", "ViewGroup"); + + viewGroup->add(&m_name); viewGroup->add(&m_backgroundColor); viewGroup->add(&m_showGridBox); viewGroup->add(&isPerspectiveView); @@ -407,11 +426,24 @@ void Rim3dView::endAnimation() //-------------------------------------------------------------------------------------------------- RimWellPathCollection* Rim3dView::wellPathCollection() const { - RimProject* proj = nullptr; - this->firstAncestorOrThisOfTypeAsserted(proj); - CVF_ASSERT(proj && proj->activeOilField() && proj->activeOilField()->wellPathCollection()); + return RimTools::wellPathCollection(); +} - return proj->activeOilField()->wellPathCollection(); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool Rim3dView::hasVisibleTimeStepDependent3dWellLogCurves() const +{ + std::vector wellLogCurves; + wellPathCollection()->descendantsIncludingThisOfType(wellLogCurves); + for (const Rim3dWellLogCurve* curve : wellLogCurves) + { + if (curve->showInView(this) && curve->isShowingTimeDependentResult()) + { + return true; + } + } + return false; } //-------------------------------------------------------------------------------------------------- @@ -554,7 +586,7 @@ void Rim3dView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const RiuMainWindow::instance()->refreshDrawStyleActions(); RiuMainWindow::instance()->refreshAnimationActions(); } - else if (changedField == &name) + else if (changedField == &m_name) { updateMdiWindowTitle(); @@ -636,9 +668,9 @@ void Rim3dView::addDynamicWellPathsToModel(cvf::ModelBasicList* wellPathModelBas //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void Rim3dView::setScaleZAndUpdate(double scaleZ) +void Rim3dView::setScaleZAndUpdate(double scalingFactor) { - this->scaleZ = scaleZ; + this->scaleZ = scalingFactor; updateScaleTransform(); this->updateGridBoxData(); @@ -725,6 +757,22 @@ void Rim3dView::createHighlightAndGridBoxDisplayModel() m_viewer->showGridBox(m_showGridBox()); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Rim3dView::setBackgroundColor(const cvf::Color3f& newBackgroundColor) +{ + m_backgroundColor = newBackgroundColor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Rim3dView::setShowGridBox(bool showGridBox) +{ + m_showGridBox = showGridBox; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -873,8 +921,8 @@ void Rim3dView::forceShowWindowOn() void Rim3dView::disableGridBoxField() { m_showGridBox = false; - m_showGridBox.uiCapability()->setUiHidden(true); - m_showGridBox.xmlCapability()->setIOWritable(false); + + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_showGridBox); } //-------------------------------------------------------------------------------------------------- @@ -883,8 +931,17 @@ void Rim3dView::disableGridBoxField() void Rim3dView::disablePerspectiveProjectionField() { isPerspectiveView = false; - isPerspectiveView.uiCapability()->setUiHidden(true); - isPerspectiveView.xmlCapability()->setIOWritable(false); + + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&isPerspectiveView); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Rim3dView::enablePerspectiveProjectionField() +{ + isPerspectiveView.uiCapability()->setUiHidden(false); + isPerspectiveView.xmlCapability()->setIOWritable(true); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Rim3dView.h b/ApplicationCode/ProjectDataModel/Rim3dView.h index d4d365f5da..2352d41e60 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dView.h +++ b/ApplicationCode/ProjectDataModel/Rim3dView.h @@ -80,11 +80,10 @@ class Rim3dView : public RimViewWindow, public RiuViewerToViewInterface CAF_PDM_HEADER_INIT; public: Rim3dView(void); - virtual ~Rim3dView(void); + ~Rim3dView(void) override; // Public fields: - caf::PdmField name; caf::PdmField scaleZ; caf::PdmField isPerspectiveView; caf::PdmField maximumFrameRate; @@ -98,13 +97,20 @@ class Rim3dView : public RimViewWindow, public RiuViewerToViewInterface caf::PdmField< caf::AppEnum< MeshModeType > > meshMode; caf::PdmField< caf::AppEnum< SurfaceModeType > > surfaceMode; - RiuViewer* viewer(); + RiuViewer* viewer() const; + + void setName(const QString& name); + QString name() const; + // Implementation of RiuViewerToViewInterface + cvf::Color3f backgroundColor() const override { return m_backgroundColor(); } void setMeshOnlyDrawstyle(); void setMeshSurfDrawstyle(); void setSurfOnlyDrawstyle(); void setFaultMeshSurfDrawstyle(); void setSurfaceDrawstyle(); + void setBackgroundColor(const cvf::Color3f& newBackgroundColor); + void setShowGridBox(bool showGridBox); void disableLighting(bool disable); bool isLightingDisabled() const; @@ -115,8 +121,8 @@ class Rim3dView : public RimViewWindow, public RiuViewerToViewInterface virtual bool showActiveCellsOnly(); virtual bool isUsingFormationNames() const = 0; - virtual QImage snapshotWindowContent() override; - virtual void zoomAll() override; + QImage snapshotWindowContent() override; + void zoomAll() override; void forceShowWindowOn(); // Animation @@ -147,12 +153,14 @@ class Rim3dView : public RimViewWindow, public RiuViewerToViewInterface virtual void setDefaultView(); void disableGridBoxField(); void disablePerspectiveProjectionField(); + void enablePerspectiveProjectionField(); cvf::Mat4d cameraPosition() const; cvf::Vec3d cameraPointOfInterest() const; RimWellPathCollection* wellPathCollection() const; - void addWellPathsToModel(cvf::ModelBasicList* wellPathModelBasicList, + bool hasVisibleTimeStepDependent3dWellLogCurves() const; + void addWellPathsToModel(cvf::ModelBasicList* wellPathModelBasicList, const cvf::BoundingBox& wellPathClipBoundingBox); void addDynamicWellPathsToModel(cvf::ModelBasicList* wellPathModelBasicList, @@ -161,7 +169,6 @@ class Rim3dView : public RimViewWindow, public RiuViewerToViewInterface void createHighlightAndGridBoxDisplayModel(); // Implementation of RiuViewerToViewInterface - virtual cvf::Color3f backgroundColor() const override { return m_backgroundColor(); } void applyBackgroundColor(); // Abstract methods to implement in subclasses @@ -198,32 +205,34 @@ class Rim3dView : public RimViewWindow, public RiuViewerToViewInterface private: // Overridden PdmObject methods: - virtual caf::PdmFieldHandle* userDescriptionField() override { return &name; } - virtual void setupBeforeSave() override; + void setupBeforeSave() override; protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + caf::PdmFieldHandle* userDescriptionField() override { return &m_name; } + caf::PdmFieldHandle* backgroundColorField() { return &m_backgroundColor; } + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + virtual void updateViewWidgetAfterCreation() override; + private: // Overridden ViewWindow methods: - virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; - virtual void updateViewWidgetAfterCreation() override; - virtual void updateMdiWindowTitle() override; - virtual void deleteViewWidget() override; - virtual QWidget* viewWidget() override; + QWidget* createViewWidget(QWidget* mainWindowParent) override; + void updateMdiWindowTitle() override; + void deleteViewWidget() override; + QWidget* viewWidget() override; // Implementation of RiuViewerToViewInterface - - virtual void setCameraPosition(const cvf::Mat4d& cameraPosition) override { m_cameraPosition = cameraPosition; } - virtual void setCameraPointOfInterest(const cvf::Vec3d& cameraPointOfInterest) override { m_cameraPointOfInterest = cameraPointOfInterest;} - virtual QString timeStepName(int frameIdx) const override; - virtual void endAnimation() override; - virtual caf::PdmObjectHandle* implementingPdmObject() override { return this; } - virtual void handleMdiWindowClosed() override; - virtual void setMdiWindowGeometry(const RimMdiWindowGeometry& windowGeometry) override; + void setCameraPosition(const cvf::Mat4d& cameraPosition) override { m_cameraPosition = cameraPosition; } + void setCameraPointOfInterest(const cvf::Vec3d& cameraPointOfInterest) override { m_cameraPointOfInterest = cameraPointOfInterest;} + QString timeStepName(int frameIdx) const override; + void endAnimation() override; + caf::PdmObjectHandle* implementingPdmObject() override { return this; } + void handleMdiWindowClosed() override; + void setMdiWindowGeometry(const RimMdiWindowGeometry& windowGeometry) override; private: + caf::PdmField m_name; caf::PdmField m_disableLighting; caf::PdmField m_cameraPosition; caf::PdmField m_cameraPointOfInterest; diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp index dfceae1f9d..b55f0bf61b 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.cpp @@ -18,7 +18,7 @@ #include "Rim3dWellLogCurve.h" -#include "RigCurveDataTools.h" +#include "RiaCurveDataTools.h" #include "Riv3dWellLogCurveGeometryGenerator.h" #include "Rim3dWellLogCurveCollection.h" @@ -86,7 +86,7 @@ void Rim3dWellLogCurve::updateCurveIn3dView() { RimProject* proj; this->firstAncestorOrThisOfTypeAsserted(proj); - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } //-------------------------------------------------------------------------------------------------- @@ -100,9 +100,9 @@ Rim3dWellLogCurve::DrawPlane Rim3dWellLogCurve::drawPlane() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double Rim3dWellLogCurve::drawPlaneAngle() const +double Rim3dWellLogCurve::drawPlaneAngle(Rim3dWellLogCurve::DrawPlane drawPlane) { - switch (drawPlane()) + switch (drawPlane) { case HORIZONTAL_LEFT: case HORIZONTAL_CENTER: @@ -135,6 +135,37 @@ bool Rim3dWellLogCurve::isShowingCurve() const return m_showCurve; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Rim3dWellLogCurve::curveValuesAndMdsAtTimeStep(std::vector* values, std::vector* measuredDepthValues, int timeStep) const +{ + return this->curveValuesAndMds(values, measuredDepthValues); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair Rim3dWellLogCurve::findCurveValueRange() +{ + double foundMinValue = std::numeric_limits::infinity(); + double foundMaxValue = -std::numeric_limits::infinity(); + + std::vector values; + std::vector measuredDepths; + this->curveValuesAndMds(&values, &measuredDepths); + + for (double value : values) + { + if (RiaCurveDataTools::isValidValue(value, false)) + { + foundMinValue = std::min(foundMinValue, value); + foundMaxValue = std::max(foundMaxValue, value); + } + } + return std::make_pair(foundMinValue, foundMaxValue); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -180,7 +211,7 @@ void Rim3dWellLogCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField } else { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } @@ -192,8 +223,8 @@ void Rim3dWellLogCurve::configurationUiOrdering(caf::PdmUiOrdering& uiOrdering) caf::PdmUiGroup* configurationGroup = uiOrdering.addNewGroup("Curve Appearance"); configurationGroup->add(&m_drawPlane); configurationGroup->add(&m_color); - configurationGroup->add(&m_minCurveUIValue); configurationGroup->add(&m_maxCurveUIValue); + configurationGroup->add(&m_minCurveUIValue); } //-------------------------------------------------------------------------------------------------- @@ -213,7 +244,7 @@ void Rim3dWellLogCurve::defineEditorAttribute(const caf::PdmFieldHandle* field, //-------------------------------------------------------------------------------------------------- void Rim3dWellLogCurve::initAfterRead() { - this->createCurveAutoName(); + this->createAutoName(); } //-------------------------------------------------------------------------------------------------- @@ -261,22 +292,10 @@ cvf::ref Rim3dWellLogCurve::geometryGenerato //-------------------------------------------------------------------------------------------------- void Rim3dWellLogCurve::resetMinMaxValues() { - std::vector values; - std::vector measuredDepths; - this->curveValuesAndMds(&values, &measuredDepths); - double foundMinValue = std::numeric_limits::infinity(); - double foundMaxValue = -std::numeric_limits::infinity(); - for (double value : values) - { - if (RigCurveDataTools::isValidValue(value, false)) - { - foundMinValue = std::min(foundMinValue, value); - foundMaxValue = std::max(foundMaxValue, value); - } - } + std::pair valueRange = findCurveValueRange(); - m_minCurveDataValue = foundMinValue; - m_maxCurveDataValue = foundMaxValue; + m_minCurveDataValue = valueRange.first; + m_maxCurveDataValue = valueRange.second; m_minCurveUIValue = m_minCurveDataValue; m_maxCurveUIValue = m_maxCurveDataValue; diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h index fce0067f9e..b5dbd81959 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogCurve.h @@ -27,15 +27,16 @@ #include "cvfObject.h" #include "cvfVector3.h" -#include "RimWellLogCurveNameConfig.h" +#include "RimNameConfig.h" class Riv3dWellLogCurveGeometryGenerator; +class Rim3dView; //================================================================================================== /// /// //================================================================================================== -class Rim3dWellLogCurve : public caf::PdmObject, public RimCurveNameConfigHolderInterface +class Rim3dWellLogCurve : public caf::PdmObject, public RimNameConfigHolderInterface { CAF_PDM_HEADER_INIT; @@ -53,7 +54,7 @@ class Rim3dWellLogCurve : public caf::PdmObject, public RimCurveNameConfigHolder public: Rim3dWellLogCurve(); - virtual ~Rim3dWellLogCurve(); + ~Rim3dWellLogCurve() override; void updateCurveIn3dView(); @@ -61,12 +62,16 @@ class Rim3dWellLogCurve : public caf::PdmObject, public RimCurveNameConfigHolder virtual QString resultPropertyString() const = 0; DrawPlane drawPlane() const; - double drawPlaneAngle() const; + static double drawPlaneAngle(DrawPlane drawPlane); cvf::Color3f color() const; bool isShowingCurve() const; - + virtual bool isShowingTimeDependentResult() const { return isShowingCurve(); } + virtual bool showInView(const Rim3dView* gridView) const { return isShowingCurve(); } + virtual bool followAnimationTimeStep() const { return false; } virtual void curveValuesAndMds(std::vector* values, std::vector* measuredDepthValues) const = 0; + virtual void curveValuesAndMdsAtTimeStep(std::vector* values, std::vector* measuredDepthValues, int timeStep) const; + virtual std::pair findCurveValueRange(); void setColor(const cvf::Color3f& color); @@ -82,11 +87,11 @@ class Rim3dWellLogCurve : public caf::PdmObject, public RimCurveNameConfigHolder cvf::ref geometryGenerator(); protected: - virtual caf::PdmFieldHandle* objectToggleField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* objectToggleField() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; void configurationUiOrdering(caf::PdmUiOrdering& uiOrdering); - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); - virtual void initAfterRead(); + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void initAfterRead() override; private: void resetMinMaxValues(); protected: diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp index afde7d1128..d36f5aa619 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.cpp @@ -21,6 +21,7 @@ #include "RigWellLogFile.h" #include "RiaExtractionTools.h" +#include "RiaCurveDataTools.h" #include "RigEclipseCaseData.h" #include "RigGeoMechCaseData.h" #include "RigEclipseWellLogExtractor.h" @@ -28,10 +29,11 @@ #include "RigResultAccessorFactory.h" #include "RigCaseCellResultsData.h" #include "RigFemPartResultsCollection.h" +#include "RigWellPath.h" #include "RimEclipseCase.h" #include "RimGeoMechCase.h" #include "Rim3dView.h" -#include "RimWellLogCurveNameConfig.h" +#include "RimWellLogExtractionCurveNameConfig.h" #include "RimCase.h" #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" @@ -43,12 +45,15 @@ #include "RimTools.h" #include "RimWellLogFile.h" #include "RimWellLogFileChannel.h" +#include "RimWellLogExtractionCurve.h" #include "RimWellPath.h" #include "cafUtils.h" #include +#include + //================================================================================================== /// /// @@ -67,7 +72,7 @@ Rim3dWellLogExtractionCurve::Rim3dWellLogExtractionCurve() m_case.uiCapability()->setUiTreeChildrenHidden(true); m_case = nullptr; - CAF_PDM_InitField(&m_timeStep, "CurveTimeStep", 0, "Time Step", "", "", ""); + CAF_PDM_InitField(&m_timeStep, "CurveTimeStep", -1, "Time Step", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_eclipseResultDefinition, "CurveEclipseResult", "", "", "", ""); m_eclipseResultDefinition.uiCapability()->setUiHidden(true); @@ -79,6 +84,7 @@ Rim3dWellLogExtractionCurve::Rim3dWellLogExtractionCurve() m_geomResultDefinition.uiCapability()->setUiHidden(true); m_geomResultDefinition.uiCapability()->setUiTreeChildrenHidden(true); m_geomResultDefinition = new RimGeoMechResultDefinition; + m_geomResultDefinition->setAddWellPathDerivedResults(true); CAF_PDM_InitFieldNoDefault(&m_nameConfig, "NameConfig", "", "", "", ""); m_nameConfig = new RimWellLogExtractionCurveNameConfig(this); @@ -112,14 +118,12 @@ void Rim3dWellLogExtractionCurve::setPropertiesFromView(Rim3dView* view) if (eclipseView) { m_eclipseResultDefinition->simpleCopy(eclipseView->cellResult()); - m_timeStep = eclipseView->currentTimeStep(); } RimGeoMechView* geoMechView = dynamic_cast(view); if (geoMechView) { m_geomResultDefinition->setResultAddress(geoMechView->cellResultResultDefinition()->resultAddress()); - m_timeStep = geoMechView->currentTimeStep(); } } @@ -134,7 +138,7 @@ QString Rim3dWellLogExtractionCurve::resultPropertyString() const QString name; if (eclipseCase) { - name = caf::Utils::makeValidFileBasename(m_eclipseResultDefinition->resultVariableUiName()); + name = caf::Utils::makeValidFileBasename(m_eclipseResultDefinition->resultVariableUiShortName()); } else if (geoMechCase) { @@ -152,10 +156,28 @@ QString Rim3dWellLogExtractionCurve::resultPropertyString() const return name; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool Rim3dWellLogExtractionCurve::followAnimationTimeStep() const +{ + return m_timeStep() == -1; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void Rim3dWellLogExtractionCurve::curveValuesAndMds(std::vector* values, std::vector* measuredDepthValues) const +{ + CVF_ASSERT(m_timeStep() >= 0); + + return this->curveValuesAndMdsAtTimeStep(values, measuredDepthValues, m_timeStep()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void Rim3dWellLogExtractionCurve::curveValuesAndMdsAtTimeStep(std::vector* values, std::vector* measuredDepthValues, int timeStep) const { CAF_ASSERT(values != nullptr); CAF_ASSERT(measuredDepthValues != nullptr); @@ -183,13 +205,13 @@ void Rim3dWellLogExtractionCurve::curveValuesAndMds(std::vector* values, if (eclExtractor.notNull() && eclipseCase) { - *measuredDepthValues = eclExtractor->measuredDepth(); + *measuredDepthValues = eclExtractor->cellIntersectionMDs(); m_eclipseResultDefinition->loadResult(); cvf::ref resAcc = RigResultAccessorFactory::createFromResultDefinition(eclipseCase->eclipseCaseData(), 0, - m_timeStep, + timeStep, m_eclipseResultDefinition); if (resAcc.notNull()) { @@ -198,12 +220,56 @@ void Rim3dWellLogExtractionCurve::curveValuesAndMds(std::vector* values, } else if (geomExtractor.notNull()) { - *measuredDepthValues = geomExtractor->measuredDepth(); + *measuredDepthValues = geomExtractor->cellIntersectionMDs(); + + RimWellLogExtractionCurve::findAndLoadWbsParametersFromLasFiles(wellPath, geomExtractor.p()); m_geomResultDefinition->loadResult(); + geomExtractor->setRkbDiff(rkbDiff()); + geomExtractor->curveData(m_geomResultDefinition->resultAddress(), timeStep, values); + } +} - geomExtractor->curveData(m_geomResultDefinition->resultAddress(), m_timeStep, values); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair Rim3dWellLogExtractionCurve::findCurveValueRange() +{ + double foundMinValue = std::numeric_limits::infinity(); + double foundMaxValue = -std::numeric_limits::infinity(); + if (m_case()) + { + std::set timeStepsToCheck; + if (followAnimationTimeStep()) + { + // Check all time steps to avoid range changing during animation. + for (int i = 0; i < m_case->timeStepStrings().size(); ++i) + { + timeStepsToCheck.insert(i); + } + } + else + { + timeStepsToCheck.insert(m_timeStep()); + } + + for (int timeStep : timeStepsToCheck) + { + std::vector values; + std::vector measuredDepths; + this->curveValuesAndMdsAtTimeStep(&values, &measuredDepths, timeStep); + + for (double value : values) + { + if (RiaCurveDataTools::isValidValue(value, false)) + { + foundMinValue = std::min(foundMinValue, value); + foundMaxValue = std::max(foundMaxValue, value); + } + } + } } + return std::make_pair(foundMinValue, foundMaxValue); } QString Rim3dWellLogExtractionCurve::name() const @@ -214,39 +280,48 @@ QString Rim3dWellLogExtractionCurve::name() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString Rim3dWellLogExtractionCurve::createCurveAutoName() const +QString Rim3dWellLogExtractionCurve::createAutoName() const { RimGeoMechCase* geomCase = dynamic_cast(m_case.value()); RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); - QStringList generatedCurveName; - + QStringList autoName; + + if (!m_nameConfig->customName().isEmpty()) + { + autoName.push_back(m_nameConfig->customName()); + } + + QStringList generatedAutoTags; + if (m_nameConfig->addWellName()) { RimWellPath* wellPath; this->firstAncestorOrThisOfTypeAsserted(wellPath); if (!wellPath->name().isEmpty()) { - generatedCurveName += wellPath->name(); + generatedAutoTags += wellPath->name(); } } if (m_nameConfig->addCaseName() && m_case()) { - generatedCurveName.push_back(m_case->caseUserDescription()); + generatedAutoTags.push_back(m_case->caseUserDescription()); } if (m_nameConfig->addProperty() && !resultPropertyString().isEmpty()) { - generatedCurveName.push_back(resultPropertyString()); + generatedAutoTags.push_back(resultPropertyString()); } if (m_nameConfig->addTimeStep() || m_nameConfig->addDate()) { + bool addTimeStep = m_nameConfig->addTimeStep() && m_timeStep() != -1; size_t maxTimeStep = 0; if (eclipseCase) { + addTimeStep = addTimeStep && m_eclipseResultDefinition->resultType() != RiaDefines::STATIC_NATIVE; RigEclipseCaseData* data = eclipseCase->eclipseCaseData(); if (data) { @@ -267,17 +342,72 @@ QString Rim3dWellLogExtractionCurve::createCurveAutoName() const QString dateString = wellDate(); if (!dateString.isEmpty()) { - generatedCurveName.push_back(dateString); + generatedAutoTags.push_back(dateString); } } - if (m_nameConfig->addTimeStep()) + if (addTimeStep) { - generatedCurveName.push_back(QString("[%1/%2]").arg(m_timeStep()).arg(maxTimeStep)); + generatedAutoTags.push_back(QString("[%1/%2]").arg(m_timeStep() + 1).arg(maxTimeStep)); } } + if (!generatedAutoTags.empty()) + { + autoName.push_back(generatedAutoTags.join(", ")); + } + return autoName.join(": "); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double Rim3dWellLogExtractionCurve::rkbDiff() const +{ + RimWellPath* wellPath; + firstAncestorOrThisOfType(wellPath); + + if (wellPath && wellPath->wellPathGeometry()) + { + return wellPath->wellPathGeometry()->rkbDiff(); + } - return generatedCurveName.join(", "); + return HUGE_VAL; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool Rim3dWellLogExtractionCurve::isShowingTimeDependentResult() const +{ + if (dynamic_cast(m_case())) + { + return m_eclipseResultDefinition->hasDynamicResult(); + } + else if (dynamic_cast(m_case())) + { + return m_geomResultDefinition->hasResult(); + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool Rim3dWellLogExtractionCurve::showInView(const Rim3dView* gridView) const +{ + if (isShowingCurve()) + { + if (dynamic_cast(m_case())) + { + return dynamic_cast(gridView) != nullptr; + } + else if (dynamic_cast(m_case())) + { + return dynamic_cast(gridView) != nullptr; + } + } + return false; } //-------------------------------------------------------------------------------------------------- @@ -293,7 +423,22 @@ caf::PdmFieldHandle* Rim3dWellLogExtractionCurve::userDescriptionField() //-------------------------------------------------------------------------------------------------- void Rim3dWellLogExtractionCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - if (changedField == &m_timeStep || changedField == &m_case) + if (changedField == &m_case) + { + RimEclipseCase* eclipseCase = dynamic_cast(m_case()); + RimGeoMechCase* geoMechCase = dynamic_cast(m_case()); + if (eclipseCase) + { + m_eclipseResultDefinition->setEclipseCase(eclipseCase); + } + else if (geoMechCase) + { + m_geomResultDefinition->setGeoMechCase(geoMechCase); + } + + this->resetMinMaxValuesAndUpdateUI(); + } + else if (changedField == &m_timeStep) { this->resetMinMaxValuesAndUpdateUI(); } @@ -324,7 +469,7 @@ QList Rim3dWellLogExtractionCurve::calculateValueOptions { timeStepNames = m_case->timeStepStrings(); } - + options.push_back(caf::PdmOptionItemInfo(QString("Follow Animation Time Step"), -1)); for (int i = 0; i < timeStepNames.size(); i++) { options.push_back(caf::PdmOptionItemInfo(timeStepNames[i], i)); @@ -363,7 +508,8 @@ void Rim3dWellLogExtractionCurve::defineUiOrdering(QString uiConfigName, caf::Pd Rim3dWellLogCurve::configurationUiOrdering(uiOrdering); - m_nameConfig()->createUiGroup(uiConfigName, uiOrdering); + caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup("Curve Name"); + m_nameConfig->uiOrdering(uiConfigName, *nameGroup); uiOrdering.skipRemainingFields(true); } @@ -380,6 +526,9 @@ void Rim3dWellLogExtractionCurve::initAfterRead() m_geomResultDefinition->setGeoMechCase(geomCase); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- QString Rim3dWellLogExtractionCurve::wellDate() const { RimGeoMechCase* geomCase = dynamic_cast(m_case.value()); @@ -389,6 +538,10 @@ QString Rim3dWellLogExtractionCurve::wellDate() const if (eclipseCase) { + if (m_eclipseResultDefinition->resultType() == RiaDefines::STATIC_NATIVE) + { + return QString(); + } if (eclipseCase->eclipseCaseData()) { timeStepNames = eclipseCase->timeStepStrings(); @@ -401,6 +554,9 @@ QString Rim3dWellLogExtractionCurve::wellDate() const timeStepNames = geomCase->timeStepStrings(); } } - + if (m_timeStep == -1) + { + return QString("Animation Time Step"); + } return (m_timeStep >= 0 && m_timeStep < timeStepNames.size()) ? timeStepNames[m_timeStep] : ""; } diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.h b/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.h index a37e06aec5..3e9ec79406 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.h +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogExtractionCurve.h @@ -40,23 +40,33 @@ class Rim3dWellLogExtractionCurve : public Rim3dWellLogCurve public: Rim3dWellLogExtractionCurve(); - virtual ~Rim3dWellLogExtractionCurve(); + ~Rim3dWellLogExtractionCurve() override; void setPropertiesFromView(Rim3dView* view); - virtual QString resultPropertyString() const override; - virtual void curveValuesAndMds(std::vector* values, std::vector* measuredDepthValues) const override; + QString resultPropertyString() const override; + + bool followAnimationTimeStep() const override; + void curveValuesAndMds(std::vector* values, std::vector* measuredDepthValues) const override; + void curveValuesAndMdsAtTimeStep(std::vector* values, std::vector* measuredDepthValues, int timeStep) const override; + std::pair findCurveValueRange() override; + + QString name() const override; + QString createAutoName() const override; + double rkbDiff() const; + + bool isShowingTimeDependentResult() const override; + + bool showInView(const Rim3dView* gridView) const override; - virtual QString name() const override; - virtual QString createCurveAutoName() const override; protected: - virtual caf::PdmFieldHandle* userDescriptionField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* userDescriptionField() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void initAfterRead() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void initAfterRead() override; QString wellDate() const; private: caf::PdmPtrField m_case; diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp index 40976b2b95..91827b4d0a 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.cpp @@ -20,7 +20,7 @@ #include "RigWellLogFile.h" -#include "RimWellLogCurveNameConfig.h" +#include "RimWellLogFileCurveNameConfig.h" #include "RimWellLogFile.h" #include "RimWellLogFileChannel.h" #include "RimWellPath.h" @@ -119,7 +119,7 @@ QString Rim3dWellLogFileCurve::name() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString Rim3dWellLogFileCurve::createCurveAutoName() const +QString Rim3dWellLogFileCurve::createAutoName() const { QStringList name; QString unit; @@ -252,7 +252,8 @@ void Rim3dWellLogFileCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrd Rim3dWellLogCurve::configurationUiOrdering(uiOrdering); - m_nameConfig()->createUiGroup(uiConfigName, uiOrdering); + caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup("Curve Name"); + m_nameConfig->uiOrdering(uiConfigName, *nameGroup); uiOrdering.skipRemainingFields(true); } diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.h b/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.h index 58390e7a7f..6b859a9eab 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.h +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogFileCurve.h @@ -37,24 +37,24 @@ class Rim3dWellLogFileCurve : public Rim3dWellLogCurve public: Rim3dWellLogFileCurve(); - virtual ~Rim3dWellLogFileCurve(); + ~Rim3dWellLogFileCurve() override; void setDefaultFileCurveDataInfo(); - virtual void curveValuesAndMds(std::vector* values, std::vector* measuredDepthValues) const override; - virtual QString resultPropertyString() const override; - virtual QString name() const override; - virtual QString createCurveAutoName() const override; + void curveValuesAndMds(std::vector* values, std::vector* measuredDepthValues) const override; + QString resultPropertyString() const override; + QString name() const override; + QString createAutoName() const override; protected: - virtual caf::PdmFieldHandle* userDescriptionField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + caf::PdmFieldHandle* userDescriptionField() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: caf::PdmPtrField m_wellLogFile; diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp b/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp index 29fb3db642..921d9433f0 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.cpp @@ -18,10 +18,13 @@ #include "Rim3dWellLogRftCurve.h" +#include "RiaQDateTimeTools.h" + #include "RifReaderEclipseRft.h" + #include "RigWellLogCurveData.h" -#include "RimWellLogCurveNameConfig.h" +#include "RimWellLogRftCurveNameConfig.h" #include "RimEclipseResultCase.h" #include "RimTools.h" #include "RimWellPath.h" @@ -99,7 +102,7 @@ QString Rim3dWellLogRftCurve::name() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString Rim3dWellLogRftCurve::createCurveAutoName() const +QString Rim3dWellLogRftCurve::createAutoName() const { QStringList name; @@ -191,7 +194,9 @@ QList Rim3dWellLogRftCurve::calculateValueOptions(const std::vector timeStamps = reader->availableTimeSteps(wellName(), m_wellLogChannelName()); for (const QDateTime& dt : timeStamps) { - options.push_back(caf::PdmOptionItemInfo(dt.toString(dateFormat), dt)); + QString dateString = RiaQDateTimeTools::toStringUsingApplicationLocale(dt, dateFormat); + + options.push_back(caf::PdmOptionItemInfo(dateString, dt)); } } @@ -213,7 +218,8 @@ void Rim3dWellLogRftCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrde Rim3dWellLogCurve::configurationUiOrdering(uiOrdering); - m_nameConfig()->createUiGroup(uiConfigName, uiOrdering); + caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup("Curve Name"); + m_nameConfig->uiOrdering(uiConfigName, *nameGroup); uiOrdering.skipRemainingFields(true); } diff --git a/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.h b/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.h index ee9b157fe0..b002a06460 100644 --- a/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.h +++ b/ApplicationCode/ProjectDataModel/Rim3dWellLogRftCurve.h @@ -41,26 +41,26 @@ class Rim3dWellLogRftCurve : public Rim3dWellLogCurve public: Rim3dWellLogRftCurve(); - virtual ~Rim3dWellLogRftCurve(); + ~Rim3dWellLogRftCurve() override; - virtual void curveValuesAndMds(std::vector* values, std::vector* measuredDepthValues) const override; + void curveValuesAndMds(std::vector* values, std::vector* measuredDepthValues) const override; - virtual QString resultPropertyString() const override; - virtual QString name() const override; - virtual QString createCurveAutoName() const override; + QString resultPropertyString() const override; + QString name() const override; + QString createAutoName() const override; protected: - virtual caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* userDescriptionField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; QString wellName() const; diff --git a/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.h b/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.h index b5f85e4784..b9dfeabf0b 100644 --- a/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.h +++ b/ApplicationCode/ProjectDataModel/RimBinaryExportSettings.h @@ -37,6 +37,6 @@ class RimBinaryExportSettings : public caf::PdmObject caf::PdmField undefinedValue; 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; }; diff --git a/ApplicationCode/ProjectDataModel/RimCalcScript.cpp b/ApplicationCode/ProjectDataModel/RimCalcScript.cpp index 1ffe6debc9..3ff0998456 100644 --- a/ApplicationCode/ProjectDataModel/RimCalcScript.cpp +++ b/ApplicationCode/ProjectDataModel/RimCalcScript.cpp @@ -1,46 +1,45 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// -#include "cafPdmField.h" #include "RimCalcScript.h" + +#include "RiaFieldHandleTools.h" + +#include "cafPdmField.h" #include "cafPdmUiFilePathEditor.h" CAF_PDM_SOURCE_INIT(RimCalcScript, "CalcScript"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimCalcScript::RimCalcScript() { CAF_PDM_InitObject("CalcScript", ":/OctaveScriptFile16x16.png", "Calc Script", ""); - CAF_PDM_InitField(&absolutePath, "AbsolutePath", QString(), "Location", "", "" ,""); - CAF_PDM_InitField(&content, "Content", QString(), "Directory", "", "" ,""); - content.uiCapability()->setUiHidden(true); - content.xmlCapability()->setIOWritable(false); + CAF_PDM_InitField(&absolutePath, "AbsolutePath", QString(), "Location", "", "", ""); + CAF_PDM_InitField(&content, "Content", QString(), "Directory", "", "", ""); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&content); absolutePath.uiCapability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimCalcScript::~RimCalcScript() -{ -} - +RimCalcScript::~RimCalcScript() {} diff --git a/ApplicationCode/ProjectDataModel/RimCalcScript.h b/ApplicationCode/ProjectDataModel/RimCalcScript.h index 77ad0f43ee..d3852fdf7b 100644 --- a/ApplicationCode/ProjectDataModel/RimCalcScript.h +++ b/ApplicationCode/ProjectDataModel/RimCalcScript.h @@ -31,7 +31,7 @@ class RimCalcScript : public caf::PdmObject public: RimCalcScript(); - virtual ~RimCalcScript(); + ~RimCalcScript() override; caf::PdmField absolutePath; caf::PdmField content; // TODO: Obsolete field, can be deleted on next project file revision. diff --git a/ApplicationCode/ProjectDataModel/RimCase.cpp b/ApplicationCode/ProjectDataModel/RimCase.cpp index ee0ce66da0..c0f221c39b 100644 --- a/ApplicationCode/ProjectDataModel/RimCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimCase.cpp @@ -121,7 +121,7 @@ void RimCase::setFormationNames(RimFormationNames* formationNames) //-------------------------------------------------------------------------------------------------- size_t RimCase::uiToNativeTimeStepIndex(size_t uiTimeStepIndex) { - std::vector nativeTimeIndices = m_timeStepFilter->filteredNativeTimeStepIndices(); + std::vector nativeTimeIndices = m_timeStepFilter->filteredTimeSteps(); if (nativeTimeIndices.size() > 0) { diff --git a/ApplicationCode/ProjectDataModel/RimCase.h b/ApplicationCode/ProjectDataModel/RimCase.h index d13f3a908d..088509a012 100644 --- a/ApplicationCode/ProjectDataModel/RimCase.h +++ b/ApplicationCode/ProjectDataModel/RimCase.h @@ -47,7 +47,7 @@ class RimCase : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimCase(); - virtual ~RimCase(); + ~RimCase() override; caf::PdmField caseId; caf::PdmField caseUserDescription; @@ -77,11 +77,11 @@ class RimCase : public caf::PdmObject Rim2dIntersectionViewCollection* intersectionViewCollection(); protected: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; virtual std::vector allSpecialViews() const = 0; private: - virtual caf::PdmFieldHandle* userDescriptionField() override { return &caseUserDescription; } + caf::PdmFieldHandle* userDescriptionField() override { return &caseUserDescription; } protected: caf::PdmChildField m_timeStepFilter; diff --git a/ApplicationCode/ProjectDataModel/RimCaseCollection.h b/ApplicationCode/ProjectDataModel/RimCaseCollection.h index e2bc36ad5c..0dd3c9340f 100644 --- a/ApplicationCode/ProjectDataModel/RimCaseCollection.h +++ b/ApplicationCode/ProjectDataModel/RimCaseCollection.h @@ -36,7 +36,7 @@ class RimCaseCollection : public caf::PdmObject public: RimCaseCollection(); - virtual ~RimCaseCollection(); + ~RimCaseCollection() override; caf::PdmChildArrayField reservoirs; RimIdenticalGridCaseGroup* parentCaseGroup(); diff --git a/ApplicationCode/ProjectDataModel/RimCellEdgeColors.cpp b/ApplicationCode/ProjectDataModel/RimCellEdgeColors.cpp index 6f3e73f500..5a5de5301e 100644 --- a/ApplicationCode/ProjectDataModel/RimCellEdgeColors.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellEdgeColors.cpp @@ -32,6 +32,7 @@ #include "cafPdmUiTreeOrdering.h" #include "cvfMath.h" +#include namespace caf { @@ -54,7 +55,7 @@ RimCellEdgeColors::RimCellEdgeColors() { CAF_PDM_InitObject("Cell Edge Result", ":/EdgeResult_1.png", "", ""); - CAF_PDM_InitField(&enableCellEdgeColors, "EnableCellEdgeColors", true, "Enable Cell Edge Results", "", "", ""); + CAF_PDM_InitField(&m_enableCellEdgeColors, "EnableCellEdgeColors", true, "Enable Cell Edge Results", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_propertyType, "propertyType", "Property Type", "", "", ""); @@ -81,8 +82,6 @@ RimCellEdgeColors::RimCellEdgeColors() //-------------------------------------------------------------------------------------------------- RimCellEdgeColors::~RimCellEdgeColors() { - delete m_legendConfig(); - delete m_singleVarEdgeResultColors; } //-------------------------------------------------------------------------------------------------- @@ -99,7 +98,8 @@ void RimCellEdgeColors::setReservoirView(RimEclipseView* ownerReservoirView) //-------------------------------------------------------------------------------------------------- void RimCellEdgeColors::loadResult() { - CVF_ASSERT(m_reservoirView && m_reservoirView->currentGridCellResults()); + if (!m_enableCellEdgeColors) return; + if (!m_reservoirView->currentGridCellResults()) return; if (isUsingSingleVariable()) { @@ -193,7 +193,7 @@ QList RimCellEdgeColors::calculateValueOptions(const caf QList options; - std::map > varBaseNameToVarsMap; + std::map > varBaseNameToVarsMap; int i; for (i = 0; i < varList.size(); ++i) @@ -213,7 +213,7 @@ QList RimCellEdgeColors::calculateValueOptions(const caf } } - std::map >::iterator it; + std::map >::iterator it; for (it = varBaseNameToVarsMap.begin(); it != varBaseNameToVarsMap.end(); ++it) { @@ -396,7 +396,7 @@ void RimCellEdgeColors::resetResultIndices() //-------------------------------------------------------------------------------------------------- bool RimCellEdgeColors::hasResult() const { - if (!enableCellEdgeColors()) return false; + if (!m_enableCellEdgeColors()) return false; if (isUsingSingleVariable() && m_singleVarEdgeResultColors->isFlowDiagOrInjectionFlooding()) { @@ -437,33 +437,35 @@ void RimCellEdgeColors::minMaxCellEdgeValues(double& min, double& max) globalMin = HUGE_VAL; globalMax = -HUGE_VAL; - if (isUsingSingleVariable() && singleVarEdgeResultColors()->isFlowDiagOrInjectionFlooding()) + if (m_reservoirView->currentGridCellResults()) { - int currentTimeStep = m_reservoirView->currentTimeStep(); - - RigFlowDiagResults* fldResults = singleVarEdgeResultColors()->flowDiagSolution()->flowDiagResults(); - RigFlowDiagResultAddress resAddr = singleVarEdgeResultColors()->flowDiagResAddress(); + if (isUsingSingleVariable() && singleVarEdgeResultColors()->isFlowDiagOrInjectionFlooding()) + { + int currentTimeStep = m_reservoirView->currentTimeStep(); - fldResults->minMaxScalarValues(resAddr, currentTimeStep, &globalMin, &globalMax); - } - else - { - size_t resultIndices[6]; - this->gridScalarIndices(resultIndices); + RigFlowDiagResults* fldResults = singleVarEdgeResultColors()->flowDiagSolution()->flowDiagResults(); + RigFlowDiagResultAddress resAddr = singleVarEdgeResultColors()->flowDiagResAddress(); - size_t idx; - for (idx = 0; idx < 6; idx++) + fldResults->minMaxScalarValues(resAddr, currentTimeStep, &globalMin, &globalMax); + } + else { - if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue; + size_t resultIndices[6]; + this->gridScalarIndices(resultIndices); + size_t idx; + for (idx = 0; idx < 6; idx++) { - double cMin, cMax; - m_reservoirView->currentGridCellResults()->minMaxCellScalarValues(resultIndices[idx], cMin, cMax); + if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue; - globalMin = CVF_MIN(globalMin, cMin); - globalMax = CVF_MAX(globalMax, cMax); - } + { + double cMin, cMax; + m_reservoirView->currentGridCellResults()->minMaxCellScalarValues(resultIndices[idx], cMin, cMax); + globalMin = CVF_MIN(globalMin, cMin); + globalMax = CVF_MAX(globalMax, cMax); + } + } } } @@ -566,12 +568,20 @@ QString RimCellEdgeColors::resultVariableUiShortName() const } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCellEdgeColors::setActive(bool active) +{ + m_enableCellEdgeColors = active; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- caf::PdmFieldHandle* RimCellEdgeColors::objectToggleField() { - return &enableCellEdgeColors; + return &m_enableCellEdgeColors; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimCellEdgeColors.h b/ApplicationCode/ProjectDataModel/RimCellEdgeColors.h index c5e99c7608..49a63fc9f7 100644 --- a/ApplicationCode/ProjectDataModel/RimCellEdgeColors.h +++ b/ApplicationCode/ProjectDataModel/RimCellEdgeColors.h @@ -21,11 +21,12 @@ #pragma once #include "cafAppEnum.h" -#include "cafFixedArray.h" #include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" +#include + class RigCaseCellResultsData; class RimEclipseCase; class RimEclipseCellColors; @@ -49,7 +50,7 @@ class RimCellEdgeColors : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimCellEdgeColors(); - virtual ~RimCellEdgeColors(); + ~RimCellEdgeColors() override; enum EdgeFaceType { @@ -66,65 +67,62 @@ class RimCellEdgeColors : public caf::PdmObject typedef caf::AppEnum EdgeFaceEnum; - void setReservoirView(RimEclipseView* ownerReservoirView); - void setEclipseCase(RimEclipseCase* eclipseCase); + void setReservoirView(RimEclipseView* ownerReservoirView); + void setEclipseCase(RimEclipseCase* eclipseCase); - void setResultVariable(const QString& variableName); - QString resultVariable() const; - QString resultVariableUiName() const; - QString resultVariableUiShortName() const; + void setResultVariable(const QString& variableName); + QString resultVariable() const; + QString resultVariableUiName() const; + QString resultVariableUiShortName() const; - caf::PdmField enableCellEdgeColors; + void setActive(bool active); - double ignoredScalarValue() { return m_ignoredResultScalar; } - void gridScalarIndices(size_t resultIndices[6]); - void cellEdgeMetaData(std::vector* metaData); + double ignoredScalarValue() { return m_ignoredResultScalar; } + void gridScalarIndices(size_t resultIndices[6]); + void cellEdgeMetaData(std::vector* metaData); - void loadResult(); - bool hasResult() const; - bool hasCategoryResult() const; - bool isUsingSingleVariable() const; + void loadResult(); + bool hasResult() const; + bool hasCategoryResult() const; + bool isUsingSingleVariable() const; - RimEclipseCellColors* singleVarEdgeResultColors(); - RimRegularLegendConfig* legendConfig(); - PropertyType propertyType() const; + RimEclipseCellColors* singleVarEdgeResultColors(); + RimRegularLegendConfig* legendConfig(); + PropertyType propertyType() const; - void minMaxCellEdgeValues(double& min, double& max); - void posNegClosestToZero(double& pos, double& neg); + void minMaxCellEdgeValues(double& min, double& max); + void posNegClosestToZero(double& pos, double& neg); - void updateUiFieldsFromActiveResult(); + void updateUiFieldsFromActiveResult(); protected: + void initAfterRead() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual void initAfterRead(); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); - - QStringList findResultVariableNames(); + QStringList findResultVariableNames(); private: - void resetResultIndices(); - void updateIgnoredScalarValue(); - - void gridScalarResultNames(std::vector* resultNames); + void resetResultIndices(); + void updateIgnoredScalarValue(); - virtual caf::PdmFieldHandle* objectToggleField(); + void gridScalarResultNames(std::vector* resultNames); - caf::PdmField m_resultVariable; - caf::PdmField useXVariable; - caf::PdmField useYVariable; - caf::PdmField useZVariable; + caf::PdmFieldHandle* objectToggleField() override; - caf::FixedArray, 6 > m_resultNameToIndexPairs; - caf::PdmPointer m_reservoirView; - double m_ignoredResultScalar; + caf::PdmField m_enableCellEdgeColors; + caf::PdmField m_resultVariable; + caf::PdmField useXVariable; + caf::PdmField useYVariable; + caf::PdmField useZVariable; + std::array, 6> m_resultNameToIndexPairs; + caf::PdmPointer m_reservoirView; + double m_ignoredResultScalar; - caf::PdmField > m_propertyType; - caf::PdmChildField m_legendConfig; - caf::PdmChildField m_singleVarEdgeResultColors; - + caf::PdmField> m_propertyType; + caf::PdmChildField m_legendConfig; + caf::PdmChildField m_singleVarEdgeResultColors; }; - diff --git a/ApplicationCode/ProjectDataModel/RimCellFilter.h b/ApplicationCode/ProjectDataModel/RimCellFilter.h index 3a576780e3..9ee21bdf47 100644 --- a/ApplicationCode/ProjectDataModel/RimCellFilter.h +++ b/ApplicationCode/ProjectDataModel/RimCellFilter.h @@ -38,7 +38,7 @@ class RimCellFilter : public caf::PdmObject }; RimCellFilter(); - virtual ~RimCellFilter(); + ~RimCellFilter() override; caf::PdmField name; caf::PdmField isActive; @@ -47,6 +47,6 @@ class RimCellFilter : public caf::PdmObject void updateIconState(); protected: - virtual caf::PdmFieldHandle* userDescriptionField(); - virtual caf::PdmFieldHandle* objectToggleField(); + caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* objectToggleField() override; }; diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp index ecec2521cd..c8fcf6588b 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.cpp @@ -21,6 +21,8 @@ #include "RimCellRangeFilter.h" +#include "RiaApplication.h" + #include "RigActiveCellInfo.h" #include "RigReservoirGridTools.h" @@ -43,7 +45,7 @@ RimCellRangeFilter::RimCellRangeFilter() { CAF_PDM_InitObject("Cell Range Filter", ":/CellFilter_Range.png", "", ""); - CAF_PDM_InitField(&gridIndex, "GridIndex", 0, "Grid", "", "",""); + CAF_PDM_InitField(&m_gridIndex, "GridIndex", 0, "Grid", "", "",""); CAF_PDM_InitField(&propagateToSubGrids, "PropagateToSubGrids", true, "Apply to Subgrids", "", "",""); CAF_PDM_InitField(&startIndexI, "StartIndexI", 1, "Start Index I", "", "",""); @@ -63,7 +65,10 @@ RimCellRangeFilter::RimCellRangeFilter() CAF_PDM_InitField(&cellCountK, "CellCountK", 1, "Cell Count K", "", "",""); cellCountK.uiCapability()->setUiEditorTypeName(caf::PdmUiSliderEditor::uiEditorTypeName()); - + + CAF_PDM_InitField(&m_useIndividualCellIndices, "UseIndividualCellIndices", false, "Use Individual Cell Indices", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_individualCellIndices, "IndividualCellIndices", "Cell Indices", "", "Use Ctrl-C for copy and Ctrl-V for paste", ""); + updateIconState(); } @@ -74,12 +79,28 @@ RimCellRangeFilter::~RimCellRangeFilter() { } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimCellRangeFilter::setGridIndex(int gridIndex) +{ + m_gridIndex = gridIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimCellRangeFilter::gridIndex() const +{ + return m_gridIndex; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCellRangeFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - if (changedField == &gridIndex) + if (changedField == &m_gridIndex) { const cvf::StructGridInterface* grid = selectedGrid(); @@ -138,6 +159,22 @@ void RimCellRangeFilter::updateActiveState() isActive.uiCapability()->setUiReadOnly(isRangeFilterControlled()); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimCellRangeFilter::useIndividualCellIndices() const +{ + return m_useIndividualCellIndices(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RimCellRangeFilter::individualCellIndices() const +{ + return m_individualCellIndices.v(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -151,7 +188,7 @@ void RimCellRangeFilter::setDefaultValues() Rim3dView* rimView = nullptr; this->firstAncestorOrThisOfTypeAsserted(rimView); - RigActiveCellInfo* actCellInfo = RigReservoirGridTools::activeCellInfo(rimView); + auto actCellInfo = RigReservoirGridTools::activeCellInfo(rimView); RimCase* rimCase = nullptr; this->firstAncestorOrThisOfTypeAsserted(rimCase); @@ -239,9 +276,9 @@ void RimCellRangeFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderi std::vector objFields; this->fields(objFields); - for (size_t i = 0; i < objFields.size(); i ++) + for (auto& objField : objFields) { - objFields[i]->uiCapability()->setUiReadOnly(readOnlyState); + objField->uiCapability()->setUiReadOnly(readOnlyState); } const cvf::StructGridInterface* grid = selectedGrid(); @@ -252,7 +289,7 @@ void RimCellRangeFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderi Rim3dView* rimView = nullptr; this->firstAncestorOrThisOfTypeAsserted(rimView); - RigActiveCellInfo* actCellInfo = RigReservoirGridTools::activeCellInfo(rimView); + auto actCellInfo = RigReservoirGridTools::activeCellInfo(rimView); if (grid == mainGrid && actCellInfo) { @@ -284,6 +321,29 @@ void RimCellRangeFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderi cellCountJ.uiCapability()->setUiName(QString(" Width")); cellCountK.uiCapability()->setUiName(QString(" Width")); } + + uiOrdering.add(&name); + uiOrdering.add(&filterMode); + uiOrdering.add(&m_gridIndex); + uiOrdering.add(&propagateToSubGrids); + uiOrdering.add(&startIndexI); + uiOrdering.add(&cellCountI); + uiOrdering.add(&startIndexJ); + uiOrdering.add(&cellCountJ); + uiOrdering.add(&startIndexK); + uiOrdering.add(&cellCountK); + + if(RiaApplication::enableDevelopmentFeatures()) + { + auto group = uiOrdering.addNewGroup("Single Cell Filtering (TEST)"); + group->setCollapsedByDefault(true); + + group->add(&m_useIndividualCellIndices); + group->add(&m_individualCellIndices); + + m_individualCellIndices.uiCapability()->setUiReadOnly(!m_useIndividualCellIndices); + } + uiOrdering.skipRemainingFields(true); } //-------------------------------------------------------------------------------------------------- @@ -306,7 +366,7 @@ QList RimCellRangeFilter::calculateValueOptions(const ca if (useOptionsOnly) (*useOptionsOnly) = true; - if (&gridIndex == fieldNeedingOptions) + if (&m_gridIndex == fieldNeedingOptions) { RimCase* rimCase = nullptr; this->firstAncestorOrThisOfTypeAsserted(rimCase); diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h index 6f6834bbc9..65cfdd2ae0 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilter.h @@ -22,6 +22,8 @@ #include "RimCellFilter.h" +#include "cafPdmFieldCvfVec3d.h" + class RigGridBase; class RigMainGrid; class RimCellRangeFilterCollection; @@ -42,9 +44,15 @@ class RimCellRangeFilter : public RimCellFilter CAF_PDM_HEADER_INIT; public: RimCellRangeFilter(); - virtual ~RimCellRangeFilter(); + ~RimCellRangeFilter() override; + + void setGridIndex(int gridIndex); + int gridIndex() const; + +private: + caf::PdmField m_gridIndex; // The index of the grid that this filter applies to - caf::PdmField gridIndex; // The index of the grid that this filter applies to +public: caf::PdmField propagateToSubGrids; // Do propagate the effects to the sub-grids caf::PdmField startIndexI; // Eclipse indexing, first index is 1 @@ -57,19 +65,24 @@ class RimCellRangeFilter : public RimCellFilter void setDefaultValues(); void updateActiveState(); + bool useIndividualCellIndices() const; + const std::vector& individualCellIndices() const; + protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override ; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; - virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); + QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ) override; private: RimCellRangeFilterCollection* parentContainer(); bool isRangeFilterControlled() const; void computeAndSetValidValues(); const cvf::StructGridInterface* selectedGrid(); -}; + caf::PdmField m_useIndividualCellIndices; + caf::PdmField> m_individualCellIndices; +}; diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp index d621a4bb9f..d20e3c7925 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.cpp @@ -70,25 +70,47 @@ void RimCellRangeFilterCollection::compoundCellRangeFilter(cvf::CellRangeFilter* { if (rangeFilter->filterMode == RimCellFilter::INCLUDE) { - cellRangeFilter->addCellIncludeRange( - rangeFilter->startIndexI - 1, - rangeFilter->startIndexJ - 1, - rangeFilter->startIndexK - 1, - rangeFilter->startIndexI - 1 + rangeFilter->cellCountI, - rangeFilter->startIndexJ - 1 + rangeFilter->cellCountJ, - rangeFilter->startIndexK - 1 + rangeFilter->cellCountK, - rangeFilter->propagateToSubGrids()); + if (rangeFilter->useIndividualCellIndices()) + { + for (const auto& cellIndex : rangeFilter->individualCellIndices()) + { + cellRangeFilter->addCellInclude( + cellIndex.x() - 1 , cellIndex.y() - 1, cellIndex.z() - 1, rangeFilter->propagateToSubGrids()); + } + } + else + { + cellRangeFilter->addCellIncludeRange( + rangeFilter->startIndexI - 1, + rangeFilter->startIndexJ - 1, + rangeFilter->startIndexK - 1, + rangeFilter->startIndexI - 1 + rangeFilter->cellCountI, + rangeFilter->startIndexJ - 1 + rangeFilter->cellCountJ, + rangeFilter->startIndexK - 1 + rangeFilter->cellCountK, + rangeFilter->propagateToSubGrids()); + } } else { - cellRangeFilter->addCellExcludeRange( - rangeFilter->startIndexI - 1, - rangeFilter->startIndexJ - 1, - rangeFilter->startIndexK - 1, - rangeFilter->startIndexI - 1 + rangeFilter->cellCountI, - rangeFilter->startIndexJ - 1 + rangeFilter->cellCountJ, - rangeFilter->startIndexK - 1 + rangeFilter->cellCountK, - rangeFilter->propagateToSubGrids()); + if (rangeFilter->useIndividualCellIndices()) + { + for (const auto& cellIndex : rangeFilter->individualCellIndices()) + { + cellRangeFilter->addCellExclude( + cellIndex.x() - 1, cellIndex.y() - 1, cellIndex.z() - 1, rangeFilter->propagateToSubGrids()); + } + } + else + { + cellRangeFilter->addCellExcludeRange( + rangeFilter->startIndexI - 1, + rangeFilter->startIndexJ - 1, + rangeFilter->startIndexK - 1, + rangeFilter->startIndexI - 1 + rangeFilter->cellCountI, + rangeFilter->startIndexJ - 1 + rangeFilter->cellCountJ, + rangeFilter->startIndexK - 1 + rangeFilter->cellCountK, + rangeFilter->propagateToSubGrids()); + } } } } diff --git a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h index 57c65d6dbf..9f79eda612 100644 --- a/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h +++ b/ApplicationCode/ProjectDataModel/RimCellRangeFilterCollection.h @@ -38,7 +38,7 @@ class RimCellRangeFilterCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimCellRangeFilterCollection(); - virtual ~RimCellRangeFilterCollection(); + ~RimCellRangeFilterCollection() override; // Fields caf::PdmField isActive; @@ -53,9 +53,9 @@ class RimCellRangeFilterCollection : public caf::PdmObject void updateIconState(); protected: - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); - virtual caf::PdmFieldHandle* objectToggleField(); + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; + caf::PdmFieldHandle* objectToggleField() override; private: Rim3dView* baseView() const; diff --git a/ApplicationCode/ProjectDataModel/RimCheckableNamedObject.h b/ApplicationCode/ProjectDataModel/RimCheckableNamedObject.h index 0cbc607973..4b63bf68b0 100644 --- a/ApplicationCode/ProjectDataModel/RimCheckableNamedObject.h +++ b/ApplicationCode/ProjectDataModel/RimCheckableNamedObject.h @@ -29,13 +29,13 @@ class RimCheckableNamedObject : public RimNamedObject CAF_PDM_HEADER_INIT; public: RimCheckableNamedObject(void); - virtual ~RimCheckableNamedObject(void); + ~RimCheckableNamedObject(void) override; bool isChecked() const; void setCheckState(bool checkState); protected: - virtual caf::PdmFieldHandle* objectToggleField() override; + caf::PdmFieldHandle* objectToggleField() override; protected: caf::PdmField m_isChecked; diff --git a/ApplicationCode/ProjectDataModel/RimCheckableObject.h b/ApplicationCode/ProjectDataModel/RimCheckableObject.h index d2ed97adfa..af4225a430 100644 --- a/ApplicationCode/ProjectDataModel/RimCheckableObject.h +++ b/ApplicationCode/ProjectDataModel/RimCheckableObject.h @@ -30,13 +30,13 @@ class RimCheckableObject : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimCheckableObject(void); - virtual ~RimCheckableObject(void); + ~RimCheckableObject(void) override; bool isChecked() const; void setCheckState(bool checkState); protected: - virtual caf::PdmFieldHandle* objectToggleField() override; + caf::PdmFieldHandle* objectToggleField() override; protected: caf::PdmField m_isChecked; diff --git a/ApplicationCode/ProjectDataModel/RimCommandObject.cpp b/ApplicationCode/ProjectDataModel/RimCommandObject.cpp index bd13d041ab..4fdbc6a4f0 100644 --- a/ApplicationCode/ProjectDataModel/RimCommandObject.cpp +++ b/ApplicationCode/ProjectDataModel/RimCommandObject.cpp @@ -67,8 +67,7 @@ RimCommandExecuteScript::RimCommandExecuteScript() CAF_PDM_InitField(&execute, "Execute", true, "Execute", "", "", ""); - execute.xmlCapability()->setIOWritable(false); - execute.xmlCapability()->setIOReadable(false); + execute.xmlCapability()->disableIO(); execute.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); execute.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); } @@ -278,14 +277,14 @@ void RimCommandIssueFieldChanged::childObjects(caf::PdmObject* pdmObject, std::v //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmObjectHandle* RimCommandIssueFieldChanged::findObjectByName(caf::PdmObjectHandle* pdmObject, const QString& objectName) +caf::PdmObjectHandle* RimCommandIssueFieldChanged::findObjectByName(caf::PdmObjectHandle* pdmObject, const QString& name) { std::vector fields; pdmObject->fields(fields); caf::PdmUiObjectHandle* uiObjectHandle = uiObj(pdmObject); - if (uiObjectHandle && uiObjectHandle->uiName() == objectName) + if (uiObjectHandle && uiObjectHandle->uiName() == name) { return pdmObject; } @@ -299,7 +298,7 @@ caf::PdmObjectHandle* RimCommandIssueFieldChanged::findObjectByName(caf::PdmObje for (size_t cIdx = 0; cIdx < children.size(); cIdx++) { - PdmObjectHandle* candidateObj = findObjectByName(children[cIdx], objectName); + PdmObjectHandle* candidateObj = findObjectByName(children[cIdx], name); if (candidateObj) { return candidateObj; diff --git a/ApplicationCode/ProjectDataModel/RimCommandObject.h b/ApplicationCode/ProjectDataModel/RimCommandObject.h index 19bb199619..8acf1c222d 100644 --- a/ApplicationCode/ProjectDataModel/RimCommandObject.h +++ b/ApplicationCode/ProjectDataModel/RimCommandObject.h @@ -35,7 +35,7 @@ class RimCommandObject : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimCommandObject(); - virtual ~RimCommandObject(); + ~RimCommandObject() override; virtual bool isAsyncronous() { return false; }; @@ -52,23 +52,23 @@ class RimCommandExecuteScript : public RimCommandObject CAF_PDM_HEADER_INIT; public: RimCommandExecuteScript(); - virtual ~RimCommandExecuteScript(); + ~RimCommandExecuteScript() override; caf::PdmField name; caf::PdmField isEnabled; caf::PdmField execute; caf::PdmField scriptText; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual caf::PdmFieldHandle* userDescriptionField(); + caf::PdmFieldHandle* userDescriptionField() override; - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; - virtual bool isAsyncronous(); + bool isAsyncronous() override; }; //-------------------------------------------------------------------------------------------------- @@ -79,21 +79,21 @@ class RimCommandIssueFieldChanged : public RimCommandObject CAF_PDM_HEADER_INIT; public: RimCommandIssueFieldChanged(); - virtual ~RimCommandIssueFieldChanged(); + ~RimCommandIssueFieldChanged() override; caf::PdmField commandName; caf::PdmField objectName; caf::PdmField fieldName; caf::PdmField fieldValueToApply; - virtual void redo(); - virtual void undo(); + void redo() override; + void undo() override; - virtual caf::PdmFieldHandle* userDescriptionField(); + caf::PdmFieldHandle* userDescriptionField() override; private: void childObjects(caf::PdmObject* pdmObject, std::vector& children); - caf::PdmObjectHandle* findObjectByName(caf::PdmObjectHandle* root, const QString& objectName); + caf::PdmObjectHandle* findObjectByName(caf::PdmObjectHandle* root, const QString& name); caf::PdmFieldHandle* findFieldByKeyword(caf::PdmObjectHandle* pdmObject, const QString& fieldName); }; diff --git a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp index f3297af89e..f408e6ed2b 100644 --- a/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -30,6 +30,7 @@ #include "RimCaseCollection.h" #include "RimCellRangeFilter.h" #include "RimCellRangeFilterCollection.h" +#include "RimContourMapViewCollection.h" #include "RimEclipseCase.h" #include "RimEclipseCaseCollection.h" #include "RimEclipseCellColors.h" @@ -39,6 +40,7 @@ #include "RimEclipsePropertyFilterCollection.h" #include "RimEclipseStatisticsCase.h" #include "RimEclipseView.h" +#include "RimEnsembleCurveFilterCollection.h" #include "RimEnsembleCurveSetCollection.h" #include "RimEnsembleCurveSet.h" #include "RimFaultInView.h" @@ -51,6 +53,7 @@ #include "RimGeoMechPropertyFilter.h" #include "RimGeoMechPropertyFilterCollection.h" #include "RimGeoMechView.h" +#include "RimGridCollection.h" #include "RimIdenticalGridCaseGroup.h" #include "RimIntersection.h" #include "RimIntersectionBox.h" @@ -81,6 +84,7 @@ #include "RimWellLogPlotCollection.h" #include "RimWellLogTrack.h" #include "RimWellPath.h" +#include "RimWellPathAttributeCollection.h" #include "RimWellPathCollection.h" #include "RimWellPltPlot.h" #include "RimWellRftPlot.h" @@ -92,6 +96,7 @@ #include "RimSimWellFracture.h" #include "RimWellPathFracture.h" #include "RimWellPathFractureCollection.h" +#include "RimModeledWellPath.h" #include "RiuMainWindow.h" @@ -151,10 +156,15 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicPasteEclipseViewsFeature"; menuBuilder << "Separator"; menuBuilder << "RicNewViewFeature"; + menuBuilder << "RicNewContourMapViewFeature"; menuBuilder << "Separator"; menuBuilder << "RicCopyReferencesToClipboardFeature"; menuBuilder << "RicSaveEclipseInputVisibleCellsFeature"; } + else if (dynamic_cast(uiItem)) + { + menuBuilder << "RicNewContourMapViewFeature"; + } else if (dynamic_cast(uiItem)) { menuBuilder << "RicPasteEclipseCasesFeature"; @@ -174,12 +184,18 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "Separator"; menuBuilder << "RicNewViewFeature"; + menuBuilder << "RicNewContourMapViewFeature"; menuBuilder << "RicShowFlowCharacteristicsPlotFeature"; menuBuilder << "RicEclipseCaseNewGroupFeature"; menuBuilder << "Separator"; menuBuilder << "RicCopyReferencesToClipboardFeature"; menuBuilder << "Separator"; } + else if (dynamic_cast(uiItem)) + { + menuBuilder << "RicExportCompletionsForTemporaryLgrsFeature"; + menuBuilder << "RicDeleteTemporaryLgrsFeature"; + } else if (dynamic_cast(uiItem)) { menuBuilder << "RicPasteGeoMechViewsFeature"; @@ -250,6 +266,10 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicReloadWellPathFormationNamesFeature"; menuBuilder << "RicWellPathImportPerforationIntervalsFeature"; menuBuilder.subMenuEnd(); + + menuBuilder.addSeparator(); + + menuBuilder << "RicNewEditableWellPathFeature"; } else if (dynamic_cast(uiItem)) { @@ -266,6 +286,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicNewRftPlotFeature"; menuBuilder << "RicNewPltPlotFeature"; menuBuilder << "RicShowWellAllocationPlotFeature"; + menuBuilder << "RicNewWellBoreStabilityPlotFeature"; menuBuilder << "RicNewWellLogFileCurveFeature"; menuBuilder << "RicNewWellLogCurveExtractionFeature"; menuBuilder.subMenuEnd(); @@ -273,31 +294,42 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder.addSeparator(); menuBuilder.subMenuStart("3D Well Log Curves", QIcon(":/WellLogCurve16x16.png")); - menuBuilder << "RicAdd3dWellLogCurveFeature"; menuBuilder << "RicAdd3dWellLogFileCurveFeature"; - + menuBuilder << "RicAdd3dWellLogRftCurveFeature"; menuBuilder.subMenuEnd(); + menuBuilder << "RicNewEditableWellPathFeature"; menuBuilder << "RicNewWellPathIntersectionFeature"; menuBuilder.addSeparator(); - - menuBuilder.subMenuStart("Completions", QIcon(":/FishBoneGroup16x16.png")); + menuBuilder.subMenuStart("Completions", QIcon(":/CompletionsSymbol16x16.png")); menuBuilder << "RicNewWellPathFractureFeature"; menuBuilder << "RicNewFishbonesSubsFeature"; menuBuilder << "RicNewPerforationIntervalFeature"; + menuBuilder << "RicNewValveFeature"; menuBuilder << "RicEditPerforationCollectionFeature"; menuBuilder.subMenuEnd(); - menuBuilder.subMenuStart("Export Completions", QIcon(":/FishBoneGroup16x16.png")); + menuBuilder.subMenuStart("Export Completions", QIcon(":/ExportCompletionsSymbol16x16.png")); menuBuilder << "RicExportCompletionsForVisibleWellPathsFeature"; menuBuilder << "RicWellPathExportCompletionDataFeature"; menuBuilder.subMenuEnd(); + if ( dynamic_cast(uiItem) ) + { + menuBuilder << "RicShowWellPlanFeature"; + } + menuBuilder << "RicCreateMultipleFracturesFeature"; + menuBuilder << "RicNewWellPathAttributeFeature"; + menuBuilder << "Separator"; } + else if (dynamic_cast(uiItem)) + { + menuBuilder << "RicDeleteWellPathAttributeFeature"; + } else if (dynamic_cast(uiItem) || dynamic_cast(uiItem) || dynamic_cast(uiItem) || @@ -368,6 +400,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicPasteWellLogPlotFeature"; menuBuilder << "Separator"; menuBuilder << "RicNewWellLogPlotFeature"; + menuBuilder << "RicNewWellBoreStabilityPlotFeature"; } else if (dynamic_cast(uiItem)) { @@ -476,12 +509,17 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() { menuBuilder << "RicNewSummaryEnsembleCurveSetFeature"; } + else if (dynamic_cast(uiItem)) + { + menuBuilder << "RicNewEnsembleCurveFilterFeature"; + } else if (dynamic_cast(uiItem)) { menuBuilder << "RicImportSummaryCaseFeature"; menuBuilder << "RicImportSummaryCasesFeature"; menuBuilder << "RicImportSummaryGroupFeature"; menuBuilder << "RicImportEnsembleFeature"; + menuBuilder << "RicNewDerivedEnsembleFeature"; } else if (dynamic_cast(uiItem)) { @@ -492,6 +530,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicImportEnsembleFeature"; menuBuilder.subMenuEnd(); menuBuilder.addSeparator(); + menuBuilder << "RicNewDerivedEnsembleFeature"; menuBuilder << "RicNewSummaryPlotFeature"; menuBuilder << "RicNewSummaryCrossPlotFeature"; menuBuilder.addSeparator(); @@ -645,7 +684,6 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() { menuBuilder << "Separator"; menuBuilder << "RicLinkVisibleViewsFeature"; - menuBuilder << "RicLinkViewFeature"; menuBuilder << "RicShowLinkOptionsFeature"; menuBuilder << "RicSetMasterViewFeature"; menuBuilder << "RicUnLinkViewFeature"; @@ -661,16 +699,18 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() // is aware of multiple selected items, move the command to this list // without using dyncamic_cast. - menuBuilder << "RicPasteTimeHistoryCurveFeature"; menuBuilder << "RicPasteAsciiDataCurveFeature"; menuBuilder << "RicPasteSummaryCaseFeature"; menuBuilder.addSeparator(); menuBuilder << "RicCopyReferencesToClipboardFeature"; + menuBuilder << "RicLinkViewFeature"; + menuBuilder << "RicShowPlotDataFeature"; menuBuilder << "RicShowTotalAllocationDataFeature"; + menuBuilder << "RicNewDerivedEnsembleFeature"; menuBuilder << "RicNewSummaryPlotFeature"; menuBuilder << "RicNewSummaryCrossPlotFeature"; menuBuilder << "RicSummaryCurveSwitchAxisFeature"; @@ -686,11 +726,15 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() { menuBuilder << "RicNewPerforationIntervalFeature"; } + if (!menuBuilder.isCmdFeatureAdded("RicNewValveFeature")) + { + menuBuilder << "RicNewValveFeature"; + } menuBuilder << "RicEditPerforationCollectionFeature"; menuBuilder << "RicExportFishbonesLateralsFeature"; menuBuilder << "RicExportFishbonesWellSegmentsFeature"; - + menuBuilder << "RicExportFracturesWellSegmentsFeature"; { QStringList candidates; @@ -705,20 +749,46 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() if (!candidates.isEmpty()) { - menuBuilder.subMenuStart("Export Completions", QIcon(":/FishBoneGroup16x16.png")); + menuBuilder.subMenuStart("Export Completions", QIcon(":/ExportCompletionsSymbol16x16.png")); for (const auto& text : candidates) { menuBuilder << text; } - + menuBuilder.subMenuEnd(); } } + { + QStringList candidates; + + if (!menuBuilder.isCmdFeatureAdded("RicExportSelectedWellPathsFeature")) + { + candidates << "RicExportSelectedWellPathsFeature"; + + } + if (!menuBuilder.isCmdFeatureAdded("RicExportVisibleWellPathsFeature")) + { + candidates << "RicExportVisibleWellPathsFeature"; + } + + if (!candidates.isEmpty()) + { + menuBuilder.subMenuStart("Export Well Paths", QIcon(":/Save.png")); + + for (const auto& text : candidates) + { + menuBuilder << text; + } + + menuBuilder.subMenuEnd(); + } + } + + menuBuilder << "RicCreateMultipleFracturesFeature"; menuBuilder << "RicWellPathImportCompletionsFileFeature"; menuBuilder << "RicFlyToObjectFeature"; - menuBuilder << "RicExportCarfin"; menuBuilder << "RicImportObservedDataFeature"; menuBuilder << "RicReloadSummaryCaseFeature"; @@ -731,6 +801,8 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() menuBuilder << "RicDeleteSummaryCaseCollectionFeature"; menuBuilder << "RicCloseObservedDataFeature"; + menuBuilder << "RicCreateTemporaryLgrFeature"; + // Work in progress -- End caf::PdmUiItem* uiItem = uiItems[0]; diff --git a/ApplicationCode/ProjectDataModel/RimContourMapNameConfig.cpp b/ApplicationCode/ProjectDataModel/RimContourMapNameConfig.cpp new file mode 100644 index 0000000000..d4b8478be0 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimContourMapNameConfig.cpp @@ -0,0 +1,97 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimContourMapNameConfig.h" + +//================================================================================================== +/// +/// +//================================================================================================== + +CAF_PDM_SOURCE_INIT(RimContourMapNameConfig, "RimContourMapNameConfig"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapNameConfig::RimContourMapNameConfig(const RimNameConfigHolderInterface* configHolder) + : RimNameConfig(configHolder) +{ + CAF_PDM_InitObject("Contour Map Name Generator", "", "", ""); + + CAF_PDM_InitField(&m_addCaseName, "AddCaseName", true, "Add Case Name", "", "", ""); + CAF_PDM_InitField(&m_addAggregationType, "AddAggregationType", true, "Add Aggregation Type", "", "", ""); + CAF_PDM_InitField(&m_addProperty, "AddProperty", true, "Add Property Type", "", "", ""); + CAF_PDM_InitField(&m_addSampleSpacing, "AddSampleSpacing", false, "Add Sample Spacing", "", "", ""); + + m_customName = "Contour Map"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapNameConfig::addCaseName() const +{ + return m_addCaseName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapNameConfig::addAggregationType() const +{ + return m_addAggregationType(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapNameConfig::addProperty() const +{ + return m_addProperty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapNameConfig::addSampleSpacing() const +{ + return m_addSampleSpacing(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapNameConfig::enableAllAutoNameTags(bool enable) +{ + m_addCaseName = enable; + m_addAggregationType = enable; + m_addProperty = enable; + m_addSampleSpacing = enable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapNameConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + RimNameConfig::defineUiOrdering(uiConfigName, uiOrdering); + uiOrdering.add(&m_addCaseName); + uiOrdering.add(&m_addAggregationType); + uiOrdering.add(&m_addProperty); + uiOrdering.add(&m_addSampleSpacing); +} diff --git a/ApplicationCode/ProjectDataModel/RimContourMapNameConfig.h b/ApplicationCode/ProjectDataModel/RimContourMapNameConfig.h new file mode 100644 index 0000000000..9fc9c61a7d --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimContourMapNameConfig.h @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimNameConfig.h" + +//================================================================================================== +/// +/// +//================================================================================================== +class RimContourMapNameConfig : public RimNameConfig +{ + CAF_PDM_HEADER_INIT; + +public: + RimContourMapNameConfig(const RimNameConfigHolderInterface* configHolder = nullptr); + + bool addCaseName() const; + bool addAggregationType() const; + bool addProperty() const; + bool addSampleSpacing() const; + + void enableAllAutoNameTags(bool enable) override; + +protected: + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +private: + caf::PdmField m_addCaseName; + caf::PdmField m_addAggregationType; + caf::PdmField m_addProperty; + caf::PdmField m_addSampleSpacing; +}; + + diff --git a/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp b/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp new file mode 100644 index 0000000000..1f75f6ca5b --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimContourMapProjection.cpp @@ -0,0 +1,1354 @@ +#include "RimContourMapProjection.h" + +#include "RiaWeightedGeometricMeanCalculator.h" +#include "RiaWeightedHarmonicMeanCalculator.h" +#include "RiaWeightedMeanCalculator.h" + +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigCell.h" +#include "RigCellGeometryTools.h" +#include "RigEclipseCaseData.h" +#include "RigHexIntersectionTools.h" +#include "RigMainGrid.h" +#include "RigResultAccessor.h" +#include "RigResultAccessorFactory.h" + +#include "RivReservoirViewPartMgr.h" + +#include "RimCellRangeFilterCollection.h" +#include "RimContourMapView.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseView.h" +#include "RimEclipseResultCase.h" +#include "RimEclipseResultDefinition.h" +#include "RimProject.h" +#include "RimRegularLegendConfig.h" + +#include "cafContourLines.h" +#include "cafPdmUiDoubleSliderEditor.h" +#include "cafPdmUiTreeOrdering.h" + +#include "cvfArray.h" +#include "cvfCellRange.h" +#include "cvfGeometryTools.h" +#include "cvfScalarMapper.h" +#include "cvfStructGridGeometryGenerator.h" + +#include + +namespace caf +{ + template<> + void RimContourMapProjection::ResultAggregation::setUp() + { + addItem(RimContourMapProjection::RESULTS_OIL_COLUMN, "OIL_COLUMN", "Oil Column"); + addItem(RimContourMapProjection::RESULTS_GAS_COLUMN, "GAS_COLUMN", "Gas Column"); + addItem(RimContourMapProjection::RESULTS_HC_COLUMN, "HC_COLUMN", "Hydrocarbon Column"); + + addItem(RimContourMapProjection::RESULTS_MEAN_VALUE, "MEAN_VALUE", "Arithmetic Mean"); + addItem(RimContourMapProjection::RESULTS_HARM_VALUE, "HARM_VALUE", "Harmonic Mean"); + addItem(RimContourMapProjection::RESULTS_GEOM_VALUE, "GEOM_VALUE", "Geometric Mean"); + addItem(RimContourMapProjection::RESULTS_VOLUME_SUM, "VOLUME_SUM", "Volume Weighted Sum"); + addItem(RimContourMapProjection::RESULTS_SUM, "SUM", "Sum"); + + addItem(RimContourMapProjection::RESULTS_TOP_VALUE, "TOP_VALUE", "Top Value"); + addItem(RimContourMapProjection::RESULTS_MIN_VALUE, "MIN_VALUE", "Min Value"); + addItem(RimContourMapProjection::RESULTS_MAX_VALUE, "MAX_VALUE", "Max Value"); + + setDefault(RimContourMapProjection::RESULTS_MEAN_VALUE); + } +} +CAF_PDM_SOURCE_INIT(RimContourMapProjection, "RimContourMapProjection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapProjection::RimContourMapProjection() + : m_pickPoint(cvf::Vec2d::UNDEFINED), + m_mapSize(cvf::Vec2ui(0u, 0u)), + m_sampleSpacing(-1.0) +{ + CAF_PDM_InitObject("RimContourMapProjection", ":/draw_style_meshlines_24x24.png", "", ""); + + CAF_PDM_InitField(&m_relativeSampleSpacing, "SampleSpacing", 0.75, "Sample Spacing Factor", "", "", ""); + m_relativeSampleSpacing.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); + + CAF_PDM_InitFieldNoDefault(&m_resultAggregation, "ResultAggregation", "Result Aggregation", "", "", ""); + + CAF_PDM_InitField(&m_showContourLines, "ContourLines", true, "Show Contour Lines", "", "", ""); + + CAF_PDM_InitField(&m_weightByParameter, "WeightByParameter", false, "Weight by Result Parameter", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_weightingResult, "WeightingResult", "", "", "", ""); + m_weightingResult.uiCapability()->setUiHidden(true); + m_weightingResult.uiCapability()->setUiTreeChildrenHidden(true); + m_weightingResult = new RimEclipseResultDefinition; + m_weightingResult->findField("MResultType")->uiCapability()->setUiName("Result Type"); + setName("Map Projection"); + nameField()->uiCapability()->setUiReadOnly(true); + + m_resultAccessor = new RigHugeValResultAccessor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapProjection::~RimContourMapProjection() +{ + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::generateVertices(cvf::Vec3fArray* vertices, const caf::DisplayCoordTransform* displayCoordTransform) +{ + CVF_ASSERT(vertices); + size_t nVertices = numberOfVertices(); + vertices->resize(nVertices); + +#pragma omp parallel for + for (int index = 0; index < static_cast(nVertices); ++index) + { + cvf::Vec2ui ij = ijFromVertexIndex(index); + cvf::Vec2d globalPos = globalCellCenterPosition(ij.x(), ij.y()); + // Shift away from sample point to vertex + globalPos.x() -= m_sampleSpacing * 0.5; + globalPos.y() -= m_sampleSpacing * 0.5; + + cvf::Vec3d globalVertexPos(globalPos, m_fullBoundingBox.min().z() - 1.0); + cvf::Vec3f displayVertexPos(displayCoordTransform->transformToDisplayCoord(globalVertexPos)); + (*vertices)[index] = displayVertexPos; + } +} + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapProjection::ContourPolygons RimContourMapProjection::generateContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform) +{ + std::vector> contourPolygons; + if (minValue() != std::numeric_limits::infinity() && + maxValue() != -std::numeric_limits::infinity() && + std::fabs(maxValue() - minValue()) > 1.0e-8) + { + std::vector contourLevels; + if (legendConfig()->mappingMode() != RimRegularLegendConfig::CATEGORY_INTEGER) + { + legendConfig()->scalarMapper()->majorTickValues(&contourLevels); + int nContourLevels = static_cast(contourLevels.size()); + if (nContourLevels > 2) + { + if (legendConfig()->mappingMode() == RimRegularLegendConfig::LINEAR_CONTINUOUS || legendConfig()->mappingMode() == RimRegularLegendConfig::LINEAR_DISCRETE) + { + // Slight fudge to avoid very jagged contour lines at the very edge + // Shift the contour levels inwards. + contourLevels[0] += (contourLevels[1] - contourLevels[0]) * 0.1; + contourLevels[nContourLevels - 1] -= (contourLevels[nContourLevels - 1] - contourLevels[nContourLevels - 2]) * 0.1; + } + std::vector> contourLines; + caf::ContourLines::create(m_aggregatedVertexResults, xVertexPositions(), yVertexPositions(), contourLevels, &contourLines); + + contourPolygons.reserve(contourLines.size()); + for (size_t i = 0; i < contourLines.size(); ++i) + { + if (!contourLines[i].empty()) + { + cvf::ref contourPolygon = new cvf::Vec3fArray(contourLines[i].size()); + for (size_t j = 0; j < contourLines[i].size(); ++j) + { + cvf::Vec3d contourPoint3d = cvf::Vec3d(contourLines[i][j], m_fullBoundingBox.min().z()); + cvf::Vec3d displayPoint3d = displayCoordTransform->transformToDisplayCoord(contourPoint3d); + (*contourPolygon)[j] = cvf::Vec3f(displayPoint3d); + } + contourPolygons.push_back(contourPolygon); + } + } + } + } + } + return contourPolygons; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref +RimContourMapProjection::generatePickPointPolygon(const caf::DisplayCoordTransform* displayCoordTransform) +{ + cvf::ref pickPolygon; + if (!m_pickPoint.isUndefined()) + { + double zPos = m_fullBoundingBox.min().z(); + + std::vector points; + { + cvf::Vec2d gridorigin(m_fullBoundingBox.min().x(), m_fullBoundingBox.min().y()); + + cvf::Vec2d localPickPoint = m_pickPoint - gridorigin; + + cvf::Vec2d cellDiagonal(m_sampleSpacing*0.5, m_sampleSpacing*0.5); + cvf::Vec2ui pickedCell = ijFromLocalPos(localPickPoint); + cvf::Vec2d cellCenter = globalCellCenterPosition(pickedCell.x(), pickedCell.y()); + cvf::Vec2d cellCorner = cellCenter - cellDiagonal; +#ifndef NDEBUG + points.push_back(cvf::Vec3d(cellCorner, zPos)); + points.push_back(cvf::Vec3d(cellCorner + cvf::Vec2d(m_sampleSpacing, 0.0), zPos)); + points.push_back(cvf::Vec3d(cellCorner + cvf::Vec2d(m_sampleSpacing, 0.0), zPos)); + points.push_back(cvf::Vec3d(cellCorner + cvf::Vec2d(m_sampleSpacing, m_sampleSpacing), zPos)); + points.push_back(cvf::Vec3d(cellCorner + cvf::Vec2d(m_sampleSpacing, m_sampleSpacing), zPos)); + points.push_back(cvf::Vec3d(cellCorner + cvf::Vec2d(0.0, m_sampleSpacing), zPos)); + points.push_back(cvf::Vec3d(cellCorner + cvf::Vec2d(0.0, m_sampleSpacing), zPos)); + points.push_back(cvf::Vec3d(cellCorner, zPos)); +#endif + points.push_back(cvf::Vec3d(m_pickPoint - cvf::Vec2d(0.5 * m_sampleSpacing, 0.0), zPos)); + points.push_back(cvf::Vec3d(m_pickPoint + cvf::Vec2d(0.5 * m_sampleSpacing, 0.0), zPos)); + points.push_back(cvf::Vec3d(m_pickPoint - cvf::Vec2d(0.0, 0.5 * m_sampleSpacing), zPos)); + points.push_back(cvf::Vec3d(m_pickPoint + cvf::Vec2d(0.0, 0.5 * m_sampleSpacing), zPos)); + } + + pickPolygon = new cvf::Vec3fArray(points.size()); + + for (size_t i = 0; i < points.size(); ++i) + { + cvf::Vec3d displayPoint = displayCoordTransform->transformToDisplayCoord(points[i]); + (*pickPolygon)[i] = cvf::Vec3f(displayPoint); + } + } + return pickPolygon; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::generateResults() +{ + updateGridInformation(); + + generateGridMapping(); + + size_t nCells = numberOfCells(); + size_t nVertices = numberOfVertices(); + + m_aggregatedResults = std::vector(nCells, std::numeric_limits::infinity()); + m_aggregatedVertexResults = std::vector(nVertices, std::numeric_limits::infinity()); + int timeStep = view()->currentTimeStep(); + RimEclipseCellColors* cellColors = view()->cellResult(); + + RimEclipseResultCase* eclipseCase = this->eclipseCase(); + { + if (!cellColors->isTernarySaturationSelected()) + { + RigCaseCellResultsData* resultData = eclipseCase->results(RiaDefines::MATRIX_MODEL); + + if (isColumnResult()) + { + resultData->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "PORO"); + resultData->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "NTG"); + resultData->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DZ"); + if (m_resultAggregation == RESULTS_OIL_COLUMN || m_resultAggregation == RESULTS_HC_COLUMN) + { + resultData->findOrLoadScalarResultForTimeStep(RiaDefines::DYNAMIC_NATIVE, "SOIL", timeStep); + } + if (m_resultAggregation == RESULTS_GAS_COLUMN || m_resultAggregation == RESULTS_HC_COLUMN) + { + resultData->findOrLoadScalarResultForTimeStep(RiaDefines::DYNAMIC_NATIVE, "SGAS", timeStep); + } + } + else + { + m_resultAccessor = RigResultAccessorFactory::createFromResultDefinition(eclipseCase->eclipseCaseData(), 0, timeStep, cellColors); + + if (m_resultAccessor.isNull()) + { + m_resultAccessor = new RigHugeValResultAccessor; + } + } + +#pragma omp parallel for + for (int index = 0; index < static_cast(nCells); ++index) + { + cvf::Vec2ui ij = ijFromCellIndex(index); + m_aggregatedResults[index] = calculateValueInCell(ij.x(), ij.y()); + } + +#pragma omp parallel for + for (int index = 0; index < static_cast(nVertices); ++index) + { + cvf::Vec2ui ij = ijFromVertexIndex(index); + m_aggregatedVertexResults[index] = calculateValueAtVertex(ij.x(), ij.y()); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapProjection::ResultAggregation RimContourMapProjection::resultAggregation() const +{ + return m_resultAggregation(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::sampleSpacing() const +{ + return m_sampleSpacing; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::sampleSpacingFactor() const +{ + return m_relativeSampleSpacing(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::showContourLines() const +{ + return m_showContourLines(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimContourMapProjection::resultAggregationText() const +{ + return m_resultAggregation().uiText(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimContourMapProjection::resultDescriptionText() const +{ + QString resultText = resultAggregationText(); + if (!isColumnResult()) + { + resultText += QString(", %1").arg(view()->cellResult()->resultVariable()); + } + + return resultText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimContourMapProjection::weightingParameter() const +{ + QString parameter = "None"; + if (m_weightByParameter() && !m_weightingResult->isTernarySaturationSelected()) + { + parameter = m_weightingResult->resultVariableUiShortName(); + } + return parameter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::maxValue() const +{ + double maxV = -std::numeric_limits::infinity(); + + int nVertices = numberOfCells(); + + for (int index = 0; index < nVertices; ++index) + { + if (m_aggregatedResults[index] != std::numeric_limits::infinity()) + { + maxV = std::max(maxV, m_aggregatedResults[index]); + } + } + return maxV; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::minValue() const +{ + double minV = std::numeric_limits::infinity(); + + int nVertices = numberOfCells(); + + for (int index = 0; index < nVertices; ++index) + { + if (m_aggregatedResults[index] != std::numeric_limits::infinity()) + { + minV = std::min(minV, m_aggregatedResults[index]); + } + } + return minV; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::meanValue() const +{ + return sumAllValues() / numberOfValidCells(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::sumAllValues() const +{ + double sum = 0.0; + + int nVertices = numberOfCells(); + + for (int index = 0; index < nVertices; ++index) + { + if (m_aggregatedResults[index] != std::numeric_limits::infinity()) + { + sum += m_aggregatedResults[index]; + } + } + return sum; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2ui RimContourMapProjection::numberOfElementsIJ() const +{ + return m_mapSize; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2ui RimContourMapProjection::numberOfVerticesIJ() const +{ + cvf::Vec2ui mapSize = this->numberOfElementsIJ(); + mapSize.x() += 1u; + mapSize.y() += 1u; + return mapSize; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isColumnResult() const +{ + return m_resultAggregation() == RESULTS_OIL_COLUMN || + m_resultAggregation() == RESULTS_GAS_COLUMN || + m_resultAggregation() == RESULTS_HC_COLUMN; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::valueAtVertex(uint i, uint j) const +{ + size_t index = vertexIndexFromIJ(i, j); + if (index < numberOfVertices()) + { + return m_aggregatedVertexResults.at(index); + } + return std::numeric_limits::infinity(); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::hasResultAtVertex(uint i, uint j) const +{ + size_t index = vertexIndexFromIJ(i, j); + return m_aggregatedVertexResults[index] != std::numeric_limits::infinity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimRegularLegendConfig* RimContourMapProjection::legendConfig() const +{ + return view()->cellResult()->legendConfig(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::updateLegend() +{ + RimEclipseCellColors* cellColors = view()->cellResult(); + + if (getLegendRangeFrom3dGrid()) + { + cellColors->updateLegendData(view()->currentTimeStep(), legendConfig()); + } + else + { + double minVal = minValue(); + double maxVal = maxValue(); + + legendConfig()->setAutomaticRanges(minVal, maxVal, minVal, maxVal); + } + + if (m_resultAggregation() == RESULTS_OIL_COLUMN || + m_resultAggregation() == RESULTS_GAS_COLUMN || + m_resultAggregation() == RESULTS_HC_COLUMN) + { + legendConfig()->setTitle(QString("Map Projection\n%1").arg(m_resultAggregation().uiText())); + } + else + { + QString projectionLegendText = QString("Map Projection\n%1").arg(m_resultAggregation().uiText()); + if (weightingParameter() != "None") + { + projectionLegendText += QString("(W: %1)").arg(weightingParameter()); + } + projectionLegendText += QString("\nResult: %1").arg(cellColors->resultVariableUiShortName()); + + legendConfig()->setTitle(projectionLegendText); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +uint RimContourMapProjection::numberOfCells() const +{ + return m_mapSize.x() * m_mapSize.y(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +uint RimContourMapProjection::numberOfValidCells() const +{ + uint validCount = 0u; + for (uint i = 0; i < numberOfCells(); ++i) + { + cvf::Vec2ui ij = ijFromCellIndex(i); + if (hasResultInCell(ij.x(), ij.y())) + { + validCount++; + } + } + return validCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimContourMapProjection::numberOfVertices() const +{ + cvf::Vec2ui gridSize = numberOfVerticesIJ(); + return static_cast(gridSize.x()) * static_cast(gridSize.y()); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::updatedWeightingResult() +{ + this->updateConnectedEditors(); + this->generateResults(); + this->updateLegend(); + + RimProject* proj; + this->firstAncestorOrThisOfTypeAsserted(proj); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::checkForMapIntersection(const cvf::Vec3d& localPoint3d, cvf::Vec2d* contourMapPoint, cvf::Vec2ui* contourMapCell, double* valueAtPoint) const +{ + CVF_TIGHT_ASSERT(contourMapPoint); + CVF_TIGHT_ASSERT(valueAtPoint); + cvf::Vec3d localPos3d(localPoint3d.x(), localPoint3d.y(), 0.0); + cvf::Vec2d localPos2d(localPos3d.x(), localPos3d.y()); + cvf::Vec2ui pickedCell = ijFromLocalPos(localPos2d); + *contourMapCell = pickedCell; + + if (true || hasResultInCell(pickedCell.x(), pickedCell.y())) + { + cvf::Vec2d gridorigin(m_fullBoundingBox.min().x(), m_fullBoundingBox.min().y()); + cvf::Vec2d cellCenter = globalCellCenterPosition(pickedCell.x(), pickedCell.y()) - gridorigin; + std::array x; + x[0] = cvf::Vec3d(cellCenter + cvf::Vec2d(-m_sampleSpacing * 0.5, -m_sampleSpacing * 0.5), 0.0); + x[1] = cvf::Vec3d(cellCenter + cvf::Vec2d(m_sampleSpacing*0.5, -m_sampleSpacing * 0.5), 0.0); + x[2] = cvf::Vec3d(cellCenter + cvf::Vec2d(m_sampleSpacing*0.5, m_sampleSpacing * 0.5), 0.0); + x[3] = cvf::Vec3d(cellCenter + cvf::Vec2d(-m_sampleSpacing * 0.5, m_sampleSpacing * 0.5), 0.0); + cvf::Vec4d baryCentricCoords = cvf::GeometryTools::barycentricCoords(x[0], x[1], x[2], x[3], localPos3d); + + std::array v; + v[0] = pickedCell; + v[1] = cvf::Vec2ui(pickedCell.x() + 1u, pickedCell.y()); + v[2] = cvf::Vec2ui(pickedCell.x() + 1u, pickedCell.y() + 1u); + v[3] = cvf::Vec2ui(pickedCell.x(), pickedCell.y() + 1u); + + double value = 0.0; + for (int i = 0; i < 4; ++i) + { + value += baryCentricCoords[i] * valueAtVertex(v[i].x(), v[i].y()); + } + + *valueAtPoint = value; + *contourMapPoint = localPos2d + gridorigin; + + return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::setPickPoint(cvf::Vec2d pickedPoint) +{ + m_pickPoint = pickedPoint; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) +{ + legendConfig()->disableAllTimeStepsRange(!getLegendRangeFrom3dGrid()); + + m_weightingResult->loadResult(); + + view()->updateConnectedEditors(); + + RimProject* proj; + firstAncestorOrThisOfTypeAsserted(proj); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) +{ + if (&m_relativeSampleSpacing == field) + { + caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast(attribute); + if (myAttr) + { + myAttr->m_minimum = 0.25; + myAttr->m_maximum = 2.0; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* mainGroup = uiOrdering.addNewGroup("Projection Settings"); + mainGroup->add(&m_relativeSampleSpacing); + mainGroup->add(&m_showContourLines); + mainGroup->add(&m_resultAggregation); + + caf::PdmUiGroup* weightingGroup = uiOrdering.addNewGroup("Mean Weighting Options"); + weightingGroup->add(&m_weightByParameter); + weightingGroup->setCollapsedByDefault(true); + + m_weightByParameter.uiCapability()->setUiReadOnly(!isMeanResult()); + if (!isMeanResult()) + { + m_weightByParameter = false; + } + + if (m_weightByParameter()) + { + m_weightingResult->uiOrdering(uiConfigName, *weightingGroup); + } + + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + uiTreeOrdering.skipRemainingChildren(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::initAfterRead() +{ + legendConfig()->disableAllTimeStepsRange(!getLegendRangeFrom3dGrid()); + if (eclipseCase()) + { + m_weightingResult->setEclipseCase(eclipseCase()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::generateGridMapping() +{ + m_cellGridIdxVisibility = view()->currentTotalCellVisibility(); + + int nCells = numberOfCells(); + m_projected3dGridIndices.resize(nCells); + + const std::vector* weightingResultValues = nullptr; + if (m_weightByParameter()) + { + size_t gridScalarResultIdx = m_weightingResult->scalarResultIndex(); + if (gridScalarResultIdx != cvf::UNDEFINED_SIZE_T) + { + m_weightingResult->loadResult(); + int timeStep = 0; + if (m_weightingResult->hasDynamicResult()) + { + timeStep = view()->currentTimeStep(); + } + weightingResultValues = + &(m_weightingResult->currentGridCellResults()->cellScalarResults(gridScalarResultIdx)[timeStep]); + } + } + + if (isStraightSummationResult()) + { + for (int index = 0; index < nCells; ++index) + { + cvf::Vec2ui ij = ijFromCellIndex(index); + + cvf::Vec2d globalPos = globalCellCenterPosition(ij.x(), ij.y()); + m_projected3dGridIndices[index] = visibleCellsAndLengthInCellFrom2dPoint(globalPos, weightingResultValues); + } + } + else + { +#pragma omp parallel for + for (int index = 0; index < nCells; ++index) + { + cvf::Vec2ui ij = ijFromCellIndex(index); + + cvf::Vec2d globalPos = globalCellCenterPosition(ij.x(), ij.y()); + m_projected3dGridIndices[index] = visibleCellsAndOverlapVolumeFrom2dPoint(globalPos, weightingResultValues); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::valueInCell(uint i, uint j) const +{ + size_t index = cellIndexFromIJ(i, j); + if (index < numberOfCells()) + { + return m_aggregatedResults.at(index); + } + return std::numeric_limits::infinity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::hasResultInCell(uint i, uint j) const +{ + RimEclipseCellColors* cellColors = view()->cellResult(); + + if (cellColors->isTernarySaturationSelected()) + { + return false; + } + return !cellsAtIJ(i, j).empty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::calculateValueInCell(uint i, uint j) const +{ + if (!isColumnResult() && view()->cellResult()->scalarResultIndex() == cvf::UNDEFINED_SIZE_T) + { + return 0.0; // Special case of NONE-result. Show 0 all over to ensure we see something. + } + const std::vector>& matchingCells = cellsAtIJ(i, j); + if (!matchingCells.empty()) + { + switch (m_resultAggregation()) + { + case RESULTS_TOP_VALUE: + { + size_t cellIdx = matchingCells.front().first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + return cellValue; + } + case RESULTS_MEAN_VALUE: + { + RiaWeightedMeanCalculator calculator; + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + calculator.addValueAndWeight(cellValue, cellIdxAndWeight.second); + } + if (calculator.validAggregatedWeight()) + { + return calculator.weightedMean(); + } + return std::numeric_limits::infinity(); + } + case RESULTS_GEOM_VALUE: + { + RiaWeightedGeometricMeanCalculator calculator; + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + if (cellValue < 1.0e-8) + { + return 0.0; + } + calculator.addValueAndWeight(cellValue, cellIdxAndWeight.second); + } + if (calculator.validAggregatedWeight()) + { + return calculator.weightedMean(); + } + return std::numeric_limits::infinity(); + } + case RESULTS_HARM_VALUE: + { + RiaWeightedHarmonicMeanCalculator calculator; + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + if (std::fabs(cellValue) < 1.0e-8) + { + return 0.0; + } + calculator.addValueAndWeight(cellValue, cellIdxAndWeight.second); + } + if (calculator.validAggregatedWeight()) + { + return calculator.weightedMean(); + } + return std::numeric_limits::infinity(); + } + case RESULTS_MAX_VALUE: + { + double maxValue = -std::numeric_limits::infinity(); + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + maxValue = std::max(maxValue, cellValue); + } + return maxValue; + } + case RESULTS_MIN_VALUE: + { + double minValue = std::numeric_limits::infinity(); + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + minValue = std::min(minValue, cellValue); + } + return minValue; + } + case RESULTS_VOLUME_SUM: + case RESULTS_SUM: + { + double sum = 0.0; + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = m_resultAccessor->cellScalarGlobIdx(cellIdx); + sum += cellValue * cellIdxAndWeight.second; + } + return sum; + } + case RESULTS_OIL_COLUMN: + case RESULTS_GAS_COLUMN: + case RESULTS_HC_COLUMN: + { + double sum = 0.0; + for (auto cellIdxAndWeight : matchingCells) + { + size_t cellIdx = cellIdxAndWeight.first; + double cellValue = findColumnResult(m_resultAggregation(), cellIdx); + sum += cellValue * cellIdxAndWeight.second; + } + return sum; + } + default: + CVF_TIGHT_ASSERT(false); + } + } + return std::numeric_limits::infinity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::calculateValueAtVertex(uint vi, uint vj) const +{ + std::vector averageIs; + std::vector averageJs; + + if (vi > 0u) averageIs.push_back(vi - 1); + if (vj > 0u) averageJs.push_back(vj - 1); + if (vi < m_mapSize.x()) averageIs.push_back(vi); + if (vj < m_mapSize.y()) averageJs.push_back(vj); + + RiaWeightedMeanCalculator calc; + for (uint j : averageJs) + { + for (uint i : averageIs) + { + if (hasResultInCell(i, j)) + { + calc.addValueAndWeight(valueInCell(i, j), 1.0); + } + } + } + if (calc.validAggregatedWeight()) + { + return calc.weightedMean(); + } + return std::numeric_limits::infinity(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> RimContourMapProjection::cellsAtIJ(uint i, uint j) const +{ + size_t cellIndex = this->cellIndexFromIJ(i, j); + if (cellIndex < m_projected3dGridIndices.size()) + { + return m_projected3dGridIndices[cellIndex]; + } + return std::vector>(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> + RimContourMapProjection::visibleCellsAndOverlapVolumeFrom2dPoint(const cvf::Vec2d& globalPos2d, + const std::vector* weightingResultValues) const +{ + cvf::Vec3d top2dElementCentroid(globalPos2d, m_fullBoundingBox.max().z()); + cvf::Vec3d bottom2dElementCentroid(globalPos2d, m_fullBoundingBox.min().z()); + cvf::Vec3d planarDiagonalVector(0.5 * m_sampleSpacing, 0.5 * m_sampleSpacing, 0.0); + cvf::Vec3d topNECorner = top2dElementCentroid + planarDiagonalVector; + cvf::Vec3d bottomSWCorner = bottom2dElementCentroid - planarDiagonalVector; + + cvf::BoundingBox bbox2dElement(bottomSWCorner, topNECorner); + + std::vector allCellIndices; + m_mainGrid->findIntersectingCells(bbox2dElement, &allCellIndices); + + typedef std::map>> KLayerCellWeightMap; + KLayerCellWeightMap matchingVisibleCellsWeightPerKLayer; + + std::array hexCorners; + for (size_t globalCellIdx : allCellIndices) + { + if ((*m_cellGridIdxVisibility)[globalCellIdx]) + { + RigCell cell = m_mainGrid->globalCellArray()[globalCellIdx]; + + size_t mainGridCellIdx = cell.mainGridCellIndex(); + size_t i, j, k; + m_mainGrid->ijkFromCellIndex(mainGridCellIdx, &i, &j, &k); + + size_t localCellIdx = cell.gridLocalCellIndex(); + RigGridBase* localGrid = cell.hostGrid(); + + localGrid->cellCornerVertices(localCellIdx, hexCorners.data()); + + cvf::BoundingBox overlapBBox; + std::array overlapCorners = + RigCellGeometryTools::estimateHexOverlapWithBoundingBox(hexCorners, bbox2dElement, &overlapBBox); + + double overlapVolume = RigCellGeometryTools::calculateCellVolume(overlapCorners); + + if (overlapVolume > 0.0) + { + double weight = overlapVolume; + if (weightingResultValues) + { + const RigActiveCellInfo* activeCellInfo = + eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); + size_t cellResultIdx = activeCellInfo->cellResultIndex(globalCellIdx); + double result = std::max((*weightingResultValues)[cellResultIdx], 0.0); + if (result < 1.0e-6) + { + result = 0.0; + } + weight *= result; + } + if (weight > 0.0) + { + matchingVisibleCellsWeightPerKLayer[k].push_back(std::make_pair(globalCellIdx, weight)); + } + } + } + } + + std::vector> matchingVisibleCellsAndWeight; + for (auto kLayerCellWeight : matchingVisibleCellsWeightPerKLayer) + { + for (auto cellWeight : kLayerCellWeight.second) + { + matchingVisibleCellsAndWeight.push_back(std::make_pair(cellWeight.first, cellWeight.second)); + } + } + + return matchingVisibleCellsAndWeight; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> RimContourMapProjection::visibleCellsAndLengthInCellFrom2dPoint( + const cvf::Vec2d& globalPos2d, + const std::vector* weightingResultValues /*= nullptr*/) const +{ + cvf::Vec3d highestPoint(globalPos2d, m_fullBoundingBox.max().z()); + cvf::Vec3d lowestPoint(globalPos2d, m_fullBoundingBox.min().z()); + + cvf::BoundingBox rayBBox; + rayBBox.add(highestPoint); + rayBBox.add(lowestPoint); + + std::vector allCellIndices; + m_mainGrid->findIntersectingCells(rayBBox, &allCellIndices); + + std::map>> matchingVisibleCellsAndWeightPerKLayer; + + cvf::Vec3d hexCorners[8]; + for (size_t globalCellIdx : allCellIndices) + { + if ((*m_cellGridIdxVisibility)[globalCellIdx]) + { + RigCell cell = m_mainGrid->globalCellArray()[globalCellIdx]; + + size_t mainGridCellIdx = cell.mainGridCellIndex(); + size_t i, j, k; + m_mainGrid->ijkFromCellIndex(mainGridCellIdx, &i, &j, &k); + + size_t localCellIdx = cell.gridLocalCellIndex(); + RigGridBase* localGrid = cell.hostGrid(); + + localGrid->cellCornerVertices(localCellIdx, hexCorners); + std::vector intersections; + + if (RigHexIntersectionTools::lineHexCellIntersection(highestPoint, lowestPoint, hexCorners, 0, &intersections)) + { + double lengthInCell = + (intersections.back().m_intersectionPoint - intersections.front().m_intersectionPoint).length(); + matchingVisibleCellsAndWeightPerKLayer[k].push_back(std::make_pair(globalCellIdx, lengthInCell)); + } + } + } + + std::vector> matchingVisibleCellsAndWeight; + for (auto kLayerCellWeight : matchingVisibleCellsAndWeightPerKLayer) + { + // Make sure the sum of all weights in the same K-layer is 1. + double weightSumThisKLayer = 0.0; + for (auto cellWeight : kLayerCellWeight.second) + { + weightSumThisKLayer += cellWeight.second; + } + + for (auto cellWeight : kLayerCellWeight.second) + { + matchingVisibleCellsAndWeight.push_back(std::make_pair(cellWeight.first, cellWeight.second / weightSumThisKLayer)); + } + } + + return matchingVisibleCellsAndWeight; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimContourMapProjection::findColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const +{ + const RigCaseCellResultsData* resultData = eclipseCase()->results(RiaDefines::MATRIX_MODEL); + size_t poroResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PORO"); + size_t ntgResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "NTG"); + size_t dzResultIndex = resultData->findScalarResultIndex(RiaDefines::STATIC_NATIVE, "DZ"); + + if (poroResultIndex == cvf::UNDEFINED_SIZE_T || ntgResultIndex == cvf::UNDEFINED_SIZE_T) + { + return std::numeric_limits::infinity(); + } + + const std::vector& poroResults = resultData->cellScalarResults(poroResultIndex)[0]; + const std::vector& ntgResults = resultData->cellScalarResults(ntgResultIndex)[0]; + const std::vector& dzResults = resultData->cellScalarResults(dzResultIndex)[0]; + + const RigActiveCellInfo* activeCellInfo = eclipseCase()->eclipseCaseData()->activeCellInfo(RiaDefines::MATRIX_MODEL); + size_t cellResultIdx = activeCellInfo->cellResultIndex(cellGlobalIdx); + + if (cellResultIdx >= poroResults.size() || cellResultIdx >= ntgResults.size()) + { + return std::numeric_limits::infinity(); + } + + double poro = poroResults.at(cellResultIdx); + double ntg = ntgResults.at(cellResultIdx); + double dz = dzResults.at(cellResultIdx); + + int timeStep = view()->currentTimeStep(); + + double resultValue = 0.0; + if (resultAggregation == RESULTS_OIL_COLUMN || resultAggregation == RESULTS_HC_COLUMN) + { + size_t soilResultIndex = resultData->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SOIL"); + const std::vector& soilResults = resultData->cellScalarResults(soilResultIndex)[timeStep]; + if (cellResultIdx < soilResults.size()) + { + resultValue = soilResults.at(cellResultIdx); + } + } + if (resultAggregation == RESULTS_GAS_COLUMN || resultAggregation == RESULTS_HC_COLUMN) + { + size_t sgasResultIndex = resultData->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SGAS"); + const std::vector& sgasResults = resultData->cellScalarResults(sgasResultIndex)[timeStep]; + if (cellResultIdx < sgasResults.size()) + { + resultValue += sgasResults.at(cellResultIdx); + } + } + + return resultValue * poro * ntg * dz; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isMeanResult() const +{ + return m_resultAggregation() == RESULTS_MEAN_VALUE || m_resultAggregation() == RESULTS_HARM_VALUE || + m_resultAggregation() == RESULTS_GEOM_VALUE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isSummationResult() const +{ + return isStraightSummationResult() || m_resultAggregation() == RESULTS_VOLUME_SUM; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isStraightSummationResult() const +{ + return isStraightSummationResult(m_resultAggregation()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::isStraightSummationResult(ResultAggregationEnum aggregationType) +{ + return aggregationType == RESULTS_OIL_COLUMN || aggregationType == RESULTS_GAS_COLUMN || + aggregationType == RESULTS_HC_COLUMN || aggregationType == RESULTS_SUM; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimContourMapProjection::cellIndexFromIJ(uint i, uint j) const +{ + CVF_ASSERT(i < m_mapSize.x()); + CVF_ASSERT(j < m_mapSize.y()); + + return i + j * m_mapSize.x(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimContourMapProjection::vertexIndexFromIJ(uint i, uint j) const +{ + return i + j * (m_mapSize.x() + 1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2ui RimContourMapProjection::ijFromVertexIndex(size_t gridIndex) const +{ + cvf::Vec2ui gridSize = numberOfVerticesIJ(); + + uint quotientX = static_cast(gridIndex) / gridSize.x(); + uint remainderX = static_cast(gridIndex) % gridSize.x(); + + return cvf::Vec2ui(remainderX, quotientX); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2ui RimContourMapProjection::ijFromCellIndex(size_t cellIndex) const +{ + CVF_TIGHT_ASSERT(cellIndex < numberOfCells()); + + uint quotientX = static_cast(cellIndex) / m_mapSize.x(); + uint remainderX = static_cast(cellIndex) % m_mapSize.x(); + + return cvf::Vec2ui(remainderX, quotientX); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2ui RimContourMapProjection::ijFromLocalPos(const cvf::Vec2d& localPos2d) const +{ + uint i = localPos2d.x() / m_sampleSpacing; + uint j = localPos2d.y() / m_sampleSpacing; + return cvf::Vec2ui(i, j); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2d RimContourMapProjection::globalCellCenterPosition(uint i, uint j) const +{ + cvf::Vec3d gridExtent = m_fullBoundingBox.extent(); + cvf::Vec2d origin(m_fullBoundingBox.min().x(), m_fullBoundingBox.min().y()); + + cvf::Vec2d cellCorner = origin + cvf::Vec2d((i * gridExtent.x()) / (m_mapSize.x()), (j * gridExtent.y()) / (m_mapSize.y())); + + return cellCorner + cvf::Vec2d(m_sampleSpacing * 0.5, m_sampleSpacing * 0.5); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimContourMapProjection::xVertexPositions() const +{ + double gridExtent = m_fullBoundingBox.extent().x(); + double origin = m_fullBoundingBox.min().x(); + + cvf::Vec2ui gridSize = numberOfVerticesIJ(); + std::vector positions; + positions.reserve(gridSize.x()); + for (uint i = 0; i < gridSize.x(); ++i) + { + positions.push_back(origin + (i * gridExtent) / (gridSize.x() - 1)); + } + + return positions; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimContourMapProjection::yVertexPositions() const +{ + double gridExtent = m_fullBoundingBox.extent().y(); + double origin = m_fullBoundingBox.min().y(); + + cvf::Vec2ui gridSize = numberOfVerticesIJ(); + std::vector positions; + positions.reserve(gridSize.y()); + for (uint j = 0; j < gridSize.y(); ++j) + { + positions.push_back(origin + (j * gridExtent) / (gridSize.y() - 1)); + } + + return positions; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimContourMapProjection::getLegendRangeFrom3dGrid() const +{ + if (isMeanResult()) + { + return true; + } + else if (m_resultAggregation == RESULTS_TOP_VALUE) + { + return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapProjection::updateGridInformation() +{ + m_mainGrid = eclipseCase()->eclipseCaseData()->mainGrid(); + m_sampleSpacing = m_relativeSampleSpacing * m_mainGrid->characteristicIJCellSize(); + m_fullBoundingBox = eclipseCase()->activeCellsBoundingBox(); + m_mapSize = calculateMapSize(); + + // Re-jig max point to be an exact multiple of cell size + cvf::Vec3d minPoint = m_fullBoundingBox.min(); + cvf::Vec3d maxPoint = m_fullBoundingBox.max(); + maxPoint.x() = minPoint.x() + m_mapSize.x() * m_sampleSpacing; + maxPoint.y() = minPoint.y() + m_mapSize.y() * m_sampleSpacing; + m_fullBoundingBox = cvf::BoundingBox(minPoint, maxPoint); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec2ui RimContourMapProjection::calculateMapSize() const +{ + cvf::Vec3d gridExtent = m_fullBoundingBox.extent(); + + uint projectionSizeX = static_cast(std::ceil(gridExtent.x() / m_sampleSpacing)); + uint projectionSizeY = static_cast(std::ceil(gridExtent.y() / m_sampleSpacing)); + + return cvf::Vec2ui(projectionSizeX, projectionSizeY); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseResultCase* RimContourMapProjection::eclipseCase() const +{ + RimEclipseResultCase* eclipseCase = nullptr; + firstAncestorOrThisOfType(eclipseCase); + return eclipseCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapView* RimContourMapProjection::view() const +{ + RimContourMapView* view = nullptr; + firstAncestorOrThisOfTypeAsserted(view); + return view; +} diff --git a/ApplicationCode/ProjectDataModel/RimContourMapProjection.h b/ApplicationCode/ProjectDataModel/RimContourMapProjection.h new file mode 100644 index 0000000000..05c5fbedc9 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimContourMapProjection.h @@ -0,0 +1,180 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// Copyright (C) Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimCheckableNamedObject.h" +#include "RimRegularLegendConfig.h" + +#include "cafDisplayCoordTransform.h" +#include "cafPdmChildField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +#include "cvfBoundingBox.h" +#include "cvfGeometryBuilderFaceList.h" +#include "cvfVector2.h" + +class RigMainGrid; +class RigResultAccessor; +class RimContourMapView; +class RimEclipseResultCase; +class RimEclipseResultDefinition; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimContourMapProjection : public RimCheckableNamedObject +{ + CAF_PDM_HEADER_INIT; +public: + enum ResultAggregationEnum + { + RESULTS_TOP_VALUE, + RESULTS_MEAN_VALUE, + RESULTS_GEOM_VALUE, + RESULTS_HARM_VALUE, + RESULTS_MIN_VALUE, + RESULTS_MAX_VALUE, + RESULTS_VOLUME_SUM, + RESULTS_SUM, + RESULTS_OIL_COLUMN, + RESULTS_GAS_COLUMN, + RESULTS_HC_COLUMN + }; + typedef caf::AppEnum ResultAggregation; + typedef std::vector> ContourPolygons; + + RimContourMapProjection(); + ~RimContourMapProjection() override; + + void generateVertices(cvf::Vec3fArray* vertices, const caf::DisplayCoordTransform* displayCoordTransform); + ContourPolygons generateContourPolygons(const caf::DisplayCoordTransform* displayCoordTransform); + cvf::ref generatePickPointPolygon(const caf::DisplayCoordTransform* displayCoordTransform); + void generateResults(); + + ResultAggregation resultAggregation() const; + double sampleSpacing() const; + double sampleSpacingFactor() const; + bool showContourLines() const; + + QString resultAggregationText() const; + QString resultDescriptionText() const; + QString weightingParameter() const; + + double maxValue() const; + double minValue() const; + double meanValue() const; + double sumAllValues() const; + + cvf::Vec2ui numberOfElementsIJ() const; + cvf::Vec2ui numberOfVerticesIJ() const; + + bool isColumnResult() const; + + double valueAtVertex(uint i, uint j) const; + bool hasResultAtVertex(uint i, uint j) const; + + RimRegularLegendConfig* legendConfig() const; + void updateLegend(); + + uint numberOfCells() const; + uint numberOfValidCells() const; + size_t numberOfVertices() const; + + void updatedWeightingResult(); + + bool checkForMapIntersection(const cvf::Vec3d& localPoint3d, cvf::Vec2d* contourMapPoint, cvf::Vec2ui* contourMapCell, double* valueAtPoint) const; + void setPickPoint(cvf::Vec2d pickedPoint); + +protected: + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void initAfterRead() override; + +private: + typedef std::pair CellIndexAndResult; + +private: + void generateGridMapping(); + + double valueInCell(uint i, uint j) const; + bool hasResultInCell(uint i, uint j) const; + + double calculateValueInCell(uint i, uint j) const; + double calculateValueAtVertex(uint i, uint j) const; + + + std::vector cellsAtIJ(uint i, uint j) const; + + std::vector visibleCellsAndOverlapVolumeFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector* weightingResultValues = nullptr) const; + std::vector visibleCellsAndLengthInCellFrom2dPoint(const cvf::Vec2d& globalPos2d, const std::vector* weightingResultValues = nullptr) const; + double findColumnResult(ResultAggregation resultAggregation, size_t cellGlobalIdx) const; + + bool isMeanResult() const; + bool isSummationResult() const; + bool isStraightSummationResult() const; + static bool isStraightSummationResult(ResultAggregationEnum aggregationType); + + size_t cellIndexFromIJ(uint i, uint j) const; + size_t vertexIndexFromIJ(uint i, uint j) const; + + cvf::Vec2ui ijFromVertexIndex(size_t gridIndex) const; + cvf::Vec2ui ijFromCellIndex(size_t mapIndex) const; + cvf::Vec2ui ijFromLocalPos(const cvf::Vec2d& localPos2d) const; + cvf::Vec2d globalCellCenterPosition(uint i, uint j) const; + + std::vector xVertexPositions() const; + std::vector yVertexPositions() const; + + bool getLegendRangeFrom3dGrid() const; + void updateGridInformation(); + cvf::Vec2ui calculateMapSize() const; + + RimEclipseResultCase* eclipseCase() const; + RimContourMapView* view() const; + +protected: + caf::PdmField m_relativeSampleSpacing; + caf::PdmField m_resultAggregation; + caf::PdmField m_showContourLines; + caf::PdmField m_weightByParameter; + caf::PdmChildField m_weightingResult; + cvf::ref m_cellGridIdxVisibility; + + std::vector m_aggregatedResults; + std::vector m_aggregatedVertexResults; + + std::vector>> m_projected3dGridIndices; + + cvf::ref m_resultAccessor; + + cvf::Vec2d m_pickPoint; + + caf::PdmPointer m_eclipseCase; + cvf::ref m_mainGrid; + cvf::Vec2ui m_mapSize; + cvf::BoundingBox m_fullBoundingBox; + double m_sampleSpacing; +}; diff --git a/ApplicationCode/ProjectDataModel/RimContourMapView.cpp b/ApplicationCode/ProjectDataModel/RimContourMapView.cpp new file mode 100644 index 0000000000..f89151e80d --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimContourMapView.cpp @@ -0,0 +1,383 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimContourMapView.h" + +#include "RivContourMapProjectionPartMgr.h" +#include "RiuViewer.h" + +#include "Rim3dOverlayInfoConfig.h" +#include "RimCase.h" +#include "RimCellRangeFilterCollection.h" +#include "RimContourMapNameConfig.h" +#include "RimContourMapProjection.h" +#include "RimEclipseCellColors.h" +#include "RimEclipseFaultColors.h" +#include "RimEclipsePropertyFilterCollection.h" +#include "RimFaultInViewCollection.h" +#include "RimGridCollection.h" +#include "RimSimWellInViewCollection.h" + +#include "cafPdmUiTreeOrdering.h" + +#include "cvfCamera.h" +#include "cvfModelBasicList.h" +#include "cvfPart.h" +#include "cvfScene.h" + +CAF_PDM_SOURCE_INIT(RimContourMapView, "RimContourMapView"); + +const cvf::Mat4d defaultViewMatrix(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 1000, + 0, 0, 0, 1); + +RimContourMapView::RimContourMapView() +{ + CAF_PDM_InitObject("Contour Map View", ":/2DMap16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_contourMapProjection, "ContourMapProjection", "Contour Map Projection", "", "", ""); + m_contourMapProjection = new RimContourMapProjection(); + + CAF_PDM_InitField(&m_showAxisLines, "ShowAxisLines", true, "Show Axis Lines", "", "", ""); + + m_gridCollection->setActive(false); // This is also not added to the tree view, so cannot be enabled. + setFaultVisParameters(); + + CAF_PDM_InitFieldNoDefault(&m_nameConfig, "NameConfig", "", "", "", ""); + m_nameConfig = new RimContourMapNameConfig(this); + + m_contourMapProjectionPartMgr = new RivContourMapProjectionPartMgr(contourMapProjection(), this); + + ((RiuViewerToViewInterface*)this)->setCameraPosition(defaultViewMatrix); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapProjection* RimContourMapView::contourMapProjection() const +{ + return m_contourMapProjection().p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimContourMapView::createAutoName() const +{ + QStringList autoName; + + if (!m_nameConfig->customName().isEmpty()) + { + autoName.push_back(m_nameConfig->customName()); + } + + QStringList generatedAutoTags; + + RimCase* ownerCase = nullptr; + this->firstAncestorOrThisOfTypeAsserted(ownerCase); + + if (m_nameConfig->addCaseName()) + { + generatedAutoTags.push_back(ownerCase->caseUserDescription()); + } + + if (m_nameConfig->addAggregationType()) + { + generatedAutoTags.push_back(contourMapProjection()->resultAggregationText()); + } + + if (m_nameConfig->addProperty() && !contourMapProjection()->isColumnResult()) + { + generatedAutoTags.push_back(cellResult()->resultVariable()); + } + + if (m_nameConfig->addSampleSpacing()) + { + generatedAutoTags.push_back(QString("%1").arg(contourMapProjection()->sampleSpacingFactor(), 3, 'f', 2)); + } + + if (!generatedAutoTags.empty()) + { + autoName.push_back(generatedAutoTags.join(", ")); + } + return autoName.join(": "); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::initAfterRead() +{ + m_gridCollection->setActive(false); // This is also not added to the tree view, so cannot be enabled. + disablePerspectiveProjectionField(); + setShowGridBox(false); + meshMode.setValue(NO_MESH); + surfaceMode.setValue(FAULTS); + setFaultVisParameters(); + scheduleCreateDisplayModelAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::createDisplayModel() +{ + RimEclipseView::createDisplayModel(); + + if (!this->isTimeStepDependentDataVisible()) + { + // Need to add geometry even if it hasn't happened during dynamic time step update. + updateGeometry(); + } + + if (this->viewer()->mainCamera()->viewMatrix() == defaultViewMatrix) + { + this->zoomAll(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + caf::PdmUiGroup* viewGroup = uiOrdering.addNewGroup("Viewer"); + viewGroup->add(this->userDescriptionField()); + viewGroup->add(this->backgroundColorField()); + viewGroup->add(&m_showAxisLines); + + caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup("Contour Map Name"); + m_nameConfig->uiOrdering(uiConfigName, *nameGroup); + + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + uiTreeOrdering.add(m_overlayInfoConfig()); + uiTreeOrdering.add(m_contourMapProjection); + uiTreeOrdering.add(cellResult()); + cellResult()->uiCapability()->setUiReadOnly(m_contourMapProjection->isColumnResult()); + uiTreeOrdering.add(wellCollection()); + uiTreeOrdering.add(faultCollection()); + uiTreeOrdering.add(m_rangeFilterCollection()); + uiTreeOrdering.add(nativePropertyFilterCollection()); + + uiTreeOrdering.skipRemainingChildren(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::updateCurrentTimeStep() +{ + static_cast(nativePropertyFilterCollection())->updateFromCurrentTimeStep(); + updateGeometry(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::updateGeometry() +{ + this->updateVisibleGeometriesAndCellColors(); + + if (m_contourMapProjection->isChecked()) + { + m_contourMapProjection->generateResults(); + } + updateLegends(); // To make sure the scalar mappers are set up correctly + + appendWellsAndFracturesToModel(); + + appendContourMapProjectionToModel(); + + appendPickPointVisToModel(); + + if (m_overlayInfoConfig->isActive()) + { + m_overlayInfoConfig()->update3DInfo(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::setFaultVisParameters() +{ + faultCollection()->setShowFaultsOutsideFilter(false); + faultCollection()->showOppositeFaultFaces = true; + faultCollection()->faultResult = RimFaultInViewCollection::FAULT_NO_FACE_CULLING; + faultResultSettings()->showCustomFaultResult = true; + faultResultSettings()->customFaultResult()->setResultVariable("None"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::appendContourMapProjectionToModel() +{ + if (m_viewer && m_contourMapProjection->isChecked()) + { + cvf::Scene* frameScene = m_viewer->frame(m_currentTimeStep); + if (frameScene) + { + cvf::String name = "ContourMapProjection"; + this->removeModelByName(frameScene, name); + + cvf::ref contourMapProjectionModelBasicList = new cvf::ModelBasicList; + contourMapProjectionModelBasicList->setName(name); + + cvf::ref transForm = this->displayCoordTransform(); + + m_contourMapProjectionPartMgr->appendProjectionToModel(contourMapProjectionModelBasicList.p(), transForm.p()); + contourMapProjectionModelBasicList->updateBoundingBoxesRecursive(); + frameScene->addModel(contourMapProjectionModelBasicList.p()); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::appendPickPointVisToModel() +{ + if (m_viewer && m_contourMapProjection->isChecked()) + { + cvf::Scene* frameScene = m_viewer->frame(m_currentTimeStep); + if (frameScene) + { + cvf::String name = "ContourMapPickPoint"; + this->removeModelByName(frameScene, name); + + cvf::ref contourMapProjectionModelBasicList = new cvf::ModelBasicList; + contourMapProjectionModelBasicList->setName(name); + + cvf::ref transForm = this->displayCoordTransform(); + + m_contourMapProjectionPartMgr->appendPickPointVisToModel(contourMapProjectionModelBasicList.p(), transForm.p()); + contourMapProjectionModelBasicList->updateBoundingBoxesRecursive(); + frameScene->addModel(contourMapProjectionModelBasicList.p()); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::updateLegends() +{ + if (m_viewer) + { + m_viewer->removeAllColorLegends(); + + if (m_contourMapProjection && m_contourMapProjection->isChecked()) + { + RimRegularLegendConfig* projectionLegend = m_contourMapProjection->legendConfig(); + if (projectionLegend) + { + m_contourMapProjection->updateLegend(); + if (projectionLegend->showLegend()) + { + m_viewer->addColorLegendToBottomLeftCorner(projectionLegend->titledOverlayFrame()); + } + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::updateViewWidgetAfterCreation() +{ + if (m_viewer) + { + m_viewer->showAxisCross(false); + m_viewer->showEdgeTickMarksXY(true, m_showAxisLines()); + m_viewer->enableNavigationRotation(false); + } + + Rim3dView::updateViewWidgetAfterCreation(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::updateViewFollowingRangeFilterUpdates() +{ + m_contourMapProjection->setCheckState(true); + scheduleCreateDisplayModelAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::onLoadDataAndUpdate() +{ + RimEclipseView::onLoadDataAndUpdate(); + if (m_viewer) + { + m_viewer->setView(cvf::Vec3d(0, 0, -1), cvf::Vec3d(0, 1, 0)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + RimEclipseView::fieldChangedByUi(changedField, oldValue, newValue); + + if (changedField == &m_showAxisLines) + { + m_viewer->showEdgeTickMarksXY(true, m_showAxisLines()); + scheduleCreateDisplayModelAndRedraw(); + } + else if (changedField == backgroundColorField()) + { + scheduleCreateDisplayModelAndRedraw(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimContourMapView::userDescriptionField() +{ + return m_nameConfig()->nameField(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RimContourMapView::allVisibleFaultGeometryTypes() const +{ + std::set faultGeoTypes; + // Normal eclipse views always shows faults for active and visible eclipse cells. + if (faultCollection()->showFaultCollection()) + { + faultGeoTypes = RimEclipseView::allVisibleFaultGeometryTypes(); + } + return faultGeoTypes; +} diff --git a/ApplicationCode/ProjectDataModel/RimContourMapView.h b/ApplicationCode/ProjectDataModel/RimContourMapView.h new file mode 100644 index 0000000000..aa35cdd7ac --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimContourMapView.h @@ -0,0 +1,62 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimEclipseView.h" +#include "RimNameConfig.h" + +class RimContourMapNameConfig; +class RivContourMapProjectionPartMgr; + +class RimContourMapView : public RimEclipseView, public RimNameConfigHolderInterface +{ + CAF_PDM_HEADER_INIT; +public: + RimContourMapView(); + RimContourMapProjection* contourMapProjection() const; + + QString createAutoName() const override; + +protected: + void initAfterRead() override; + void createDisplayModel() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void updateCurrentTimeStep() override; + void updateGeometry(); + void setFaultVisParameters(); + void appendContourMapProjectionToModel(); + void appendPickPointVisToModel(); + void updateLegends() override; + void updateViewWidgetAfterCreation() override; + void updateViewFollowingRangeFilterUpdates() override; + void onLoadDataAndUpdate() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + + caf::PdmFieldHandle* userDescriptionField() override; + + virtual std::set allVisibleFaultGeometryTypes() const override; + +private: + cvf::ref m_contourMapProjectionPartMgr; + caf::PdmChildField m_contourMapProjection; + caf::PdmField m_showAxisLines; + caf::PdmChildField m_nameConfig; +}; + diff --git a/ApplicationCode/ProjectDataModel/RimContourMapViewCollection.cpp b/ApplicationCode/ProjectDataModel/RimContourMapViewCollection.cpp new file mode 100644 index 0000000000..abeaeda2b6 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimContourMapViewCollection.cpp @@ -0,0 +1,42 @@ +#include "RimContourMapViewCollection.h" + +#include "RimContourMapView.h" +#include "RimCase.h" + +CAF_PDM_SOURCE_INIT(RimContourMapViewCollection, "Eclipse2dViewCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapViewCollection::RimContourMapViewCollection() +{ + CAF_PDM_InitObject("Contour Maps", ":/2DMaps16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_contourMapViews, "EclipseViews", "Contour Maps", ":/CrossSection16x16.png", "", ""); + m_contourMapViews.uiCapability()->setUiTreeHidden(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapViewCollection::~RimContourMapViewCollection() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimContourMapViewCollection::views() +{ + return m_contourMapViews.childObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimContourMapViewCollection::push_back(RimContourMapView* contourMap) +{ + m_contourMapViews.push_back(contourMap); +} + diff --git a/ApplicationCode/ProjectDataModel/RimContourMapViewCollection.h b/ApplicationCode/ProjectDataModel/RimContourMapViewCollection.h new file mode 100644 index 0000000000..741cfa3b5f --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimContourMapViewCollection.h @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" +#include "cafPdmChildArrayField.h" + +class RimContourMapView; + +class RimContourMapViewCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimContourMapViewCollection(); + ~RimContourMapViewCollection() override; + + std::vector views(); + void push_back(RimContourMapView* contourMap); +private: + caf::PdmChildArrayField m_contourMapViews; +}; + + + diff --git a/ApplicationCode/ProjectDataModel/RimDataSourceSteppingTools.cpp b/ApplicationCode/ProjectDataModel/RimDataSourceSteppingTools.cpp new file mode 100644 index 0000000000..36046de1bb --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimDataSourceSteppingTools.cpp @@ -0,0 +1,46 @@ +#include "RimDataSourceSteppingTools.h" + +#include "cvfAssert.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDataSourceSteppingTools::modifyCurrentIndex(caf::PdmValueField* valueField, const QList& options, int indexOffset) +{ + if (valueField && !options.isEmpty()) + { + QVariant currentValue = valueField->toQVariant(); + caf::PdmPointer currentHandle = currentValue.value>(); + int currentIndex = -1; + for (int i = 0; i < options.size(); i++) + { + QVariant optionValue = options[i].value(); + // First try pointer variety. They are not supported by QVariant::operator== + caf::PdmPointer optionHandle = optionValue.value>(); + if (optionHandle) + { + if (currentHandle == optionHandle) + { + currentIndex = i; + } + } + else if (currentValue == optionValue) + { + currentIndex = i; + } + } + + if (currentIndex == -1) + { + currentIndex = 0; + } + + int nextIndex = currentIndex + indexOffset; + if (nextIndex < options.size() && nextIndex > -1) + { + QVariant newValue = options[nextIndex].value(); + valueField->setFromQVariant(newValue); + valueField->uiCapability()->notifyFieldChanged(currentValue, newValue); + } + } +} diff --git a/ApplicationCode/ProjectDataModel/RimDataSourceSteppingTools.h b/ApplicationCode/ProjectDataModel/RimDataSourceSteppingTools.h new file mode 100644 index 0000000000..a9b4131946 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimDataSourceSteppingTools.h @@ -0,0 +1,32 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + + +#include "cafPdmField.h" +#include "cafPdmObject.h" + +//================================================================================================== +/// +//================================================================================================== +class RimDataSourceSteppingTools +{ +public: + static void modifyCurrentIndex(caf::PdmValueField* valueField, const QList& options, int indexOffset); +}; diff --git a/ApplicationCode/ProjectDataModel/RimDialogData.cpp b/ApplicationCode/ProjectDataModel/RimDialogData.cpp index 79138b2a90..f72b16766b 100644 --- a/ApplicationCode/ProjectDataModel/RimDialogData.cpp +++ b/ApplicationCode/ProjectDataModel/RimDialogData.cpp @@ -18,8 +18,14 @@ #include "RimDialogData.h" +#include "RimMockModelSettings.h" + #include "ExportCommands/RicExportCarfinUi.h" #include "CompletionExportCommands/RicExportCompletionDataSettingsUi.h" +#include "FractureCommands/RicCreateMultipleFracturesUi.h" +#include "HoloLensCommands/RicHoloLensExportToFolderUi.h" +#include "ExportCommands/RicExportWellPathsUi.h" +#include "ExportCommands/RicExportLgrUi.h" CAF_PDM_SOURCE_INIT(RimDialogData, "RimDialogData"); @@ -35,6 +41,29 @@ RimDialogData::RimDialogData() CAF_PDM_InitFieldNoDefault(&m_exportCompletionData, "ExportCompletionData", "Export Completion Data", "", "", ""); m_exportCompletionData = new RicExportCompletionDataSettingsUi(); + + CAF_PDM_InitFieldNoDefault(&m_multipleFractionsData, "MultipleFractionsData", "Multiple Fractures Data", "", "", ""); + m_multipleFractionsData = new RiuCreateMultipleFractionsUi(); + + CAF_PDM_InitFieldNoDefault(&m_holoLenseExportToFolderData, "HoloLenseExportToFolderData", "Holo Lens Export To Folder Data", "", "", ""); + m_holoLenseExportToFolderData = new RicHoloLensExportToFolderUi(); + + CAF_PDM_InitFieldNoDefault(&m_exportWellPathsData, "ExportwellPathsData", "Export Well Paths Data", "", "", ""); + m_exportWellPathsData = new RicExportWellPathsUi(); + + CAF_PDM_InitFieldNoDefault(&m_exportLgrData, "ExportLgr", "LGR Export", "", "", ""); + m_exportLgrData = new RicExportLgrUi(); + + CAF_PDM_InitFieldNoDefault(&m_mockModelSettings, "MockModelSettings", "Mock Model Settings", "", "", ""); + m_mockModelSettings = new RimMockModelSettings(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDialogData::clearProjectSpecificData() +{ + m_multipleFractionsData->resetValues(); } //-------------------------------------------------------------------------------------------------- @@ -70,3 +99,43 @@ RicExportCompletionDataSettingsUi* RimDialogData::exportCompletionData() const return m_exportCompletionData; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuCreateMultipleFractionsUi* RimDialogData::multipleFractionsData() const +{ + return m_multipleFractionsData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicHoloLensExportToFolderUi* RimDialogData::holoLensExportToFolderData() const +{ + return m_holoLenseExportToFolderData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicExportWellPathsUi* RimDialogData::wellPathsExportData() const +{ + return m_exportWellPathsData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RicExportLgrUi* RimDialogData::exportLgrData() const +{ + return m_exportLgrData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimMockModelSettings* RimDialogData::mockModelSettings() const +{ + return m_mockModelSettings; +} + diff --git a/ApplicationCode/ProjectDataModel/RimDialogData.h b/ApplicationCode/ProjectDataModel/RimDialogData.h index a03131c48d..50c1cdea8a 100644 --- a/ApplicationCode/ProjectDataModel/RimDialogData.h +++ b/ApplicationCode/ProjectDataModel/RimDialogData.h @@ -1,47 +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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "cafPdmObject.h" #include "cafPdmChildField.h" +#include "cafPdmObject.h" class RicExportCarfinUi; class RicExportCompletionDataSettingsUi; +class RiuCreateMultipleFractionsUi; +class RicHoloLensExportToFolderUi; +class RicExportWellPathsUi; +class RicExportLgrUi; +class RimMockModelSettings; //================================================================================================== -/// -/// +/// +/// This class is used as a container for UI specific data that is not part of the project tree view +/// Example of use is to store export settings for complex export dialogs or settings for advanced +/// creation of multiple objects +/// +/// The data in this object will be stored in the project file, as RimDialogData is a child object of +/// RimProject +/// //================================================================================================== class RimDialogData : public caf::PdmObject { - CAF_PDM_HEADER_INIT; + CAF_PDM_HEADER_INIT; public: RimDialogData(); - + + void clearProjectSpecificData(); + RicExportCarfinUi* exportCarfin() const; QString exportCarfinDataAsString() const; void setExportCarfinDataFromString(const QString& data); RicExportCompletionDataSettingsUi* exportCompletionData() const; + RiuCreateMultipleFractionsUi* multipleFractionsData() const; + RicHoloLensExportToFolderUi* holoLensExportToFolderData() const; + RicExportWellPathsUi* wellPathsExportData() const; + RicExportLgrUi* exportLgrData() const; + RimMockModelSettings* mockModelSettings() const; + private: - caf::PdmChildField m_exportCarfin; - caf::PdmChildField m_exportCompletionData; + caf::PdmChildField m_exportCarfin; + caf::PdmChildField m_exportCompletionData; + caf::PdmChildField m_multipleFractionsData; + caf::PdmChildField m_holoLenseExportToFolderData; + caf::PdmChildField m_exportWellPathsData; + caf::PdmChildField m_exportLgrData; + caf::PdmChildField m_mockModelSettings; }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp index 04e6ea9c39..6c46324d5b 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.cpp @@ -3,17 +3,17 @@ // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -22,10 +22,11 @@ #include "RiaApplication.h" #include "RiaColorTables.h" +#include "RiaFieldHandleTools.h" #include "RiaPreferences.h" -#include "CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h" #include "CompletionExportCommands/RicExportCompletionDataSettingsUi.h" +#include "CompletionExportCommands/RicWellPathExportCompletionDataFeatureImpl.h" #include "RigActiveCellInfo.h" #include "RigCaseCellResultsData.h" @@ -34,6 +35,9 @@ #include "RigSimWellData.h" #include "RigVirtualPerforationTransmissibilities.h" +#include "RimContourMapView.h" +#include "RimContourMapViewCollection.h" +#include "Rim2dIntersectionView.h" #include "Rim2dIntersectionViewCollection.h" #include "RimCaseCollection.h" #include "RimCellEdgeColors.h" @@ -46,12 +50,13 @@ #include "RimFlowCharacteristicsPlot.h" #include "RimFlowPlotCollection.h" #include "RimFormationNames.h" +#include "RimGridCollection.h" #include "RimIntersectionCollection.h" -#include "RimRegularLegendConfig.h" #include "RimMainPlotCollection.h" #include "RimOilField.h" #include "RimPerforationCollection.h" #include "RimProject.h" +#include "RimRegularLegendConfig.h" #include "RimReservoirCellResultsStorage.h" #include "RimStimPlanColors.h" #include "RimSummaryCase.h" @@ -67,44 +72,45 @@ #include "RimWellPathCollection.h" #include "cafPdmDocument.h" -#include "cafProgressInfo.h" #include "cafPdmUiTreeOrdering.h" +#include "cafProgressInfo.h" +#include +#include #include #include -#include -#include - CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimEclipseCase, "RimReservoir"); //------------------------------------------------------------------------------------------------ -/// +/// //-------------------------------------------------------------------------------------------------- -RimEclipseCase::RimEclipseCase() +RimEclipseCase::RimEclipseCase() { - CAF_PDM_InitFieldNoDefault(&reservoirViews, "ReservoirViews", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&reservoirViews, "ReservoirViews", "", "", "", ""); reservoirViews.uiCapability()->setUiHidden(true); - CAF_PDM_InitFieldNoDefault(&m_matrixModelResults, "MatrixModelResults", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_matrixModelResults, "MatrixModelResults", "", "", "", ""); m_matrixModelResults.uiCapability()->setUiHidden(true); - CAF_PDM_InitFieldNoDefault(&m_fractureModelResults, "FractureModelResults", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_fractureModelResults, "FractureModelResults", "", "", "", ""); m_fractureModelResults.uiCapability()->setUiHidden(true); - CAF_PDM_InitField(&flipXAxis, "FlipXAxis", false, "Flip X Axis", "", "", ""); - CAF_PDM_InitField(&flipYAxis, "FlipYAxis", false, "Flip Y Axis", "", "", ""); + CAF_PDM_InitField(&m_flipXAxis, "FlipXAxis", false, "Flip X Axis", "", "", ""); + CAF_PDM_InitField(&m_flipYAxis, "FlipYAxis", false, "Flip Y Axis", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_filesContainingFaultsSemColSeparated, "CachedFileNamesContainingFaults", "", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_filesContainingFaultsSemColSeparated, "CachedFileNamesContainingFaults", "", "", "", ""); m_filesContainingFaultsSemColSeparated.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_contourMapCollection, "ContourMaps", "2d Contour Maps", "", "", ""); + m_contourMapCollection = new RimContourMapViewCollection; + m_contourMapCollection.uiCapability()->setUiTreeHidden(true); + // Obsolete fields - CAF_PDM_InitFieldNoDefault(&m_filesContainingFaults_OBSOLETE, "FilesContainingFaults", "", "", "", ""); - m_filesContainingFaults_OBSOLETE.xmlCapability()->setIOWritable(false); - m_filesContainingFaults_OBSOLETE.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_filesContainingFaults_OBSOLETE, "FilesContainingFaults", "", "", "", ""); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_filesContainingFaults_OBSOLETE); - CAF_PDM_InitField(&m_caseName_OBSOLETE, "CaseName", QString(), "Obsolete", "", "" ,""); - m_caseName_OBSOLETE.xmlCapability()->setIOWritable(false); - m_caseName_OBSOLETE.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&m_caseName_OBSOLETE, "CaseName", QString(), "Obsolete", "", "", ""); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_caseName_OBSOLETE); // Init @@ -116,11 +122,11 @@ RimEclipseCase::RimEclipseCase() m_fractureModelResults.uiCapability()->setUiHidden(true); m_fractureModelResults.uiCapability()->setUiTreeChildrenHidden(true); - this->setReservoirData( nullptr ); + this->setReservoirData(nullptr); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimEclipseCase::~RimEclipseCase() { @@ -150,7 +156,7 @@ RimEclipseCase::~RimEclipseCase() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RigEclipseCaseData* RimEclipseCase::eclipseCaseData() { @@ -166,29 +172,29 @@ const RigEclipseCaseData* RimEclipseCase::eclipseCaseData() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::Color3f RimEclipseCase::defaultWellColor(const QString& wellName) { - if ( m_wellToColorMap.empty() ) + if (m_wellToColorMap.empty()) { - const caf::ColorTable& colorTable = RiaColorTables::wellsPaletteColors(); - cvf::Color3ubArray wellColors = colorTable.color3ubArray(); - cvf::Color3ubArray interpolatedWellColors = wellColors; + const caf::ColorTable& colorTable = RiaColorTables::wellsPaletteColors(); + cvf::Color3ubArray wellColors = colorTable.color3ubArray(); + cvf::Color3ubArray interpolatedWellColors = wellColors; const cvf::Collection& simWellData = this->eclipseCaseData()->wellResults(); - if ( simWellData.size() > 1 ) + if (simWellData.size() > 1) { interpolatedWellColors = caf::ColorTable::interpolateColorArray(wellColors, simWellData.size()); } - for ( size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx ) + for (size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx) { m_wellToColorMap[simWellData[wIdx]->m_wellName] = cvf::Color3f::BLACK; } size_t wIdx = 0; - for ( auto & wNameColorPair: m_wellToColorMap ) + for (auto& wNameColorPair : m_wellToColorMap) { wNameColorPair.second = cvf::Color3f(interpolatedWellColors[wIdx]); @@ -197,7 +203,7 @@ cvf::Color3f RimEclipseCase::defaultWellColor(const QString& wellName) } auto nmColor = m_wellToColorMap.find(wellName); - if (nmColor != m_wellToColorMap.end()) + if (nmColor != m_wellToColorMap.end()) { return nmColor->second; } @@ -208,7 +214,7 @@ cvf::Color3f RimEclipseCase::defaultWellColor(const QString& wellName) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const RigMainGrid* RimEclipseCase::mainGrid() const { @@ -221,7 +227,7 @@ const RigMainGrid* RimEclipseCase::mainGrid() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEclipseCase::initAfterRead() { @@ -233,6 +239,10 @@ void RimEclipseCase::initAfterRead() riv->setEclipseCase(this); } + for (RimContourMapView* contourMap : m_contourMapCollection->views()) + { + contourMap->setEclipseCase(this); + } if (caseUserDescription().isEmpty() && !m_caseName_OBSOLETE().isEmpty()) { @@ -241,7 +251,7 @@ void RimEclipseCase::initAfterRead() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimEclipseView* RimEclipseCase::createAndAddReservoirView() { @@ -260,14 +270,14 @@ RimEclipseView* RimEclipseCase::createAndAddReservoirView() rimEclipseView->hasUserRequestedAnimation = true; rimEclipseView->cellEdgeResult()->setResultVariable("MULT"); - rimEclipseView->cellEdgeResult()->enableCellEdgeColors = false; + rimEclipseView->cellEdgeResult()->setActive(false); rimEclipseView->fractureColors()->setDefaultResultName(); } caf::PdmDocument::updateUiIconStateRecursively(rimEclipseView); size_t i = reservoirViews().size(); - rimEclipseView->name = QString("View %1").arg(i + 1); + rimEclipseView->setName(QString("View %1").arg(i + 1)); reservoirViews().push_back(rimEclipseView); @@ -275,17 +285,18 @@ RimEclipseView* RimEclipseCase::createAndAddReservoirView() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimEclipseView* RimEclipseCase::createCopyAndAddView(const RimEclipseView* sourceView) { CVF_ASSERT(sourceView); - RimEclipseView* rimEclipseView = dynamic_cast(sourceView->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); + RimEclipseView* rimEclipseView = dynamic_cast( + sourceView->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); CVF_ASSERT(rimEclipseView); rimEclipseView->setEclipseCase(this); - + caf::PdmDocument::updateUiIconStateRecursively(rimEclipseView); reservoirViews().push_back(rimEclipseView); @@ -298,20 +309,21 @@ RimEclipseView* RimEclipseCase::createCopyAndAddView(const RimEclipseView* sourc } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const RigVirtualPerforationTransmissibilities* RimEclipseCase::computeAndGetVirtualPerforationTransmissibilities() { RigEclipseCaseData* rigEclipseCase = eclipseCaseData(); + if (!rigEclipseCase) return nullptr; if (rigEclipseCase->virtualPerforationTransmissibilities() == nullptr) { cvf::ref perfTrans = new RigVirtualPerforationTransmissibilities; std::vector visibleWellPaths; - bool anyPerforationsPresent = false; + bool anyPerforationsPresent = false; { - RimProject* proj = RiaApplication::instance()->project(); + RimProject* proj = RiaApplication::instance()->project(); std::vector wellPaths = proj->allWellPaths(); for (auto w : wellPaths) { @@ -329,21 +341,25 @@ const RigVirtualPerforationTransmissibilities* RimEclipseCase::computeAndGetVirt for (auto w : visibleWellPaths) { - std::vector staticCompletionData = RicWellPathExportCompletionDataFeatureImpl::computeStaticCompletionsForWellPath(w, this); - + std::vector staticCompletionData = + RicWellPathExportCompletionDataFeatureImpl::computeStaticCompletionsForWellPath(w, this); + if (anyPerforationsPresent) { std::vector> allCompletionData; - + for (size_t i = 0; i < timeStepDates().size(); i++) { - std::vector dynamicCompletionDataOneTimeStep = RicWellPathExportCompletionDataFeatureImpl::computeDynamicCompletionsForWellPath(w, this, i); + std::vector dynamicCompletionDataOneTimeStep = + RicWellPathExportCompletionDataFeatureImpl::computeDynamicCompletionsForWellPath(w, this, i); - std::copy(staticCompletionData.begin(), staticCompletionData.end(), std::back_inserter(dynamicCompletionDataOneTimeStep)); + std::copy(staticCompletionData.begin(), + staticCompletionData.end(), + std::back_inserter(dynamicCompletionDataOneTimeStep)); allCompletionData.push_back(dynamicCompletionDataOneTimeStep); } - + perfTrans->setCompletionDataForWellPath(w, allCompletionData); } else @@ -370,14 +386,16 @@ const RigVirtualPerforationTransmissibilities* RimEclipseCase::computeAndGetVirt { if (r.isValid()) { - RigCompletionData compData(wellRes->m_wellName, RigCompletionDataGridCell(r.m_gridCellIndex, rigEclipseCase->mainGrid()), 0); + RigCompletionData compData( + wellRes->m_wellName, + RigCompletionDataGridCell(r.m_gridCellIndex, rigEclipseCase->mainGrid()), + 0); compData.setTransmissibility(r.connectionFactor()); completionData.push_back(compData); } } } - } completionsPerTimeStep.push_back(completionData); @@ -393,22 +411,22 @@ const RigVirtualPerforationTransmissibilities* RimEclipseCase::computeAndGetVirt } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEclipseCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - if (changedField == &releaseResultMemory) + if (changedField == &m_releaseResultMemory) { reloadDataAndUpdate(); - releaseResultMemory = oldValue.toBool(); + m_releaseResultMemory = oldValue.toBool(); } - else if (changedField == &flipXAxis || changedField == &flipYAxis) + else if (changedField == &m_flipXAxis || changedField == &m_flipYAxis) { RigEclipseCaseData* rigEclipseCase = eclipseCaseData(); if (rigEclipseCase) { - rigEclipseCase->mainGrid()->setFlipAxis(flipXAxis, flipYAxis); + rigEclipseCase->mainGrid()->setFlipAxis(m_flipXAxis, m_flipYAxis); computeCachedData(); @@ -422,22 +440,21 @@ void RimEclipseCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c } } } - else if(changedField == &activeFormationNames) + else if (changedField == &activeFormationNames) { updateFormationNamesData(); } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEclipseCase::updateFormationNamesData() { RigEclipseCaseData* rigEclipseCase = eclipseCaseData(); - if(rigEclipseCase) + if (rigEclipseCase) { - if(activeFormationNames()) + if (activeFormationNames()) { rigEclipseCase->setActiveFormationNames(activeFormationNames()->formationNamesData()); } @@ -446,24 +463,24 @@ void RimEclipseCase::updateFormationNamesData() rigEclipseCase->setActiveFormationNames(nullptr); } std::vector views = this->views(); - for(Rim3dView* view : views) + for (Rim3dView* view : views) { RimEclipseView* eclView = dynamic_cast(view); - if(eclView && eclView->isUsingFormationNames()) + if (eclView && eclView->isUsingFormationNames()) { if (!activeFormationNames()) { - if (eclView->cellResult()->resultType() == RiaDefines::FORMATION_NAMES) + if (eclView->cellResult()->resultType() == RiaDefines::FORMATION_NAMES) { eclView->cellResult()->setResultVariable(RiaDefines::undefinedResultName()); eclView->cellResult()->updateConnectedEditors(); } RimEclipsePropertyFilterCollection* eclFilColl = eclView->eclipsePropertyFilterCollection(); - for ( RimEclipsePropertyFilter* propFilter : eclFilColl->propertyFilters ) + for (RimEclipsePropertyFilter* propFilter : eclFilColl->propertyFilters) { - if ( propFilter->resultDefinition->resultType() == RiaDefines::FORMATION_NAMES ) + if (propFilter->resultDefinition->resultType() == RiaDefines::FORMATION_NAMES) { propFilter->resultDefinition()->setResultVariable(RiaDefines::undefinedResultName()); } @@ -471,9 +488,9 @@ void RimEclipseCase::updateFormationNamesData() } RimEclipsePropertyFilterCollection* eclFilColl = eclView->eclipsePropertyFilterCollection(); - for ( RimEclipsePropertyFilter* propFilter : eclFilColl->propertyFilters ) + for (RimEclipsePropertyFilter* propFilter : eclFilColl->propertyFilters) { - if ( propFilter->resultDefinition->resultType() == RiaDefines::FORMATION_NAMES ) + if (propFilter->resultDefinition->resultType() == RiaDefines::FORMATION_NAMES) { propFilter->setToDefaultValues(); propFilter->updateConnectedEditors(); @@ -489,25 +506,29 @@ void RimEclipseCase::updateFormationNamesData() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEclipseCase::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) { std::vector children; reservoirViews.childObjects(&children); - for (auto child : children) uiTreeOrdering.add(child); - + for (auto child : children) + uiTreeOrdering.add(child); + if (!m_2dIntersectionViewCollection->views().empty()) { uiTreeOrdering.add(&m_2dIntersectionViewCollection); } - + if (!m_contourMapCollection->views().empty()) + { + uiTreeOrdering.add(&m_contourMapCollection); + } uiTreeOrdering.skipRemainingChildren(true); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEclipseCase::computeCachedData() { @@ -528,9 +549,9 @@ void RimEclipseCase::computeCachedData() pInf.setProgressDescription("Calculating faults"); rigEclipseCase->mainGrid()->calculateFaults(rigEclipseCase->activeCellInfo(RiaDefines::MATRIX_MODEL)); pInf.incrementProgress(); - + pInf.setProgressDescription("Calculating Formation Names Result"); - if ( activeFormationNames() ) + if (activeFormationNames()) { rigEclipseCase->setActiveFormationNames(activeFormationNames()->formationNamesData()); } @@ -543,9 +564,8 @@ void RimEclipseCase::computeCachedData() } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimCaseCollection* RimEclipseCase::parentCaseCollection() { @@ -553,11 +573,19 @@ RimCaseCollection* RimEclipseCase::parentCaseCollection() } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +RimContourMapViewCollection* RimEclipseCase::contourMapCollection() +{ + return m_contourMapCollection; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RimEclipseCase::setReservoirData(RigEclipseCaseData* eclipseCase) { - m_rigEclipseCase = eclipseCase; + m_rigEclipseCase = eclipseCase; if (this->eclipseCaseData()) { m_fractureModelResults()->setCellResults(eclipseCaseData()->results(RiaDefines::FRACTURE_MODEL)); @@ -571,7 +599,7 @@ void RimEclipseCase::setReservoirData(RigEclipseCaseData* eclipseCase) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEclipseCase::createTimeStepFormatString() { @@ -581,7 +609,7 @@ void RimEclipseCase::createTimeStepFormatString() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::BoundingBox RimEclipseCase::activeCellsBoundingBox() const { @@ -596,7 +624,7 @@ cvf::BoundingBox RimEclipseCase::activeCellsBoundingBox() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::BoundingBox RimEclipseCase::allCellsBoundingBox() const { @@ -611,7 +639,7 @@ cvf::BoundingBox RimEclipseCase::allCellsBoundingBox() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::Vec3d RimEclipseCase::displayModelOffset() const { @@ -626,24 +654,24 @@ cvf::Vec3d RimEclipseCase::displayModelOffset() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RigCaseCellResultsData* RimEclipseCase::results(RiaDefines::PorosityModelType porosityModel) { - if (m_rigEclipseCase.notNull()) + if (m_rigEclipseCase.notNull()) { return m_rigEclipseCase->results(porosityModel); } - + return nullptr; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const RigCaseCellResultsData* RimEclipseCase::results(RiaDefines::PorosityModelType porosityModel) const { - if (m_rigEclipseCase.notNull()) + if (m_rigEclipseCase.notNull()) { return m_rigEclipseCase->results(porosityModel); } @@ -652,7 +680,31 @@ const RigCaseCellResultsData* RimEclipseCase::results(RiaDefines::PorosityModelT } //-------------------------------------------------------------------------------------------------- -/// +/// Convenience function used to pre-load data before const access of data +/// Used when implementing calculations in a parallelized loop +//-------------------------------------------------------------------------------------------------- +bool RimEclipseCase::loadStaticResultsByName(const std::vector& resultNames) +{ + bool foundDataForAllResults = true; + + RigCaseCellResultsData* cellResultsData = this->results(RiaDefines::MATRIX_MODEL); + if (cellResultsData) + { + for (const auto& resultName : resultNames) + { + size_t resultIdx = cellResultsData->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, resultName); + if (resultIdx == cvf::UNDEFINED_SIZE_T) + { + foundDataForAllResults = false; + } + } + } + + return foundDataForAllResults; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- RimReservoirCellResultsStorage* RimEclipseCase::resultsStorage(RiaDefines::PorosityModelType porosityModel) { @@ -665,7 +717,7 @@ RimReservoirCellResultsStorage* RimEclipseCase::resultsStorage(RiaDefines::Poros } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const RimReservoirCellResultsStorage* RimEclipseCase::resultsStorage(RiaDefines::PorosityModelType porosityModel) const { @@ -678,31 +730,32 @@ const RimReservoirCellResultsStorage* RimEclipseCase::resultsStorage(RiaDefines: } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RimEclipseCase::filesContainingFaults() const { - QString separatedPaths = m_filesContainingFaultsSemColSeparated; - QStringList pathList = separatedPaths.split(";", QString::SkipEmptyParts); + QString separatedPaths = m_filesContainingFaultsSemColSeparated; + QStringList pathList = separatedPaths.split(";", QString::SkipEmptyParts); std::vector stdPathList; - for (auto& path: pathList) stdPathList.push_back(path); + for (auto& path : pathList) + stdPathList.push_back(path); return stdPathList; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEclipseCase::setFilesContainingFaults(const std::vector& val) { QString separatedPaths; - + for (size_t i = 0; i < val.size(); ++i) { const auto& path = val[i]; separatedPaths += path; - if (!(i+1 >= val.size()) ) + if (!(i + 1 >= val.size())) { separatedPaths += ";"; } @@ -711,7 +764,7 @@ void RimEclipseCase::setFilesContainingFaults(const std::vector& val) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimEclipseCase::openReserviorCase() { @@ -723,7 +776,7 @@ bool RimEclipseCase::openReserviorCase() bool createPlaceholderEntries = true; if (dynamic_cast(this)) { - // Never create placeholder entries for statistical cases. This does not make sense, and breaks the + // Never create placeholder entries for statistical cases. This does not make sense, and breaks the // logic for testing if data is present in RimEclipseStatisticsCase::hasComputedStatistics() createPlaceholderEntries = false; } @@ -732,33 +785,40 @@ bool RimEclipseCase::openReserviorCase() { { RigCaseCellResultsData* results = this->results(RiaDefines::MATRIX_MODEL); - if (results ) + if (results) { results->createPlaceholderResultEntries(); - // After the placeholder result for combined transmissibility is created, + // After the placeholder result for combined transmissibility is created, // make sure the nnc transmissibilities can be addressed by this scalarResultIndex as well - size_t combinedTransResIdx = results->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName()); + size_t combinedTransResIdx = + results->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName()); if (combinedTransResIdx != cvf::UNDEFINED_SIZE_T) { - eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameCombTrans(), combinedTransResIdx); + eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameCombTrans(), + combinedTransResIdx); } - size_t combinedWatFluxResIdx = results->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedWaterFluxResultName()); + size_t combinedWatFluxResIdx = + results->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedWaterFluxResultName()); if (combinedWatFluxResIdx != cvf::UNDEFINED_SIZE_T) { - eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameFluxWat(), combinedWatFluxResIdx); + eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameFluxWat(), + combinedWatFluxResIdx); } - size_t combinedOilFluxResIdx = results->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedOilFluxResultName()); + size_t combinedOilFluxResIdx = + results->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedOilFluxResultName()); if (combinedOilFluxResIdx != cvf::UNDEFINED_SIZE_T) { - eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameFluxOil(), combinedOilFluxResIdx); + eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameFluxOil(), + combinedOilFluxResIdx); } - size_t combinedGasFluxResIdx = results->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedGasFluxResultName()); + size_t combinedGasFluxResIdx = + results->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::combinedGasFluxResultName()); if (combinedGasFluxResIdx != cvf::UNDEFINED_SIZE_T) { - eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameFluxGas(), combinedGasFluxResIdx); + eclipseCaseData()->mainGrid()->nncData()->setScalarResultIndex(RigNNCData::propertyNameFluxGas(), + combinedGasFluxResIdx); } } - } { @@ -784,54 +844,77 @@ bool RimEclipseCase::openReserviorCase() } } } + + // Update grids node + { + std::vector gridColls; + descendantsIncludingThisOfType(gridColls); + for (RimGridCollection* gridCollection : gridColls) + { + gridCollection->syncFromMainEclipseGrid(); + } + } + return true; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RimEclipseCase::allSpecialViews() const { std::vector views; - for (size_t vIdx = 0; vIdx < reservoirViews.size(); ++vIdx) + for (RimEclipseView* view : reservoirViews) { - views.push_back(reservoirViews[vIdx]); + views.push_back(view); } - + + for (RimContourMapView* view : m_contourMapCollection->views()) + { + views.push_back(view); + } + return views; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QStringList RimEclipseCase::timeStepStrings() const { QStringList stringList; - int timeStepCount = static_cast(results(RiaDefines::MATRIX_MODEL)->maxTimeStepCount()); - for (int i = 0; i < timeStepCount; i++) + const RigCaseCellResultsData* cellResultData = results(RiaDefines::MATRIX_MODEL); + if (cellResultData) { - stringList += this->timeStepName(i); + int timeStepCount = static_cast(cellResultData->maxTimeStepCount()); + for (int i = 0; i < timeStepCount; i++) + { + stringList += this->timeStepName(i); + } } return stringList; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QString RimEclipseCase::timeStepName(int frameIdx) const { std::vector timeStepDates = this->timeStepDates(); - CVF_ASSERT(frameIdx < static_cast(timeStepDates.size())); + if (frameIdx < static_cast(timeStepDates.size())) + { + QDateTime date = timeStepDates.at(frameIdx); - QDateTime date = timeStepDates.at(frameIdx); + return RiaQDateTimeTools::toStringUsingApplicationLocale(date, m_timeStepFormatString); + } - return date.toString(m_timeStepFormatString); + return QString(""); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEclipseCase::reloadDataAndUpdate() { @@ -860,10 +943,24 @@ void RimEclipseCase::reloadDataAndUpdate() reservoirView->updateAnnotationItems(); } + for (RimContourMapView* contourMap : m_contourMapCollection->views()) + { + CVF_ASSERT(contourMap); + contourMap->loadDataAndUpdate(); + contourMap->updateGridBoxData(); + contourMap->updateAnnotationItems(); + } + + for (Rim2dIntersectionView* view : intersectionViewCollection()->views()) + { + view->createDisplayModelAndRedraw(); + } + RimProject* project = RiaApplication::instance()->project(); if (project) { - RimSummaryCaseMainCollection* sumCaseColl = project->activeOilField() ? project->activeOilField()->summaryCaseMainCollection() : nullptr; + RimSummaryCaseMainCollection* sumCaseColl = + project->activeOilField() ? project->activeOilField()->summaryCaseMainCollection() : nullptr; if (sumCaseColl) { sumCaseColl->loadAllSummaryCaseData(); @@ -871,9 +968,9 @@ void RimEclipseCase::reloadDataAndUpdate() if (project->mainPlotCollection()) { - RimWellLogPlotCollection* wellPlotCollection = project->mainPlotCollection()->wellLogPlotCollection(); + RimWellLogPlotCollection* wellPlotCollection = project->mainPlotCollection()->wellLogPlotCollection(); RimSummaryPlotCollection* summaryPlotCollection = project->mainPlotCollection()->summaryPlotCollection(); - RimFlowPlotCollection* flowPlotCollection = project->mainPlotCollection()->flowPlotCollection(); + RimFlowPlotCollection* flowPlotCollection = project->mainPlotCollection()->flowPlotCollection(); if (wellPlotCollection) { @@ -899,7 +996,7 @@ void RimEclipseCase::reloadDataAndUpdate() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RimEclipseCase::characteristicCellSize() const { @@ -913,7 +1010,7 @@ double RimEclipseCase::characteristicCellSize() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEclipseCase::setFormationNames(RimFormationNames* formationNames) { @@ -925,9 +1022,31 @@ void RimEclipseCase::setFormationNames(RimFormationNames* formationNames) } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +std::set RimEclipseCase::sortedSimWellNames() const +{ + std::set sortedWellNames; + if (eclipseCaseData()) + { + const cvf::Collection& simWellData = eclipseCaseData()->wellResults(); + + for (size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx) + { + sortedWellNames.insert(simWellData[wIdx]->m_wellName); + } + } + return sortedWellNames; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- std::vector RimEclipseCase::timeStepDates() const { - return results(RiaDefines::MATRIX_MODEL)->timeStepDates(); + if (results(RiaDefines::MATRIX_MODEL)) + { + return results(RiaDefines::MATRIX_MODEL)->timeStepDates(); + } + return std::vector(); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCase.h b/ApplicationCode/ProjectDataModel/RimEclipseCase.h index 16faea32cc..7b8f4d48d6 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCase.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseCase.h @@ -34,6 +34,8 @@ #include "cvfObject.h" #include "cvfColor3.h" +#include + class QString; class RigEclipseCaseData; @@ -43,6 +45,8 @@ class RigMainGrid; class RimCaseCollection; class RimIdenticalGridCaseGroup; class RimReservoirCellResultsStorage; +class RimContourMapView; +class RimContourMapViewCollection; class RimEclipseView; class RigVirtualPerforationTransmissibilities; @@ -57,14 +61,10 @@ class RimEclipseCase : public RimCase CAF_PDM_HEADER_INIT; public: RimEclipseCase(); - virtual ~RimEclipseCase(); - + ~RimEclipseCase() override; // Fields: - caf::PdmField releaseResultMemory; caf::PdmChildArrayField reservoirViews; - caf::PdmField flipXAxis; - caf::PdmField flipYAxis; std::vector filesContainingFaults() const; void setFilesContainingFaults(const std::vector& val); @@ -80,6 +80,7 @@ class RimEclipseCase : public RimCase RigCaseCellResultsData* results(RiaDefines::PorosityModelType porosityModel); const RigCaseCellResultsData* results(RiaDefines::PorosityModelType porosityModel) const; + bool loadStaticResultsByName(const std::vector& resultNames); RimReservoirCellResultsStorage* resultsStorage(RiaDefines::PorosityModelType porosityModel); const RimReservoirCellResultsStorage* resultsStorage(RiaDefines::PorosityModelType porosityModel) const; @@ -94,30 +95,33 @@ class RimEclipseCase : public RimCase RimCaseCollection* parentCaseCollection(); - - virtual QStringList timeStepStrings() const override; - virtual QString timeStepName(int frameIdx) const override; - virtual std::vector timeStepDates() const override; + RimContourMapViewCollection* contourMapCollection(); + + QStringList timeStepStrings() const override; + QString timeStepName(int frameIdx) const override; + std::vector timeStepDates() const override; - virtual cvf::BoundingBox activeCellsBoundingBox() const; - virtual cvf::BoundingBox allCellsBoundingBox() const; - virtual cvf::Vec3d displayModelOffset() const; + cvf::BoundingBox activeCellsBoundingBox() const override; + cvf::BoundingBox allCellsBoundingBox() const override; + cvf::Vec3d displayModelOffset() const override; void reloadDataAndUpdate(); virtual void reloadEclipseGridFile() = 0; - virtual double characteristicCellSize() const override; + double characteristicCellSize() const override; - virtual void setFormationNames(RimFormationNames* formationNames) override; + void setFormationNames(RimFormationNames* formationNames) override; + std::set sortedSimWellNames() const; + protected: - virtual void initAfterRead(); - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void initAfterRead() override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual void updateFormationNamesData() override; + void updateFormationNamesData() override; // Internal methods protected: @@ -126,14 +130,21 @@ class RimEclipseCase : public RimCase private: void createTimeStepFormatString(); - virtual std::vector allSpecialViews() const override; + std::vector allSpecialViews() const override; + +protected: + caf::PdmField m_flipXAxis; + caf::PdmField m_flipYAxis; private: + caf::PdmField m_filesContainingFaultsSemColSeparated; + caf::PdmField m_releaseResultMemory; + + caf::PdmChildField m_contourMapCollection; + cvf::ref m_rigEclipseCase; QString m_timeStepFormatString; - std::map m_wellToColorMap; - caf::PdmField m_filesContainingFaultsSemColSeparated; - + std::map m_wellToColorMap; caf::PdmChildField m_matrixModelResults; caf::PdmChildField m_fractureModelResults; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.cpp index 3a71cb4472..6945ed51de 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.cpp @@ -94,46 +94,6 @@ RimIdenticalGridCaseGroup* RimEclipseCaseCollection::createIdenticalCaseGroupFro return group; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseCaseCollection::moveEclipseCaseIntoCaseGroup(RimEclipseCase* rimReservoir) -{ - CVF_ASSERT(rimReservoir); - - RigEclipseCaseData* rigEclipseCase = rimReservoir->eclipseCaseData(); - RigMainGrid* equalGrid = registerCaseInGridCollection(rigEclipseCase); - CVF_ASSERT(equalGrid); - - // Insert in identical grid group - bool foundGroup = false; - - for (size_t i = 0; i < caseGroups.size(); i++) - { - RimIdenticalGridCaseGroup* cg = caseGroups()[i]; - - if (cg->mainGrid() == equalGrid) - { - cg->addCase(rimReservoir); - foundGroup = true; - } - } - - if (!foundGroup) - { - RimIdenticalGridCaseGroup* group = new RimIdenticalGridCaseGroup; - assert(RiaApplication::instance()->project()); - RiaApplication::instance()->project()->assignIdToCaseGroup(group); - - group->addCase(rimReservoir); - - caseGroups().push_back(group); - } - - // Remove reservoir from main container - cases().removeChildObject(rimReservoir); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.h b/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.h index ce843ceabb..10363c4f60 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseCaseCollection.h @@ -44,7 +44,7 @@ class RimEclipseCaseCollection : public caf::PdmObject public: RimEclipseCaseCollection(void); - virtual ~RimEclipseCaseCollection(void); + ~RimEclipseCaseCollection(void) override; caf::PdmChildArrayField cases; caf::PdmChildArrayField caseGroups; @@ -53,7 +53,6 @@ class RimEclipseCaseCollection : public caf::PdmObject RimIdenticalGridCaseGroup* createIdenticalCaseGroupFromMainCase(RimEclipseCase* mainCase); void insertCaseInCaseGroup(RimIdenticalGridCaseGroup* caseGroup, RimEclipseCase* rimReservoir); - void moveEclipseCaseIntoCaseGroup(RimEclipseCase* rimReservoir); void removeCaseFromAllGroups(RimEclipseCase* rimReservoir); void recomputeStatisticsForAllCaseGroups(); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp index fe3d9148dd..b1c08d4afd 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.cpp @@ -20,6 +20,7 @@ #include "RimEclipseCellColors.h" +#include "RiaColorTables.h" #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" #include "RigFlowDiagResults.h" @@ -56,8 +57,8 @@ RimEclipseCellColors::RimEclipseCellColors() CAF_PDM_InitFieldNoDefault(&m_legendConfigData, "ResultVarLegendDefinitionList", "", "", "", ""); - CAF_PDM_InitFieldNoDefault(&ternaryLegendConfig, "TernaryLegendDefinition", "Ternary Legend Definition", "", "", ""); - this->ternaryLegendConfig = new RimTernaryLegendConfig(); + CAF_PDM_InitFieldNoDefault(&m_ternaryLegendConfig, "TernaryLegendDefinition", "Ternary Legend Definition", "", "", ""); + this->m_ternaryLegendConfig = new RimTernaryLegendConfig(); CAF_PDM_InitFieldNoDefault(&m_legendConfigPtrField, "LegendDefinitionPtrField", "Legend Definition PtrField", "", "", ""); @@ -74,7 +75,7 @@ RimEclipseCellColors::~RimEclipseCellColors() m_legendConfigData.deleteAllChildObjects(); - delete ternaryLegendConfig(); + delete m_ternaryLegendConfig(); } //-------------------------------------------------------------------------------------------------- @@ -170,7 +171,7 @@ void RimEclipseCellColors::initAfterRead() // The current legend config is NOT stored in in ResInsight up to v 1.3.7-dev RimRegularLegendConfig* obsoleteLegend = obsoleteField_legendConfig(); - // set to NULL before pushing into container + // set to nullptr before pushing into container obsoleteField_legendConfig = nullptr; m_legendConfigData.push_back(obsoleteLegend); @@ -189,7 +190,7 @@ void RimEclipseCellColors::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOr { if (this->resultVariable() == RiaDefines::ternarySaturationResultName()) { - uiTreeOrdering.add(ternaryLegendConfig()); + uiTreeOrdering.add(m_ternaryLegendConfig()); } else { @@ -278,7 +279,7 @@ void RimEclipseCellColors::updateLegendData(size_t currentTimeStep, RimTernaryLegendConfig* ternaryLegendConfig) { if (!legendConfig) legendConfig = this->legendConfig(); - if (!ternaryLegendConfig) ternaryLegendConfig = this->ternaryLegendConfig(); + if (!ternaryLegendConfig) ternaryLegendConfig = this->m_ternaryLegendConfig(); if ( this->hasResult() ) { @@ -392,34 +393,22 @@ void RimEclipseCellColors::updateLegendData(size_t currentTimeStep, legendConfig->setNamedCategoriesInverse(fnVector); } else if ( this->resultType() == RiaDefines::DYNAMIC_NATIVE && this->resultVariable() == RiaDefines::completionTypeResultName() ) - { + { + const std::vector& visibleCategories = cellResultsData->uniqueCellScalarValues(this->scalarResultIndex()); + + std::vector supportedCompletionTypes = + { RiaDefines::WELL_PATH, RiaDefines::FISHBONES, RiaDefines::PERFORATION_INTERVAL, RiaDefines::FRACTURE }; + + RiaColorTables::WellPathComponentColors colors = RiaColorTables::wellPathComponentColors(); + std::vector< std::tuple > categories; - - caf::AppEnum wellPath(RiaDefines::WELL_PATH); - caf::AppEnum fishbone(RiaDefines::FISHBONES); - caf::AppEnum perforationInterval(RiaDefines::PERFORATION_INTERVAL); - caf::AppEnum fracture(RiaDefines::FRACTURE); - - const std::vector& visibleCatetories = cellResultsData->uniqueCellScalarValues(this->scalarResultIndex()); - - if (std::find(visibleCatetories.begin(), visibleCatetories.end(), wellPath.index()) != visibleCatetories.end()) - { - categories.push_back(std::make_tuple(wellPath.uiText(), static_cast(wellPath.index()), cvf::Color3::RED)); - } - - if (std::find(visibleCatetories.begin(), visibleCatetories.end(), fishbone.index()) != visibleCatetories.end()) - { - categories.push_back(std::make_tuple(fishbone.uiText(), static_cast(fishbone.index()), cvf::Color3::DARK_GREEN)); - } - - if (std::find(visibleCatetories.begin(), visibleCatetories.end(), perforationInterval.index()) != visibleCatetories.end()) + for (auto completionType : supportedCompletionTypes) { - categories.push_back(std::make_tuple(perforationInterval.uiText(), static_cast(perforationInterval.index()), cvf::Color3::GREEN)); - } - - if (std::find(visibleCatetories.begin(), visibleCatetories.end(), fracture.index()) != visibleCatetories.end()) - { - categories.push_back(std::make_tuple(fracture.uiText(), static_cast(fracture.index()), cvf::Color3::YELLOW_GREEN)); + if (std::find(visibleCategories.begin(), visibleCategories.end(), completionType) != visibleCategories.end()) + { + QString categoryText = caf::AppEnum::uiText(completionType); + categories.push_back(std::make_tuple(categoryText, completionType, colors[completionType])); + } } legendConfig->setCategoryItems(categories); @@ -519,6 +508,14 @@ RimRegularLegendConfig* RimEclipseCellColors::legendConfig() return m_legendConfigPtrField; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimTernaryLegendConfig* RimEclipseCellColors::ternaryLegendConfig() +{ + return m_ternaryLegendConfig; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.h b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.h index 3962a7ecaa..1626f83580 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseCellColors.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseCellColors.h @@ -38,7 +38,7 @@ class RimEclipseCellColors : public RimEclipseResultDefinition CAF_PDM_HEADER_INIT; public: RimEclipseCellColors(); - virtual ~RimEclipseCellColors(); + ~RimEclipseCellColors() override; void setReservoirView(RimEclipseView* ownerReservoirView); RimEclipseView* reservoirView(); @@ -46,31 +46,33 @@ class RimEclipseCellColors : public RimEclipseResultDefinition void updateLegendData(size_t timestep, RimRegularLegendConfig* legendConfig = nullptr, RimTernaryLegendConfig* ternaryLegendConfig = nullptr); + RimRegularLegendConfig* legendConfig(); - caf::PdmChildField ternaryLegendConfig; + RimTernaryLegendConfig* ternaryLegendConfig(); - virtual void setResultVariable(const QString& resultName); + void setResultVariable(const QString& resultName) override; void updateIconState(); - virtual void updateLegendCategorySettings() override; + void updateLegendCategorySettings() override; protected: // Overridden methods - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; friend class RimEclipseFaultColors; friend class RimCellEdgeColors; - virtual void initAfterRead(); + void initAfterRead() override; private: void changeLegendConfig(QString resultVarNameOfNewLegend); caf::PdmChildArrayField m_legendConfigData; caf::PdmPtrField m_legendConfigPtrField; + caf::PdmChildField m_ternaryLegendConfig; - caf::PdmPointer m_reservoirView; + caf::PdmPointer m_reservoirView; // Obsolete caf::PdmChildField obsoleteField_legendConfig; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.h b/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.h index 2856bf484e..960fb3c966 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseFaultColors.h @@ -37,7 +37,7 @@ class RimEclipseFaultColors : public caf::PdmObject public: RimEclipseFaultColors(); - virtual ~RimEclipseFaultColors(); + ~RimEclipseFaultColors() override; void setReservoirView(RimEclipseView* ownerReservoirView); @@ -49,11 +49,11 @@ class RimEclipseFaultColors : public caf::PdmObject void updateUiFieldsFromActiveResult(); protected: - virtual void initAfterRead(); - virtual caf::PdmFieldHandle* objectToggleField(); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); + void initAfterRead() override; + caf::PdmFieldHandle* objectToggleField() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override ; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; private: caf::PdmChildField m_customFaultResultColors; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseGeometrySelectionItem.cpp b/ApplicationCode/ProjectDataModel/RimEclipseGeometrySelectionItem.cpp index 3692c6dfa5..5d5701a1eb 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseGeometrySelectionItem.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseGeometrySelectionItem.cpp @@ -39,7 +39,7 @@ RimEclipseGeometrySelectionItem::RimEclipseGeometrySelectionItem() CAF_PDM_InitFieldNoDefault(&m_eclipseCase, "EclipseCase", "Eclipse Case", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_gridIndex, "GridIndex", "Grid Index", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_cellIndex, "CellIndex", "Cell Index", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_localIntersectionPoint, "LocalIntersectionPoint", "local Intersection Point", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_localIntersectionPointInDisplay, "LocalIntersectionPoint", "local Intersection Point", "", "", ""); } //-------------------------------------------------------------------------------------------------- @@ -56,7 +56,7 @@ void RimEclipseGeometrySelectionItem::setFromSelectionItem(const RiuEclipseSelec { m_gridIndex = selectionItem->m_gridIndex; m_cellIndex = selectionItem->m_gridLocalCellIndex; - m_localIntersectionPoint = selectionItem->m_localIntersectionPoint; + m_localIntersectionPointInDisplay = selectionItem->m_localIntersectionPointInDisplay; m_eclipseCase = selectionItem->m_view->eclipseCase(); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseGeometrySelectionItem.h b/ApplicationCode/ProjectDataModel/RimEclipseGeometrySelectionItem.h index faf69a1146..0dce751565 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseGeometrySelectionItem.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseGeometrySelectionItem.h @@ -36,11 +36,11 @@ class RimEclipseGeometrySelectionItem : public RimGeometrySelectionItem CAF_PDM_HEADER_INIT; public: RimEclipseGeometrySelectionItem(); - virtual ~RimEclipseGeometrySelectionItem() override; + ~RimEclipseGeometrySelectionItem() override; void setFromSelectionItem(const RiuEclipseSelectionItem* selectionItem); - virtual QString geometrySelectionText() const override; + QString geometrySelectionText() const override; RimEclipseCase* eclipseCase() const; size_t gridIndex() const; @@ -51,6 +51,6 @@ class RimEclipseGeometrySelectionItem : public RimGeometrySelectionItem caf::PdmField m_gridIndex; caf::PdmField m_cellIndex; - caf::PdmField m_localIntersectionPoint; + caf::PdmField m_localIntersectionPointInDisplay; }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseInputCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseInputCase.cpp index d3bcae58ba..bf0f01b77d 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseInputCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseInputCase.cpp @@ -20,6 +20,7 @@ #include "RimEclipseInputCase.h" +#include "RiaFieldHandleTools.h" #include "RiaPreferences.h" #include "RifEclipseInputFileTools.h" @@ -39,6 +40,7 @@ #include "RimReservoirCellResultsStorage.h" #include "RimTools.h" +#include "cafPdmUiTreeOrdering.h" #include "cafProgressInfo.h" #include @@ -66,8 +68,7 @@ RimEclipseInputCase::RimEclipseInputCase() CAF_PDM_InitFieldNoDefault(&m_additionalFilenames_OBSOLETE, "AdditionalFileNames", "Additional Files", "", "" ,""); m_additionalFilenames_OBSOLETE.uiCapability()->setUiReadOnly(true); - m_additionalFilenames_OBSOLETE.uiCapability()->setUiHidden(true); - m_additionalFilenames_OBSOLETE.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_additionalFilenames_OBSOLETE); } @@ -124,7 +125,7 @@ bool RimEclipseInputCase::openDataFileSet(const QStringList& fileNames) this->caseUserDescription = caseName; - this->eclipseCaseData()->mainGrid()->setFlipAxis(flipXAxis, flipYAxis); + this->eclipseCaseData()->mainGrid()->setFlipAxis(m_flipXAxis, m_flipYAxis); computeCachedData(); @@ -208,13 +209,12 @@ bool RimEclipseInputCase::openEclipseGridFile() results(RiaDefines::MATRIX_MODEL)->setReaderInterface(readerInterface.p()); results(RiaDefines::FRACTURE_MODEL)->setReaderInterface(readerInterface.p()); - this->eclipseCaseData()->mainGrid()->setFlipAxis(flipXAxis, flipYAxis); + this->eclipseCaseData()->mainGrid()->setFlipAxis(m_flipXAxis, m_flipYAxis); computeCachedData(); loadAndSyncronizeInputProperties(); } - RiaApplication* app = RiaApplication::instance(); if (app->preferences()->autocomputeDepthRelatedProperties) { @@ -222,6 +222,8 @@ bool RimEclipseInputCase::openEclipseGridFile() results(RiaDefines::FRACTURE_MODEL)->computeDepthRelatedResults(); } + results(RiaDefines::MATRIX_MODEL)->computeCellVolumes(); + return true; } @@ -311,7 +313,7 @@ void RimEclipseInputCase::loadAndSyncronizeInputProperties() progInfo.setProgress(static_cast(progress + inputPropCount)); // Check if there are more known property keywords left on file. If it is, read them and create inputProperty objects - for (const QString fileKeyword : fileKeywordSet) + for (const QString& fileKeyword : fileKeywordSet) { { QString resultName = this->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->makeResultNameUnique(fileKeyword); @@ -339,6 +341,14 @@ void RimEclipseInputCase::loadAndSyncronizeInputProperties() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseInputPropertyCollection* RimEclipseInputCase::inputPropertyCollection() +{ + return m_inputPropertyCollection(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -397,9 +407,19 @@ void RimEclipseInputCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder auto group = uiOrdering.addNewGroup("Case Options"); group->add(&activeFormationNames); - group->add(&flipXAxis); - group->add(&flipYAxis); + group->add(&m_flipXAxis); + group->add(&m_flipYAxis); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseInputCase::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + uiTreeOrdering.add(&m_inputPropertyCollection); + RimEclipseCase::defineUiTreeOrdering(uiTreeOrdering, uiConfigName); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimEclipseInputCase.h b/ApplicationCode/ProjectDataModel/RimEclipseInputCase.h index 525a0f4231..62af5761cc 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseInputCase.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseInputCase.h @@ -43,24 +43,23 @@ class RimEclipseInputCase : public RimEclipseCase public: RimEclipseInputCase(); - virtual ~RimEclipseInputCase(); - - // Fields - caf::PdmChildField m_inputPropertyCollection; + ~RimEclipseInputCase() override; // File open methods bool openDataFileSet(const QStringList& fileNames); void loadAndSyncronizeInputProperties(); + RimEclipseInputPropertyCollection* inputPropertyCollection(); + // RimCase overrides - virtual bool openEclipseGridFile(); // Find grid file among file set. Read, Find read and validate property date. Syncronize child property sets. - virtual void reloadEclipseGridFile(); + bool openEclipseGridFile() override; + void reloadEclipseGridFile() override; // Overrides from RimCase - virtual QString locationOnDisc() const; - virtual QString gridFileName() const { return m_gridFileName();} + QString locationOnDisc() const override; + QString gridFileName() const override { return m_gridFileName();} - virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath); + void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath) override; void updateAdditionalFileFolder(const QString& newFolder); @@ -68,12 +67,15 @@ class RimEclipseInputCase : public RimEclipseCase std::vector additionalFiles() const; protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; private: cvf::ref createMockModel(QString modelName); +private: // Fields + caf::PdmChildField m_inputPropertyCollection; caf::PdmField m_gridFileName; caf::PdmProxyValueField< std::vector > m_additionalFiles; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.cpp b/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.cpp index 2890926008..8fc468f347 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.cpp @@ -60,8 +60,7 @@ RimEclipseInputProperty::RimEclipseInputProperty() CAF_PDM_InitField(&resolvedState, "ResolvedState", (ResolveStateEnum)UNKNOWN, "Data State", "", "", ""); resolvedState.uiCapability()->setUiReadOnly(true); - resolvedState.xmlCapability()->setIOReadable(false); - resolvedState.xmlCapability()->setIOWritable(false); + resolvedState.xmlCapability()->disableIO(); resolvedState.uiCapability()->setUiEditorTypeName(caf::PdmUiLineEditor::uiEditorTypeName()); fileName.uiCapability()->setUiReadOnly(true); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.h b/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.h index f8dbb9749a..5fcc0b30a5 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseInputProperty.h @@ -37,7 +37,7 @@ class RimEclipseInputProperty : public caf::PdmObject public: RimEclipseInputProperty(); - virtual ~RimEclipseInputProperty(); + ~RimEclipseInputProperty() override; enum ResolveState { @@ -56,6 +56,6 @@ class RimEclipseInputProperty : public caf::PdmObject caf::PdmField resolvedState; // ReadOnly and not writable // PdmObject Overrides - virtual caf::PdmFieldHandle* userDescriptionField() { return &resultName;} - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* userDescriptionField() override { return &resultName;} + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.h b/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.h index b7049d926e..ea9c409e14 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseInputPropertyCollection.h @@ -41,7 +41,7 @@ class RimEclipseInputPropertyCollection : public caf::PdmObject public: RimEclipseInputPropertyCollection(); - virtual ~RimEclipseInputPropertyCollection(); + ~RimEclipseInputPropertyCollection() override; std::vector findInputProperties(QString fileName); RimEclipseInputProperty* findInputProperty(QString resultName); diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp index ec2d91f925..3397e46477 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.cpp @@ -20,6 +20,9 @@ #include "RimEclipsePropertyFilter.h" +#include "RiaDefines.h" +#include "RiaFieldHandleTools.h" + #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" #include "RigFlowDiagResults.h" @@ -65,8 +68,7 @@ RimEclipsePropertyFilter::RimEclipsePropertyFilter() CAF_PDM_InitObject("Cell Property Filter", ":/CellFilter_Values.png", "", ""); CAF_PDM_InitFieldNoDefault(&obsoleteField_evaluationRegion, "EvaluationRegion", "Evaluation Region", "", "", ""); - obsoleteField_evaluationRegion.uiCapability()->setUiHidden(true); - obsoleteField_evaluationRegion.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&obsoleteField_evaluationRegion); CAF_PDM_InitFieldNoDefault(&resultDefinition, "ResultDefinition", "Result Definition", "", "", ""); resultDefinition = new RimEclipseResultDefinition(); @@ -77,8 +79,7 @@ RimEclipsePropertyFilter::RimEclipsePropertyFilter() resultDefinition.uiCapability()->setUiTreeChildrenHidden(true); CAF_PDM_InitField(&m_rangeLabelText, "Dummy_keyword", QString("Range Type"), "Range Type", "", "", ""); - m_rangeLabelText.xmlCapability()->setIOReadable(false); - m_rangeLabelText.xmlCapability()->setIOWritable(false); + m_rangeLabelText.xmlCapability()->disableIO(); m_rangeLabelText.uiCapability()->setUiReadOnly(true); CAF_PDM_InitField(&m_lowerBound, "LowerBound", 0.0, "Min", "", "", ""); @@ -139,11 +140,13 @@ void RimEclipsePropertyFilter::fieldChangedByUi(const caf::PdmFieldHandle* chang || &m_selectedCategoryValues == changedField || &m_useCategorySelection == changedField) { + this->resultDefinition->loadResult(); + this->computeResultValueRange(); updateFilterName(); this->updateIconState(); this->uiCapability()->updateConnectedEditors(); - parentContainer()->updateDisplayModelNotifyManagedViews(); + parentContainer()->updateDisplayModelNotifyManagedViews(this); } } @@ -389,12 +392,17 @@ void RimEclipsePropertyFilter::computeResultValueRange() } else if (resultDefinition->resultVariable() == RiaDefines::completionTypeResultName()) { - std::vector ctNames; - for (const QString& ctName : caf::AppEnum::uiTexts()) + std::vector componentTypes = + { + RiaDefines::WELL_PATH, RiaDefines::PERFORATION_INTERVAL, + RiaDefines::FISHBONES, RiaDefines::FRACTURE + }; + std::vector> ctNamesAndValues; + for (RiaDefines::WellPathComponentType type : componentTypes) { - ctNames.push_back(ctName); + ctNamesAndValues.push_back(std::make_pair(caf::AppEnum::uiText(type), type)); } - setCategoryNames(ctNames); + setCategoryNamesAndValues(ctNamesAndValues); } else { diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h index 506fb9a1b1..333ffc8f44 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilter.h @@ -37,7 +37,7 @@ class RimEclipsePropertyFilter : public RimPropertyFilter public: RimEclipsePropertyFilter(); - virtual ~RimEclipsePropertyFilter(); + ~RimEclipsePropertyFilter() override; caf::PdmChildField resultDefinition; @@ -49,16 +49,16 @@ class RimEclipsePropertyFilter : public RimPropertyFilter void computeResultValueRange(); void updateFromCurrentTimeStep(); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void initAfterRead() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void initAfterRead() override; void updateUiFieldsFromActiveResult(); protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; private: friend class RimEclipsePropertyFilterCollection; diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.cpp index 5c7709e76f..58fd2c7960 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.cpp @@ -72,8 +72,11 @@ void RimEclipsePropertyFilterCollection::loadAndInitializePropertyFilters() RimEclipsePropertyFilter* propertyFilter = propertyFilters[i]; propertyFilter->resultDefinition->setEclipseCase(reservoirView()->eclipseCase()); propertyFilter->initAfterRead(); - propertyFilter->resultDefinition->loadResult(); - propertyFilter->computeResultValueRange(); + if (isActive() && propertyFilter->isActive()) + { + propertyFilter->resultDefinition->loadResult(); + propertyFilter->computeResultValueRange(); + } } } diff --git a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.h b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.h index 7abdeb7490..238699ba42 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipsePropertyFilterCollection.h @@ -36,7 +36,7 @@ class RimEclipsePropertyFilterCollection : public RimPropertyFilterCollection CAF_PDM_HEADER_INIT; public: RimEclipsePropertyFilterCollection(); - virtual ~RimEclipsePropertyFilterCollection(); + ~RimEclipsePropertyFilterCollection() override; RimEclipseView* reservoirView(); @@ -44,16 +44,16 @@ class RimEclipsePropertyFilterCollection : public RimPropertyFilterCollection caf::PdmChildArrayField propertyFilters; // Methods - bool hasActiveFilters() const; - bool hasActiveDynamicFilters() const; + bool hasActiveFilters() const override; + bool hasActiveDynamicFilters() const override; bool isUsingFormationNames() const; - void loadAndInitializePropertyFilters(); + void loadAndInitializePropertyFilters() override; - void updateIconState(); + void updateIconState() override; void updateFromCurrentTimeStep(); protected: // Overridden methods - virtual void initAfterRead(); + void initAfterRead() override; }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp index 28c0c2d5a0..22c91a5c69 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.cpp @@ -20,8 +20,11 @@ #include "RimEclipseResultCase.h" +#include "RiaApplication.h" +#include "RiaFieldHandleTools.h" #include "RiaLogging.h" #include "RiaPreferences.h" +#include "RiaRegressionTestRunner.h" #include "RifEclipseOutputFileTools.h" #include "RifReaderEclipseOutput.h" @@ -34,11 +37,13 @@ #include "RigFlowDiagSolverInterface.h" #include "RigMainGrid.h" +#include "RimDialogData.h" #include "RimEclipseCellColors.h" #include "RimEclipseView.h" #include "RimFlowDiagSolution.h" #include "RimMockModelSettings.h" #include "RimProject.h" +#include "RimProject.h" #include "RimReservoirCellResultsStorage.h" #include "RimTimeStepFilter.h" #include "RimTools.h" @@ -56,7 +61,6 @@ #include - CAF_PDM_SOURCE_INIT(RimEclipseResultCase, "EclipseCase"); //-------------------------------------------------------------------------------------------------- /// @@ -69,6 +73,10 @@ RimEclipseResultCase::RimEclipseResultCase() CAF_PDM_InitField(&caseFileName, "CaseFileName", QString(), "Case File Name", "", "" ,""); caseFileName.uiCapability()->setUiReadOnly(true); + CAF_PDM_InitFieldNoDefault(&m_unitSystem, "UnitSystem", "Unit System", "", "", ""); + m_unitSystem.registerGetMethod(RiaApplication::instance()->project(), &RimProject::commonUnitSystemForAllCases); + m_unitSystem.uiCapability()->setUiReadOnly(true); + CAF_PDM_InitFieldNoDefault (&m_flowDiagSolutions, "FlowDiagSolutions", "Flow Diagnostics Solutions", "", "", ""); m_flowDiagSolutions.uiCapability()->setUiHidden(true); m_flowDiagSolutions.uiCapability()->setUiTreeHidden(true); @@ -76,12 +84,11 @@ RimEclipseResultCase::RimEclipseResultCase() // Obsolete, unused field CAF_PDM_InitField(&caseDirectory, "CaseFolder", QString(), "Directory", "", "" ,""); - caseDirectory.xmlCapability()->setIOWritable(false); - caseDirectory.uiCapability()->setUiHidden(true); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&caseDirectory); - flipXAxis.xmlCapability()->setIOWritable(true); + m_flipXAxis.xmlCapability()->setIOWritable(true); //flipXAxis.uiCapability()->setUiHidden(true); - flipYAxis.xmlCapability()->setIOWritable(true); + m_flipYAxis.xmlCapability()->setIOWritable(true); //flipYAxis.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&m_sourSimFileName, "SourSimFileName", QString(), "SourSim File Name", "", "", ""); @@ -131,47 +138,40 @@ bool RimEclipseResultCase::importGridAndResultMetaData(bool showTimeStepFilter) cvf::ref readerEclipseOutput = new RifReaderEclipseOutput; readerEclipseOutput->setFilenamesWithFaults(this->filesContainingFaults()); - if (showTimeStepFilter) + cvf::ref restartDataAccess = RifEclipseOutputFileTools::createDynamicResultAccess(caseFileName()); + { - cvf::ref restartDataAccess = RifEclipseOutputFileTools::createDynamicResultAccess(caseFileName()); - if (restartDataAccess.isNull()) - { - return false; - } + std::vector timeSteps; + std::vector daysSinceSimulationStart; + if (restartDataAccess.notNull()) { - std::vector timeSteps; - std::vector daysSinceSimulationStart; - restartDataAccess->timeSteps(&timeSteps, &daysSinceSimulationStart); - - // Restore cursor as the progress dialog is active - QApplication::restoreOverrideCursor(); - - // Show GUI to select time steps - - m_timeStepFilter->setTimeStepsFromFile(timeSteps); - - caf::PdmUiPropertyViewDialog propertyDialog(nullptr, m_timeStepFilter, "Time Step Filter", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - propertyDialog.resize(QSize(400, 400)); - - if (propertyDialog.exec() != QDialog::Accepted) - { - return false; - } - - m_timeStepFilter->clearTimeStepsFromFile(); - - // Set cursor in wait state to continue display of progress dialog including - // wait cursor - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); } - - readerEclipseOutput->setFileDataAccess(restartDataAccess.p()); + m_timeStepFilter->setTimeStepsFromFile(timeSteps); } - readerEclipseOutput->setTimeStepFilter(m_timeStepFilter->filteredNativeTimeStepIndices()); + if (showTimeStepFilter) + { + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, m_timeStepFilter, "Time Step Filter", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + propertyDialog.resize(QSize(400, 400)); + + // Push arrow cursor onto the cursor stack so it takes over from the wait cursor. + QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); + // Show GUI to select time steps + int dialogReturnValue = propertyDialog.exec(); + // Pop arrow cursor off the cursor stack so that the previous (wait) cursor takes over. + QApplication::restoreOverrideCursor(); + if (dialogReturnValue != QDialog::Accepted) + { + return false; + } + m_timeStepFilter->updateFilteredTimeStepsFromUi(); + } + readerEclipseOutput->setFileDataAccess(restartDataAccess.p()); + readerEclipseOutput->setTimeStepFilter(m_timeStepFilter->filteredTimeSteps()); + cvf::ref eclipseCase = new RigEclipseCaseData(this); if (!readerEclipseOutput->open(caseFileName(), eclipseCase.p())) { @@ -222,7 +222,16 @@ bool RimEclipseResultCase::importGridAndResultMetaData(bool showTimeStepFilter) RifReaderEclipseOutput* outReader = dynamic_cast(readerInterface.p()); outReader->setHdf5FileName(m_sourSimFileName()); } + + RiaApplication* app = RiaApplication::instance(); + if (app->preferences()->autocomputeDepthRelatedProperties) + { + results(RiaDefines::MATRIX_MODEL)->computeDepthRelatedResults(); + results(RiaDefines::FRACTURE_MODEL)->computeDepthRelatedResults(); + } + results(RiaDefines::MATRIX_MODEL)->computeCellVolumes(); + return true; } @@ -384,16 +393,17 @@ cvf::ref RimEclipseResultCase::createMockModel(QString model { QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); - RimMockModelSettings rimMockModelSettings; - caf::PdmSettings::readFieldsFromApplicationStore(&rimMockModelSettings); + RimMockModelSettings* mockModelSettings = RiaApplication::instance()->project()->dialogData()->mockModelSettings(); - caf::PdmUiPropertyViewDialog propertyDialog(nullptr, &rimMockModelSettings, "Customize Mock Model", ""); - if (propertyDialog.exec() == QDialog::Accepted) + if (!RiaRegressionTestRunner::instance()->isRunningRegressionTests()) { - QApplication::restoreOverrideCursor(); - - caf::PdmSettings::writeFieldsToApplicationStore(&rimMockModelSettings); + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, mockModelSettings, "Customize Mock Model", ""); + if (propertyDialog.exec() == QDialog::Accepted) + { + } + } + { double startX = 0; double startY = 0; double startZ = 0; @@ -408,16 +418,14 @@ cvf::ref RimEclipseResultCase::createMockModel(QString model double offsetZ = 0; mockFileInterface->setWorldCoordinates(cvf::Vec3d(startX + offsetX, startY + offsetY, startZ + offsetZ), cvf::Vec3d(startX + widthX + offsetX, startY + widthY + offsetY, startZ + widthZ + offsetZ)); - mockFileInterface->setGridPointDimensions(cvf::Vec3st(rimMockModelSettings.cellCountX + 1, rimMockModelSettings.cellCountY + 1, rimMockModelSettings.cellCountZ + 1)); - mockFileInterface->setResultInfo(rimMockModelSettings.resultCount, rimMockModelSettings.timeStepCount); + mockFileInterface->setGridPointDimensions(cvf::Vec3st(mockModelSettings->cellCountX + 1, mockModelSettings->cellCountY + 1, mockModelSettings->cellCountZ + 1)); + mockFileInterface->setResultInfo(mockModelSettings->resultCount, mockModelSettings->timeStepCount); mockFileInterface->enableWellData(false); mockFileInterface->open("", reservoir.p()); } - else - { - QApplication::restoreOverrideCursor(); - } + + QApplication::restoreOverrideCursor(); } this->setReservoirData( reservoir.p() ); @@ -526,19 +534,18 @@ RifReaderEclipseRft* RimEclipseResultCase::rftReader() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipseResultCase::setGridFileName(const QString& caseFileName) +void RimEclipseResultCase::setGridFileName(const QString& fileName) { - this->caseFileName = caseFileName; + this->caseFileName = fileName; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipseResultCase::setCaseInfo(const QString& userDescription, const QString& caseFileName) +void RimEclipseResultCase::setCaseInfo(const QString& userDescription, const QString& fileName) { this->caseUserDescription = userDescription; - this->caseFileName = caseFileName; + this->caseFileName = fileName; RimProject* proj = RiaApplication::instance()->project(); proj->assignCaseIdToCase(this); @@ -587,11 +594,12 @@ void RimEclipseResultCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrde uiOrdering.add(&caseUserDescription); uiOrdering.add(&caseId); uiOrdering.add(&caseFileName); + uiOrdering.add(&m_unitSystem); auto group = uiOrdering.addNewGroup("Case Options"); group->add(&activeFormationNames); - group->add(&flipXAxis); - group->add(&flipYAxis); + group->add(&m_flipXAxis); + group->add(&m_flipYAxis); if (eclipseCaseData() && eclipseCaseData()->results(RiaDefines::MATRIX_MODEL) diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.h b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.h index ef6aa46d7f..8b8dcdc9f9 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultCase.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultCase.h @@ -20,8 +20,12 @@ #pragma once +#include "RiaEclipseUnitTools.h" + #include "RimEclipseCase.h" +#include + class RifReaderInterface; class RigMainGrid; class RimFlowDiagSolution; @@ -39,25 +43,25 @@ class RimEclipseResultCase : public RimEclipseCase public: RimEclipseResultCase(); - virtual ~RimEclipseResultCase(); + ~RimEclipseResultCase() override; - void setGridFileName(const QString& caseFileName); - void setCaseInfo(const QString& userDescription, const QString& caseFileName); + void setGridFileName(const QString& fileName); + void setCaseInfo(const QString& userDescription, const QString& fileName); void setSourSimFileName(const QString& fileName); bool hasSourSimFile(); - virtual bool openEclipseGridFile(); + bool openEclipseGridFile() override; bool importGridAndResultMetaData(bool showTimeStepFilter); - virtual void reloadEclipseGridFile(); + void reloadEclipseGridFile() override; bool openAndReadActiveCellData(RigEclipseCaseData* mainEclipseCase); void readGridDimensions(std::vector< std::vector >& gridDimensions); // Overrides from RimCase - virtual QString locationOnDisc() const; - virtual QString gridFileName() const { return caseFileName();} - virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath); + QString locationOnDisc() const override; + QString gridFileName() const override { return caseFileName();} + void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; RimFlowDiagSolution* defaultFlowDiagSolution(); std::vector flowDiagSolutions(); @@ -66,8 +70,8 @@ class RimEclipseResultCase : public RimEclipseCase RifReaderEclipseRft* rftReader(); protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; private: void loadAndUpdateSourSimData(); @@ -75,9 +79,9 @@ class RimEclipseResultCase : public RimEclipseCase private: cvf::ref createMockModel(QString modelName); - virtual void initAfterRead(); + void initAfterRead() override; - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; cvf::ref m_flowDagSolverInterface; @@ -85,6 +89,7 @@ class RimEclipseResultCase : public RimEclipseCase // Fields: caf::PdmField caseFileName; + caf::PdmProxyValueField m_unitSystem; caf::PdmChildArrayField m_flowDiagSolutions; caf::PdmField m_sourSimFileName; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp index 0c0be159a1..936aa73dbe 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.cpp @@ -24,10 +24,12 @@ #include "RigCaseCellResultsData.h" #include "RigEclipseCaseData.h" #include "RigFlowDiagResultAddress.h" +#include "RigFlowDiagResults.h" #include "Rim3dView.h" #include "Rim3dWellLogCurve.h" #include "RimCellEdgeColors.h" +#include "RimContourMapProjection.h" #include "RimEclipseCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseFaultColors.h" @@ -43,8 +45,12 @@ #include "RimWellLogExtractionCurve.h" #include "cafPdmUiListEditor.h" +#include "cafPdmUiToolButtonEditor.h" +#include "cafPdmUiTreeSelectionEditor.h" #include "cafUtils.h" +#include + namespace caf { template<> @@ -81,8 +87,17 @@ RimEclipseResultDefinition::RimEclipseResultDefinition() CAF_PDM_InitFieldNoDefault(&m_flowSolution, "FlowDiagSolution", "Solution", "", "", ""); m_flowSolution.uiCapability()->setUiHidden(true); - CAF_PDM_InitFieldNoDefault(&m_selectedTracers, "SelectedTracers", "Tracers", "", "", ""); - m_selectedTracers.uiCapability()->setUiHidden(true); + // One single tracer list has been split into injectors and producers. + // The old list is defined as injectors and we'll have to move any producers in old projects. + CAF_PDM_InitFieldNoDefault(&m_selectedTracers_OBSOLETE, "SelectedTracers", "Tracers", "", "", ""); + m_selectedTracers_OBSOLETE.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_selectedInjectorTracers, "SelectedInjectorTracers", "Injector Tracers", "", "", ""); + m_selectedInjectorTracers.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_selectedProducerTracers, "SelectedProducerTracers", "Producer Tracers", "", "", ""); + m_selectedProducerTracers.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_selectedSouringTracers, "SelectedSouringTracers", "Tracers", "", "", ""); m_selectedSouringTracers.uiCapability()->setUiHidden(true); @@ -93,35 +108,40 @@ RimEclipseResultDefinition::RimEclipseResultDefinition() // Ui only fields CAF_PDM_InitFieldNoDefault(&m_resultTypeUiField, "MResultType", "Type", "", "", ""); - m_resultTypeUiField.xmlCapability()->setIOReadable(false); - m_resultTypeUiField.xmlCapability()->setIOWritable(false); + m_resultTypeUiField.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault(&m_porosityModelUiField, "MPorosityModelType", "Porosity", "", "", ""); - m_porosityModelUiField.xmlCapability()->setIOReadable(false); - m_porosityModelUiField.xmlCapability()->setIOWritable(false); + m_porosityModelUiField.xmlCapability()->disableIO(); CAF_PDM_InitField(&m_resultVariableUiField, "MResultVariable", RiaDefines::undefinedResultName(), "Result Property", "", "", "" ); - m_resultVariableUiField.xmlCapability()->setIOReadable(false); - m_resultVariableUiField.xmlCapability()->setIOWritable(false); + m_resultVariableUiField.xmlCapability()->disableIO(); m_resultVariableUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); CAF_PDM_InitFieldNoDefault(&m_flowSolutionUiField, "MFlowDiagSolution", "Solution", "", "", ""); - m_flowSolutionUiField.xmlCapability()->setIOReadable(false); - m_flowSolutionUiField.xmlCapability()->setIOWritable(false); + m_flowSolutionUiField.xmlCapability()->disableIO(); m_flowSolutionUiField.uiCapability()->setUiHidden(true); // For now since there are only one to choose from - CAF_PDM_InitFieldNoDefault(&m_selectedTracersUiField, "MSelectedTracers", " ", "", "", ""); - m_selectedTracersUiField.xmlCapability()->setIOReadable(false); - m_selectedTracersUiField.xmlCapability()->setIOWritable(false); - m_selectedTracersUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); - + CAF_PDM_InitField(&m_syncInjectorToProducerSelection, "MSyncSelectedInjProd", false, "Add Communicators ->", "", "", ""); + m_syncInjectorToProducerSelection.uiCapability()->setUiEditorTypeName(caf::PdmUiToolButtonEditor::uiEditorTypeName()); + + CAF_PDM_InitField(&m_syncProducerToInjectorSelection, "MSyncSelectedProdInj", false, "<- Add Communicators", "", "", ""); + m_syncProducerToInjectorSelection.uiCapability()->setUiEditorTypeName(caf::PdmUiToolButtonEditor::uiEditorTypeName()); + + + CAF_PDM_InitFieldNoDefault(&m_selectedInjectorTracersUiField, "MSelectedInjectorTracers", "Injector Tracers", "", "", ""); + m_selectedInjectorTracersUiField.xmlCapability()->disableIO(); + m_selectedInjectorTracersUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName()); + m_selectedInjectorTracersUiField.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + CAF_PDM_InitFieldNoDefault(&m_selectedProducerTracersUiField, "MSelectedProducerTracers", "Producer Tracers", "", "", ""); + m_selectedProducerTracersUiField.xmlCapability()->disableIO(); + m_selectedProducerTracersUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName()); + m_selectedProducerTracersUiField.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + CAF_PDM_InitFieldNoDefault(&m_selectedSouringTracersUiField, "MSelectedSouringTracers", "Tracers", "", "", ""); - m_selectedSouringTracersUiField.xmlCapability()->setIOReadable(false); - m_selectedSouringTracersUiField.xmlCapability()->setIOWritable(false); + m_selectedSouringTracersUiField.xmlCapability()->disableIO(); m_selectedSouringTracersUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); - - CAF_PDM_InitFieldNoDefault(&m_selectedTracersUiFieldFilter, "SelectedTracersFilter", "Filter", "", "", ""); } //-------------------------------------------------------------------------------------------------- @@ -141,7 +161,8 @@ void RimEclipseResultDefinition::simpleCopy(const RimEclipseResultDefinition* ot this->setPorosityModel(other->porosityModel()); this->setResultType(other->resultType()); this->setFlowSolution(other->m_flowSolution()); - this->setSelectedTracers(other->m_selectedTracers()); + this->setSelectedInjectorTracers(other->m_selectedInjectorTracers()); + this->setSelectedProducerTracers(other->m_selectedProducerTracers()); this->setSelectedSouringTracers(other->m_selectedSouringTracers()); m_flowTracerSelectionMode = other->m_flowTracerSelectionMode(); m_phaseSelection = other->m_phaseSelection; @@ -194,13 +215,22 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha m_resultVariableUiField = resultVariable(); } - if (isFlowDiagFieldsRelevant) m_selectedTracersUiField = m_selectedTracers(); - else m_selectedTracersUiField = std::vector(); + if (isFlowDiagFieldsRelevant) + { + m_selectedInjectorTracersUiField = m_selectedInjectorTracers(); + m_selectedProducerTracersUiField = m_selectedProducerTracers(); + } + else + { + m_selectedInjectorTracersUiField = std::vector(); + m_selectedProducerTracersUiField = std::vector(); + } } else { m_resultVariableUiField = ""; - m_selectedTracersUiField = std::vector(); + m_selectedInjectorTracersUiField = std::vector(); + m_selectedProducerTracersUiField = std::vector(); } } @@ -213,7 +243,8 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha if (m_resultTypeUiField() == RiaDefines::FLOW_DIAGNOSTICS) { m_flowSolution = m_flowSolutionUiField(); - m_selectedTracers = m_selectedTracersUiField(); + m_selectedInjectorTracers = m_selectedInjectorTracersUiField(); + m_selectedProducerTracers = m_selectedProducerTracersUiField(); } else if (m_resultTypeUiField() == RiaDefines::INJECTION_FLOODING) { @@ -222,39 +253,35 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha loadDataAndUpdate(); } - if ( &m_selectedTracersUiField == changedField ) + if (&m_flowTracerSelectionMode == changedField) { - m_flowSolution = m_flowSolutionUiField(); + loadDataAndUpdate(); + } - if (m_selectedTracersUiFieldFilter().isEmpty()) - { - m_selectedTracers = m_selectedTracersUiField(); - } - else - { - auto filteredTracerNames = tracerNamesMatchingFilter(); - // Keep selected strings not part of currently visible selection items - std::vector newSelection; - for (auto selectedTracer : m_selectedTracers()) - { - if (std::find(begin(filteredTracerNames), end(filteredTracerNames), selectedTracer) == end(filteredTracerNames)) - { - newSelection.push_back(selectedTracer); - } - } + if (&m_selectedInjectorTracersUiField == changedField ) + { + changedTracerSelectionField(true); + } - for (auto selectedTracerUi : m_selectedTracersUiField()) - { - newSelection.push_back(selectedTracerUi); - } + if (&m_selectedProducerTracersUiField == changedField) + { + changedTracerSelectionField(false); + } - m_selectedTracers = newSelection; - } + if (&m_syncInjectorToProducerSelection == changedField) + { + syncInjectorToProducerSelection(); + m_syncInjectorToProducerSelection = false; + } - loadDataAndUpdate(); + if (&m_syncProducerToInjectorSelection == changedField) + { + syncProducerToInjectorSelection(); + m_syncProducerToInjectorSelection = false; } + if (&m_selectedSouringTracersUiField == changedField) { if (!m_resultVariable().isEmpty()) @@ -275,27 +302,24 @@ void RimEclipseResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha loadDataAndUpdate(); } - if (&m_selectedTracersUiFieldFilter == changedField) - { - auto visibleTracerNames = tracerNamesMatchingFilter(); - - std::vector subSelection; + updateAnyFieldHasChanged(); +} - // Remove hidden items from selection - for (auto selectedTracer : m_selectedTracers()) - { - if (std::find(begin(visibleTracerNames), end(visibleTracerNames), selectedTracer) != end(visibleTracerNames)) - { - subSelection.push_back(selectedTracer); - } - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::changedTracerSelectionField(bool injector) +{ + m_flowSolution = m_flowSolutionUiField(); - m_selectedTracersUiField = subSelection; + std::vector& selectedTracers = injector ? m_selectedInjectorTracers.v() + : m_selectedProducerTracers.v(); + std::vector& selectedTracersUi = injector ? m_selectedInjectorTracersUiField.v() + : m_selectedProducerTracersUiField.v(); - updateConnectedEditors(); - } + selectedTracers = selectedTracersUi; - updateAnyFieldHasChanged(); + loadDataAndUpdate(); } //-------------------------------------------------------------------------------------------------- @@ -344,6 +368,13 @@ void RimEclipseResultDefinition::updateAnyFieldHasChanged() { rim3dWellLogCurve->resetMinMaxValuesAndUpdateUI(); } + + RimContourMapProjection* contourMap = nullptr; + this->firstAncestorOrThisOfType(contourMap); + if (contourMap) + { + contourMap->updatedWeightingResult(); + } } //-------------------------------------------------------------------------------------------------- @@ -355,30 +386,26 @@ void RimEclipseResultDefinition::setTofAndSelectTracer(const QString& tracerName setResultVariable("TOF"); setFlowDiagTracerSelectionType(FLOW_TR_BY_SELECTION); - std::vector tracers; - tracers.push_back(tracerName); - setSelectedTracers(tracers); - if (m_flowSolution() == nullptr) { assignFlowSolutionFromCase(); } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::assignFlowSolutionFromCase() -{ - RimFlowDiagSolution* defaultFlowDiagSolution = nullptr; - - RimEclipseResultCase* eclCase = dynamic_cast(m_eclipseCase.p()); - if (eclCase) + if (m_flowSolution()) { - defaultFlowDiagSolution = eclCase->defaultFlowDiagSolution(); + RimFlowDiagSolution::TracerStatusType tracerStatus = m_flowSolution()->tracerStatusOverall(tracerName); + + std::vector tracers; + tracers.push_back(tracerName); + if (tracerStatus == RimFlowDiagSolution::INJECTOR) + { + setSelectedInjectorTracers(tracers); + } + else if (tracerStatus == RimFlowDiagSolution::PRODUCER) + { + setSelectedProducerTracers(tracers); + } } - this->setFlowSolution(defaultFlowDiagSolution); } //-------------------------------------------------------------------------------------------------- @@ -526,11 +553,11 @@ QList RimEclipseResultDefinition::calculateValueOptions( { if ( fieldNeedingOptions == &m_resultVariableUiField ) { - options.push_back(caf::PdmOptionItemInfo("Time Of Flight (Average)", RIG_FLD_TOF_RESNAME)); + options.push_back(caf::PdmOptionItemInfo(timeOfFlightString(false), RIG_FLD_TOF_RESNAME)); if (m_phaseSelection() == RigFlowDiagResultAddress::PHASE_ALL) { options.push_back(caf::PdmOptionItemInfo("Tracer Cell Fraction (Sum)", RIG_FLD_CELL_FRACTION_RESNAME)); - options.push_back(caf::PdmOptionItemInfo("Max Fraction Tracer", RIG_FLD_MAX_FRACTION_TRACER_RESNAME)); + options.push_back(caf::PdmOptionItemInfo(maxFractionTracerString(false), RIG_FLD_MAX_FRACTION_TRACER_RESNAME)); options.push_back(caf::PdmOptionItemInfo("Injector Producer Communication", RIG_FLD_COMMUNICATION_RESNAME)); } } @@ -546,33 +573,13 @@ QList RimEclipseResultDefinition::calculateValueOptions( } } } - else if (fieldNeedingOptions == &m_selectedTracersUiField) + else if (fieldNeedingOptions == &m_selectedInjectorTracersUiField) { - RimFlowDiagSolution* flowSol = m_flowSolutionUiField(); - if (flowSol) - { - std::vector tracerNames = tracerNamesMatchingFilter(); - std::map prefixedTracerNamesMap; - for ( const QString& tracerName : tracerNames ) - { - RimFlowDiagSolution::TracerStatusType status = flowSol->tracerStatusOverall(tracerName); - QString prefix; - switch ( status ) - { - case RimFlowDiagSolution::INJECTOR: prefix = "I : "; break; - case RimFlowDiagSolution::PRODUCER: prefix = "P : "; break; - case RimFlowDiagSolution::VARYING: prefix = "I/P: "; break; - case RimFlowDiagSolution::UNDEFINED:prefix = "U : "; break; - } - - if (status != RimFlowDiagSolution::CLOSED) prefixedTracerNamesMap[prefix + tracerName] = tracerName; - } - - for (auto nameIt: prefixedTracerNamesMap) - { - options.push_back(caf::PdmOptionItemInfo(nameIt.first, QVariant(nameIt.second))); - } - } + options = calcOptionsForSelectedTracerField(true); + } + else if (fieldNeedingOptions == &m_selectedProducerTracersUiField) + { + options = calcOptionsForSelectedTracerField(false); } } else if (m_resultTypeUiField() == RiaDefines::INJECTION_FLOODING) @@ -614,126 +621,6 @@ QList RimEclipseResultDefinition::calculateValueOptions( return options; } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QList RimEclipseResultDefinition::calcOptionsForVariableUiFieldStandard() -{ - CVF_ASSERT(m_resultTypeUiField() != RiaDefines::FLOW_DIAGNOSTICS && m_resultTypeUiField() != RiaDefines::INJECTION_FLOODING); - - if (this->currentGridCellResults()) - { - QList optionList; - - QStringList cellCenterResultNames; - QStringList cellFaceResultNames; - - RigCaseCellResultsData* results = this->currentGridCellResults(); - foreach(QString s, getResultNamesForCurrentUiResultType()) - { - if (s == RiaDefines::completionTypeResultName() && results->timeStepDates().empty()) continue; - - if (RiaDefines::isPerCellFaceResult(s)) - { - cellFaceResultNames.push_back(s); - } - else - { - cellCenterResultNames.push_back(s); - } - } - - cellCenterResultNames.sort(); - cellFaceResultNames.sort(); - - // Cell Center result names - foreach(QString s, cellCenterResultNames) - { - optionList.push_back(caf::PdmOptionItemInfo(s, s)); - } - - // Ternary Result - bool hasAtLeastOneTernaryComponent = false; - if (cellCenterResultNames.contains("SOIL")) hasAtLeastOneTernaryComponent = true; - else if (cellCenterResultNames.contains("SGAS")) hasAtLeastOneTernaryComponent = true; - else if (cellCenterResultNames.contains("SWAT")) hasAtLeastOneTernaryComponent = true; - - if (m_resultTypeUiField == RiaDefines::DYNAMIC_NATIVE && hasAtLeastOneTernaryComponent) - { - optionList.push_front(caf::PdmOptionItemInfo(RiaDefines::ternarySaturationResultName(), RiaDefines::ternarySaturationResultName())); - } - - // Cell Face result names - bool showDerivedResultsFirstInList = false; - { - RimEclipseFaultColors* rimEclipseFaultColors = nullptr; - this->firstAncestorOrThisOfType(rimEclipseFaultColors); - - if ( rimEclipseFaultColors ) showDerivedResultsFirstInList = true; - } - - foreach(QString s, cellFaceResultNames) - { - if (showDerivedResultsFirstInList) - { - optionList.push_front(caf::PdmOptionItemInfo(s, s)); - } - else - { - optionList.push_back(caf::PdmOptionItemInfo(s, s)); - } - } - - optionList.push_front(caf::PdmOptionItemInfo(RiaDefines::undefinedResultName(), RiaDefines::undefinedResultName())); - - // Remove Per Cell Face options - { - RimPlotCurve* curve = nullptr; - this->firstAncestorOrThisOfType(curve); - - RimEclipsePropertyFilter* propFilter = nullptr; - this->firstAncestorOrThisOfType(propFilter); - - RimCellEdgeColors* cellEdge = nullptr; - this->firstAncestorOrThisOfType(cellEdge); - - if ( propFilter || curve || cellEdge ) - { - removePerCellFaceOptionItems(optionList); - } - } - - return optionList; - } - - return QList(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QStringList RimEclipseResultDefinition::getResultNamesForCurrentUiResultType() -{ - if ( m_resultTypeUiField() != RiaDefines::FLOW_DIAGNOSTICS ) - { - RigCaseCellResultsData* cellResultsStorage = currentGridCellResults(); - - if ( !cellResultsStorage ) return QStringList(); - - return cellResultsStorage->resultNames(m_resultTypeUiField()); - } - else - { - QStringList flowVars; - flowVars.push_back(RIG_FLD_TOF_RESNAME); - flowVars.push_back(RIG_FLD_CELL_FRACTION_RESNAME); - flowVars.push_back(RIG_FLD_MAX_FRACTION_TRACER_RESNAME); - flowVars.push_back(RIG_FLD_COMMUNICATION_RESNAME); - return flowVars; - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -785,7 +672,11 @@ RigFlowDiagResultAddress RimEclipseResultDefinition::flowDiagResAddress() const std::set selTracerNames; if (m_flowTracerSelectionMode == FLOW_TR_BY_SELECTION) { - for (const QString& tName : m_selectedTracers()) + for (const QString& tName : m_selectedInjectorTracers()) + { + selTracerNames.insert(tName.toStdString()); + } + for (const QString& tName : m_selectedProducerTracers()) { selTracerNames.insert(tName.toStdString()); } @@ -851,19 +742,7 @@ QString RimEclipseResultDefinition::resultVariableUiName() const { if (resultType() == RiaDefines::FLOW_DIAGNOSTICS) { - QString fullName; - - if (m_flowTracerSelectionMode() == FLOW_TR_BY_SELECTION) - { - fullName = QString::fromStdString(flowDiagResAddress().uiText()); - } - else - { - fullName = QString::fromStdString(flowDiagResAddress().uiShortText()); - fullName += QString(" (%1)").arg(m_flowTracerSelectionMode().uiText()); - } - - return fullName; + return flowDiagResUiText(false, 32); } return m_resultVariable(); @@ -876,28 +755,7 @@ QString RimEclipseResultDefinition::resultVariableUiShortName() const { if (resultType() == RiaDefines::FLOW_DIAGNOSTICS) { - QString shortName; - - if (m_flowTracerSelectionMode() == FLOW_TR_BY_SELECTION) - { - QString candidate = QString::fromStdString(flowDiagResAddress().uiText()); - - int stringSizeLimit = 32; - if (candidate.size() > stringSizeLimit) - { - candidate = candidate.left(stringSizeLimit); - candidate += "..."; - } - - shortName = candidate; - } - else - { - shortName = QString::fromStdString(flowDiagResAddress().uiShortText()); - shortName += QString(" (%1)").arg(m_flowTracerSelectionMode().uiText()); - } - - return shortName; + return flowDiagResUiText(true, 24); } return m_resultVariable(); @@ -1008,7 +866,43 @@ void RimEclipseResultDefinition::initAfterRead() m_resultVariableUiField = m_resultVariable; m_flowSolutionUiField = m_flowSolution(); - m_selectedTracersUiField = m_selectedTracers; + m_selectedInjectorTracersUiField = m_selectedInjectorTracers; + + if (m_flowSolution() == nullptr) + { + assignFlowSolutionFromCase(); + } + + if (m_flowSolution()) + { + std::vector selectedInjectorTracers; + std::vector selectedProducerTracers; + for (const QString& tracerName : m_selectedTracers_OBSOLETE()) + { + RimFlowDiagSolution::TracerStatusType tracerStatus = m_flowSolution()->tracerStatusOverall(tracerName); + if (tracerStatus == RimFlowDiagSolution::INJECTOR) + { + selectedInjectorTracers.push_back(tracerName); + } + else if (tracerStatus == RimFlowDiagSolution::PRODUCER) + { + selectedProducerTracers.push_back(tracerName); + } + else if (tracerStatus == RimFlowDiagSolution::VARYING || tracerStatus == RimFlowDiagSolution::UNDEFINED) + { + selectedInjectorTracers.push_back(tracerName); + selectedProducerTracers.push_back(tracerName); + } + } + if (!selectedInjectorTracers.empty()) + { + setSelectedInjectorTracers(selectedInjectorTracers); + } + if (!selectedProducerTracers.empty()) + { + setSelectedProducerTracers(selectedProducerTracers); + } + } this->updateUiIconFromToggleField(); } @@ -1058,23 +952,67 @@ void RimEclipseResultDefinition::setFlowSolution(RimFlowDiagSolution* flowSol) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimEclipseResultDefinition::setSelectedTracers(const std::vector& selectedTracers) { - this->m_selectedTracers = selectedTracers; - this->m_selectedTracersUiField = selectedTracers; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEclipseResultDefinition::setSelectedSouringTracers(const std::vector& selectedTracers) -{ - this->m_selectedSouringTracers = selectedTracers; - this->m_selectedSouringTracersUiField = selectedTracers; -} - + if (m_flowSolution() == nullptr) + { + assignFlowSolutionFromCase(); + } + if (m_flowSolution()) + { + std::vector injectorTracers; + std::vector producerTracers; + for (const QString& tracerName : selectedTracers) + { + RimFlowDiagSolution::TracerStatusType tracerStatus = m_flowSolution()->tracerStatusOverall(tracerName); + if (tracerStatus == RimFlowDiagSolution::INJECTOR) + { + injectorTracers.push_back(tracerName); + } + else if (tracerStatus == RimFlowDiagSolution::PRODUCER) + { + producerTracers.push_back(tracerName); + } + else if (tracerStatus == RimFlowDiagSolution::VARYING || tracerStatus == RimFlowDiagSolution::UNDEFINED) + { + injectorTracers.push_back(tracerName); + producerTracers.push_back(tracerName); + } + } + setSelectedInjectorTracers(injectorTracers); + setSelectedProducerTracers(producerTracers); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setSelectedInjectorTracers(const std::vector& selectedTracers) +{ + this->m_selectedInjectorTracers = selectedTracers; + this->m_selectedInjectorTracersUiField = selectedTracers; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setSelectedProducerTracers(const std::vector& selectedTracers) +{ + this->m_selectedProducerTracers = selectedTracers; + this->m_selectedProducerTracersUiField = selectedTracers; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::setSelectedSouringTracers(const std::vector& selectedTracers) +{ + this->m_selectedSouringTracers = selectedTracers; + this->m_selectedSouringTracersUiField = selectedTracers; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1137,21 +1075,6 @@ bool RimEclipseResultDefinition::isFlowDiagOrInjectionFlooding() const return false; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimEclipseResultDefinition::hasDualPorFractureResult() -{ - if (m_eclipseCase - && m_eclipseCase->eclipseCaseData()) - { - return m_eclipseCase->eclipseCaseData()->hasFractureResults(); - } - - return false; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1172,8 +1095,16 @@ void RimEclipseResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm if (m_flowTracerSelectionMode == FLOW_TR_BY_SELECTION) { - uiOrdering.add(&m_selectedTracersUiFieldFilter); - uiOrdering.add(&m_selectedTracersUiField); + caf::PdmUiGroup* selectionGroup = uiOrdering.addNewGroup("Tracer Selection"); + selectionGroup->setEnableFrame(false); + + caf::PdmUiGroup* injectorGroup = selectionGroup->addNewGroup("Injectors"); + injectorGroup->add(&m_selectedInjectorTracersUiField); + injectorGroup->add(&m_syncInjectorToProducerSelection); + + caf::PdmUiGroup* producerGroup = selectionGroup->addNewGroup("Producers", false); + producerGroup->add(&m_selectedProducerTracersUiField); + producerGroup->add(&m_syncProducerToInjectorSelection); } uiOrdering.add(&m_phaseSelection); @@ -1189,7 +1120,14 @@ void RimEclipseResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm uiOrdering.add(&m_selectedSouringTracersUiField); } - uiOrdering.add(&m_resultVariableUiField); + if (m_resultTypeUiField() == RiaDefines::FLOW_DIAGNOSTICS) + { + uiOrdering.add(&m_resultVariableUiField); + } + else + { + uiOrdering.add(&m_resultVariableUiField); + } uiOrdering.skipRemainingFields(true); } @@ -1199,14 +1137,375 @@ void RimEclipseResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm //-------------------------------------------------------------------------------------------------- void RimEclipseResultDefinition::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) { - if (m_resultTypeUiField() == RiaDefines::FLOW_DIAGNOSTICS - && field == &m_resultVariableUiField) + if (m_resultTypeUiField() == RiaDefines::FLOW_DIAGNOSTICS) + { + if (field == &m_resultVariableUiField) + { + caf::PdmUiListEditorAttribute* listEditAttr = dynamic_cast(attribute); + if (listEditAttr) + { + listEditAttr->m_heightHint = 50; + } + } + else if (field == &m_syncInjectorToProducerSelection || + field == &m_syncProducerToInjectorSelection) + { + caf::PdmUiToolButtonEditorAttribute* toolButtonAttr = dynamic_cast(attribute); + if (toolButtonAttr) + { + toolButtonAttr->m_sizePolicy.setHorizontalPolicy(QSizePolicy::MinimumExpanding); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::TracerComp::operator()(const QString& lhs, const QString& rhs) const +{ + if (!lhs.endsWith("-XF") && rhs.endsWith("-XF")) + { + return true; + } + else if (lhs.endsWith("-XF") && !rhs.endsWith("-XF")) + { + return false; + } + else + { + return lhs < rhs; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::assignFlowSolutionFromCase() +{ + RimFlowDiagSolution* defaultFlowDiagSolution = nullptr; + + RimEclipseResultCase* eclCase = dynamic_cast(m_eclipseCase.p()); + + if (eclCase) + { + defaultFlowDiagSolution = eclCase->defaultFlowDiagSolution(); + } + this->setFlowSolution(defaultFlowDiagSolution); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseResultDefinition::hasDualPorFractureResult() +{ + if (m_eclipseCase + && m_eclipseCase->eclipseCaseData()) + { + return m_eclipseCase->eclipseCaseData()->hasFractureResults(); + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::flowDiagResUiText(bool shortLabel, int maxTracerStringLength) const +{ + QString uiText = QString::fromStdString(flowDiagResAddress().variableName); + if (flowDiagResAddress().variableName == RIG_FLD_TOF_RESNAME) { - caf::PdmUiListEditorAttribute* listEditAttr = dynamic_cast(attribute); - if (listEditAttr) + uiText = timeOfFlightString(shortLabel); + } + else if (flowDiagResAddress().variableName == RIG_FLD_MAX_FRACTION_TRACER_RESNAME) + { + uiText = maxFractionTracerString(shortLabel); + } + + QString tracersString = selectedTracersString(); + + if (!tracersString.isEmpty()) + { + const QString postfix = "..."; + + if (tracersString.size() > maxTracerStringLength + postfix.size()) { - listEditAttr->m_heightHint = 50; + tracersString = tracersString.left(maxTracerStringLength); + tracersString += postfix; } + uiText += QString("\n%1").arg(tracersString); + } + return uiText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimEclipseResultDefinition::calcOptionsForVariableUiFieldStandard() +{ + CVF_ASSERT(m_resultTypeUiField() != RiaDefines::FLOW_DIAGNOSTICS && m_resultTypeUiField() != RiaDefines::INJECTION_FLOODING); + + if (this->currentGridCellResults()) + { + QList optionList; + + QStringList cellCenterResultNames; + QStringList cellFaceResultNames; + + RigCaseCellResultsData* results = this->currentGridCellResults(); + foreach(QString s, getResultNamesForCurrentUiResultType()) + { + if (s == RiaDefines::completionTypeResultName() && results->timeStepDates().empty()) continue; + + if (RiaDefines::isPerCellFaceResult(s)) + { + cellFaceResultNames.push_back(s); + } + else + { + cellCenterResultNames.push_back(s); + } + } + + cellCenterResultNames.sort(); + cellFaceResultNames.sort(); + + // Cell Center result names + foreach(QString s, cellCenterResultNames) + { + optionList.push_back(caf::PdmOptionItemInfo(s, s)); + } + + // Ternary Result + bool hasAtLeastOneTernaryComponent = false; + if (cellCenterResultNames.contains("SOIL")) hasAtLeastOneTernaryComponent = true; + else if (cellCenterResultNames.contains("SGAS")) hasAtLeastOneTernaryComponent = true; + else if (cellCenterResultNames.contains("SWAT")) hasAtLeastOneTernaryComponent = true; + + if (m_resultTypeUiField == RiaDefines::DYNAMIC_NATIVE && hasAtLeastOneTernaryComponent) + { + optionList.push_front(caf::PdmOptionItemInfo(RiaDefines::ternarySaturationResultName(), RiaDefines::ternarySaturationResultName())); + } + + // Cell Face result names + bool showDerivedResultsFirstInList = false; + { + RimEclipseFaultColors* rimEclipseFaultColors = nullptr; + this->firstAncestorOrThisOfType(rimEclipseFaultColors); + + if ( rimEclipseFaultColors ) showDerivedResultsFirstInList = true; + } + + foreach(QString s, cellFaceResultNames) + { + if (showDerivedResultsFirstInList) + { + optionList.push_front(caf::PdmOptionItemInfo(s, s)); + } + else + { + optionList.push_back(caf::PdmOptionItemInfo(s, s)); + } + } + + optionList.push_front(caf::PdmOptionItemInfo(RiaDefines::undefinedResultName(), RiaDefines::undefinedResultName())); + + // Remove Per Cell Face options + { + RimPlotCurve* curve = nullptr; + this->firstAncestorOrThisOfType(curve); + + RimEclipsePropertyFilter* propFilter = nullptr; + this->firstAncestorOrThisOfType(propFilter); + + RimCellEdgeColors* cellEdge = nullptr; + this->firstAncestorOrThisOfType(cellEdge); + + if ( propFilter || curve || cellEdge ) + { + removePerCellFaceOptionItems(optionList); + } + } + + return optionList; + } + + return QList(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimEclipseResultDefinition::calcOptionsForSelectedTracerField(bool injector) +{ + QList options; + + RimFlowDiagSolution* flowSol = m_flowSolutionUiField(); + if (flowSol) + { + std::set sortedTracers = setOfTracersOfType(injector); + + for (const QString& tracerName : sortedTracers) + { + QString postfix; + RimFlowDiagSolution::TracerStatusType status = flowSol->tracerStatusOverall(tracerName); + if (status == RimFlowDiagSolution::VARYING) + { + postfix = " [I/P]"; + } + else if (status == RimFlowDiagSolution::UNDEFINED) + { + postfix = " [U]"; + } + options.push_back(caf::PdmOptionItemInfo(tracerName + postfix, tracerName)); + } + } + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::timeOfFlightString(bool shorter) const +{ + QString tofString; + bool multipleSelected = false; + if (injectorSelectionState() != NONE_SELECTED && producerSelectionState() != NONE_SELECTED) + { + tofString = shorter ? "Res.Time" : "Residence Time"; + multipleSelected = true; + } + else if (injectorSelectionState() != NONE_SELECTED) + { + tofString = shorter ? "Fwd.TOF" : "Forward Time Of Flight"; + } + else if (producerSelectionState() != NONE_SELECTED) + { + tofString = shorter ? "Rev.TOF" : "Reverse Time Of Flight"; + } + else + { + tofString = shorter ? "TOF" : "Time Of Flight"; + } + + multipleSelected = multipleSelected || + injectorSelectionState() >= MULTIPLE_SELECTED || producerSelectionState() >= MULTIPLE_SELECTED; + + if (multipleSelected && !shorter) + { + tofString += " (Average)"; + } + return tofString; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::maxFractionTracerString(bool shorter) const +{ + QString mfString; + if (injectorSelectionState() >= ONE_SELECTED && producerSelectionState() == NONE_SELECTED) + { + mfString = shorter ? "FloodReg" : "Flooding Region"; + if (injectorSelectionState() >= MULTIPLE_SELECTED) + mfString += "s"; + } + else if (injectorSelectionState() == NONE_SELECTED && producerSelectionState() >= ONE_SELECTED) + { + mfString = shorter ? "DrainReg" : "Drainage Region"; + if (producerSelectionState() >= MULTIPLE_SELECTED) + mfString += "s"; + } + else + { + mfString = shorter ? "Drain&FloodReg" : "Drainage/Flooding Regions"; + } + return mfString; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEclipseResultDefinition::selectedTracersString() const +{ + QStringList fullTracersList; + + FlowTracerSelectionState injectorState = injectorSelectionState(); + FlowTracerSelectionState producerState = producerSelectionState(); + + if (injectorState == ALL_SELECTED && producerState == ALL_SELECTED) + { + fullTracersList += caf::AppEnum::uiText(FLOW_TR_INJ_AND_PROD); + } + else + { + if (injectorState == ALL_SELECTED) + { + fullTracersList += caf::AppEnum::uiText(FLOW_TR_INJECTORS); + } + + if (producerState == ALL_SELECTED) + { + fullTracersList += caf::AppEnum::uiText(FLOW_TR_PRODUCERS); + } + + if (injectorSelectionState() == ONE_SELECTED || injectorSelectionState() == MULTIPLE_SELECTED) + { + QStringList listOfSelectedInjectors; + for (const QString& injector : m_selectedInjectorTracers()) + { + listOfSelectedInjectors.push_back(injector); + } + if (!listOfSelectedInjectors.empty()) + { + fullTracersList += listOfSelectedInjectors.join(", "); + } + } + + if (producerSelectionState() == ONE_SELECTED || producerSelectionState() == MULTIPLE_SELECTED) + { + QStringList listOfSelectedProducers; + for (const QString& producer : m_selectedProducerTracers()) + { + listOfSelectedProducers.push_back(producer); + } + if (!listOfSelectedProducers.empty()) + { + fullTracersList.push_back(listOfSelectedProducers.join(", ")); + } + } + } + + QString tracersText; + if (!fullTracersList.empty()) + { + tracersText = fullTracersList.join(", "); + } + return tracersText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QStringList RimEclipseResultDefinition::getResultNamesForCurrentUiResultType() +{ + if (m_resultTypeUiField() != RiaDefines::FLOW_DIAGNOSTICS) + { + RigCaseCellResultsData* cellResultsStorage = currentGridCellResults(); + + if (!cellResultsStorage) return QStringList(); + + return cellResultsStorage->resultNames(m_resultTypeUiField()); + } + else + { + QStringList flowVars; + flowVars.push_back(RIG_FLD_TOF_RESNAME); + flowVars.push_back(RIG_FLD_CELL_FRACTION_RESNAME); + flowVars.push_back(RIG_FLD_MAX_FRACTION_TRACER_RESNAME); + flowVars.push_back(RIG_FLD_COMMUNICATION_RESNAME); + return flowVars; } } @@ -1238,30 +1537,185 @@ void RimEclipseResultDefinition::removePerCellFaceOptionItems(QList RimEclipseResultDefinition::tracerNamesMatchingFilter() const +std::vector RimEclipseResultDefinition::allTracerNames() const +{ + std::vector tracerNames; + + RimFlowDiagSolution* flowSol = m_flowSolutionUiField(); + if (flowSol) + { + tracerNames = flowSol->tracerNames(); + } + + return tracerNames; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RimEclipseResultDefinition::setOfTracersOfType(bool injector) const { - std::vector matchingNames; + std::set sortedTracers; RimFlowDiagSolution* flowSol = m_flowSolutionUiField(); if (flowSol) { - std::vector tracerNames = flowSol->tracerNames(); - if (m_selectedTracersUiFieldFilter().isEmpty()) + std::vector tracerNames = allTracerNames(); + for (const QString& tracerName : tracerNames) { - matchingNames = tracerNames; + RimFlowDiagSolution::TracerStatusType status = flowSol->tracerStatusOverall(tracerName); + bool includeTracer = status == RimFlowDiagSolution::VARYING || status == RimFlowDiagSolution::UNDEFINED; + includeTracer |= injector && status == RimFlowDiagSolution::INJECTOR; + includeTracer |= !injector && status == RimFlowDiagSolution::PRODUCER; + + if (includeTracer) + { + sortedTracers.insert(tracerName); + } } - else + } + return sortedTracers; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseResultDefinition::FlowTracerSelectionState RimEclipseResultDefinition::injectorSelectionState() const +{ + if (m_flowTracerSelectionMode == FLOW_TR_INJECTORS || m_flowTracerSelectionMode == FLOW_TR_INJ_AND_PROD) + { + return ALL_SELECTED; + } + else if (m_flowTracerSelectionMode == FLOW_TR_BY_SELECTION) + { + if (m_selectedInjectorTracers().size() == setOfTracersOfType(true).size()) + { + return ALL_SELECTED; + } + else if (m_selectedInjectorTracers().size() == (size_t) 1) + { + return ONE_SELECTED; + } + else if (m_selectedInjectorTracers().size() > (size_t) 1) + { + return MULTIPLE_SELECTED; + } + } + return NONE_SELECTED; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseResultDefinition::FlowTracerSelectionState RimEclipseResultDefinition::producerSelectionState() const +{ + if (m_flowTracerSelectionMode == FLOW_TR_PRODUCERS || m_flowTracerSelectionMode == FLOW_TR_INJ_AND_PROD) + { + return ALL_SELECTED; + } + else if (m_flowTracerSelectionMode == FLOW_TR_BY_SELECTION) + { + if (m_selectedProducerTracers().size() == setOfTracersOfType(false).size()) + { + return ALL_SELECTED; + } + else if (m_selectedProducerTracers().size() == (size_t) 1) + { + return ONE_SELECTED; + } + else if (m_selectedProducerTracers().size() > (size_t) 1) + { + return MULTIPLE_SELECTED; + } + } + return NONE_SELECTED; + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::syncInjectorToProducerSelection() +{ + const double epsilon = 1.0e-8; + + int timeStep = 0; + + Rim3dView* rimView = nullptr; + this->firstAncestorOrThisOfType(rimView); + if (rimView) + { + timeStep = rimView->currentTimeStep(); + } + + RimFlowDiagSolution* flowSol = m_flowSolution(); + if (flowSol && m_flowTracerSelectionMode == FLOW_TR_BY_SELECTION) + { + std::set producers = setOfTracersOfType(false); + + std::set newProducerSelection; + for (const QString& selectedInjector : m_selectedInjectorTracers()) { - for (const QString& tracerName : tracerNames) + for (const QString& producer : producers) { - if (caf::Utils::isStringMatch(m_selectedTracersUiFieldFilter, tracerName)) + std::pair commFluxes = flowSol->flowDiagResults()->injectorProducerPairFluxes( + selectedInjector.toStdString(), producer.toStdString(), timeStep); + if (std::abs(commFluxes.first) > epsilon || std::abs(commFluxes.second) > epsilon) { - matchingNames.push_back(tracerName); + newProducerSelection.insert(producer); } } } + // Add all currently selected producers to set + for (const QString& selectedProducer : m_selectedProducerTracers()) + { + newProducerSelection.insert(selectedProducer); + } + std::vector newProducerVector(newProducerSelection.begin(), newProducerSelection.end()); + setSelectedProducerTracers(newProducerVector); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseResultDefinition::syncProducerToInjectorSelection() +{ + const double epsilon = 1.0e-8; + + int timeStep = 0; + + Rim3dView* rimView = nullptr; + this->firstAncestorOrThisOfType(rimView); + if (rimView) + { + timeStep = rimView->currentTimeStep(); } - return matchingNames; -} + RimFlowDiagSolution* flowSol = m_flowSolution(); + if (flowSol && m_flowTracerSelectionMode == FLOW_TR_BY_SELECTION) + { + std::set injectors = setOfTracersOfType(true); + std::set newInjectorSelection; + for (const QString& selectedProducer : m_selectedProducerTracers()) + { + for (const QString& injector : injectors) + { + std::pair commFluxes = flowSol->flowDiagResults()->injectorProducerPairFluxes( + injector.toStdString(), selectedProducer.toStdString(), timeStep); + if (std::abs(commFluxes.first) > epsilon || std::abs(commFluxes.second) > epsilon) + { + newInjectorSelection.insert(injector); + } + } + } + // Add all currently selected injectors to set + for (const QString& selectedInjector : m_selectedInjectorTracers()) + { + newInjectorSelection.insert(selectedInjector); + } + std::vector newInjectorVector(newInjectorSelection.begin(), newInjectorSelection.end()); + setSelectedInjectorTracers(newInjectorVector); + } +} diff --git a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h index d9d1ff188b..1d7c7279d7 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseResultDefinition.h @@ -24,18 +24,21 @@ #include "RiaPorosityModel.h" #include "RigFlowDiagResultAddress.h" +#include "RimFlowDiagSolution.h" #include "cafAppEnum.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPointer.h" #include "cafPdmPtrField.h" +#include "cafPdmUiItem.h" + +#include class RigCaseCellResultsData; class RimEclipseCase; class RimEclipseView; class RimReservoirCellResultsStorage; -class RimFlowDiagSolution; //================================================================================================== @@ -56,9 +59,17 @@ class RimEclipseResultDefinition : public caf::PdmObject }; typedef caf::AppEnum FlowTracerSelectionEnum; + enum FlowTracerSelectionState + { + NONE_SELECTED, + ONE_SELECTED, + MULTIPLE_SELECTED, + ALL_SELECTED + }; + public: RimEclipseResultDefinition(); - virtual ~RimEclipseResultDefinition(); + ~RimEclipseResultDefinition() override; void simpleCopy(const RimEclipseResultDefinition* other); @@ -97,6 +108,8 @@ class RimEclipseResultDefinition : public caf::PdmObject void setTofAndSelectTracer(const QString& tracerName); void setSelectedTracers(const std::vector& selectedTracers); + void setSelectedInjectorTracers(const std::vector& selectedTracers); + void setSelectedProducerTracers(const std::vector& selectedTracers); void setSelectedSouringTracers(const std::vector& selectedTracers); void updateUiFieldsFromActiveResult(); @@ -104,11 +117,12 @@ class RimEclipseResultDefinition : public caf::PdmObject protected: virtual void updateLegendCategorySettings() {}; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual void initAfterRead(); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + + void initAfterRead() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; protected: caf::PdmField< caf::AppEnum< RiaDefines::ResultCatType > > m_resultType; @@ -116,8 +130,8 @@ class RimEclipseResultDefinition : public caf::PdmObject caf::PdmField m_resultVariable; caf::PdmPtrField m_flowSolution; - caf::PdmField > m_selectedTracers; - + caf::PdmField > m_selectedInjectorTracers; + caf::PdmField > m_selectedProducerTracers; caf::PdmField > m_selectedSouringTracers; friend class RimEclipsePropertyFilter; @@ -134,23 +148,48 @@ class RimEclipseResultDefinition : public caf::PdmObject caf::PdmPtrField m_flowSolutionUiField; caf::PdmField< RigFlowDiagResultAddress::PhaseSelectionEnum > m_phaseSelection; - caf::PdmField m_selectedTracersUiFieldFilter; - caf::PdmField > m_selectedTracersUiField; + caf::PdmField m_syncInjectorToProducerSelection; + caf::PdmField m_syncProducerToInjectorSelection; + caf::PdmField > m_selectedInjectorTracersUiField; + caf::PdmField > m_selectedProducerTracersUiField; caf::PdmField > m_selectedSouringTracersUiField; caf::PdmPointer m_eclipseCase; + caf::PdmField > m_selectedTracers_OBSOLETE; +private: + struct TracerComp + { + bool operator()(const QString& lhs, const QString& rhs) const; + }; + private: void assignFlowSolutionFromCase(); bool hasDualPorFractureResult(); + QString flowDiagResUiText(bool shortLabel, int maxTracerStringLength = std::numeric_limits::max()) const; + QList calcOptionsForVariableUiFieldStandard(); + QList calcOptionsForSelectedTracerField(bool injector); + QString timeOfFlightString(bool shorter) const; + QString maxFractionTracerString(bool shorter) const; + + QString selectedTracersString() const; + + void changedTracerSelectionField(bool injector); QStringList getResultNamesForCurrentUiResultType(); static void removePerCellFaceOptionItems(QList& optionItems); - std::vector tracerNamesMatchingFilter() const; + std::vector allTracerNames() const; + std::set setOfTracersOfType(bool injector) const; + + FlowTracerSelectionState injectorSelectionState() const; + FlowTracerSelectionState producerSelectionState() const; + + void syncInjectorToProducerSelection(); + void syncProducerToInjectorSelection(); }; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.cpp b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.cpp index 68c7cc305e..619c2cde4f 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.cpp @@ -31,6 +31,7 @@ #include "RimEclipseStatisticsCaseEvaluator.h" #include "RimEclipseView.h" #include "RimIdenticalGridCaseGroup.h" +#include "RimIntersectionCollection.h" #include "RimReservoirCellResultsStorage.h" #include "RimSimWellInViewCollection.h" @@ -39,7 +40,6 @@ #include "cafPdmUiPushButtonEditor.h" #include "cafPdmUiTextEditor.h" #include "cafProgressInfo.h" -#include "RimIntersectionCollection.h" namespace caf { template<> @@ -68,8 +68,7 @@ RimEclipseStatisticsCase::RimEclipseStatisticsCase() m_calculateEditCommand = false; CAF_PDM_InitField(&m_selectionSummary, "SelectionSummary", QString(""), "Summary of Calculation Setup", "", "", ""); - m_selectionSummary.xmlCapability()->setIOWritable(false); - m_selectionSummary.xmlCapability()->setIOReadable(false); + m_selectionSummary.xmlCapability()->disableIO(); m_selectionSummary.uiCapability()->setUiReadOnly(true); m_selectionSummary.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); m_selectionSummary.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); @@ -113,8 +112,8 @@ RimEclipseStatisticsCase::RimEclipseStatisticsCase() m_populateSelectionAfterLoadingGrid = false; // These does not work properly for statistics case, so hide for now - flipXAxis.uiCapability()->setUiHidden(true); - flipYAxis.uiCapability()->setUiHidden(true); + m_flipXAxis.uiCapability()->setUiHidden(true); + m_flipYAxis.uiCapability()->setUiHidden(true); activeFormationNames.uiCapability()->setUiHidden(true); } @@ -183,7 +182,7 @@ void RimEclipseStatisticsCase::reloadEclipseGridFile() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimCaseCollection* RimEclipseStatisticsCase::parentStatisticsCaseCollection() +RimCaseCollection* RimEclipseStatisticsCase::parentStatisticsCaseCollection() const { return dynamic_cast(this->parentField()->ownerObject()); } @@ -210,9 +209,7 @@ void RimEclipseStatisticsCase::computeStatistics() CVF_ASSERT(gridCaseGroup); gridCaseGroup->computeUnionOfActiveCells(); - std::vector sourceCases; - - getSourceCases(sourceCases); + std::vector sourceCases = getSourceCases(); if (sourceCases.size() == 0 || !sourceCases.at(0)->results(RiaDefines::MATRIX_MODEL)) @@ -308,8 +305,10 @@ void RimEclipseStatisticsCase::scheduleACTIVEGeometryRegenOnReservoirViews() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipseStatisticsCase::getSourceCases(std::vector& sourceCases) +std::vector RimEclipseStatisticsCase::getSourceCases() const { + std::vector sourceCases; + RimIdenticalGridCaseGroup* gridCaseGroup = caseGroup(); if (gridCaseGroup) { @@ -323,12 +322,14 @@ void RimEclipseStatisticsCase::getSourceCases(std::vector& sour sourceCases.push_back(sourceCase); } } + + return sourceCases; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimIdenticalGridCaseGroup* RimEclipseStatisticsCase::caseGroup() +RimIdenticalGridCaseGroup* RimEclipseStatisticsCase::caseGroup() const { RimCaseCollection* parentCollection = parentStatisticsCaseCollection(); if (parentCollection) @@ -383,8 +384,8 @@ void RimEclipseStatisticsCase::defineUiOrdering(QString uiConfigName, caf::PdmUi group = uiOrdering.addNewGroup("Case Options"); group->add(&m_wellDataSourceCase); group->add(&activeFormationNames); - group->add(&flipXAxis); - group->add(&flipYAxis); + group->add(&m_flipXAxis); + group->add(&m_flipYAxis); } QList toOptionList(const QStringList& varList) @@ -722,6 +723,8 @@ void RimEclipseStatisticsCase::clearComputedStatistics() //-------------------------------------------------------------------------------------------------- void RimEclipseStatisticsCase::computeStatisticsAndUpdateViews() { + if (getSourceCases().empty()) return; + computeStatistics(); scheduleACTIVEGeometryRegenOnReservoirViews(); updateConnectedEditorsAndReservoirViews(); diff --git a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.h b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.h index 096d0700ca..c861ae368a 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.h @@ -20,9 +20,10 @@ #pragma once -#include "RimEclipseCase.h" #include "RiaDefines.h" +#include "RimEclipseCase.h" + #include "cvfBase.h" #include "cvfObject.h" #include "cafPdmField.h" @@ -30,12 +31,11 @@ #include "cafAppEnum.h" #include "cvfCollection.h" - -class RimIdenticalGridCaseGroup; -class RimEclipseResultDefinition; -class RimEclipseStatisticsCaseCollection; class RigMainGrid; class RigSimWellData; +class RimEclipseResultDefinition; +class RimEclipseStatisticsCaseCollection; +class RimIdenticalGridCaseGroup; //================================================================================================== @@ -49,7 +49,7 @@ class RimEclipseStatisticsCase : public RimEclipseCase public: RimEclipseStatisticsCase(); - virtual ~RimEclipseStatisticsCase(); + ~RimEclipseStatisticsCase() override; void setMainGrid(RigMainGrid* mainGrid); @@ -60,10 +60,10 @@ class RimEclipseStatisticsCase : public RimEclipseCase void updateConnectedEditorsAndReservoirViews(); - virtual bool openEclipseGridFile(); - virtual void reloadEclipseGridFile(); + bool openEclipseGridFile() override; + void reloadEclipseGridFile() override; - RimCaseCollection* parentStatisticsCaseCollection(); + RimCaseCollection* parentStatisticsCaseCollection() const; enum PercentileCalcType { @@ -73,16 +73,15 @@ class RimEclipseStatisticsCase : public RimEclipseCase }; caf::PdmField< bool > m_calculateEditCommand; - virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath){} + void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath) override{} void populateResultSelectionAfterLoadingGrid(); private: void scheduleACTIVEGeometryRegenOnReservoirViews(); - RimIdenticalGridCaseGroup* caseGroup(); - - void getSourceCases(std::vector& sourceCases); + RimIdenticalGridCaseGroup* caseGroup() const; + std::vector getSourceCases() const; void populateResultSelection(); @@ -90,17 +89,15 @@ class RimEclipseStatisticsCase : public RimEclipseCase void updateSelectionSummaryLabel(); void updatePercentileUiVisibility(); - void setWellResultsAndUpdateViews(const cvf::Collection& sourceCaseSimWellData); - // Pdm system overrides - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) ; - virtual QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override ; + QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly ) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute ); - // Fields + void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute ) override; +private: caf::PdmField< caf::AppEnum< RiaDefines::ResultCatType > > m_resultType; caf::PdmField< caf::AppEnum< RiaDefines::PorosityModelType > > m_porosityModel; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.h b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.h index e6cab8e3be..7821779461 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseCollection.h @@ -42,7 +42,7 @@ class RimEclipseStatisticsCaseCollection : public caf::PdmObject public: RimEclipseStatisticsCaseCollection(); - virtual ~RimEclipseStatisticsCaseCollection(); + ~RimEclipseStatisticsCaseCollection() override; caf::PdmChildArrayField cases; diff --git a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp index c4e0fbcc68..434fc62491 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCaseEvaluator.cpp @@ -112,9 +112,9 @@ void RimEclipseStatisticsCaseEvaluator::evaluateForResults(const QList& if (activeCellCount > 0) { - for (size_t i = 0; i < statisticalResultNames.size(); ++i) + for (size_t j = 0; j < statisticalResultNames.size(); ++j) { - addNamedResult(destCellResultsData, resultType, statisticalResultNames[i], activeCellCount); + addNamedResult(destCellResultsData, resultType, statisticalResultNames[j], activeCellCount); } } } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp index 969156944b..abaec62c4f 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.cpp +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.cpp @@ -22,6 +22,7 @@ #include "RiaApplication.h" #include "RiaColorTables.h" +#include "RiaFieldHandleTools.h" #include "RiaPreferences.h" #include "RigActiveCellInfo.h" @@ -35,6 +36,7 @@ #include "RigSimWellData.h" #include "RigVirtualPerforationTransmissibilities.h" +#include "Rim2dIntersectionView.h" #include "Rim3dOverlayInfoConfig.h" #include "RimCellEdgeColors.h" #include "RimCellRangeFilterCollection.h" @@ -50,9 +52,9 @@ #include "RimGridCollection.h" #include "RimIntersection.h" #include "RimIntersectionCollection.h" -#include "RimRegularLegendConfig.h" #include "RimOilField.h" #include "RimProject.h" +#include "RimRegularLegendConfig.h" #include "RimReservoirCellResultsStorage.h" #include "RimSimWellInView.h" #include "RimSimWellInViewCollection.h" @@ -144,7 +146,9 @@ RimEclipseView::RimEclipseView() m_propertyFilterCollection.uiCapability()->setUiHidden(true); // Visualization fields - CAF_PDM_InitField(&m_showMainGrid, "ShowMainGrid", true, "Show Main Grid", "", "", ""); + CAF_PDM_InitField(&m_showMainGrid_OBSOLETE, "ShowMainGrid", true, "Show Main Grid", "", "", ""); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_showMainGrid_OBSOLETE); + CAF_PDM_InitField(&m_showInactiveCells, "ShowInactiveCells", false, "Show Inactive Cells", "", "", ""); CAF_PDM_InitField(&m_showInvalidCells, "ShowInvalidCells", false, "Show Invalid Cells", "", "", ""); @@ -157,7 +161,6 @@ RimEclipseView::RimEclipseView() m_reservoirGridPartManager = new RivReservoirViewPartMgr(this); m_simWellsPartManager = new RivReservoirSimWellsPartMgr(this); - m_eclipseCase = nullptr; } @@ -294,10 +297,6 @@ void RimEclipseView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c scheduleCreateDisplayModelAndRedraw(); } - else if (changedField == &m_showMainGrid) - { - scheduleCreateDisplayModelAndRedraw(); - } else if (changedField == &m_rangeFilterCollection) { this->scheduleGeometryRegen(RANGE_FILTERED); @@ -310,7 +309,7 @@ void RimEclipseView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c this->scheduleGeometryRegen(PROPERTY_FILTERED); scheduleCreateDisplayModelAndRedraw(); - } + } } //-------------------------------------------------------------------------------------------------- @@ -387,8 +386,7 @@ void RimEclipseView::createDisplayModel() wellCollection()->scheduleIsWellPipesVisibleRecalculation(); // Create vector of grid indices to render - std::vector gridIndices; - this->indicesToVisibleGrids(&gridIndices); + std::vector gridIndices = this->indicesToVisibleGrids(); /// // Get or create the parts for "static" type geometry. The same geometry is used @@ -498,6 +496,7 @@ void RimEclipseView::createDisplayModel() // Cross sections m_crossSectionVizModel->removeAllParts(); + m_crossSectionCollection->rebuildGeometry(); m_crossSectionCollection->appendPartsToModel(*this, m_crossSectionVizModel.p(), m_reservoirGridPartManager->scaleTransform()); m_viewer->addStaticModelOnce(m_crossSectionVizModel.p()); @@ -546,11 +545,10 @@ void RimEclipseView::createDisplayModel() updateLegends(); } - std::vector objects; - this->referringPtrFields(objects); - for (auto object : objects) + std::vector objects; + this->objectsWithReferringPtrFieldsOfType(objects); + for (auto plot : objects) { - RimFlowCharacteristicsPlot* plot = dynamic_cast(object->ownerObject()); if (plot != nullptr) { plot->viewGeometryUpdated(); @@ -567,6 +565,22 @@ void RimEclipseView::updateCurrentTimeStep() updateLegends(); // To make sure the scalar mappers are set up correctly + updateVisibleGeometriesAndCellColors(); + + appendWellsAndFracturesToModel(); + + m_overlayInfoConfig()->update3DInfo(); + + // Invisible Wells are marked as read only when "show wells intersecting visible cells" is enabled + // Visibility of wells differ betweeen time steps, so trigger a rebuild of tree state items + wellCollection()->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseView::updateVisibleGeometriesAndCellColors() +{ std::vector geometriesToRecolor; if (this->viewController() && this->viewController()->isVisibleCellsOveridden()) @@ -578,13 +592,12 @@ void RimEclipseView::updateCurrentTimeStep() cvf::ref frameParts = new cvf::ModelBasicList; frameParts->setName("GridModel"); - std::vector gridIndices; - this->indicesToVisibleGrids(&gridIndices); + std::vector gridIndices = this->indicesToVisibleGrids(); - geometriesToRecolor.push_back( PROPERTY_FILTERED); - geometriesToRecolor.push_back( PROPERTY_FILTERED_WELL_CELLS); + geometriesToRecolor.push_back(PROPERTY_FILTERED); + geometriesToRecolor.push_back(PROPERTY_FILTERED_WELL_CELLS); - if ( isGridVisualizationMode() ) + if (isGridVisualizationMode()) { m_reservoirGridPartManager->appendDynamicGeometryPartsToModel(frameParts.p(), PROPERTY_FILTERED, m_currentTimeStep, gridIndices); m_reservoirGridPartManager->appendDynamicGeometryPartsToModel(frameParts.p(), PROPERTY_FILTERED_WELL_CELLS, m_currentTimeStep, gridIndices); @@ -622,22 +635,19 @@ void RimEclipseView::updateCurrentTimeStep() } // Set the transparency on all the Wellcell parts before setting the result color - float opacity = static_cast< float> (1 - cvf::Math::clamp(this->wellCollection()->wellCellTransparencyLevel(), 0.0, 1.0)); + float opacity = static_cast (1 - cvf::Math::clamp(this->wellCollection()->wellCellTransparencyLevel(), 0.0, 1.0)); m_reservoirGridPartManager->updateCellColor(PROPERTY_FILTERED_WELL_CELLS, m_currentTimeStep, cvf::Color4f(cvf::Color3f(cvf::Color3::WHITE), opacity)); if (this->showInactiveCells()) { - std::vector gridIndices; - this->indicesToVisibleGrids(&gridIndices); - - if (this->rangeFilterCollection()->hasActiveFilters() ) // Wells not considered, because we do not have a INACTIVE_WELL_CELLS group yet. + if (this->rangeFilterCollection()->hasActiveFilters()) // Wells not considered, because we do not have a INACTIVE_WELL_CELLS group yet. { - m_reservoirGridPartManager->appendStaticGeometryPartsToModel(frameParts.p(), RANGE_FILTERED_INACTIVE, gridIndices); + m_reservoirGridPartManager->appendStaticGeometryPartsToModel(frameParts.p(), RANGE_FILTERED_INACTIVE, gridIndices); if (!faultCollection()->isShowingFaultsAndFaultsOutsideFilters()) { - m_reservoirGridPartManager->appendFaultsStaticGeometryPartsToModel(frameParts.p(), RANGE_FILTERED_INACTIVE); + m_reservoirGridPartManager->appendFaultsStaticGeometryPartsToModel(frameParts.p(), RANGE_FILTERED_INACTIVE); } } else @@ -679,7 +689,7 @@ void RimEclipseView::updateCurrentTimeStep() geometriesToRecolor.push_back(RANGE_FILTERED); geometriesToRecolor.push_back(RANGE_FILTERED_WELL_CELLS); } - else + else { geometriesToRecolor.push_back(ACTIVE); geometriesToRecolor.push_back(ALL_WELL_CELLS); @@ -690,7 +700,7 @@ void RimEclipseView::updateCurrentTimeStep() if (this->hasUserRequestedAnimation() && this->cellEdgeResult()->hasResult()) { m_reservoirGridPartManager->updateCellEdgeResultColor(geometriesToRecolor[i], m_currentTimeStep, this->cellResult(), this->cellEdgeResult()); - } + } else if ((this->hasUserRequestedAnimation() && this->cellResult()->hasResult()) || this->cellResult()->isTernarySaturationSelected()) { m_reservoirGridPartManager->updateCellResultColor(geometriesToRecolor[i], m_currentTimeStep, this->cellResult()); @@ -706,15 +716,21 @@ void RimEclipseView::updateCurrentTimeStep() if ((this->hasUserRequestedAnimation() && this->cellResult()->hasResult()) || this->cellResult()->isTernarySaturationSelected()) { - m_crossSectionCollection->updateCellResultColor(m_currentTimeStep, - this->cellResult()->legendConfig()->scalarMapper(), - this->cellResult()->ternaryLegendConfig()->scalarMapper()); + m_crossSectionCollection->updateCellResultColor(m_currentTimeStep, + this->cellResult()->legendConfig()->scalarMapper(), + this->cellResult()->ternaryLegendConfig()->scalarMapper()); } else { m_crossSectionCollection->applySingleColorEffect(); } +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEclipseView::appendWellsAndFracturesToModel() +{ if (m_viewer) { cvf::Scene* frameScene = m_viewer->frame(m_currentTimeStep); @@ -741,7 +757,7 @@ void RimEclipseView::updateCurrentTimeStep() { cvf::String name = "WellPathMod"; this->removeModelByName(frameScene, name); - + cvf::ref wellPathModelBasicList = new cvf::ModelBasicList; wellPathModelBasicList->setName(name); @@ -783,12 +799,6 @@ void RimEclipseView::updateCurrentTimeStep() } } } - - m_overlayInfoConfig()->update3DInfo(); - - // Invisible Wells are marked as read only when "show wells intersecting visible cells" is enabled - // Visibility of wells differ betweeen time steps, so trigger a rebuild of tree state items - wellCollection()->updateConnectedEditors(); } //-------------------------------------------------------------------------------------------------- @@ -823,10 +833,9 @@ void RimEclipseView::onLoadDataAndUpdate() this->m_propertyFilterCollection()->loadAndInitializePropertyFilters(); - this->faultCollection()->setReservoirView(this); this->faultCollection()->syncronizeFaults(); - m_reservoirGridPartManager->clearGeometryCache(); + scheduleReservoirGridGeometryRegen(); m_simWellsPartManager->clearGeometryCache(); syncronizeWellsWithResults(); @@ -863,6 +872,11 @@ void RimEclipseView::initAfterRead() this->cellResult()->setReservoirView(this); this->cellEdgeResult()->setReservoirView(this); + if (!m_showMainGrid_OBSOLETE()) + { + gridCollection()->setMainGridActive(false); + } + this->updateUiIconFromToggleField(); } @@ -890,24 +904,7 @@ void RimEclipseView::updateStaticCellColors() //-------------------------------------------------------------------------------------------------- void RimEclipseView::updateStaticCellColors(RivCellSetEnum geometryType) { - float opacity = static_cast< float> (1 - cvf::Math::clamp(this->wellCollection()->wellCellTransparencyLevel(), 0.0, 1.0)); - cvf::Color4f color(cvf::Color3::ORANGE); - - switch (geometryType) - { - case ACTIVE: color = cvf::Color4f(cvf::Color3::ORANGE); break; - case ALL_WELL_CELLS: color = cvf::Color4f(cvf::Color3f(cvf::Color3::BROWN), opacity ); break; - case VISIBLE_WELL_CELLS: color = cvf::Color4f(cvf::Color3f(cvf::Color3::BROWN), opacity ); break; - case VISIBLE_WELL_FENCE_CELLS: color = cvf::Color4f(cvf::Color3::ORANGE); break; - case VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER: - color = cvf::Color4f(cvf::Color3f(cvf::Color3::BROWN), opacity ); break; - case VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER: - color = cvf::Color4f(cvf::Color3::ORANGE); break; - case INACTIVE: color = cvf::Color4f(RiaColorTables::undefinedCellColor()); break; - case RANGE_FILTERED: color = cvf::Color4f(cvf::Color3::ORANGE); break; - case RANGE_FILTERED_WELL_CELLS: color = cvf::Color4f(cvf::Color3f(cvf::Color3::BROWN), opacity ); break; - case RANGE_FILTERED_INACTIVE: color = cvf::Color4f(RiaColorTables::undefinedCellColor()); break; - } + cvf::Color4f color = colorFromCellCategory(geometryType); if (geometryType == PROPERTY_FILTERED || geometryType == PROPERTY_FILTERED_WELL_CELLS) { @@ -921,6 +918,33 @@ void RimEclipseView::updateStaticCellColors(RivCellSetEnum geometryType) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color4f RimEclipseView::colorFromCellCategory(RivCellSetEnum geometryType) const +{ + float opacity = static_cast (1 - cvf::Math::clamp(this->wellCollection()->wellCellTransparencyLevel(), 0.0, 1.0)); + cvf::Color4f color(cvf::Color3::ORANGE); + + switch (geometryType) + { + case ACTIVE: color = cvf::Color4f(cvf::Color3::ORANGE); break; + case ALL_WELL_CELLS: color = cvf::Color4f(cvf::Color3f(cvf::Color3::BROWN), opacity); break; + case VISIBLE_WELL_CELLS: color = cvf::Color4f(cvf::Color3f(cvf::Color3::BROWN), opacity); break; + case VISIBLE_WELL_FENCE_CELLS: color = cvf::Color4f(cvf::Color3::ORANGE); break; + case VISIBLE_WELL_CELLS_OUTSIDE_RANGE_FILTER: + color = cvf::Color4f(cvf::Color3f(cvf::Color3::BROWN), opacity); break; + case VISIBLE_WELL_FENCE_CELLS_OUTSIDE_RANGE_FILTER: + color = cvf::Color4f(cvf::Color3::ORANGE); break; + case INACTIVE: color = cvf::Color4f(RiaColorTables::undefinedCellColor()); break; + case RANGE_FILTERED: color = cvf::Color4f(cvf::Color3::ORANGE); break; + case RANGE_FILTERED_WELL_CELLS: color = cvf::Color4f(cvf::Color3f(cvf::Color3::BROWN), opacity); break; + case RANGE_FILTERED_INACTIVE: color = cvf::Color4f(RiaColorTables::undefinedCellColor()); break; + } + + return color; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -954,7 +978,7 @@ RigCaseCellResultsData* RimEclipseView::currentGridCellResults() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigActiveCellInfo* RimEclipseView::currentActiveCellInfo() +const RigActiveCellInfo* RimEclipseView::currentActiveCellInfo() const { if (m_eclipseCase && m_eclipseCase->eclipseCaseData() @@ -992,6 +1016,7 @@ void RimEclipseView::scheduleGeometryRegen(RivCellSetEnum geometryType) void RimEclipseView::scheduleReservoirGridGeometryRegen() { m_reservoirGridPartManager->clearGeometryCache(); + m_currentReservoirCellVisibility = nullptr; } //-------------------------------------------------------------------------------------------------- @@ -1006,25 +1031,11 @@ void RimEclipseView::scheduleSimWellGeometryRegen() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEclipseView::indicesToVisibleGrids(std::vector* gridIndices) +std::vector RimEclipseView::indicesToVisibleGrids() const { - CVF_ASSERT(gridIndices != nullptr); - - // Create vector of grid indices to render - std::vector grids; - if (this->m_eclipseCase && this->m_eclipseCase->eclipseCaseData() ) - { - this->m_eclipseCase->eclipseCaseData()->allGrids(&grids); - } + CVF_ASSERT(gridCollection()); - size_t i; - for (i = 0; i < grids.size(); i++) - { - if (!grids[i]->isMainGrid() || this->showMainGrid() ) - { - gridIndices->push_back(i); - } - } + return gridCollection()->indicesToVisibleGrids(); } //-------------------------------------------------------------------------------------------------- @@ -1128,17 +1139,17 @@ void RimEclipseView::updateMinMaxValuesAndAddLegendToView(QString legendLabel, if (resultColors->hasResult() && resultColors->legendConfig()->showLegend()) { - resultColors->legendConfig()->setTitle(legendLabel + resultColors->resultVariableUiShortName()); + resultColors->legendConfig()->setTitle(legendLabel + resultColors->resultVariableUiName()); m_viewer->addColorLegendToBottomLeftCorner(resultColors->legendConfig()->titledOverlayFrame()); } size_t maxTimeStepCount = cellResultsData->maxTimeStepCount(); if (resultColors->isTernarySaturationSelected() && maxTimeStepCount > 1) { - if (resultColors->ternaryLegendConfig->showLegend() && resultColors->ternaryLegendConfig->titledOverlayFrame()) + if (resultColors->ternaryLegendConfig()->showLegend() && resultColors->ternaryLegendConfig()->titledOverlayFrame()) { - resultColors->ternaryLegendConfig->setTitle(legendLabel); - m_viewer->addColorLegendToBottomLeftCorner(resultColors->ternaryLegendConfig->titledOverlayFrame()); + resultColors->ternaryLegendConfig()->setTitle(legendLabel); + m_viewer->addColorLegendToBottomLeftCorner(resultColors->ternaryLegendConfig()->titledOverlayFrame()); } } } @@ -1180,7 +1191,7 @@ void RimEclipseView::syncronizeWellsWithResults() { if (!(m_eclipseCase && m_eclipseCase->eclipseCaseData()) ) return; - cvf::Collection simWellData = m_eclipseCase->eclipseCaseData()->wellResults(); + cvf::Collection wellResults = m_eclipseCase->eclipseCaseData()->wellResults(); std::vector > newWells; @@ -1196,20 +1207,20 @@ void RimEclipseView::syncronizeWellsWithResults() // Find corresponding well from well result, or create a new - for (size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx) + for (size_t wIdx = 0; wIdx < wellResults.size(); ++wIdx) { - RimSimWellInView* well = this->wellCollection()->findWell(simWellData[wIdx]->m_wellName); + RimSimWellInView* well = this->wellCollection()->findWell(wellResults[wIdx]->m_wellName); if (!well) { well = new RimSimWellInView; - well->name = simWellData[wIdx]->m_wellName; + well->name = wellResults[wIdx]->m_wellName; isAnyWellCreated = true; } newWells.push_back(well); - well->setSimWellData(simWellData[wIdx].p(), wIdx); + well->setSimWellData(wellResults[wIdx].p(), wIdx); } // Delete all wells that does not have a result @@ -1270,7 +1281,7 @@ void RimEclipseView::calculateVisibleWellCellsIncFence(cvf::UByteArray* visibleC } visibleCells->setAll(false); - RigActiveCellInfo* activeCellInfo = this->currentActiveCellInfo(); + const RigActiveCellInfo* activeCellInfo = this->currentActiveCellInfo(); CVF_ASSERT(activeCellInfo); @@ -1415,6 +1426,15 @@ void RimEclipseView::calculateCompletionTypeAndRedrawIfRequired() if (isDependingOnCompletionType) { this->loadDataAndUpdate(); + + std::vector intersections = m_crossSectionCollection->intersections(); + for (auto intersection : intersections) + { + if ( intersection && intersection->correspondingIntersectionView() ) + { + intersection->correspondingIntersectionView()->scheduleCreateDisplayModelAndRedraw(); + } + } } for (const auto& propFilter : m_propertyFilterCollection()->propertyFilters) @@ -1440,6 +1460,19 @@ bool RimEclipseView::isVirtualConnectionFactorGeometryVisible() const return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEclipseView::isMainGridVisible() const +{ + auto indicesToVisibleGrids = m_gridCollection->indicesToVisibleGrids(); + bool isMainGridVisible = std::find(indicesToVisibleGrids.begin(), indicesToVisibleGrids.end(), 0) != indicesToVisibleGrids.end(); + + if (!isMainGridVisible) return false; + + return this->m_gridCollection->isActive(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1456,7 +1489,6 @@ void RimEclipseView::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& Rim3dView::defineUiOrdering(uiConfigName, uiOrdering); caf::PdmUiGroup* cellGroup = uiOrdering.addNewGroup("Cell Visibility"); - cellGroup->add(&m_showMainGrid); cellGroup->add(&m_showInactiveCells); cellGroup->add(&m_showInvalidCells); } @@ -1493,7 +1525,6 @@ void RimEclipseView::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering uiTreeOrdering.add(m_rangeFilterCollection()); uiTreeOrdering.add(m_propertyFilterCollection()); - uiTreeOrdering.skipRemainingChildren(true); } @@ -1564,6 +1595,8 @@ bool RimEclipseView::isTimeStepDependentDataVisible() const if (this->wellPathCollection()->anyWellsContainingPerforationIntervals()) return true; + if (this->hasVisibleTimeStepDependent3dWellLogCurves()) return true; + return false; } @@ -1591,7 +1624,7 @@ void RimEclipseView::resetLegendsInViewer() RimRegularLegendConfig* cellResultNormalLegendConfig = this->cellResult()->legendConfig(); if (cellResultNormalLegendConfig) cellResultNormalLegendConfig->recreateLegend(); - this->cellResult()->ternaryLegendConfig->recreateLegend(); + this->cellResult()->ternaryLegendConfig()->recreateLegend(); this->cellEdgeResult()->legendConfig()->recreateLegend(); m_viewer->removeAllColorLegends(); @@ -1696,7 +1729,11 @@ const RimEclipsePropertyFilterCollection* RimEclipseView::eclipsePropertyFilterC void RimEclipseView::setOverridePropertyFilterCollection(RimEclipsePropertyFilterCollection* pfc) { m_overridePropertyFilterCollection = pfc; - + if (m_overridePropertyFilterCollection != nullptr) + { + m_propertyFilterCollection->isActive = m_overridePropertyFilterCollection->isActive; + } + uiCapability()->updateConnectedEditors(); this->scheduleGeometryRegen(PROPERTY_FILTERED); this->scheduleCreateDisplayModelAndRedraw(); } @@ -1839,15 +1876,15 @@ bool RimEclipseView::showInactiveCells() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimEclipseView::showMainGrid() const +const RimPropertyFilterCollection* RimEclipseView::propertyFilterCollection() const { - return m_showMainGrid; + return eclipsePropertyFilterCollection(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const RimPropertyFilterCollection* RimEclipseView::propertyFilterCollection() const +RimPropertyFilterCollection* RimEclipseView::nativePropertyFilterCollection() { - return eclipsePropertyFilterCollection(); + return m_propertyFilterCollection(); } diff --git a/ApplicationCode/ProjectDataModel/RimEclipseView.h b/ApplicationCode/ProjectDataModel/RimEclipseView.h index fe973c9ce1..8d5ff87b29 100644 --- a/ApplicationCode/ProjectDataModel/RimEclipseView.h +++ b/ApplicationCode/ProjectDataModel/RimEclipseView.h @@ -77,7 +77,7 @@ class RimEclipseView : public RimGridView CAF_PDM_HEADER_INIT; public: RimEclipseView(); - virtual ~RimEclipseView(); + ~RimEclipseView() override; RimEclipseCellColors* cellResult() const; RimCellEdgeColors* cellEdgeResult() const; @@ -89,22 +89,21 @@ class RimEclipseView : public RimGridView bool showInvalidCells() const; bool showInactiveCells() const; - bool showMainGrid() const; // Access internal objects - virtual const RimPropertyFilterCollection* propertyFilterCollection() const override; + const RimPropertyFilterCollection* propertyFilterCollection() const override; RimEclipsePropertyFilterCollection* eclipsePropertyFilterCollection(); const RimEclipsePropertyFilterCollection* eclipsePropertyFilterCollection() const; void setOverridePropertyFilterCollection(RimEclipsePropertyFilterCollection* pfc); RigCaseCellResultsData* currentGridCellResults(); - RigActiveCellInfo* currentActiveCellInfo(); + const RigActiveCellInfo* currentActiveCellInfo() const; RimEclipseCellColors* currentFaultResultColors(); void setEclipseCase(RimEclipseCase* reservoir); RimEclipseCase* eclipseCase() const; - virtual RimCase* ownerCase() const override; + RimCase* ownerCase() const override; RigMainGrid* mainGrid() const; @@ -112,7 +111,7 @@ class RimEclipseView : public RimGridView bool isTimeStepDependentDataVisible() const override; - virtual void scheduleGeometryRegen(RivCellSetEnum geometryType) override; + void scheduleGeometryRegen(RivCellSetEnum geometryType) override; void scheduleReservoirGridGeometryRegen(); void scheduleSimWellGeometryRegen(); void updateDisplayModelForWellResults(); @@ -120,6 +119,7 @@ class RimEclipseView : public RimGridView void calculateCompletionTypeAndRedrawIfRequired(); bool isVirtualConnectionFactorGeometryVisible() const; + bool isMainGridVisible() const; const std::vector& visibleGridParts() const; @@ -130,43 +130,49 @@ class RimEclipseView : public RimGridView void calculateVisibleWellCellsIncFence(cvf::UByteArray* visibleCells, RigGridBase * grid); // Overridden PDM methods: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; void updateIconStateForFilterCollections(); - virtual void axisLabels(cvf::String* xLabel, cvf::String* yLabel, cvf::String* zLabel) override; + void axisLabels(cvf::String* xLabel, cvf::String* yLabel, cvf::String* zLabel) override; - virtual bool isUsingFormationNames() const override; + bool isUsingFormationNames() const override; virtual void calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility, int timeStep) override; - std::vector legendConfigs() const override; + virtual std::vector legendConfigs() const override; + cvf::Color4f colorFromCellCategory(RivCellSetEnum geometryType) const; protected: - virtual void initAfterRead() override; - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual void onLoadDataAndUpdate() override; + void initAfterRead() override; + virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + virtual void onLoadDataAndUpdate() override; - virtual void createPartCollectionFromSelection(cvf::Collection* parts) override; - virtual bool showActiveCellsOnly() override; + void createPartCollectionFromSelection(cvf::Collection* parts) override; + bool showActiveCellsOnly() override; + virtual void updateCurrentTimeStep() override; + void updateVisibleGeometriesAndCellColors(); + void appendWellsAndFracturesToModel(); + + virtual void createDisplayModel() override; + RimPropertyFilterCollection* nativePropertyFilterCollection(); + virtual std::set allVisibleFaultGeometryTypes() const; private: - void createDisplayModel() override; void updateDisplayModelVisibility() override; - virtual void updateCurrentTimeStep() override; - void indicesToVisibleGrids(std::vector* gridIndices); - virtual void updateScaleTransform() override; - virtual cvf::Transform* scaleTransform() override; + std::vector indicesToVisibleGrids() const; + void updateScaleTransform() override; + cvf::Transform* scaleTransform() override; - virtual void updateStaticCellColors() override; + void updateStaticCellColors() override; void updateStaticCellColors(RivCellSetEnum geometryType); - void updateLegends() override; + + virtual void updateLegends() override; void updateMinMaxValuesAndAddLegendToView(QString legendLabel, RimEclipseCellColors* resultColors, RigCaseCellResultsData* cellResultsData); - virtual void resetLegendsInViewer() override; + void resetLegendsInViewer() override; void updateVirtualConnectionLegendRanges(); - std::set allVisibleFaultGeometryTypes() const; void updateFaultColors(); void syncronizeWellsWithResults(); @@ -178,7 +184,7 @@ class RimEclipseView : public RimGridView private: caf::PdmField m_showInvalidCells; caf::PdmField m_showInactiveCells; - caf::PdmField m_showMainGrid; + caf::PdmField m_showMainGrid_OBSOLETE; caf::PdmChildField m_cellResult; caf::PdmChildField m_cellEdgeResult; diff --git a/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.h b/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.h index 3348e8bbaf..697f1c47ea 100644 --- a/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.h +++ b/ApplicationCode/ProjectDataModel/RimExportInputPropertySettings.h @@ -36,6 +36,6 @@ class RimExportInputSettings : public caf::PdmObject caf::PdmField eclipseKeyword; 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; }; diff --git a/ApplicationCode/ProjectDataModel/RimFaultInView.h b/ApplicationCode/ProjectDataModel/RimFaultInView.h index cbf4542b68..28ab2cb27a 100644 --- a/ApplicationCode/ProjectDataModel/RimFaultInView.h +++ b/ApplicationCode/ProjectDataModel/RimFaultInView.h @@ -40,16 +40,16 @@ class RimFaultInView : public caf::PdmObject public: RimFaultInView(); - virtual ~RimFaultInView(); + ~RimFaultInView() override; void setFaultGeometry(const RigFault* faultGeometry); const RigFault* faultGeometry() const; - virtual caf::PdmFieldHandle* userDescriptionField(); - virtual caf::PdmFieldHandle* objectToggleField(); + caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* objectToggleField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual void initAfterRead(); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void initAfterRead() override; caf::PdmField showFault; diff --git a/ApplicationCode/ProjectDataModel/RimFaultInViewCollection.cpp b/ApplicationCode/ProjectDataModel/RimFaultInViewCollection.cpp index 5bfafccde1..bdcb7e3735 100644 --- a/ApplicationCode/ProjectDataModel/RimFaultInViewCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimFaultInViewCollection.cpp @@ -84,8 +84,6 @@ RimFaultInViewCollection::RimFaultInViewCollection() CAF_PDM_InitFieldNoDefault(&faults, "Faults", "Faults", "", "", ""); faults.uiCapability()->setUiHidden(true); - - m_reservoirView = nullptr; } //-------------------------------------------------------------------------------------------------- @@ -108,8 +106,8 @@ void RimFaultInViewCollection::fieldChangedByUi(const caf::PdmFieldHandle* chang if (&faultLabelColor == changedField) { - m_reservoirView->scheduleReservoirGridGeometryRegen(); - m_reservoirView->crossSectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); + parentView()->scheduleReservoirGridGeometryRegen(); + parentView()->crossSectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } if (&showFaultFaces == changedField || @@ -123,11 +121,8 @@ void RimFaultInViewCollection::fieldChangedByUi(const caf::PdmFieldHandle* chang &hideNncsWhenNoResultIsAvailable == changedField ) { - if (m_reservoirView) - { - m_reservoirView->scheduleCreateDisplayModelAndRedraw(); - m_reservoirView->crossSectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); - } + parentView()->scheduleCreateDisplayModelAndRedraw(); + parentView()->crossSectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } @@ -138,15 +133,6 @@ void RimFaultInViewCollection::fieldChangedByUi(const caf::PdmFieldHandle* chang } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimFaultInViewCollection::setReservoirView(RimEclipseView* ownerReservoirView) -{ - m_reservoirView = ownerReservoirView; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -188,11 +174,11 @@ bool faultComparator(const cvf::ref& a, const cvf::ref& b) //-------------------------------------------------------------------------------------------------- void RimFaultInViewCollection::syncronizeFaults() { - if (!(m_reservoirView && m_reservoirView->mainGrid()) ) return; + if (!(parentView() && parentView()->mainGrid()) ) return; const caf::ColorTable& colorTable = RiaColorTables::faultsPaletteColors(); - const cvf::Collection constRigFaults = m_reservoirView->mainGrid()->faults(); + const cvf::Collection constRigFaults = parentView()->mainGrid()->faults(); cvf::Collection rigFaults; { @@ -273,11 +259,11 @@ void RimFaultInViewCollection::syncronizeFaults() // NNCs this->noCommonAreaNnncCollection()->noCommonAreaNncs().deleteAllChildObjects(); - RigMainGrid* mainGrid = m_reservoirView->mainGrid(); + RigMainGrid* mainGrid = parentView()->mainGrid(); std::vector& nncConnections = mainGrid->nncData()->connections(); - for (size_t i = 0; i < nncConnections.size(); i++) + for (size_t connIndex = 0; connIndex < nncConnections.size(); connIndex++) { - if (!nncConnections[i].hasCommonArea()) + if (!nncConnections[connIndex].hasCommonArea()) { RimNoCommonAreaNNC* noCommonAreaNnc = new RimNoCommonAreaNNC(); @@ -286,7 +272,7 @@ void RimFaultInViewCollection::syncronizeFaults() { size_t gridLocalCellIndex; - const RigGridBase* hostGrid = mainGrid->gridAndGridLocalIdxFromGlobalCellIdx(nncConnections[i].m_c1GlobIdx, &gridLocalCellIndex); + const RigGridBase* hostGrid = mainGrid->gridAndGridLocalIdxFromGlobalCellIdx(nncConnections[connIndex].m_c1GlobIdx, &gridLocalCellIndex); size_t i, j, k; if (hostGrid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k)) @@ -307,7 +293,7 @@ void RimFaultInViewCollection::syncronizeFaults() { size_t gridLocalCellIndex; - const RigGridBase* hostGrid = mainGrid->gridAndGridLocalIdxFromGlobalCellIdx(nncConnections[i].m_c2GlobIdx, &gridLocalCellIndex); + const RigGridBase* hostGrid = mainGrid->gridAndGridLocalIdxFromGlobalCellIdx(nncConnections[connIndex].m_c2GlobIdx, &gridLocalCellIndex); size_t i, j, k; if (hostGrid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k)) @@ -339,9 +325,7 @@ void RimFaultInViewCollection::syncronizeFaults() //-------------------------------------------------------------------------------------------------- bool RimFaultInViewCollection::isGridVisualizationMode() const { - CVF_ASSERT(m_reservoirView); - - return m_reservoirView->isGridVisualizationMode(); + return parentView()->isGridVisualizationMode(); } //-------------------------------------------------------------------------------------------------- @@ -373,6 +357,17 @@ void RimFaultInViewCollection::defineUiOrdering(QString uiConfigName, caf::PdmUi } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEclipseView* RimFaultInViewCollection::parentView() const +{ + RimEclipseView* view = nullptr; + this->firstAncestorOrThisOfTypeAsserted(view); + + return view; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -383,3 +378,11 @@ bool RimFaultInViewCollection::isShowingFaultsAndFaultsOutsideFilters() const return m_showFaultsOutsideFilters; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFaultInViewCollection::setShowFaultsOutsideFilter(bool show) +{ + m_showFaultsOutsideFilters = show; +} + diff --git a/ApplicationCode/ProjectDataModel/RimFaultInViewCollection.h b/ApplicationCode/ProjectDataModel/RimFaultInViewCollection.h index 7e91ac2875..444d2148af 100644 --- a/ApplicationCode/ProjectDataModel/RimFaultInViewCollection.h +++ b/ApplicationCode/ProjectDataModel/RimFaultInViewCollection.h @@ -55,14 +55,14 @@ class RimFaultInViewCollection : public caf::PdmObject public: RimFaultInViewCollection(); - virtual ~RimFaultInViewCollection(); + ~RimFaultInViewCollection() override; - void setReservoirView(RimEclipseView* ownerReservoirView); void syncronizeFaults(); bool isGridVisualizationMode() const; bool isShowingFaultsAndFaultsOutsideFilters() const; + void setShowFaultsOutsideFilter(bool show); caf::PdmField showFaultFaces; caf::PdmField showOppositeFaultFaces; @@ -82,13 +82,13 @@ class RimFaultInViewCollection : public caf::PdmObject caf::PdmChildField noCommonAreaNnncCollection; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual caf::PdmFieldHandle* objectToggleField(); private: - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* objectToggleField() override; + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + RimEclipseView* parentView() const; private: caf::PdmField m_showFaultsOutsideFilters; - RimEclipseView* m_reservoirView; }; diff --git a/ApplicationCode/ProjectDataModel/RimFileWellPath.cpp b/ApplicationCode/ProjectDataModel/RimFileWellPath.cpp new file mode 100644 index 0000000000..c7908d6f52 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimFileWellPath.cpp @@ -0,0 +1,238 @@ +#include "RimFileWellPath.h" +#include "cafUtils.h" +#include "RifWellPathImporter.h" +#include "RimTools.h" +#include "QFileInfo" +#include "QDir" + + +CAF_PDM_SOURCE_INIT(RimFileWellPath, "WellPath"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFileWellPath::RimFileWellPath() +{ + CAF_PDM_InitFieldNoDefault(&id, "WellPathId", "Id", "", "", ""); + id.uiCapability()->setUiReadOnly(true); + id.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault(&sourceSystem, "SourceSystem", "Source System", "", "", ""); + sourceSystem.uiCapability()->setUiReadOnly(true); + sourceSystem.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault(&utmZone, "UTMZone", "UTM Zone", "", "", ""); + utmZone.uiCapability()->setUiReadOnly(true); + utmZone.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault(&updateDate, "WellPathUpdateDate", "Update Date", "", "", ""); + updateDate.uiCapability()->setUiReadOnly(true); + updateDate.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault(&updateUser, "WellPathUpdateUser", "Update User", "", "", ""); + updateUser.uiCapability()->setUiReadOnly(true); + updateUser.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault(&m_surveyType, "WellPathSurveyType", "Survey Type", "", "", ""); + m_surveyType.uiCapability()->setUiReadOnly(true); + m_surveyType.xmlCapability()->disableIO(); + + CAF_PDM_InitField(&m_filepath, "WellPathFilepath", QString(""), "File Path", "", "", ""); + m_filepath.uiCapability()->setUiReadOnly(true); + CAF_PDM_InitField(&m_wellPathIndexInFile, "WellPathNumberInFile", -1, "Well Number in File", "", "", ""); + m_wellPathIndexInFile.uiCapability()->setUiReadOnly(true); + + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimFileWellPath::~RimFileWellPath() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimFileWellPath::filepath() const +{ + return m_filepath(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFileWellPath::setFilepath(const QString& path) +{ + m_filepath = path; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimFileWellPath::wellPathIndexInFile() const +{ + return m_wellPathIndexInFile(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFileWellPath::setWellPathIndexInFile(int index) +{ + m_wellPathIndexInFile = index ; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFileWellPath::setSurveyType(QString surveyType) +{ + m_surveyType = surveyType; + if (m_surveyType == "PLAN") + setWellPathColor(cvf::Color3f(0.999f, 0.333f, 0.0f)); + else if (m_surveyType == "PROTOTYPE") + setWellPathColor(cvf::Color3f(0.0f, 0.333f, 0.999f)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFileWellPath::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + RimWellPath::defineUiOrdering(uiConfigName, uiOrdering); + + caf::PdmUiGroup* fileInfoGroup = uiOrdering.createGroupBeforeGroup("Simulation Well", "File"); + fileInfoGroup->add(&m_filepath); + fileInfoGroup->add(&m_wellPathIndexInFile); + + if ( !id().isEmpty() ) uiOrdering.insertBeforeItem(m_datumElevation.uiCapability(), &id); + if ( !sourceSystem().isEmpty() ) uiOrdering.insertBeforeItem(m_datumElevation.uiCapability(), &sourceSystem); + if ( !utmZone().isEmpty() ) uiOrdering.insertBeforeItem(m_datumElevation.uiCapability(), &utmZone); + if ( !updateDate().isEmpty() ) uiOrdering.insertBeforeItem(m_datumElevation.uiCapability(), &updateDate); + if ( !updateUser().isEmpty() ) uiOrdering.insertBeforeItem(m_datumElevation.uiCapability(), &updateUser); + if ( !m_surveyType().isEmpty() ) uiOrdering.insertBeforeItem(m_datumElevation.uiCapability(), &m_surveyType); +} + +//-------------------------------------------------------------------------------------------------- +/// Read JSON or ascii file containing well path data +//-------------------------------------------------------------------------------------------------- +bool RimFileWellPath::readWellPathFile(QString* errorMessage, RifWellPathImporter* wellPathImporter) +{ + if (caf::Utils::fileExists(m_filepath())) + { + RifWellPathImporter::WellData wellData = wellPathImporter->readWellData(m_filepath(), m_wellPathIndexInFile()); + RifWellPathImporter::WellMetaData wellMetaData = wellPathImporter->readWellMetaData(m_filepath(), m_wellPathIndexInFile()); + // General well info + + setName(wellData.m_name); + id = wellMetaData.m_id; + sourceSystem = wellMetaData.m_sourceSystem; + utmZone = wellMetaData.m_utmZone; + updateUser = wellMetaData.m_updateUser; + setSurveyType(wellMetaData.m_surveyType); + updateDate = wellMetaData.m_updateDate.toString("d MMMM yyyy"); + + setWellPathGeometry(wellData.m_wellPathGeometry.p()); + return true; + } + else + { + if (errorMessage) (*errorMessage) = "Could not find the well path file: " + m_filepath(); + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimFileWellPath::getCacheDirectoryPath() +{ + QString cacheDirPath = RimTools::getCacheRootDirectoryPathFromProject(); + cacheDirPath += "_wellpaths"; + return cacheDirPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimFileWellPath::getCacheFileName() +{ + if (m_filepath().isEmpty()) + { + return ""; + } + + QString cacheFileName; + + // Make the path correct related to the possibly new project filename + QString newCacheDirPath = getCacheDirectoryPath(); + QFileInfo oldCacheFile(m_filepath); + + + cacheFileName = newCacheDirPath + "/" + oldCacheFile.fileName(); + + return cacheFileName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFileWellPath::setupBeforeSave() +{ + // SSIHUB is the only source for populating Id, use text in this field to decide if the cache file must be copied to new project cache location + if (!isStoredInCache()) + { + return; + } + + if (m_filepath().isEmpty()) + { + return; + } + + QDir::root().mkpath(getCacheDirectoryPath()); + + QString newCacheFileName = getCacheFileName(); + + // Use QFileInfo to get same string representation to avoid issues with mix of forward and backward slashes + QFileInfo prevFileInfo(m_filepath); + QFileInfo currentFileInfo(newCacheFileName); + + if (prevFileInfo.absoluteFilePath().compare(currentFileInfo.absoluteFilePath()) != 0) + { + QFile::copy(m_filepath, newCacheFileName); + + m_filepath = newCacheFileName; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimFileWellPath::isStoredInCache() +{ + // SSIHUB is the only source for populating Id, use text in this field to decide if the cache file must be copied to new project cache location + return !id().isEmpty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimFileWellPath::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) +{ + RimWellPath::updateFilePathsFromProjectPath(newProjectPath, oldProjectPath); + + if (isStoredInCache()) + { + QString newCacheFileName = getCacheFileName(); + + if (caf::Utils::fileExists(newCacheFileName)) + { + m_filepath = newCacheFileName; + } + } + else + { + m_filepath = RimTools::relocateFile(m_filepath(), newProjectPath, oldProjectPath, nullptr, nullptr); + } +} + diff --git a/ApplicationCode/ProjectDataModel/RimFileWellPath.h b/ApplicationCode/ProjectDataModel/RimFileWellPath.h new file mode 100644 index 0000000000..e8e462dab9 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimFileWellPath.h @@ -0,0 +1,59 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once +#include "RimWellPath.h" + +class RimFileWellPath : public RimWellPath +{ + CAF_PDM_HEADER_INIT; +public: + + RimFileWellPath(); + ~RimFileWellPath() override; + + QString filepath() const; + void setFilepath(const QString& path); + bool readWellPathFile(QString * errorMessage, RifWellPathImporter* wellPathImporter); + int wellPathIndexInFile() const; // -1 means none. + void setWellPathIndexInFile(int index); + void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; + +private: + QString surveyType() { return m_surveyType; } + void setSurveyType(QString surveyType); + bool isStoredInCache(); + QString getCacheFileName(); + QString getCacheDirectoryPath(); + + void setupBeforeSave() override; + + caf::PdmField m_filepath; + caf::PdmField m_wellPathIndexInFile; // -1 means none. + + caf::PdmField id; + caf::PdmField sourceSystem; + caf::PdmField utmZone; + caf::PdmField updateDate; + caf::PdmField updateUser; + caf::PdmField m_surveyType; + + + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +}; + diff --git a/ApplicationCode/ProjectDataModel/RimFormationNames.cpp b/ApplicationCode/ProjectDataModel/RimFormationNames.cpp index fdb8a6db9d..535f89f038 100644 --- a/ApplicationCode/ProjectDataModel/RimFormationNames.cpp +++ b/ApplicationCode/ProjectDataModel/RimFormationNames.cpp @@ -23,6 +23,7 @@ #include "RimCase.h" #include "RimTools.h" #include "Rim3dView.h" +#include "RimWellLogTrack.h" #include "cafPdmUiFilePathEditor.h" @@ -118,14 +119,25 @@ QString RimFormationNames::fileNameWoPath() //-------------------------------------------------------------------------------------------------- void RimFormationNames::updateConnectedViews() { - std::vector usingObjs; - this->objectsWithReferringPtrFields(usingObjs); - for (caf::PdmObjectHandle* obj: usingObjs) + std::vector objects; + this->objectsWithReferringPtrFieldsOfType(objects); + + for (RimCase* caseObj : objects) { - RimCase* caseObj = dynamic_cast(obj); if (caseObj) { caseObj->updateFormationNamesData(); + + std::vector tracks; + caseObj->objectsWithReferringPtrFieldsOfType(tracks); + for (RimWellLogTrack* track : tracks) + { + // The track may be referring to the case for other reasons than formations. + if (track->formationNamesCase() == caseObj) + { + track->loadDataAndUpdate(true); + } + } } } } diff --git a/ApplicationCode/ProjectDataModel/RimFormationNames.h b/ApplicationCode/ProjectDataModel/RimFormationNames.h index a40689ad9c..04d27b8832 100644 --- a/ApplicationCode/ProjectDataModel/RimFormationNames.h +++ b/ApplicationCode/ProjectDataModel/RimFormationNames.h @@ -32,7 +32,7 @@ class RimFormationNames : public caf::PdmObject public: RimFormationNames(); - ~RimFormationNames(); + ~RimFormationNames() override; void setFileName(const QString& fileName); const QString& fileName(); @@ -45,8 +45,8 @@ class RimFormationNames : public caf::PdmObject void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath); protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void initAfterRead() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void initAfterRead() override; private: void updateUiTreeName(); diff --git a/ApplicationCode/ProjectDataModel/RimFormationNamesCollection.h b/ApplicationCode/ProjectDataModel/RimFormationNamesCollection.h index a06875d318..88b4b99610 100644 --- a/ApplicationCode/ProjectDataModel/RimFormationNamesCollection.h +++ b/ApplicationCode/ProjectDataModel/RimFormationNamesCollection.h @@ -31,7 +31,7 @@ class RimFormationNamesCollection: public caf::PdmObject public: RimFormationNamesCollection(); - ~RimFormationNamesCollection(); + ~RimFormationNamesCollection() override; const caf::PdmChildArrayField& formationNamesList() const { return m_formationNamesList;} diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp index 2e4dd648f1..494d284f8b 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCase.cpp @@ -20,6 +20,7 @@ #include "RimGeoMechCase.h" #include "RiaApplication.h" +#include "RiaLogging.h" #include "RiaPreferences.h" #include "RifOdbReader.h" @@ -39,9 +40,11 @@ #include "RimIntersectionCollection.h" #include "RimMainPlotCollection.h" #include "RimProject.h" +#include "RimTimeStepFilter.h" #include "RimTools.h" #include "RimWellLogPlotCollection.h" +#include "cafPdmUiPropertyViewDialog.h" #include "cafPdmUiPushButtonEditor.h" #include "cafPdmUiTreeOrdering.h" #include "cafUtils.h" @@ -54,6 +57,7 @@ CAF_PDM_SOURCE_INIT(RimGeoMechCase, "ResInsightGeoMechCase"); /// //-------------------------------------------------------------------------------------------------- RimGeoMechCase::RimGeoMechCase(void) + : m_applyTimeFilter(false) { CAF_PDM_InitObject("Geomechanical Case", ":/GeoMechCase48x48.png", "", ""); @@ -125,7 +129,7 @@ QString RimGeoMechCase::caseFileName() const //-------------------------------------------------------------------------------------------------- RigGeoMechCaseData* RimGeoMechCase::geoMechData() { - return m_geoMechCaseData.p(); + return m_geoMechCaseData.p(); } //-------------------------------------------------------------------------------------------------- @@ -133,7 +137,28 @@ RigGeoMechCaseData* RimGeoMechCase::geoMechData() //-------------------------------------------------------------------------------------------------- const RigGeoMechCaseData* RimGeoMechCase::geoMechData() const { - return m_geoMechCaseData.p(); + return m_geoMechCaseData.p(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechCase::reloadDataAndUpdate() +{ + if (this->geoMechData()) + { + m_geoMechCaseData = nullptr; + std::string errMsg; + if (this->openGeoMechCase(&errMsg) == CASE_OPEN_ERROR) + { + RiaLogging::error(QString::fromStdString(errMsg)); + } + for (auto v : geoMechViews()) + { + v->loadDataAndUpdate(); + v->setCurrentTimeStep(v->currentTimeStep()); + } + } } //-------------------------------------------------------------------------------------------------- @@ -143,7 +168,7 @@ RimGeoMechView* RimGeoMechCase::createAndAddReservoirView() { RimGeoMechView* gmv = new RimGeoMechView(); size_t i = geoMechViews().size(); - gmv->name = QString("View %1").arg(i + 1); + gmv->setName(QString("View %1").arg(i + 1)); gmv->setGeoMechCase(this); @@ -154,47 +179,82 @@ RimGeoMechView* RimGeoMechCase::createAndAddReservoirView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimGeoMechCase::openGeoMechCase(std::string* errorMessage) +RimGeoMechCase::CaseOpenStatus RimGeoMechCase::openGeoMechCase(std::string* errorMessage) { // If read already, return - if (this->m_geoMechCaseData.notNull()) return true; + if (this->m_geoMechCaseData.notNull()) return CASE_OPEN_OK; if (!caf::Utils::fileExists(m_caseFileName().path())) { - return false; + return CASE_OPEN_ERROR; } - m_geoMechCaseData = new RigGeoMechCaseData(m_caseFileName().path().toStdString()); - - bool fileOpenSuccess = m_geoMechCaseData->openAndReadFemParts(errorMessage); + cvf::ref geoMechCaseData = new RigGeoMechCaseData(m_caseFileName().path().toStdString()); + bool fileOpenSuccess = geoMechCaseData->open(errorMessage); if (!fileOpenSuccess) { - // If opening failed, release all data - // Also, several places is checked for this data to validate availability of data - m_geoMechCaseData = nullptr; - return false; + return CASE_OPEN_ERROR; + } + + std::vector stepNames; + if (!geoMechCaseData->readTimeSteps(errorMessage, &stepNames)) + { + return CASE_OPEN_ERROR; + } + + std::vector> timeSteps; + for (const std::string& timeStepStringStdString : stepNames) + { + QString timeStepString = QString::fromStdString(timeStepStringStdString); + timeSteps.push_back(std::make_pair(timeStepString, dateTimeFromTimeStepString(timeStepString))); + } + + m_timeStepFilter->setTimeStepsFromFile(timeSteps); + + if (m_applyTimeFilter) + { + m_applyTimeFilter = false; // Clear when we've done this once. + + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, m_timeStepFilter, "Time Step Filter", "", QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + propertyDialog.resize(QSize(400, 400)); + + // Push arrow cursor onto the cursor stack so it takes over from the wait cursor. + QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); + int propertyReturnValue = propertyDialog.exec(); + // Pop arrow cursor off the cursor stack so that the previous (wait) cursor takes over. + QApplication::restoreOverrideCursor(); + if (propertyReturnValue != QDialog::Accepted) + { + return CASE_OPEN_CANCELLED; + } + m_timeStepFilter->updateFilteredTimeStepsFromUi(); + } + + // Continue reading the open file + if (!geoMechCaseData->readFemParts(errorMessage, m_timeStepFilter->filteredTimeSteps())) + { + return CASE_OPEN_ERROR; } if (activeFormationNames()) { - m_geoMechCaseData->femPartResults()->setActiveFormationNames(activeFormationNames()->formationNamesData()); + geoMechCaseData->femPartResults()->setActiveFormationNames(activeFormationNames()->formationNamesData()); } else { - m_geoMechCaseData->femPartResults()->setActiveFormationNames(nullptr); + geoMechCaseData->femPartResults()->setActiveFormationNames(nullptr); } - if (m_geoMechCaseData.notNull()) + std::vector fileNames; + for (const caf::FilePath& fileName : m_elementPropertyFileNames.v()) { - std::vector fileNames; - for (const caf::FilePath& fileName : m_elementPropertyFileNames.v()) - { - fileNames.push_back(fileName.path()); - } - geoMechData()->femPartResults()->addElementPropertyFiles(fileNames); + fileNames.push_back(fileName.path()); } + geoMechCaseData->femPartResults()->addElementPropertyFiles(fileNames); - return fileOpenSuccess; + m_geoMechCaseData = geoMechCaseData; + + return CASE_OPEN_OK; } //-------------------------------------------------------------------------------------------------- @@ -244,7 +304,7 @@ std::vector RimGeoMechCase::timeStepDates() const { QStringList timeStrings = timeStepStrings(); - return RimGeoMechCase::dateTimeVectorFromTimeStepStrings(timeStrings); + return RimGeoMechCase::vectorOfValidDateTimesFromTimeStepStrings(timeStrings); } //-------------------------------------------------------------------------------------------------- @@ -273,7 +333,7 @@ QStringList RimGeoMechCase::timeStepStrings() const const RigGeoMechCaseData* rigCaseData = geoMechData(); if (rigCaseData && rigCaseData->femPartResults()) { - std::vector stepNames = rigCaseData->femPartResults()->stepNames(); + std::vector stepNames = rigCaseData->femPartResults()->filteredStepNames(); for (size_t i = 0; i < stepNames.size(); i++) { stringList += QString::fromStdString(stepNames[i]); @@ -291,9 +351,11 @@ QString RimGeoMechCase::timeStepName(int frameIdx) const const RigGeoMechCaseData* rigCaseData = geoMechData(); if (rigCaseData && rigCaseData->femPartResults()) { - std::vector stepNames = rigCaseData->femPartResults()->stepNames(); - - return QString::fromStdString(stepNames[frameIdx]); + std::vector stepNames = rigCaseData->femPartResults()->filteredStepNames(); + if (frameIdx < static_cast(stepNames.size())) + { + return QString::fromStdString(stepNames[frameIdx]); + } } return ""; @@ -399,30 +461,40 @@ double RimGeoMechCase::frictionAngleDeg() const return m_frictionAngleDeg; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechCase::setApplyTimeFilter(bool applyTimeFilter) +{ + m_applyTimeFilter = applyTimeFilter; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::Vec3d RimGeoMechCase::displayModelOffset() const { - return this->allCellsBoundingBox().min(); + auto bb = this->allCellsBoundingBox(); + if (bb.isValid()) + { + return this->allCellsBoundingBox().min(); + } + + return cvf::Vec3d::ZERO; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimGeoMechCase::dateTimeVectorFromTimeStepStrings(const QStringList& timeStepStrings) +std::vector RimGeoMechCase::vectorOfValidDateTimesFromTimeStepStrings(const QStringList& timeStepStrings) { std::vector dates; - QString dateFormat = "ddMMyyyy"; + QString dateFormat = "yyyyMMdd"; - for (int i = 0; i < timeStepStrings.size(); i++) + for (const QString& timeStepString : timeStepStrings) { - QString timeStepString = timeStepStrings[i]; - - QString dateStr = subStringOfDigits(timeStepString, dateFormat.size()); - - QDateTime dateTime = QDateTime::fromString(dateStr, dateFormat); + QDateTime dateTime = dateTimeFromTimeStepString(timeStepString); if (dateTime.isValid()) { dates.push_back(dateTime); @@ -432,6 +504,16 @@ std::vector RimGeoMechCase::dateTimeVectorFromTimeStepStrings(const Q return dates; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QDateTime RimGeoMechCase::dateTimeFromTimeStepString(const QString& timeStepString) +{ + QString dateFormat = "yyyyMMdd"; + QString dateStr = subStringOfDigits(timeStepString, dateFormat.size()); + return QDateTime::fromString(dateStr, dateFormat); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -661,6 +743,12 @@ void RimGeoMechCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& elmPropGroup->add(&m_elementPropertyFileNameIndexUiSelection); elmPropGroup->add(&m_reloadElementPropertyFileCommand); elmPropGroup->add(&m_closeElementPropertyFileCommand); + + + caf::PdmUiGroup* timeStepFilterGroup = uiOrdering.addNewGroup("Time Step Filter"); + timeStepFilterGroup->setCollapsedByDefault(true); + m_timeStepFilter->uiOrdering(uiConfigName, *timeStepFilterGroup); + } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCase.h b/ApplicationCode/ProjectDataModel/RimGeoMechCase.h index 3caae63564..d2ea9003aa 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCase.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCase.h @@ -44,61 +44,67 @@ class RimGeoMechCase : public RimCase CAF_PDM_HEADER_INIT; public: + enum CaseOpenStatus + { + CASE_OPEN_OK = 0, + CASE_OPEN_CANCELLED, + CASE_OPEN_ERROR + }; RimGeoMechCase(void); - virtual ~RimGeoMechCase(void); + ~RimGeoMechCase(void) override; void setFileName(const QString& fileName); QString caseFileName() const; - bool openGeoMechCase(std::string* errorMessage); + CaseOpenStatus openGeoMechCase(std::string* errorMessage); RigGeoMechCaseData* geoMechData(); const RigGeoMechCaseData* geoMechData() const; + void reloadDataAndUpdate(); + RimGeoMechView* createAndAddReservoirView(); - virtual void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath); + void updateFilePathsFromProjectPath(const QString& projectPath, const QString& oldProjectPath) override; - virtual std::vector timeStepDates() const override; - virtual QStringList timeStepStrings() const override; - virtual QString timeStepName(int frameIdx) const override; + std::vector timeStepDates() const override; + QStringList timeStepStrings() const override; + QString timeStepName(int frameIdx) const override; - virtual cvf::BoundingBox activeCellsBoundingBox() const override; - virtual cvf::BoundingBox allCellsBoundingBox() const override; + cvf::BoundingBox activeCellsBoundingBox() const override; + cvf::BoundingBox allCellsBoundingBox() const override; - virtual double characteristicCellSize() const override; + double characteristicCellSize() const override; - virtual void setFormationNames(RimFormationNames* formationNames) override; + void setFormationNames(RimFormationNames* formationNames) override; void addElementPropertyFiles(const std::vector& filenames); double cohesion() const; double frictionAngleDeg() const; + void setApplyTimeFilter(bool applyTimeFilter); // Fields: caf::PdmChildArrayField geoMechViews; - - - - private: - virtual cvf::Vec3d displayModelOffset() const override; - static std::vector dateTimeVectorFromTimeStepStrings(const QStringList& timeStepStrings); + cvf::Vec3d displayModelOffset() const override; + static std::vector vectorOfValidDateTimesFromTimeStepStrings(const QStringList& timeStepStrings); + static QDateTime dateTimeFromTimeStepString(const QString& timeStepString); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual void updateFormationNamesData() override; + void updateFormationNamesData() override; - virtual void initAfterRead() override; + void initAfterRead() override; static QString subStringOfDigits(const QString& timeStepString, int numberOfDigitsToFind); void closeSelectedElementPropertyFiles(); void reloadSelectedElementPropertyFiles(); - virtual std::vector allSpecialViews() const override; + std::vector allSpecialViews() const override; private: cvf::ref m_geoMechCaseData; @@ -109,4 +115,5 @@ class RimGeoMechCase : public RimCase caf::PdmField > m_elementPropertyFileNameIndexUiSelection; caf::PdmField m_closeElementPropertyFileCommand; caf::PdmField m_reloadElementPropertyFileCommand; + bool m_applyTimeFilter; }; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.h b/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.h index 0e14fdd270..8c4954db81 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechCellColors.h @@ -37,12 +37,12 @@ class RimGeoMechCellColors : public RimGeoMechResultDefinition public: RimGeoMechCellColors(void); - virtual ~RimGeoMechCellColors(void); + ~RimGeoMechCellColors(void) override; caf::PdmChildField legendConfig; void updateIconState(); - virtual void initAfterRead() override; + void initAfterRead() override; protected: void updateLegendCategorySettings() override; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechModels.h b/ApplicationCode/ProjectDataModel/RimGeoMechModels.h index e96288bfee..a7dcdd14eb 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechModels.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechModels.h @@ -36,7 +36,7 @@ class RimGeoMechModels : public caf::PdmObject public: RimGeoMechModels(void); - virtual ~RimGeoMechModels(void); + ~RimGeoMechModels(void) override; caf::PdmChildArrayField cases; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp index bbc305e647..f15f5c1438 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.cpp @@ -88,7 +88,7 @@ void RimGeoMechPropertyFilter::fieldChangedByUi(const caf::PdmFieldHandle* chang this->updateFilterName(); this->uiCapability()->updateConnectedEditors(); - parentContainer()->updateDisplayModelNotifyManagedViews(); + parentContainer()->updateDisplayModelNotifyManagedViews(this); } } diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.h b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.h index 23c636b706..a8c3d5a969 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilter.h @@ -37,7 +37,7 @@ class RimGeoMechPropertyFilter : public RimPropertyFilter public: RimGeoMechPropertyFilter(); - virtual ~RimGeoMechPropertyFilter(); + ~RimGeoMechPropertyFilter() override; caf::PdmChildField resultDefinition; @@ -54,10 +54,10 @@ class RimGeoMechPropertyFilter : public RimPropertyFilter bool isActiveAndHasResult(); protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) ; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override ; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; private: void updateReadOnlyStateOfAllFields(); diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.h b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.h index d27fac7ec2..5ca617f6ca 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechPropertyFilterCollection.h @@ -37,7 +37,7 @@ class RimGeoMechPropertyFilterCollection : public RimPropertyFilterCollection CAF_PDM_HEADER_INIT; public: RimGeoMechPropertyFilterCollection(); - virtual ~RimGeoMechPropertyFilterCollection(); + ~RimGeoMechPropertyFilterCollection() override; RimGeoMechView* reservoirView(); @@ -54,5 +54,5 @@ class RimGeoMechPropertyFilterCollection : public RimPropertyFilterCollection protected: // Overridden methods - virtual void initAfterRead() override; + void initAfterRead() override; }; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp index c8b2d20710..a90c1d050b 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp @@ -51,6 +51,7 @@ void caf::AppEnum< RigFemResultPosEnum >::setUp() addItem(RIG_ELEMENT_NODAL_FACE, "ELEMENT_NODAL_FACE", "Element Nodal On Face"); addItem(RIG_FORMATION_NAMES, "FORMATION_NAMES", "Formation Names"); addItem(RIG_ELEMENT, "ELEMENT", "Element"); + addItem(RIG_WELLPATH_DERIVED, "WELLPATH_DERIVED", "Well Path Derived"); setDefault(RIG_NODAL); } } @@ -85,29 +86,25 @@ RimGeoMechResultDefinition::RimGeoMechResultDefinition(void) m_compactionRefLayer.uiCapability()->setUiHidden(true); CAF_PDM_InitFieldNoDefault(&m_resultPositionTypeUiField, "ResultPositionTypeUi", "Result Position", "", "", ""); - m_resultPositionTypeUiField.xmlCapability()->setIOWritable(false); - m_resultPositionTypeUiField.xmlCapability()->setIOReadable(false); + m_resultPositionTypeUiField.xmlCapability()->disableIO(); CAF_PDM_InitField(&m_resultVariableUiField, "ResultVariableUI", QString(""), "Value", "", "", ""); - m_resultVariableUiField.xmlCapability()->setIOWritable(false); - m_resultVariableUiField.xmlCapability()->setIOReadable(false); + m_resultVariableUiField.xmlCapability()->disableIO(); CAF_PDM_InitField(&m_isTimeLapseResultUiField, "IsTimeLapseResultUI", false, "Enable Relative Result", "", "Use the difference with respect to a specific time step as the result variable to plot", ""); - m_isTimeLapseResultUiField.xmlCapability()->setIOWritable(false); - m_isTimeLapseResultUiField.xmlCapability()->setIOReadable(false); + m_isTimeLapseResultUiField.xmlCapability()->disableIO(); CAF_PDM_InitField(&m_timeLapseBaseTimestepUiField, "TimeLapseBaseTimeStepUI", 0, "Base Time Step", "", "", ""); - m_timeLapseBaseTimestepUiField.xmlCapability()->setIOWritable(false); - m_timeLapseBaseTimestepUiField.xmlCapability()->setIOReadable(false); + m_timeLapseBaseTimestepUiField.xmlCapability()->disableIO(); m_resultVariableUiField.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); m_resultVariableUiField.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); CAF_PDM_InitField(&m_compactionRefLayerUiField, "CompactionRefLayerUi", (int)RigFemResultAddress::NO_COMPACTION, "Compaction Ref Layer", "", "The compaction is calculated with reference to this layer. Default layer is the topmost layer with POR", ""); - m_compactionRefLayerUiField.xmlCapability()->setIOWritable(false); - m_compactionRefLayerUiField.xmlCapability()->setIOReadable(false); + m_compactionRefLayerUiField.xmlCapability()->disableIO(); m_isChangedByField = false; + m_addWellPathDerivedResults = false; } //-------------------------------------------------------------------------------------------------- @@ -143,7 +140,7 @@ void RimGeoMechResultDefinition::defineUiOrdering(QString uiConfigName, caf::Pdm { if (m_geomCase && m_geomCase->geoMechData() ) { - m_compactionRefLayerUiField = (int)m_geomCase->geoMechData()->femParts()->part(0)->structGrid()->reservoirIJKBoundingBox().first.z(); + m_compactionRefLayerUiField = (int)m_geomCase->geoMechData()->femParts()->part(0)->getOrCreateStructGrid()->reservoirIJKBoundingBox().first.z(); } } } @@ -169,7 +166,19 @@ QList RimGeoMechResultDefinition::calculateValueOptions( if (m_geomCase) { - if (&m_resultVariableUiField == fieldNeedingOptions) + if (&m_resultPositionTypeUiField == fieldNeedingOptions) + { + std::vector optionItems = { RIG_NODAL, RIG_ELEMENT_NODAL, RIG_INTEGRATION_POINT, RIG_ELEMENT_NODAL_FACE, RIG_FORMATION_NAMES, RIG_ELEMENT }; + if (m_addWellPathDerivedResults) + { + optionItems.push_back(RIG_WELLPATH_DERIVED); + } + for (RigFemResultPosEnum value : optionItems) + { + options.push_back(caf::PdmOptionItemInfo(caf::AppEnum::uiText(value), QVariant(value))); + } + } + else if (&m_resultVariableUiField == fieldNeedingOptions) { std::map > fieldCompNames = getResultMetaDataForUIFieldSetting(); @@ -194,7 +203,7 @@ QList RimGeoMechResultDefinition::calculateValueOptions( std::vector stepNames; if(m_geomCase->geoMechData()) { - stepNames = m_geomCase->geoMechData()->femPartResults()->stepNames(); + stepNames = m_geomCase->geoMechData()->femPartResults()->filteredStepNames(); } for (size_t stepIdx = 0; stepIdx < stepNames.size(); ++stepIdx) @@ -206,7 +215,7 @@ QList RimGeoMechResultDefinition::calculateValueOptions( { if (m_geomCase->geoMechData()) { - size_t kCount = m_geomCase->geoMechData()->femParts()->part(0)->structGrid()->gridPointCountK() - 1; + size_t kCount = m_geomCase->geoMechData()->femParts()->part(0)->getOrCreateStructGrid()->gridPointCountK() - 1; for ( size_t layerIdx = 0; layerIdx < kCount; ++layerIdx ) { options.push_back(caf::PdmOptionItemInfo(QString::number(layerIdx + 1), (int)layerIdx)); @@ -235,6 +244,34 @@ void RimGeoMechResultDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha { m_isChangedByField = true; + if (&m_resultPositionTypeUiField == changedField) + { + if (m_resultPositionTypeUiField() == RIG_WELLPATH_DERIVED) + { + m_isTimeLapseResultUiField = false; + m_isTimeLapseResultUiField.uiCapability()->setUiReadOnly(true); + m_timeLapseBaseTimestepUiField.uiCapability()->setUiReadOnly(true); + } + else + { + m_isTimeLapseResultUiField.uiCapability()->setUiReadOnly(false); + m_timeLapseBaseTimestepUiField.uiCapability()->setUiReadOnly(false); + } + } + + if (&m_isTimeLapseResultUiField == changedField) + { + m_isTimeLapseResult = m_isTimeLapseResultUiField; + if (m_isTimeLapseResult()) + { + if (m_timeLapseBaseTimestep() == RigFemResultAddress::NO_TIME_LAPSE) + { + m_timeLapseBaseTimestep = 0; + m_timeLapseBaseTimestepUiField = 0; + } + } + } + if( &m_resultPositionTypeUiField == changedField || &m_isTimeLapseResultUiField == changedField || &m_timeLapseBaseTimestepUiField == changedField) @@ -428,6 +465,8 @@ void RimGeoMechResultDefinition::initAfterRead() m_resultVariableUiField = composeFieldCompString(m_resultFieldName(), m_resultComponentName()); m_isTimeLapseResultUiField = m_isTimeLapseResult; m_timeLapseBaseTimestepUiField = m_timeLapseBaseTimestep; + m_isTimeLapseResultUiField.uiCapability()->setUiReadOnly(resultPositionType() == RIG_WELLPATH_DERIVED); + m_timeLapseBaseTimestepUiField.uiCapability()->setUiReadOnly(resultPositionType() == RIG_WELLPATH_DERIVED); m_compactionRefLayerUiField = m_compactionRefLayer; } @@ -439,14 +478,33 @@ void RimGeoMechResultDefinition::loadResult() { if (m_geomCase && m_geomCase->geoMechData()) { - m_geomCase->geoMechData()->femPartResults()->assertResultsLoaded(this->resultAddress()); + if (this->resultAddress().fieldName == RiaDefines::wellPathFGResultName().toStdString() || + this->resultAddress().fieldName == RiaDefines::wellPathSFGResultName().toStdString()) + { + RigFemResultAddress stressResAddr(RIG_ELEMENT_NODAL, std::string("ST"), ""); + RigFemResultAddress porBarResAddr(RIG_ELEMENT_NODAL, std::string("POR-Bar"), ""); + m_geomCase->geoMechData()->femPartResults()->assertResultsLoaded(stressResAddr); + m_geomCase->geoMechData()->femPartResults()->assertResultsLoaded(porBarResAddr); + } + else + { + m_geomCase->geoMechData()->femPartResults()->assertResultsLoaded(this->resultAddress()); + } } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGeoMechResultDefinition::setAddWellPathDerivedResults(bool addWellPathDerivedResults) +{ + m_addWellPathDerivedResults = addWellPathDerivedResults; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigFemResultAddress RimGeoMechResultDefinition::resultAddress() +RigFemResultAddress RimGeoMechResultDefinition::resultAddress() const { return RigFemResultAddress(resultPositionType(), resultFieldName().toStdString(), @@ -455,6 +513,38 @@ RigFemResultAddress RimGeoMechResultDefinition::resultAddress() resultFieldName().toStdString() == RigFemPartResultsCollection::FIELD_NAME_COMPACTION ? m_compactionRefLayer() : RigFemResultAddress::NO_COMPACTION); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimGeoMechResultDefinition::observedResults() const +{ + return std::vector(1, resultAddress()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigFemResultPosEnum RimGeoMechResultDefinition::resultPositionType() const +{ + return m_resultPositionType(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimGeoMechResultDefinition::resultFieldName() const +{ + return m_resultFieldName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimGeoMechResultDefinition::resultComponentName() const +{ + return m_resultComponentName(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -468,7 +558,16 @@ RigGeoMechCaseData* RimGeoMechResultDefinition::ownerCaseData() //-------------------------------------------------------------------------------------------------- bool RimGeoMechResultDefinition::hasResult() { - return ownerCaseData()->femPartResults()->assertResultsLoaded(this->resultAddress()); + RigGeoMechCaseData* caseData = ownerCaseData(); + if (caseData) + { + RigFemPartResultsCollection* results = caseData->femPartResults(); + if (results) + { + return results->assertResultsLoaded(this->resultAddress()); + } + } + return false; } @@ -529,14 +628,18 @@ void RimGeoMechResultDefinition::setResultAddress( const RigFemResultAddress& re m_resultPositionType = resultAddress.resultPosType; m_resultFieldName = QString::fromStdString(resultAddress.fieldName); m_resultComponentName = QString::fromStdString(resultAddress.componentName); - m_isTimeLapseResult = resultAddress.isTimeLapse(); - - m_timeLapseBaseTimestep = m_isTimeLapseResult ? resultAddress.timeLapseBaseFrameIdx: -1; - m_compactionRefLayer = resultAddress.refKLayerIndex; - m_resultPositionTypeUiField = m_resultPositionType; m_resultVariableUiField = composeFieldCompString(m_resultFieldName(), m_resultComponentName()); + + m_isTimeLapseResult = resultAddress.isTimeLapse(); m_isTimeLapseResultUiField = m_isTimeLapseResult; + + if (m_isTimeLapseResult) + { + m_timeLapseBaseTimestep = resultAddress.timeLapseBaseFrameIdx; + } m_timeLapseBaseTimestepUiField = m_timeLapseBaseTimestep; + + m_compactionRefLayer = resultAddress.refKLayerIndex; m_compactionRefLayerUiField = m_compactionRefLayer; } diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h index 0cc449b192..5784cff651 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.h @@ -25,6 +25,7 @@ #include "cafAppEnum.h" #include "RigFemResultPosEnum.h" #include "RigFemResultAddress.h" +#include "RimFemResultObserver.h" class RimGeoMechView; class RimGeoMechPropertyFilter; @@ -36,24 +37,26 @@ class RimGeoMechCase; /// /// //================================================================================================== -class RimGeoMechResultDefinition : public caf::PdmObject +class RimGeoMechResultDefinition : public RimFemResultObserver { CAF_PDM_HEADER_INIT; public: RimGeoMechResultDefinition(void); - virtual ~RimGeoMechResultDefinition(void); + ~RimGeoMechResultDefinition(void) override; void setGeoMechCase(RimGeoMechCase* geomCase); RigGeoMechCaseData* ownerCaseData(); bool hasResult(); void loadResult(); + void setAddWellPathDerivedResults(bool addWellPathDerivedResults); - RigFemResultAddress resultAddress(); + RigFemResultAddress resultAddress() const; + std::vector observedResults() const override; - RigFemResultPosEnum resultPositionType() { return m_resultPositionType();} - QString resultFieldName() { return m_resultFieldName();} - QString resultComponentName() { return m_resultComponentName();} + RigFemResultPosEnum resultPositionType() const; + QString resultFieldName() const; + QString resultComponentName() const; void setResultAddress(const RigFemResultAddress& resultAddress); QString resultFieldUiName(); @@ -63,18 +66,18 @@ class RimGeoMechResultDefinition : public caf::PdmObject protected: virtual void updateLegendCategorySettings() {}; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: // Overridden PDM methods - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void initAfterRead() override; + void initAfterRead() override; // Metadata and option build tools @@ -117,4 +120,5 @@ class RimGeoMechResultDefinition : public caf::PdmObject caf::PdmPointer m_geomCase; bool m_isChangedByField; + bool m_addWellPathDerivedResults; }; diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp index bfbfbe501b..7307e3d7c4 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechView.cpp @@ -21,6 +21,7 @@ #include "RiaApplication.h" #include "RiaPreferences.h" +#include "RiaRegressionTestRunner.h" #include "RigFemPartCollection.h" #include "RigFemPartGrid.h" @@ -122,13 +123,23 @@ void RimGeoMechView::onLoadDataAndUpdate() if (m_geomechCase) { std::string errorMessage; - if (!m_geomechCase->openGeoMechCase(&errorMessage)) + RimGeoMechCase::CaseOpenStatus status = m_geomechCase->openGeoMechCase(&errorMessage); + if (status == RimGeoMechCase::CASE_OPEN_CANCELLED) { - QString displayMessage = errorMessage.empty() ? "Could not open the Odb file: \n" + m_geomechCase->caseFileName() : QString::fromStdString(errorMessage); + m_geomechCase = nullptr; + return; + } + else if (status == RimGeoMechCase::CASE_OPEN_ERROR) + { + if (!RiaRegressionTestRunner::instance()->isRunningRegressionTests()) + { + QString displayMessage = errorMessage.empty() ? "Could not open the Odb file: \n" + m_geomechCase->caseFileName() : QString::fromStdString(errorMessage); + + QMessageBox::warning(Riu3DMainWindowTools::mainWindowWidget(), + "File open error", + displayMessage); + } - QMessageBox::warning(Riu3DMainWindowTools::mainWindowWidget(), - "File open error", - displayMessage); m_geomechCase = nullptr; return; } @@ -635,7 +646,16 @@ void RimGeoMechView::clampCurrentTimestep() //-------------------------------------------------------------------------------------------------- bool RimGeoMechView::isTimeStepDependentDataVisible() const { - return this->hasUserRequestedAnimation() && (this->cellResult()->hasResult() || this->geoMechPropertyFilterCollection()->hasActiveFilters()); + if (this->hasUserRequestedAnimation() && + (this->cellResult()->hasResult() || this->geoMechPropertyFilterCollection()->hasActiveFilters())) + { + return true; + } + if (this->hasVisibleTimeStepDependent3dWellLogCurves()) + { + return true; + } + return false; } //-------------------------------------------------------------------------------------------------- @@ -697,6 +717,11 @@ void RimGeoMechView::scheduleGeometryRegen(RivCellSetEnum geometryType) void RimGeoMechView::setOverridePropertyFilterCollection(RimGeoMechPropertyFilterCollection* pfc) { m_overridePropertyFilterCollection = pfc; + if (m_overridePropertyFilterCollection) + { + m_propertyFilterCollection->isActive = m_overridePropertyFilterCollection->isActive; + } + m_propertyFilterCollection.uiCapability()->updateConnectedEditors(); this->scheduleGeometryRegen(PROPERTY_FILTERED); this->scheduleCreateDisplayModelAndRedraw(); diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechView.h b/ApplicationCode/ProjectDataModel/RimGeoMechView.h index 7448bae1f0..e2eb099c49 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechView.h +++ b/ApplicationCode/ProjectDataModel/RimGeoMechView.h @@ -61,16 +61,16 @@ class RimGeoMechView : public RimGridView public: RimGeoMechView(void); - virtual ~RimGeoMechView(void); + ~RimGeoMechView(void) override; void setGeoMechCase(RimGeoMechCase* gmCase); RimGeoMechCase* geoMechCase(); - virtual RimCase* ownerCase() const override; + RimCase* ownerCase() const override; caf::PdmChildField cellResult; RimGeoMechResultDefinition* cellResultResultDefinition(); - virtual const RimPropertyFilterCollection* propertyFilterCollection() const override; + const RimPropertyFilterCollection* propertyFilterCollection() const override; RimGeoMechPropertyFilterCollection* geoMechPropertyFilterCollection(); const RimGeoMechPropertyFilterCollection* geoMechPropertyFilterCollection() const; @@ -78,15 +78,15 @@ class RimGeoMechView : public RimGridView bool isTimeStepDependentDataVisible() const override ; - virtual cvf::Transform* scaleTransform() override; - virtual void scheduleGeometryRegen(RivCellSetEnum geometryType) override; + cvf::Transform* scaleTransform() override; + void scheduleGeometryRegen(RivCellSetEnum geometryType) override; void updateIconStateForFilterCollections(); - virtual void axisLabels(cvf::String* xLabel, cvf::String* yLabel, cvf::String* zLabel) override; + void axisLabels(cvf::String* xLabel, cvf::String* yLabel, cvf::String* zLabel) override; - virtual bool isUsingFormationNames() const override; + bool isUsingFormationNames() const override; - virtual void calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility, int timeStep) override; + void calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility, int timeStep) override; void updateLegendTextAndRanges(RimRegularLegendConfig* legendConfig, int timeStepIndex); @@ -102,28 +102,28 @@ class RimGeoMechView : public RimGridView void convertCameraPositionFromOldProjectFiles(); protected: - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual void onLoadDataAndUpdate() override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void onLoadDataAndUpdate() override; - virtual void createPartCollectionFromSelection(cvf::Collection* parts) override; + void createPartCollectionFromSelection(cvf::Collection* parts) override; private: - virtual void createDisplayModel() override; - virtual void updateScaleTransform() override; + void createDisplayModel() override; + void updateScaleTransform() override; - virtual void clampCurrentTimestep() override; + void clampCurrentTimestep() override; - virtual void updateCurrentTimeStep() override; - virtual void updateStaticCellColors() override; + void updateCurrentTimeStep() override; + void updateStaticCellColors() override; - virtual void resetLegendsInViewer() override; + void resetLegendsInViewer() override; void updateLegends() override; void updateTensorLegendTextAndRanges(RimRegularLegendConfig* legendConfig, int timeStepIndex); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void initAfterRead() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void initAfterRead() override; caf::PdmChildField m_tensorResults; diff --git a/ApplicationCode/ProjectDataModel/RimGeometrySelectionItem.h b/ApplicationCode/ProjectDataModel/RimGeometrySelectionItem.h index 57ddd966ad..cbf41b6a2c 100644 --- a/ApplicationCode/ProjectDataModel/RimGeometrySelectionItem.h +++ b/ApplicationCode/ProjectDataModel/RimGeometrySelectionItem.h @@ -25,7 +25,7 @@ class RimGeometrySelectionItem : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimGeometrySelectionItem(); - virtual ~RimGeometrySelectionItem(); + ~RimGeometrySelectionItem() override; virtual QString geometrySelectionText() const = 0; }; diff --git a/ApplicationCode/ProjectDataModel/RimGridCollection.cpp b/ApplicationCode/ProjectDataModel/RimGridCollection.cpp index d236211695..b8643e1593 100644 --- a/ApplicationCode/ProjectDataModel/RimGridCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimGridCollection.cpp @@ -2,75 +2,529 @@ // // Copyright (C) Statoil ASA // Copyright (C) Ceetron Solutions AS -// +// // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RimGridCollection.h" +#include "RimEclipseCase.h" #include "RimGridView.h" +#include "RigMainGrid.h" + +#include "cafPdmUiTreeOrdering.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void removeGridInfo(const QString& gridName, std::vector& collection) +{ + for (size_t i = 0; i < collection.size(); i++) + { + if (collection[i]->name() == gridName) + { + collection.erase(collection.begin() + i); + return; + } + } +} + +CAF_PDM_SOURCE_INIT(RimGridInfo, "GridInfo"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGridInfo::RimGridInfo() +{ + CAF_PDM_InitObject("GridInfo", ":/draw_style_meshlines_24x24.png", "", ""); + + CAF_PDM_InitField(&m_isActive, "IsActive", true, "Show Grid Cells", "", "", ""); + CAF_PDM_InitField(&m_gridName, "GridName", QString(), "Grid Name", "", "", ""); + m_gridName.uiCapability()->setUiReadOnly(true); + + CAF_PDM_InitField(&m_eclipseGridIndex, "GridIndex", 0, "Grid Index", "", "", ""); + m_eclipseGridIndex.uiCapability()->setUiReadOnly(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimGridInfo::objectToggleField() +{ + return &m_isActive; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridInfo::setName(const QString& name) +{ + m_gridName = name; + setUiName(name); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridInfo::setEclipseGridIndex(int index) +{ + m_eclipseGridIndex = index; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridInfo::setActive(bool active) +{ + m_isActive = active; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGridInfo::isActive() const +{ + return m_isActive(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimGridInfo::name() const +{ + return m_gridName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimGridInfo::eclipseGridIndex() const +{ + return m_eclipseGridIndex(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimGridInfo::userDescriptionField() +{ + return &m_gridName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridInfo::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + RimGridView* rimView = nullptr; + this->firstAncestorOrThisOfType(rimView); + + rimView->scheduleCreateDisplayModelAndRedraw(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridInfo::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + uiOrdering.add(&m_gridName); + uiOrdering.add(&m_eclipseGridIndex); + + uiOrdering.skipRemainingFields(); +} + +CAF_PDM_SOURCE_INIT(RimGridInfoCollection, "GridInfoCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGridInfoCollection::RimGridInfoCollection() +{ + CAF_PDM_InitObject("GridInfoCollection", ":/draw_style_meshlines_24x24.png", "", ""); + + CAF_PDM_InitField(&m_isActive, "IsActive", true, "Show Grid Cells", "", "", ""); + m_isActive.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_gridInfos, "GridInfos", "Grid Infos", "", "", ""); + + m_gridInfos.uiCapability()->setUiTreeHidden(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGridInfoCollection::isActive() const +{ + return m_isActive(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridInfoCollection::addGridInfo(RimGridInfo* gridInfo) +{ + + m_gridInfos.push_back(gridInfo); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridInfoCollection::clear() +{ + m_gridInfos.deleteAllChildObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGridInfoCollection::containsGrid(const QString& gridName) const +{ + for (auto gridInfo : m_gridInfos) + { + if (gridInfo->name() == gridName) return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridInfoCollection::deleteGridInfo(const QString& gridName) +{ + for (size_t i = 0; i < m_gridInfos.size(); i++) + { + auto gridInfo = m_gridInfos[i]; + if (gridInfo->name() == gridName) + { + m_gridInfos.erase(i); + delete gridInfo; + break; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimGridInfoCollection::gridInfos() const +{ + return m_gridInfos.childObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimGridInfoCollection::objectToggleField() +{ + return &m_isActive; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridInfoCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) +{ + RimGridView* rimView = nullptr; + this->firstAncestorOrThisOfType(rimView); + + rimView->scheduleCreateDisplayModelAndRedraw(); +} CAF_PDM_SOURCE_INIT(RimGridCollection, "GridCollection"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimGridCollection::RimGridCollection() { CAF_PDM_InitObject("Grids", ":/draw_style_meshlines_24x24.png", "", ""); - CAF_PDM_InitField(&isActive, "IsActive", true, "Show Grid Cells", "", "", ""); - isActive.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&m_isActive, "IsActive", true, "Show Grid Cells", "", "", ""); + m_isActive.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_mainGrid, "MainGrid", "Main Grid", "", "", ""); + m_mainGrid = new RimGridInfo(); + m_mainGrid->setUiName("Main Grid"); + m_mainGrid->uiCapability()->setUiTreeHidden(true); + m_mainGrid->setUiIcon(QIcon(":/MainGrid16x16.png")); + + CAF_PDM_InitFieldNoDefault(&m_persistentLgrs, "PersistentLgrs", "Persistent LGRs", "", "", ""); + m_persistentLgrs = new RimGridInfoCollection(); + m_persistentLgrs->setUiName(persistentGridUiName()); + m_persistentLgrs->setUiIcon(QIcon(":/LGR16x16.png")); + + CAF_PDM_InitFieldNoDefault(&m_temporaryLgrs, "TemporaryLgrs", "Temporary LGRs", "", "", ""); + m_temporaryLgrs.xmlCapability()->disableIO(); + m_temporaryLgrs = new RimGridInfoCollection(); + m_temporaryLgrs->setUiName(temporaryGridUiName()); + m_temporaryLgrs->setUiIcon(QIcon(":/TempLGR16x16.png")); } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +RimGridCollection::~RimGridCollection() {} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- -RimGridCollection::~RimGridCollection() +const QString RimGridCollection::persistentGridUiName() { + return "LGRs"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QString RimGridCollection::temporaryGridUiName() +{ + return "Temporary LGRs"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimGridCollection::indicesToVisibleGrids() const +{ + std::vector gridIndices; + + if (!isActive()) return gridIndices; + + if (m_mainGrid()->isActive()) + { + gridIndices.push_back(m_mainGrid->eclipseGridIndex()); + } + + if (m_persistentLgrs()->isActive()) + { + for (const auto& gridInfo : m_persistentLgrs->gridInfos()) + { + if (gridInfo->isActive()) + { + gridIndices.push_back(gridInfo->eclipseGridIndex()); + } + } + } + + if (m_temporaryLgrs()->isActive()) + { + for (const auto& gridInfo : m_temporaryLgrs->gridInfos()) + { + if (gridInfo->isActive()) + { + gridIndices.push_back(gridInfo->eclipseGridIndex()); + } + } + } + return gridIndices; } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void RimGridCollection::setActive(bool active) +{ + m_isActive = active; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGridCollection::isActive() const +{ + return m_isActive; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- caf::PdmFieldHandle* RimGridCollection::objectToggleField() { - return &isActive; + return &m_isActive; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridCollection::syncFromMainEclipseGrid() +{ + auto mainGrid = this->mainEclipseGrid(); + if (mainGrid) + { + m_mainGrid->setName("Main Grid"); + m_mainGrid->setEclipseGridIndex(0); + + auto allTemporaryGrids = m_temporaryLgrs->gridInfos(); + auto allPersistentGrids = m_persistentLgrs->gridInfos(); + + size_t gridCount = mainGrid->gridCount(); + for (size_t i = 1; i < gridCount; i++) + { + auto grid = mainGrid->gridByIndex(i); + QString gridName = QString::fromStdString(grid->gridName()); + size_t gridIndex = grid->gridIndex(); + + if (grid->isTempGrid()) + { + if (m_temporaryLgrs->containsGrid(gridName)) + { + removeGridInfo(gridName, allTemporaryGrids); + } + else + { + auto gridInfo = new RimGridInfo(); + gridInfo->setName(gridName); + gridInfo->setEclipseGridIndex((int)gridIndex); + gridInfo->setUiIcon(QIcon(":/TempLGR16x16.png")); + m_temporaryLgrs->addGridInfo(gridInfo); + } + } + else + { + if (m_persistentLgrs->containsGrid(gridName)) + { + removeGridInfo(gridName, allPersistentGrids); + } + else + { + auto gridInfo = new RimGridInfo(); + gridInfo->setName(gridName); + gridInfo->setEclipseGridIndex((int)gridIndex); + gridInfo->setUiIcon(QIcon(":/LGR16x16.png")); + m_persistentLgrs->addGridInfo(gridInfo); + } + } + } + + for (const auto& grid : allPersistentGrids) + { + auto gridName = grid->name(); + m_persistentLgrs->deleteGridInfo(gridName); + } + + for (const auto& grid : allTemporaryGrids) + { + auto gridName = grid->name(); + m_temporaryLgrs->deleteGridInfo(gridName); + } + } + updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridCollection::setMainGridActive(bool active) +{ + m_mainGrid()->setActive(active); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimGridCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimGridCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { - if (changedField == &isActive) + if (changedField == &m_isActive) { RimGridView* rimView = nullptr; this->firstAncestorOrThisOfType(rimView); CVF_ASSERT(rimView); - if (rimView) rimView->showGridCells(isActive); + if (rimView) rimView->showGridCells(m_isActive); - updateUiIconFromState(isActive); + updateUiIconFromState(m_isActive); } + + RimGridView* rimView = nullptr; + this->firstAncestorOrThisOfType(rimView); + + rimView->scheduleCreateDisplayModelAndRedraw(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimGridCollection::initAfterRead() { - updateUiIconFromState(isActive); + updateUiIconFromState(m_isActive); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridCollection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + if (mainEclipseGrid()) + { + uiTreeOrdering.add(m_mainGrid()); + if (hasPersistentLgrs()) + { + uiTreeOrdering.add(m_persistentLgrs()); + } + if (hasTemporaryLgrs()) + { + uiTreeOrdering.add(m_temporaryLgrs()); + } + } + uiTreeOrdering.skipRemainingChildren(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigMainGrid* RimGridCollection::mainEclipseGrid() const +{ + RimEclipseCase* eclipseCase; + firstAncestorOrThisOfType(eclipseCase); + return eclipseCase ? eclipseCase->mainGrid() : nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGridCollection::hasPersistentLgrs() const +{ + auto mainGrid = this->mainEclipseGrid(); + if (!mainGrid) return false; + + for (size_t i = 1; i < mainGrid->gridCount(); i++) + { + const auto grid = mainGrid->gridByIndex(i); + if (!grid->isTempGrid()) return true; + } + return false; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGridCollection::hasTemporaryLgrs() const +{ + auto mainGrid = this->mainEclipseGrid(); + if (!mainGrid) return false; + + for (size_t i = 1; i < mainGrid->gridCount(); i++) + { + const auto grid = mainGrid->gridByIndex(i); + if (grid->isTempGrid()) return true; + } + return false; +} + diff --git a/ApplicationCode/ProjectDataModel/RimGridCollection.h b/ApplicationCode/ProjectDataModel/RimGridCollection.h index 4f04b0565e..273832d2f1 100644 --- a/ApplicationCode/ProjectDataModel/RimGridCollection.h +++ b/ApplicationCode/ProjectDataModel/RimGridCollection.h @@ -2,44 +2,125 @@ // // Copyright (C) Statoil ASA // Copyright (C) Ceetron Solutions AS -// +// // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" #include "cafPdmField.h" #include "cafPdmObject.h" +#include + +class RigMainGrid; + +//================================================================================================== +/// +//================================================================================================== +class RimGridInfo : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimGridInfo(); + ~RimGridInfo() {} + + void setName(const QString& name); + void setEclipseGridIndex(int index); + void setActive(bool active); + bool isActive() const; + QString name() const; + int eclipseGridIndex() const; + + caf::PdmFieldHandle* objectToggleField() override; + +protected: + caf::PdmFieldHandle* userDescriptionField() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +private: + caf::PdmField m_isActive; + caf::PdmField m_gridName; + caf::PdmField m_eclipseGridIndex; +}; + +//================================================================================================== +/// +//================================================================================================== +class RimGridInfoCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimGridInfoCollection(); + ~RimGridInfoCollection() {} + + bool isActive() const; + void addGridInfo(RimGridInfo * gridInfo); + void clear(); + bool containsGrid(const QString& gridName) const; + void deleteGridInfo(const QString& gridName); + std::vector gridInfos() const; + caf::PdmFieldHandle* objectToggleField() override; + +protected: + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + +private: + caf::PdmField m_isActive; + caf::PdmChildArrayField m_gridInfos; +}; //================================================================================================== -/// -/// +/// +/// //================================================================================================== class RimGridCollection : public caf::PdmObject { CAF_PDM_HEADER_INIT; + public: RimGridCollection(); - virtual ~RimGridCollection(); + ~RimGridCollection() override; - virtual caf::PdmFieldHandle* objectToggleField(); + void setActive(bool active); + bool isActive() const; + std::vector indicesToVisibleGrids() const; - caf::PdmField isActive; + caf::PdmFieldHandle* objectToggleField() override; + void syncFromMainEclipseGrid(); + void setMainGridActive(bool active); + + static const QString persistentGridUiName(); + static const QString temporaryGridUiName(); protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual void initAfterRead(); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void initAfterRead() override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + +private: + const RigMainGrid* mainEclipseGrid() const; + bool hasPersistentLgrs() const; + bool hasTemporaryLgrs() const; + caf::PdmField m_isActive; + caf::PdmChildField m_mainGrid; + caf::PdmChildField m_persistentLgrs; + caf::PdmChildField m_temporaryLgrs; }; diff --git a/ApplicationCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp b/ApplicationCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp index d251fee345..c78a2f7422 100644 --- a/ApplicationCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimGridTimeHistoryCurve.cpp @@ -40,7 +40,7 @@ #include "RimSummaryTimeAxisProperties.h" #include "RiuFemTimeHistoryResultAccessor.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuSelectionManager.h" #include "qwt_plot.h" diff --git a/ApplicationCode/ProjectDataModel/RimGridTimeHistoryCurve.h b/ApplicationCode/ProjectDataModel/RimGridTimeHistoryCurve.h index 39908a9bbd..3536809baf 100644 --- a/ApplicationCode/ProjectDataModel/RimGridTimeHistoryCurve.h +++ b/ApplicationCode/ProjectDataModel/RimGridTimeHistoryCurve.h @@ -48,7 +48,7 @@ class RimGridTimeHistoryCurve : public RimPlotCurve public: RimGridTimeHistoryCurve(); - virtual ~RimGridTimeHistoryCurve(); + ~RimGridTimeHistoryCurve() override; void setFromSelectionItem(const RiuSelectionItem* selectionItem); RiaDefines::PlotAxis yAxis() const; @@ -62,14 +62,14 @@ class RimGridTimeHistoryCurve : public RimPlotCurve QString caseName() const; protected: - virtual QString createCurveAutoName() override; - virtual void updateZoomInParentPlot() override; - virtual void onLoadDataAndUpdate(bool updateParentPlot) override; + QString createCurveAutoName() override; + void updateZoomInParentPlot() override; + void onLoadDataAndUpdate(bool updateParentPlot) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void initAfterRead() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void initAfterRead() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: RigMainGrid* mainGrid(); diff --git a/ApplicationCode/ProjectDataModel/RimGridView.cpp b/ApplicationCode/ProjectDataModel/RimGridView.cpp index 2353dbba16..8c301725e2 100644 --- a/ApplicationCode/ProjectDataModel/RimGridView.cpp +++ b/ApplicationCode/ProjectDataModel/RimGridView.cpp @@ -51,8 +51,7 @@ RimGridView::RimGridView() CAF_PDM_InitFieldNoDefault(&m_overrideRangeFilterCollection, "RangeFiltersControlled", "Range Filters (controlled)", "", "", ""); m_overrideRangeFilterCollection.uiCapability()->setUiHidden(true); - m_overrideRangeFilterCollection.xmlCapability()->setIOWritable(false); - m_overrideRangeFilterCollection.xmlCapability()->setIOReadable(false); + m_overrideRangeFilterCollection.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault(&m_crossSectionCollection, "CrossSections", "Intersections", "", "", ""); m_crossSectionCollection.uiCapability()->setUiHidden(true); @@ -68,6 +67,7 @@ RimGridView::RimGridView() m_overlayInfoConfig = new Rim3dOverlayInfoConfig(); m_overlayInfoConfig->setReservoirView(this); m_overlayInfoConfig.uiCapability()->setUiHidden(true); + } //-------------------------------------------------------------------------------------------------- @@ -108,8 +108,7 @@ RimGridView::~RimGridView(void) //-------------------------------------------------------------------------------------------------- void RimGridView::showGridCells(bool enableGridCells) { - - m_gridCollection->isActive = enableGridCells; + m_gridCollection->setActive(enableGridCells); createDisplayModel(); updateDisplayModelVisibility(); @@ -142,6 +141,14 @@ RimIntersectionCollection* RimGridView::crossSectionCollection() const return m_crossSectionCollection(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridView::rangeFiltersUpdated() +{ + updateViewFollowingRangeFilterUpdates(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -188,6 +195,13 @@ void RimGridView::setOverrideRangeFilterCollection(RimCellRangeFilterCollection* if (m_overrideRangeFilterCollection()) delete m_overrideRangeFilterCollection(); m_overrideRangeFilterCollection = rfc; + // Maintain a link in the active-selection + if (m_overrideRangeFilterCollection) + { + m_rangeFilterCollection->isActive = m_overrideRangeFilterCollection->isActive; + m_rangeFilterCollection()->uiCapability()->updateConnectedEditors(); + } + this->scheduleGeometryRegen(RANGE_FILTERED); this->scheduleGeometryRegen(RANGE_FILTERED_INACTIVE); @@ -221,17 +235,18 @@ void RimGridView::replaceRangeFilterCollectionWithOverride() //-------------------------------------------------------------------------------------------------- RimViewController* RimGridView::viewController() const { - RimViewController* viewController = nullptr; - std::vector reffingObjs; + std::vector objects; + this->objectsWithReferringPtrFieldsOfType(objects); - this->objectsWithReferringPtrFields(reffingObjs); - for (size_t i = 0; i < reffingObjs.size(); ++i) + for (auto v : objects) { - viewController = dynamic_cast(reffingObjs[i]); - if (viewController) break; + if (v) + { + return v; + } } - return viewController; + return nullptr; } //-------------------------------------------------------------------------------------------------- @@ -268,6 +283,14 @@ Rim3dOverlayInfoConfig* RimGridView::overlayInfoConfig() const return m_overlayInfoConfig; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimGridView::updateViewFollowingRangeFilterUpdates() +{ + showGridCells(true); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -285,7 +308,7 @@ void RimGridView::initAfterRead() bool isGridVisualizationModeBefore_2018_1_1 = ((surfaceMode() == RimGridView::SURFACE) || (meshMode() == RimGridView::FULL_MESH)); - m_gridCollection->isActive = isGridVisualizationModeBefore_2018_1_1; + m_gridCollection->setActive(isGridVisualizationModeBefore_2018_1_1); if (!isGridVisualizationModeBefore_2018_1_1) { // Was showing faults and intersections. @@ -339,6 +362,14 @@ void RimGridView::fieldChangedByUi(const caf::PdmFieldHandle* changedField, cons } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGridCollection* RimGridView::gridCollection() const +{ + return m_gridCollection(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -352,18 +383,18 @@ void RimGridView::selectOverlayInfoConfig() //-------------------------------------------------------------------------------------------------- RimViewLinker* RimGridView::viewLinkerIfMasterView() const { - RimViewLinker* viewLinker = nullptr; - std::vector reffingObjs; - - this->objectsWithReferringPtrFields(reffingObjs); + std::vector objects; + this->objectsWithReferringPtrFieldsOfType(objects); - for (size_t i = 0; i < reffingObjs.size(); ++i) + for (auto viewLinker : objects) { - viewLinker = dynamic_cast(reffingObjs[i]); - if (viewLinker) break; + if (viewLinker) + { + return viewLinker; + } } - return viewLinker; + return nullptr; } diff --git a/ApplicationCode/ProjectDataModel/RimGridView.h b/ApplicationCode/ProjectDataModel/RimGridView.h index cb4d8f2143..2befa053d0 100644 --- a/ApplicationCode/ProjectDataModel/RimGridView.h +++ b/ApplicationCode/ProjectDataModel/RimGridView.h @@ -23,6 +23,7 @@ #include "cvfBase.h" #include "cvfArray.h" +class RimContourMapProjection; class Rim3dOverlayInfoConfig; class RimIntersectionCollection; class RimPropertyFilterCollection; @@ -34,10 +35,10 @@ class RimGridView : public Rim3dView CAF_PDM_HEADER_INIT; public: RimGridView(); - virtual ~RimGridView(void); + ~RimGridView(void) override; void showGridCells(bool enableGridCells); - + Rim3dOverlayInfoConfig* overlayInfoConfig() const; cvf::ref currentTotalCellVisibility(); @@ -45,6 +46,8 @@ class RimGridView : public Rim3dView RimIntersectionCollection* crossSectionCollection() const; virtual const RimPropertyFilterCollection* propertyFilterCollection() const = 0; + + void rangeFiltersUpdated(); RimCellRangeFilterCollection* rangeFilterCollection(); const RimCellRangeFilterCollection* rangeFilterCollection() const; @@ -56,15 +59,18 @@ class RimGridView : public Rim3dView RimViewLinker* assosiatedViewLinker() const override; - virtual bool isGridVisualizationMode() const override; + bool isGridVisualizationMode() const override; protected: - virtual void initAfterRead() override; - virtual void onTimeStepChanged() override; + virtual void updateViewFollowingRangeFilterUpdates(); + void initAfterRead() override; + void onTimeStepChanged() override; virtual void calculateCurrentTotalCellVisibility(cvf::UByteArray* totalVisibility, int timeStep) = 0; - virtual void selectOverlayInfoConfig() override; + void selectOverlayInfoConfig() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + + RimGridCollection* gridCollection() const; protected: // Fields caf::PdmChildField m_crossSectionCollection; @@ -72,7 +78,6 @@ class RimGridView : public Rim3dView caf::PdmChildField m_rangeFilterCollection; caf::PdmChildField m_overrideRangeFilterCollection; caf::PdmChildField m_gridCollection; - protected: cvf::ref m_currentReservoirCellVisibility; diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp index d88876c537..df58cd91ac 100644 --- a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.cpp @@ -236,8 +236,6 @@ void RimIdenticalGridCaseGroup::loadMainCaseAndActiveCellInfo() // for all cases { - RiaDefines::PorosityModelType poroModel = RiaDefines::MATRIX_MODEL; - std::vector timeStepInfos = rigCaseData->results(poroModel)->timeStepInfos(0); const std::vector resultInfos = rigCaseData->results(poroModel)->infoForEachResultIndex(); @@ -251,15 +249,15 @@ void RimIdenticalGridCaseGroup::loadMainCaseAndActiveCellInfo() for (size_t resIdx = 0; resIdx < resultInfos.size(); resIdx++) { - RiaDefines::ResultCatType resultType = resultInfos[resIdx].m_resultType; - QString resultName = resultInfos[resIdx].m_resultName; - bool needsToBeStored = resultInfos[resIdx].m_needsToBeStored; - bool mustBeCalculated = resultInfos[resIdx].m_mustBeCalculated; + RiaDefines::ResultCatType resultType = resultInfos[resIdx].resultType(); + QString resultName = resultInfos[resIdx].resultName(); + bool needsToBeStored = resultInfos[resIdx].needsToBeStored(); + bool mustBeCalculated = resultInfos[resIdx].mustBeCalculated(); size_t scalarResultIndex = cellResultsStorage->findScalarResultIndex(resultType, resultName); if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) { - size_t scalarResultIndex = cellResultsStorage->findOrCreateScalarResultIndex(resultType, resultName, needsToBeStored); + scalarResultIndex = cellResultsStorage->findOrCreateScalarResultIndex(resultType, resultName, needsToBeStored); if (mustBeCalculated) cellResultsStorage->setMustBeCalculated(scalarResultIndex); @@ -516,25 +514,3 @@ RimEclipseCase* RimIdenticalGridCaseGroup::mainCase() } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimIdenticalGridCaseGroup::canCaseBeAdded(RimEclipseCase* reservoir) const -{ - CVF_ASSERT(reservoir && reservoir->eclipseCaseData() && reservoir->eclipseCaseData()->mainGrid()); - - if (!m_mainGrid) - { - // Empty case group, reservoir can be added - return true; - } - - RigMainGrid* incomingMainGrid = reservoir->eclipseCaseData()->mainGrid(); - - if (RigGridManager::isEqual(m_mainGrid, incomingMainGrid)) - { - return true; - } - - return false; -} diff --git a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h index 2486729a64..8f3b5e921b 100644 --- a/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h +++ b/ApplicationCode/ProjectDataModel/RimIdenticalGridCaseGroup.h @@ -47,7 +47,7 @@ class RimIdenticalGridCaseGroup : public caf::PdmObject public: RimIdenticalGridCaseGroup(); - virtual ~RimIdenticalGridCaseGroup(); + ~RimIdenticalGridCaseGroup() override; caf::PdmField name; caf::PdmField groupId; @@ -58,7 +58,6 @@ class RimIdenticalGridCaseGroup : public caf::PdmObject void removeCase(RimEclipseCase* reservoir); bool contains(RimEclipseCase* reservoir) const; - bool canCaseBeAdded(RimEclipseCase* reservoir) const; RimEclipseStatisticsCase* createAndAppendStatisticsCase(); @@ -74,7 +73,7 @@ class RimIdenticalGridCaseGroup : public caf::PdmObject static bool isStatisticsCaseCollection(RimCaseCollection* rimCaseCollection); protected: - virtual caf::PdmFieldHandle* userDescriptionField(); + caf::PdmFieldHandle* userDescriptionField() override; private: void updateMainGridAndActiveCellsForStatisticsCases(); diff --git a/ApplicationCode/ProjectDataModel/RimIntersection.cpp b/ApplicationCode/ProjectDataModel/RimIntersection.cpp index 07688ccf98..053adf58b9 100644 --- a/ApplicationCode/ProjectDataModel/RimIntersection.cpp +++ b/ApplicationCode/ProjectDataModel/RimIntersection.cpp @@ -500,6 +500,14 @@ RivIntersectionPartMgr* RimIntersection::intersectionPartMgr() return m_crossSectionPartMgr.p(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIntersection::rebuildGeometry() +{ + m_crossSectionPartMgr = nullptr; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -744,16 +752,16 @@ void RimIntersection::appendPointToPolyLine(const cvf::Vec3d& point) //-------------------------------------------------------------------------------------------------- Rim2dIntersectionView* RimIntersection::correspondingIntersectionView() { - std::vector objects; - - this->objectsWithReferringPtrFields(objects); - Rim2dIntersectionView* isectView = nullptr; - for (auto obj : objects) + std::vector objects; + this->objectsWithReferringPtrFieldsOfType(objects); + for (auto isectView : objects) { - isectView = dynamic_cast(obj); - if (isectView) break; + if (isectView) + { + return isectView; + } } - return isectView; + return nullptr; } diff --git a/ApplicationCode/ProjectDataModel/RimIntersection.h b/ApplicationCode/ProjectDataModel/RimIntersection.h index 3d30d1c1c3..d3c3bbfc61 100644 --- a/ApplicationCode/ProjectDataModel/RimIntersection.h +++ b/ApplicationCode/ProjectDataModel/RimIntersection.h @@ -68,7 +68,7 @@ class RimIntersection : public caf::PdmObject public: RimIntersection(); - ~RimIntersection(); + ~RimIntersection() override; caf::PdmField name; caf::PdmField isActive; @@ -89,6 +89,7 @@ class RimIntersection : public caf::PdmObject Rim2dIntersectionView* correspondingIntersectionView(); RivIntersectionPartMgr* intersectionPartMgr(); + void rebuildGeometry(); std::vector polyLinesForExtrusionDirection() const; void appendPointToExtrusionDirection(const cvf::Vec3d& point); @@ -105,17 +106,19 @@ class RimIntersection : public caf::PdmObject bool hasDefiningPoints() const; int branchIndex() const; + void rebuildGeometryAndScheduleCreateDisplayModel(); + protected: - virtual caf::PdmFieldHandle* userDescriptionField(); - virtual caf::PdmFieldHandle* objectToggleField(); + caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* objectToggleField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; private: @@ -140,7 +143,6 @@ class RimIntersection : public caf::PdmObject void updateWellExtentDefaultValue(); void addExtents(std::vector &polyLine) const; void updateName(); - void rebuildGeometryAndScheduleCreateDisplayModel(); static double azimuthInRadians(cvf::Vec3d vec); private: cvf::ref m_crossSectionPartMgr; diff --git a/ApplicationCode/ProjectDataModel/RimIntersectionBox.cpp b/ApplicationCode/ProjectDataModel/RimIntersectionBox.cpp index 402a717a2d..c4e5e061ac 100644 --- a/ApplicationCode/ProjectDataModel/RimIntersectionBox.cpp +++ b/ApplicationCode/ProjectDataModel/RimIntersectionBox.cpp @@ -229,6 +229,14 @@ void RimIntersectionBox::appendManipulatorPartsToModel(cvf::ModelBasicList* mode } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIntersectionBox::rebuildGeometry() +{ + m_intersectionBoxPartMgr = nullptr; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimIntersectionBox.h b/ApplicationCode/ProjectDataModel/RimIntersectionBox.h index 8971c4e5d9..e79ae8b017 100644 --- a/ApplicationCode/ProjectDataModel/RimIntersectionBox.h +++ b/ApplicationCode/ProjectDataModel/RimIntersectionBox.h @@ -58,7 +58,7 @@ class RimIntersectionBox : public QObject, public caf::PdmObject public: RimIntersectionBox(); - ~RimIntersectionBox(); + ~RimIntersectionBox() override; // Fields caf::PdmField name; @@ -70,20 +70,22 @@ class RimIntersectionBox : public QObject, public caf::PdmObject SinglePlaneState singlePlaneState() const; bool show3dManipulator() const; + RivIntersectionBoxPartMgr* intersectionBoxPartMgr(); void appendManipulatorPartsToModel(cvf::ModelBasicList* model); + void rebuildGeometry(); void setToDefaultSizeBox(); void setToDefaultSizeSlice(SinglePlaneState plane, const cvf::Vec3d& position); protected: - virtual caf::PdmFieldHandle* userDescriptionField() override; - virtual caf::PdmFieldHandle* objectToggleField() override; + caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* objectToggleField() override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void initAfterRead() override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void initAfterRead() override; protected slots: void slotScheduleRedraw(); diff --git a/ApplicationCode/ProjectDataModel/RimIntersectionCollection.cpp b/ApplicationCode/ProjectDataModel/RimIntersectionCollection.cpp index f18423d6b8..0739e526dc 100644 --- a/ApplicationCode/ProjectDataModel/RimIntersectionCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimIntersectionCollection.cpp @@ -151,6 +151,22 @@ void RimIntersectionCollection::appendPartsToModel(Rim3dView& view, cvf::ModelBa } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimIntersectionCollection::rebuildGeometry() +{ + for (RimIntersection* intersection : m_intersections) + { + intersection->rebuildGeometry(); + } + + for (RimIntersectionBox* intersectionBox : m_intersectionBoxes) + { + intersectionBox->rebuildGeometry(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -223,7 +239,10 @@ void RimIntersectionCollection::scheduleCreateDisplayModelAndRedraw2dIntersectio { for (RimIntersection* isection: m_intersections) { - isection->correspondingIntersectionView()->scheduleCreateDisplayModelAndRedraw(); + if (isection->correspondingIntersectionView()) + { + isection->correspondingIntersectionView()->scheduleCreateDisplayModelAndRedraw(); + } } } diff --git a/ApplicationCode/ProjectDataModel/RimIntersectionCollection.h b/ApplicationCode/ProjectDataModel/RimIntersectionCollection.h index 12b0fd9eac..3dcda37b09 100644 --- a/ApplicationCode/ProjectDataModel/RimIntersectionCollection.h +++ b/ApplicationCode/ProjectDataModel/RimIntersectionCollection.h @@ -47,7 +47,7 @@ class RimIntersectionCollection : public caf::PdmObject public: RimIntersectionCollection(); - ~RimIntersectionCollection(); + ~RimIntersectionCollection() override; caf::PdmField isActive; @@ -72,13 +72,14 @@ class RimIntersectionCollection : public caf::PdmObject const cvf::ScalarMapper* scalarColorMapper, const RivTernaryScalarMapper* ternaryColorMapper); void appendPartsToModel(Rim3dView& view, cvf::ModelBasicList* model, cvf::Transform* scaleTransform); + void rebuildGeometry(); std::vector intersections() const; std::vector intersectionBoxes() const; protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual caf::PdmFieldHandle* objectToggleField(); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* objectToggleField() override; private: caf::PdmChildArrayField m_intersections; diff --git a/ApplicationCode/ProjectDataModel/RimLegendConfig.h b/ApplicationCode/ProjectDataModel/RimLegendConfig.h index dacedeba67..50b6616ac2 100644 --- a/ApplicationCode/ProjectDataModel/RimLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimLegendConfig.h @@ -36,7 +36,7 @@ class RimLegendConfig : public caf::PdmObject public: RimLegendConfig(); - virtual ~RimLegendConfig(); + ~RimLegendConfig() override; enum RangeModeType { diff --git a/ApplicationCode/ProjectDataModel/RimMainPlotCollection.cpp b/ApplicationCode/ProjectDataModel/RimMainPlotCollection.cpp index d4b2b73349..8baf71ea6f 100644 --- a/ApplicationCode/ProjectDataModel/RimMainPlotCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimMainPlotCollection.cpp @@ -210,3 +210,27 @@ void RimMainPlotCollection::updatePlotsWithFormations() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMainPlotCollection::updatePlotsWithCompletions() +{ + if (m_wellLogPlotCollection) + { + for (RimWellLogPlot* wellLogPlot : m_wellLogPlotCollection->wellLogPlots()) + { + wellLogPlot->loadDataAndUpdate(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimMainPlotCollection::deleteAllCachedData() +{ + m_wellLogPlotCollection()->deleteAllExtractors(); + m_rftPlotCollection()->deleteAllExtractors(); + m_pltPlotCollection()->deleteAllExtractors(); +} + diff --git a/ApplicationCode/ProjectDataModel/RimMainPlotCollection.h b/ApplicationCode/ProjectDataModel/RimMainPlotCollection.h index c842bc03d0..95cdc674d1 100644 --- a/ApplicationCode/ProjectDataModel/RimMainPlotCollection.h +++ b/ApplicationCode/ProjectDataModel/RimMainPlotCollection.h @@ -47,7 +47,7 @@ class RimMainPlotCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimMainPlotCollection(); - virtual ~RimMainPlotCollection(); + ~RimMainPlotCollection() override; RimWellLogPlotCollection* wellLogPlotCollection(); RimRftPlotCollection* rftPlotCollection(); @@ -59,12 +59,13 @@ class RimMainPlotCollection : public caf::PdmObject void deleteAllContainedObjects(); void updateCurrentTimeStepInPlots(); void updatePlotsWithFormations(); - + void updatePlotsWithCompletions(); + void deleteAllCachedData(); private: // Overridden PDM methods - virtual caf::PdmFieldHandle* objectToggleField(); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + caf::PdmFieldHandle* objectToggleField() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: caf::PdmChildField m_wellLogPlotCollection; diff --git a/ApplicationCode/ProjectDataModel/RimMdiWindowController.h b/ApplicationCode/ProjectDataModel/RimMdiWindowController.h index 4ba4062b70..47d3a5ea9f 100644 --- a/ApplicationCode/ProjectDataModel/RimMdiWindowController.h +++ b/ApplicationCode/ProjectDataModel/RimMdiWindowController.h @@ -37,7 +37,7 @@ class RimMdiWindowController : public caf::PdmObject public: RimMdiWindowController(); - virtual ~RimMdiWindowController(); + ~RimMdiWindowController() override; void setMdiWindowGeometry(const RimMdiWindowGeometry& windowGeometry); RimMdiWindowGeometry mdiWindowGeometry(); @@ -53,7 +53,7 @@ class RimMdiWindowController : public caf::PdmObject RiuMainWindowBase* getMainWindow(); // Overridden PDM methods - virtual void setupBeforeSave() override; + void setupBeforeSave() override; private: diff --git a/ApplicationCode/ProjectDataModel/RimMimeData.h b/ApplicationCode/ProjectDataModel/RimMimeData.h index 28ad20fa7c..909931ccb0 100644 --- a/ApplicationCode/ProjectDataModel/RimMimeData.h +++ b/ApplicationCode/ProjectDataModel/RimMimeData.h @@ -38,8 +38,8 @@ class MimeDataWithIndexes : public QMimeData void setIndexes(const QModelIndexList& indexes); const QModelIndexList& indexes() const; - virtual bool hasFormat(const QString& mimetype) const; - virtual QStringList formats() const; + bool hasFormat(const QString& mimetype) const override; + QStringList formats() const override; static QString formatName(); private: @@ -62,8 +62,8 @@ class MimeDataWithReferences : public QMimeData void setReferences(const std::vector& references); const std::vector& references() const; - virtual bool hasFormat(const QString& mimetype) const; - virtual QStringList formats() const; + bool hasFormat(const QString& mimetype) const override; + QStringList formats() const override; static QString formatName(); private: diff --git a/ApplicationCode/ProjectDataModel/RimMockModelSettings.h b/ApplicationCode/ProjectDataModel/RimMockModelSettings.h index b6bc055bea..57e8cc43cf 100644 --- a/ApplicationCode/ProjectDataModel/RimMockModelSettings.h +++ b/ApplicationCode/ProjectDataModel/RimMockModelSettings.h @@ -34,7 +34,7 @@ class RimMockModelSettings : public caf::PdmObject public: RimMockModelSettings(); - virtual ~RimMockModelSettings(); + ~RimMockModelSettings() override; caf::PdmField cellCountX; caf::PdmField cellCountY; @@ -46,8 +46,8 @@ class RimMockModelSettings : public caf::PdmObject caf::PdmField timeStepCount; - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ); + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; }; diff --git a/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp b/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp new file mode 100644 index 0000000000..4096a1b59e --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimModeledWellPath.cpp @@ -0,0 +1,178 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimModeledWellPath.h" + +#include "RimWellPathGeometryDef.h" +#include "RimProject.h" + +#include "RigWellPath.h" + +#include "cafPdmUiTreeOrdering.h" +#include "RimPlotCurve.h" +#include "RiaCompletionTypeCalculationScheduler.h" +#include "RimIntersection.h" +#include "RimWellPath.h" +#include "RimWellPathFractureCollection.h" +#include "RimWellPathFracture.h" +#include "RifEclipseDataTableFormatter.h" + + +CAF_PDM_SOURCE_INIT(RimModeledWellPath, "ModeledWellPath"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimModeledWellPath::RimModeledWellPath() +{ + CAF_PDM_InitObject("Modeled WellPath", ":/EditableWell.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_geometryDefinition, "WellPathGeometryDef", "Trajectory", "", "", ""); + m_geometryDefinition = new RimWellPathGeometryDef; + + // Required, as these settings are set in RimWellPath() + m_name.uiCapability()->setUiReadOnly(false); + m_name.xmlCapability()->setIOReadable(true); + m_name.xmlCapability()->setIOWritable(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimModeledWellPath::~RimModeledWellPath() +{ + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimModeledWellPath::createWellPathGeometry() +{ + this->setWellPathGeometry(m_geometryDefinition->createWellPathGeometry().p()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimModeledWellPath::updateWellPathVisualization() +{ + this->setWellPathGeometry(m_geometryDefinition->createWellPathGeometry().p()); + + std::vector refferingCurves; + this->objectsWithReferringPtrFieldsOfType(refferingCurves); + + for (auto curve: refferingCurves) + { + curve->loadDataAndUpdate(false); + } + + for ( auto fracture : this->fractureCollection()->activeFractures() ) + { + fracture->loadDataAndUpdate(); + } + + std::vector refferingIntersections; + this->objectsWithReferringPtrFieldsOfType(refferingIntersections); + + for (auto intersection: refferingIntersections) + { + intersection->rebuildGeometryAndScheduleCreateDisplayModel(); + } + + RimProject* proj; + this->firstAncestorOrThisOfTypeAsserted(proj); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimModeledWellPath::scheduleUpdateOfDependentVisualization() +{ + + RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathGeometryDef* RimModeledWellPath::geometryDefinition() const +{ + return m_geometryDefinition; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimModeledWellPath::wellPlanText() +{ + QString planText; + QTextStream qtxtStream(&planText); + + RifEclipseDataTableFormatter formatter(qtxtStream); + formatter.setTableRowPrependText(""); + formatter.setTableRowLineAppendText(""); + + std::vector tableHeader; + tableHeader.push_back({"MDRKB"}); + tableHeader.push_back({"CL"}); + tableHeader.push_back({"Inc"}); + tableHeader.push_back({"Azi"}); + tableHeader.push_back({"TVDMSL"}); + tableHeader.push_back({"NS"}); + tableHeader.push_back({"EW"}); + tableHeader.push_back({"Dogleg"}); + tableHeader.push_back({"Build"}); + tableHeader.push_back({"Turn"}); + formatter.header(tableHeader); + + double mdrkbAtFirstTarget = m_geometryDefinition->mdrkbAtFirstTarget(); + if (m_geometryDefinition) + { + std::vector wellPlan = m_geometryDefinition->wellPlan(); + for (const auto& segment : wellPlan) + { + formatter.add(segment.MD + mdrkbAtFirstTarget); + formatter.add(segment.CL); + formatter.add(segment.inc); + formatter.add(segment.azi); + formatter.add(segment.TVD); + formatter.add(segment.NS); + formatter.add(segment.EW); + formatter.add(segment.dogleg); + formatter.add(segment.build); + formatter.add(segment.turn); + formatter.rowCompleted(); + } + } + formatter.tableCompleted(); + + return planText; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimModeledWellPath::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) +{ + uiTreeOrdering.add(m_geometryDefinition()); + RimWellPath::defineUiTreeOrdering(uiTreeOrdering, uiConfigName); +} + diff --git a/ApplicationCode/ProjectDataModel/RimModeledWellPath.h b/ApplicationCode/ProjectDataModel/RimModeledWellPath.h new file mode 100644 index 0000000000..3cb1172579 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimModeledWellPath.h @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "RimWellPath.h" + +#include "cafPdmChildField.h" + +class RimWellPathTarget; +class RimWellPath; +class RimWellPathGeometryDef; + +class RimModeledWellPath: public RimWellPath +{ + CAF_PDM_HEADER_INIT; +public: + + RimModeledWellPath(); + ~RimModeledWellPath() override; + + void createWellPathGeometry(); + void updateWellPathVisualization(); + void scheduleUpdateOfDependentVisualization(); + RimWellPathGeometryDef* geometryDefinition() const; + QString wellPlanText(); + +private: + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; + + caf::PdmChildField m_geometryDefinition; + +}; + diff --git a/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.cpp b/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.cpp index d3075e792c..309b17fb3d 100644 --- a/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2016- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -19,20 +19,23 @@ #include "RimMultiSnapshotDefinition.h" #include "RiaApplication.h" +#include "RiaOptionItemFactory.h" #include "RigActiveCellInfo.h" #include "RigCaseCellResultsData.h" #include "RigReservoirGridTools.h" +#include "Rim3dView.h" #include "RimCase.h" #include "RimEclipseView.h" #include "RimProject.h" #include "RimReservoirCellResultsStorage.h" #include "RimTools.h" -#include "Rim3dView.h" #include "cafPdmPointer.h" +// clang-format off + namespace caf { template<> @@ -74,17 +77,18 @@ RimMultiSnapshotDefinition::RimMultiSnapshotDefinition() CAF_PDM_InitFieldNoDefault(&additionalCases, "AdditionalCases", "Cases", "", "", ""); } +// clang-format on + //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimMultiSnapshotDefinition::~RimMultiSnapshotDefinition() -{ -} +RimMultiSnapshotDefinition::~RimMultiSnapshotDefinition() {} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QList RimMultiSnapshotDefinition::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +QList RimMultiSnapshotDefinition::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) { QList options; @@ -92,9 +96,9 @@ QList RimMultiSnapshotDefinition::calculateValueOptions( { options.push_back(caf::PdmOptionItemInfo("None", nullptr)); - std::vector views; + std::vector views; - RimProject* proj = RiaApplication::instance()->project(); + RimProject* proj = RiaApplication::instance()->project(); std::vector cases; proj->allCases(cases); @@ -106,16 +110,17 @@ QList RimMultiSnapshotDefinition::calculateValueOptions( } } - for (Rim3dView* view : views) + for (Rim3dView* rim3dView : views) { - QString caseAndView = view->ownerCase()->caseUserDescription() + " - " + view->name(); - options.push_back(caf::PdmOptionItemInfo(caseAndView, view)); + RiaOptionItemFactory::appendOptionItemFromViewNameAndCaseName(rim3dView, &options); } } else if (fieldNeedingOptions == &eclipseResultType) { - options.push_back(caf::PdmOptionItemInfo(caf::AppEnum(RiaDefines::DYNAMIC_NATIVE).uiText(), RiaDefines::DYNAMIC_NATIVE)); - options.push_back(caf::PdmOptionItemInfo(caf::AppEnum(RiaDefines::STATIC_NATIVE).uiText(), RiaDefines::STATIC_NATIVE)); + options.push_back(caf::PdmOptionItemInfo(caf::AppEnum(RiaDefines::DYNAMIC_NATIVE).uiText(), + RiaDefines::DYNAMIC_NATIVE)); + options.push_back(caf::PdmOptionItemInfo(caf::AppEnum(RiaDefines::STATIC_NATIVE).uiText(), + RiaDefines::STATIC_NATIVE)); } else if (fieldNeedingOptions == &selectedEclipseResults) { @@ -147,9 +152,9 @@ QList RimMultiSnapshotDefinition::calculateValueOptions( } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimMultiSnapshotDefinition::getTimeStepStrings(QList &options) +void RimMultiSnapshotDefinition::getTimeStepStrings(QList& options) { if (!view()) return; @@ -164,9 +169,11 @@ void RimMultiSnapshotDefinition::getTimeStepStrings(QListfirstAncestorOrThisOfTypeAsserted(rimCase); - + mainGrid = RigReservoirGridTools::mainGrid(rimCase); } @@ -219,23 +226,22 @@ void RimMultiSnapshotDefinition::fieldChangedByUi(const caf::PdmFieldHandle* cha maxInt = static_cast(max.z()); minInt = static_cast(min.z()); } - - startSliceIndex = minInt; - endSliceIndex = maxInt; + startSliceIndex = minInt; + endSliceIndex = maxInt; } - + startSliceIndex.uiCapability()->updateConnectedEditors(); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QList RimMultiSnapshotDefinition::toOptionList(const QStringList& varList) { QList optionList; - int i; + int i; for (i = 0; i < varList.size(); ++i) { optionList.push_back(caf::PdmOptionItemInfo(varList[i], varList[i])); @@ -244,7 +250,7 @@ QList RimMultiSnapshotDefinition::toOptionList(const QSt } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimMultiSnapshotDefinition::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { diff --git a/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.h b/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.h index cbfc10d715..0e68a7eba2 100644 --- a/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.h +++ b/ApplicationCode/ProjectDataModel/RimMultiSnapshotDefinition.h @@ -38,7 +38,7 @@ class RimMultiSnapshotDefinition : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimMultiSnapshotDefinition(); - virtual ~RimMultiSnapshotDefinition(); + ~RimMultiSnapshotDefinition() override; caf::PdmField isActive; @@ -65,14 +65,14 @@ class RimMultiSnapshotDefinition : public caf::PdmObject caf::PdmPtrArrayField additionalCases; protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; void getTimeStepStrings(QList &options); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; QList toOptionList(const QStringList& varList); }; diff --git a/ApplicationCode/ProjectDataModel/RimNameConfig.cpp b/ApplicationCode/ProjectDataModel/RimNameConfig.cpp new file mode 100644 index 0000000000..8c018a7c99 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimNameConfig.cpp @@ -0,0 +1,150 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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. +// + m_addWellName {m_fieldValue=true m_defaultFieldValue=true } caf::PdmField + +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimProject.h" +#include "RimNameConfig.h" +#include "Rim3dWellLogCurve.h" + +//================================================================================================== +/// +/// +//================================================================================================== + +CAF_PDM_SOURCE_INIT(RimNameConfig, "RimCurveNameConfig"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimNameConfig::RimNameConfig(const RimNameConfigHolderInterface* configHolder /*= nullptr*/) + : m_configHolder(configHolder) +{ + CAF_PDM_InitObject("Curve Name Generator", "", "", ""); + + CAF_PDM_InitField(&m_isUsingAutoName_OBSOLETE, "IsUsingAutoName", true, "Add Automatic Name Tags", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_customName, "CustomCurveName", "Custom Name Part", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_autoName, "AutoCurveName", "Full Curve Name", "", "", ""); + m_isUsingAutoName_OBSOLETE.xmlCapability()->setIOWritable(false); + m_autoName.registerGetMethod(this, &RimNameConfig::autoName); + m_autoName.xmlCapability()->disableIO(); + m_autoName.uiCapability()->setUiReadOnly(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimNameConfig::~RimNameConfig() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimNameConfig::customName() const +{ + return m_customName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimNameConfig::nameField() +{ + return &m_autoName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimNameConfig::name() const +{ + return m_autoName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimNameConfig::uiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + defineUiOrdering(uiConfigName, uiOrdering); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimNameConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + uiOrdering.add(&m_customName); + uiOrdering.add(&m_autoName); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimNameConfig::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + updateAllSettings(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimNameConfig::autoName() const +{ + return m_configHolder->createAutoName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimNameConfig::setCustomName(const QString& name) +{ + m_customName = name; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimNameConfig::updateAllSettings() +{ + m_autoName.uiCapability()->updateConnectedEditors(); + m_customName.uiCapability()->updateConnectedEditors(); + + RimNameConfigHolderInterface* holder; + this->firstAncestorOrThisOfTypeAsserted(holder); + holder->updateHolder(); + caf::PdmObject* pdmObject = dynamic_cast(holder); + if (pdmObject) + { + pdmObject->updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimNameConfig::initAfterRead() +{ + // Now we just switch them all individually. + if (!m_isUsingAutoName_OBSOLETE()) + { + enableAllAutoNameTags(false); + } + + updateAllSettings(); +} diff --git a/ApplicationCode/ProjectDataModel/RimNameConfig.h b/ApplicationCode/ProjectDataModel/RimNameConfig.h new file mode 100644 index 0000000000..3ffc8fb8f7 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimNameConfig.h @@ -0,0 +1,73 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmProxyValueField.h" + +//================================================================================================== +/// +/// +//================================================================================================== +class RimNameConfigHolderInterface +{ +public: + virtual QString createAutoName() const = 0; + void updateHolder() { performHolderUpdate(); } + +protected: + virtual void performHolderUpdate() {} +}; + +//================================================================================================== +/// +/// +//================================================================================================== +class RimNameConfig : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimNameConfig(const RimNameConfigHolderInterface* configHolder = nullptr); + ~RimNameConfig() override; + QString customName() const; + void setCustomName(const QString& name); + virtual void enableAllAutoNameTags(bool enable) {} + + caf::PdmFieldHandle* nameField(); + QString name() const; + void uiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); + +protected: + virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + QString autoName() const; + virtual void updateAllSettings(); + void initAfterRead() override; + +protected: + caf::PdmField m_isUsingAutoName_OBSOLETE; + caf::PdmField m_customName; + caf::PdmProxyValueField m_autoName; + + const RimNameConfigHolderInterface* m_configHolder; +}; + + diff --git a/ApplicationCode/ProjectDataModel/RimNamedObject.h b/ApplicationCode/ProjectDataModel/RimNamedObject.h index 6a8d6ed487..8f66e58cd0 100644 --- a/ApplicationCode/ProjectDataModel/RimNamedObject.h +++ b/ApplicationCode/ProjectDataModel/RimNamedObject.h @@ -32,13 +32,13 @@ class RimNamedObject : public caf::PdmObject public: RimNamedObject(void); - virtual ~RimNamedObject(void); + ~RimNamedObject(void) override; QString name() const; void setName(const QString& name); protected: - virtual caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* userDescriptionField() override; // To be used from derived objects when manipulating visibility and ui ordering caf::PdmFieldHandle* nameField(); diff --git a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.h b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.h index 0707dd66e9..b8caaab12b 100644 --- a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.h +++ b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNNC.h @@ -36,6 +36,6 @@ class RimNoCommonAreaNNC : public caf::PdmObject caf::PdmField name; - caf::PdmFieldHandle* userDescriptionField(); + caf::PdmFieldHandle* userDescriptionField() override; }; diff --git a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp index 7ab3bbdd61..b58734b28b 100644 --- a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.cpp @@ -36,8 +36,7 @@ RimNoCommonAreaNncCollection::RimNoCommonAreaNncCollection() CAF_PDM_InitFieldNoDefault(&noCommonAreaNncs, "NoCommonAreaNncs", "NoCommonAreaNncs", "", "", ""); noCommonAreaNncs.uiCapability()->setUiHidden(true); - noCommonAreaNncs.xmlCapability()->setIOReadable(false); - noCommonAreaNncs.xmlCapability()->setIOWritable(false); + noCommonAreaNncs.xmlCapability()->disableIO(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h index c52c9ae00f..8c41e21645 100644 --- a/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h +++ b/ApplicationCode/ProjectDataModel/RimNoCommonAreaNncCollection.h @@ -35,11 +35,11 @@ class RimNoCommonAreaNncCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimNoCommonAreaNncCollection(); - virtual ~RimNoCommonAreaNncCollection(); + ~RimNoCommonAreaNncCollection() override; void updateName(); - virtual caf::PdmFieldHandle* userDescriptionField(); + caf::PdmFieldHandle* userDescriptionField() override; caf::PdmField name; caf::PdmChildArrayField noCommonAreaNncs; diff --git a/ApplicationCode/ProjectDataModel/RimOilField.h b/ApplicationCode/ProjectDataModel/RimOilField.h index af49ecd388..2e180c5848 100644 --- a/ApplicationCode/ProjectDataModel/RimOilField.h +++ b/ApplicationCode/ProjectDataModel/RimOilField.h @@ -44,7 +44,7 @@ class RimOilField : public caf::PdmObject public: RimOilField(void); - virtual ~RimOilField(void); + ~RimOilField(void) override; QString uniqueShortNameForCase(RimSummaryCase* summaryCase); diff --git a/ApplicationCode/ProjectDataModel/RimPlotCurve.cpp b/ApplicationCode/ProjectDataModel/RimPlotCurve.cpp index b1a8f070ee..5c64efa587 100644 --- a/ApplicationCode/ProjectDataModel/RimPlotCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimPlotCurve.cpp @@ -20,11 +20,14 @@ #include "RimEnsembleCurveSet.h" #include "RimEnsembleCurveSetCollection.h" +#include "RimNameConfig.h" +#include "RimSummaryCrossPlot.h" #include "RimSummaryCurve.h" #include "RimSummaryCurveCollection.h" #include "RimSummaryCurveFilter.h" #include "RimSummaryPlot.h" +#include "RiuPlotMainWindowTools.h" #include "RiuRimQwtPlotCurve.h" #include "cafPdmUiComboBoxEditor.h" @@ -40,40 +43,41 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimPlotCurve, "PlotCurve"); namespace caf { template<> -void caf::AppEnum< RimPlotCurve::LineStyleEnum >::setUp() +void RimPlotCurve::CurveInterpolation::setUp() { - addItem(RimPlotCurve::STYLE_NONE, "STYLE_NONE", "None"); - addItem(RimPlotCurve::STYLE_SOLID, "STYLE_SOLID", "Solid"); - addItem(RimPlotCurve::STYLE_DASH, "STYLE_DASH", "Dashes"); - addItem(RimPlotCurve::STYLE_DOT, "STYLE_DOT", "Dots"); - addItem(RimPlotCurve::STYLE_DASH_DOT, "STYLE_DASH_DOT", "Dashes and Dots"); + addItem(RiuQwtPlotCurve::INTERPOLATION_POINT_TO_POINT, "INTERPOLATION_POINT_TO_POINT", "Point to Point"); + addItem(RiuQwtPlotCurve::INTERPOLATION_STEP_LEFT, "INTERPOLATION_STEP_LEFT", "Step Left"); - setDefault(RimPlotCurve::STYLE_SOLID); + setDefault(RiuQwtPlotCurve::INTERPOLATION_POINT_TO_POINT); } - template<> -void caf::AppEnum< RimPlotCurve::PointSymbolEnum >::setUp() +void RimPlotCurve::LineStyle::setUp() { - addItem(RimPlotCurve::SYMBOL_NONE, "SYMBOL_NONE", "None"); - addItem(RimPlotCurve::SYMBOL_ELLIPSE, "SYMBOL_ELLIPSE", "Ellipse"); - addItem(RimPlotCurve::SYMBOL_RECT, "SYMBOL_RECT", "Rect"); - addItem(RimPlotCurve::SYMBOL_DIAMOND, "SYMBOL_DIAMOND", "Diamond"); - addItem(RimPlotCurve::SYMBOL_TRIANGLE, "SYMBOL_TRIANGLE", "Triangle"); - addItem(RimPlotCurve::SYMBOL_CROSS, "SYMBOL_CROSS", "Cross"); - addItem(RimPlotCurve::SYMBOL_XCROSS, "SYMBOL_XCROSS", "X Cross"); + addItem(RiuQwtPlotCurve::STYLE_NONE, "STYLE_NONE", "None"); + addItem(RiuQwtPlotCurve::STYLE_SOLID, "STYLE_SOLID", "Solid"); + addItem(RiuQwtPlotCurve::STYLE_DASH, "STYLE_DASH", "Dashes"); + addItem(RiuQwtPlotCurve::STYLE_DOT, "STYLE_DOT", "Dots"); + addItem(RiuQwtPlotCurve::STYLE_DASH_DOT, "STYLE_DASH_DOT", "Dashes and Dots"); - setDefault(RimPlotCurve::SYMBOL_NONE); + setDefault(RiuQwtPlotCurve::STYLE_SOLID); } + template<> -void RimPlotCurve::CurveInterpolation::setUp() +void RimPlotCurve::PointSymbol::setUp() { - addItem(RimPlotCurve::INTERPOLATION_POINT_TO_POINT, "INTERPOLATION_POINT_TO_POINT", "Point to Point"); - addItem(RimPlotCurve::INTERPOLATION_STEP_LEFT, "INTERPOLATION_STEP_LEFT", "Step Left"); + addItem(RiuQwtSymbol::SYMBOL_NONE, "SYMBOL_NONE", "None"); + addItem(RiuQwtSymbol::SYMBOL_ELLIPSE, "SYMBOL_ELLIPSE", "Ellipse"); + addItem(RiuQwtSymbol::SYMBOL_RECT, "SYMBOL_RECT", "Rect"); + addItem(RiuQwtSymbol::SYMBOL_DIAMOND, "SYMBOL_DIAMOND", "Diamond"); + addItem(RiuQwtSymbol::SYMBOL_TRIANGLE, "SYMBOL_TRIANGLE", "Triangle"); + addItem(RiuQwtSymbol::SYMBOL_CROSS, "SYMBOL_CROSS", "Cross"); + addItem(RiuQwtSymbol::SYMBOL_XCROSS, "SYMBOL_XCROSS", "X Cross"); - setDefault(RimPlotCurve::INTERPOLATION_POINT_TO_POINT); + setDefault(RiuQwtSymbol::SYMBOL_NONE); } + } @@ -81,6 +85,7 @@ void RimPlotCurve::CurveInterpolation::setUp() /// //-------------------------------------------------------------------------------------------------- RimPlotCurve::RimPlotCurve() + : m_symbolLabelPosition(RiuQwtSymbol::LabelAboveSymbol) { CAF_PDM_InitObject("Curve", ":/WellLogCurve16x16.png", "", ""); @@ -98,18 +103,18 @@ RimPlotCurve::RimPlotCurve() CAF_PDM_InitField(&m_curveThickness, "Thickness", 1, "Line Thickness", "", "", ""); m_curveThickness.uiCapability()->setUiEditorTypeName(caf::PdmUiComboBoxEditor::uiEditorTypeName()); - caf::AppEnum< RimPlotCurve::LineStyleEnum > lineStyle = STYLE_SOLID; - CAF_PDM_InitField(&m_lineStyle, "LineStyle", lineStyle, "Line Style", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_curveInterpolation, "CurveInterpolation", "Interpolation", "", "", ""); - - caf::AppEnum< RimPlotCurve::PointSymbolEnum > pointSymbol = SYMBOL_NONE; - CAF_PDM_InitField(&m_pointSymbol, "PointSymbol", pointSymbol, "Symbol", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_lineStyle, "LineStyle", "Line Style", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_pointSymbol, "PointSymbol", "Symbol", "", "", ""); CAF_PDM_InitField(&m_symbolSkipPixelDistance, "SymbolSkipPxDist", 0.0f, "Symbol Skip Distance", "", "Minimum pixel distance between symbols", ""); CAF_PDM_InitField(&m_showLegend, "ShowLegend", true, "Contribute To Legend", "", "", ""); + CAF_PDM_InitField(&m_symbolSize, "SymbolSize", 6, "Symbol Size", "", "", ""); + + CAF_PDM_InitField(&m_showErrorBars, "ShowErrorBars", true, "Show Error Bars", "", "", ""); + m_qwtPlotCurve = new RiuRimQwtPlotCurve(this); m_parentQwtPlot = nullptr; @@ -146,16 +151,28 @@ void RimPlotCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, con else if (changedField == &m_curveName) { m_customCurveName = m_curveName; - updateCurveNameAndUpdatePlotLegend(); + updateCurveNameAndUpdatePlotLegendAndTitle(); } else if (&m_curveColor == changedField || &m_curveThickness == changedField || &m_pointSymbol == changedField || &m_lineStyle == changedField || &m_symbolSkipPixelDistance == changedField - || &m_curveInterpolation == changedField) + || &m_curveInterpolation == changedField + || &m_symbolSize == changedField) { updateCurveAppearance(); + + if (&m_pointSymbol == changedField) + { + m_symbolSize.uiCapability()->setUiReadOnly(m_pointSymbol() == RiuQwtSymbol::SYMBOL_NONE); + m_symbolSkipPixelDistance.uiCapability()->setUiReadOnly(m_pointSymbol() == RiuQwtSymbol::SYMBOL_NONE); + } + else if (&m_lineStyle == changedField) + { + m_curveThickness.uiCapability()->setUiReadOnly(m_lineStyle() == RiuQwtPlotCurve::STYLE_NONE); + m_curveInterpolation.uiCapability()->setUiReadOnly(m_lineStyle() == RiuQwtPlotCurve::STYLE_NONE); + } } else if (changedField == &m_isUsingAutoName) { @@ -164,13 +181,18 @@ void RimPlotCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, con m_customCurveName = createCurveAutoName(); } - updateCurveNameAndUpdatePlotLegend(); + updateCurveNameAndUpdatePlotLegendAndTitle(); } else if (changedField == &m_showLegend) { updateLegendEntryVisibilityAndPlotLegend(); } - + else if (changedField == &m_showErrorBars) + { + m_qwtPlotCurve->showErrorBars(m_showErrorBars); + updateCurveAppearance(); + } + RiuPlotMainWindowTools::refreshToolbars(); if (m_parentQwtPlot) m_parentQwtPlot->replot(); } @@ -182,6 +204,15 @@ caf::PdmFieldHandle* RimPlotCurve::objectToggleField() return &m_showCurve; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotCurve::setCustomName(const QString& customName) +{ + m_isUsingAutoName = false; + m_customCurveName = customName; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -214,16 +245,28 @@ void RimPlotCurve::updateCurveVisibility(bool updateParentPlot) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotCurve::initAfterRead() +{ + m_symbolSize.uiCapability()->setUiReadOnly(m_pointSymbol() == RiuQwtSymbol::SYMBOL_NONE); + m_symbolSkipPixelDistance.uiCapability()->setUiReadOnly(m_pointSymbol() == RiuQwtSymbol::SYMBOL_NONE); + m_curveThickness.uiCapability()->setUiReadOnly(m_lineStyle() == RiuQwtPlotCurve::STYLE_NONE); + m_curveInterpolation.uiCapability()->setUiReadOnly(m_lineStyle() == RiuQwtPlotCurve::STYLE_NONE); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimPlotCurve::updateCurvePresentation(bool updatePlotLegend) +void RimPlotCurve::updateCurvePresentation(bool updatePlotLegendAndTitle) { - this->updateCurveVisibility(updatePlotLegend); + this->updateCurveVisibility(updatePlotLegendAndTitle); - if (updatePlotLegend) + if (updatePlotLegendAndTitle) { - this->updateCurveNameAndUpdatePlotLegend(); + this->updateCurveNameAndUpdatePlotLegendAndTitle(); + this->updatePlotTitle(); } else { @@ -282,6 +325,18 @@ void RimPlotCurve::detachQwtCurve() m_qwtPlotCurve->detach(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotCurve::reattachQwtCurve() +{ + detachQwtCurve(); + if (m_parentQwtPlot && m_showCurve) + { + m_qwtPlotCurve->attach(m_parentQwtPlot); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -309,7 +364,7 @@ void RimPlotCurve::setCurveVisiblity(bool visible) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimPlotCurve::updateCurveNameAndUpdatePlotLegend() +void RimPlotCurve::updateCurveNameAndUpdatePlotLegendAndTitle() { if (m_isUsingAutoName) { @@ -351,6 +406,30 @@ void RimPlotCurve::updateOptionSensitivity() } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotCurve::updatePlotTitle() +{ + RimNameConfigHolderInterface* nameConfigHolder = nullptr; + this->firstAncestorOrThisOfType(nameConfigHolder); + if (nameConfigHolder) + { + nameConfigHolder->updateHolder(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotCurve::updateLegendsInPlot() +{ + if (m_parentQwtPlot != nullptr) + { + m_parentQwtPlot->updateLegend(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -358,10 +437,12 @@ void RimPlotCurve::appearanceUiOrdering(caf::PdmUiOrdering& uiOrdering) { uiOrdering.add(&m_curveColor); uiOrdering.add(&m_pointSymbol); + uiOrdering.add(&m_symbolSize); uiOrdering.add(&m_symbolSkipPixelDistance); - uiOrdering.add(&m_curveThickness); uiOrdering.add(&m_lineStyle); + uiOrdering.add(&m_curveThickness); uiOrdering.add(&m_curveInterpolation); + } //-------------------------------------------------------------------------------------------------- @@ -384,86 +465,47 @@ void RimPlotCurve::updateCurveAppearance() QwtSymbol* symbol = nullptr; - if (m_pointSymbol() != SYMBOL_NONE) + if (m_pointSymbol() != RiuQwtSymbol::SYMBOL_NONE) { - QwtSymbol::Style style = QwtSymbol::NoSymbol; - - switch (m_pointSymbol()) - { - case SYMBOL_ELLIPSE: - style = QwtSymbol::Ellipse; - break; - case SYMBOL_RECT: - style = QwtSymbol::Rect; - break; - case SYMBOL_DIAMOND: - style = QwtSymbol::Diamond; - break; - case SYMBOL_TRIANGLE: - style = QwtSymbol::Triangle; - break; - case SYMBOL_CROSS: - style = QwtSymbol::Cross; - break; - case SYMBOL_XCROSS: - style = QwtSymbol::XCross; - break; - - default: - break; - } - // QwtPlotCurve will take ownership of the symbol - symbol = new QwtSymbol(style); - - symbol->setSize(6, 6); + symbol = new RiuQwtSymbol(m_pointSymbol(), m_symbolLabel, m_symbolLabelPosition); + symbol->setSize(m_symbolSize, m_symbolSize); symbol->setColor(curveColor); } - QwtPlotCurve::CurveStyle curveStyle = QwtPlotCurve::NoCurve; - Qt::PenStyle penStyle = Qt::SolidLine; + m_qwtPlotCurve->setAppearance(m_lineStyle(), m_curveInterpolation(), m_curveThickness(), curveColor); + m_qwtPlotCurve->setSymbol(symbol); + m_qwtPlotCurve->setSymbolSkipPixelDistance(m_symbolSkipPixelDistance()); - if (m_lineStyle() != STYLE_NONE) - { - switch (m_curveInterpolation()) - { - case INTERPOLATION_STEP_LEFT: - curveStyle = QwtPlotCurve::Steps; - m_qwtPlotCurve->setCurveAttribute(QwtPlotCurve::Inverted, false); - break; - case INTERPOLATION_POINT_TO_POINT: // Fall through - default: - curveStyle = QwtPlotCurve::Lines; - break; - } + m_qwtPlotCurve->setErrorBarsColor(curveColor); - switch (m_lineStyle()) - { - case STYLE_SOLID: - penStyle = Qt::SolidLine; - break; - case STYLE_DASH: - penStyle = Qt::DashLine; - break; - case STYLE_DOT: - penStyle = Qt::DotLine; - break; - case STYLE_DASH_DOT: - penStyle = Qt::DashDotLine; - break; - - default: - break; - } + // Make sure the legend lines are long enough to distinguish between line types. + // Standard width in Qwt is 8 which is too short. + // Use 10 and scale this by curve thickness + add space for displaying symbol. + QSize legendIconSize = m_qwtPlotCurve->legendIconSize(); + + int symbolWidth = 0; + if (symbol) + { + symbolWidth = symbol->boundingRect().size().width() + 2; } - QPen curvePen(curveColor); - curvePen.setWidth(m_curveThickness); - curvePen.setStyle(penStyle); - m_qwtPlotCurve->setPen(curvePen); - m_qwtPlotCurve->setStyle(curveStyle); - m_qwtPlotCurve->setSymbol(symbol); - m_qwtPlotCurve->setSymbolSkipPixelDistance(m_symbolSkipPixelDistance()); + int width = std::max(10 * m_curveThickness, (symbolWidth * 3) / 2); + + legendIconSize.setWidth(width); + m_qwtPlotCurve->setLegendIconSize(legendIconSize); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimPlotCurve::isCrossPlotCurve() const +{ + RimSummaryCrossPlot* crossPlot = nullptr; + this->firstAncestorOrThisOfType(crossPlot); + if (crossPlot) return true; + + return false; } //-------------------------------------------------------------------------------------------------- @@ -492,10 +534,48 @@ void RimPlotCurve::loadDataAndUpdate(bool updateParentPlot) this->onLoadDataAndUpdate(updateParentPlot); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimPlotCurve::xValueRange(double* minimumValue, double* maximumValue) const +{ + CVF_ASSERT(minimumValue && maximumValue); + CVF_ASSERT(m_qwtPlotCurve); + + if (m_qwtPlotCurve->data()->size() < 1) + { + return false; + } + + *minimumValue = m_qwtPlotCurve->minXValue(); + *maximumValue = m_qwtPlotCurve->maxXValue(); + + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimPlotCurve::yValueRange(double* minimumValue, double* maximumValue) const +{ + CVF_ASSERT(minimumValue && maximumValue); + CVF_ASSERT(m_qwtPlotCurve); + + if (m_qwtPlotCurve->data()->size() < 1) + { + return false; + } + + *minimumValue = m_qwtPlotCurve->minYValue(); + *maximumValue = m_qwtPlotCurve->maxYValue(); + + return true; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimPlotCurve::setLineStyle(LineStyleEnum lineStyle) +void RimPlotCurve::setLineStyle(RiuQwtPlotCurve::LineStyleEnum lineStyle) { m_lineStyle = lineStyle; } @@ -503,7 +583,7 @@ void RimPlotCurve::setLineStyle(LineStyleEnum lineStyle) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimPlotCurve::setSymbol(PointSymbolEnum symbolStyle) +void RimPlotCurve::setSymbol(RiuQwtSymbol::PointSymbolEnum symbolStyle) { m_pointSymbol = symbolStyle; } @@ -511,7 +591,7 @@ void RimPlotCurve::setSymbol(PointSymbolEnum symbolStyle) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimPlotCurve::PointSymbolEnum RimPlotCurve::symbol() +RiuQwtSymbol::PointSymbolEnum RimPlotCurve::symbol() { return m_pointSymbol(); } @@ -519,11 +599,27 @@ RimPlotCurve::PointSymbolEnum RimPlotCurve::symbol() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimPlotCurve::setSymbolSkipDinstance(float distance) +void RimPlotCurve::setSymbolSkipDistance(float distance) { m_symbolSkipPixelDistance = distance; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotCurve::setSymbolLabel(const QString& label) +{ + m_symbolLabel = label; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPlotCurve::setSymbolSize(int sizeInPixels) +{ + m_symbolSize = sizeInPixels; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -539,9 +635,9 @@ void RimPlotCurve::resetAppearance() { setColor(cvf::Color3f(cvf::Color3::BLACK)); setLineThickness(2); - setLineStyle(STYLE_SOLID); - setSymbol(SYMBOL_NONE); - setSymbolSkipDinstance(10); + setLineStyle(RiuQwtPlotCurve::STYLE_SOLID); + setSymbol(RiuQwtSymbol::SYMBOL_NONE); + setSymbolSkipDistance(10); } //-------------------------------------------------------------------------------------------------- @@ -570,11 +666,7 @@ void RimPlotCurve::setZOrder(double z) void RimPlotCurve::updateLegendEntryVisibilityAndPlotLegend() { updateLegendEntryVisibilityNoPlotUpdate(); - - if (m_parentQwtPlot != nullptr) - { - m_parentQwtPlot->updateLegend(); - } + updateLegendsInPlot(); } //-------------------------------------------------------------------------------------------------- @@ -592,16 +684,15 @@ void RimPlotCurve::updateLegendEntryVisibilityNoPlotUpdate() RimSummaryPlot* summaryPlot = nullptr; this->firstAncestorOrThisOfType(summaryPlot); + bool showLegendInQwt = m_showLegend(); if (summaryPlot) { - bool showLegendInQwt = m_showLegend(); if (summaryPlot->ensembleCurveSetCollection()->curveSets().empty() && summaryPlot->curveCount() == 1) { // Disable display of legend if the summary plot has only one single curve showLegendInQwt = false; } - - m_qwtPlotCurve->setItemAttribute(QwtPlotItem::Legend, showLegendInQwt); } + m_qwtPlotCurve->setItemAttribute(QwtPlotItem::Legend, showLegendInQwt); } diff --git a/ApplicationCode/ProjectDataModel/RimPlotCurve.h b/ApplicationCode/ProjectDataModel/RimPlotCurve.h index 9ece407b89..8150d873b1 100644 --- a/ApplicationCode/ProjectDataModel/RimPlotCurve.h +++ b/ApplicationCode/ProjectDataModel/RimPlotCurve.h @@ -17,14 +17,16 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once +#include "RifEclipseSummaryAddress.h" +#include "RiuQwtSymbol.h" +#include "RiuQwtPlotCurve.h" + #include "cafPdmField.h" #include "cafPdmFieldCvfColor.h" #include "cafPdmObject.h" #include -class RiuLineSegmentQwtPlotCurve; - class QwtPlot; class QwtPlotCurve; @@ -36,62 +38,45 @@ class RimPlotCurve : public caf::PdmObject { CAF_PDM_HEADER_INIT; public: - enum LineStyleEnum - { - STYLE_NONE, - STYLE_SOLID, - STYLE_DASH, - STYLE_DOT, - STYLE_DASH_DOT - }; - - enum PointSymbolEnum - { - SYMBOL_NONE, - SYMBOL_ELLIPSE, - SYMBOL_RECT, - SYMBOL_DIAMOND, - SYMBOL_TRIANGLE, - SYMBOL_CROSS, - SYMBOL_XCROSS - }; - - enum CurveInterpolationEnum - { - INTERPOLATION_POINT_TO_POINT, - INTERPOLATION_STEP_LEFT, - }; - - typedef caf::AppEnum CurveInterpolation; + typedef caf::AppEnum CurveInterpolation; + typedef caf::AppEnum LineStyle; + typedef caf::AppEnum PointSymbol; public: RimPlotCurve(); - virtual ~RimPlotCurve(); + ~RimPlotCurve() override; void loadDataAndUpdate(bool updateParentPlot); + virtual bool xValueRange(double* minimumValue, double* maximumValue) const; + virtual bool yValueRange(double* minimumValue, double* maximumValue) const; + void setParentQwtPlotAndReplot(QwtPlot* plot); void setParentQwtPlotNoReplot(QwtPlot* plot); void detachQwtCurve(); + void reattachQwtCurve(); QwtPlotCurve* qwtPlotCurve() const; void setColor(const cvf::Color3f& color); cvf::Color3f color() const { return m_curveColor; } - void setLineStyle(LineStyleEnum lineStyle); - void setSymbol(PointSymbolEnum symbolStyle); - PointSymbolEnum symbol(); - void setSymbolSkipDinstance(float distance); + void setLineStyle(RiuQwtPlotCurve::LineStyleEnum lineStyle); + void setSymbol(RiuQwtSymbol::PointSymbolEnum symbolStyle); + RiuQwtSymbol::PointSymbolEnum symbol(); + void setSymbolSkipDistance(float distance); + void setSymbolLabel(const QString& label); + void setSymbolSize(int sizeInPixels); void setLineThickness(int thickness); void resetAppearance(); bool isCurveVisible() const; void setCurveVisiblity(bool visible); - void updateCurveNameAndUpdatePlotLegend(); + void updateCurveNameAndUpdatePlotLegendAndTitle(); void updateCurveNameNoLegendUpdate(); QString curveName() const { return m_curveName; } - + virtual QString curveExportDescription(const RifEclipseSummaryAddress& address = RifEclipseSummaryAddress()) const { return m_curveName; } + void setCustomName(const QString& customName); void updateCurveVisibility(bool updateParentPlot); void updateLegendEntryVisibilityAndPlotLegend(); void updateLegendEntryVisibilityNoPlotUpdate(); @@ -101,45 +86,50 @@ class RimPlotCurve : public caf::PdmObject void setZOrder(double z); virtual void updateCurveAppearance(); + bool isCrossPlotCurve() const; protected: virtual QString createCurveAutoName() = 0; virtual void updateZoomInParentPlot() = 0; virtual void onLoadDataAndUpdate(bool updateParentPlot) = 0; - - void updateCurvePresentation(bool updatePlotLegend); + void initAfterRead() override; + void updateCurvePresentation(bool updatePlotLegendAndTitle); void updateOptionSensitivity(); - + void updatePlotTitle(); + virtual void updateLegendsInPlot(); protected: // Overridden PDM methods - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual caf::PdmFieldHandle* objectToggleField(); - virtual caf::PdmFieldHandle* userDescriptionField(); - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* objectToggleField() override; + caf::PdmFieldHandle* userDescriptionField() override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; void appearanceUiOrdering(caf::PdmUiOrdering& uiOrdering); void curveNameUiOrdering(caf::PdmUiOrdering& uiOrdering); protected: - QPointer m_parentQwtPlot; - RiuLineSegmentQwtPlotCurve* m_qwtPlotCurve; - - caf::PdmField m_showCurve; - caf::PdmField m_curveName; - caf::PdmField m_customCurveName; - caf::PdmField m_showLegend; - - caf::PdmField m_isUsingAutoName; - caf::PdmField m_curveColor; - caf::PdmField m_curveThickness; - caf::PdmField m_symbolSkipPixelDistance; - - - caf::PdmField< caf::AppEnum< PointSymbolEnum > > m_pointSymbol; - caf::PdmField< caf::AppEnum< LineStyleEnum > > m_lineStyle; - caf::PdmField< CurveInterpolation > m_curveInterpolation; + QPointer m_parentQwtPlot; + RiuQwtPlotCurve* m_qwtPlotCurve; + + caf::PdmField m_showCurve; + caf::PdmField m_curveName; + caf::PdmField m_customCurveName; + caf::PdmField m_showLegend; + QString m_symbolLabel; + caf::PdmField m_symbolSize; + + caf::PdmField m_isUsingAutoName; + caf::PdmField m_curveColor; + caf::PdmField m_curveThickness; + caf::PdmField m_symbolSkipPixelDistance; + caf::PdmField m_showErrorBars; + + caf::PdmField m_pointSymbol; + caf::PdmField m_lineStyle; + caf::PdmField m_curveInterpolation; + RiuQwtSymbol::LabelPosition m_symbolLabelPosition; }; diff --git a/ApplicationCode/ProjectDataModel/RimPltPlotCollection.cpp b/ApplicationCode/ProjectDataModel/RimPltPlotCollection.cpp index 044af69106..05a6083d7e 100644 --- a/ApplicationCode/ProjectDataModel/RimPltPlotCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimPltPlotCollection.cpp @@ -185,6 +185,15 @@ void RimPltPlotCollection::removeExtractors(const RigGeoMechCaseData* caseData) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimPltPlotCollection::deleteAllExtractors() +{ + m_extractors.clear(); + m_geomExtractors.clear(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimPltPlotCollection.h b/ApplicationCode/ProjectDataModel/RimPltPlotCollection.h index eefc9e4148..544cba00b8 100644 --- a/ApplicationCode/ProjectDataModel/RimPltPlotCollection.h +++ b/ApplicationCode/ProjectDataModel/RimPltPlotCollection.h @@ -45,7 +45,7 @@ class RimPltPlotCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimPltPlotCollection(); - virtual ~RimPltPlotCollection(); + ~RimPltPlotCollection() override; RigEclipseWellLogExtractor* findOrCreateSimWellExtractor(const QString& simWellName, const QString& caseUserDescription, @@ -58,6 +58,7 @@ class RimPltPlotCollection : public caf::PdmObject void removeExtractors(const RigWellPath* wellPath); void removeExtractors(const RigEclipseCaseData* caseData); void removeExtractors(const RigGeoMechCaseData* caseData); + void deleteAllExtractors(); const std::vector pltPlots() const; void addPlot(RimWellPltPlot* newPlot); diff --git a/ApplicationCode/ProjectDataModel/RimProject.cpp b/ApplicationCode/ProjectDataModel/RimProject.cpp index 76b8eb90a4..2ee8bdccd9 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.cpp +++ b/ApplicationCode/ProjectDataModel/RimProject.cpp @@ -21,9 +21,11 @@ #include "RimProject.h" #include "RiaApplication.h" +#include "RiaCompletionTypeCalculationScheduler.h" +#include "RiaFieldHandleTools.h" +#include "RiaFilePathTools.h" #include "RiaProjectFileVersionTools.h" #include "RiaVersionInfo.h" -#include "RiaFilePathTools.h" #include "RigEclipseCaseData.h" #include "RigGridBase.h" @@ -78,7 +80,6 @@ #include #include -#include "RiaCompletionTypeCalculationScheduler.h" CAF_PDM_SOURCE_INIT(RimProject, "ResInsightProject"); @@ -145,11 +146,10 @@ RimProject::RimProject(void) // Obsolete fields. The content is moved to OilFields and friends CAF_PDM_InitFieldNoDefault(&casesObsolete, "Reservoirs", "", "", "", ""); - casesObsolete.uiCapability()->setUiHidden(true); - casesObsolete.xmlCapability()->setIOWritable(false); // read but not write, they will be moved into RimAnalysisGroups + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&casesObsolete); + CAF_PDM_InitFieldNoDefault(&caseGroupsObsolete, "CaseGroups", "", "", "", ""); - caseGroupsObsolete.uiCapability()->setUiHidden(true); - caseGroupsObsolete.xmlCapability()->setIOWritable(false); // read but not write, they will be moved into RimAnalysisGroups + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&caseGroupsObsolete); // Initialization @@ -201,6 +201,8 @@ void RimProject::close() multiSnapshotDefinitions.deleteAllChildObjects(); + m_dialogData->clearProjectSpecificData(); + calculationCollection->deleteAllContainedObjects(); delete viewLinkerCollection->viewLinker(); @@ -426,14 +428,14 @@ bool RimProject::isProjectFileVersionEqualOrOlderThan(const QString& otherProjec //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimProject::setProjectFileNameAndUpdateDependencies(const QString& fileName) +void RimProject::setProjectFileNameAndUpdateDependencies(const QString& projectFileName) { // Extract the filename of the project file when it was saved QString oldProjectFileName = this->fileName; // Replace with the new actual filename - this->fileName = fileName; + this->fileName = projectFileName; - QFileInfo fileInfo(fileName); + QFileInfo fileInfo(projectFileName); QString newProjectPath = fileInfo.path(); QFileInfo fileInfoOld(oldProjectFileName); @@ -527,7 +529,7 @@ void RimProject::assignIdToCaseGroup(RimIdenticalGridCaseGroup* caseGroup) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimProject::allCases(std::vector& cases) +void RimProject::allCases(std::vector& cases) const { for (size_t oilFieldIdx = 0; oilFieldIdx < oilFields().size(); oilFieldIdx++) { @@ -624,6 +626,15 @@ std::vector RimProject::summaryGroups() const return groups; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSummaryCaseMainCollection* RimProject::firstSummaryCaseMainCollection() const +{ + if (oilFields.empty()) return nullptr; + return oilFields[0]->summaryCaseMainCollection; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -707,7 +718,7 @@ void RimProject::allVisibleGridViews(std::vector& views) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimProject::createDisplayModelAndRedrawAllViews() +void RimProject::scheduleCreateDisplayModelAndRedrawAllViews() { std::vector cases; allCases(cases); @@ -727,12 +738,12 @@ void RimProject::createDisplayModelAndRedrawAllViews() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimProject::allOilFields(std::vector& oilFields) const +void RimProject::allOilFields(std::vector& allOilFields) const { - oilFields.clear(); + allOilFields.clear(); for (const auto& oilField : this->oilFields) { - oilFields.push_back(oilField); + allOilFields.push_back(oilField); } } @@ -835,8 +846,10 @@ bool RimProject::showPlotWindow() const //-------------------------------------------------------------------------------------------------- void RimProject::reloadCompletionTypeResultsInAllViews() { - createDisplayModelAndRedrawAllViews(); + scheduleCreateDisplayModelAndRedrawAllViews(); RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews(); + + this->mainPlotCollection()->updatePlotsWithCompletions(); } //-------------------------------------------------------------------------------------------------- @@ -975,10 +988,10 @@ std::vector RimProject::geoMechCases() const std::vector RimProject::allFractureTemplateCollections() const { std::vector templColls; - std::vector oilFields; + std::vector rimOilFields; - allOilFields(oilFields); - for (RimOilField* oilField : oilFields) + allOilFields(rimOilFields); + for (RimOilField* oilField : rimOilFields) { templColls.push_back(oilField->fractureDefinitionCollection()); } @@ -991,9 +1004,6 @@ std::vector RimProject::allFractureTemplateColle std::vector RimProject::allFractureTemplates() const { std::vector templates; - std::vector oilFields; - - allOilFields(oilFields); for (RimFractureTemplateCollection* templColl : allFractureTemplateCollections()) { for (RimFractureTemplate* templ : templColl->fractureTemplates()) @@ -1004,6 +1014,36 @@ std::vector RimProject::allFractureTemplates() const return templates; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaEclipseUnitTools::UnitSystemType RimProject::commonUnitSystemForAllCases() const +{ + std::vector rimCases; + allCases(rimCases); + + RiaEclipseUnitTools::UnitSystem commonUnitSystem = RiaEclipseUnitTools::UNITS_UNKNOWN; + + for (const auto& c : rimCases) + { + auto eclipseCase = dynamic_cast(c); + if (eclipseCase && eclipseCase->eclipseCaseData()) + { + if (commonUnitSystem == RiaEclipseUnitTools::UNITS_UNKNOWN) + { + commonUnitSystem = eclipseCase->eclipseCaseData()->unitsType(); + } + else if (commonUnitSystem != eclipseCase->eclipseCaseData()->unitsType()) + { + commonUnitSystem = RiaEclipseUnitTools::UNITS_UNKNOWN; + break; + } + } + } + + return commonUnitSystem; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimProject.h b/ApplicationCode/ProjectDataModel/RimProject.h index 22e1091435..7f349e0734 100644 --- a/ApplicationCode/ProjectDataModel/RimProject.h +++ b/ApplicationCode/ProjectDataModel/RimProject.h @@ -21,6 +21,7 @@ #pragma once #include "RiaDefines.h" +#include "RiaEclipseUnitTools.h" #include "cafPdmChildArrayField.h" #include "cafPdmChildField.h" @@ -48,6 +49,7 @@ class RimOilField; class RimScriptCollection; class RimSummaryCase; class RimSummaryCaseCollection; +class RimSummaryCaseMainCollection; class Rim3dView; class RimGridView; class RimViewLinker; @@ -76,7 +78,7 @@ class RimProject : public caf::PdmDocument public: RimProject(void); - virtual ~RimProject(void); + ~RimProject(void) override; caf::PdmChildArrayField oilFields; caf::PdmChildField scriptCollection; @@ -99,25 +101,26 @@ class RimProject : public caf::PdmDocument bool isProjectFileVersionEqualOrOlderThan(const QString& otherProjectFileVersion) const; void close(); - void setProjectFileNameAndUpdateDependencies(const QString& fileName); + void setProjectFileNameAndUpdateDependencies(const QString& projectFileName); void assignCaseIdToCase(RimCase* reservoirCase); void assignIdToCaseGroup(RimIdenticalGridCaseGroup* caseGroup); - void allCases(std::vector& cases); + void allCases(std::vector& cases) const; std::vector allSummaryCases() const; std::vector summaryGroups() const; - + RimSummaryCaseMainCollection* firstSummaryCaseMainCollection() const; + void allVisibleViews(std::vector& views); void allVisibleGridViews(std::vector& views); void allNotLinkedViews(std::vector& views); - void createDisplayModelAndRedrawAllViews(); + void scheduleCreateDisplayModelAndRedrawAllViews(); void computeUtmAreaOfInterest(); - void allOilFields(std::vector& oilFields) const; + void allOilFields(std::vector& allOilFields) const; RimOilField* activeOilField(); const RimOilField* activeOilField() const; @@ -145,13 +148,15 @@ class RimProject : public caf::PdmDocument std::vector allFractureTemplateCollections() const; std::vector allFractureTemplates() const; + RiaEclipseUnitTools::UnitSystemType commonUnitSystemForAllCases() const; + protected: // Overridden methods void initScriptDirectories(); - virtual void initAfterRead(); - virtual void setupBeforeSave(); + void initAfterRead() override; + void setupBeforeSave() override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; private: template diff --git a/ApplicationCode/ProjectDataModel/RimPropertyFilter.cpp b/ApplicationCode/ProjectDataModel/RimPropertyFilter.cpp index 35abd2db2e..42866b3495 100644 --- a/ApplicationCode/ProjectDataModel/RimPropertyFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimPropertyFilter.cpp @@ -18,6 +18,7 @@ #include "RimPropertyFilter.h" +#include "RimPropertyFilterCollection.h" CAF_PDM_SOURCE_INIT(RimPropertyFilter, "PropertyFilter"); diff --git a/ApplicationCode/ProjectDataModel/RimPropertyFilter.h b/ApplicationCode/ProjectDataModel/RimPropertyFilter.h index bb786eebb1..f985a61a37 100644 --- a/ApplicationCode/ProjectDataModel/RimPropertyFilter.h +++ b/ApplicationCode/ProjectDataModel/RimPropertyFilter.h @@ -30,7 +30,7 @@ class RimPropertyFilter : public RimCellFilter CAF_PDM_HEADER_INIT; public: RimPropertyFilter(); - virtual ~RimPropertyFilter(); + ~RimPropertyFilter() override; std::vector selectedCategoryValues() const; @@ -39,8 +39,8 @@ class RimPropertyFilter : public RimCellFilter void setCategoryNames(const std::vector& categoryNames); void setCategoryNamesAndValues(const std::vector>& categoryNamesAndValues); void clearCategories(); - - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; protected: caf::PdmField< std::vector > m_selectedCategoryValues; diff --git a/ApplicationCode/ProjectDataModel/RimPropertyFilterCollection.cpp b/ApplicationCode/ProjectDataModel/RimPropertyFilterCollection.cpp index c46df10fc6..1eac45dafe 100644 --- a/ApplicationCode/ProjectDataModel/RimPropertyFilterCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimPropertyFilterCollection.cpp @@ -19,7 +19,9 @@ #include "RimPropertyFilterCollection.h" #include "Rim3dView.h" +#include "RimPropertyFilter.h" #include "RimViewController.h" +#include "RimViewLinker.h" CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimPropertyFilterCollection, "RimPropertyFilterCollection"); // Abstract class @@ -44,13 +46,24 @@ RimPropertyFilterCollection::~RimPropertyFilterCollection() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimPropertyFilterCollection::updateDisplayModelNotifyManagedViews() const +void RimPropertyFilterCollection::updateDisplayModelNotifyManagedViews(RimPropertyFilter* changedFilter) const { Rim3dView* view = nullptr; this->firstAncestorOrThisOfType(view); CVF_ASSERT(view); if (!view) return; + if (view->isMasterView()) + { + RimViewLinker* viewLinker = view->assosiatedViewLinker(); + if (viewLinker) + { + // Update data for property filter + // Update of display model is handled by view->scheduleGeometryRegen, also for managed views + viewLinker->updatePropertyFilters(changedFilter); + } + } + view->scheduleGeometryRegen(PROPERTY_FILTERED); view->scheduleCreateDisplayModelAndRedraw(); } @@ -64,7 +77,7 @@ void RimPropertyFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* ch updateIconState(); uiCapability()->updateConnectedEditors(); - updateDisplayModelNotifyManagedViews(); + updateDisplayModelNotifyManagedViews(nullptr); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimPropertyFilterCollection.h b/ApplicationCode/ProjectDataModel/RimPropertyFilterCollection.h index 0fdd5a2d42..7d1f3fa0dd 100644 --- a/ApplicationCode/ProjectDataModel/RimPropertyFilterCollection.h +++ b/ApplicationCode/ProjectDataModel/RimPropertyFilterCollection.h @@ -21,6 +21,8 @@ #include "cafPdmObject.h" #include "cafPdmField.h" +class RimPropertyFilter; + //================================================================================================== /// /// @@ -30,7 +32,7 @@ class RimPropertyFilterCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimPropertyFilterCollection(); - virtual ~RimPropertyFilterCollection(); + ~RimPropertyFilterCollection() override; // Fields: caf::PdmField isActive; @@ -41,13 +43,13 @@ class RimPropertyFilterCollection : public caf::PdmObject virtual void loadAndInitializePropertyFilters() = 0; - void updateDisplayModelNotifyManagedViews() const; + void updateDisplayModelNotifyManagedViews(RimPropertyFilter* changedFilter) const; virtual void updateIconState() = 0; protected: // Overridden methods - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName); - virtual caf::PdmFieldHandle* objectToggleField(); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; + caf::PdmFieldHandle* objectToggleField() override; }; diff --git a/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.cpp index f07d096d52..c4ddeac25b 100644 --- a/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.cpp @@ -714,6 +714,14 @@ bool RimRegularLegendConfig::showLegend() const return m_showLegend; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimRegularLegendConfig::setShowLegend(bool show) +{ + m_showLegend = show; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -744,6 +752,14 @@ const caf::TitledOverlayFrame* RimRegularLegendConfig::titledOverlayFrame() cons } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimLegendConfig::RangeModeType RimRegularLegendConfig::rangeMode() const +{ + return m_rangeMode(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -852,7 +868,7 @@ QList RimRegularLegendConfig::calculateValueOptions(cons if ( ( eclCellColors && eclCellColors->hasCategoryResult()) || ( gmCellColors && gmCellColors->hasCategoryResult()) || ( eclCellEdgColors && eclCellEdgColors->hasCategoryResult()) - || ( ensembleCurveSet && ensembleCurveSet->currentEnsembleParameterType() == RimEnsembleCurveSet::TYPE_TEXT) ) + || ( ensembleCurveSet && ensembleCurveSet->currentEnsembleParameterType() == EnsembleParameter::TYPE_TEXT) ) { isCategoryResult = true; } diff --git a/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.h b/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.h index 8dafd2af15..a1ba2857cd 100644 --- a/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimRegularLegendConfig.h @@ -59,7 +59,7 @@ class RimRegularLegendConfig : public RimLegendConfig CAF_PDM_HEADER_INIT; public: RimRegularLegendConfig(); - virtual ~RimRegularLegendConfig(); + ~RimRegularLegendConfig() override; caf::PdmField resultVariableName; // Used internally to describe the variable this legend setup is used for @@ -121,17 +121,19 @@ class RimRegularLegendConfig : public RimLegendConfig cvf::ScalarMapper* scalarMapper() { return m_currentScalarMapper.p(); } bool showLegend() const; + void setShowLegend(bool show); const caf::TitledOverlayFrame* titledOverlayFrame() const override; caf::TitledOverlayFrame* titledOverlayFrame() override; + RangeModeType rangeMode() const; + private: void setNamedCategories(const std::vector& categoryNames, bool inverse); void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; void initAfterRead() override; caf::PdmFieldHandle* objectToggleField() override; - friend class RimStimPlanLegendConfig; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp index e366396acd..e4c3229587 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.cpp @@ -96,7 +96,7 @@ void RimReservoirCellResultsStorage::setupBeforeSave() bool hasResultsToStore = false; for (size_t rIdx = 0; rIdx < resInfo.size(); ++rIdx) { - if (resInfo[rIdx].m_needsToBeStored) + if (resInfo[rIdx].needsToBeStored()) { hasResultsToStore = true; break; @@ -128,18 +128,18 @@ void RimReservoirCellResultsStorage::setupBeforeSave() { // If there is no data, we do not store anything for the current result variable // (Even not the metadata, of cause) - size_t timestepCount = m_cellResults->cellScalarResults(resInfo[rIdx].m_gridScalarResultIndex).size(); + size_t timestepCount = m_cellResults->cellScalarResults(resInfo[rIdx].gridScalarResultIndex()).size(); - if (timestepCount && resInfo[rIdx].m_needsToBeStored) + if (timestepCount && resInfo[rIdx].needsToBeStored()) { - progInfo.setProgressDescription(resInfo[rIdx].m_resultName); + progInfo.setProgressDescription(resInfo[rIdx].resultName()); // Create and setup the cache information for this result RimReservoirCellResultsStorageEntryInfo* cacheEntry = new RimReservoirCellResultsStorageEntryInfo; m_resultCacheMetaData.push_back(cacheEntry); - cacheEntry->m_resultType = resInfo[rIdx].m_resultType; - cacheEntry->m_resultName = resInfo[rIdx].m_resultName; + cacheEntry->m_resultType = resInfo[rIdx].resultType(); + cacheEntry->m_resultName = resInfo[rIdx].resultName(); cacheEntry->m_timeStepDates = resInfo[rIdx].dates(); cacheEntry->m_daysSinceSimulationStart = resInfo[rIdx].daysSinceSimulationStarts(); @@ -153,7 +153,7 @@ void RimReservoirCellResultsStorage::setupBeforeSave() const std::vector* data = nullptr; if (tsIdx < timestepCount) { - data = &(m_cellResults->cellScalarResults(resInfo[rIdx].m_gridScalarResultIndex, tsIdx)); + data = &(m_cellResults->cellScalarResults(resInfo[rIdx].gridScalarResultIndex(), tsIdx)); } if (data && data->size()) @@ -271,7 +271,7 @@ void RimReservoirCellResultsStorage::setCellResults(RigCaseCellResultsData* cell for (size_t rIdx = 0; rIdx < m_resultCacheMetaData.size(); ++rIdx) { RimReservoirCellResultsStorageEntryInfo* resInfo = m_resultCacheMetaData[rIdx]; - size_t resultIndex = m_cellResults->findOrCreateScalarResultIndex(resInfo->m_resultType(), resInfo->m_resultName(), true); + size_t resultIndex = m_cellResults->findOrCreateScalarResultIndex(resInfo->m_resultType(), resInfo->m_resultName, true); std::vector reportNumbers; // Hack: Using no report step numbers. Not really used except for Flow Diagnostics... reportNumbers.resize(resInfo->m_timeStepDates().size()); diff --git a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h index ac3921a82a..b81de2127f 100644 --- a/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h +++ b/ApplicationCode/ProjectDataModel/RimReservoirCellResultsStorage.h @@ -43,7 +43,7 @@ class RimReservoirCellResultsStorage : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimReservoirCellResultsStorage(); - virtual ~RimReservoirCellResultsStorage(); + ~RimReservoirCellResultsStorage() override; void setCellResults(RigCaseCellResultsData* cellResults); @@ -51,7 +51,7 @@ class RimReservoirCellResultsStorage : public caf::PdmObject protected: // Overridden methods from PdmObject - virtual void setupBeforeSave(); + void setupBeforeSave() override; private: QString getValidCacheFileName(); @@ -69,7 +69,7 @@ class RimReservoirCellResultsStorageEntryInfo : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimReservoirCellResultsStorageEntryInfo(); - virtual ~RimReservoirCellResultsStorageEntryInfo(); + ~RimReservoirCellResultsStorageEntryInfo() override; caf::PdmField > m_resultType; caf::PdmField m_resultName; diff --git a/ApplicationCode/ProjectDataModel/RimRftPlotCollection.cpp b/ApplicationCode/ProjectDataModel/RimRftPlotCollection.cpp index ede492a3b0..30f617f0e6 100644 --- a/ApplicationCode/ProjectDataModel/RimRftPlotCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimRftPlotCollection.cpp @@ -185,6 +185,15 @@ void RimRftPlotCollection::removeExtractors(const RigGeoMechCaseData* caseData) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimRftPlotCollection::deleteAllExtractors() +{ + m_extractors.clear(); + m_geomExtractors.clear(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimRftPlotCollection.h b/ApplicationCode/ProjectDataModel/RimRftPlotCollection.h index f65a8e035c..51c24b3d23 100644 --- a/ApplicationCode/ProjectDataModel/RimRftPlotCollection.h +++ b/ApplicationCode/ProjectDataModel/RimRftPlotCollection.h @@ -45,7 +45,7 @@ class RimRftPlotCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimRftPlotCollection(); - virtual ~RimRftPlotCollection(); + ~RimRftPlotCollection() override; RigEclipseWellLogExtractor* findOrCreateSimWellExtractor(const QString& simWellName, const QString& caseUserDescription, @@ -58,6 +58,7 @@ class RimRftPlotCollection : public caf::PdmObject void removeExtractors(const RigWellPath* wellPath); void removeExtractors(const RigEclipseCaseData* caseData); void removeExtractors(const RigGeoMechCaseData* caseData); + void deleteAllExtractors(); const std::vector rftPlots() const; void addPlot(RimWellRftPlot* newPlot); diff --git a/ApplicationCode/ProjectDataModel/RimScriptCollection.h b/ApplicationCode/ProjectDataModel/RimScriptCollection.h index 094d89abff..d3b41147e8 100644 --- a/ApplicationCode/ProjectDataModel/RimScriptCollection.h +++ b/ApplicationCode/ProjectDataModel/RimScriptCollection.h @@ -41,7 +41,7 @@ class RimScriptCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimScriptCollection(); - virtual ~RimScriptCollection(); + ~RimScriptCollection() override; public: // Pdm Fields caf::PdmField directory; @@ -55,8 +55,8 @@ class RimScriptCollection : public caf::PdmObject RimScriptCollection* findScriptCollection(const QString& path); // Overrides from PdmObject - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; 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; }; diff --git a/ApplicationCode/ProjectDataModel/RimSimWellInView.cpp b/ApplicationCode/ProjectDataModel/RimSimWellInView.cpp index 57ac920432..fb89640b24 100644 --- a/ApplicationCode/ProjectDataModel/RimSimWellInView.cpp +++ b/ApplicationCode/ProjectDataModel/RimSimWellInView.cpp @@ -219,7 +219,6 @@ void RimSimWellInView::wellHeadTopBottomPosition(int frameIndex, cvf::Vec3d* top whCellPtr = &(rigReservoir->cellFromWellResultCell(wellResultFramePtr->wellHeadOrStartCell())); } - const RigWellResultFrame& wellResultFrame = *wellResultFramePtr; const RigCell& whCell = *whCellPtr; // Match this position with pipe start position in RivWellPipesPartMgr::calculateWellPipeCenterline() @@ -588,10 +587,6 @@ bool RimSimWellInView::isWellSpheresVisible(size_t frameIndex) const { return true; } - - CVF_ASSERT(false); // Never end here. have you added new pipe visibility modes ? - - return false; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimSimWellInView.h b/ApplicationCode/ProjectDataModel/RimSimWellInView.h index 770c43f6b3..fabe7551a6 100644 --- a/ApplicationCode/ProjectDataModel/RimSimWellInView.h +++ b/ApplicationCode/ProjectDataModel/RimSimWellInView.h @@ -49,7 +49,7 @@ class RimSimWellInView : public caf::PdmObject public: RimSimWellInView(); - virtual ~RimSimWellInView(); + ~RimSimWellInView() override; void setSimWellData(RigSimWellData* simWellData, size_t resultWellIndex); RigSimWellData* simWellData(); @@ -62,8 +62,8 @@ class RimSimWellInView : public caf::PdmObject bool isUsingCellCenterForPipe() const; - virtual caf::PdmFieldHandle* userDescriptionField() override; - virtual caf::PdmFieldHandle* objectToggleField() override; + caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* objectToggleField() override; std::vector wellPipeBranches() const; @@ -97,9 +97,9 @@ class RimSimWellInView : public caf::PdmObject protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; private: bool intersectsDynamicWellCellsFilteredCells(size_t frameIndex) const; diff --git a/ApplicationCode/ProjectDataModel/RimSimWellInViewCollection.cpp b/ApplicationCode/ProjectDataModel/RimSimWellInViewCollection.cpp index 269c8c59ac..37d1d5cc5e 100644 --- a/ApplicationCode/ProjectDataModel/RimSimWellInViewCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimSimWellInViewCollection.cpp @@ -22,11 +22,13 @@ #include "RiaApplication.h" #include "RiaColorTables.h" +#include "RiaFieldHandleTools.h" #include "RiaPreferences.h" #include "RigEclipseCaseData.h" #include "RigSimWellData.h" +#include "RimContourMapView.h" #include "RimEclipseCase.h" #include "RimEclipseResultCase.h" #include "RimEclipseView.h" @@ -127,20 +129,16 @@ RimSimWellInViewCollection::RimSimWellInViewCollection() CAF_PDM_InitFieldNoDefault(&m_showWellSpheres, "ShowWellSpheres", "Spheres", "", "", ""); m_showWellHead.uiCapability()->setUiEditorTypeName(caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName()); - m_showWellHead.xmlCapability()->setIOReadable(false); - m_showWellHead.xmlCapability()->setIOWritable(false); + m_showWellHead.xmlCapability()->disableIO(); m_showWellLabel.uiCapability()->setUiEditorTypeName(caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName()); - m_showWellLabel.xmlCapability()->setIOReadable(false); - m_showWellLabel.xmlCapability()->setIOWritable(false); + m_showWellLabel.xmlCapability()->disableIO(); m_showWellPipe.uiCapability()->setUiEditorTypeName(caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName()); - m_showWellPipe.xmlCapability()->setIOReadable(false); - m_showWellPipe.xmlCapability()->setIOWritable(false); + m_showWellPipe.xmlCapability()->disableIO(); m_showWellSpheres.uiCapability()->setUiEditorTypeName(caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName()); - m_showWellSpheres.xmlCapability()->setIOReadable(false); - m_showWellSpheres.xmlCapability()->setIOWritable(false); + m_showWellSpheres.xmlCapability()->disableIO(); // Scaling CAF_PDM_InitField(&wellHeadScaleFactor, "WellHeadScale", 1.0, "Well Head Scale", "", "", ""); @@ -168,8 +166,7 @@ RimSimWellInViewCollection::RimSimWellInViewCollection() CAF_PDM_InitFieldNoDefault(&m_showWellCells, "ShowWellCellsTristate", "Show Well Cells", "", "", ""); m_showWellCells.uiCapability()->setUiEditorTypeName(caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName()); - m_showWellCells.xmlCapability()->setIOReadable(false); - m_showWellCells.xmlCapability()->setIOWritable(false); + m_showWellCells.xmlCapability()->disableIO(); CAF_PDM_InitField(&wellCellFenceType, "DefaultWellFenceDirection", WellFenceEnum(K_DIRECTION), "Well Fence Direction", "", "", ""); @@ -182,31 +179,23 @@ RimSimWellInViewCollection::RimSimWellInViewCollection() CAF_PDM_InitFieldNoDefault(&m_showWellCellFence, "ShowWellCellFenceTristate", "Show Well Cell Fence", "", "", ""); m_showWellCellFence.uiCapability()->setUiEditorTypeName(caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName()); - m_showWellCellFence.xmlCapability()->setIOReadable(false); - m_showWellCellFence.xmlCapability()->setIOWritable(false); + m_showWellCellFence.xmlCapability()->disableIO(); CAF_PDM_InitField(&obsoleteField_wellPipeVisibility, "GlobalWellPipeVisibility", WellVisibilityEnum(PIPES_INDIVIDUALLY), "Global well pipe visibility", "", "", ""); - obsoleteField_wellPipeVisibility.uiCapability()->setUiHidden(true); - obsoleteField_wellPipeVisibility.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&obsoleteField_wellPipeVisibility); CAF_PDM_InitField(&obsoleteField_wellCellsToRangeFilterMode, "GlobalWellCellVisibility", WellCellsRangeFilterEnum(RANGE_ADD_INDIVIDUAL), "Add cells to range filter", "", "", ""); - obsoleteField_wellCellsToRangeFilterMode.uiCapability()->setUiHidden(true); - obsoleteField_wellCellsToRangeFilterMode.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&obsoleteField_wellCellsToRangeFilterMode); CAF_PDM_InitField(&obsoleteField_showWellHead, "ShowWellHead", true, "Show Well Head", "", "", ""); CAF_PDM_InitField(&obsoleteField_showWellLabel, "ShowWellLabel", true, "Show Well Label", "", "", ""); CAF_PDM_InitField(&obsoleteField_showWellCellFence, "ShowWellFences", false, "Show Well Cell Fence", "", "", ""); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&obsoleteField_showWellHead); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&obsoleteField_showWellLabel); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&obsoleteField_showWellCellFence); CAF_PDM_InitField(&m_showWellCommunicationLines, "ShowWellCommunicationLines", false, "Communication Lines", "", "", ""); - obsoleteField_showWellHead.uiCapability()->setUiHidden(true); - obsoleteField_showWellLabel.uiCapability()->setUiHidden(true); - obsoleteField_showWellCellFence.uiCapability()->setUiHidden(true); - - obsoleteField_showWellHead.xmlCapability()->setIOWritable(false); - obsoleteField_showWellLabel.xmlCapability()->setIOWritable(false); - obsoleteField_showWellCellFence.xmlCapability()->setIOWritable(false); - m_reservoirView = nullptr; } @@ -530,18 +519,26 @@ void RimSimWellInViewCollection::defineUiOrdering(QString uiConfigName, caf::Pdm { updateStateForVisibilityCheckboxes(); + bool isContourMap = dynamic_cast(m_reservoirView) != nullptr; + caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup("Visibility"); - appearanceGroup->add(&showWellsIntersectingVisibleCells); + if (!isContourMap) + { + appearanceGroup->add(&showWellsIntersectingVisibleCells); + } appearanceGroup->add(&m_showWellLabel); appearanceGroup->add(&m_showWellHead); appearanceGroup->add(&m_showWellPipe); appearanceGroup->add(&m_showWellSpheres); appearanceGroup->add(&m_showWellCommunicationLines); - caf::PdmUiGroup* filterGroup = uiOrdering.addNewGroup("Well Cells and Fence"); - filterGroup->add(&m_showWellCells); - filterGroup->add(&m_showWellCellFence); - filterGroup->add(&wellCellFenceType); + if (!isContourMap) + { + caf::PdmUiGroup* filterGroup = uiOrdering.addNewGroup("Well Cells and Fence"); + filterGroup->add(&m_showWellCells); + filterGroup->add(&m_showWellCellFence); + filterGroup->add(&wellCellFenceType); + } caf::PdmUiGroup* sizeScalingGroup = uiOrdering.addNewGroup("Size Scaling"); sizeScalingGroup->add(&wellHeadScaleFactor); @@ -560,10 +557,13 @@ void RimSimWellInViewCollection::defineUiOrdering(QString uiConfigName, caf::Pdm wellPipeGroup->add(&wellPipeCoordType); wellPipeGroup->add(&isAutoDetectingBranches); - caf::PdmUiGroup* advancedGroup = uiOrdering.addNewGroup("Advanced"); - advancedGroup->setCollapsedByDefault(true); - advancedGroup->add(&wellCellTransparencyLevel); - advancedGroup->add(&wellHeadPosition); + if (!isContourMap) + { + caf::PdmUiGroup* advancedGroup = uiOrdering.addNewGroup("Advanced"); + advancedGroup->setCollapsedByDefault(true); + advancedGroup->add(&wellCellTransparencyLevel); + advancedGroup->add(&wellHeadPosition); + } RimEclipseResultCase* ownerCase = nullptr; firstAncestorOrThisOfType(ownerCase); @@ -574,6 +574,8 @@ void RimSimWellInViewCollection::defineUiOrdering(QString uiConfigName, caf::Pdm m_showWellCellFence.uiCapability()->setUiReadOnly(!showWellCells()); wellCellFenceType.uiCapability()->setUiReadOnly(!showWellCells()); + + uiOrdering.skipRemainingFields(true); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimSimWellInViewCollection.h b/ApplicationCode/ProjectDataModel/RimSimWellInViewCollection.h index dea4460889..a58b50acaa 100644 --- a/ApplicationCode/ProjectDataModel/RimSimWellInViewCollection.h +++ b/ApplicationCode/ProjectDataModel/RimSimWellInViewCollection.h @@ -41,7 +41,7 @@ class RimSimWellInViewCollection : public caf::PdmObject public: RimSimWellInViewCollection(); - virtual ~RimSimWellInViewCollection(); + ~RimSimWellInViewCollection() override; void setReservoirView(RimEclipseView* ownerReservoirView); @@ -127,15 +127,15 @@ class RimSimWellInViewCollection : public caf::PdmObject static void updateWellAllocationPlots(); protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual caf::PdmFieldHandle* objectToggleField() override; - virtual void initAfterRead() override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + caf::PdmFieldHandle* objectToggleField() override; + void initAfterRead() override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; private: void calculateWellGeometryVisibility(size_t frameIndex); diff --git a/ApplicationCode/ProjectDataModel/RimStimPlanColors.cpp b/ApplicationCode/ProjectDataModel/RimStimPlanColors.cpp index a9850e13d4..66be397e33 100644 --- a/ApplicationCode/ProjectDataModel/RimStimPlanColors.cpp +++ b/ApplicationCode/ProjectDataModel/RimStimPlanColors.cpp @@ -208,7 +208,7 @@ void RimStimPlanColors::fieldChangedByUi(const caf::PdmFieldHandle* changedField this->firstAncestorOrThisOfType(proj); if (proj) { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } @@ -314,7 +314,7 @@ void RimStimPlanColors::updateStimPlanTemplates() const { stimPlanFracTemplate->updateFractureGrid(); } - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } diff --git a/ApplicationCode/ProjectDataModel/RimStimPlanColors.h b/ApplicationCode/ProjectDataModel/RimStimPlanColors.h index 1ff3a5735e..e7d29325db 100644 --- a/ApplicationCode/ProjectDataModel/RimStimPlanColors.h +++ b/ApplicationCode/ProjectDataModel/RimStimPlanColors.h @@ -52,7 +52,7 @@ class RimStimPlanColors : public RimCheckableObject }; public: RimStimPlanColors(); - virtual ~RimStimPlanColors(); + ~RimStimPlanColors() override; RimRegularLegendConfig* activeLegend() const; QString uiResultName() const; @@ -71,10 +71,10 @@ class RimStimPlanColors : public RimCheckableObject void updateConductivityResultName(); protected: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: RimFractureTemplateCollection* fractureTemplateCollection() const; diff --git a/ApplicationCode/ProjectDataModel/RimStimPlanLegendConfig.cpp b/ApplicationCode/ProjectDataModel/RimStimPlanLegendConfig.cpp index b5d54fe9b6..413cb977dd 100644 --- a/ApplicationCode/ProjectDataModel/RimStimPlanLegendConfig.cpp +++ b/ApplicationCode/ProjectDataModel/RimStimPlanLegendConfig.cpp @@ -80,7 +80,7 @@ void RimStimPlanLegendConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiO { uiOrdering.add(&m_name); - m_legend->defineUiOrdering(uiConfigName, uiOrdering); + m_legend->uiOrdering(uiConfigName, uiOrdering); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimStimPlanLegendConfig.h b/ApplicationCode/ProjectDataModel/RimStimPlanLegendConfig.h index 3a60a9719c..ef3508876a 100644 --- a/ApplicationCode/ProjectDataModel/RimStimPlanLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimStimPlanLegendConfig.h @@ -36,17 +36,17 @@ class RimStimPlanLegendConfig : public caf::PdmObject public: RimStimPlanLegendConfig(); - virtual ~RimStimPlanLegendConfig(); + ~RimStimPlanLegendConfig() override; QString name() const; void setName(const QString& name); - virtual caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* userDescriptionField() override; protected: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; private: caf::PdmField m_name; diff --git a/ApplicationCode/ProjectDataModel/RimSummaryCalculation.cpp b/ApplicationCode/ProjectDataModel/RimSummaryCalculation.cpp index 9ec7e9117e..2654de8215 100644 --- a/ApplicationCode/ProjectDataModel/RimSummaryCalculation.cpp +++ b/ApplicationCode/ProjectDataModel/RimSummaryCalculation.cpp @@ -23,7 +23,7 @@ #include "RiaSummaryCurveDefinition.h" #include "RiaSummaryTools.h" -#include "RigTimeHistoryCurveMerger.h" +#include "RiaTimeHistoryCurveMerger.h" #include "RimProject.h" #include "RimSummaryAddress.h" @@ -240,7 +240,7 @@ bool RimSummaryCalculation::calculate() { QString leftHandSideVariableName = RimSummaryCalculation::findLeftHandSide(m_expression); - RigTimeHistoryCurveMerger timeHistoryCurveMerger; + RiaTimeHistoryCurveMerger timeHistoryCurveMerger; for (size_t i = 0; i < m_variables.size(); i++) { @@ -260,7 +260,6 @@ bool RimSummaryCalculation::calculate() return false; } - RimSummaryAddress* sumAdr = v->summaryAddress(); RiaSummaryCurveDefinition curveDef(v->summaryCase(), v->summaryAddress()->address()); std::vector curveValues; diff --git a/ApplicationCode/ProjectDataModel/RimSummaryCalculation.h b/ApplicationCode/ProjectDataModel/RimSummaryCalculation.h index 8c973ff724..676a37c6d5 100644 --- a/ApplicationCode/ProjectDataModel/RimSummaryCalculation.h +++ b/ApplicationCode/ProjectDataModel/RimSummaryCalculation.h @@ -57,17 +57,17 @@ class RimSummaryCalculation : public caf::PdmObject bool calculate(); void updateDependentCurvesAndPlots(); - virtual caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* userDescriptionField() override; static QString findLeftHandSide(const QString& expresion); void attachToWidget(); private: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; RimSummaryCalculationVariable* findByName(const QString& name) const; RimSummaryCalculationVariable* addVariable(const QString& name); diff --git a/ApplicationCode/ProjectDataModel/RimSummaryCalculationCollection.h b/ApplicationCode/ProjectDataModel/RimSummaryCalculationCollection.h index 4b29886798..e2b882c036 100644 --- a/ApplicationCode/ProjectDataModel/RimSummaryCalculationCollection.h +++ b/ApplicationCode/ProjectDataModel/RimSummaryCalculationCollection.h @@ -48,7 +48,7 @@ class RimSummaryCalculationCollection : public caf::PdmObject void rebuildCaseMetaData(); private: - virtual void initAfterRead() override; + void initAfterRead() override; private: caf::PdmChildArrayField m_calcuations; diff --git a/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp b/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp index c5f31f6842..92d3de5e1d 100644 --- a/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp +++ b/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.cpp @@ -32,7 +32,7 @@ #include "RiuSummaryCurveDefSelectionDialog.h" #include "cafPdmUiPushButtonEditor.h" -#include "cafPdmUiTableView.h" +#include "cafPdmUiTableViewEditor.h" CAF_PDM_SOURCE_INIT(RimSummaryCalculationVariable, "RimSummaryCalculationVariable"); @@ -169,7 +169,7 @@ void RimSummaryCalculationVariable::defineUiOrdering(QString uiConfigName, caf:: //-------------------------------------------------------------------------------------------------- void RimSummaryCalculationVariable::defineObjectEditorAttribute(QString uiConfigName, caf::PdmUiEditorAttribute* attribute) { - caf::PdmUiTableViewEditorAttribute* attr = dynamic_cast(attribute); + caf::PdmUiTableViewPushButtonEditorAttribute* attr = dynamic_cast(attribute); if (attr) { attr->registerPushButtonTextForFieldKeyword(m_button.keyword(), "Edit"); diff --git a/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.h b/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.h index baff8ada55..39673480d4 100644 --- a/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.h +++ b/ApplicationCode/ProjectDataModel/RimSummaryCalculationVariable.h @@ -50,9 +50,9 @@ class RimSummaryCalculationVariable : public caf::PdmObject RimSummaryAddress* summaryAddress(); private: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineObjectEditorAttribute(QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineObjectEditorAttribute(QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; void readDataFromApplicationStore(RiuSummaryCurveDefSelectionDialog* selectionDialog) const; void writeDataToApplicationStore() const; diff --git a/ApplicationCode/ProjectDataModel/RimTensorResults.cpp b/ApplicationCode/ProjectDataModel/RimTensorResults.cpp index d2f05925a2..cb31fa5bfb 100644 --- a/ApplicationCode/ProjectDataModel/RimTensorResults.cpp +++ b/ApplicationCode/ProjectDataModel/RimTensorResults.cpp @@ -70,8 +70,7 @@ RimTensorResults::RimTensorResults() m_resultFieldName.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&m_resultFieldNameUiField, "ResultVariableUI", QString("ST"), "Value", "", "", ""); - m_resultFieldNameUiField.xmlCapability()->setIOWritable(false); - m_resultFieldNameUiField.xmlCapability()->setIOReadable(false); + m_resultFieldNameUiField.xmlCapability()->disableIO(); CAF_PDM_InitField(&m_showTensors, "ShowTensors", false, "", "", "", ""); @@ -214,6 +213,18 @@ void RimTensorResults::mappingRange(double* min, double* max) const } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimTensorResults::observedResults() const +{ + RigFemResultAddress mainResult = selectedTensorResult(); + std::vector tensorComponents = RigFemPartResultsCollection::tensorComponentAddresses(mainResult); + std::vector principleComponents = RigFemPartResultsCollection::tensorPrincipalComponentAdresses(mainResult); + tensorComponents.insert(tensorComponents.end(), principleComponents.begin(), principleComponents.end()); + return tensorComponents; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimTensorResults.h b/ApplicationCode/ProjectDataModel/RimTensorResults.h index 18701d39f1..babb51dc74 100644 --- a/ApplicationCode/ProjectDataModel/RimTensorResults.h +++ b/ApplicationCode/ProjectDataModel/RimTensorResults.h @@ -22,6 +22,7 @@ #include "cafPdmField.h" #include "cafPdmObject.h" +#include "RimFemResultObserver.h" #include "RigFemResultPosEnum.h" #include "RimRegularLegendConfig.h" @@ -36,7 +37,7 @@ class RimRegularLegendConfig; /// /// //================================================================================================== -class RimTensorResults : public caf::PdmObject +class RimTensorResults : public RimFemResultObserver { CAF_PDM_HEADER_INIT; @@ -57,7 +58,7 @@ class RimTensorResults : public caf::PdmObject public: RimTensorResults(); - virtual ~RimTensorResults(); + ~RimTensorResults() override; RigFemResultAddress selectedTensorResult() const; void setShowTensors(bool enableTensors); @@ -72,21 +73,22 @@ class RimTensorResults : public caf::PdmObject void mappingRange(double *min, double* max) const; - static RigFemResultPosEnum resultPositionType(); - QString resultFieldName() const; - static QString uiFieldName(const QString& fieldName); + std::vector observedResults() const override; + static RigFemResultPosEnum resultPositionType(); + QString resultFieldName() const; + static QString uiFieldName(const QString& fieldName); caf::PdmChildField arrowColorLegendConfig; private: std::vector getResultMetaDataForUIFieldSetting(); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual caf::PdmFieldHandle* objectToggleField() override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void initAfterRead() override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* objectToggleField() override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void initAfterRead() override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; static QString fieldNameFromUi(const QString& uiFieldName); diff --git a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h index 3d651b318d..a0789eab9e 100644 --- a/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h +++ b/ApplicationCode/ProjectDataModel/RimTernaryLegendConfig.h @@ -53,7 +53,7 @@ class RimTernaryLegendConfig : public RimLegendConfig public: RimTernaryLegendConfig(); - virtual ~RimTernaryLegendConfig(); + ~RimTernaryLegendConfig() override; void setUiValuesFromLegendConfig(const RimTernaryLegendConfig* otherLegendConfig); void setAutomaticRanges(TernaryArrayIndex ternaryIndex, double globalMin, double globalMax, double localMin, double localMax); diff --git a/ApplicationCode/ProjectDataModel/RimTimeStepFilter.cpp b/ApplicationCode/ProjectDataModel/RimTimeStepFilter.cpp index d11262f34e..eeeb6ce0a8 100644 --- a/ApplicationCode/ProjectDataModel/RimTimeStepFilter.cpp +++ b/ApplicationCode/ProjectDataModel/RimTimeStepFilter.cpp @@ -18,17 +18,24 @@ #include "RimTimeStepFilter.h" +#include "RiaQDateTimeTools.h" + #include "RifReaderEclipseOutput.h" +#include "RigCaseCellResultsData.h" + #include "RimEclipseResultCase.h" +#include "RimGeoMechCase.h" #include "RimReservoirCellResultsStorage.h" #include "RimTools.h" +#include "cafPdmUiLineEditor.h" +#include "cafPdmUiListEditor.h" #include "cafPdmUiPushButtonEditor.h" -#include "cafPdmUiTextEditor.h" #include -#include "RigCaseCellResultsData.h" + +#include namespace caf { @@ -57,22 +64,25 @@ RimTimeStepFilter::RimTimeStepFilter() { CAF_PDM_InitObject("Time Step Filter", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_selectedTimeStepIndices, "TimeStepIndicesToImport", "Values", "", "", ""); + caf::AppEnum< RimTimeStepFilter::TimeStepFilterTypeEnum > filterType = TS_ALL; + CAF_PDM_InitField(&m_filterType, "FilterType", filterType, "Filter Type", "", "", ""); CAF_PDM_InitField(&m_firstTimeStep, "FirstTimeStep", 0, "First Time Step", "", "", ""); CAF_PDM_InitField(&m_lastTimeStep, "LastTimeStep", 0, "Last Time Step", "", "", ""); - caf::AppEnum< RimTimeStepFilter::TimeStepFilterTypeEnum > filterType = TS_ALL; - CAF_PDM_InitField(&m_filterType, "FilterType", filterType, "Filter Type", "", "", ""); - CAF_PDM_InitField(&m_interval, "Interval", 1, "Interval", "", "", ""); + m_interval.uiCapability()->setUiEditorTypeName(caf::PdmUiLineEditor::uiEditorTypeName()); - CAF_PDM_InitField(&m_filteredTimeStepsText, "FilteredTimeSteps", QString(), "Filtered TimeSteps", "", "", ""); - m_filteredTimeStepsText.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName()); - m_filteredTimeStepsText.uiCapability()->setUiReadOnly(true); - m_filteredTimeStepsText.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + CAF_PDM_InitField(&m_timeStepNamesFromFile, "TimeStepsFromFile", std::vector(), "TimeSteps From File", "", "", ""); + CAF_PDM_InitField(&m_dateFormat, "DateFormat", QString("yyyy-MM-dd"), "Date Format", "", "", ""); - m_filteredTimeStepsText.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault(&m_filteredTimeSteps, "TimeStepIndicesToImport", "Select From Time Steps", "", "", ""); + m_filteredTimeSteps.uiCapability()->setUiReadOnly(true); + + CAF_PDM_InitFieldNoDefault(&m_filteredTimeStepsUi, "TimeStepIndicesUi", "Select From TimeSteps", "", "", ""); + m_filteredTimeStepsUi.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_filteredTimeStepsUi.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); + m_filteredTimeStepsUi.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault(&m_applyReloadOfCase, "ApplyReloadOfCase", "", "", "", ""); caf::PdmUiPushButtonEditor::configureEditorForField(&m_applyReloadOfCase); @@ -83,62 +93,134 @@ RimTimeStepFilter::RimTimeStepFilter() //-------------------------------------------------------------------------------------------------- void RimTimeStepFilter::setTimeStepsFromFile(const std::vector& timeSteps) { - m_timeStepsFromFile = timeSteps; + m_dateFormat = RimTools::createTimeFormatStringFromDates(timeSteps); + + std::vector timeStepStrings; + for (const QDateTime& date : timeSteps) + { + QString dateString = RiaQDateTimeTools::toStringUsingApplicationLocale(date, m_dateFormat); + + timeStepStrings.push_back(dateString); + } + m_timeStepNamesFromFile = timeStepStrings; m_lastTimeStep = static_cast(timeSteps.size()) - 1; - updateSelectedTimeStepIndices(); - updateDerivedData(); + if (m_filteredTimeSteps().empty()) + { + m_filteredTimeSteps = filteredTimeStepIndicesFromUi(); + } + m_filteredTimeStepsUi = m_filteredTimeSteps; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimTimeStepFilter::clearTimeStepsFromFile() +void RimTimeStepFilter::setTimeStepsFromFile(const std::vector>& timeSteps) { - m_timeStepsFromFile.clear(); + std::vector validDates; + for (auto stringDatePair : timeSteps) + { + if (stringDatePair.second.isValid()) + { + validDates.push_back(stringDatePair.second); + } + } + m_dateFormat = RimTools::createTimeFormatStringFromDates(validDates); + + std::vector timeStepStrings; + for (auto stringDatePair : timeSteps) + { + QString stepString = stringDatePair.first; + if (stringDatePair.second.isValid()) + { + stepString = RiaQDateTimeTools::toStringUsingApplicationLocale(stringDatePair.second, m_dateFormat); + } + timeStepStrings.push_back(stepString); + } + + m_timeStepNamesFromFile = timeStepStrings; + m_lastTimeStep = static_cast(timeSteps.size()) - 1; + + if (m_filteredTimeSteps().empty()) + { + m_filteredTimeSteps = filteredTimeStepIndicesFromUi(); + } + m_filteredTimeStepsUi = m_filteredTimeSteps; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimTimeStepFilter::filteredNativeTimeStepIndices() const +std::vector RimTimeStepFilter::filteredTimeSteps() const { std::vector indices; // Convert vector from int to size_t - for (auto intValue : m_selectedTimeStepIndices.v()) + for (int index : m_filteredTimeSteps()) { - indices.push_back(intValue); + indices.push_back(static_cast(index)); } return indices; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimTimeStepFilter::updateFilteredTimeStepsFromUi() +{ + std::vector timeSteps = m_filteredTimeStepsUi; + std::sort(timeSteps.begin(), timeSteps.end()); + if (m_filteredTimeSteps() == timeSteps) + { + return false; + } + m_filteredTimeSteps = timeSteps; + return true; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTimeStepFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { RimEclipseResultCase* rimEclipseResultCase = parentEclipseResultCase(); - + RimGeoMechCase* rimGeoMechCase = parentGeoMechCase(); if (changedField == &m_applyReloadOfCase) { - if (rimEclipseResultCase) + if (updateFilteredTimeStepsFromUi()) { - rimEclipseResultCase->reloadDataAndUpdate(); - } - return; + if (rimEclipseResultCase) + { + rimEclipseResultCase->reloadDataAndUpdate(); + } + else if (rimGeoMechCase) + { + rimGeoMechCase->reloadDataAndUpdate(); + } + + return; + } } - updateSelectedTimeStepIndices(); - updateDerivedData(); + if (changedField == &m_filterType || + changedField == &m_firstTimeStep || + changedField == &m_lastTimeStep || + changedField == &m_interval) + { + m_filteredTimeStepsUi = filteredTimeStepIndicesFromUi(); + } if (rimEclipseResultCase) { rimEclipseResultCase->updateConnectedEditors(); } + else if (rimGeoMechCase) + { + rimGeoMechCase->updateConnectedEditors(); + } } //-------------------------------------------------------------------------------------------------- @@ -151,13 +233,21 @@ QList RimTimeStepFilter::calculateValueOptions(const caf if (fieldNeedingOptions == &m_firstTimeStep || fieldNeedingOptions == &m_lastTimeStep) { - std::vector timeSteps = allTimeSteps(); - - QString formatString = RimTools::createTimeFormatStringFromDates(timeSteps); + for (size_t i = 0; i < m_timeStepNamesFromFile().size(); i++) + { + optionItems.push_back(caf::PdmOptionItemInfo(m_timeStepNamesFromFile()[i], static_cast(i))); + } + } - for (size_t i = 0; i < timeSteps.size(); i++) + if (fieldNeedingOptions == &m_filteredTimeStepsUi) + { + std::vector filteredTimeSteps = filteredTimeStepIndicesFromUi(); + for (auto filteredIndex : filteredTimeSteps) { - optionItems.push_back(caf::PdmOptionItemInfo(timeSteps[i].toString(formatString), static_cast(i))); + if (filteredIndex < static_cast(m_timeStepNamesFromFile().size())) + { + optionItems.push_back(caf::PdmOptionItemInfo(m_timeStepNamesFromFile()[filteredIndex], static_cast(filteredIndex))); + } } } @@ -177,67 +267,33 @@ void RimTimeStepFilter::defineEditorAttribute(const caf::PdmFieldHandle* field, attrib->m_buttonText = "Reload Case"; } } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimTimeStepFilter::filteredTimeStepsAsText() const -{ - QString text; - - std::vector timeSteps = allTimeSteps(); - - QString formatString = RimTools::createTimeFormatStringFromDates(timeSteps); - - for (auto selectedIndex : m_selectedTimeStepIndices.v()) + else if (field == &m_interval) { - size_t timeStepIndex = static_cast(selectedIndex); - - if (timeStepIndex < timeSteps.size()) + caf::PdmUiLineEditorAttribute* attrib = dynamic_cast(attribute); + if (attrib) { - text += timeSteps[timeStepIndex].toString(formatString); - text += "\n"; + attrib->avoidSendingEnterEventToParentWidget = true; } } - - return text; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimTimeStepFilter::updateDerivedData() +std::vector> RimTimeStepFilter::allTimeSteps() const { - m_filteredTimeStepsText = filteredTimeStepsAsText(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimTimeStepFilter::updateSelectedTimeStepIndices() -{ - m_selectedTimeStepIndices = selectedTimeStepIndicesFromUi(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimTimeStepFilter::allTimeSteps() const -{ - RimEclipseResultCase* rimEclipseResultCase = parentEclipseResultCase(); - if (rimEclipseResultCase && rimEclipseResultCase->results(RiaDefines::MATRIX_MODEL)) + std::vector> timeSteps; + for (const QString& dateString : m_timeStepNamesFromFile()) { - return rimEclipseResultCase->results(RiaDefines::MATRIX_MODEL)->allTimeStepDatesFromEclipseReader(); + timeSteps.push_back(std::make_pair(dateString, QDateTime::fromString(dateString, m_dateFormat))); } - - return m_timeStepsFromFile; + return timeSteps; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimTimeStepFilter::selectedTimeStepIndicesFromUi() const +std::vector RimTimeStepFilter::filteredTimeStepIndicesFromUi() const { std::vector indices; @@ -271,20 +327,32 @@ std::vector RimTimeStepFilter::selectedTimeStepIndicesFromUi() const int daysToSkip = m_interval * intervalFactor; + std::vector> timeSteps = allTimeSteps(); - std::vector timeSteps = allTimeSteps(); - - indices.push_back(m_firstTimeStep); - QDateTime d = timeSteps[m_firstTimeStep].addDays(daysToSkip); - - for (int i = m_firstTimeStep + 1; i <= m_lastTimeStep; i++) + QDateTime d; + for (int i = m_firstTimeStep; i <= m_lastTimeStep; i++) { - if (timeSteps[i] > d) + if (!timeSteps[i].second.isValid()) { - d = d.addDays(daysToSkip); indices.push_back(i); } - } + else + { + if (d.isValid()) + { + if (timeSteps[i].second > d) + { + d = d.addDays(daysToSkip); + indices.push_back(i); + } + } + else + { + d = timeSteps[i].second.addDays(daysToSkip); + indices.push_back(i); + } + } + } } return indices; @@ -316,36 +384,49 @@ RimEclipseResultCase* RimTimeStepFilter::parentEclipseResultCase() const return rimEclipseResultCase; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimGeoMechCase* RimTimeStepFilter::parentGeoMechCase() const +{ + RimGeoMechCase* rimGeoMechCase = nullptr; + this->firstAncestorOrThisOfType(rimGeoMechCase); + return rimGeoMechCase; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimTimeStepFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { + uiOrdering.add(&m_filterType); uiOrdering.add(&m_firstTimeStep); uiOrdering.add(&m_lastTimeStep); - uiOrdering.add(&m_filterType); uiOrdering.add(&m_interval); + uiOrdering.add(&m_filteredTimeStepsUi); + size_t numberOfFilterOptions = filteredTimeStepIndicesFromUi().size(); + QString displayUiName = QString("Select From %1 Time Steps:").arg(numberOfFilterOptions); + m_filteredTimeStepsUi.uiCapability()->setUiName(displayUiName); - if (m_timeStepsFromFile.size() == 0) - { - uiOrdering.add(&m_applyReloadOfCase); - } - - QString displayUiName = QString("Filtered Time Steps (%1)").arg(m_selectedTimeStepIndices().size()); + bool caseLoaded = false; - caf::PdmUiGroup* group = uiOrdering.addNewGroupWithKeyword(displayUiName, "FilteredTimeStepKeyword"); - group->add(&m_filteredTimeStepsText); + RimEclipseResultCase* eclipseCase = parentEclipseResultCase(); + RimGeoMechCase* geoMechCase = parentGeoMechCase(); - if (m_timeStepsFromFile.size() == 0) + if (eclipseCase) { - group->setCollapsedByDefault(true); + caseLoaded = eclipseCase->eclipseCaseData() != nullptr; } - else + else if (geoMechCase) + { + caseLoaded = geoMechCase->geoMechData() != nullptr; + } + + if (caseLoaded) { - group->setCollapsedByDefault(false); + uiOrdering.add(&m_applyReloadOfCase); } - updateDerivedData(); updateFieldVisibility(); uiOrdering.skipRemainingFields(); diff --git a/ApplicationCode/ProjectDataModel/RimTimeStepFilter.h b/ApplicationCode/ProjectDataModel/RimTimeStepFilter.h index 55d282ae51..46409f9793 100644 --- a/ApplicationCode/ProjectDataModel/RimTimeStepFilter.h +++ b/ApplicationCode/ProjectDataModel/RimTimeStepFilter.h @@ -25,6 +25,7 @@ class QDateTime; class RimEclipseResultCase; +class RimGeoMechCase; //-------------------------------------------------------------------------------------------------- /// @@ -48,41 +49,32 @@ class RimTimeStepFilter : public caf::PdmObject RimTimeStepFilter(); void setTimeStepsFromFile(const std::vector& timeSteps); - void clearTimeStepsFromFile(); - - std::vector filteredNativeTimeStepIndices() const; - + void setTimeStepsFromFile(const std::vector>& timeSteps); + std::vector filteredTimeSteps() const; + bool updateFilteredTimeStepsFromUi(); private: - QString filteredTimeStepsAsText() const; - - void updateDerivedData(); - void updateSelectedTimeStepIndices(); - - std::vector allTimeSteps() const; - std::vector selectedTimeStepIndicesFromUi() const; + std::vector> allTimeSteps() const; + std::vector filteredTimeStepIndicesFromUi() const; void updateFieldVisibility(); - RimEclipseResultCase* parentEclipseResultCase() const; + RimGeoMechCase* parentGeoMechCase() const; // PDM overrides - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; private: - caf::PdmField< std::vector > m_selectedTimeStepIndices; - caf::PdmField< caf::AppEnum< TimeStepFilterTypeEnum > > m_filterType; - - caf::PdmField m_firstTimeStep; - caf::PdmField m_lastTimeStep; - caf::PdmField m_interval; - - caf::PdmField m_filteredTimeStepsText; - - caf::PdmField m_applyReloadOfCase; - - std::vector m_timeStepsFromFile; /// Temporarily set to provide correct options before the case data structures are operative + + caf::PdmField< std::vector > m_filteredTimeSteps; + caf::PdmField< std::vector > m_filteredTimeStepsUi; + caf::PdmField m_firstTimeStep; + caf::PdmField m_lastTimeStep; + caf::PdmField m_interval; + caf::PdmField m_applyReloadOfCase; + caf::PdmField m_dateFormat; + caf::PdmField> m_timeStepNamesFromFile; }; diff --git a/ApplicationCode/ProjectDataModel/RimTools.cpp b/ApplicationCode/ProjectDataModel/RimTools.cpp index 4047cc1108..ce82055855 100644 --- a/ApplicationCode/ProjectDataModel/RimTools.cpp +++ b/ApplicationCode/ProjectDataModel/RimTools.cpp @@ -67,23 +67,26 @@ QString RimTools::getCacheRootDirectoryPathFromProject() /// such that the common start of oldProjectPath and m_gridFileName is removed from m_gridFileName /// and replaced with the start of newProjectPath up to where newProjectPath starts to be equal to oldProjectPath //-------------------------------------------------------------------------------------------------- -QString RimTools::relocateFile(const QString& orgFileName, const QString& orgNewProjectPath, const QString& orgOldProjectPath, - bool* foundFile, std::vector* searchedPaths) +QString RimTools::relocateFile(const QString& originalFileName, + const QString& currentProjectPath, + const QString& previousProjectPath, + bool* foundFile, + std::vector* searchedPaths) { if (foundFile) *foundFile = true; // Make sure we have a Qt formatted path ( using "/" not "\") - QString fileName = QDir::fromNativeSeparators(orgFileName); - QString newProjectPath = QDir::fromNativeSeparators(orgNewProjectPath); - QString oldProjectPath = QDir::fromNativeSeparators(orgOldProjectPath); + QString fileName = QDir::fromNativeSeparators(originalFileName); + QString newProjectPath = QDir::fromNativeSeparators(currentProjectPath); + QString oldProjectPath = QDir::fromNativeSeparators(previousProjectPath); // If we from a file or whatever gets a real windows path on linux, we need to manually convert it // because Qt will not. QDir::fromNativeSeparators does nothing on linux. bool isWindowsPath = false; - if (orgFileName.count("/")) isWindowsPath = false; // "/" are not allowed in a windows path - else if (orgFileName.count("\\") - && !caf::Utils::fileExists(orgFileName)) // To make sure we do not convert single linux files containing "\" + if (originalFileName.count("/")) isWindowsPath = false; // "/" are not allowed in a windows path + else if (originalFileName.count("\\") + && !caf::Utils::fileExists(originalFileName)) // To make sure we do not convert single linux files containing "\" { isWindowsPath = true; } @@ -114,10 +117,10 @@ QString RimTools::relocateFile(const QString& orgFileName, const QString& orgNew // Then find the possible move of a directory structure where projects and files referenced are moved in "paralell" - QFileInfo gridFileInfo(QDir::fromNativeSeparators(fileName)); - QString gridFilePath = gridFileInfo.path(); - QString gridFileNameWoPath = gridFileInfo.fileName(); - QStringList gridPathElements = gridFilePath.split("/", QString::KeepEmptyParts); + QFileInfo fileNameFileInfo(QDir::fromNativeSeparators(fileName)); + QString fileNamePath = fileNameFileInfo.path(); + QString fileNameWithoutPath = fileNameFileInfo.fileName(); + QStringList fileNamePathElements = fileNamePath.split("/", QString::KeepEmptyParts); QString oldProjPath = QDir::fromNativeSeparators(oldProjectPath); QStringList oldProjPathElements = oldProjPath.split("/", QString::KeepEmptyParts); @@ -130,7 +133,7 @@ QString RimTools::relocateFile(const QString& orgFileName, const QString& orgNew bool pathStartsAreEqual = false; bool pathEndsDiffer = false; int firstDiffIdx = 0; - for (firstDiffIdx = 0; firstDiffIdx < gridPathElements.size() && firstDiffIdx < oldProjPathElements.size(); ++firstDiffIdx) + for (firstDiffIdx = 0; firstDiffIdx < fileNamePathElements.size() && firstDiffIdx < oldProjPathElements.size(); ++firstDiffIdx) { #ifdef WIN32 // When comparing parts of a file path, the drive letter has been seen to be a mix of @@ -140,9 +143,9 @@ QString RimTools::relocateFile(const QString& orgFileName, const QString& orgNew #else Qt::CaseSensitivity cs = Qt::CaseSensitive; #endif - if (gridPathElements[firstDiffIdx].compare(oldProjPathElements[firstDiffIdx], cs) == 0) + if (fileNamePathElements[firstDiffIdx].compare(oldProjPathElements[firstDiffIdx], cs) == 0) { - pathStartsAreEqual = pathStartsAreEqual || !gridPathElements[firstDiffIdx].isEmpty(); + pathStartsAreEqual = pathStartsAreEqual || !fileNamePathElements[firstDiffIdx].isEmpty(); } else { @@ -151,7 +154,7 @@ QString RimTools::relocateFile(const QString& orgFileName, const QString& orgNew } } - if (!pathEndsDiffer && firstDiffIdx < gridPathElements.size() || firstDiffIdx < oldProjPathElements.size()) + if (!pathEndsDiffer && firstDiffIdx < fileNamePathElements.size() || firstDiffIdx < oldProjPathElements.size()) { pathEndsDiffer = true; } @@ -162,11 +165,11 @@ QString RimTools::relocateFile(const QString& orgFileName, const QString& orgNew { if (pathEndsDiffer) { - QString oldGridFilePathEnd; - for (int i = firstDiffIdx; i < gridPathElements.size(); ++i) + QString oldFileNamePathEnd; + for (int i = firstDiffIdx; i < fileNamePathElements.size(); ++i) { - oldGridFilePathEnd += gridPathElements[i]; - oldGridFilePathEnd += "/"; + oldFileNamePathEnd += fileNamePathElements[i]; + oldFileNamePathEnd += "/"; } // Find the new Project File Start Path @@ -177,27 +180,29 @@ QString RimTools::relocateFile(const QString& orgFileName, const QString& orgNew oldProjectFilePathEndElements.push_back(oldProjPathElements[i]); } - int ppIdx = oldProjectFilePathEndElements.size() - 1; - int lastDiffIdx = newProjPathElements.size() - 1; - - for (; lastDiffIdx >= 0 && ppIdx >= 0; --lastDiffIdx, --ppIdx) + int lastProjectDiffIdx = newProjPathElements.size() - 1; { - if (oldProjectFilePathEndElements[ppIdx] != newProjPathElements[lastDiffIdx]) + int ppIdx = oldProjectFilePathEndElements.size() - 1; + + for (; lastProjectDiffIdx >= 0 && ppIdx >= 0; --lastProjectDiffIdx, --ppIdx) { - break; + if (oldProjectFilePathEndElements[ppIdx] != newProjPathElements[lastProjectDiffIdx]) + { + break; + } } } - QString newProjecetFileStartPath; - for (int i = 0; i <= lastDiffIdx; ++i) + QString newProjectFileStartPath; + for (int i = 0; i <= lastProjectDiffIdx; ++i) { - newProjecetFileStartPath += newProjPathElements[i]; - newProjecetFileStartPath += "/"; + newProjectFileStartPath += newProjPathElements[i]; + newProjectFileStartPath += "/"; } - QString relocationPath = newProjecetFileStartPath + oldGridFilePathEnd; + QString relocationPath = newProjectFileStartPath + oldFileNamePathEnd; - QString relocatedFileName = relocationPath + gridFileNameWoPath; + QString relocatedFileName = relocationPath + fileNameWithoutPath; if (searchedPaths) searchedPaths->push_back(relocatedFileName); @@ -227,10 +232,10 @@ void RimTools::wellPathOptionItems(QList* options) CVF_ASSERT(options); if (!options) return; - RimProject* proj = RiaApplication::instance()->project(); - if (proj && proj->activeOilField() && proj->activeOilField()->wellPathCollection()) + auto wellPathColl = RimTools::wellPathCollection(); + if (wellPathColl) { - caf::PdmChildArrayField& wellPaths = proj->activeOilField()->wellPathCollection()->wellPaths; + caf::PdmChildArrayField& wellPaths = wellPathColl->wellPaths; QIcon wellIcon(":/Well.png"); for (RimWellPath* wellPath : wellPaths) @@ -263,10 +268,10 @@ void RimTools::wellPathWithFormationsOptionItems(QList* //-------------------------------------------------------------------------------------------------- void RimTools::wellPathWithFormations(std::vector* wellPaths) { - RimProject* proj = RiaApplication::instance()->project(); - if (proj && proj->activeOilField() && proj->activeOilField()->wellPathCollection()) + auto wellPathColl = RimTools::wellPathCollection(); + if (wellPathColl) { - caf::PdmChildArrayField& allWellPaths = proj->activeOilField()->wellPathCollection()->wellPaths; + caf::PdmChildArrayField& allWellPaths = wellPathColl->wellPaths; for (RimWellPath* wellPath : allWellPaths) { @@ -352,3 +357,17 @@ QString RimTools::dateFormatString() { return "dd.MMM yyyy"; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathCollection* RimTools::wellPathCollection() +{ + RimProject* proj = RiaApplication::instance()->project(); + if (proj && proj->activeOilField()) + { + return proj->activeOilField()->wellPathCollection(); + } + + return nullptr; +} diff --git a/ApplicationCode/ProjectDataModel/RimTools.h b/ApplicationCode/ProjectDataModel/RimTools.h index 54e5e16788..8c8726c40b 100644 --- a/ApplicationCode/ProjectDataModel/RimTools.h +++ b/ApplicationCode/ProjectDataModel/RimTools.h @@ -33,6 +33,8 @@ namespace caf { class PdmOptionItemInfo; } +class RimWellPathCollection; + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -41,7 +43,11 @@ class RimTools public: static QString getCacheRootDirectoryPathFromProject(); - static QString relocateFile(const QString& fileName, const QString& newProjectPath, const QString& oldProjectPath, bool* foundFile, std::vector* searchedPaths); + static QString relocateFile(const QString& originalFileName, + const QString& currentProjectPath, + const QString& previousProjectPath, + bool* foundFile, + std::vector* searchedPaths); static void wellPathOptionItems(QList* options); static void wellPathWithFormationsOptionItems(QList* options); @@ -51,4 +57,6 @@ class RimTools static QString createTimeFormatStringFromDates(const std::vector& dates); static QString dateFormatString(); + + static RimWellPathCollection* wellPathCollection(); }; diff --git a/ApplicationCode/ProjectDataModel/RimViewController.cpp b/ApplicationCode/ProjectDataModel/RimViewController.cpp index 9aed000ab7..941c48f9f8 100644 --- a/ApplicationCode/ProjectDataModel/RimViewController.cpp +++ b/ApplicationCode/ProjectDataModel/RimViewController.cpp @@ -2,17 +2,17 @@ // // Copyright (C) 2015- Statoil ASA // Copyright (C) 2015- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -20,6 +20,7 @@ #include "RimViewController.h" #include "RiaApplication.h" +#include "RiaOptionItemFactory.h" #include "RigCaseToCaseCellMapper.h" #include "RigCaseToCaseRangeFilterMapper.h" @@ -27,6 +28,8 @@ #include "RigGeoMechCaseData.h" #include "RigMainGrid.h" +#include "RimContourMapView.h" +#include "Rim3dView.h" #include "RimCase.h" #include "RimCellRangeFilter.h" #include "RimCellRangeFilterCollection.h" @@ -38,8 +41,8 @@ #include "RimGeoMechCellColors.h" #include "RimGeoMechPropertyFilterCollection.h" #include "RimGeoMechView.h" +#include "RimIntersectionCollection.h" #include "RimProject.h" -#include "Rim3dView.h" #include "RimViewLinker.h" #include "RimViewLinkerCollection.h" @@ -48,14 +51,15 @@ #include "cafPdmUiTreeOrdering.h" #include -#include "RimIntersectionCollection.h" CAF_PDM_SOURCE_INIT(RimViewController, "ViewController"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimViewController::RimViewController(void) +RimViewController::RimViewController() { + // clang-format off + CAF_PDM_InitObject("View Link", "", "", ""); CAF_PDM_InitField(&m_isActive, "Active", true, "Active", "", "", ""); @@ -77,31 +81,33 @@ RimViewController::RimViewController(void) CAF_PDM_InitField(&m_syncVisibleCells, "SyncVisibleCells", false, "Visible Cells", "", "", ""); /// We do not support this. Consider to remove sometime m_syncVisibleCells.uiCapability()->setUiHidden(true); - m_syncVisibleCells.xmlCapability()->setIOWritable(false); - m_syncVisibleCells.xmlCapability()->setIOReadable(false); + m_syncVisibleCells.xmlCapability()->disableIO(); CAF_PDM_InitField(&m_syncRangeFilters, "SyncRangeFilters", false, "Range Filters", "", "", ""); CAF_PDM_InitField(&m_syncPropertyFilters, "SyncPropertyFilters", false,"Property Filters", "", "", ""); + + // clang-format on } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimViewController::~RimViewController(void) +RimViewController::~RimViewController() { this->removeOverrides(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QList RimViewController::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +QList RimViewController::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) { QList options; if (fieldNeedingOptions == &m_managedView) { - RimProject* proj = RiaApplication::instance()->project(); + RimProject* proj = RiaApplication::instance()->project(); std::vector views; proj->allNotLinkedViews(views); @@ -119,19 +125,11 @@ QList RimViewController::calculateValueOptions(const caf { if (view != viewLinker->masterView()) { - RimCase* rimCase = nullptr; - view->firstAncestorOrThisOfType(rimCase); - QIcon icon; - if (rimCase) - { - icon = rimCase->uiCapability()->uiIcon(); - } - - options.push_back(caf::PdmOptionItemInfo(RimViewLinker::displayNameForView(view), view, false, icon)); + RiaOptionItemFactory::appendOptionItemFromViewNameAndCaseName(view, &options); } } - if (options.size() > 0) + if (!options.empty()) { options.push_front(caf::PdmOptionItemInfo("None", nullptr)); } @@ -141,7 +139,7 @@ QList RimViewController::calculateValueOptions(const caf } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) { @@ -150,9 +148,11 @@ void RimViewController::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrder } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimViewController::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +void RimViewController::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { if (changedField == &m_isActive) { @@ -171,7 +171,7 @@ void RimViewController::fieldChangedByUi(const caf::PdmFieldHandle* changedField { updateCameraLink(); } - else if (changedField == &m_syncTimeStep ) + else if (changedField == &m_syncTimeStep) { updateTimeStepLink(); } @@ -212,8 +212,8 @@ void RimViewController::fieldChangedByUi(const caf::PdmFieldHandle* changedField } else if (changedField == &m_managedView) { - PdmObjectHandle* prevValue = oldValue.value >().rawPtr(); - RimGridView* previousManagedView = dynamic_cast(prevValue); + PdmObjectHandle* prevValue = oldValue.value>().rawPtr(); + RimGridView* previousManagedView = dynamic_cast(prevValue); RimViewController::removeOverrides(previousManagedView); setManagedView(m_managedView()); @@ -227,9 +227,8 @@ void RimViewController::fieldChangedByUi(const caf::PdmFieldHandle* changedField } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimEclipseView* RimViewController::managedEclipseView() const { @@ -239,7 +238,7 @@ RimEclipseView* RimViewController::managedEclipseView() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimGeoMechView* RimViewController::managedGeoView() const { @@ -249,16 +248,16 @@ RimGeoMechView* RimViewController::managedGeoView() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::updateOverrides() { RimViewLinker* viewLinker = ownerViewLinker(); - + RimGridView* masterView = viewLinker->masterView(); CVF_ASSERT(masterView); - + if (m_managedView) { RimEclipseView* manEclView = managedEclipseView(); @@ -276,7 +275,6 @@ void RimViewController::updateOverrides() RimEclipseView* masterEclipseView = dynamic_cast(masterView); if (masterEclipseView) { - if (manEclView) { if (isPropertyFilterOveridden()) @@ -308,7 +306,7 @@ void RimViewController::updateOverrides() } this->updateRangeFilterOverrides(nullptr); - + if (manGeoView) { manGeoView->updateIconStateForFilterCollections(); @@ -322,7 +320,7 @@ void RimViewController::updateOverrides() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::removeOverrides() { @@ -342,7 +340,7 @@ void RimViewController::removeOverrides() } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::removeOverrides(RimGridView* view) { @@ -353,18 +351,18 @@ void RimViewController::removeOverrides(RimGridView* view) if (manEclView) manEclView->setOverridePropertyFilterCollection(nullptr); if (manGeoView) manGeoView->setOverridePropertyFilterCollection(nullptr); - + view->setOverrideRangeFilterCollection(nullptr); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::updateOptionSensitivity() { RimGridView* mainView = nullptr; - + { RimViewLinker* linkedViews = nullptr; firstAncestorOrThisOfType(linkedViews); @@ -378,7 +376,7 @@ void RimViewController::updateOptionSensitivity() } RimEclipseView* eclipseMasterView = dynamic_cast(mainView); - RimGeoMechView* geoMasterView = dynamic_cast(mainView); + RimGeoMechView* geoMasterView = dynamic_cast(mainView); bool isMasterAndDependentViewDifferentType = false; if (eclipseMasterView && !managedEclipseView()) @@ -413,6 +411,16 @@ void RimViewController::updateOptionSensitivity() } } + if (isCameraControlPossible()) + { + this->m_syncCamera.uiCapability()->setUiReadOnly(false); + } + else + { + this->m_syncCamera.uiCapability()->setUiReadOnly(true); + this->m_syncCamera = false; + } + if (isPropertyFilterControlPossible()) { this->m_syncPropertyFilters.uiCapability()->setUiReadOnly(false); @@ -444,10 +452,11 @@ void RimViewController::updateOptionSensitivity() } m_syncVisibleCells.uiCapability()->setUiReadOnly(!this->isMasterAndDepViewDifferentType()); + } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimGridView* RimViewController::managedView() const { @@ -455,13 +464,14 @@ RimGridView* RimViewController::managedView() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::setManagedView(RimGridView* view) { m_managedView = view; updateOptionSensitivity(); + updateDefaultOptions(); updateOverrides(); updateResultColorsControl(); updateCameraLink(); @@ -470,7 +480,7 @@ void RimViewController::setManagedView(RimGridView* view) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { @@ -491,9 +501,8 @@ void RimViewController::defineUiOrdering(QString uiConfigName, caf::PdmUiOrderin visibleCells->add(&m_syncPropertyFilters); } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::updateDisplayNameAndIcon() { @@ -502,7 +511,7 @@ void RimViewController::updateDisplayNameAndIcon() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::updateCameraLink() { @@ -517,22 +526,22 @@ void RimViewController::updateCameraLink() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::updateTimeStepLink() { - if (!this->isTimeStepLinked()) return; + if (!this->isTimeStepLinked()) return; if (m_managedView) { - RimViewLinker* viewLinker = this->ownerViewLinker(); + RimViewLinker* viewLinker = this->ownerViewLinker(); viewLinker->updateTimeStep(viewLinker->masterView(), viewLinker->masterView()->currentTimeStep()); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::updateResultColorsControl() { @@ -543,7 +552,7 @@ void RimViewController::updateResultColorsControl() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::updateLegendDefinitions() { @@ -554,7 +563,17 @@ void RimViewController::updateLegendDefinitions() } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::updateDefaultOptions() +{ + m_syncCellResult = isCellResultControlAdvisable(); + m_syncRangeFilters = isRangeFilterControlAdvisable(); + m_syncPropertyFilters = isPropertyFilterControlAdvisable(); +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- RimViewLinker* RimViewController::ownerViewLinker() const { @@ -565,7 +584,7 @@ RimViewLinker* RimViewController::ownerViewLinker() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const RigCaseToCaseCellMapper* RimViewController::cellMapper() { @@ -589,14 +608,12 @@ const RigCaseToCaseCellMapper* RimViewController::cellMapper() dependEclGrid = dependEclipseView->mainGrid(); } - if (masterGeomechView && masterGeomechView->geoMechCase()->geoMechData() - && masterGeomechView->femParts()->partCount()) + if (masterGeomechView && masterGeomechView->geoMechCase()->geoMechData() && masterGeomechView->femParts()->partCount()) { masterFemPart = masterGeomechView->femParts()->part(0); } - if (dependGeomechView && dependGeomechView->geoMechCase()->geoMechData() - && dependGeomechView->femParts()->partCount()) + if (dependGeomechView && dependGeomechView->geoMechCase()->geoMechData() && dependGeomechView->femParts()->partCount()) { dependFemPart = dependGeomechView->femParts()->part(0); } @@ -604,17 +621,16 @@ const RigCaseToCaseCellMapper* RimViewController::cellMapper() // If we have the correct mapping already, return it. if (m_caseToCaseCellMapper.notNull()) { - if ( masterEclGrid == m_caseToCaseCellMapper->masterGrid() - && dependEclGrid == m_caseToCaseCellMapper->dependentGrid() - && masterFemPart == m_caseToCaseCellMapper->masterFemPart() - && dependFemPart == m_caseToCaseCellMapper->dependentFemPart()) - { - return m_caseToCaseCellMapper.p(); - } - else - { - m_caseToCaseCellMapper = nullptr; - } + if (masterEclGrid == m_caseToCaseCellMapper->masterGrid() && dependEclGrid == m_caseToCaseCellMapper->dependentGrid() && + masterFemPart == m_caseToCaseCellMapper->masterFemPart() && + dependFemPart == m_caseToCaseCellMapper->dependentFemPart()) + { + return m_caseToCaseCellMapper.p(); + } + else + { + m_caseToCaseCellMapper = nullptr; + } } // Create the mapping if needed @@ -633,7 +649,7 @@ const RigCaseToCaseCellMapper* RimViewController::cellMapper() { m_caseToCaseCellMapper = new RigCaseToCaseCellMapper(masterFemPart, dependFemPart); } - else if (masterFemPart && dependEclGrid) + else if (masterFemPart && dependEclGrid) { m_caseToCaseCellMapper = new RigCaseToCaseCellMapper(masterFemPart, dependEclGrid); } @@ -643,7 +659,7 @@ const RigCaseToCaseCellMapper* RimViewController::cellMapper() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimGridView* RimViewController::masterView() const { @@ -651,12 +667,22 @@ RimGridView* RimViewController::masterView() const } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isCameraControlPossible() const +{ + RimContourMapView* contourMapMasterView = dynamic_cast(masterView()); + RimContourMapView* contourMapManagedView = dynamic_cast(managedEclipseView()); + return !(contourMapMasterView || contourMapManagedView); +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isMasterAndDepViewDifferentType() const { RimEclipseView* eclipseMasterView = dynamic_cast(masterView()); - RimGeoMechView* geoMasterView = dynamic_cast(masterView()); + RimGeoMechView* geoMasterView = dynamic_cast(masterView()); bool isMasterAndDependentViewDifferentType = false; if (eclipseMasterView && !managedEclipseView()) @@ -666,23 +692,20 @@ bool RimViewController::isMasterAndDepViewDifferentType() const if (geoMasterView && !managedGeoView()) { isMasterAndDependentViewDifferentType = true; - } + } return isMasterAndDependentViewDifferentType; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::scheduleCreateDisplayModelAndRedrawForDependentView() const { if (!this->isActive()) return; - if (this->isVisibleCellsOveridden() - || this->isRangeFiltersControlled() - || this->isPropertyFilterOveridden() - || this->isResultColorControlled() - ) + if (this->isVisibleCellsOveridden() || this->isRangeFiltersControlled() || this->isPropertyFilterOveridden() || + this->isResultColorControlled()) { if (this->managedView()) { @@ -690,28 +713,25 @@ void RimViewController::scheduleCreateDisplayModelAndRedrawForDependentView() co } } - if (this->isResultColorControlled() && this->managedView() ) + if (this->isResultColorControlled() && this->managedView()) { this->managedView()->crossSectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType) const { if (!this->isActive()) return; - if ( this->isVisibleCellsOveridden() - || this->isRangeFiltersControlled() - || this->isPropertyFilterOveridden() - || this->isResultColorControlled() - ) + if (this->isVisibleCellsOveridden() || this->isRangeFiltersControlled() || this->isPropertyFilterOveridden() || + this->isResultColorControlled()) { if (this->managedView()) { - if (this->isVisibleCellsOveridden()) + if (this->isVisibleCellsOveridden()) { this->managedView()->scheduleGeometryRegen(OVERRIDDEN_CELL_VISIBILITY); } @@ -722,7 +742,7 @@ void RimViewController::scheduleGeometryRegenForDepViews(RivCellSetEnum geometry } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isActive() const { @@ -730,7 +750,7 @@ bool RimViewController::isActive() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isCameraLinked() const { @@ -745,7 +765,7 @@ bool RimViewController::isCameraLinked() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::showCursor() const { @@ -753,7 +773,7 @@ bool RimViewController::showCursor() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isTimeStepLinked() const { @@ -768,11 +788,11 @@ bool RimViewController::isTimeStepLinked() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isResultColorControlled() const { - if (ownerViewLinker()->isActive() && this->m_isActive()) + if (ownerViewLinker()->isActive() && this->m_isActive()) { return m_syncCellResult; } @@ -783,7 +803,7 @@ bool RimViewController::isResultColorControlled() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isLegendDefinitionsControlled() const { @@ -798,7 +818,7 @@ bool RimViewController::isLegendDefinitionsControlled() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isVisibleCellsOveridden() const { @@ -820,12 +840,12 @@ bool RimViewController::isVisibleCellsOveridden() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isRangeFilterControlPossible() const { return true; - #if 0 +#if 0 if (!isMasterAndDepViewDifferentType()) return true; // Make sure the cases are in the same domain @@ -850,19 +870,19 @@ bool RimViewController::isRangeFilterControlPossible() const } } return false; - #endif +#endif } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -bool RimViewController::isRangeFilterMappingApliccable() const +bool RimViewController::isRangeFilterMappingApplicable() const { if (!isMasterAndDepViewDifferentType()) return false; // Make sure the cases are in the same domain RimEclipseView* eclipseView = dynamic_cast(masterView()); - RimGeoMechView* geomView = dynamic_cast(masterView()); + RimGeoMechView* geomView = dynamic_cast(masterView()); if (!geomView) geomView = managedGeoView(); if (!eclipseView) eclipseView = managedEclipseView(); @@ -871,7 +891,7 @@ bool RimViewController::isRangeFilterMappingApliccable() const if (eclipseView->eclipseCase()->eclipseCaseData() && geomView->geoMechCase() && geomView->geoMechCase()->geoMechData()) { RigMainGrid* eclGrid = eclipseView->mainGrid(); - RigFemPart* femPart = geomView->femParts()->part(0); + RigFemPart* femPart = geomView->femParts()->part(0); if (eclGrid && femPart) { @@ -885,9 +905,38 @@ bool RimViewController::isRangeFilterMappingApliccable() const return false; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isCellResultControlAdvisable() const +{ + bool contourMapMasterView = dynamic_cast(masterView()) != nullptr; + bool contourMapManagedView = dynamic_cast(managedEclipseView()) != nullptr; + return !isMasterAndDepViewDifferentType() && contourMapMasterView != contourMapManagedView; +} //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isRangeFilterControlAdvisable() const +{ + bool contourMapMasterView = dynamic_cast(masterView()) != nullptr; + bool contourMapManagedView = dynamic_cast(managedEclipseView()) != nullptr; + return isRangeFilterControlPossible() && contourMapMasterView != contourMapManagedView; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewController::isPropertyFilterControlAdvisable() const +{ + bool contourMapMasterView = dynamic_cast(masterView()) != nullptr; + bool contourMapManagedView = dynamic_cast(managedEclipseView()) != nullptr; + return isPropertyFilterControlPossible() && contourMapMasterView != contourMapManagedView; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isRangeFiltersControlled() const { @@ -903,16 +952,16 @@ bool RimViewController::isRangeFiltersControlled() const } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isPropertyFilterControlPossible() const { - // The cases need to be the same + // The cases need to be the same RimGeoMechView* geomView = dynamic_cast(masterView()); if (geomView) { - RimGeoMechView* depGeomView = managedGeoView(); + RimGeoMechView* depGeomView = managedGeoView(); if (depGeomView && geomView->geoMechCase() == depGeomView->geoMechCase()) { return true; @@ -925,23 +974,22 @@ bool RimViewController::isPropertyFilterControlPossible() const { RimEclipseView* depEclipseView = managedEclipseView(); if (depEclipseView && eclipseView->eclipseCase() == depEclipseView->eclipseCase()) - { + { return true; } } - - return false; -} + return false; +} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::isPropertyFilterOveridden() const { - if (!isPropertyFilterControlPossible()) return false; + if (!isPropertyFilterControlPossible()) return false; - if (ownerViewLinker()->isActive() && this->m_isActive()) + if (ownerViewLinker()->isActive() && this->m_isActive()) { return m_syncPropertyFilters; } @@ -952,7 +1000,7 @@ bool RimViewController::isPropertyFilterOveridden() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::updateRangeFilterOverrides(RimCellRangeFilter* changedRangeFilter) { @@ -971,30 +1019,31 @@ void RimViewController::updateRangeFilterOverrides(RimCellRangeFilter* changedRa // Copy the rangeFilterCollection RimCellRangeFilterCollection* sourceFilterCollection = masterView()->rangeFilterCollection(); - QString xmlRangeFilterCollCopy = sourceFilterCollection->writeObjectToXmlString(); - PdmObjectHandle* objectCopy = PdmXmlObjectHandle::readUnknownObjectFromXmlString(xmlRangeFilterCollCopy, caf::PdmDefaultObjectFactory::instance()); + QString xmlRangeFilterCollCopy = sourceFilterCollection->writeObjectToXmlString(); + PdmObjectHandle* objectCopy = + PdmXmlObjectHandle::readUnknownObjectFromXmlString(xmlRangeFilterCollCopy, caf::PdmDefaultObjectFactory::instance()); RimCellRangeFilterCollection* overrideRangeFilterColl = dynamic_cast(objectCopy); // Convert the range filter to fit in the managed view if needed - if (isRangeFilterMappingApliccable()) + if (isRangeFilterMappingApplicable()) { RimEclipseView* eclipseMasterView = dynamic_cast(masterView()); - RimGeoMechView* geoMasterView = dynamic_cast(masterView()); - RimEclipseView* depEclView = managedEclipseView(); - RimGeoMechView* depGeomView = managedGeoView(); + RimGeoMechView* geoMasterView = dynamic_cast(masterView()); + RimEclipseView* depEclView = managedEclipseView(); + RimGeoMechView* depGeomView = managedGeoView(); if (eclipseMasterView && depGeomView) { if (eclipseMasterView->mainGrid()) { RigMainGrid* srcEclGrid = eclipseMasterView->mainGrid(); - RigFemPart* dstFemPart = depGeomView->femParts()->part(0); + RigFemPart* dstFemPart = depGeomView->femParts()->part(0); for (size_t rfIdx = 0; rfIdx < sourceFilterCollection->rangeFilters().size(); ++rfIdx) { RimCellRangeFilter* srcRFilter = sourceFilterCollection->rangeFilters[rfIdx]; RimCellRangeFilter* dstRFilter = overrideRangeFilterColl->rangeFilters[rfIdx]; - RigCaseToCaseRangeFilterMapper::convertRangeFilterEclToFem(srcRFilter, srcEclGrid, - dstRFilter, dstFemPart); + RigCaseToCaseRangeFilterMapper::convertRangeFilterEclToFem( + srcRFilter, srcEclGrid, dstRFilter, dstFemPart); } } } @@ -1002,14 +1051,14 @@ void RimViewController::updateRangeFilterOverrides(RimCellRangeFilter* changedRa { if (depEclView->mainGrid()) { - RigFemPart* srcFemPart = geoMasterView->femParts()->part(0); + RigFemPart* srcFemPart = geoMasterView->femParts()->part(0); RigMainGrid* dstEclGrid = depEclView->mainGrid(); for (size_t rfIdx = 0; rfIdx < sourceFilterCollection->rangeFilters().size(); ++rfIdx) { RimCellRangeFilter* srcRFilter = sourceFilterCollection->rangeFilters[rfIdx]; RimCellRangeFilter* dstRFilter = overrideRangeFilterColl->rangeFilters[rfIdx]; - RigCaseToCaseRangeFilterMapper::convertRangeFilterFemToEcl(srcRFilter, srcFemPart, - dstRFilter, dstEclGrid); + RigCaseToCaseRangeFilterMapper::convertRangeFilterFemToEcl( + srcRFilter, srcFemPart, dstRFilter, dstEclGrid); } } } @@ -1019,8 +1068,18 @@ void RimViewController::updateRangeFilterOverrides(RimCellRangeFilter* changedRa } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimViewController::updatePropertyFilterOverrides(RimPropertyFilter* changedPropertyFilter) +{ + updateOverrides(); +} + + //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewController::applyRangeFilterCollectionByUserChoice() { @@ -1031,7 +1090,7 @@ void RimViewController::applyRangeFilterCollectionByUserChoice() return; } - bool restoreOriginal = askUserToRestoreOriginalRangeFilterCollection(m_managedView->name); + bool restoreOriginal = askUserToRestoreOriginalRangeFilterCollection(m_managedView->name()); if (restoreOriginal) { m_managedView->setOverrideRangeFilterCollection(nullptr); @@ -1043,7 +1102,7 @@ void RimViewController::applyRangeFilterCollectionByUserChoice() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewController::askUserToRestoreOriginalRangeFilterCollection(const QString& viewName) { @@ -1069,4 +1128,3 @@ bool RimViewController::askUserToRestoreOriginalRangeFilterCollection(const QStr return true; } } - diff --git a/ApplicationCode/ProjectDataModel/RimViewController.h b/ApplicationCode/ProjectDataModel/RimViewController.h index 01003cbb7e..a254b14939 100644 --- a/ApplicationCode/ProjectDataModel/RimViewController.h +++ b/ApplicationCode/ProjectDataModel/RimViewController.h @@ -34,6 +34,7 @@ class RimGeoMechView; class RimViewLinker; class RigCaseToCaseCellMapper; class RimCellRangeFilter; +class RimPropertyFilter; //================================================================================================== /// @@ -44,15 +45,15 @@ class RimViewController : public caf::PdmObject CAF_PDM_HEADER_INIT; public: - RimViewController(void); - virtual ~RimViewController(void); + RimViewController(); + ~RimViewController() override; bool isActive() const; - RimGridView* managedView() const; + RimGridView* managedView() const; void setManagedView(RimGridView* view); - RimGridView* masterView() const; + RimGridView* masterView() const; RimViewLinker* ownerViewLinker() const; const RigCaseToCaseCellMapper* cellMapper(); @@ -77,16 +78,16 @@ class RimViewController : public caf::PdmObject void updateRangeFilterOverrides(RimCellRangeFilter* changedRangeFilter); void applyRangeFilterCollectionByUserChoice(); - + void updatePropertyFilterOverrides(RimPropertyFilter* changedPropertyFilter); protected: // Pdm overridden methods - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual caf::PdmFieldHandle* userDescriptionField() { return &m_name; } - virtual caf::PdmFieldHandle* objectToggleField() { return &m_isActive; } + caf::PdmFieldHandle* userDescriptionField() override { return &m_name; } + caf::PdmFieldHandle* objectToggleField() override { return &m_isActive; } private: void updateCameraLink(); @@ -94,10 +95,16 @@ class RimViewController : public caf::PdmObject void updateResultColorsControl(); void updateLegendDefinitions(); + void updateDefaultOptions(); + + bool isCameraControlPossible() const; bool isMasterAndDepViewDifferentType() const; bool isRangeFilterControlPossible() const; bool isPropertyFilterControlPossible() const; - bool isRangeFilterMappingApliccable() const; + bool isRangeFilterMappingApplicable() const; + bool isCellResultControlAdvisable() const; + bool isRangeFilterControlAdvisable() const; + bool isPropertyFilterControlAdvisable() const; RimEclipseView* managedEclipseView() const; RimGeoMechView* managedGeoView() const; @@ -107,7 +114,7 @@ class RimViewController : public caf::PdmObject private: caf::PdmField m_name; - caf::PdmPtrField m_managedView; + caf::PdmPtrField m_managedView; caf::PdmField m_isActive; caf::PdmField m_syncCamera; diff --git a/ApplicationCode/ProjectDataModel/RimViewLinker.cpp b/ApplicationCode/ProjectDataModel/RimViewLinker.cpp index 25dc2d4126..77d192bd2e 100644 --- a/ApplicationCode/ProjectDataModel/RimViewLinker.cpp +++ b/ApplicationCode/ProjectDataModel/RimViewLinker.cpp @@ -2,17 +2,17 @@ // // Copyright (C) 2015- Statoil ASA // Copyright (C) 2015- 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -23,6 +23,7 @@ #include "RigMainGrid.h" +#include "Rim3dView.h" #include "RimCase.h" #include "RimEclipseCellColors.h" #include "RimEclipseInputCase.h" @@ -34,29 +35,27 @@ #include "RimGeoMechResultDefinition.h" #include "RimGeoMechView.h" #include "RimIntersectionCollection.h" -#include "RimRegularLegendConfig.h" #include "RimProject.h" +#include "RimRegularLegendConfig.h" #include "RimTernaryLegendConfig.h" -#include "Rim3dView.h" #include "RimViewController.h" #include "RimViewLinkerCollection.h" #include "RimViewManipulator.h" #include "RiuViewer.h" +#include "cafPdmUiTreeOrdering.h" #include "cvfCamera.h" -#include "cvfScene.h" #include "cvfMatrix4.h" -#include "cafPdmUiTreeOrdering.h" - - +#include "cvfScene.h" CAF_PDM_SOURCE_INIT(RimViewLinker, "ViewLinker"); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimViewLinker::RimViewLinker(void) +RimViewLinker::RimViewLinker() { + // clang-format off CAF_PDM_InitObject("Linked Views", "", "", ""); CAF_PDM_InitField(&m_name, "Name", QString("View Group Name"), "View Group Name", "", "", ""); @@ -69,12 +68,13 @@ RimViewLinker::RimViewLinker(void) CAF_PDM_InitFieldNoDefault(&m_viewControllers, "ManagedViews", "Managed Views", "", "", ""); m_viewControllers.uiCapability()->setUiHidden(true); m_viewControllers.uiCapability()->setUiTreeChildrenHidden(true); + // clang-format on } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RimViewLinker::~RimViewLinker(void) +RimViewLinker::~RimViewLinker() { removeOverrides(); @@ -82,7 +82,7 @@ RimViewLinker::~RimViewLinker(void) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateTimeStep(RimGridView* sourceView, int timeStep) { @@ -106,15 +106,11 @@ void RimViewLinker::updateTimeStep(RimGridView* sourceView, int timeStep) m_masterView->viewer()->setCurrentFrame(timeStep); } - for (size_t i = 0; i < m_viewControllers.size(); i++) + for (RimViewController* viewLink : m_viewControllers) { - RimViewController* viewLink = m_viewControllers[i]; - if (!viewLink->isTimeStepLinked()) continue; - if ( viewLink->managedView() - && viewLink->managedView() != sourceView - && viewLink->managedView()->viewer()) + if (viewLink->managedView() && viewLink->managedView() != sourceView && viewLink->managedView()->viewer()) { viewLink->managedView()->viewer()->setCurrentFrame(timeStep); } @@ -122,24 +118,22 @@ void RimViewLinker::updateTimeStep(RimGridView* sourceView, int timeStep) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateCellResult() { - Rim3dView* rimView = m_masterView; + Rim3dView* rimView = m_masterView; RimEclipseView* masterEclipseView = dynamic_cast(rimView); if (masterEclipseView && masterEclipseView->cellResult()) { RimEclipseResultDefinition* eclipseCellResultDefinition = masterEclipseView->cellResult(); - for (size_t i = 0; i < m_viewControllers.size(); i++) + for (RimViewController* viewLink : m_viewControllers) { - RimViewController* viewLink = m_viewControllers[i]; - if (viewLink->managedView()) { - Rim3dView* rimView = viewLink->managedView(); - RimEclipseView* eclipseView = dynamic_cast(rimView); + Rim3dView* managedView = viewLink->managedView(); + RimEclipseView* eclipseView = dynamic_cast(managedView); if (eclipseView) { if (viewLink->isResultColorControlled()) @@ -149,16 +143,18 @@ void RimViewLinker::updateCellResult() if (viewLink->isLegendDefinitionsControlled()) { - eclipseView->cellResult()->legendConfig()->setUiValuesFromLegendConfig(masterEclipseView->cellResult()->legendConfig()); + eclipseView->cellResult()->legendConfig()->setUiValuesFromLegendConfig( + masterEclipseView->cellResult()->legendConfig()); eclipseView->cellResult()->legendConfig()->updateLegend(); - eclipseView->cellResult()->ternaryLegendConfig()->setUiValuesFromLegendConfig(masterEclipseView->cellResult()->ternaryLegendConfig()); + eclipseView->cellResult()->ternaryLegendConfig()->setUiValuesFromLegendConfig( + masterEclipseView->cellResult()->ternaryLegendConfig()); } eclipseView->scheduleCreateDisplayModelAndRedraw(); eclipseView->crossSectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews(); } - + eclipseView->cellResult()->updateIconState(); } } @@ -170,14 +166,12 @@ void RimViewLinker::updateCellResult() { RimGeoMechResultDefinition* geoMechResultDefinition = masterGeoView->cellResult(); - for (size_t i = 0; i < m_viewControllers.size(); i++) + for (RimViewController* viewLink : m_viewControllers) { - RimViewController* viewLink = m_viewControllers[i]; - if (viewLink->managedView()) { - Rim3dView* rimView = viewLink->managedView(); - RimGeoMechView* geoView = dynamic_cast(rimView); + Rim3dView* managedView = viewLink->managedView(); + RimGeoMechView* geoView = dynamic_cast(managedView); if (geoView) { if (viewLink->isResultColorControlled()) @@ -186,7 +180,8 @@ void RimViewLinker::updateCellResult() if (viewLink->isLegendDefinitionsControlled()) { - geoView->cellResult()->legendConfig()->setUiValuesFromLegendConfig(masterGeoView->cellResult()->legendConfig()); + geoView->cellResult()->legendConfig()->setUiValuesFromLegendConfig( + masterGeoView->cellResult()->legendConfig()); geoView->cellResult()->legendConfig()->updateLegend(); } @@ -202,25 +197,23 @@ void RimViewLinker::updateCellResult() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateRangeFilters(RimCellRangeFilter* changedRangeFilter) { - for (size_t i = 0; i < m_viewControllers.size(); i++) + for (RimViewController* viewLink : m_viewControllers) { - RimViewController* viewLink = m_viewControllers[i]; viewLink->updateRangeFilterOverrides(changedRangeFilter); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateOverrides() { - for (size_t i = 0; i < m_viewControllers.size(); i++) + for (RimViewController* viewLink : m_viewControllers) { - RimViewController* viewLink = m_viewControllers[i]; if (viewLink->isActive()) { viewLink->updateOverrides(); @@ -233,21 +226,21 @@ void RimViewLinker::updateOverrides() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::removeOverrides() { - for (size_t i = 0; i < m_viewControllers.size(); i++) + for (const auto& viewController : m_viewControllers) { - if (m_viewControllers[i]->managedView()) + if (viewController->managedView()) { - m_viewControllers[i]->removeOverrides(); + viewController->removeOverrides(); } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::allViewsForCameraSync(const RimGridView* source, std::vector& views) const { @@ -258,20 +251,20 @@ void RimViewLinker::allViewsForCameraSync(const RimGridView* source, std::vector views.push_back(m_masterView()); } - for (size_t i = 0; i < m_viewControllers.size(); i++) + for (const auto& viewController : m_viewControllers) { - if (m_viewControllers[i]->managedView() && source != m_viewControllers[i]->managedView()) + if (viewController->managedView() && source != viewController->managedView()) { - if (m_viewControllers[i]->isCameraLinked()) + if (viewController->isCameraLinked()) { - views.push_back(m_viewControllers[i]->managedView()); + views.push_back(viewController->managedView()); } } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateDependentViews() { @@ -283,7 +276,7 @@ void RimViewLinker::updateDependentViews() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QString RimViewLinker::displayNameForView(RimGridView* view) { @@ -295,7 +288,7 @@ QString RimViewLinker::displayNameForView(RimGridView* view) view->firstAncestorOrThisOfType(rimCase); if (rimCase) { - displayName = rimCase->caseUserDescription() + ": " + view->name; + displayName = rimCase->caseUserDescription() + ": " + view->name(); } } @@ -303,7 +296,7 @@ QString RimViewLinker::displayNameForView(RimGridView* view) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::setMasterView(RimGridView* view) { @@ -324,7 +317,7 @@ void RimViewLinker::setMasterView(RimGridView* view) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RimGridView* RimViewLinker::masterView() const { @@ -332,23 +325,23 @@ RimGridView* RimViewLinker::masterView() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::allViews(std::vector& views) const { views.push_back(m_masterView()); - for (size_t i = 0; i < m_viewControllers.size(); i++) + for (const auto& viewController : m_viewControllers) { - if (m_viewControllers[i]->managedView()) + if (viewController->managedView()) { - views.push_back(m_viewControllers[i]->managedView()); + views.push_back(viewController->managedView()); } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::initAfterRead() { @@ -356,7 +349,7 @@ void RimViewLinker::initAfterRead() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateScaleZ(RimGridView* sourceView, double scaleZ) { @@ -377,20 +370,20 @@ void RimViewLinker::updateScaleZ(RimGridView* sourceView, double scaleZ) allViewsForCameraSync(sourceView, views); // Make sure scale factors are identical - for (size_t i = 0; i < views.size(); i++) + for (auto& view : views) { - views[i]->setScaleZAndUpdate(scaleZ); + view->setScaleZAndUpdate(scaleZ); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RimViewLinker::isActive() const { RimViewLinkerCollection* viewLinkerCollection = nullptr; this->firstAncestorOrThisOfType(viewLinkerCollection); - + if (!viewLinkerCollection) { // This will happen when the all linked views are about to be deleted @@ -420,9 +413,8 @@ void RimViewLinker::applyIconEnabledState(caf::PdmObject* obj, const QIcon& icon obj->setUiIcon(newIcon); } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateUiNameAndIcon() { @@ -431,30 +423,29 @@ void RimViewLinker::updateUiNameAndIcon() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType) { - for (size_t i = 0; i < m_viewControllers.size(); i++) + for (const auto& viewController : m_viewControllers) { - m_viewControllers[i]->scheduleGeometryRegenForDepViews(geometryType); + viewController->scheduleGeometryRegenForDepViews(geometryType); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::scheduleCreateDisplayModelAndRedrawForDependentViews() { - for (size_t i = 0; i < m_viewControllers.size(); i++) + for (const auto& viewController : m_viewControllers) { - m_viewControllers[i]->scheduleCreateDisplayModelAndRedrawForDependentView(); + viewController->scheduleCreateDisplayModelAndRedrawForDependentView(); } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::findNameAndIconFromView(QString* name, QIcon* icon, RimGridView* view) { @@ -487,7 +478,7 @@ void RimViewLinker::findNameAndIconFromView(QString* name, QIcon* icon, RimGridV } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateCursorPosition(const RimGridView* sourceView, const cvf::Vec3d& domainCoord) { @@ -521,12 +512,12 @@ void RimViewLinker::updateCursorPosition(const RimGridView* sourceView, const cv } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::updateCamera(RimGridView* sourceView) { if (!sourceView->viewer()) return; - + if (!isActive()) return; RimViewController* viewLink = sourceView->viewController(); @@ -545,12 +536,12 @@ void RimViewLinker::updateCamera(RimGridView* sourceView) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::addDependentView(RimGridView* view) { CVF_ASSERT(view && view != m_masterView); - + RimViewController* viewContr = new RimViewController; this->m_viewControllers.push_back(viewContr); @@ -558,32 +549,57 @@ void RimViewLinker::addDependentView(RimGridView* view) } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +bool RimViewLinker::isFirstViewDependentOnSecondView(const RimGridView* firstView, const RimGridView* secondView) const +{ + for (const RimViewController* controller : m_viewControllers()) + { + if (controller->masterView() == secondView && controller->managedView() == firstView) + { + return true; + } + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::addViewControllers(caf::PdmUiTreeOrdering& uiTreeOrdering) const { - for (size_t j = 0; j < m_viewControllers.size(); j++) + for (const auto& viewController : m_viewControllers) { - uiTreeOrdering.add(m_viewControllers[j]); + uiTreeOrdering.add(viewController); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::applyRangeFilterCollectionByUserChoice() { - for (size_t j = 0; j < m_viewControllers.size(); j++) + for (const auto& viewController : m_viewControllers) { - m_viewControllers[j]->applyRangeFilterCollectionByUserChoice(); + viewController->applyRangeFilterCollectionByUserChoice(); } } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void RimViewLinker::updatePropertyFilters(RimPropertyFilter* changedPropertyFilter) +{ + for (RimViewController* viewLink : m_viewControllers) + { + viewLink->updatePropertyFilterOverrides(changedPropertyFilter); + } +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RimViewLinker::removeViewController(RimViewController* viewController) { m_viewControllers.removeChildObject(viewController); } - diff --git a/ApplicationCode/ProjectDataModel/RimViewLinker.h b/ApplicationCode/ProjectDataModel/RimViewLinker.h index acffd56229..a63002c683 100644 --- a/ApplicationCode/ProjectDataModel/RimViewLinker.h +++ b/ApplicationCode/ProjectDataModel/RimViewLinker.h @@ -38,6 +38,7 @@ class RimViewController; class RiuViewer; class RimGridView; class RimCellRangeFilter; +class RimPropertyFilter; //================================================================================================== /// @@ -48,15 +49,15 @@ class RimViewLinker : public caf::PdmObject CAF_PDM_HEADER_INIT; public: - RimViewLinker(void); - virtual ~RimViewLinker(void); + RimViewLinker(); + ~RimViewLinker() override; bool isActive() const; void setMasterView(RimGridView* view); - RimGridView* masterView() const; - + RimGridView* masterView() const; void addDependentView(RimGridView* view); + bool isFirstViewDependentOnSecondView(const RimGridView* firstView, const RimGridView* secondView) const; void updateDependentViews(); void removeViewController(RimViewController* viewController); @@ -71,6 +72,8 @@ class RimViewLinker : public caf::PdmObject void updateRangeFilters(RimCellRangeFilter* changedRangeFilter); void applyRangeFilterCollectionByUserChoice(); + void updatePropertyFilters(RimPropertyFilter* changedPropertyFilter); + void scheduleGeometryRegenForDepViews(RivCellSetEnum geometryType); void scheduleCreateDisplayModelAndRedrawForDependentViews(); @@ -85,21 +88,20 @@ class RimViewLinker : public caf::PdmObject void updateCursorPosition(const RimGridView* sourceView, const cvf::Vec3d& domainCoord); -public: - static QString displayNameForView(RimGridView* view); - protected: - virtual caf::PdmFieldHandle* userDescriptionField() { return &m_name; } - virtual void initAfterRead(); + caf::PdmFieldHandle* userDescriptionField() override { return &m_name; } + void initAfterRead() override; private: + static QString displayNameForView(RimGridView* view); + void allViewsForCameraSync(const RimGridView* source, std::vector& views) const; void removeOverrides(); private: caf::PdmChildArrayField m_viewControllers; - caf::PdmPtrField m_masterView; + caf::PdmPtrField m_masterView; caf::PdmField m_name; QIcon m_originalIcon; }; diff --git a/ApplicationCode/ProjectDataModel/RimViewLinkerCollection.h b/ApplicationCode/ProjectDataModel/RimViewLinkerCollection.h index 11fb5c90c4..27edf23611 100644 --- a/ApplicationCode/ProjectDataModel/RimViewLinkerCollection.h +++ b/ApplicationCode/ProjectDataModel/RimViewLinkerCollection.h @@ -36,14 +36,14 @@ class RimViewLinkerCollection : public caf::PdmObject public: RimViewLinkerCollection(void); - virtual ~RimViewLinkerCollection(void); + ~RimViewLinkerCollection(void) override; caf::PdmField isActive; caf::PdmChildField viewLinker; protected: - virtual caf::PdmFieldHandle* objectToggleField() { return &isActive; } - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = ""); - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual void initAfterRead(); + caf::PdmFieldHandle* objectToggleField() override { return &isActive; } + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void initAfterRead() override; }; diff --git a/ApplicationCode/ProjectDataModel/RimViewWindow.cpp b/ApplicationCode/ProjectDataModel/RimViewWindow.cpp index b0e995cee3..72bfa65042 100644 --- a/ApplicationCode/ProjectDataModel/RimViewWindow.cpp +++ b/ApplicationCode/ProjectDataModel/RimViewWindow.cpp @@ -17,8 +17,13 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimViewWindow.h" + +#include "RiaFieldHandleTools.h" + #include "RimMdiWindowController.h" + #include "cvfAssert.h" + #include CAF_PDM_XML_ABSTRACT_SOURCE_INIT(RimViewWindow, "ViewWindow"); // Do not use. Abstract class @@ -37,8 +42,7 @@ RimViewWindow::RimViewWindow(void) // Obsolete field CAF_PDM_InitFieldNoDefault(&obsoleteField_windowGeometry, "WindowGeometry", "", "", "", ""); - obsoleteField_windowGeometry.uiCapability()->setUiHidden(true); - obsoleteField_windowGeometry.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&obsoleteField_windowGeometry); } //-------------------------------------------------------------------------------------------------- @@ -65,6 +69,23 @@ void RimViewWindow::removeMdiWindowFromMdiArea() if ( m_windowController() ) m_windowController->removeWindowFromMDI(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimViewWindow::windowTitle() +{ + if (this->userDescriptionField()) + { + caf::PdmUiFieldHandle* uiFieldHandle = this->userDescriptionField()->uiCapability(); + if (uiFieldHandle) + { + QVariant v = uiFieldHandle->uiValue(); + return v.toString(); + } + } + return QString(""); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -168,15 +189,7 @@ void RimViewWindow::updateMdiWindowTitle() { if ( viewWidget() ) { - if ( this->userDescriptionField() ) - { - caf::PdmUiFieldHandle* uiFieldHandle = this->userDescriptionField()->uiCapability(); - if ( uiFieldHandle ) - { - QVariant v = uiFieldHandle->uiValue(); - viewWidget()->setWindowTitle(v.toString()); - } - } + viewWidget()->setWindowTitle(windowTitle()); } } diff --git a/ApplicationCode/ProjectDataModel/RimViewWindow.h b/ApplicationCode/ProjectDataModel/RimViewWindow.h index 3583aea248..aae0500e23 100644 --- a/ApplicationCode/ProjectDataModel/RimViewWindow.h +++ b/ApplicationCode/ProjectDataModel/RimViewWindow.h @@ -45,7 +45,7 @@ class RimViewWindow : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimViewWindow(void); - virtual ~RimViewWindow(void); + ~RimViewWindow(void) override; void loadDataAndUpdate(); void handleMdiWindowClosed(); @@ -69,6 +69,7 @@ class RimViewWindow : public caf::PdmObject ///////// Interface for the Window controller friend class RimMdiWindowController; + QString windowTitle(); virtual QWidget* createViewWidget(QWidget* mainWindowParent) = 0; virtual void updateViewWidgetAfterCreation() {}; virtual void updateMdiWindowTitle(); // Has real default implementation @@ -80,9 +81,9 @@ class RimViewWindow : public caf::PdmObject // Derived classes are not supposed to override this function. The intention is to always use m_showWindow // as the objectToggleField for this class. This way the visibility of a widget being part of a composite widget // can be controlled from the project tree using check box toggles - virtual caf::PdmFieldHandle* objectToggleField() override final; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void initAfterRead() override; + caf::PdmFieldHandle* objectToggleField() final; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void initAfterRead() override; caf::PdmField m_showWindow; diff --git a/ApplicationCode/ProjectDataModel/RimVirtualPerforationResults.h b/ApplicationCode/ProjectDataModel/RimVirtualPerforationResults.h index 6f1b6abeb9..c536a56738 100644 --- a/ApplicationCode/ProjectDataModel/RimVirtualPerforationResults.h +++ b/ApplicationCode/ProjectDataModel/RimVirtualPerforationResults.h @@ -36,7 +36,7 @@ class RimVirtualPerforationResults : public caf::PdmObject public: RimVirtualPerforationResults(); - virtual ~RimVirtualPerforationResults(); + ~RimVirtualPerforationResults() override; bool showConnectionFactors() const; bool showConnectionFactorsOnClosedConnections() const; @@ -45,10 +45,10 @@ class RimVirtualPerforationResults : public caf::PdmObject void loadData(); private: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual caf::PdmFieldHandle* objectToggleField() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void initAfterRead() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + caf::PdmFieldHandle* objectToggleField() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void initAfterRead() override; private: caf::PdmField m_isActive; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogCurve.cpp index 2edbead991..21c952f68c 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogCurve.cpp @@ -24,7 +24,7 @@ #include "RimWellLogPlot.h" #include "RimWellLogTrack.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuWellLogTrack.h" #include "cafPdmUiComboBoxEditor.h" @@ -56,46 +56,23 @@ RimWellLogCurve::~RimWellLogCurve() { } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -bool RimWellLogCurve::depthRange(double* minimumDepth, double* maximumDepth) const +bool RimWellLogCurve::valueRange(double* minimumValue, double* maximumValue) const { - CVF_ASSERT(minimumDepth && maximumDepth); - CVF_ASSERT(m_qwtPlotCurve); - - if (m_qwtPlotCurve->data()->size() < 1) - { - return false; - } - - *minimumDepth = m_qwtPlotCurve->minYValue(); - *maximumDepth = m_qwtPlotCurve->maxYValue(); - - return true; + return xValueRange(minimumValue, maximumValue); } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimWellLogCurve::valueRange(double* minimumValue, double* maximumValue) const +const RigWellLogCurveData* RimWellLogCurve::curveData() const { - CVF_ASSERT(minimumValue && maximumValue); - CVF_ASSERT(m_qwtPlotCurve); - - if (m_qwtPlotCurve->data()->size() < 1) - { - return false; - } - - *minimumValue = m_qwtPlotCurve->minXValue(); - *maximumValue = m_qwtPlotCurve->maxXValue(); - - return true; + return m_curveData.p(); } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -113,15 +90,20 @@ void RimWellLogCurve::updateZoomInParentPlot() firstAncestorOrThisOfType(plotTrack); if (plotTrack) { - plotTrack->updateXZoomAndParentPlotDepthZoom(); + plotTrack->calculateXZoomRangeAndUpdateQwt(); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const RigWellLogCurveData* RimWellLogCurve::curveData() const +void RimWellLogCurve::updateLegendsInPlot() { - return m_curveData.p(); + RimWellLogTrack* wellLogTrack; + firstAncestorOrThisOfType(wellLogTrack); + if (wellLogTrack) + { + wellLogTrack->updateAllLegendItems(); + } } diff --git a/ApplicationCode/ProjectDataModel/RimWellLogCurve.h b/ApplicationCode/ProjectDataModel/RimWellLogCurve.h index 68a6f65653..08461ccd40 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogCurve.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogCurve.h @@ -36,9 +36,8 @@ class RimWellLogCurve : public RimPlotCurve public: RimWellLogCurve(); - virtual ~RimWellLogCurve(); + ~RimWellLogCurve() override; - bool depthRange(double* minimumDepth, double* maximumDepth) const; bool valueRange(double* minimumValue, double* maximumValue) const; const RigWellLogCurveData* curveData() const; @@ -48,7 +47,9 @@ class RimWellLogCurve : public RimPlotCurve virtual QString wellDate() const { return ""; }; protected: - virtual void updateZoomInParentPlot(); + void updateZoomInParentPlot() override; + void updateLegendsInPlot() override; - cvf::ref m_curveData; +protected: + cvf::ref m_curveData; }; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogCurveCommonDataSource.cpp b/ApplicationCode/ProjectDataModel/RimWellLogCurveCommonDataSource.cpp new file mode 100644 index 0000000000..e93eccd56d --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogCurveCommonDataSource.cpp @@ -0,0 +1,736 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogCurveCommonDataSource.h" + +#include "RimCase.h" +#include "RimDataSourceSteppingTools.h" +#include "RimEclipseCase.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimTools.h" +#include "RimWellLogExtractionCurve.h" +#include "RimWellLogFileCurve.h" +#include "RimWellLogPlot.h" +#include "RimWellLogPlotCollection.h" +#include "RimWellLogTrack.h" +#include "RimWellPath.h" +#include "RimWellPathCollection.h" + +#include "RiaApplication.h" +#include "RiaSimWellBranchTools.h" + +#include "cafPdmUiCheckBoxTristateEditor.h" +#include "cafPdmUiComboBoxEditor.h" + +CAF_PDM_SOURCE_INIT(RimWellLogCurveCommonDataSource, "ChangeDataSourceFeatureUi"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogCurveCommonDataSource::RimWellLogCurveCommonDataSource() +{ + CAF_PDM_InitObject("Change Data Source", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_case, "CurveCase", "Case", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_trajectoryType, "TrajectoryType", "Trajectory Type", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_wellPath, "CurveWellPath", "Well Name", "", "", ""); + + CAF_PDM_InitField(&m_simWellName, "SimulationWellName", QString("None"), "Well Name", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_branchDetection, "BranchDetection", "Branch Detection", "", + "Compute branches based on how simulation well cells are organized", ""); + m_branchDetection.v() = caf::Tristate::State::PartiallyTrue; + m_branchDetection.uiCapability()->setUiEditorTypeName(caf::PdmUiCheckBoxTristateEditor::uiEditorTypeName()); + CAF_PDM_InitField(&m_branchIndex, "Branch", -1, "Branch Index", "", "", ""); + + CAF_PDM_InitField(&m_timeStep, "CurveTimeStep", -1, "Time Step", "", "", ""); + + m_case = nullptr; + m_wellPath = nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimCase* RimWellLogCurveCommonDataSource::caseToApply() const +{ + return m_case; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::setCaseToApply(RimCase* val) +{ + m_case = val; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimWellLogCurveCommonDataSource::trajectoryTypeToApply() const +{ + return m_trajectoryType(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::setTrajectoryTypeToApply(int val) +{ + m_trajectoryType = val; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RimWellLogCurveCommonDataSource::wellPathToApply() const +{ + return m_wellPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::setWellPathToApply(RimWellPath* val) +{ + m_wellPath = val; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::setBranchIndexToApply(int val) +{ + m_branchIndex = val; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::setBranchDetectionToApply(caf::Tristate::State val) +{ + m_branchDetection.v() = val; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogCurveCommonDataSource::simWellNameToApply() const +{ + return m_simWellName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::setSimWellNameToApply(const QString& val) +{ + m_simWellName = val; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimWellLogCurveCommonDataSource::timeStepToApply() const +{ + return m_timeStep; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::setTimeStepToApply(int val) +{ + m_timeStep = val; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::resetDefaultOptions() +{ + setCaseToApply(nullptr); + setTrajectoryTypeToApply(-1); + setWellPathToApply(nullptr); + setBranchIndexToApply(-1); + setBranchDetectionToApply(caf::Tristate::State::PartiallyTrue); + setSimWellNameToApply(QString("")); + setTimeStepToApply(-1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::updateDefaultOptions(const std::vector& curves, const std::vector& tracks) +{ + // Reset all options in the UI + resetDefaultOptions(); + + // Check to see if the parameters are unique + std::set uniqueCases; + std::set uniqueTrajectoryTypes; + std::set uniqueWellPaths; + std::set uniqueWellNames; + std::set uniqueTimeSteps; + std::set uniqueBranchDetection; + std::set uniqueBranchIndex; + for (RimWellLogCurve* curve : curves) + { + if (!curve->isCurveVisible()) + { + continue; + } + RimWellLogExtractionCurve* extractionCurve = dynamic_cast(curve); + RimWellLogFileCurve* fileCurve = dynamic_cast(curve); + if (extractionCurve) + { + uniqueCases.insert(extractionCurve->rimCase()); + uniqueTrajectoryTypes.insert(static_cast(extractionCurve->trajectoryType())); + uniqueWellPaths.insert(extractionCurve->wellPath()); + uniqueWellNames.insert(extractionCurve->wellName()); + uniqueTimeSteps.insert(extractionCurve->currentTimeStep()); + uniqueBranchDetection.insert(extractionCurve->branchDetection()); + uniqueBranchIndex.insert(extractionCurve->branchIndex()); + } + else if (fileCurve) + { + uniqueWellPaths.insert(fileCurve->wellPath()); + uniqueWellNames.insert(fileCurve->wellName()); + } + } + for (RimWellLogTrack* track : tracks) + { + if (track->showWellPathAttributes()) + { + uniqueTrajectoryTypes.insert(static_cast(RimWellLogExtractionCurve::WELL_PATH)); + uniqueWellPaths.insert(track->wellPathAttributeSource()); + } + if (track->showFormations()) + { + uniqueCases.insert(track->formationNamesCase()); + uniqueWellPaths.insert(track->formationWellPath()); + } + } + + + if (uniqueCases.size() == 1u) + { + setCaseToApply(*uniqueCases.begin()); + } + + if (uniqueTrajectoryTypes.size() == 1u) + { + m_trajectoryType = *uniqueTrajectoryTypes.begin(); + + if (uniqueWellPaths.size() == 1u) + { + setWellPathToApply(*uniqueWellPaths.begin()); + } + if (uniqueBranchIndex.size() == 1u) + { + setBranchIndexToApply(*uniqueBranchIndex.begin()); + } + if (uniqueBranchDetection.size() == 1u) + { + setBranchDetectionToApply(*uniqueBranchDetection.begin() == true ? + caf::Tristate::State::True : caf::Tristate::State::False); + } + if (uniqueWellNames.size() == 1u) + { + setSimWellNameToApply(*uniqueWellNames.begin()); + } + } + + if (uniqueTimeSteps.size() == 1u) + { + setTimeStepToApply(*uniqueTimeSteps.begin()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::updateDefaultOptions() +{ + RimWellLogPlot* parentPlot = nullptr; + this->firstAncestorOrThisOfType(parentPlot); + if (parentPlot) + { + std::vector curves; + parentPlot->descendantsIncludingThisOfType(curves); + + std::vector tracks; + parentPlot->descendantsIncludingThisOfType(tracks); + + this->updateDefaultOptions(curves, tracks); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::updateCurvesAndTracks(std::vector& curves, std::vector& tracks) +{ + std::set plots; + for (RimWellLogCurve* curve : curves) + { + if (!curve->isCurveVisible()) + { + continue; + } + RimWellLogFileCurve* fileCurve = dynamic_cast(curve); + RimWellLogExtractionCurve* extractionCurve = dynamic_cast(curve); + if (fileCurve) + { + if (wellPathToApply() != nullptr) + { + fileCurve->setWellPath(wellPathToApply()); + if (!fileCurve->wellLogChannelName().isEmpty()) + { + RimWellLogFile* logFile = wellPathToApply()->firstWellLogFileMatchingChannelName(fileCurve->wellLogChannelName()); + fileCurve->setWellLogFile(logFile); + RimWellLogPlot* parentPlot = nullptr; + fileCurve->firstAncestorOrThisOfTypeAsserted(parentPlot); + plots.insert(parentPlot); + } + } + } + else if (extractionCurve) + { + bool updatedSomething = false; + if (caseToApply() != nullptr) + { + extractionCurve->setCase(caseToApply()); + updatedSomething = true; + } + + if (wellPathToApply() != nullptr) + { + extractionCurve->setWellPath(wellPathToApply()); + updatedSomething = true; + } + + if (m_trajectoryType() != -1) + { + extractionCurve->setTrajectoryType(static_cast(m_trajectoryType())); + if (m_trajectoryType() == (int)RimWellLogExtractionCurve::SIMULATION_WELL) + { + + if (m_branchDetection().isTrue()) + { + extractionCurve->setBranchDetection(true); + } + else if (m_branchDetection().isFalse()) + { + extractionCurve->setBranchDetection(false); + } + + if (m_branchIndex() != -1) + { + extractionCurve->setBranchIndex(m_branchIndex()); + } + if (m_simWellName() != QString("")) + { + extractionCurve->setWellName(m_simWellName()); + } + } + updatedSomething = true; + } + + if (timeStepToApply() != -1) + { + extractionCurve->setCurrentTimeStep(timeStepToApply()); + updatedSomething = true; + } + + if (updatedSomething) + { + RimWellLogPlot* parentPlot = nullptr; + extractionCurve->firstAncestorOrThisOfTypeAsserted(parentPlot); + plots.insert(parentPlot); + curve->updateConnectedEditors(); + } + } + } + + for (RimWellLogTrack* track : tracks) + { + bool updatedSomething = false; + if (caseToApply() != nullptr) + { + if (track->showFormations()) + { + track->setFormationCase(caseToApply()); + updatedSomething = true; + } + } + + if (wellPathToApply() != nullptr) + { + if (track->showWellPathAttributes()) + { + track->setWellPathAttributesSource(wellPathToApply()); + updatedSomething = true; + } + if (track->showFormations()) + { + track->setFormationWellPath(wellPathToApply()); + updatedSomething = true; + } + } + + if (updatedSomething) + { + RimWellLogPlot* parentPlot = nullptr; + track->firstAncestorOrThisOfTypeAsserted(parentPlot); + plots.insert(parentPlot); + track->updateConnectedEditors(); + } + } + + for (RimWellLogPlot* plot : plots) + { + plot->loadDataAndUpdate(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::updateCurvesAndTracks() +{ + RimWellLogPlot* parentPlot = nullptr; + this->firstAncestorOrThisOfType(parentPlot); + if (parentPlot) + { + std::vector curves; + parentPlot->descendantsIncludingThisOfType(curves); + + std::vector tracks; + parentPlot->descendantsIncludingThisOfType(tracks); + + this->updateCurvesAndTracks(curves, tracks); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::applyPrevCase() +{ + modifyCurrentIndex(&m_case, -1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::applyNextCase() +{ + modifyCurrentIndex(&m_case, 1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::applyPrevWell() +{ + if (m_trajectoryType() == RimWellLogExtractionCurve::WELL_PATH) + { + modifyCurrentIndex(&m_wellPath, -1); + } + else if (m_trajectoryType() == RimWellLogExtractionCurve::SIMULATION_WELL) + { + modifyCurrentIndex(&m_simWellName, -1); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::applyNextWell() +{ + if (m_trajectoryType() == RimWellLogExtractionCurve::WELL_PATH) + { + modifyCurrentIndex(&m_wellPath, 1); + } + else if (m_trajectoryType() == RimWellLogExtractionCurve::SIMULATION_WELL) + { + modifyCurrentIndex(&m_simWellName, 1); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::applyPrevTimeStep() +{ + modifyCurrentIndex(&m_timeStep, -1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::applyNextTimeStep() +{ + modifyCurrentIndex(&m_timeStep, 1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellLogCurveCommonDataSource::fieldsToShowInToolbar() +{ + updateDefaultOptions(); + + std::vector fieldsToDisplay; + fieldsToDisplay.push_back(&m_case); + if (trajectoryTypeToApply() == RimWellLogExtractionCurve::WELL_PATH) + { + fieldsToDisplay.push_back(&m_wellPath); + } + else if (trajectoryTypeToApply() == RimWellLogExtractionCurve::SIMULATION_WELL) + { + fieldsToDisplay.push_back(&m_simWellName); + } + fieldsToDisplay.push_back(&m_timeStep); + + return fieldsToDisplay; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + RimWellLogPlot* parentPlot = nullptr; + this->firstAncestorOrThisOfType(parentPlot); + + if (changedField == &m_branchDetection) + { + if (m_branchDetection().isPartiallyTrue()) + { + // The Tristate is cycled from false -> partially true -> true + // Partially true is used for "Mixed state" and is not settable by the user so cycle on to true. + m_branchDetection.v() = caf::Tristate::State::True; + } + } + + this->updateCurvesAndTracks(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimWellLogCurveCommonDataSource::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) +{ + QList options; + + this->updateDefaultOptions(); + + if (fieldNeedingOptions == &m_case) + { + RimTools::caseOptionItems(&options); + + if (caseToApply() == nullptr) + { + options.push_front(caf::PdmOptionItemInfo("Mixed Cases", nullptr)); + } + } + else if (fieldNeedingOptions == &m_trajectoryType) + { + if (m_trajectoryType() == -1) + { + options.push_back(caf::PdmOptionItemInfo("Mixed Trajectory Types", -1)); + } + std::vector trajectoryTypes = + { RimWellLogExtractionCurve::WELL_PATH, RimWellLogExtractionCurve::SIMULATION_WELL }; + for (RimWellLogExtractionCurve::TrajectoryType trajectoryType : trajectoryTypes) + { + caf::PdmOptionItemInfo item(caf::AppEnum::uiText(trajectoryType), + static_cast(trajectoryType)); + options.push_back(item); + } + } + else if (fieldNeedingOptions == &m_wellPath) + { + RimTools::wellPathOptionItems(&options); + if (wellPathToApply() == nullptr) + { + options.push_front(caf::PdmOptionItemInfo("Mixed Well Paths", nullptr)); + } + + } + else if (fieldNeedingOptions == &m_timeStep) + { + QStringList timeStepNames; + + if (m_case) + { + timeStepNames = m_case->timeStepStrings(); + } + + for (int i = 0; i < timeStepNames.size(); i++) + { + options.push_back(caf::PdmOptionItemInfo(timeStepNames[i], i)); + } + + if (timeStepToApply() == -1) + { + options.push_front(caf::PdmOptionItemInfo("Mixed Time Steps", -1)); + } + } + else if (fieldNeedingOptions == &m_simWellName) + { + RimEclipseCase* eclipseCase = dynamic_cast(m_case()); + if (eclipseCase) + { + std::set sortedWellNames = eclipseCase->sortedSimWellNames(); + + QIcon simWellIcon(":/Well.png"); + for (const QString& wname : sortedWellNames) + { + options.push_back(caf::PdmOptionItemInfo(wname, wname, false, simWellIcon)); + } + + if (options.size() == 0) + { + options.push_front(caf::PdmOptionItemInfo("None", "None")); + } + + if (m_simWellName == QString("")) + { + options.push_front(caf::PdmOptionItemInfo("Mixed Well Names", "")); + } + } + } + else if (fieldNeedingOptions == &m_branchIndex) + { + bool hasCommonBranchDetection = !m_branchDetection().isPartiallyTrue(); + if (hasCommonBranchDetection) + { + bool doBranchDetection = m_branchDetection().isTrue(); + auto branches = RiaSimWellBranchTools::simulationWellBranches(m_simWellName, doBranchDetection); + + options = RiaSimWellBranchTools::valueOptionsForBranchIndexField(branches); + + if (m_branchIndex() == -1) + { + options.push_front(caf::PdmOptionItemInfo("Mixed Branches", -1)); + } + } + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + updateDefaultOptions(); + + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Data Source"); + group->add(&m_case); + + RimEclipseCase* eclipseCase = dynamic_cast(m_case()); + if (eclipseCase) + { + group->add(&m_trajectoryType); + if (trajectoryTypeToApply() == RimWellLogExtractionCurve::WELL_PATH) + { + group->add(&m_wellPath); + } + else if (trajectoryTypeToApply() == RimWellLogExtractionCurve::SIMULATION_WELL) + { + group->add(&m_simWellName); + if (RiaSimWellBranchTools::simulationWellBranches(m_simWellName(), true).size() > 1) + { + group->add(&m_branchDetection); + bool hasCommonBranchDetection = !m_branchDetection().isPartiallyTrue(); + if (hasCommonBranchDetection) + { + bool doBranchDetection = m_branchDetection().isTrue(); + if (RiaSimWellBranchTools::simulationWellBranches(m_simWellName(), doBranchDetection).size() > 1) + { + group->add(&m_branchIndex); + } + } + } + } + } + else + { + group->add(&m_wellPath); + } + group->add(&m_timeStep); + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) +{ + caf::PdmUiComboBoxEditorAttribute* myAttr = dynamic_cast(attribute); + if (myAttr) + { + if (field == &m_case || + field == &m_simWellName || + field == &m_wellPath || + field == &m_timeStep) + { + myAttr->showPreviousAndNextButtons = true; + } + + QString modifierText; + + if (field == &m_case) + { + modifierText = ("(Shift+"); + } + else if (field == &m_wellPath || field == &m_simWellName) + { + modifierText = ("(Ctrl+"); + } + else if (field == &m_timeStep) + { + modifierText = ("("); + } + + if (!modifierText.isEmpty()) + { + myAttr->nextButtonText = "Next " + modifierText + "PgDown)"; + myAttr->prevButtonText = "Previous " + modifierText + "PgUp)"; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogCurveCommonDataSource::modifyCurrentIndex(caf::PdmValueField* field, int indexOffset) +{ + bool useOptionsOnly; + QList options = calculateValueOptions(field, &useOptionsOnly); + RimDataSourceSteppingTools::modifyCurrentIndex(field, options, indexOffset); +} diff --git a/ApplicationCode/ProjectDataModel/RimWellLogCurveCommonDataSource.h b/ApplicationCode/ProjectDataModel/RimWellLogCurveCommonDataSource.h new file mode 100644 index 0000000000..7a06de0ea1 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogCurveCommonDataSource.h @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimWellPath.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" +#include "cafPdmUiOrdering.h" +#include "cafTristate.h" + +class RimCase; +class RimWellLogCurve; +class RimWellLogPlot; +class RimWellLogTrack; +class RimWellPath; + +//================================================================================================== +/// +//================================================================================================== +class RimWellLogCurveCommonDataSource : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimWellLogCurveCommonDataSource(); + + RimCase* caseToApply() const; + void setCaseToApply(RimCase* val); + int trajectoryTypeToApply() const; + void setTrajectoryTypeToApply(int val); + RimWellPath* wellPathToApply() const; + void setWellPathToApply(RimWellPath* val); + void setBranchIndexToApply(int val); + void setBranchDetectionToApply(caf::Tristate::State val); + QString simWellNameToApply() const; + void setSimWellNameToApply(const QString& val); + int timeStepToApply() const; + void setTimeStepToApply(int val); + + void resetDefaultOptions(); + void updateDefaultOptions(const std::vector& curves, const std::vector& tracks); + void updateDefaultOptions(); + void updateCurvesAndTracks(std::vector& curves, std::vector& tracks); + void updateCurvesAndTracks(); + void applyPrevCase(); + void applyNextCase(); + + void applyPrevWell(); + void applyNextWell(); + + void applyPrevTimeStep(); + void applyNextTimeStep(); + std::vector fieldsToShowInToolbar(); +protected: + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) override; + QList 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; + void modifyCurrentIndex(caf::PdmValueField* field, int indexOffset); +private: + caf::PdmPtrField m_case; + caf::PdmField m_trajectoryType; + caf::PdmPtrField m_wellPath; + caf::PdmField m_simWellName; + caf::PdmField m_branchIndex; + caf::PdmField m_branchDetection; + caf::PdmField m_timeStep; +}; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogCurveNameConfig.cpp b/ApplicationCode/ProjectDataModel/RimWellLogCurveNameConfig.cpp deleted file mode 100644 index 1cd7555830..0000000000 --- a/ApplicationCode/ProjectDataModel/RimWellLogCurveNameConfig.cpp +++ /dev/null @@ -1,271 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// 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. -// + m_addWellName {m_fieldValue=true m_defaultFieldValue=true } caf::PdmField - -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RimProject.h" -#include "RimWellLogCurveNameConfig.h" -#include "Rim3dWellLogCurve.h" - -//================================================================================================== -/// -/// -//================================================================================================== - -CAF_PDM_SOURCE_INIT(RimCurveNameConfig, "RimCurveNameConfig"); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimCurveNameConfig::RimCurveNameConfig(const RimCurveNameConfigHolderInterface* configHolder /*= nullptr*/) - : m_configHolder(configHolder) -{ - CAF_PDM_InitObject("Curve Name Generator", "", "", ""); - - CAF_PDM_InitField(&m_isUsingAutoName, "IsUsingAutoName", true, "Generate Name Automatically", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_customName, "CustomCurveName", "Curve Name", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_autoName, "AutoCurveName", "Curve Name", "", "", ""); - m_autoName.registerGetMethod(this, &RimCurveNameConfig::autoName); - m_autoName.registerSetMethod(this, &RimCurveNameConfig::setCustomName); - m_autoName.xmlCapability()->disableIO(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimCurveNameConfig::~RimCurveNameConfig() -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimCurveNameConfig::isUsingAutoName() const -{ - return m_isUsingAutoName(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -caf::PdmFieldHandle* RimCurveNameConfig::nameField() -{ - if (isUsingAutoName()) - { - return &m_autoName; - } - return &m_customName; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimCurveNameConfig::name() const -{ - if (isUsingAutoName()) - { - return m_autoName(); - } - return m_customName(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -caf::PdmUiGroup* RimCurveNameConfig::createUiGroup(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) -{ - caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup("Curve Name"); - nameGroup->add(&m_isUsingAutoName); - return nameGroup; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimCurveNameConfig::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) -{ - if (changedField == &m_customName) - { - m_isUsingAutoName = false; - } - - if (changedField == &m_isUsingAutoName && !isUsingAutoName()) - { - m_customName = m_configHolder->createCurveAutoName(); - } - - updateAllSettings(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimCurveNameConfig::autoName() const -{ - return m_configHolder->createCurveAutoName(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimCurveNameConfig::setCustomName(const QString& name) -{ - m_isUsingAutoName = false; - m_customName = name; - updateAllSettings(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimCurveNameConfig::updateAllSettings() -{ - m_isUsingAutoName.uiCapability()->updateConnectedEditors(); - m_autoName.uiCapability()->updateConnectedEditors(); - m_customName.uiCapability()->updateConnectedEditors(); - - Rim3dWellLogCurve* curve; - this->firstAncestorOrThisOfTypeAsserted(curve); - curve->updateConnectedEditors(); - -} - -//================================================================================================== -/// -/// -//================================================================================================== - -CAF_PDM_SOURCE_INIT(RimWellLogExtractionCurveNameConfig, "RimWellLogExtractionCurveNameConfig"); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellLogExtractionCurveNameConfig::RimWellLogExtractionCurveNameConfig(const RimCurveNameConfigHolderInterface* configHolder) - : RimCurveNameConfig(configHolder) -{ - CAF_PDM_InitObject("Well Log Extraction Curve Name Generator", "", "", ""); - - CAF_PDM_InitField(&m_addCaseName, "AddCaseName", false, "Add Case Name To Auto Name", "", "", ""); - CAF_PDM_InitField(&m_addProperty, "AddProperty", true, "Add Property Type To Auto Name", "", "", ""); - CAF_PDM_InitField(&m_addWellName, "AddWellName", true, "Add Well Name To Auto Name", "", "", ""); - CAF_PDM_InitField(&m_addTimestep, "AddTimeStep", true, "Add Time Step To Auto Name", "", "", ""); - CAF_PDM_InitField(&m_addDate, "AddDate", true, "Add Date To Auto Name", "", "", ""); - - m_customName = "Extraction Curve"; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -caf::PdmUiGroup* RimWellLogExtractionCurveNameConfig::createUiGroup(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) -{ - caf::PdmUiGroup* nameGroup = RimCurveNameConfig::createUiGroup(uiConfigName, uiOrdering); - nameGroup->add(&m_addCaseName); - nameGroup->add(&m_addProperty); - nameGroup->add(&m_addWellName); - nameGroup->add(&m_addTimestep); - nameGroup->add(&m_addDate); - return nameGroup; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimWellLogExtractionCurveNameConfig::addCaseName() const -{ - return m_addCaseName(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimWellLogExtractionCurveNameConfig::addProperty() const -{ - return m_addProperty(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimWellLogExtractionCurveNameConfig::addWellName() const -{ - return m_addWellName(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimWellLogExtractionCurveNameConfig::addTimeStep() const -{ - return m_addTimestep(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimWellLogExtractionCurveNameConfig::addDate() const -{ - return m_addDate(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellLogExtractionCurveNameConfig::updateAllSettings() -{ - m_addCaseName.uiCapability()->setUiReadOnly(!isUsingAutoName()); - m_addProperty.uiCapability()->setUiReadOnly(!isUsingAutoName()); - m_addWellName.uiCapability()->setUiReadOnly(!isUsingAutoName()); - m_addTimestep.uiCapability()->setUiReadOnly(!isUsingAutoName()); - m_addDate.uiCapability()->setUiReadOnly(!isUsingAutoName()); - - RimCurveNameConfig::updateAllSettings(); -} - -//================================================================================================== -/// -/// -//================================================================================================== - -CAF_PDM_SOURCE_INIT(RimWellLogFileCurveNameConfig, "RimWellLogFileCurveNameConfig"); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellLogFileCurveNameConfig::RimWellLogFileCurveNameConfig(const RimCurveNameConfigHolderInterface* configHolder) - : RimCurveNameConfig(configHolder) -{ - CAF_PDM_InitObject("Well Log File Curve Name Generator", "", "", ""); - m_customName = "Las Curve"; -} - -//================================================================================================== -/// -/// -//================================================================================================== - -CAF_PDM_SOURCE_INIT(RimWellLogRftCurveNameConfig, "RimWellLogRftCurveNameConfig"); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellLogRftCurveNameConfig::RimWellLogRftCurveNameConfig(const RimCurveNameConfigHolderInterface* configHolder) - : RimCurveNameConfig(configHolder) -{ - CAF_PDM_InitObject("Well Log Rft Curve Name Generator", "", "", ""); - m_customName = "Rft Curve"; -} \ No newline at end of file diff --git a/ApplicationCode/ProjectDataModel/RimWellLogCurveNameConfig.h b/ApplicationCode/ProjectDataModel/RimWellLogCurveNameConfig.h deleted file mode 100644 index 0ad17339e4..0000000000 --- a/ApplicationCode/ProjectDataModel/RimWellLogCurveNameConfig.h +++ /dev/null @@ -1,115 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015- Statoil ASA -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "cafPdmField.h" -#include "cafPdmObject.h" -#include "cafPdmProxyValueField.h" - -//================================================================================================== -/// -/// -//================================================================================================== -class RimCurveNameConfigHolderInterface -{ -public: - virtual QString createCurveAutoName() const = 0; -}; - -//================================================================================================== -/// -/// -//================================================================================================== -class RimCurveNameConfig : public caf::PdmObject -{ - CAF_PDM_HEADER_INIT; - -public: - RimCurveNameConfig(const RimCurveNameConfigHolderInterface* configHolder = nullptr); - virtual ~RimCurveNameConfig(); - bool isUsingAutoName() const; - caf::PdmFieldHandle* nameField(); - QString name() const; - virtual caf::PdmUiGroup* createUiGroup(QString uiConfigName, caf::PdmUiOrdering& uiOrdering); - -protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - QString autoName() const; - void setCustomName(const QString& name); - virtual void updateAllSettings(); -protected: - caf::PdmField m_isUsingAutoName; - caf::PdmField m_customName; - caf::PdmProxyValueField m_autoName; - - const RimCurveNameConfigHolderInterface* m_configHolder; -}; - -//================================================================================================== -/// -/// -//================================================================================================== -class RimWellLogExtractionCurveNameConfig : public RimCurveNameConfig -{ - CAF_PDM_HEADER_INIT; - -public: - RimWellLogExtractionCurveNameConfig(const RimCurveNameConfigHolderInterface* configHolder = nullptr); - virtual caf::PdmUiGroup* createUiGroup(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - - bool addCaseName() const; - bool addProperty() const; - bool addWellName() const; - bool addTimeStep() const; - bool addDate() const; - -protected: - virtual void updateAllSettings(); - -private: - caf::PdmField m_addCaseName; - caf::PdmField m_addProperty; - caf::PdmField m_addWellName; - caf::PdmField m_addTimestep; - caf::PdmField m_addDate; -}; - -//================================================================================================== -/// -/// -//================================================================================================== -class RimWellLogFileCurveNameConfig : public RimCurveNameConfig -{ - CAF_PDM_HEADER_INIT; - -public: - RimWellLogFileCurveNameConfig(const RimCurveNameConfigHolderInterface* configHolder = nullptr); -}; - -//================================================================================================== -/// -/// -//================================================================================================== -class RimWellLogRftCurveNameConfig : public RimCurveNameConfig -{ - CAF_PDM_HEADER_INIT; - -public: - RimWellLogRftCurveNameConfig(const RimCurveNameConfigHolderInterface* configHolder = nullptr); -}; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp index d53adb88dc..20f2df7036 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp @@ -47,13 +47,17 @@ #include "RimProject.h" #include "RimTools.h" #include "RimWellLogCurve.h" +#include "RimWellLogFile.h" +#include "RimWellLogFileChannel.h" #include "RimWellLogPlot.h" #include "RimWellLogPlotCollection.h" #include "RimWellLogTrack.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" +#include "RimWellPlotTools.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuPlotMainWindowTools.h" +#include "RiuQwtPlotCurve.h" #include "RiuWellLogTrack.h" #include "cafPdmUiTreeOrdering.h" @@ -88,12 +92,12 @@ RimWellLogExtractionCurve::RimWellLogExtractionCurve() { CAF_PDM_InitObject("Well Log Curve", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_trajectoryType, "TrajectoryType", "Trajectory", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_trajectoryType, "TrajectoryType", "Trajectory Type", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_wellPath, "CurveWellPath", " ", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_wellPath, "CurveWellPath", "Well Name", "", "", ""); m_wellPath.uiCapability()->setUiTreeChildrenHidden(true); - CAF_PDM_InitField(&m_simWellName, "SimulationWellName", QString("None"), " ", "", "", ""); + CAF_PDM_InitField(&m_simWellName, "SimulationWellName", QString("None"), "Well Name", "", "", ""); CAF_PDM_InitField(&m_branchDetection, "BranchDetection", true, "Branch Detection", "", "Compute branches based on how simulation well cells are organized", ""); CAF_PDM_InitField(&m_branchIndex, "Branch", 0, "Branch Index", "", "", ""); @@ -111,6 +115,7 @@ RimWellLogExtractionCurve::RimWellLogExtractionCurve() m_geomResultDefinition.uiCapability()->setUiHidden(true); m_geomResultDefinition.uiCapability()->setUiTreeChildrenHidden(true); m_geomResultDefinition = new RimGeoMechResultDefinition; + m_geomResultDefinition->setAddWellPathDerivedResults(true); CAF_PDM_InitField(&m_timeStep, "CurveTimeStep", 0,"Time Step", "", "", ""); @@ -210,6 +215,14 @@ void RimWellLogExtractionCurve::setPropertiesFromView(Rim3dView* view) clearGeneratedSimWellPaths(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogExtractionCurve::TrajectoryType RimWellLogExtractionCurve::trajectoryType() const +{ + return m_trajectoryType(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -229,7 +242,7 @@ void RimWellLogExtractionCurve::clampTimestep() //-------------------------------------------------------------------------------------------------- void RimWellLogExtractionCurve::clampBranchIndex() { - int branchCount = static_cast(simulationWellBranches().size()); + int branchCount = static_cast(RiaSimWellBranchTools::simulationWellBranches(m_simWellName, m_branchDetection).size()); if ( branchCount > 0 ) { if ( m_branchIndex >= branchCount ) m_branchIndex = branchCount - 1; @@ -252,7 +265,7 @@ void RimWellLogExtractionCurve::fieldChangedByUi(const caf::PdmFieldHandle* chan { clampTimestep(); - auto wellNameSet = findSortedWellNames(); + auto wellNameSet = sortedSimWellNames(); if (!wellNameSet.count(m_simWellName())) m_simWellName = "None"; clearGeneratedSimWellPaths(); @@ -293,7 +306,7 @@ void RimWellLogExtractionCurve::fieldChangedByUi(const caf::PdmFieldHandle* chan changedField == &m_addDateToCurveName) { this->uiCapability()->updateConnectedEditors(); - updateCurveNameAndUpdatePlotLegend(); + updateCurveNameAndUpdatePlotLegendAndTitle(); } } @@ -331,7 +344,7 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate(bool updateParentPlot) } else { - std::vector simWellBranches = simulationWellBranches(); + std::vector simWellBranches = RiaSimWellBranchTools::simulationWellBranches(m_simWellName, m_branchDetection); if (m_branchIndex >= 0 && m_branchIndex < static_cast(simWellBranches.size())) { auto wellBranch = simWellBranches[m_branchIndex]; @@ -358,8 +371,8 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate(bool updateParentPlot) if (eclExtractor.notNull() && eclipseCase) { - measuredDepthValues = eclExtractor->measuredDepth(); - tvDepthValues = eclExtractor->trueVerticalDepth(); + measuredDepthValues = eclExtractor->cellIntersectionMDs(); + tvDepthValues = eclExtractor->cellIntersectionTVDs(); m_eclipseResultDefinition->loadResult(); @@ -384,11 +397,14 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate(bool updateParentPlot) else if (geomExtractor.notNull()) // geomExtractor { - measuredDepthValues = geomExtractor->measuredDepth(); - tvDepthValues = geomExtractor->trueVerticalDepth(); + measuredDepthValues = geomExtractor->cellIntersectionMDs(); + tvDepthValues = geomExtractor->cellIntersectionTVDs(); - m_geomResultDefinition->loadResult(); + findAndLoadWbsParametersFromLasFiles(m_wellPath(), geomExtractor.p()); + + geomExtractor->setRkbDiff(rkbDiff()); + m_geomResultDefinition->loadResult(); geomExtractor->curveData(m_geomResultDefinition->resultAddress(), m_timeStep, &values); } @@ -439,30 +455,67 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate(bool updateParentPlot) } } - updateZoomInParentPlot(); + if (updateParentPlot) + { + updateZoomInParentPlot(); + } setLogScaleFromSelectedResult(); - if (m_parentQwtPlot) m_parentQwtPlot->replot(); + if (m_parentQwtPlot) + { + m_parentQwtPlot->replot(); + } } } //-------------------------------------------------------------------------------------------------- -/// +/// Search well path for LAS-files containing Well Bore Stability data and set them in the extractor. //-------------------------------------------------------------------------------------------------- -std::set RimWellLogExtractionCurve::findSortedWellNames() +void RimWellLogExtractionCurve::findAndLoadWbsParametersFromLasFiles(const RimWellPath* wellPath, RigGeoMechWellLogExtractor* geomExtractor) { - std::set sortedWellNames; - RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); - - if ( eclipseCase && eclipseCase->eclipseCaseData() ) + std::vector> logFileMudWeights = RimWellLogFile::findMdAndChannelValuesForWellPath(wellPath, "PP"); + if (!logFileMudWeights.empty()) { - const cvf::Collection& simWellData = eclipseCase->eclipseCaseData()->wellResults(); + // Log file pressures come in SG units (g / cm^3). + // We need SI as input (kg / m^3), so multiply by 1000: + for (auto& mudWeight : logFileMudWeights) + { + mudWeight.second *= 1000.0; + } + geomExtractor->setWellLogMdAndMudWeightKgPerM3(logFileMudWeights); + } - for ( size_t wIdx = 0; wIdx < simWellData.size(); ++wIdx ) + std::vector> logFileUcs = RimWellLogFile::findMdAndChannelValuesForWellPath(wellPath, "UCS"); + if (!logFileUcs.empty()) + { + // TODO: UCS is typically in MPa, but not necessarily. + // We need to at least give a warning if the units don't match + // ... and preferable do a conversion. + for (auto& ucsValue : logFileUcs) { - sortedWellNames.insert(simWellData[wIdx]->m_wellName); + ucsValue.second *= 10.0; // MPa -> Bar } + geomExtractor->setWellLogMdAndUcsBar(logFileUcs); + } + + std::vector> logFilePoissonRatio = RimWellLogFile::findMdAndChannelValuesForWellPath(wellPath, "POISSON_RATIO"); + if (!logFilePoissonRatio.empty()) + { + geomExtractor->setWellLogMdAndPoissonRatio(logFilePoissonRatio); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RimWellLogExtractionCurve::sortedSimWellNames() +{ + std::set sortedWellNames; + RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); + if (eclipseCase) + { + sortedWellNames = eclipseCase->sortedSimWellNames(); } return sortedWellNames; @@ -490,14 +543,6 @@ void RimWellLogExtractionCurve::clearGeneratedSimWellPaths() m_wellPathsWithExtractors.clear(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimWellLogExtractionCurve::simulationWellBranches() const -{ - return RiaSimWellBranchTools::simulationWellBranches(m_simWellName, m_branchDetection); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -536,7 +581,7 @@ QList RimWellLogExtractionCurve::calculateValueOptions(c } else if (fieldNeedingOptions == &m_simWellName) { - std::set sortedWellNames = this->findSortedWellNames(); + std::set sortedWellNames = this->sortedSimWellNames(); QIcon simWellIcon(":/Well.png"); for ( const QString& wname: sortedWellNames ) @@ -551,7 +596,7 @@ QList RimWellLogExtractionCurve::calculateValueOptions(c } else if (fieldNeedingOptions == &m_branchIndex) { - auto branches = simulationWellBranches(); + auto branches = RiaSimWellBranchTools::simulationWellBranches(m_simWellName, m_branchDetection); options = RiaSimWellBranchTools::valueOptionsForBranchIndexField(branches); } @@ -573,28 +618,28 @@ void RimWellLogExtractionCurve::defineUiOrdering(QString uiConfigName, caf::PdmU RimGeoMechCase* geomCase = dynamic_cast(m_case.value()); RimEclipseCase* eclipseCase = dynamic_cast(m_case.value()); - curveDataGroup->add(&m_trajectoryType); - if (m_trajectoryType() == WELL_PATH) - { - curveDataGroup->add(&m_wellPath); - } - else - { - curveDataGroup->add(&m_simWellName); - - RiaSimWellBranchTools::appendSimWellBranchFieldsIfRequiredFromSimWellName(curveDataGroup, - m_simWellName, - m_branchDetection, - m_branchIndex); - } - if (eclipseCase) { + curveDataGroup->add(&m_trajectoryType); + if (m_trajectoryType() == WELL_PATH) + { + curveDataGroup->add(&m_wellPath); + } + else + { + curveDataGroup->add(&m_simWellName); + + RiaSimWellBranchTools::appendSimWellBranchFieldsIfRequiredFromSimWellName(curveDataGroup, + m_simWellName, + m_branchDetection, + m_branchIndex); + } m_eclipseResultDefinition->uiOrdering(uiConfigName, *curveDataGroup); } else if (geomCase) { + curveDataGroup->add(&m_wellPath); m_geomResultDefinition->uiOrdering(uiConfigName, *curveDataGroup); } @@ -684,7 +729,7 @@ QString RimWellLogExtractionCurve::createCurveAutoName() if (!wellName().isEmpty()) { generatedCurveName += wellName(); - if (m_trajectoryType == SIMULATION_WELL && simulationWellBranches().size() > 1) + if (m_trajectoryType == SIMULATION_WELL && RiaSimWellBranchTools::simulationWellBranches(m_simWellName, m_branchDetection).size() > 1) { generatedCurveName.push_back(" Br" + QString::number(m_branchIndex + 1)); } @@ -731,7 +776,7 @@ QString RimWellLogExtractionCurve::createCurveAutoName() if (m_addTimestepToCurveName) { - generatedCurveName.push_back(QString("[%1/%2]").arg(m_timeStep()).arg(maxTimeStep)); + generatedCurveName.push_back(QString("[%1/%2]").arg(m_timeStep() + 1).arg(maxTimeStep)); } } @@ -749,7 +794,7 @@ QString RimWellLogExtractionCurve::wellLogChannelName() const QString name; if (eclipseCase) { - name = caf::Utils::makeValidFileBasename( m_eclipseResultDefinition->resultVariableUiName()); + name = caf::Utils::makeValidFileBasename( m_eclipseResultDefinition->resultVariableUiShortName()); } else if (geoMechCase) { @@ -817,6 +862,22 @@ QString RimWellLogExtractionCurve::wellDate() const return (m_timeStep >= 0 && m_timeStep < timeStepNames.size()) ? timeStepNames[m_timeStep] : ""; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimWellLogExtractionCurve::branchIndex() const +{ + return m_branchIndex(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogExtractionCurve::branchDetection() const +{ + return m_branchDetection(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -851,27 +912,8 @@ double RimWellLogExtractionCurve::rkbDiff() const { if (m_wellPath && m_wellPath->wellPathGeometry()) { - RigWellPath* geo = m_wellPath->wellPathGeometry(); - - if (geo->hasDatumElevation()) - { - return geo->datumElevation(); - } - - // If measured depth is zero, use the z-value of the well path points - if (geo->m_wellPathPoints.size() > 0 && geo->m_measuredDepths.size() > 0) - { - double epsilon = 1e-3; - - if (cvf::Math::abs(geo->m_measuredDepths[0]) < epsilon) - { - double diff = geo->m_measuredDepths[0] - (-geo->m_wellPathPoints[0].z()); - - return diff; - } - } + return m_wellPath->wellPathGeometry()->rkbDiff(); } - return HUGE_VAL; } @@ -898,3 +940,43 @@ void RimWellLogExtractionCurve::setEclipseResultVariable(const QString& resVarna { m_eclipseResultDefinition->setResultVariable(resVarname); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::setGeoMechResultAddress(const RigFemResultAddress& resAddr) +{ + m_geomResultDefinition->setResultAddress(resAddr); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::setTrajectoryType(TrajectoryType trajectoryType) +{ + m_trajectoryType = trajectoryType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::setWellName(QString wellName) +{ + m_simWellName = wellName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::setBranchDetection(bool branchDetection) +{ + m_branchDetection = branchDetection; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::setBranchIndex(int index) +{ + m_branchIndex = index; +} \ No newline at end of file diff --git a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h index 62f0622d1f..36d9f06b1b 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h @@ -21,9 +21,12 @@ #include "RimWellLogCurve.h" +#include "RigFemResultAddress.h" + #include "cafPdmPtrField.h" #include "cafPdmChildField.h" +class RigGeoMechWellLogExtractor; class RigWellPath; class RimCase; class RimEclipseResultDefinition; @@ -40,7 +43,7 @@ class RimWellLogExtractionCurve : public RimWellLogCurve CAF_PDM_HEADER_INIT; public: RimWellLogExtractionCurve(); - virtual ~RimWellLogExtractionCurve(); + ~RimWellLogExtractionCurve() override; enum TrajectoryType { WELL_PATH, SIMULATION_WELL}; @@ -54,9 +57,12 @@ class RimWellLogExtractionCurve : public RimWellLogCurve void setPropertiesFromView(Rim3dView* view); - virtual QString wellName() const; - virtual QString wellLogChannelName() const; - virtual QString wellDate() const; + TrajectoryType trajectoryType() const; + QString wellName() const override; + QString wellLogChannelName() const override; + QString wellDate() const override; + int branchIndex() const; + bool branchDetection() const; bool isEclipseCurve() const; QString caseName() const; @@ -66,24 +72,30 @@ class RimWellLogExtractionCurve : public RimWellLogCurve void setCurrentTimeStep(int timeStep); void setEclipseResultVariable(const QString& resVarname); + void setGeoMechResultAddress(const RigFemResultAddress& resAddr); + + void setTrajectoryType(TrajectoryType trajectoryType); + void setWellName(QString wellName); + void setBranchDetection(bool branchDetection); + void setBranchIndex(int index); + static void findAndLoadWbsParametersFromLasFiles(const RimWellPath* wellPath, RigGeoMechWellLogExtractor* geomExtractor); protected: - virtual QString createCurveAutoName() override; - virtual void onLoadDataAndUpdate(bool updateParentPlot) override; + QString createCurveAutoName() override; + void onLoadDataAndUpdate(bool updateParentPlot) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual void initAfterRead() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + void initAfterRead() override; private: void setLogScaleFromSelectedResult(); void clampTimestep(); void clampBranchIndex(); - std::set findSortedWellNames(); + std::set sortedSimWellNames(); void clearGeneratedSimWellPaths(); - std::vector simulationWellBranches() const; private: caf::PdmPtrField m_case; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurveNameConfig.cpp b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurveNameConfig.cpp new file mode 100644 index 0000000000..d33847ba00 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurveNameConfig.cpp @@ -0,0 +1,108 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogExtractionCurveNameConfig.h" + +//================================================================================================== +/// +/// +//================================================================================================== + +CAF_PDM_SOURCE_INIT(RimWellLogExtractionCurveNameConfig, "RimWellLogExtractionCurveNameConfig"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogExtractionCurveNameConfig::RimWellLogExtractionCurveNameConfig(const RimNameConfigHolderInterface* configHolder) + : RimNameConfig(configHolder) +{ + CAF_PDM_InitObject("Well Log Extraction Curve Name Generator", "", "", ""); + + CAF_PDM_InitField(&m_addCaseName, "AddCaseName", true, "Add Case Name", "", "", ""); + CAF_PDM_InitField(&m_addProperty, "AddProperty", true, "Add Property Type", "", "", ""); + CAF_PDM_InitField(&m_addWellName, "AddWellName", true, "Add Well Name", "", "", ""); + CAF_PDM_InitField(&m_addTimestep, "AddTimeStep", true, "Add Time Step", "", "", ""); + CAF_PDM_InitField(&m_addDate, "AddDate", true, "Add Date", "", "", ""); + + m_customName = "Log Extraction"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogExtractionCurveNameConfig::addCaseName() const +{ + return m_addCaseName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogExtractionCurveNameConfig::addProperty() const +{ + return m_addProperty(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogExtractionCurveNameConfig::addWellName() const +{ + return m_addWellName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogExtractionCurveNameConfig::addTimeStep() const +{ + return m_addTimestep(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogExtractionCurveNameConfig::addDate() const +{ + return m_addDate(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurveNameConfig::enableAllAutoNameTags(bool enable) +{ + m_addCaseName = enable; + m_addProperty = enable; + m_addWellName = enable; + m_addTimestep = enable; + m_addDate = enable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurveNameConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + RimNameConfig::defineUiOrdering(uiConfigName, uiOrdering); + uiOrdering.add(&m_addCaseName); + uiOrdering.add(&m_addProperty); + uiOrdering.add(&m_addWellName); + uiOrdering.add(&m_addTimestep); + uiOrdering.add(&m_addDate); +} diff --git a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurveNameConfig.h b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurveNameConfig.h new file mode 100644 index 0000000000..93422083bb --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurveNameConfig.h @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimNameConfig.h" + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogExtractionCurveNameConfig : public RimNameConfig +{ + CAF_PDM_HEADER_INIT; + +public: + RimWellLogExtractionCurveNameConfig(const RimNameConfigHolderInterface* configHolder = nullptr); + + bool addCaseName() const; + bool addProperty() const; + bool addWellName() const; + bool addTimeStep() const; + bool addDate() const; + + void enableAllAutoNameTags(bool enable) override; + +protected: + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +private: + caf::PdmField m_addCaseName; + caf::PdmField m_addProperty; + caf::PdmField m_addWellName; + caf::PdmField m_addTimestep; + caf::PdmField m_addDate; +}; + + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFile.cpp b/ApplicationCode/ProjectDataModel/RimWellLogFile.cpp index 646f975e61..a7b403111a 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogFile.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogFile.cpp @@ -18,25 +18,26 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimWellLogFile.h" -#include "RimWellLogFileChannel.h" -#include "RimWellPath.h" -#include "RimWellPathCollection.h" -#include "RimTools.h" -//#include "RimWellPltPlot.h" -#include "RimWellPlotTools.h" #include "RiaDateStringParser.h" +#include "RiaFieldHandleTools.h" +#include "RiaQDateTimeTools.h" #include "RigWellLogFile.h" +#include "RimFileWellPath.h" +#include "RimTools.h" +#include "RimWellLogFileChannel.h" +#include "RimWellPathCollection.h" +#include "RimWellPlotTools.h" + #include "Riu3DMainWindowTools.h" #include "cafPdmUiDateEditor.h" -#include #include #include -#include "RiaQDateTimeTools.h" +#include CAF_PDM_SOURCE_INIT(RimWellLogFile, "WellLogFile"); @@ -65,8 +66,7 @@ RimWellLogFile::RimWellLogFile() CAF_PDM_InitFieldNoDefault(&m_wellName, "WellName", "", "", "", ""); m_wellName.uiCapability()->setUiReadOnly(true); - m_wellName.uiCapability()->setUiHidden(true); - m_wellName.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_wellName); CAF_PDM_InitFieldNoDefault(&m_date, "Date", "Date", "", "", ""); m_date.uiCapability()->setUiReadOnly(true); @@ -76,12 +76,10 @@ RimWellLogFile::RimWellLogFile() CAF_PDM_InitFieldNoDefault(&m_name, "Name", "", "", "", ""); m_name.uiCapability()->setUiReadOnly(true); - m_name.uiCapability()->setUiHidden(true); - m_name.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_name); CAF_PDM_InitFieldNoDefault(&m_wellLogChannelNames, "WellLogFileChannels", "", "", "", ""); - m_wellLogChannelNames.uiCapability()->setUiHidden(true); - m_wellLogChannelNames.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_wellLogChannelNames); CAF_PDM_InitField(&m_wellFlowCondition, "WellFlowCondition", caf::AppEnum(RimWellLogFile::WELL_FLOW_COND_STANDARD), "Well Flow Rates", "", "", ""); @@ -90,6 +88,7 @@ RimWellLogFile::RimWellLogFile() m_invalidDateMessage.xmlCapability()->disableIO(); m_wellLogDataFile = nullptr; + m_lasFileHasValidDate = false; } //-------------------------------------------------------------------------------------------------- @@ -193,11 +192,11 @@ bool RimWellLogFile::readFile(QString* errorMessage) m_wellLogChannelNames.push_back(wellLog); } - RimWellPath* wellPath; - firstAncestorOrThisOfType(wellPath); + RimFileWellPath* wellPath; + this->firstAncestorOrThisOfType(wellPath); if (wellPath) { - if (wellPath->filepath().isEmpty()) + if (wellPath->filepath().isEmpty()) // Has dummy wellpath { wellPath->setName(m_wellName); } @@ -258,6 +257,33 @@ void RimWellLogFile::updateFilePathsFromProjectPath(const QString& newProjectPat } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> RimWellLogFile::findMdAndChannelValuesForWellPath(const RimWellPath* wellPath, const QString& channelName) +{ + CVF_ASSERT(wellPath); + std::vector wellLogFiles; + wellPath->descendantsIncludingThisOfType(wellLogFiles); + for (RimWellLogFile* wellLogFile : wellLogFiles) + { + RigWellLogFile* fileData = wellLogFile->wellLogFileData(); + std::vector channelValues = fileData->values(channelName); + if (!channelValues.empty()) + { + std::vector depthValues = fileData->depthValues(); + CVF_ASSERT(depthValues.size() == channelValues.size()); + std::vector> depthValuePairs; + for (size_t i = 0; i < depthValues.size(); ++i) + { + depthValuePairs.push_back(std::make_pair(depthValues[i], channelValues[i])); + } + return depthValuePairs; + } + } + return std::vector>(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -275,8 +301,6 @@ void RimWellLogFile::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering.add(&m_date); m_date.uiCapability()->setUiReadOnly(m_lasFileHasValidDate); - auto timespec = m_date().timeSpec(); - if (!isDateValid(m_date())) { uiOrdering.add(&m_invalidDateMessage); diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFile.h b/ApplicationCode/ProjectDataModel/RimWellLogFile.h index 819a0b8797..f7954e69f1 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogFile.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogFile.h @@ -31,6 +31,7 @@ class RimWellLogFileChannel; +class RimWellPath; class QString; @@ -46,7 +47,7 @@ class RimWellLogFile : public caf::PdmObject public: RimWellLogFile(); - virtual ~RimWellLogFile(); + ~RimWellLogFile() override; static RimWellLogFile* readWellLogFile(const QString& logFilePath); @@ -74,14 +75,16 @@ class RimWellLogFile : public caf::PdmObject void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath); + static std::vector> findMdAndChannelValuesForWellPath(const RimWellPath* wellPath, const QString& channelName); + private: - virtual void setupBeforeSave() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, + void setupBeforeSave() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual caf::PdmFieldHandle* userDescriptionField() { return &m_name; } + caf::PdmFieldHandle* userDescriptionField() override { return &m_name; } static bool isDateValid(const QDateTime dateTime); diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.cpp b/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.cpp index 5487603496..35d810d27a 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.cpp @@ -19,6 +19,8 @@ #include "RimWellLogFileChannel.h" +#include "RiaFieldHandleTools.h" + #include @@ -32,8 +34,7 @@ RimWellLogFileChannel::RimWellLogFileChannel() CAF_PDM_InitObject("Well Log File Channel", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_name, "Name", "", "", "", ""); - m_name.uiCapability()->setUiHidden(true); - m_name.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_name); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.h b/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.h index 796c1a535f..bf2b6e4e2d 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileChannel.h @@ -38,7 +38,7 @@ class RimWellLogFileChannel : public caf::PdmObject void setName(const QString& name); QString name() const { return m_name; } - virtual caf::PdmFieldHandle* userDescriptionField() { return &m_name; } + caf::PdmFieldHandle* userDescriptionField() override { return &m_name; } private: caf::PdmField m_name; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp index 1864756ee3..9ca9be2200 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp @@ -22,18 +22,18 @@ #include "RigWellLogCurveData.h" #include "RigWellPath.h" -#include "RimOilField.h" #include "RimProject.h" +#include "RimTools.h" #include "RimWellLogFile.h" #include "RimWellLogFileChannel.h" #include "RimWellLogPlot.h" #include "RimWellLogTrack.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" -#include "RimWellRftPlot.h" #include "RimWellPlotTools.h" +#include "RimWellRftPlot.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuWellLogTrack.h" #include "RiaApplication.h" @@ -168,9 +168,15 @@ void RimWellLogFileCurve::onLoadDataAndUpdate(bool updateParentPlot) } m_qwtPlotCurve->setLineSegmentStartStopIndices(m_curveData->polylineStartStopIndices()); - updateZoomInParentPlot(); + if (updateParentPlot) + { + updateZoomInParentPlot(); + } - if (m_parentQwtPlot) m_parentQwtPlot->replot(); + if (m_parentQwtPlot) + { + m_parentQwtPlot->replot(); + } } } @@ -269,10 +275,10 @@ QList RimWellLogFileCurve::calculateValueOptions(const c if (fieldNeedingOptions == &m_wellPath) { - RimProject* proj = RiaApplication::instance()->project(); - if (proj->activeOilField()->wellPathCollection()) + auto wellPathColl = RimTools::wellPathCollection(); + if (wellPathColl) { - caf::PdmChildArrayField& wellPaths = proj->activeOilField()->wellPathCollection()->wellPaths; + caf::PdmChildArrayField& wellPaths = wellPathColl->wellPaths; for (size_t i = 0; i < wellPaths.size(); i++) { diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h index c9e9f3f936..491824299b 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h @@ -40,7 +40,7 @@ class RimWellLogFileCurve : public RimWellLogCurve public: RimWellLogFileCurve(); - virtual ~RimWellLogFileCurve(); + ~RimWellLogFileCurve() override; void setWellPath(RimWellPath* wellPath); RimWellPath* wellPath() const; @@ -48,22 +48,22 @@ class RimWellLogFileCurve : public RimWellLogCurve void setWellLogFile(RimWellLogFile* wellLogFile); // Overrides from RimWellLogPlotCurve - virtual QString wellName() const override; - virtual QString wellLogChannelName() const override; + QString wellName() const override; + QString wellLogChannelName() const override; RimWellLogFile* wellLogFile() const; protected: // Overrides from RimWellLogPlotCurve - virtual QString createCurveAutoName() override; - virtual void onLoadDataAndUpdate(bool updateParentPlot) override; + QString createCurveAutoName() override; + void onLoadDataAndUpdate(bool updateParentPlot) override; // Pdm overrrides - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual void initAfterRead() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + void initAfterRead() override; bool isRftPlotChild() const; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileCurveNameConfig.cpp b/ApplicationCode/ProjectDataModel/RimWellLogFileCurveNameConfig.cpp new file mode 100644 index 0000000000..d78732b015 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileCurveNameConfig.cpp @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogFileCurveNameConfig.h" + +//================================================================================================== +/// +/// +//================================================================================================== + +CAF_PDM_SOURCE_INIT(RimWellLogFileCurveNameConfig, "RimWellLogFileCurveNameConfig"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogFileCurveNameConfig::RimWellLogFileCurveNameConfig(const RimNameConfigHolderInterface* configHolder) + : RimNameConfig(configHolder) +{ + CAF_PDM_InitObject("Well Log File Curve Name Generator", "", "", ""); + m_customName = "Las Curve"; +} + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileCurveNameConfig.h b/ApplicationCode/ProjectDataModel/RimWellLogFileCurveNameConfig.h new file mode 100644 index 0000000000..02e335b98e --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileCurveNameConfig.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimNameConfig.h" + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogFileCurveNameConfig : public RimNameConfig +{ + CAF_PDM_HEADER_INIT; + +public: + RimWellLogFileCurveNameConfig(const RimNameConfigHolderInterface* configHolder = nullptr); +}; + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp index d75f5c9b9f..08ccd4408a 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp @@ -22,9 +22,13 @@ #include "RiaApplication.h" #include "RigWellLogCurveData.h" +#include "RigWellPath.h" +#include "RimGeoMechCase.h" +#include "RimEclipseCase.h" #include "RimWellAllocationPlot.h" #include "RimWellLogCurve.h" +#include "RimWellLogCurveCommonDataSource.h" #include "RimWellLogTrack.h" #include "RimWellRftPlot.h" #include "RimWellPltPlot.h" @@ -33,8 +37,11 @@ #include "RiuWellLogPlot.h" #include "RiuWellLogTrack.h" +#include "cafPdmUiComboBoxEditor.h" #include "cvfAssert.h" +#include + #include #define RI_LOGPLOT_MINDEPTH_DEFAULT 0.0 @@ -46,18 +53,26 @@ namespace caf { void caf::AppEnum< RimWellLogPlot::DepthTypeEnum >::setUp() { addItem(RimWellLogPlot::MEASURED_DEPTH, "MEASURED_DEPTH", "Measured Depth"); - addItem(RimWellLogPlot::TRUE_VERTICAL_DEPTH, "TRUE_VERTICAL_DEPTH", "True Vertical Depth"); + addItem(RimWellLogPlot::TRUE_VERTICAL_DEPTH, "TRUE_VERTICAL_DEPTH", "True Vertical Depth (MSL)"); addItem(RimWellLogPlot::PSEUDO_LENGTH, "PSEUDO_LENGTH", "Pseudo Length"); addItem(RimWellLogPlot::CONNECTION_NUMBER, "CONNECTION_NUMBER", "Connection Number"); setDefault(RimWellLogPlot::MEASURED_DEPTH); } + template<> + void RimWellLogPlot::AxisGridEnum::setUp() + { + addItem(RimWellLogPlot::AXIS_GRID_NONE, "GRID_X_NONE", "No Grid Lines"); + addItem(RimWellLogPlot::AXIS_GRID_MAJOR, "GRID_X_MAJOR", "Major Only"); + addItem(RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR, "GRID_X_MAJOR_AND_MINOR", "Major and Minor"); + setDefault(RimWellLogPlot::AXIS_GRID_MAJOR); + } + } // End namespace caf CAF_PDM_SOURCE_INIT(RimWellLogPlot, "WellLogPlot"); - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -67,22 +82,39 @@ RimWellLogPlot::RimWellLogPlot() m_viewer = nullptr; - CAF_PDM_InitField(&m_userName, "PlotDescription", QString("Well Log Plot"),"Name", "", "", ""); - + CAF_PDM_InitField(&m_userName_OBSOLETE, "PlotDescription", QString(""),"Name", "", "", ""); + m_userName_OBSOLETE.xmlCapability()->setIOWritable(false); + + CAF_PDM_InitFieldNoDefault(&m_commonDataSource, "CommonDataSource", "Data Source", "", "Change the Data Source of All Curves in the Plot", ""); + m_commonDataSource = new RimWellLogCurveCommonDataSource; + m_commonDataSource.uiCapability()->setUiTreeHidden(true); + m_commonDataSource.uiCapability()->setUiTreeChildrenHidden(true); + m_commonDataSource.xmlCapability()->disableIO(); + caf::AppEnum< RimWellLogPlot::DepthTypeEnum > depthType = MEASURED_DEPTH; - CAF_PDM_InitField(&m_depthType, "DepthType", depthType, "Depth type", "", "", ""); + CAF_PDM_InitField(&m_depthType, "DepthType", depthType, "Type", "", "", ""); caf::AppEnum< RiaDefines::DepthUnitType > depthUnit = RiaDefines::UNIT_METER; - CAF_PDM_InitField(&m_depthUnit, "DepthUnit", depthUnit, "Depth unit", "", "", ""); + CAF_PDM_InitField(&m_depthUnit, "DepthUnit", depthUnit, "Unit", "", "", ""); CAF_PDM_InitField(&m_minVisibleDepth, "MinimumDepth", 0.0, "Min", "", "", ""); CAF_PDM_InitField(&m_maxVisibleDepth, "MaximumDepth", 1000.0, "Max", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_depthAxisGridVisibility, "ShowDepthGridLines", "Show Grid Lines", "", "", ""); CAF_PDM_InitField(&m_isAutoScaleDepthEnabled, "AutoScaleDepthEnabled", true, "Auto Scale", "", "", ""); + m_isAutoScaleDepthEnabled.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&m_showTitleInPlot, "ShowTitleInPlot", false, "Show Title", "", "", ""); CAF_PDM_InitField(&m_showTrackLegends, "ShowTrackLegends", true, "Show Legends", "", "", ""); + CAF_PDM_InitField(&m_trackLegendsHorizontal, "TrackLegendsHorizontal", false, "Legend Orientation", "", "", ""); + m_trackLegendsHorizontal.uiCapability()->setUiEditorTypeName(caf::PdmUiComboBoxEditor::uiEditorTypeName()); CAF_PDM_InitFieldNoDefault(&m_tracks, "Tracks", "", "", "", ""); m_tracks.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_nameConfig, "NameConfig", "", "", "", ""); + m_nameConfig = new RimWellLogPlotNameConfig(this); + m_nameConfig.uiCapability()->setUiTreeHidden(true); + m_nameConfig.uiCapability()->setUiTreeChildrenHidden(true); + m_minAvailableDepth = HUGE_VAL; m_maxAvailableDepth = -HUGE_VAL; } @@ -97,6 +129,24 @@ RimWellLogPlot::~RimWellLogPlot() m_tracks.deleteAllChildObjects(); deleteViewWidget(); + delete m_commonDataSource; + delete m_nameConfig; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* RimWellLogPlot::createPlotWidget() +{ + return createViewWidget(nullptr); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* RimWellLogPlot::viewWidget() +{ + return m_viewer; } //-------------------------------------------------------------------------------------------------- @@ -112,32 +162,34 @@ void RimWellLogPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c m_isAutoScaleDepthEnabled = false; } - else if (changedField == &m_isAutoScaleDepthEnabled) + else if (changedField == &m_showTitleInPlot || + changedField == &m_showTrackLegends || + changedField == &m_trackLegendsHorizontal || + changedField == &m_depthAxisGridVisibility) { - updateDepthZoom(); + updateTracks(); + if (m_viewer) m_viewer->updateChildrenLayout(); } - else if (changedField == &m_userName) + else if (changedField == &m_isAutoScaleDepthEnabled) { - updateMdiWindowTitle(); + updateDepthZoom(); } - - if ( changedField == &m_depthType ) + else if ( changedField == &m_depthType ) { RimWellAllocationPlot* wellAllocPlot; firstAncestorOrThisOfType(wellAllocPlot); if (wellAllocPlot) wellAllocPlot->loadDataAndUpdate(); else if (isRftPlotChild()) rftPlot()->loadDataAndUpdate(); - else updateTracks(); - } - if ( changedField == &m_depthUnit) - { - updateTracks(); + else + { + updateTracks(); + updateDepthZoom(); + } } - - if ( changedField == &m_showTrackLegends) + else if ( changedField == &m_depthUnit) { updateTracks(); - if (m_viewer) m_viewer->updateChildrenLayout(); + updateDepthZoom(); } RimWellRftPlot* rftPlot(nullptr); @@ -183,6 +235,11 @@ QList RimWellLogPlot::calculateValueOptions(const caf::P options.push_back(caf::PdmOptionItemInfo(UnitAppEnum::uiText(RiaDefines::UNIT_METER), RiaDefines::UNIT_METER)); options.push_back(caf::PdmOptionItemInfo(UnitAppEnum::uiText(RiaDefines::UNIT_FEET), RiaDefines::UNIT_FEET)); } + else if (fieldNeedingOptions == &m_trackLegendsHorizontal) + { + options.push_back(caf::PdmOptionItemInfo("Vertical", QVariant::fromValue(false))); + options.push_back(caf::PdmOptionItemInfo("Horizontal", QVariant::fromValue(true))); + } (*useOptionsOnly) = true; return options; @@ -248,49 +305,24 @@ void RimWellLogPlot::removeTrack(RimWellLogTrack* track) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellLogPlot::removeTrackByIndex(size_t index) +RimWellLogTrack* RimWellLogPlot::trackByIndex(size_t index) { - CVF_ASSERT(index < m_tracks.size()); - - RimWellLogTrack* track = m_tracks[index]; - this->removeTrack(track); + return m_tracks[index]; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimWellLogPlot::moveTracks(RimWellLogTrack* insertAfterTrack, const std::vector& tracksToMove) +size_t RimWellLogPlot::firstVisibleTrackIndex() const { - for (size_t tIdx = 0; tIdx < tracksToMove.size(); tIdx++) + for (size_t i = 0; i < m_tracks.size(); ++i) { - RimWellLogTrack* track = tracksToMove[tIdx]; - - RimWellLogPlot* wellLogPlot; - track->firstAncestorOrThisOfType(wellLogPlot); - if (wellLogPlot) + if (m_tracks[i]->isVisible()) { - wellLogPlot->removeTrack(track); - wellLogPlot->updateTrackNames(); - wellLogPlot->updateConnectedEditors(); + return i; } } - - size_t index = m_tracks.index(insertAfterTrack) + 1; - - for (size_t tIdx = 0; tIdx < tracksToMove.size(); tIdx++) - { - insertTrack(tracksToMove[tIdx], index + tIdx); - } - - updateTrackNames(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellLogTrack* RimWellLogPlot::trackByIndex(size_t index) -{ - return m_tracks[index]; + return std::numeric_limits::max(); } //-------------------------------------------------------------------------------------------------- @@ -395,23 +427,24 @@ void RimWellLogPlot::zoomAll() { setDepthAutoZoom(true); updateDepthZoom(); + updateTracks(true); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QWidget* RimWellLogPlot::viewWidget() +void RimWellLogPlot::setDepthAutoZoom(bool on) { - return m_viewer; + m_isAutoScaleDepthEnabled = on; + m_isAutoScaleDepthEnabled.uiCapability()->updateConnectedEditors(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimWellLogPlot::setDepthAutoZoom(bool on) +void RimWellLogPlot::enableAllAutoNameTags(bool enable) { - m_isAutoScaleDepthEnabled = on; - m_isAutoScaleDepthEnabled.uiCapability()->updateConnectedEditors(); + m_nameConfig->enableAllAutoNameTags(enable); } //-------------------------------------------------------------------------------------------------- @@ -549,35 +582,177 @@ bool RimWellLogPlot::isPltPlotChild() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellLogPlot::uiOrderingForVisibleDepthRange(caf::PdmUiOrdering& uiOrdering) +void RimWellLogPlot::uiOrderingForDepthAxis(caf::PdmUiOrdering& uiOrdering) { - caf::PdmUiGroup* gridGroup = uiOrdering.addNewGroup("Visible Depth Range"); - gridGroup->add(&m_isAutoScaleDepthEnabled); + caf::PdmUiGroup* gridGroup = uiOrdering.addNewGroup("Depth Axis"); + + RimWellRftPlot* rftp = rftPlot(); + if (!(rftp || pltPlot())) + { + gridGroup->add(&m_depthType); + } + + RimWellAllocationPlot* wap; + firstAncestorOrThisOfType(wap); + + if (!(wap || rftp)) + { + gridGroup->add(&m_depthUnit); + } gridGroup->add(&m_minVisibleDepth); gridGroup->add(&m_maxVisibleDepth); + gridGroup->add(&m_depthAxisGridVisibility); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellLogPlot::uiOrderingForPlot(caf::PdmUiOrdering& uiOrdering) +void RimWellLogPlot::uiOrderingForPlotSettings(caf::PdmUiOrdering& uiOrdering) { - RimWellRftPlot* rftp = rftPlot(); + caf::PdmUiGroup* titleAndLegendsGroup = uiOrdering.addNewGroup("Title and Legends"); + titleAndLegendsGroup->add(&m_showTitleInPlot); + titleAndLegendsGroup->add(&m_showTrackLegends); + titleAndLegendsGroup->add(&m_trackLegendsHorizontal); + +} - if (!(rftp || pltPlot())) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogPlot::createAutoName() const +{ + QStringList generatedCurveName; + + if (!m_nameConfig->customName().isEmpty()) { - uiOrdering.add(&m_depthType); + generatedCurveName.push_back(m_nameConfig->customName()); } - RimWellAllocationPlot* wap; - firstAncestorOrThisOfType(wap); + RimCase* commonCase = m_commonDataSource->caseToApply(); + RimWellPath* commonWellPath = m_commonDataSource->wellPathToApply(); - if (!(wap || rftp)) + QStringList generatedAutoTags; + if (m_nameConfig->addCaseName() && commonCase) + { + generatedAutoTags.push_back(commonCase->caseUserDescription()); + } + + if (m_nameConfig->addWellName()) + { + + if (commonWellPath && !commonWellPath->name().isEmpty()) + { + generatedAutoTags.push_back(commonWellPath->name()); + } + else if (!m_commonDataSource->simWellNameToApply().isEmpty()) + { + generatedAutoTags.push_back(m_commonDataSource->simWellNameToApply()); + } + } + + if (m_nameConfig->addTimeStep()) + { + if (commonCase && m_commonDataSource->timeStepToApply() != -1) + { + generatedAutoTags.push_back(commonCase->timeStepName(m_commonDataSource->timeStepToApply())); + } + } + + if (m_nameConfig->addAirGap()) { - uiOrdering.add(&m_depthUnit); + if (commonWellPath) + { + RigWellPath* wellPathGeometry = commonWellPath->wellPathGeometry(); + if (wellPathGeometry) + { + double rkb = wellPathGeometry->rkbDiff(); + generatedAutoTags.push_back(QString("Air Gap = %1 m").arg(rkb)); + } + } + } + + if (m_nameConfig->addWaterDepth()) + { + if (commonWellPath) + { + RigWellPath* wellPathGeometry = commonWellPath->wellPathGeometry(); + if (wellPathGeometry) + { + const std::vector& wellPathPoints = wellPathGeometry->wellPathPoints(); + if (!wellPathPoints.empty()) + { + double tvdmsl = std::abs(wellPathPoints.front()[2]); + generatedAutoTags.push_back(QString("Water Depth = %1 m").arg(tvdmsl)); + } + } + } + } + + if (!generatedAutoTags.empty()) + { + generatedCurveName.push_back(generatedAutoTags.join(", ")); + } + return generatedCurveName.join(": "); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::performHolderUpdate() +{ + this->m_commonDataSource->updateDefaultOptions(); + this->updatePlotTitle(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::handleKeyPressEvent(QKeyEvent* keyEvent) +{ + if (keyEvent->key() == Qt::Key_PageUp) + { + if (keyEvent->modifiers() & Qt::ShiftModifier) + { + m_commonDataSource->applyPrevCase(); + keyEvent->accept(); + } + else if (keyEvent->modifiers() & Qt::ControlModifier) + { + m_commonDataSource->applyPrevWell(); + keyEvent->accept(); + } + else + { + m_commonDataSource->applyPrevTimeStep(); + keyEvent->accept(); + } } + else if (keyEvent->key() == Qt::Key_PageDown) + { + if (keyEvent->modifiers() & Qt::ShiftModifier) + { + m_commonDataSource->applyNextCase(); + keyEvent->accept(); + } + else if (keyEvent->modifiers() & Qt::ControlModifier) + { + m_commonDataSource->applyNextWell(); + keyEvent->accept(); + } + else + { + m_commonDataSource->applyNextTimeStep(); + keyEvent->accept(); + } + } +} - uiOrdering.add(&m_showTrackLegends); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogCurveCommonDataSource* RimWellLogPlot::commonDataSource() const +{ + return m_commonDataSource; } //-------------------------------------------------------------------------------------------------- @@ -595,28 +770,39 @@ void RimWellLogPlot::depthZoomMinMax(double* minimumDepth, double* maximumDepth) //-------------------------------------------------------------------------------------------------- void RimWellLogPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { - uiOrdering.add(&m_userName); - uiOrderingForPlot(uiOrdering); - uiOrderingForVisibleDepthRange(uiOrdering); + m_commonDataSource->uiOrdering(uiConfigName, uiOrdering); + uiOrderingForDepthAxis(uiOrdering); + uiOrderingForPlotSettings(uiOrdering); + + caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup("Plot Name"); + m_nameConfig->uiOrdering(uiConfigName, *nameGroup); uiOrdering.skipRemainingFields(true); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimWellLogPlot::userDescriptionField() +{ + return m_nameConfig->nameField(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellLogPlot::onLoadDataAndUpdate() { updateMdiWindowVisibility(); - - updateTracks(); + updatePlotTitle(); + updateTracks(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellLogPlot::updateTracks() +void RimWellLogPlot::updateTracks(bool autoScaleXAxis) { if (m_showWindow) { @@ -625,10 +811,16 @@ void RimWellLogPlot::updateTracks() for (size_t tIdx = 0; tIdx < m_tracks.size(); ++tIdx) { m_tracks[tIdx]->loadDataAndUpdate(); + if (autoScaleXAxis) + { + m_tracks[tIdx]->setAutoScaleXEnabled(true); + m_tracks[tIdx]->calculateXZoomRangeAndUpdateQwt(); + m_tracks[tIdx]->updateAxisAndGridTickIntervals(); + } } calculateAvailableDepthRange(); - updateDepthZoom(); + applyDepthZoomFromVisibleDepth(); } } @@ -678,6 +870,8 @@ void RimWellLogPlot::applyDepthZoomFromVisibleDepth() //-------------------------------------------------------------------------------------------------- void RimWellLogPlot::applyZoomAllDepths() { + calculateAvailableDepthRange(); + if (hasAvailableDepthRange()) { setDepthZoomMinMax(m_minAvailableDepth, m_maxAvailableDepth + 0.01*(m_maxAvailableDepth - m_minAvailableDepth)); @@ -718,7 +912,7 @@ void RimWellLogPlot::detachAllCurves() //-------------------------------------------------------------------------------------------------- void RimWellLogPlot::setDescription(const QString& description) { - m_userName = description; + m_nameConfig->setCustomName(description); } //-------------------------------------------------------------------------------------------------- @@ -726,7 +920,7 @@ void RimWellLogPlot::setDescription(const QString& description) //-------------------------------------------------------------------------------------------------- QString RimWellLogPlot::description() const { - return m_userName(); + return createAutoName(); } //-------------------------------------------------------------------------------------------------- @@ -735,9 +929,7 @@ QString RimWellLogPlot::description() const QWidget* RimWellLogPlot::createViewWidget(QWidget* mainWindowParent) { m_viewer = new RiuWellLogPlot(this, mainWindowParent); - recreateTrackPlots(); - return m_viewer; } @@ -755,6 +947,18 @@ void RimWellLogPlot::deleteViewWidget() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::initAfterRead() +{ + m_commonDataSource->updateDefaultOptions(); + if (!m_userName_OBSOLETE().isEmpty()) + { + m_nameConfig->setCustomName(m_userName_OBSOLETE()); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -793,7 +997,7 @@ QString RimWellLogPlot::depthPlotTitle() const break; case TRUE_VERTICAL_DEPTH: - depthTitle = "TVD"; + depthTitle = "TVDMSL"; break; case PSEUDO_LENGTH: @@ -823,10 +1027,42 @@ QString RimWellLogPlot::depthPlotTitle() const return depthTitle; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::enableDepthGridLines(AxisGridVisibility gridVisibility) +{ + m_depthAxisGridVisibility = gridVisibility; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlot::AxisGridVisibility RimWellLogPlot::depthGridLinesVisibility() const +{ + return m_depthAxisGridVisibility(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlot::isPlotTitleVisible() const +{ + return m_showTitleInPlot(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::setPlotTitleVisible(bool visible) +{ + m_showTitleInPlot = visible; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimWellLogPlot::isTrackLegendsVisible() const +bool RimWellLogPlot::areTrackLegendsVisible() const { return m_showTrackLegends(); } @@ -839,10 +1075,26 @@ void RimWellLogPlot::setTrackLegendsVisible(bool doShow) m_showTrackLegends = doShow; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlot::areTrackLegendsHorizontal() const +{ + return m_trackLegendsHorizontal; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::setTrackLegendsHorizontal(bool horizontal) +{ + m_trackLegendsHorizontal = horizontal; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RimWellLogPlot::trackIndex(RimWellLogTrack* track) +size_t RimWellLogPlot::trackIndex(const RimWellLogTrack* track) const { return m_tracks.index(track); } @@ -892,3 +1144,15 @@ void RimWellLogPlot::updateDisabledDepthTypes() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlot::updatePlotTitle() +{ + if (m_viewer) + { + m_viewer->setPlotTitle(this->createAutoName()); + + } +} + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlot.h b/ApplicationCode/ProjectDataModel/RimWellLogPlot.h index da12f14bff..8272f9bdc5 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogPlot.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlot.h @@ -19,27 +19,30 @@ #pragma once -#include "cafPdmObject.h" -#include "cafPdmField.h" -#include "cafPdmChildArrayField.h" #include "cafAppEnum.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmChildField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" #include "RiaDefines.h" #include "RimViewWindow.h" +#include "RimWellLogPlotNameConfig.h" #include +class RimWellLogCurveCommonDataSource; class RiuWellLogPlot; class RimWellLogTrack; class RimWellRftPlot; class RimWellPltPlot; - +class QKeyEvent; //================================================================================================== /// /// //================================================================================================== -class RimWellLogPlot : public RimViewWindow +class RimWellLogPlot : public RimViewWindow, public RimNameConfigHolderInterface { CAF_PDM_HEADER_INIT; @@ -52,12 +55,16 @@ class RimWellLogPlot : public RimViewWindow CONNECTION_NUMBER }; + enum AxisGridVisibility { AXIS_GRID_NONE, AXIS_GRID_MAJOR, AXIS_GRID_MAJOR_AND_MINOR }; - + typedef caf::AppEnum AxisGridEnum; public: RimWellLogPlot(); - virtual ~RimWellLogPlot(); + ~RimWellLogPlot() override; + + QWidget* createPlotWidget(); + QWidget* viewWidget() override; void setDescription(const QString& description); QString description() const; @@ -68,23 +75,27 @@ class RimWellLogPlot : public RimViewWindow RiaDefines::DepthUnitType depthUnit() const; void setDepthUnit(RiaDefines::DepthUnitType depthUnit); - QString depthPlotTitle() const; - bool isTrackLegendsVisible() const; + void enableDepthGridLines(AxisGridVisibility gridVisibility); + AxisGridVisibility depthGridLinesVisibility() const; + + bool isPlotTitleVisible() const; + void setPlotTitleVisible(bool visible); + bool areTrackLegendsVisible() const; void setTrackLegendsVisible(bool doShow); + bool areTrackLegendsHorizontal() const; + void setTrackLegendsHorizontal(bool horizontal); void addTrack(RimWellLogTrack* track); void insertTrack(RimWellLogTrack* track, size_t index); size_t trackCount() { return m_tracks.size();} - void removeTrackByIndex(size_t index); void removeTrack(RimWellLogTrack* track); - size_t trackIndex(RimWellLogTrack* track); - void moveTracks(RimWellLogTrack* insertAfterTrack, const std::vector& tracksToMove); - + size_t trackIndex(const RimWellLogTrack* track) const; RimWellLogTrack* trackByIndex(size_t index); + size_t firstVisibleTrackIndex() const; - void updateTracks(); + void updateTracks(bool autoScaleXAxis = false); void updateTrackNames(); void updateDepthZoom(); @@ -97,10 +108,9 @@ class RimWellLogPlot : public RimViewWindow void availableDepthRange(double* minimumDepth, double* maximumDepth) const; bool hasAvailableDepthRange() const; - virtual void zoomAll() override; - virtual QWidget* viewWidget() override; + void zoomAll() override; void setDepthAutoZoom(bool on); - + void enableAllAutoNameTags(bool enable); QString asciiDataForPlotExport() const; @@ -109,20 +119,29 @@ class RimWellLogPlot : public RimViewWindow RimWellPltPlot* pltPlot() const; bool isPltPlotChild() const; - void uiOrderingForVisibleDepthRange(caf::PdmUiOrdering& uiOrdering); - void uiOrderingForPlot(caf::PdmUiOrdering& uiOrdering); + void uiOrderingForDepthAxis(caf::PdmUiOrdering& uiOrdering); + void uiOrderingForPlotSettings(caf::PdmUiOrdering& uiOrdering); + QString createAutoName() const override; + + void handleKeyPressEvent(QKeyEvent* keyEvent); + RimWellLogCurveCommonDataSource* commonDataSource() const; protected: + void performHolderUpdate() override; // Overridden PDM methods - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual caf::PdmFieldHandle* userDescriptionField() override { return &m_userName; } - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void onLoadDataAndUpdate() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + caf::PdmFieldHandle* userDescriptionField() override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void onLoadDataAndUpdate() override; + + QImage snapshotWindowContent() override; - virtual QImage snapshotWindowContent() override; + QWidget* createViewWidget(QWidget* mainWindowParent) override; + void deleteViewWidget() override; + void initAfterRead() override; private: void applyZoomAllDepths(); @@ -131,31 +150,30 @@ class RimWellLogPlot : public RimViewWindow void detachAllCurves(); void updateDisabledDepthTypes(); - -public: // Needed by RiuWellAllocation Plot - // RimViewWindow overrides - - virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; - virtual void deleteViewWidget() override; + void updatePlotTitle(); private: - caf::PdmField m_userName; + caf::PdmField m_userName_OBSOLETE; + caf::PdmChildField m_commonDataSource; + caf::PdmChildArrayField m_tracks; + + caf::PdmField< caf::AppEnum> m_depthType; + caf::PdmField< caf::AppEnum> m_depthUnit; + std::set m_disabledDepthTypes; + caf::PdmField m_minVisibleDepth; + caf::PdmField m_maxVisibleDepth; + caf::PdmField m_depthAxisGridVisibility; + caf::PdmField m_isAutoScaleDepthEnabled; - caf::PdmField< caf::AppEnum< DepthTypeEnum > > m_depthType; - caf::PdmField< caf::AppEnum< RiaDefines::DepthUnitType > > m_depthUnit; - std::set m_disabledDepthTypes; + caf::PdmField m_showTitleInPlot; + caf::PdmField m_showTrackLegends; + caf::PdmField m_trackLegendsHorizontal; - caf::PdmChildArrayField m_tracks; + caf::PdmChildField m_nameConfig; - caf::PdmField m_minVisibleDepth; - caf::PdmField m_maxVisibleDepth; - caf::PdmField m_isAutoScaleDepthEnabled; - caf::PdmField m_showTrackLegends; - - double m_minAvailableDepth; - double m_maxAvailableDepth; + double m_minAvailableDepth; + double m_maxAvailableDepth; friend class RiuWellLogPlot; - QPointer m_viewer; - + QPointer m_viewer; }; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp index f89bf09c5a..fcd8254ae1 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.cpp @@ -134,6 +134,26 @@ RigGeoMechWellLogExtractor* RimWellLogPlotCollection::findOrCreateExtractor(RimW return extractor.p(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCollection::reloadAllPlots() +{ + for (const auto& w : wellLogPlots()) + { + w->loadDataAndUpdate(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotCollection::deleteAllExtractors() +{ + m_extractors.clear(); + m_geomExtractors.clear(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.h b/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.h index 11990bffbe..f0b994bb56 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotCollection.h @@ -44,7 +44,7 @@ class RimWellLogPlotCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimWellLogPlotCollection(); - virtual ~RimWellLogPlotCollection(); + ~RimWellLogPlotCollection() override; RigEclipseWellLogExtractor* findOrCreateSimWellExtractor(const QString& simWellName, const QString& caseUserDescription, @@ -54,6 +54,9 @@ class RimWellLogPlotCollection : public caf::PdmObject RigEclipseWellLogExtractor* findOrCreateExtractor(RimWellPath* wellPath, RimEclipseCase* eclCase); RigGeoMechWellLogExtractor* findOrCreateExtractor(RimWellPath* wellPath, RimGeoMechCase* eclCase); + void reloadAllPlots(); + + void deleteAllExtractors(); void removeExtractors(const RigWellPath* wellPath); void removeExtractors(const RigEclipseCaseData* caseData); void removeExtractors(const RigGeoMechCaseData* caseData); diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotNameConfig.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlotNameConfig.cpp new file mode 100644 index 0000000000..2649ed1ca2 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotNameConfig.cpp @@ -0,0 +1,109 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogPlotNameConfig.h" + +//================================================================================================== +/// +/// +//================================================================================================== + +CAF_PDM_SOURCE_INIT(RimWellLogPlotNameConfig, "RimWellLogPlotNameConfig"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogPlotNameConfig::RimWellLogPlotNameConfig(const RimNameConfigHolderInterface* configHolder) + : RimNameConfig(configHolder) +{ + CAF_PDM_InitObject("Well Log Plot Name Generator", "", "", ""); + + CAF_PDM_InitField(&m_addCaseName, "AddCaseName", false, "Add Case Name", "", "", ""); + CAF_PDM_InitField(&m_addWellName, "AddWellName", false, "Add Well Name", "", "", ""); + CAF_PDM_InitField(&m_addTimestep, "AddTimeStep", false, "Add Time Step", "", "", ""); + CAF_PDM_InitField(&m_addAirGap, "AddAirGap", false, "Add Air Gap", "", "", ""); + CAF_PDM_InitField(&m_addWaterDepth, "AddWaterDepth", false, "Add Water Depth", "", "", ""); + + m_customName = "Well Log Plot"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlotNameConfig::addCaseName() const +{ + return m_addCaseName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlotNameConfig::addWellName() const +{ + return m_addWellName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlotNameConfig::addTimeStep() const +{ + return m_addTimestep(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlotNameConfig::addAirGap() const +{ + return m_addAirGap(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlotNameConfig::addWaterDepth() const +{ + return m_addWaterDepth(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotNameConfig::enableAllAutoNameTags(bool enable) +{ + m_addCaseName = enable; + m_addWellName = enable; + m_addTimestep = enable; + m_addAirGap = enable; + m_addWaterDepth = enable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogPlotNameConfig::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + RimNameConfig::defineUiOrdering(uiConfigName, uiOrdering); + uiOrdering.add(&m_addCaseName); + uiOrdering.add(&m_addWellName); + uiOrdering.add(&m_addTimestep); + uiOrdering.add(&m_addAirGap); + uiOrdering.add(&m_addWaterDepth); +} + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlotNameConfig.h b/ApplicationCode/ProjectDataModel/RimWellLogPlotNameConfig.h new file mode 100644 index 0000000000..337c9703b8 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlotNameConfig.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimNameConfig.h" + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogPlotNameConfig : public RimNameConfig +{ + CAF_PDM_HEADER_INIT; + +public: + RimWellLogPlotNameConfig(const RimNameConfigHolderInterface* configHolder = nullptr); + + bool addCaseName() const; + bool addWellName() const; + bool addTimeStep() const; + bool addAirGap() const; + bool addWaterDepth() const; + void enableAllAutoNameTags(bool enable) override; + +protected: + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +private: + caf::PdmField m_addCaseName; + caf::PdmField m_addWellName; + caf::PdmField m_addTimestep; + caf::PdmField m_addAirGap; + caf::PdmField m_addWaterDepth; +}; + + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.cpp index b583f9e4ab..202dd0e0cd 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.cpp @@ -21,6 +21,7 @@ #include "RiaApplication.h" #include "RiaEclipseUnitTools.h" +#include "RiaQDateTimeTools.h" #include "RiaSimWellBranchTools.h" #include "RifEclipseRftAddress.h" @@ -43,7 +44,7 @@ #include "RimWellPath.h" #include "RimWellPlotTools.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuWellLogTrack.h" #include "cafPdmObject.h" @@ -335,9 +336,13 @@ void RimWellLogRftCurve::onLoadDataAndUpdate(bool updateParentPlot) m_qwtPlotCurve->setLineSegmentStartStopIndices(m_curveData->polylineStartStopIndices()); - if ( updateParentPlot && m_parentQwtPlot) + if (updateParentPlot) { updateZoomInParentPlot(); + } + + if (m_parentQwtPlot) + { m_parentQwtPlot->replot(); } } @@ -426,7 +431,9 @@ QList RimWellLogRftCurve::calculateValueOptions(const ca std::vector timeStamps = reader->availableTimeSteps(m_wellName, m_wellLogChannelName()); for (const QDateTime& dt : timeStamps) { - options.push_back(caf::PdmOptionItemInfo(dt.toString(dateFormat), dt)); + QString dateString = RiaQDateTimeTools::toStringUsingApplicationLocale(dt, dateFormat); + + options.push_back(caf::PdmOptionItemInfo(dateString, dt)); } } @@ -705,7 +712,7 @@ std::vector RimWellLogRftCurve::measuredDepthValues() if (!eclExtractor) return measuredDepthForCells; - std::vector measuredDepthForIntersections = eclExtractor->measuredDepth(); + std::vector measuredDepthForIntersections = eclExtractor->cellIntersectionMDs(); if (measuredDepthForIntersections.empty()) { diff --git a/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.h b/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.h index 3652f74d68..564e60353a 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogRftCurve.h @@ -46,10 +46,10 @@ class RimWellLogRftCurve : public RimWellLogCurve public: RimWellLogRftCurve(); - virtual ~RimWellLogRftCurve(); + ~RimWellLogRftCurve() override; - virtual QString wellName() const override; - virtual QString wellLogChannelName() const override; + QString wellName() const override; + QString wellLogChannelName() const override; void setEclipseResultCase(RimEclipseResultCase* eclipseResultCase); RimEclipseResultCase* eclipseResultCase() const; @@ -64,13 +64,13 @@ class RimWellLogRftCurve : public RimWellLogCurve protected: // Overrides from RimWellLogPlotCurve - virtual QString createCurveAutoName() override; - virtual void onLoadDataAndUpdate(bool updateParentPlot) override; + QString createCurveAutoName() override; + void onLoadDataAndUpdate(bool updateParentPlot) override; // Pdm overrrides - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: RifReaderEclipseRft* rftReader() const; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogRftCurveNameConfig.cpp b/ApplicationCode/ProjectDataModel/RimWellLogRftCurveNameConfig.cpp new file mode 100644 index 0000000000..22851c48f7 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogRftCurveNameConfig.cpp @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellLogRftCurveNameConfig.h" + +//================================================================================================== +/// +/// +//================================================================================================== + +CAF_PDM_SOURCE_INIT(RimWellLogRftCurveNameConfig, "RimWellLogRftCurveNameConfig"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogRftCurveNameConfig::RimWellLogRftCurveNameConfig(const RimNameConfigHolderInterface* configHolder) + : RimNameConfig(configHolder) +{ + CAF_PDM_InitObject("Well Log Rft Curve Name Generator", "", "", ""); + m_customName = "Rft Curve"; +} + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogRftCurveNameConfig.h b/ApplicationCode/ProjectDataModel/RimWellLogRftCurveNameConfig.h new file mode 100644 index 0000000000..438f874e4d --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellLogRftCurveNameConfig.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RimNameConfig.h" + +//================================================================================================== +/// +/// +//================================================================================================== +class RimWellLogRftCurveNameConfig : public RimNameConfig +{ + CAF_PDM_HEADER_INIT; + +public: + RimWellLogRftCurveNameConfig(const RimNameConfigHolderInterface* configHolder = nullptr); +}; + diff --git a/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp b/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp index d3c8bcbde5..09f1ebf484 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp @@ -20,6 +20,9 @@ #include "RimWellLogTrack.h" #include "RiaApplication.h" +#include "RiaColorTables.h" +#include "RiaExtractionTools.h" +#include "RiaSimWellBranchTools.h" #include "RigEclipseCaseData.h" #include "RigEclipseWellLogExtractor.h" @@ -41,29 +44,37 @@ #include "RimEclipseCase.h" #include "RimGeoMechCase.h" #include "RimMainPlotCollection.h" +#include "RimFishbonesCollection.h" +#include "RimFishbonesMultipleSubs.h" +#include "RimPerforationCollection.h" +#include "RimPerforationInterval.h" #include "RimProject.h" #include "RimTools.h" +#include "RimWellPathAttribute.h" +#include "RimWellPathAttributeCollection.h" +#include "RimWellPathFracture.h" +#include "RimWellPathFractureCollection.h" #include "RimWellFlowRateCurve.h" #include "RimWellLogCurve.h" #include "RimWellLogPlotCollection.h" #include "RimWellPath.h" +#include "RimWellPathCompletions.h" #include "RimWellPltPlot.h" #include "RimWellRftPlot.h" #include "RiuMainWindow.h" #include "RiuPlotAnnotationTool.h" +#include "RiuPlotMainWindowTools.h" +#include "RiuWellPathComponentPlotItem.h" #include "RiuWellLogPlot.h" #include "RiuWellLogTrack.h" +#include "RiuQwtLinearScaleEngine.h" #include "cvfAssert.h" -#include "qwt_scale_engine.h" -#include "RiaSimWellBranchTools.h" -#include "RiaExtractionTools.h" - #define RI_LOGPLOTTRACK_MINX_DEFAULT -10.0 #define RI_LOGPLOTTRACK_MAXX_DEFAULT 100.0 - +#define RI_LOGPLOTTRACK_MINOR_TICK_DEFAULT CAF_PDM_SOURCE_INIT(RimWellLogTrack, "WellLogPlotTrack"); @@ -81,7 +92,7 @@ namespace caf void AppEnum< RimWellLogTrack::FormationSource >::setUp() { addItem(RimWellLogTrack::CASE, "CASE", "Case"); - addItem(RimWellLogTrack::WELL_PICK_FILTER, "WELL_PICK_FILTER", "Well Path"); + addItem(RimWellLogTrack::WELL_PICK_FILTER, "WELL_PICK_FILTER", "Well Picks for Well Path"); setDefault(RimWellLogTrack::CASE); } @@ -104,6 +115,17 @@ namespace caf addItem(RigWellPathFormations::LEVEL10, "LEVEL10", "Formation 10"); setDefault(RigWellPathFormations::ALL); } + + template<> + void AppEnum< RimWellLogTrack::WidthScaleFactor >::setUp() + { + addItem(RimWellLogTrack::EXTRA_NARROW_TRACK, "EXTRA_NARROW_TRACK", "Extra Narrow"); + addItem(RimWellLogTrack::NARROW_TRACK, "NARROW_TRACK", "Narrow"); + addItem(RimWellLogTrack::NORMAL_TRACK, "NORMAL_TRACK", "Normal"); + addItem(RimWellLogTrack::WIDE_TRACK, "WIDE_TRACK", "Wide"); + addItem(RimWellLogTrack::EXTRA_WIDE_TRACK, "EXTRA_WIDE_TRACK", "Extra wide"); + setDefault(RimWellLogTrack::NORMAL_TRACK); + } } @@ -127,10 +149,20 @@ RimWellLogTrack::RimWellLogTrack() CAF_PDM_InitField(&m_visibleXRangeMax, "VisibleXRangeMax", RI_LOGPLOTTRACK_MAXX_DEFAULT, "Max", "", "", ""); CAF_PDM_InitField(&m_isAutoScaleXEnabled, "AutoScaleX", true, "Auto Scale", "", "", ""); + m_isAutoScaleXEnabled.uiCapability()->setUiHidden(true); CAF_PDM_InitField(&m_isLogarithmicScaleEnabled, "LogarithmicScaleX", false, "Logarithmic Scale", "", "", ""); - CAF_PDM_InitField(&m_showFormations, "ShowFormations", false, "Show", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_xAxisGridVisibility, "ShowXGridLines", "Show Grid Lines", "", "", ""); + + CAF_PDM_InitField(&m_explicitTickIntervals, "ExplicitTickIntervals", false, "Manually Set Tick Intervals", "", "", ""); + CAF_PDM_InitField(&m_majorTickInterval, "MajorTickIntervals", 0.0, "Major Tick Interval", "", "", ""); + CAF_PDM_InitField(&m_minorTickInterval, "MinorTickIntervals", 0.0, "Minor Tick Interval", "", "", ""); + m_majorTickInterval.uiCapability()->setUiHidden(true); + m_minorTickInterval.uiCapability()->setUiHidden(true); + + CAF_PDM_InitField(&m_showFormations, "ShowFormations", false, "Show Lines", "", "", ""); + CAF_PDM_InitField(&m_showFormationLabels, "ShowFormationLabels", true, "Show Labels", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_formationSource, "FormationSource", "Source", "", "", ""); @@ -154,6 +186,17 @@ RimWellLogTrack::RimWellLogTrack() CAF_PDM_InitField(&m_showformationFluids, "ShowFormationFluids", false, "Show Fluids", "", "", ""); + CAF_PDM_InitField(&m_showWellPathAttributes, "ShowWellPathAttributes", false, "Show Well Attributes", "", "", ""); + CAF_PDM_InitField(&m_wellPathAttributesInLegend, "WellPathAttributesInLegend", false, "Attributes in Legend", "", "", ""); + CAF_PDM_InitField(&m_showWellPathCompletions, "ShowWellPathCompletions", true, "Show Well Completions", "", "", ""); + CAF_PDM_InitField(&m_wellPathCompletionsInLegend, "WellPathCompletionsInLegend", false, "Completions in Legend", "", "", ""); + CAF_PDM_InitField(&m_showWellPathComponentsBothSides, "ShowWellPathAttrBothSides", true, "Show Both Sides", "", "", ""); + CAF_PDM_InitField(&m_showWellPathComponentLabels, "ShowWellPathAttrLabels", false, "Show Labels", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_wellPathComponentSource, "AttributesWellPathSource", "Well Path", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_wellPathAttributeCollection, "AttributesCollection", "Well Attributes", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_widthScaleFactor, "Width", "Track Width", "", "Set width of track. ", ""); + m_formationsForCaseWithSimWellOnly = false; } @@ -220,41 +263,67 @@ void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, m_wellLogTrackPlotWidget->setVisible(m_show()); } - RimWellLogPlot* wellLogPlot; - this->firstAncestorOrThisOfType(wellLogPlot); - if (wellLogPlot) + updateParentPlotLayout(); + } + else if (changedField == &m_widthScaleFactor) + { + updateParentPlotLayout(); + updateAxisAndGridTickIntervals(); + applyXZoomFromVisibleRange(); + } + else if (changedField == &m_explicitTickIntervals) + { + if (m_wellLogTrackPlotWidget) { - wellLogPlot->calculateAvailableDepthRange(); - wellLogPlot->updateDepthZoom(); - - RiuWellLogPlot* wellLogPlotViewer = dynamic_cast(wellLogPlot->viewWidget()); - if (wellLogPlotViewer) - { - wellLogPlotViewer->updateChildrenLayout(); - } + m_majorTickInterval = m_wellLogTrackPlotWidget->getCurrentMajorTickInterval(); + m_minorTickInterval = m_wellLogTrackPlotWidget->getCurrentMinorTickInterval(); + } + m_majorTickInterval.uiCapability()->setUiHidden(!m_explicitTickIntervals()); + m_minorTickInterval.uiCapability()->setUiHidden(!m_explicitTickIntervals()); + if (!m_explicitTickIntervals()) + { + updateAxisAndGridTickIntervals(); } } + else if (changedField == &m_xAxisGridVisibility || + changedField == &m_majorTickInterval || + changedField == &m_minorTickInterval) + { + updateAxisAndGridTickIntervals(); + } else if (changedField == &m_visibleXRangeMin || changedField == &m_visibleXRangeMax) { m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax); m_wellLogTrackPlotWidget->replot(); m_isAutoScaleXEnabled = false; + bool emptyRange = std::abs(m_visibleXRangeMax() - m_visibleXRangeMin) < 1.0e-6 * std::max(1.0, std::max(m_visibleXRangeMax(), m_visibleXRangeMin())); + m_explicitTickIntervals.uiCapability()->setUiReadOnly(emptyRange); + m_xAxisGridVisibility.uiCapability()->setUiReadOnly(emptyRange); + + updateEditors(); + updateParentPlotLayout(); + updateAxisAndGridTickIntervals(); } else if (changedField == &m_isAutoScaleXEnabled) { if (m_isAutoScaleXEnabled()) { - this->updateXZoom(); + this->calculateXZoomRangeAndUpdateQwt(); computeAndSetXRangeMinForLogarithmicScale(); if (m_wellLogTrackPlotWidget) m_wellLogTrackPlotWidget->replot(); - } + } } else if (changedField == &m_isLogarithmicScaleEnabled) { updateAxisScaleEngine(); + if (m_isLogarithmicScaleEnabled()) + { + m_explicitTickIntervals = false; + } + m_explicitTickIntervals.uiCapability()->setUiHidden(m_isLogarithmicScaleEnabled()); - this->updateXZoom(); + this->calculateXZoomRangeAndUpdateQwt(); computeAndSetXRangeMinForLogarithmicScale(); m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax); @@ -277,7 +346,8 @@ void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, } } - loadDataAndUpdate(); + loadDataAndUpdate(true); + RimWellRftPlot* rftPlot(nullptr); firstAncestorOrThisOfType(rftPlot); @@ -297,6 +367,10 @@ void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, } } } + else if (changedField == &m_showFormationLabels) + { + loadDataAndUpdate(); + } else if (changedField == &m_formationCase) { QList options; @@ -307,15 +381,15 @@ void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, m_formationSimWellName = QString("None"); } - loadDataAndUpdate(); + loadDataAndUpdate(true); } else if (changedField == &m_formationWellPathForSourceCase) { - loadDataAndUpdate(); + loadDataAndUpdate(true); } else if (changedField == &m_formationSimWellName) { - loadDataAndUpdate(); + loadDataAndUpdate(true); } else if (changedField == &m_formationTrajectoryType) { @@ -328,22 +402,22 @@ void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, { if (m_formationWellPathForSourceCase) { - m_formationSimWellName = m_formationWellPathForSourceCase->m_simWellName; + m_formationSimWellName = m_formationWellPathForSourceCase->associatedSimulationWellName(); } } - loadDataAndUpdate(); + loadDataAndUpdate(true); } else if (changedField == &m_formationBranchIndex || changedField == &m_formationBranchDetection) { m_formationBranchIndex = RiaSimWellBranchTools::clampBranchIndex(m_formationSimWellName, m_formationBranchIndex, m_formationBranchDetection); - loadDataAndUpdate(); + loadDataAndUpdate(true); } else if (changedField == &m_formationWellPathForSourceWellPath) { - loadDataAndUpdate(); + loadDataAndUpdate(true); } else if (changedField == &m_formationLevel) { @@ -353,6 +427,124 @@ void RimWellLogTrack::fieldChangedByUi(const caf::PdmFieldHandle* changedField, { loadDataAndUpdate(); } + else if (changedField == &m_showWellPathAttributes || + changedField == &m_showWellPathCompletions || + changedField == &m_showWellPathComponentsBothSides || + changedField == &m_showWellPathComponentLabels || + changedField == &m_wellPathAttributesInLegend || + changedField == &m_wellPathCompletionsInLegend) + { + updateWellPathAttributesOnPlot(); + updateParentPlotLayout(); + RiuPlotMainWindowTools::refreshToolbars(); + } + else if (changedField == &m_wellPathComponentSource) + { + updateWellPathAttributesCollection(); + updateWellPathAttributesOnPlot(); + updateParentPlotLayout(); + RiuPlotMainWindowTools::refreshToolbars(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::updateParentPlotLayout() +{ + RimWellLogPlot* wellLogPlot; + this->firstAncestorOrThisOfType(wellLogPlot); + if (wellLogPlot) + { + RiuWellLogPlot* wellLogPlotViewer = dynamic_cast(wellLogPlot->viewWidget()); + if (wellLogPlotViewer) + { + wellLogPlotViewer->updateChildrenLayout(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::updateAxisAndGridTickIntervals() +{ + if (!m_wellLogTrackPlotWidget) return; + + if (m_explicitTickIntervals) + { + m_wellLogTrackPlotWidget->setMajorAndMinorTickIntervals(m_majorTickInterval(), m_minorTickInterval()); + } + else + { + int xMajorTickIntervals = 3; + int xMinorTickIntervals = 0; + switch (m_widthScaleFactor()) + { + case EXTRA_NARROW_TRACK: + xMajorTickIntervals = 3; + xMinorTickIntervals = 2; + break; + case NARROW_TRACK: + xMajorTickIntervals = 3; + xMinorTickIntervals = 5; + break; + case NORMAL_TRACK: + xMajorTickIntervals = 5; + xMinorTickIntervals = 5; + break; + case WIDE_TRACK: + xMajorTickIntervals = 5; + xMinorTickIntervals = 10; + break; + case EXTRA_WIDE_TRACK: + xMajorTickIntervals = 10; + xMinorTickIntervals = 10; + break; + } + m_wellLogTrackPlotWidget->setAutoTickIntervalCounts(xMajorTickIntervals, xMinorTickIntervals); + } + + switch (m_xAxisGridVisibility()) + { + case RimWellLogPlot::AXIS_GRID_NONE: + m_wellLogTrackPlotWidget->enableXGridLines(false, false); + break; + case RimWellLogPlot::AXIS_GRID_MAJOR: + m_wellLogTrackPlotWidget->enableXGridLines(true, false); + break; + case RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR: + m_wellLogTrackPlotWidget->enableXGridLines(true, true); + break; + } + + RimWellLogPlot* plot = nullptr; + this->firstAncestorOrThisOfTypeAsserted(plot); + switch (plot->depthGridLinesVisibility()) + { + case RimWellLogPlot::AXIS_GRID_NONE: + m_wellLogTrackPlotWidget->enableDepthGridLines(false, false); + break; + case RimWellLogPlot::AXIS_GRID_MAJOR: + m_wellLogTrackPlotWidget->enableDepthGridLines(true, false); + break; + case RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR: + m_wellLogTrackPlotWidget->enableDepthGridLines(true, true); + break; + } + m_wellLogTrackPlotWidget->replot(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::updateAllLegendItems() +{ + reattachAllCurves(); + if (m_wellLogTrackPlotWidget) + { + m_wellLogTrackPlotWidget->updateLegend(); + } } //-------------------------------------------------------------------------------------------------- @@ -415,7 +607,11 @@ QList RimWellLogTrack::calculateValueOptions(const caf:: } } } - + else if (fieldNeedingOptions == &m_wellPathComponentSource) + { + RimTools::wellPathOptionItems(&options); + options.push_front(caf::PdmOptionItemInfo("None", nullptr)); + } return options; } @@ -499,14 +695,12 @@ void RimWellLogTrack::availableDepthRange(double* minimumDepth, double* maximumD double minDepth = HUGE_VAL; double maxDepth = -HUGE_VAL; - size_t curveCount = curves.size(); - - for (size_t cIdx = 0; cIdx < curveCount; cIdx++) + for (RimPlotCurve* curve : curves) { double minCurveDepth = HUGE_VAL; double maxCurveDepth = -HUGE_VAL; - if (curves[cIdx]->isCurveVisible() && curves[cIdx]->depthRange(&minCurveDepth, &maxCurveDepth)) + if (curve->isCurveVisible() && curve->yValueRange(&minCurveDepth, &maxCurveDepth)) { if (minCurveDepth < minDepth) { @@ -520,6 +714,27 @@ void RimWellLogTrack::availableDepthRange(double* minimumDepth, double* maximumD } } + if (m_showWellPathAttributes || m_showWellPathCompletions) + { + for (const std::unique_ptr& plotObject : m_wellPathAttributePlotObjects) + { + double minObjectDepth = HUGE_VAL; + double maxObjectDepth = -HUGE_VAL; + if (plotObject->yValueRange(&minObjectDepth, &maxObjectDepth)) + { + if (minObjectDepth < minDepth) + { + minDepth = minObjectDepth; + } + + if (maxObjectDepth > maxDepth) + { + maxDepth = maxObjectDepth; + } + } + } + } + *minimumDepth = minDepth; *maximumDepth = maxDepth; } @@ -527,14 +742,17 @@ void RimWellLogTrack::availableDepthRange(double* minimumDepth, double* maximumD //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellLogTrack::loadDataAndUpdate() +void RimWellLogTrack::loadDataAndUpdate(bool updateParentPlotAndToolbars) { RimWellLogPlot* wellLogPlot = nullptr; firstAncestorOrThisOfType(wellLogPlot); if (wellLogPlot && m_wellLogTrackPlotWidget) { - m_wellLogTrackPlotWidget->setDepthTitle(wellLogPlot->depthPlotTitle()); + if (isFirstVisibleTrackInPlot()) + { + m_wellLogTrackPlotWidget->setDepthTitle(wellLogPlot->depthPlotTitle()); + } m_wellLogTrackPlotWidget->setXTitle(m_xAxisTitle); } @@ -554,10 +772,29 @@ void RimWellLogTrack::loadDataAndUpdate() if ( m_wellLogTrackPlotWidget ) { + this->updateWellPathAttributesCollection(); + this->updateWellPathAttributesOnPlot(); m_wellLogTrackPlotWidget->updateLegend(); + this->updateAxisScaleEngine(); this->updateFormationNamesOnPlot(); - this->updateXZoomAndParentPlotDepthZoom(); + this->applyXZoomFromVisibleRange(); + } + + this->updateAxisAndGridTickIntervals(); + m_majorTickInterval.uiCapability()->setUiHidden(!m_explicitTickIntervals()); + m_minorTickInterval.uiCapability()->setUiHidden(!m_explicitTickIntervals()); + + bool emptyRange = std::abs(m_visibleXRangeMax() - m_visibleXRangeMin) < 1.0e-6 * std::max(1.0, std::max(m_visibleXRangeMax(), m_visibleXRangeMin())); + m_explicitTickIntervals.uiCapability()->setUiReadOnly(emptyRange); + m_xAxisGridVisibility.uiCapability()->setUiReadOnly(emptyRange); + + updateAllLegendItems(); + + if (updateParentPlotAndToolbars) + { + updateParentPlotLayout(); + RiuPlotMainWindowTools::refreshToolbars(); } } @@ -609,6 +846,14 @@ void RimWellLogTrack::setAndUpdateSimWellFormationNamesData(RimCase* rimCase, co } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::setAutoScaleXEnabled(bool enabled) +{ + m_isAutoScaleXEnabled = enabled; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -617,6 +862,33 @@ void RimWellLogTrack::setXAxisTitle(const QString& text) m_xAxisTitle = text; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellLogTrack::depthPlotTitle() const +{ + RimWellLogPlot* parent; + this->firstAncestorOrThisOfTypeAsserted(parent); + + return parent->depthPlotTitle(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimWellLogTrack::widthScaleFactor() const +{ + return static_cast(m_widthScaleFactor()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::setWidthScaleFactor(WidthScaleFactor scaleFactor) +{ + m_widthScaleFactor = scaleFactor; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -625,6 +897,14 @@ void RimWellLogTrack::setFormationWellPath(RimWellPath* wellPath) m_formationWellPathForSourceCase = wellPath; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RimWellLogTrack::formationWellPath() const +{ + return m_formationWellPathForSourceCase; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -689,16 +969,35 @@ void RimWellLogTrack::recreateViewer() //-------------------------------------------------------------------------------------------------- void RimWellLogTrack::detachAllCurves() { - for (size_t cIdx = 0; cIdx < curves.size(); ++cIdx) + for (RimPlotCurve* curve : curves) + { + curve->detachQwtCurve(); + } + for (auto& plotObjects : m_wellPathAttributePlotObjects) + { + plotObjects->detachFromQwt(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::reattachAllCurves() +{ + for (RimPlotCurve* curve : curves) { - curves[cIdx]->detachQwtCurve(); + curve->reattachQwtCurve(); + } + for (auto& plotObjects : m_wellPathAttributePlotObjects) + { + plotObjects->reattachToQwt(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellLogTrack::updateXZoomAndParentPlotDepthZoom() +void RimWellLogTrack::updateParentPlotZoom() { if (m_wellLogTrackPlotWidget) { @@ -708,17 +1007,45 @@ void RimWellLogTrack::updateXZoomAndParentPlotDepthZoom() { wellLogPlot->updateDepthZoom(); } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::calculateXZoomRangeAndUpdateQwt() +{ + this->calculateXZoomRange(); + this->applyXZoomFromVisibleRange(); +} - updateXZoom(); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::applyXZoomFromVisibleRange() +{ + if (!m_wellLogTrackPlotWidget) return; - m_wellLogTrackPlotWidget->replot(); + m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax); + + // Attribute range. Fixed range where well components are positioned [-1, 1]. + // Set an extended range here to allow for some label space. + double componentRangeMax = 1.5 * (10.0 / (m_widthScaleFactor())); + double componentRangeMin = -0.25; + if (m_showWellPathComponentsBothSides) + { + componentRangeMin = -1.5; } + + m_wellLogTrackPlotWidget->setXRange(componentRangeMin, componentRangeMax, QwtPlot::xBottom); + + m_wellLogTrackPlotWidget->replot(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellLogTrack::updateXZoom() +void RimWellLogTrack::calculateXZoomRange() { std::map> stackCurveGroups = visibleStackedCurves(); for (const std::pair>& curveGroup : stackCurveGroups) @@ -728,51 +1055,120 @@ void RimWellLogTrack::updateXZoom() if (!m_isAutoScaleXEnabled()) { - if (m_wellLogTrackPlotWidget) - { - m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax); - m_wellLogTrackPlotWidget->replot(); - } - return; } double minValue = HUGE_VAL; double maxValue = -HUGE_VAL; - for (size_t cIdx = 0; cIdx < curves.size(); cIdx++) + size_t visibleCurves = 0u; + for (auto curve : curves) { double minCurveValue = HUGE_VAL; double maxCurveValue = -HUGE_VAL; - if (curves[cIdx]->isCurveVisible() && curves[cIdx]->valueRange(&minCurveValue, &maxCurveValue)) + if (curve->isCurveVisible()) { - if (minCurveValue < minValue) + visibleCurves++; + if (curve->xValueRange(&minCurveValue, &maxCurveValue)) { - minValue = minCurveValue; - } + if (minCurveValue < minValue) + { + minValue = minCurveValue; + } - if (maxCurveValue > maxValue) - { - maxValue = maxCurveValue; + if (maxCurveValue > maxValue) + { + maxValue = maxCurveValue; + } } } } if (minValue == HUGE_VAL) { - minValue = RI_LOGPLOTTRACK_MINX_DEFAULT; - maxValue = RI_LOGPLOTTRACK_MAXX_DEFAULT; + if (visibleCurves) + { + minValue = RI_LOGPLOTTRACK_MINX_DEFAULT; + maxValue = RI_LOGPLOTTRACK_MAXX_DEFAULT; + } + else + { + // Empty axis when there are no curves + minValue = 0; + maxValue = 0; + } + } + + if (m_minorTickInterval() != 0.0) + { + std::tie(minValue, maxValue) = adjustXRange(minValue, maxValue, m_minorTickInterval()); } m_visibleXRangeMin = minValue; m_visibleXRangeMax = maxValue; computeAndSetXRangeMinForLogarithmicScale(); + updateEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::updateEditors() +{ + this->updateConnectedEditors(); - if (m_wellLogTrackPlotWidget) m_wellLogTrackPlotWidget->setXRange(m_visibleXRangeMin, m_visibleXRangeMax); + RimWellLogPlot* plot = nullptr; + firstAncestorOrThisOfTypeAsserted(plot); + plot->updateConnectedEditors(); - updateConnectedEditors(); + RimWellRftPlot* rftPlot(nullptr); + + firstAncestorOrThisOfType(rftPlot); + + if (rftPlot) + { + rftPlot->updateConnectedEditors(); + } + else + { + RimWellPltPlot* pltPlot(nullptr); + firstAncestorOrThisOfType(pltPlot); + + if (pltPlot) + { + pltPlot->updateConnectedEditors(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::setVisibleXRange(double minValue, double maxValue) +{ + this->setAutoScaleXEnabled(false); + m_visibleXRangeMin = minValue; + m_visibleXRangeMax = maxValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::setTickIntervals(double majorTickInterval, double minorTickInterval) +{ + m_explicitTickIntervals = true; + m_majorTickInterval = majorTickInterval; + m_minorTickInterval = minorTickInterval; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::setXAxisGridVisibility(RimWellLogPlot::AxisGridVisibility gridLines) +{ + m_xAxisGridVisibility = gridLines; } //-------------------------------------------------------------------------------------------------- @@ -783,6 +1179,55 @@ void RimWellLogTrack::setShowFormations(bool on) m_showFormations = on; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogTrack::showFormations() const +{ + return m_showFormations; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::setShowFormationLabels(bool on) +{ + m_showFormationLabels = on; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogTrack::showWellPathAttributes() const +{ + return m_showWellPathAttributes; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::setShowWellPathAttributes(bool on) +{ + m_showWellPathAttributes = on; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::setWellPathAttributesSource(RimWellPath* wellPath) +{ + m_wellPathComponentSource = wellPath; + updateWellPathAttributesCollection(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPath* RimWellLogTrack::wellPathAttributeSource() const +{ + return m_wellPathComponentSource; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -805,10 +1250,10 @@ RimWellLogCurve* RimWellLogTrack::curveDefinitionFromCurve(const QwtPlotCurve* c void RimWellLogTrack::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { uiOrdering.add(&m_userName); - caf::PdmUiGroup* formationGroup = uiOrdering.addNewGroup("Zonation/Formation Names"); formationGroup->add(&m_showFormations); + formationGroup->add(&m_showFormationLabels); if (!m_formationsForCaseWithSimWellOnly) { @@ -853,7 +1298,20 @@ void RimWellLogTrack::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& } } - uiOrderingForVisibleXRange(uiOrdering); + caf::PdmUiGroup* componentGroup = uiOrdering.addNewGroup("Well Path Components"); + componentGroup->add(&m_showWellPathAttributes); + componentGroup->add(&m_showWellPathCompletions); + componentGroup->add(&m_wellPathAttributesInLegend); + componentGroup->add(&m_wellPathCompletionsInLegend); + componentGroup->add(&m_showWellPathComponentsBothSides); + componentGroup->add(&m_showWellPathComponentLabels); + + componentGroup->add(&m_wellPathComponentSource); + + uiOrderingForXAxisSettings(uiOrdering); + + caf::PdmUiGroup* trackSettingsGroup = uiOrdering.addNewGroup("Track Settings"); + trackSettingsGroup->add(&m_widthScaleFactor); uiOrdering.skipRemainingFields(true); } @@ -888,14 +1346,54 @@ void RimWellLogTrack::updateAxisScaleEngine() } else { - m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xTop, new QwtLinearScaleEngine); + m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xTop, new RiuQwtLinearScaleEngine); // NB! Must assign scale engine to bottom in order to make QwtPlotGrid work - m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine); + m_wellLogTrackPlotWidget->setAxisScaleEngine(QwtPlot::xBottom, new RiuQwtLinearScaleEngine); } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogTrack::isFirstVisibleTrackInPlot() const +{ + RimWellLogPlot* plot = nullptr; + firstAncestorOrThisOfTypeAsserted(plot); + size_t ownIndex = plot->trackIndex(this); + return plot->firstVisibleTrackIndex() == ownIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair RimWellLogTrack::adjustXRange(double minValue, double maxValue, double tickInterval) +{ + double minRemainder = std::fmod(minValue, tickInterval); + double maxRemainder = std::fmod(maxValue, tickInterval); + double adjustedMin = minValue - minRemainder; + double adjustedMax = maxValue + (tickInterval - maxRemainder); + return std::make_pair(adjustedMin, adjustedMax); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::updateWellPathAttributesCollection() +{ + m_wellPathAttributeCollection = nullptr; + if (m_wellPathComponentSource) + { + std::vector attributeCollection; + m_wellPathComponentSource->descendantsIncludingThisOfType(attributeCollection); + if (!attributeCollection.empty()) + { + m_wellPathAttributeCollection = attributeCollection.front(); + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1002,13 +1500,16 @@ void RimWellLogTrack::uiOrderingForRftPltFormations(caf::PdmUiOrdering& uiOrderi //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellLogTrack::uiOrderingForVisibleXRange(caf::PdmUiOrdering& uiOrdering) +void RimWellLogTrack::uiOrderingForXAxisSettings(caf::PdmUiOrdering& uiOrdering) { - caf::PdmUiGroup* gridGroup = uiOrdering.addNewGroup("Visible X Axis Range"); - gridGroup->add(&m_isAutoScaleXEnabled); + caf::PdmUiGroup* gridGroup = uiOrdering.addNewGroup("X Axis Settings"); gridGroup->add(&m_isLogarithmicScaleEnabled); gridGroup->add(&m_visibleXRangeMin); gridGroup->add(&m_visibleXRangeMax); + gridGroup->add(&m_xAxisGridVisibility); + gridGroup->add(&m_explicitTickIntervals); + gridGroup->add(&m_majorTickInterval); + gridGroup->add(&m_minorTickInterval); } //-------------------------------------------------------------------------------------------------- @@ -1048,8 +1549,8 @@ CurveSamplingPointData RimWellLogTrack::curveSamplingPointData(RigEclipseWellLog { CurveSamplingPointData curveData; - curveData.md = extractor->measuredDepth(); - curveData.tvd = extractor->trueVerticalDepth(); + curveData.md = extractor->cellIntersectionMDs(); + curveData.tvd = extractor->cellIntersectionTVDs(); extractor->curveData(resultAccessor, &curveData.data); @@ -1063,30 +1564,13 @@ CurveSamplingPointData RimWellLogTrack::curveSamplingPointData(RigGeoMechWellLog { CurveSamplingPointData curveData; - curveData.md = extractor->measuredDepth(); - curveData.tvd = extractor->trueVerticalDepth(); + curveData.md = extractor->cellIntersectionMDs(); + curveData.tvd = extractor->cellIntersectionTVDs(); extractor->curveData(resultAddress, 0, &curveData.data); return curveData; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimWellLogTrack::formationNameIndexToName(RimCase* rimCase, const std::vector& formationNameInidces) -{ - std::vector availableFormationNames = RimWellLogTrack::formationNamesVector(rimCase); - - std::vector formationNames; - - for (int index : formationNameInidces) - { - formationNames.push_back(availableFormationNames[index]); - } - - return formationNames; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1102,7 +1586,14 @@ void RimWellLogTrack::findFormationNamesToPlot(const CurveSamplingPointData& for (double nameIdx : curveData.data) { - formationNameIndicesFromCurve.push_back(round(nameIdx)); + if (nameIdx != std::numeric_limits::infinity()) + { + formationNameIndicesFromCurve.push_back(static_cast(round(nameIdx))); + } + else + { + formationNameIndicesFromCurve.push_back(std::numeric_limits::max()); + } } if (formationNameIndicesFromCurve.empty()) return; @@ -1121,13 +1612,13 @@ void RimWellLogTrack::findFormationNamesToPlot(const CurveSamplingPointData& if (depthVector.empty()) return; double currentYStart = depthVector[0]; - double prevNameIndex = formationNameIndicesFromCurve[0]; - double currentNameIndex; + size_t prevNameIndex = formationNameIndicesFromCurve[0]; + size_t currentNameIndex; for (size_t i = 1; i < formationNameIndicesFromCurve.size(); i++) { currentNameIndex = formationNameIndicesFromCurve[i]; - if (currentNameIndex != prevNameIndex) + if (currentNameIndex != std::numeric_limits::max() && currentNameIndex != prevNameIndex) { if (prevNameIndex < formationNamesVector.size()) { @@ -1140,10 +1631,12 @@ void RimWellLogTrack::findFormationNamesToPlot(const CurveSamplingPointData& } } - size_t lastIdx = formationNameIndicesFromCurve.size() - 1; - - formationNamesToPlot->push_back(formationNamesVector[formationNameIndicesFromCurve[lastIdx]]); - yValues->push_back(std::make_pair(currentYStart, depthVector[lastIdx])); + size_t lastFormationIdx = formationNameIndicesFromCurve.back(); + if (lastFormationIdx < formationNamesVector.size()) + { + formationNamesToPlot->push_back(formationNamesVector[lastFormationIdx]); + yValues->push_back(std::make_pair(currentYStart, depthVector.back())); + } } //-------------------------------------------------------------------------------------------------- @@ -1177,6 +1670,7 @@ std::vector RimWellLogTrack::formationNamesVector(RimCase* rimCase) //-------------------------------------------------------------------------------------------------- void RimWellLogTrack::setFormationFieldsUiReadOnly(bool readOnly /*= true*/) { + m_showFormationLabels.uiCapability()->setUiReadOnly(readOnly); m_formationSource.uiCapability()->setUiReadOnly(readOnly); m_formationTrajectoryType.uiCapability()->setUiReadOnly(readOnly); m_formationSimWellName.uiCapability()->setUiReadOnly(readOnly); @@ -1204,7 +1698,6 @@ void RimWellLogTrack::updateFormationNamesOnPlot() } std::vector formationNamesToPlot; - std::vector> yValues; RimWellLogPlot* plot = nullptr; firstAncestorOrThisOfTypeAsserted(plot); @@ -1260,6 +1753,7 @@ void RimWellLogTrack::updateFormationNamesOnPlot() RigFemResultAddress(RIG_FORMATION_NAMES, activeFormationNamesResultName, "")); } + std::vector> yValues; std::vector formationNamesVector = RimWellLogTrack::formationNamesVector(m_formationCase); RimWellLogTrack::findFormationNamesToPlot(curveData, @@ -1268,7 +1762,7 @@ void RimWellLogTrack::updateFormationNamesOnPlot() &formationNamesToPlot, &yValues); - m_annotationTool->attachFormationNames(this->viewer(), formationNamesToPlot, yValues); + m_annotationTool->attachFormationNames(this->viewer(), formationNamesToPlot, yValues, m_showFormationLabels()); } else if (m_formationSource() == WELL_PICK_FILTER) { @@ -1291,6 +1785,82 @@ void RimWellLogTrack::updateFormationNamesOnPlot() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::updateWellPathAttributesOnPlot() +{ + m_wellPathAttributePlotObjects.clear(); + + if (wellPathAttributeSource()) + { + if (m_showWellPathAttributes || m_showWellPathCompletions) + { + m_wellPathAttributePlotObjects.push_back(std::unique_ptr(new RiuWellPathComponentPlotItem(wellPathAttributeSource()))); + } + + if (m_showWellPathAttributes) + { + if (m_wellPathAttributeCollection) + { + std::vector attributes = m_wellPathAttributeCollection->attributes(); + std::sort(attributes.begin(), attributes.end(), [](const RimWellPathAttribute* lhs, const RimWellPathAttribute* rhs) + { + return *lhs < *rhs; + }); + + std::set attributesAssignedToLegend; + for (RimWellPathAttribute* attribute : attributes) + { + if (attribute->isEnabled()) + { + std::unique_ptr plotItem(new RiuWellPathComponentPlotItem(wellPathAttributeSource(), attribute)); + QString legendTitle = plotItem->legendTitle(); + bool contributeToLegend = m_wellPathAttributesInLegend() && + !attributesAssignedToLegend.count(legendTitle); + plotItem->setContributeToLegend(contributeToLegend); + m_wellPathAttributePlotObjects.push_back(std::move(plotItem)); + attributesAssignedToLegend.insert(legendTitle); + } + } + } + } + if (m_showWellPathCompletions) + { + const RimWellPathCompletions* completionsCollection = wellPathAttributeSource()->completions(); + std::vector allCompletions = completionsCollection->allCompletions(); + + std::set completionsAssignedToLegend; + for (const RimWellPathComponentInterface* completion : allCompletions) + { + if (completion->isEnabled()) + { + std::unique_ptr plotItem(new RiuWellPathComponentPlotItem(wellPathAttributeSource(), completion)); + QString legendTitle = plotItem->legendTitle(); + bool contributeToLegend = m_wellPathCompletionsInLegend() && + !completionsAssignedToLegend.count(legendTitle); + plotItem->setContributeToLegend(contributeToLegend); + m_wellPathAttributePlotObjects.push_back(std::move(plotItem)); + completionsAssignedToLegend.insert(legendTitle); + } + } + } + + RimWellLogPlot* wellLogPlot; + this->firstAncestorOrThisOfTypeAsserted(wellLogPlot); + RimWellLogPlot::DepthTypeEnum depthType = wellLogPlot->depthType(); + + for (auto& attributePlotObject : m_wellPathAttributePlotObjects) + { + attributePlotObject->setDepthType(depthType); + attributePlotObject->setShowLabel(m_showWellPathComponentLabels()); + attributePlotObject->loadDataAndUpdate(false); + attributePlotObject->setParentQwtPlotNoReplot(m_wellLogTrackPlotWidget); + } + } + applyXZoomFromVisibleRange(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellLogTrack.h b/ApplicationCode/ProjectDataModel/RimWellLogTrack.h index c6a7b70729..efb1a3d37e 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogTrack.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogTrack.h @@ -36,10 +36,12 @@ class RigWellPath; class RimCase; +class RimWellPathAttributeCollection; class RimWellFlowRateCurve; class RimWellLogCurve; class RimWellPath; class RiuPlotAnnotationTool; +class RiuWellPathComponentPlotItem; class RiuWellLogTrack; class RigEclipseWellLogExtractor; class RimWellLogPlotCollection; @@ -66,10 +68,11 @@ class RimWellLogTrack : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimWellLogTrack(); - virtual ~RimWellLogTrack(); + ~RimWellLogTrack() override; - enum TrajectoryType { WELL_PATH, SIMULATION_WELL }; - enum FormationSource { CASE, WELL_PICK_FILTER }; + enum TrajectoryType { WELL_PATH, SIMULATION_WELL }; + enum FormationSource { CASE, WELL_PICK_FILTER }; + enum WidthScaleFactor { EXTRA_NARROW_TRACK = 2, NARROW_TRACK = 3, NORMAL_TRACK = 4, WIDE_TRACK = 6, EXTRA_WIDE_TRACK = 10 }; void setDescription(const QString& description); bool isVisible(); @@ -78,11 +81,15 @@ class RimWellLogTrack : public caf::PdmObject void takeOutCurve(RimWellLogCurve* curve); void deleteAllCurves(); - size_t curveIndex(RimWellLogCurve* curve); - size_t curveCount() { return curves.size(); } - void setXAxisTitle(const QString& text); + size_t curveIndex(RimWellLogCurve* curve); + size_t curveCount() { return curves.size(); } + void setXAxisTitle(const QString& text); + QString depthPlotTitle() const; + int widthScaleFactor() const; + void setWidthScaleFactor(WidthScaleFactor scaleFactor); void setFormationWellPath(RimWellPath* wellPath); + RimWellPath* formationWellPath() const; void setFormationSimWellName(const QString& simWellName); void setFormationBranchIndex(int branchIndex); void setFormationCase(RimCase* rimCase); @@ -91,25 +98,39 @@ class RimWellLogTrack : public caf::PdmObject void recreateViewer(); void detachAllCurves(); + void reattachAllCurves(); - void loadDataAndUpdate(); + void loadDataAndUpdate(bool updateParentPlotAndToolbars = false); void setAndUpdateWellPathFormationNamesData(RimCase* rimCase, RimWellPath* wellPath); void setAndUpdateSimWellFormationNamesAndBranchData(RimCase* rimCase, const QString& simWellName, int branchIndex, bool useBranchDetection); void setAndUpdateSimWellFormationNamesData(RimCase* rimCase, const QString& simWellName); + void setAutoScaleXEnabled(bool enabled); void availableDepthRange(double* minimumDepth, double* maximumDepth); - void updateXZoomAndParentPlotDepthZoom(); - void updateXZoom(); - + void updateParentPlotZoom(); + void calculateXZoomRangeAndUpdateQwt(); + void applyXZoomFromVisibleRange(); + void calculateXZoomRange(); + void updateEditors(); + void setVisibleXRange(double minValue, double maxValue); + void setTickIntervals(double majorTickInterval, double minorTickInterval); + void setXAxisGridVisibility(RimWellLogPlot::AxisGridVisibility gridLines); void setShowFormations(bool on); - + bool showFormations() const; + void setShowFormationLabels(bool on); + + bool showWellPathAttributes() const; + void setShowWellPathAttributes(bool on); + void setWellPathAttributesSource(RimWellPath* wellPath); + + RimWellPath* wellPathAttributeSource() const; RiuWellLogTrack* viewer(); RimWellLogCurve* curveDefinitionFromCurve(const QwtPlotCurve* curve) const; - void setLogarithmicScale(bool enable); + void setLogarithmicScale(bool enable); std::map> visibleStackedCurves(); @@ -117,17 +138,20 @@ class RimWellLogTrack : public caf::PdmObject std::vector curvesVector(); void uiOrderingForRftPltFormations(caf::PdmUiOrdering& uiOrdering); - void uiOrderingForVisibleXRange(caf::PdmUiOrdering& uiOrdering); + void uiOrderingForXAxisSettings(caf::PdmUiOrdering& uiOrdering); void setFormationsForCaseWithSimWellOnly(bool caseWithSimWellOnly); + void updateAxisAndGridTickIntervals(); + void updateAllLegendItems(); private: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void updateParentPlotLayout(); + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual caf::PdmFieldHandle* objectToggleField() override; - virtual caf::PdmFieldHandle* userDescriptionField() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + caf::PdmFieldHandle* objectToggleField() override; + caf::PdmFieldHandle* userDescriptionField() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; void computeAndSetXRangeMinForLogarithmicScale(); @@ -138,8 +162,6 @@ class RimWellLogTrack : public caf::PdmObject static CurveSamplingPointData curveSamplingPointData(RigEclipseWellLogExtractor* extractor, RigResultAccessor* resultAccessor); static CurveSamplingPointData curveSamplingPointData(RigGeoMechWellLogExtractor* extractor, const RigFemResultAddress& resultAddress); - static std::vector formationNameIndexToName(RimCase* rimCase, const std::vector& formationNameInidces); - static void findFormationNamesToPlot(const CurveSamplingPointData& curveData, const std::vector& formationNamesVector, RimWellLogPlot::DepthTypeEnum depthType, @@ -151,32 +173,52 @@ class RimWellLogTrack : public caf::PdmObject void setFormationFieldsUiReadOnly(bool readOnly = true); void updateFormationNamesOnPlot(); + void updateWellPathAttributesOnPlot(); void removeFormationNames(); void updateAxisScaleEngine(); + bool isFirstVisibleTrackInPlot() const; + + std::pair adjustXRange(double minValue, double maxValue, double tickInterval); + void updateWellPathAttributesCollection(); private: QString m_xAxisTitle; - caf::PdmField m_show; - caf::PdmField m_userName; - caf::PdmChildArrayField curves; - caf::PdmField m_visibleXRangeMin; - caf::PdmField m_visibleXRangeMax; - caf::PdmField m_isAutoScaleXEnabled; - caf::PdmField m_isLogarithmicScaleEnabled; + caf::PdmField m_show; + caf::PdmField m_userName; + caf::PdmChildArrayField curves; + caf::PdmField m_visibleXRangeMin; + caf::PdmField m_visibleXRangeMax; + caf::PdmField m_isAutoScaleXEnabled; + caf::PdmField m_isLogarithmicScaleEnabled; + caf::PdmField m_xAxisGridVisibility; + caf::PdmField m_explicitTickIntervals; + caf::PdmField m_majorTickInterval; + caf::PdmField m_minorTickInterval; caf::PdmField m_showFormations; - caf::PdmField > m_formationSource; + caf::PdmField m_showFormationLabels; + caf::PdmField> m_formationSource; caf::PdmPtrField m_formationCase; - caf::PdmField > m_formationTrajectoryType; + caf::PdmField> m_formationTrajectoryType; caf::PdmPtrField m_formationWellPathForSourceCase; caf::PdmPtrField m_formationWellPathForSourceWellPath; caf::PdmField m_formationSimWellName; caf::PdmField m_formationBranchIndex; caf::PdmField> m_formationLevel; caf::PdmField m_showformationFluids; - - caf::PdmField m_formationBranchDetection; + caf::PdmField> m_widthScaleFactor; + caf::PdmField m_formationBranchDetection; + caf::PdmField m_showWellPathAttributes; + caf::PdmField m_showWellPathCompletions; + caf::PdmField m_showWellPathComponentsBothSides; + caf::PdmField m_showWellPathComponentLabels; + caf::PdmField m_wellPathAttributesInLegend; + caf::PdmField m_wellPathCompletionsInLegend; + caf::PdmPtrField m_wellPathComponentSource; + caf::PdmPtrField m_wellPathAttributeCollection; + + std::vector> m_wellPathAttributePlotObjects; bool m_formationsForCaseWithSimWellOnly; diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.cpp b/ApplicationCode/ProjectDataModel/RimWellPath.cpp index 87ca37e852..f5fdce2345 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPath.cpp @@ -21,6 +21,8 @@ #include "RimWellPath.h" #include "RiaApplication.h" +#include "RiaColorTables.h" +#include "RiaFieldHandleTools.h" #include "RiaSimWellBranchTools.h" #include "RiaWellNameComparer.h" @@ -36,7 +38,9 @@ #include "RimProject.h" #include "RimTools.h" #include "RimWellLogFile.h" +#include "RimWellLogFileChannel.h" #include "RimWellLogPlotCollection.h" +#include "RimWellPathAttributeCollection.h" #include "RimWellPathCollection.h" #include "RimWellPathCompletions.h" #include "RimWellPathFracture.h" @@ -55,7 +59,7 @@ #include -CAF_PDM_SOURCE_INIT(RimWellPath, "WellPath"); +CAF_PDM_SOURCE_INIT(RimWellPath, "WellPathBase"); //-------------------------------------------------------------------------------------------------- /// @@ -71,57 +75,26 @@ RimWellPath::RimWellPath() CAF_PDM_InitFieldNoDefault(&m_name, "WellPathName", "Name", "", "", ""); m_name.uiCapability()->setUiReadOnly(true); - m_name.xmlCapability()->setIOWritable(false); - m_name.xmlCapability()->setIOReadable(false); m_name.uiCapability()->setUiHidden(true); - CAF_PDM_InitFieldNoDefault(&id, "WellPathId", "Id", "", "", ""); - id.uiCapability()->setUiReadOnly(true); - id.xmlCapability()->setIOWritable(false); - id.xmlCapability()->setIOReadable(false); - CAF_PDM_InitFieldNoDefault(&sourceSystem, "SourceSystem", "Source System", "", "", ""); - sourceSystem.uiCapability()->setUiReadOnly(true); - sourceSystem.xmlCapability()->setIOWritable(false); - sourceSystem.xmlCapability()->setIOReadable(false); - CAF_PDM_InitFieldNoDefault(&utmZone, "UTMZone", "UTM Zone", "", "", ""); - utmZone.uiCapability()->setUiReadOnly(true); - utmZone.xmlCapability()->setIOWritable(false); - utmZone.xmlCapability()->setIOReadable(false); - CAF_PDM_InitFieldNoDefault(&updateDate, "WellPathUpdateDate", "Update Date", "", "", ""); - updateDate.uiCapability()->setUiReadOnly(true); - updateDate.xmlCapability()->setIOWritable(false); - updateDate.xmlCapability()->setIOReadable(false); - CAF_PDM_InitFieldNoDefault(&updateUser, "WellPathUpdateUser", "Update User", "", "", ""); - updateUser.uiCapability()->setUiReadOnly(true); - updateUser.xmlCapability()->setIOWritable(false); - updateUser.xmlCapability()->setIOReadable(false); - CAF_PDM_InitFieldNoDefault(&m_surveyType, "WellPathSurveyType", "Survey Type", "", "", ""); - m_surveyType.uiCapability()->setUiReadOnly(true); - m_surveyType.xmlCapability()->setIOWritable(false); - m_surveyType.xmlCapability()->setIOReadable(false); + m_name.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault(&m_datumElevation, "DatumElevation", "Datum Elevation", "", "", ""); m_datumElevation.uiCapability()->setUiReadOnly(true); - m_datumElevation.xmlCapability()->setIOWritable(false); - m_datumElevation.xmlCapability()->setIOReadable(false); + m_datumElevation.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault(&m_unitSystem, "UnitSystem", "Unit System", "", "", ""); m_unitSystem.uiCapability()->setUiReadOnly(true); - CAF_PDM_InitField(&filepath, "WellPathFilepath", QString(""), "File Path", "", "", ""); - filepath.uiCapability()->setUiReadOnly(true); - CAF_PDM_InitField(&wellPathIndexInFile, "WellPathNumberInFile", -1, "Well Number in File", "", "", ""); - wellPathIndexInFile.uiCapability()->setUiReadOnly(true); - CAF_PDM_InitField(&m_simWellName, "SimWellName", QString(""), "Well", "", "", ""); CAF_PDM_InitField(&m_branchIndex, "SimBranchIndex", 0, "Branch", "", "", ""); - CAF_PDM_InitField(&showWellPathLabel, "ShowWellPathLabel", true, "Show Well Path Label", "", "", ""); + CAF_PDM_InitField(&m_showWellPathLabel, "ShowWellPathLabel", true, "Show Well Path Label", "", "", ""); - CAF_PDM_InitField(&showWellPath, "ShowWellPath", true, "Show Well Path", "", "", ""); - showWellPath.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&m_showWellPath, "ShowWellPath", true, "Show Well Path", "", "", ""); + m_showWellPath.uiCapability()->setUiHidden(true); - CAF_PDM_InitField(&wellPathRadiusScaleFactor, "WellPathRadiusScale", 1.0, "Well Path Radius Scale", "", "", ""); - CAF_PDM_InitField(&wellPathColor, "WellPathColor", cvf::Color3f(0.999f, 0.333f, 0.999f), "Well Path Color", "", "", ""); + CAF_PDM_InitField(&m_wellPathRadiusScaleFactor, "WellPathRadiusScale", 1.0, "Well Path Radius Scale", "", "", ""); + CAF_PDM_InitField(&m_wellPathColor, "WellPathColor", cvf::Color3f(0.999f, 0.333f, 0.999f), "Well Path Color", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_completions, "Completions", "Completions", "", "", ""); m_completions = new RimWellPathCompletions; @@ -141,8 +114,11 @@ RimWellPath::RimWellPath() m_wellPathFormationFilePath.uiCapability()->setUiReadOnly(true); CAF_PDM_InitFieldNoDefault(&m_wellLogFile_OBSOLETE, "WellLogFile", "Well Log File", "", "", ""); - m_wellLogFile_OBSOLETE.uiCapability()->setUiHidden(true); - m_wellLogFile_OBSOLETE.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_wellLogFile_OBSOLETE); + + CAF_PDM_InitFieldNoDefault(&m_wellPathAttributes, "WellPathAttributes", "Casing Design Rubbish", "", "", ""); + m_wellPathAttributes = new RimWellPathAttributeCollection; + m_wellPathAttributes->uiCapability()->setUiTreeHidden(true); m_wellPath = nullptr; } @@ -187,24 +163,12 @@ caf::PdmFieldHandle* RimWellPath::userDescriptionField() return &m_name; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPath::setSurveyType(QString surveyType) -{ - m_surveyType = surveyType; - if (m_surveyType == "PLAN") - wellPathColor = cvf::Color3f(0.999f, 0.333f, 0.0f); - else if (m_surveyType == "PROTOTYPE") - wellPathColor = cvf::Color3f(0.0f, 0.333f, 0.999f); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- double RimWellPath::wellPathRadius(double characteristicCellSize) const { - double radius = characteristicCellSize * wellPathRadiusScaleFactor(); + double radius = characteristicCellSize * m_wellPathRadiusScaleFactor(); RimWellPathCollection* coll = nullptr; this->firstAncestorOrThisOfType(coll); @@ -216,6 +180,78 @@ double RimWellPath::wellPathRadius(double characteristicCellSize) const return radius; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPath::wellPathRadiusScaleFactor() const +{ + return m_wellPathRadiusScaleFactor(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellPath::isEnabled() const +{ + return m_showWellPath; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::WellPathComponentType RimWellPath::componentType() const +{ + return RiaDefines::WELL_PATH; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPath::componentLabel() const +{ + return name(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPath::componentTypeLabel() const +{ + return "Well Path"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RimWellPath::defaultComponentColor() const +{ + return RiaColorTables::wellPathComponentColors()[componentType()]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPath::startMD() const +{ + if (wellPathGeometry()) + { + return wellPathGeometry()->measureDepths().front(); + } + return 0.0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPath::endMD() const +{ + if (wellPathGeometry()) + { + return wellPathGeometry()->measureDepths().back(); + } + return 0.0; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -307,13 +343,13 @@ void RimWellPath::fieldChangedByUi(const caf::PdmFieldHandle* changedField, cons { RimProject* proj; this->firstAncestorOrThisOfTypeAsserted(proj); - if (changedField == &showWellPath) + if (changedField == &m_showWellPath) { proj->reloadCompletionTypeResultsInAllViews(); } else { - proj->createDisplayModelAndRedrawAllViews(); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); } } @@ -405,41 +441,80 @@ std::vector RimWellPath::wellLogFiles() const return std::vector(m_wellLogFiles.begin(), m_wellLogFiles.end()); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogFile* RimWellPath::firstWellLogFileMatchingChannelName(const QString& channelName) const +{ + std::vector allWellLogFiles = wellLogFiles(); + for (RimWellLogFile* logFile : allWellLogFiles) + { + std::vector channels = logFile->wellLogChannels(); + for (RimWellLogFileChannel* channel : channels) + { + if (channel->name() == channelName) + { + return logFile; + } + } + } + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathAttributeCollection* RimWellPath::attributeCollection() +{ + return m_wellPathAttributes; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimWellPathAttributeCollection* RimWellPath::attributeCollection() const +{ + return m_wellPathAttributes; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmFieldHandle* RimWellPath::objectToggleField() +bool RimWellPath::showWellPathLabel() const { - return &showWellPath; + return m_showWellPathLabel(); } //-------------------------------------------------------------------------------------------------- -/// Read JSON or ascii file containing well path data +/// //-------------------------------------------------------------------------------------------------- -bool RimWellPath::readWellPathFile(QString* errorMessage, RifWellPathImporter* wellPathImporter) +bool RimWellPath::showWellPath() const { - if (caf::Utils::fileExists(filepath())) - { - RifWellPathImporter::WellData wellData = wellPathImporter->readWellData(filepath(), wellPathIndexInFile()); - RifWellPathImporter::WellMetaData wellMetaData = wellPathImporter->readWellMetaData(filepath(), wellPathIndexInFile()); - // General well info - - setName(wellData.m_name); - id = wellMetaData.m_id; - sourceSystem = wellMetaData.m_sourceSystem; - utmZone = wellMetaData.m_utmZone; - updateUser = wellMetaData.m_updateUser; - setSurveyType(wellMetaData.m_surveyType); - updateDate = wellMetaData.m_updateDate.toString("d MMMM yyyy"); - - m_wellPath = wellData.m_wellPathGeometry; - return true; - } - else - { - if (errorMessage) (*errorMessage) = "Could not find the well path file: " + filepath(); - return false; - } + return m_showWellPath(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RimWellPath::wellPathColor() const +{ + return m_wellPathColor; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPath::setWellPathColor(const cvf::Color3f& color) +{ + m_wellPathColor = color; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimWellPath::objectToggleField() +{ + return &m_showWellPath; } //-------------------------------------------------------------------------------------------------- @@ -462,13 +537,10 @@ void RimWellPath::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiO } caf::PdmUiGroup* appGroup = uiOrdering.addNewGroup("Appearance"); - appGroup->add(&showWellPathLabel); - appGroup->add(&wellPathColor); - appGroup->add(&wellPathRadiusScaleFactor); + appGroup->add(&m_showWellPathLabel); + appGroup->add(&m_wellPathColor); + appGroup->add(&m_wellPathRadiusScaleFactor); - caf::PdmUiGroup* fileInfoGroup = uiOrdering.addNewGroup("File"); - fileInfoGroup->add(&filepath); - fileInfoGroup->add(&wellPathIndexInFile); caf::PdmUiGroup* simWellGroup = uiOrdering.addNewGroup("Simulation Well"); simWellGroup->add(&m_simWellName); @@ -479,12 +551,7 @@ void RimWellPath::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiO } caf::PdmUiGroup* ssihubGroup = uiOrdering.addNewGroup("Well Info"); - ssihubGroup->add(&id); - ssihubGroup->add(&sourceSystem); - ssihubGroup->add(&utmZone); - ssihubGroup->add(&updateDate); - ssihubGroup->add(&updateUser); - ssihubGroup->add(&m_surveyType); + ssihubGroup->add(&m_datumElevation); ssihubGroup->add(&m_unitSystem); @@ -514,79 +581,20 @@ void RimWellPath::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, Q if (m_completions->hasCompletions()) { - uiTreeOrdering.add(&m_completions); + uiTreeOrdering.add(m_completions()); } if (m_3dWellLogCurves->has3dWellLogCurves()) { - uiTreeOrdering.add(&m_3dWellLogCurves); + uiTreeOrdering.add(m_3dWellLogCurves()); } - uiTreeOrdering.skipRemainingChildren(true); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPath::getCacheDirectoryPath() -{ - QString cacheDirPath = RimTools::getCacheRootDirectoryPathFromProject(); - cacheDirPath += "_wellpaths"; - return cacheDirPath; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimWellPath::getCacheFileName() -{ - if (filepath().isEmpty()) + if (!m_wellPathAttributes->attributes().empty()) { - return ""; + uiTreeOrdering.add(m_wellPathAttributes()); } - QString cacheFileName; - - // Make the path correct related to the possibly new project filename - QString newCacheDirPath = getCacheDirectoryPath(); - QFileInfo oldCacheFile(filepath); - - - cacheFileName = newCacheDirPath + "/" + oldCacheFile.fileName(); - - return cacheFileName; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellPath::setupBeforeSave() -{ - // SSIHUB is the only source for populating Id, use text in this field to decide if the cache file must be copied to new project cache location - if (!isStoredInCache()) - { - return; - } - - if (filepath().isEmpty()) - { - return; - } - - QDir::root().mkpath(getCacheDirectoryPath()); - - QString newCacheFileName = getCacheFileName(); - - // Use QFileInfo to get same string representation to avoid issues with mix of forward and backward slashes - QFileInfo prevFileInfo(filepath); - QFileInfo currentFileInfo(newCacheFileName); - - if (prevFileInfo.absoluteFilePath().compare(currentFileInfo.absoluteFilePath()) != 0) - { - QFile::copy(filepath, newCacheFileName); - - filepath = newCacheFileName; - } + uiTreeOrdering.skipRemainingChildren(true); } //-------------------------------------------------------------------------------------------------- @@ -601,33 +609,11 @@ size_t RimWellPath::simulationWellBranchCount(const QString& simWellName) return branches.size(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimWellPath::isStoredInCache() -{ - // SSIHUB is the only source for populating Id, use text in this field to decide if the cache file must be copied to new project cache location - return !id().isEmpty(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPath::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) { - if (isStoredInCache()) - { - QString newCacheFileName = getCacheFileName(); - - if (caf::Utils::fileExists(newCacheFileName)) - { - filepath = newCacheFileName; - } - } - else - { - filepath = RimTools::relocateFile(filepath(), newProjectPath, oldProjectPath, nullptr, nullptr); - } { bool foundFile = false; @@ -650,7 +636,7 @@ double RimWellPath::combinedScaleFactor() const RimWellPathCollection* wellPathColl = nullptr; this->firstAncestorOrThisOfTypeAsserted(wellPathColl); - return this->wellPathRadiusScaleFactor() * wellPathColl->wellPathRadiusScaleFactor(); + return this->m_wellPathRadiusScaleFactor() * wellPathColl->wellPathRadiusScaleFactor(); } //-------------------------------------------------------------------------------------------------- @@ -817,21 +803,6 @@ Rim3dWellLogCurveCollection* RimWellPath::rim3dWellLogCurveCollection() const return m_3dWellLogCurves(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPath* RimWellPath::fromFilePath(QString filePath) -{ - RimWellLogFile* logFileInfo = RimWellLogFile::readWellLogFile(filePath); - if (logFileInfo) - { - auto wellPath = new RimWellPath(); - wellPath->addWellLogFile(logFileInfo); - return wellPath; - } - return nullptr; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.h b/ApplicationCode/ProjectDataModel/RimWellPath.h index 3cc8721ed1..4c5ccde6a4 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.h +++ b/ApplicationCode/ProjectDataModel/RimWellPath.h @@ -22,7 +22,7 @@ #include "RiaEclipseUnitTools.h" -#include "Rim3dWellLogCurve.h" +#include "RimWellPathComponentInterface.h" #include "cafPdmField.h" #include "cafPdmObject.h" @@ -48,17 +48,19 @@ class RimFishboneWellPathCollection; class RimFishbonesCollection; class RimPerforationCollection; +class RimWellPathAttributeCollection; class RimWellPathCompletions; class RigWellPathFormations; class RimWellPathFractureCollection; +class Rim3dWellLogCurve; class Rim3dWellLogCurveCollection; //================================================================================================== /// /// //================================================================================================== -class RimWellPath : public caf::PdmObject +class RimWellPath : public caf::PdmObject, public RimWellPathComponentInterface { CAF_PDM_HEADER_INIT; @@ -67,11 +69,29 @@ class RimWellPath : public caf::PdmObject public: RimWellPath(); - virtual ~RimWellPath(); + ~RimWellPath() override; + + QString name() const; + void setName(const QString& name); + + const QString associatedSimulationWellName() const; + int associatedSimulationWellBranch() const; + bool tryAssociateWithSimulationWell(); + bool isAssociatedWithSimulationWell() const; + + virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath); + + void setUnitSystem(RiaEclipseUnitTools::UnitSystem unitSystem); + RiaEclipseUnitTools::UnitSystem unitSystem() const; + + RigWellPath* wellPathGeometry(); + const RigWellPath* wellPathGeometry() const; void addWellLogFile(RimWellLogFile* logFileInfo); void deleteWellLogFile(RimWellLogFile* logFileInfo); void detachWellLogFile(RimWellLogFile* logFileInfo); + std::vector wellLogFiles() const; + RimWellLogFile* firstWellLogFileMatchingChannelName(const QString& channelName) const; void setFormationsGeometry(cvf::ref wellPathFormations); bool readWellPathFormationsFile(QString* errorMessage, RifWellPathFormationsImporter* wellPathFormationsImporter); @@ -82,104 +102,87 @@ class RimWellPath : public caf::PdmObject void add3dWellLogCurve(Rim3dWellLogCurve* rim3dWellLogCurve); Rim3dWellLogCurveCollection* rim3dWellLogCurveCollection() const; - virtual caf::PdmFieldHandle* userDescriptionField() override; - virtual caf::PdmFieldHandle* objectToggleField() override; + const RimWellPathCompletions* completions() const; + RimFishbonesCollection* fishbonesCollection(); + const RimFishbonesCollection* fishbonesCollection() const; + RimPerforationCollection* perforationIntervalCollection(); + const RimPerforationCollection* perforationIntervalCollection() const; + RimWellPathFractureCollection* fractureCollection(); + const RimWellPathFractureCollection* fractureCollection() const; + RimWellPathAttributeCollection* attributeCollection(); + const RimWellPathAttributeCollection* attributeCollection() const; - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual void initAfterRead() override; + bool showWellPathLabel() const; + bool showWellPath() const; - QString name() const; - void setName(const QString& name); - - std::vector wellLogFiles() const; - - caf::PdmField filepath; - caf::PdmField wellPathIndexInFile; // -1 means none. - - caf::PdmField m_simWellName; - caf::PdmField m_branchIndex; - - caf::PdmField showWellPathLabel; - - caf::PdmField showWellPath; - caf::PdmField wellPathColor; + cvf::Color3f wellPathColor() const; + void setWellPathColor(const cvf::Color3f& color ); + double combinedScaleFactor() const; double wellPathRadius(double characteristicCellSize) const; + double wellPathRadiusScaleFactor() const; + - caf::PdmField wellPathRadiusScaleFactor; - - RimFishbonesCollection* fishbonesCollection(); - const RimFishbonesCollection* fishbonesCollection() const; - RimPerforationCollection* perforationIntervalCollection(); - const RimPerforationCollection* perforationIntervalCollection() const; - const RimWellPathCompletions* completions() const; + // RimWellPathComponentInterface overrides + bool isEnabled() const override; + RiaDefines::WellPathComponentType componentType() const override; + QString componentLabel() const override; + QString componentTypeLabel() const override; + cvf::Color3f defaultComponentColor() const override; + double startMD() const override; + double endMD() const override; - RimWellPathFractureCollection* fractureCollection(); - const RimWellPathFractureCollection* fractureCollection() const; +protected: - RigWellPath* wellPathGeometry(); - const RigWellPath* wellPathGeometry() const; + // Override PdmObject - bool readWellPathFile(QString * errorMessage, RifWellPathImporter* wellPathImporter); - void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath); + caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* objectToggleField() override; - double combinedScaleFactor() const; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + void initAfterRead() override; + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; - void setUnitSystem(RiaEclipseUnitTools::UnitSystem unitSystem); - RiaEclipseUnitTools::UnitSystem unitSystem() const; - static RimWellPath* fromFilePath(QString filePath); - - const QString associatedSimulationWellName() const; - int associatedSimulationWellBranch() const; + void setWellPathGeometry(RigWellPath* wellPathModel); - bool tryAssociateWithSimulationWell(); - bool isAssociatedWithSimulationWell() const; - bool tryMatchName(QString wellPathName, - const std::vector& simWellNames, - std::function stringFormatter = nullptr); + // Fields +protected: + caf::PdmField m_datumElevation; + caf::PdmField m_name; private: + caf::PdmField m_simWellName; + caf::PdmField m_branchIndex; - void setWellPathGeometry(RigWellPath* wellPathModel); - QString surveyType() { return m_surveyType; } - void setSurveyType(QString surveyType); - - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override; - - bool isStoredInCache(); - QString getCacheFileName(); - QString getCacheDirectoryPath(); + caf::PdmField m_unitSystem; + + caf::PdmField m_wellPathFormationFilePath; + caf::PdmField m_formationKeyInFile; + + caf::PdmField m_showWellPath; + caf::PdmField m_showWellPathLabel; + + caf::PdmField m_wellPathRadiusScaleFactor; + caf::PdmField m_wellPathColor; + + caf::PdmChildArrayField m_wellLogFiles; + caf::PdmChildField m_3dWellLogCurves; + caf::PdmChildField m_completions; + caf::PdmChildField m_wellPathAttributes; - virtual void setupBeforeSave() override; +private: static size_t simulationWellBranchCount(const QString& simWellName); private: - caf::PdmField id; - caf::PdmField sourceSystem; - caf::PdmField utmZone; - caf::PdmField updateDate; - caf::PdmField updateUser; - - caf::PdmField m_surveyType; - caf::PdmField m_datumElevation; - - caf::PdmField m_unitSystem; - - caf::PdmChildField m_completions; + // Geometry and data cvf::ref m_wellPath; cvf::ref m_wellPathFormations; - caf::PdmField m_name; - - caf::PdmField m_wellPathFormationFilePath; - caf::PdmField m_formationKeyInFile; - caf::PdmChildArrayField m_wellLogFiles; - - caf::PdmChildField m_3dWellLogCurves; + // Obsolete fields caf::PdmChildField m_wellLogFile_OBSOLETE; }; diff --git a/ApplicationCode/ProjectDataModel/RimWellPathAttribute.cpp b/ApplicationCode/ProjectDataModel/RimWellPathAttribute.cpp new file mode 100644 index 0000000000..31e99f5c8d --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellPathAttribute.cpp @@ -0,0 +1,264 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RimWellPathAttribute.h" + +#include "RiaColorTables.h" +#include "RigWellPath.h" + +#include "RimProject.h" +#include "RimWellPathAttributeCollection.h" +#include "RimWellPath.h" + +#include "cafPdmUiComboBoxEditor.h" + +#include + +CAF_PDM_SOURCE_INIT(RimWellPathAttribute, "WellPathAttribute"); + +double RimWellPathAttribute::MAX_DIAMETER_IN_INCHES = 30.0; +double RimWellPathAttribute::MIN_DIAMETER_IN_INCHES = 7.0; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathAttribute::RimWellPathAttribute() +{ + CAF_PDM_InitObject("RimWellPathAttribute", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_type, "CompletionType", "Type ", "", "", ""); + CAF_PDM_InitField(&m_startMD, "DepthStart", -1.0, "Start MD", "", "", ""); + CAF_PDM_InitField(&m_endMD, "DepthEnd", -1.0, "End MD", "", "", ""); + CAF_PDM_InitField(&m_diameterInInches, "DiameterInInches", MAX_DIAMETER_IN_INCHES, "Diameter", "", "", ""); + m_type = RiaDefines::CASING; + m_diameterInInches.uiCapability()->setUiEditorTypeName(caf::PdmUiComboBoxEditor::uiEditorTypeName()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathAttribute::~RimWellPathAttribute() +{ + +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathAttribute::diameterInInches() const +{ + return m_diameterInInches; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathAttribute::diameterLabel() const +{ + return generateInchesLabel(m_diameterInInches()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellPathAttribute::operator<(const RimWellPathAttribute& rhs) const +{ + if (componentType() != rhs.componentType()) + { + return componentType() < rhs.componentType(); + } + return endMD() > rhs.endMD(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttribute::setDepthsFromWellPath(const RimWellPath* wellPath) +{ + m_startMD = wellPath->wellPathGeometry()->measureDepths().front(); + m_endMD = wellPath->wellPathGeometry()->measureDepths().back(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellPathAttribute::isEnabled() const +{ + RimWellPathAttributeCollection* collection = nullptr; + this->firstAncestorOrThisOfTypeAsserted(collection); + return collection->isChecked(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::WellPathComponentType RimWellPathAttribute::componentType() const +{ + return m_type(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathAttribute::componentLabel() const +{ + QString fullLabel = componentTypeLabel(); + if (m_type() == RiaDefines::CASING || m_type() == RiaDefines::LINER) + { + fullLabel += QString(" %1").arg(diameterLabel()); + } + return fullLabel; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathAttribute::componentTypeLabel() const +{ + return m_type().uiText(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color3f RimWellPathAttribute::defaultComponentColor() const +{ + return RiaColorTables::wellPathComponentColors()[componentType()]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathAttribute::startMD() const +{ + return m_startMD(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathAttribute::endMD() const +{ + return m_endMD(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellPathAttribute::isDiameterSupported() const +{ + return m_type() == RiaDefines::CASING || m_type() == RiaDefines::LINER; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimWellPathAttribute::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList options; + if (fieldNeedingOptions == &m_type) + { + std::set supportedTypes = { RiaDefines::CASING, RiaDefines::LINER, RiaDefines::PACKER }; + for (RiaDefines::WellPathComponentType type : supportedTypes) + { + options.push_back(caf::PdmOptionItemInfo(CompletionTypeEnum::uiText(type), type)); + } + } + else if (fieldNeedingOptions == &m_diameterInInches) + { + if (isDiameterSupported()) + { + std::vector values = { MAX_DIAMETER_IN_INCHES, 22.0, 20.0, 18.0 + 5.0 / 8.0, 16.0, 14.0, 13.0 + 3.0 / 8.0, 10.0 + 3.0 / 4.0, 9.0 + 7.0 / 8.0, 9.0 + 5.0 / 8.0, MIN_DIAMETER_IN_INCHES }; + + for (double value : values) + { + options.push_back(caf::PdmOptionItemInfo(generateInchesLabel(value), value)); + } + } + else + { + options.push_back(caf::PdmOptionItemInfo("N/A", MAX_DIAMETER_IN_INCHES)); + } + } + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathAttribute::generateInchesLabel(double diameter) +{ + double integerPart = 0.0; + double fraction = modf(diameter, &integerPart); + + int numerator = static_cast(std::round(8.0 * fraction)); + + if (numerator > 0) + { + return QString("%1 %2/8\"").arg(static_cast(integerPart)).arg(numerator); + } + return QString("%1\"").arg(static_cast(integerPart)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttribute::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) +{ + if (changedField == &m_type) + { + if (m_type() == RiaDefines::CASING) + { + RimWellPath* wellPath = nullptr; + this->firstAncestorOrThisOfTypeAsserted(wellPath); + m_startMD = wellPath->wellPathGeometry()->measureDepths().front(); + } + else if (m_type() == RiaDefines::PACKER) + { + m_endMD = m_startMD + 2; + } + } + if (changedField == &m_startMD) + { + if (m_type() == RiaDefines::PACKER) + { + m_endMD = m_startMD + 2; + } + } + + { + RimWellPathAttributeCollection* collection = nullptr; + this->firstAncestorOrThisOfTypeAsserted(collection); + collection->updateAllReferringTracks(); + } + { + RimProject* proj; + this->firstAncestorOrThisOfTypeAsserted(proj); + proj->reloadCompletionTypeResultsInAllViews(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttribute::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + bool startDepthAvailable = m_type() != RiaDefines::CASING; + + m_startMD.uiCapability()->setUiReadOnly(!startDepthAvailable); + m_diameterInInches.uiCapability()->setUiReadOnly(!isDiameterSupported()); +} diff --git a/ApplicationCode/ProjectDataModel/RimWellPathAttribute.h b/ApplicationCode/ProjectDataModel/RimWellPathAttribute.h new file mode 100644 index 0000000000..effd3e18c1 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellPathAttribute.h @@ -0,0 +1,71 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "RimWellPathComponentInterface.h" + +#include "cafPdmObject.h" + +#include "cafAppEnum.h" +#include "cvfBase.h" +#include "cafPdmField.h" + +#include + +class RimWellPath; + +class RimWellPathAttribute : public caf::PdmObject, public RimWellPathComponentInterface +{ + CAF_PDM_HEADER_INIT; +public: + static double MAX_DIAMETER_IN_INCHES; + static double MIN_DIAMETER_IN_INCHES; + typedef caf::AppEnum CompletionTypeEnum; + + RimWellPathAttribute(); + ~RimWellPathAttribute() override; + + double diameterInInches() const; + QString diameterLabel() const; + bool operator<(const RimWellPathAttribute& rhs) const; + void setDepthsFromWellPath(const RimWellPath* wellPath); + + // Overrides from RimWellPathCompletionInterface + bool isEnabled() const override; + RiaDefines::WellPathComponentType componentType() const override; + QString componentLabel() const override; + QString componentTypeLabel() const override; + cvf::Color3f defaultComponentColor() const override; + double startMD() const override; + double endMD() const override; + +private: + bool isDiameterSupported() const; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + static QString generateInchesLabel(double diameter); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +private: + caf::PdmField m_type; + caf::PdmField m_startMD; + caf::PdmField m_endMD; + caf::PdmField m_diameterInInches; +}; + + diff --git a/ApplicationCode/ProjectDataModel/RimWellPathAttributeCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellPathAttributeCollection.cpp new file mode 100644 index 0000000000..4e272eb66b --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellPathAttributeCollection.cpp @@ -0,0 +1,178 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RimWellPathAttributeCollection.h" + +#include "RimProject.h" +#include "RimWellPathAttribute.h" +#include "RimWellLogTrack.h" + +#include "cafCmdFeatureMenuBuilder.h" +#include "cafPdmUiTableViewEditor.h" +#include "cafPdmUiTreeOrdering.h" + +CAF_PDM_SOURCE_INIT(RimWellPathAttributeCollection, "WellPathAttributes"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathAttributeCollection::RimWellPathAttributeCollection() +{ + CAF_PDM_InitObject("Casing Design", ":/CasingDesign16x16", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_attributes, "Attributes", "Casing Design Attributes", "", "", ""); + m_attributes.uiCapability()->setUiEditorTypeName(caf::PdmUiTableViewEditor::uiEditorTypeName()); + m_attributes.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_attributes.uiCapability()->setCustomContextMenuEnabled(true); + this->setName("Casing Design"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathAttributeCollection::~RimWellPathAttributeCollection() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttributeCollection::updateAllReferringTracks() +{ + std::vector wellLogTracks; + + this->objectsWithReferringPtrFieldsOfType(wellLogTracks); + for (RimWellLogTrack* track : wellLogTracks) + { + track->loadDataAndUpdate(); + } + this->updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathAttributeCollection::attributes() const +{ + std::vector attrs; + + for (auto attr : m_attributes) + { + attrs.push_back(attr.p()); + } + return attrs; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttributeCollection::insertAttribute(RimWellPathAttribute* insertBefore, RimWellPathAttribute* attribute) +{ + size_t index = m_attributes.index(insertBefore); + if (index < m_attributes.size()) + m_attributes.insert(index, attribute); + else + m_attributes.push_back(attribute); + + this->updateAllReferringTracks(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttributeCollection::deleteAttribute(RimWellPathAttribute* attributeToDelete) +{ + m_attributes.removeChildObject(attributeToDelete); + delete attributeToDelete; + + this->updateAllReferringTracks(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttributeCollection::deleteAllAttributes() +{ + m_attributes.deleteAllChildObjects(); + this->updateAllReferringTracks(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttributeCollection::defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, + QMenu* menu, + QWidget* fieldEditorWidget) +{ + caf::CmdFeatureMenuBuilder menuBuilder; + + menuBuilder << "RicNewWellPathAttributeFeature"; + menuBuilder << "Separator"; + menuBuilder << "RicDeleteWellPathAttributeFeature"; + + menuBuilder.appendToMenu(menu); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttributeCollection::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_attributes) + { + auto tvAttribute = dynamic_cast(attribute); + if (tvAttribute) + { + tvAttribute->resizePolicy = caf::PdmUiTableViewEditorAttribute::RESIZE_TO_FILL_CONTAINER; + tvAttribute->alwaysEnforceResizePolicy = true; + tvAttribute->minimumHeight = 300; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttributeCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + uiOrdering.add(&m_attributes); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttributeCollection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/) +{ + uiTreeOrdering.skipRemainingChildren(true); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathAttributeCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) +{ + if (changedField == this->objectToggleField()) + { + RimProject* proj; + this->firstAncestorOrThisOfTypeAsserted(proj); + proj->scheduleCreateDisplayModelAndRedrawAllViews(); + this->updateAllReferringTracks(); + } +} diff --git a/ApplicationCode/ProjectDataModel/RimWellPathAttributeCollection.h b/ApplicationCode/ProjectDataModel/RimWellPathAttributeCollection.h new file mode 100644 index 0000000000..48e0615aea --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellPathAttributeCollection.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "RimCheckableNamedObject.h" + +#include "cafAppEnum.h" +#include "cvfBase.h" +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + +class RimWellPathAttribute; + +class RimWellPathAttributeCollection : public RimCheckableNamedObject +{ + CAF_PDM_HEADER_INIT; +public: + RimWellPathAttributeCollection(); + ~RimWellPathAttributeCollection() override; + + void updateAllReferringTracks(); + std::vector attributes() const; + void insertAttribute(RimWellPathAttribute* insertBefore, RimWellPathAttribute* attribute); + void deleteAttribute(RimWellPathAttribute* attributeToDelete); + void deleteAllAttributes(); + +protected: + void defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, QWidget* fieldEditorWidget) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + +private: + caf::PdmChildArrayField m_attributes; +}; \ No newline at end of file diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp index ed2ed64361..a099abacdf 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp @@ -54,6 +54,8 @@ #include #include +#include "RimFileWellPath.h" +#include "RimModeledWellPath.h" namespace caf { @@ -88,9 +90,9 @@ RimWellPathCollection::RimWellPathCollection() CAF_PDM_InitField(&wellPathRadiusScaleFactor, "WellPathRadiusScale", 0.1, "Well Path Radius Scale", "", "", ""); CAF_PDM_InitField(&wellPathCrossSectionVertexCount, "WellPathVertexCount", 12, "Well Path Vertex Count", "", "", ""); - wellPathCrossSectionVertexCount.xmlCapability()->setIOWritable(false); - wellPathCrossSectionVertexCount.xmlCapability()->setIOReadable(false); + wellPathCrossSectionVertexCount.xmlCapability()->disableIO(); wellPathCrossSectionVertexCount.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&wellPathClip, "WellPathClip", true, "Clip Well Paths", "", "", ""); CAF_PDM_InitField(&wellPathClipZDistance, "WellPathClipZDistance", 100, "Well Path Clipping Depth Distance", "", "", ""); @@ -125,46 +127,56 @@ void RimWellPathCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedF //-------------------------------------------------------------------------------------------------- -/// Read JSON files containing well path data +/// Read files containing well path data, or create geometry based on the targets //-------------------------------------------------------------------------------------------------- -void RimWellPathCollection::readWellPathFiles() +void RimWellPathCollection::loadDataAndUpdate() { caf::ProgressInfo progress(wellPaths.size(), "Reading well paths from file"); for (size_t wpIdx = 0; wpIdx < wellPaths.size(); wpIdx++) { - if (!wellPaths[wpIdx]->filepath().isEmpty()) + RimFileWellPath* fWPath = dynamic_cast(wellPaths[wpIdx]); + RimModeledWellPath* mWPath = dynamic_cast(wellPaths[wpIdx]); + if (fWPath) { - QString errorMessage; - if (!wellPaths[wpIdx]->readWellPathFile(&errorMessage, m_wellPathImporter)) + if ( !fWPath->filepath().isEmpty() ) { - QMessageBox::warning(Riu3DMainWindowTools::mainWindowWidget(), - "File open error", - errorMessage); + QString errorMessage; + if ( !fWPath->readWellPathFile(&errorMessage, m_wellPathImporter) ) + { + QMessageBox::warning(Riu3DMainWindowTools::mainWindowWidget(), + "File open error", + errorMessage); + } } - } - for (RimWellLogFile* const wellLogFile : wellPaths[wpIdx]->wellLogFiles()) - { - if (wellLogFile) + for ( RimWellLogFile* const wellLogFile : fWPath->wellLogFiles() ) { - QString errorMessage; - if (!wellLogFile->readFile(&errorMessage)) + if ( wellLogFile ) { - QString displayMessage = "Could not open the well log file: \n" + wellLogFile->fileName(); - - if (!errorMessage.isEmpty()) + QString errorMessage; + if ( !wellLogFile->readFile(&errorMessage) ) { - displayMessage += "\n\n"; - displayMessage += errorMessage; - } + QString displayMessage = "Could not open the well log file: \n" + wellLogFile->fileName(); - QMessageBox::warning(Riu3DMainWindowTools::mainWindowWidget(), - "File open error", - displayMessage); + if ( !errorMessage.isEmpty() ) + { + displayMessage += "\n\n"; + displayMessage += errorMessage; + } + + QMessageBox::warning(Riu3DMainWindowTools::mainWindowWidget(), + "File open error", + displayMessage); + } } } } + else if (mWPath) + { + mWPath->createWellPathGeometry(); + } + progress.setProgressDescription(QString("Reading file %1").arg(wellPaths[wpIdx]->name())); progress.incrementProgress(); } @@ -178,7 +190,7 @@ void RimWellPathCollection::readWellPathFiles() //-------------------------------------------------------------------------------------------------- void RimWellPathCollection::addWellPaths( QStringList filePaths ) { - std::vector wellPathArray; + std::vector wellPathArray; for (QString filePath : filePaths) { @@ -186,11 +198,14 @@ void RimWellPathCollection::addWellPaths( QStringList filePaths ) bool alreadyOpen = false; for (size_t wpIdx = 0; wpIdx < wellPaths.size(); wpIdx++) { + RimFileWellPath* fWPath = dynamic_cast(wellPaths[wpIdx]); + if (!fWPath) continue; + QFile f1; f1.setFileName(filePath); QString s1 = f1.fileName(); QFile f2; - f2.setFileName(wellPaths[wpIdx]->filepath()); + f2.setFileName(fWPath->filepath()); QString s2 = f2.fileName(); if (s1 == s2) { @@ -206,8 +221,8 @@ void RimWellPathCollection::addWellPaths( QStringList filePaths ) if (fi.suffix().compare("json") == 0) { - RimWellPath* wellPath = new RimWellPath(); - wellPath->filepath = filePath; + RimFileWellPath* wellPath = new RimFileWellPath(); + wellPath->setFilepath(filePath); wellPathArray.push_back(wellPath); } else @@ -216,9 +231,9 @@ void RimWellPathCollection::addWellPaths( QStringList filePaths ) size_t wellPathCount = m_wellPathImporter->wellDataCount(filePath); for (size_t i = 0; i < wellPathCount; ++i) { - RimWellPath* wellPath = new RimWellPath(); - wellPath->filepath = filePath; - wellPath->wellPathIndexInFile = static_cast(i); + RimFileWellPath* wellPath = new RimFileWellPath(); + wellPath->setFilepath(filePath); + wellPath->setWellPathIndexInFile(static_cast(i)); wellPathArray.push_back(wellPath); } } @@ -236,32 +251,23 @@ void RimWellPathCollection::addWellPaths( QStringList filePaths ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPathCollection::readAndAddWellPaths(std::vector& wellPathArray) +void RimWellPathCollection::readAndAddWellPaths(std::vector& wellPathArray) { caf::ProgressInfo progress(wellPathArray.size(), "Reading well paths from file"); - const caf::ColorTable& colorTable = RiaColorTables::wellLogPlotPaletteColors(); - cvf::Color3ubArray wellColors = colorTable.color3ubArray(); - cvf::Color3ubArray interpolatedWellColors = wellColors; - - if (wellPathArray.size() > 1) - { - interpolatedWellColors = caf::ColorTable::interpolateColorArray(wellColors, wellPathArray.size()); - } - for (size_t wpIdx = 0; wpIdx < wellPathArray.size(); wpIdx++) { - RimWellPath* wellPath = wellPathArray[wpIdx]; + RimFileWellPath* wellPath = wellPathArray[wpIdx]; wellPath->readWellPathFile(nullptr, m_wellPathImporter); progress.setProgressDescription(QString("Reading file %1").arg(wellPath->name())); // If a well path with this name exists already, make it read the well path file - RimWellPath* existingWellPath = tryFindMatchingWellPath(wellPath->name()); + RimFileWellPath* existingWellPath = dynamic_cast< RimFileWellPath*>( tryFindMatchingWellPath(wellPath->name())); if (existingWellPath) { - existingWellPath->filepath = wellPath->filepath; - existingWellPath->wellPathIndexInFile = wellPath->wellPathIndexInFile; + existingWellPath->setFilepath(wellPath->filepath()); + existingWellPath->setWellPathIndexInFile(wellPath->wellPathIndexInFile()); existingWellPath->readWellPathFile(nullptr, m_wellPathImporter); // Let name from well path file override name from well log file @@ -272,7 +278,7 @@ void RimWellPathCollection::readAndAddWellPaths(std::vector& wellP } else { - wellPath->wellPathColor = cvf::Color3f(interpolatedWellColors[wpIdx]); + wellPath->setWellPathColor(RiaColorTables::wellPathsPaletteColors().cycledColor3f(wellPaths.size())); wellPath->setUnitSystem(findUnitSystemForWellPath(wellPath)); m_mostRecentlyUpdatedWellPath = wellPath; wellPaths.push_back(wellPath); @@ -287,9 +293,9 @@ void RimWellPathCollection::readAndAddWellPaths(std::vector& wellP //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPathCollection::addWellPaths(const std::vector wellPaths) +void RimWellPathCollection::addWellPaths(const std::vector incomingWellPaths) { - for(const auto& wellPath : wellPaths) + for(const auto& wellPath : incomingWellPaths) { this->wellPaths.push_back(wellPath); } @@ -433,6 +439,22 @@ bool RimWellPathCollection::anyWellsContainingPerforationIntervals() const return false; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimWellPathCollection::modelledWellPathCount() const +{ + size_t count = 0; + for (size_t wellPathIdx = 0; wellPathIdx < wellPaths.size(); wellPathIdx++) + { + if (dynamic_cast( wellPaths[wellPathIdx])) + { + count++; + } + } + return count; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -528,21 +550,26 @@ void RimWellPathCollection::removeWellPath(RimWellPath* wellPath) { wellPaths.removeChildObject(wellPath); - bool isFilePathUsed = false; - for (size_t i = 0; i < wellPaths.size(); i++) + RimFileWellPath* fileWellPath = dynamic_cast(wellPath); + if ( fileWellPath ) { - if (wellPaths[i]->filepath == wellPath->filepath) + bool isFilePathUsed = false; + for ( size_t i = 0; i < wellPaths.size(); i++ ) { - isFilePathUsed = true; - break; + RimFileWellPath* fWPath = dynamic_cast(wellPaths[i]); + if (fWPath && fWPath->filepath() == fileWellPath->filepath() ) + { + isFilePathUsed = true; + break; + } } - } - if (!isFilePathUsed) - { - // One file can have multiple well paths - // If no other well paths are referencing the filepath, remove cached data from the file reader - m_wellPathImporter->removeFilePath(wellPath->filepath); + if ( !isFilePathUsed ) + { + // One file can have multiple well paths + // If no other well paths are referencing the filepath, remove cached data from the file reader + m_wellPathImporter->removeFilePath(fileWellPath->filepath()); + } } } diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.h b/ApplicationCode/ProjectDataModel/RimWellPathCollection.h index 10bef47eaa..ebd96c616e 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.h +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.h @@ -36,6 +36,7 @@ class RifWellPathImporter; class RigWellPath; +class RimFileWellPath; class RimEclipseView; class RimProject; class RimWellLogFile; @@ -60,11 +61,8 @@ class RimWellPathCollection : public caf::PdmObject { CAF_PDM_HEADER_INIT; public: - RimWellPathCollection(); - virtual ~RimWellPathCollection(); - - void setProject(RimProject* project); + ~RimWellPathCollection() override; enum WellVisibilityType { @@ -87,7 +85,7 @@ class RimWellPathCollection : public caf::PdmObject caf::PdmChildArrayField wellPaths; - void readWellPathFiles(); + void loadDataAndUpdate(); void addWellPaths(QStringList filePaths); void removeWellPath(RimWellPath* wellPath); @@ -100,7 +98,7 @@ class RimWellPathCollection : public caf::PdmObject RimWellPath* wellPathByName(const QString& wellPathName) const; RimWellPath* tryFindMatchingWellPath(const QString& wellName) const; - void addWellPaths(const std::vector wellPaths); + void addWellPaths(const std::vector incomingWellPaths); RimWellLogFile* addWellLogs(const QStringList& filePaths); void addWellPathFormations(const QStringList& filePaths); @@ -108,15 +106,15 @@ class RimWellPathCollection : public caf::PdmObject void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath); bool anyWellsContainingPerforationIntervals() const; - + size_t modelledWellPathCount() const; protected: - virtual void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; private: - virtual void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; - virtual caf::PdmFieldHandle* objectToggleField() override; + void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + caf::PdmFieldHandle* objectToggleField() override; - void readAndAddWellPaths(std::vector& wellPathArray); + void readAndAddWellPaths(std::vector& wellPathArray); void sortWellsByName(); RiaEclipseUnitTools::UnitSystemType findUnitSystemForWellPath(const RimWellPath* wellPath); diff --git a/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.cpp b/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.cpp new file mode 100644 index 0000000000..290636bc0b --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.cpp @@ -0,0 +1,652 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#include "RimWellPathGeometryDef.h" + +#include "WellPathCommands/RicCreateWellTargetsPickEventHandler.h" + +#include "RiaFieldHandleTools.h" +#include "RiaJCurveCalculator.h" +#include "RiaLogging.h" +#include "RiaOffshoreSphericalCoords.h" +#include "RiaPolyArcLineSampler.h" +#include "RiaSCurveCalculator.h" + +#include "RigWellPath.h" + +#include "RimModeledWellPath.h" +#include "RimWellPathTarget.h" + +#include "RiuViewerCommands.h" + +#include "cafCmdFeatureMenuBuilder.h" +#include "cafPdmUiPushButtonEditor.h" +#include "cafPdmUiTableViewEditor.h" +#include "cafPdmUiTreeOrdering.h" +#include "cvfGeometryTools.h" + + +namespace caf +{ +template<> +void caf::AppEnum< RimWellPathGeometryDef::WellStartType >::setUp() +{ + addItem(RimWellPathGeometryDef::START_AT_FIRST_TARGET, "START_AT_FIRST_TARGET", "Start at First Target"); + addItem(RimWellPathGeometryDef::START_AT_SURFACE, "START_AT_SURFACE", "Start at Surface"); + addItem(RimWellPathGeometryDef::START_FROM_OTHER_WELL, "START_FROM_OTHER_WELL", "Branch"); + addItem(RimWellPathGeometryDef::START_AT_AUTO_SURFACE, "START_AT_AUTO_SURFACE", "Auto Surface"); + + setDefault(RimWellPathGeometryDef::START_AT_FIRST_TARGET); +} +} + +CAF_PDM_SOURCE_INIT(RimWellPathGeometryDef, "WellPathGeometryDef"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathGeometryDef::RimWellPathGeometryDef() + : m_pickTargetsEventHandler(new RicCreateWellTargetsPickEventHandler(this)) +{ + CAF_PDM_InitObject("Well Targets", ":/WellTargets.png", "", ""); + + CAF_PDM_InitField(&m_referencePointUtmXyd, "ReferencePosUtmXyd", cvf::Vec3d(0,0,0), "UTM Reference Point", "", "", ""); + + CAF_PDM_InitField(&m_mdrkbAtFirstTarget, "MdrkbAtFirstTarget", 0.0, "MDRKB at First Target", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_wellTargets, "WellPathTargets", "Well Targets", "", "", ""); + m_wellTargets.uiCapability()->setUiEditorTypeName(caf::PdmUiTableViewEditor::uiEditorTypeName()); + //m_wellTargets.uiCapability()->setUiTreeHidden(true); + m_wellTargets.uiCapability()->setUiTreeChildrenHidden(true); + m_wellTargets.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + m_wellTargets.uiCapability()->setCustomContextMenuEnabled(true); + + CAF_PDM_InitField(&m_pickPointsEnabled, "m_pickPointsEnabled", false, "", "", "", ""); + caf::PdmUiPushButtonEditor::configureEditorForField(&m_pickPointsEnabled); + + // Temp conversion field. + CAF_PDM_InitField(&m_referencePointXyz_OBSOLETE, "ReferencePos", cvf::Vec3d(0,0,0), "UTM Reference Point", "", "", ""); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_referencePointXyz_OBSOLETE); + + /// To be removed ? + + CAF_PDM_InitFieldNoDefault(&m_wellStartType, "WellStartType", "Start Type", "", "", ""); + m_wellStartType.xmlCapability()->disableIO(); + CAF_PDM_InitFieldNoDefault(&m_parentWell, "ParentWell", "Parent Well", "", "", ""); + m_parentWell.xmlCapability()->disableIO(); + CAF_PDM_InitField(&m_kickoffDepthOrMD, "KickoffDepthOrMD", 100.0, "Kickoff Depth", "", "", ""); + m_kickoffDepthOrMD.xmlCapability()->disableIO(); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathGeometryDef::~RimWellPathGeometryDef() +{ + RiuViewerCommands::removePickEventHandlerIfActive(m_pickTargetsEventHandler); + + delete m_pickTargetsEventHandler; + + m_pickTargetsEventHandler = nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec3d RimWellPathGeometryDef::referencePointXyz() const +{ + cvf::Vec3d xyz(m_referencePointUtmXyd()); + xyz.z() = -xyz.z(); + return xyz; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::setReferencePointXyz(const cvf::Vec3d& refPointXyz) +{ + cvf::Vec3d xyd(refPointXyz); + xyd.z() = -xyd.z(); + m_referencePointUtmXyd = xyd; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathGeometryDef::mdrkbAtFirstTarget() const +{ + return m_mdrkbAtFirstTarget; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::setMdrkbAtFirstTarget(double mdrkb) +{ + m_mdrkbAtFirstTarget = mdrkb; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::ref RimWellPathGeometryDef::createWellPathGeometry() +{ + cvf::ref wellPathGeometry = new RigWellPath; + + RiaLineArcWellPathCalculator wellPathCalculator = lineArcWellPathCalculator(); + + if (wellPathCalculator.lineArcEndpoints().size() < 2) return wellPathGeometry; + + RiaPolyArcLineSampler arcLineSampler(wellPathCalculator.startTangent(), wellPathCalculator.lineArcEndpoints()); + + + arcLineSampler.sampledPointsAndMDs(30, + false, + &(wellPathGeometry->m_wellPathPoints), + &(wellPathGeometry->m_measuredDepths)); + + return wellPathGeometry; +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathGeometryDef::wellPlan() const +{ + RiaLineArcWellPathCalculator wellPathCalculator = lineArcWellPathCalculator(); + + RiaWellPlanCalculator wpCalc(wellPathCalculator.startTangent(), wellPathCalculator.lineArcEndpoints()); + + return wpCalc.wellPlan(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::updateWellPathVisualization() +{ + RimModeledWellPath* modWellPath; + this->firstAncestorOrThisOfTypeAsserted(modWellPath); + modWellPath->updateWellPathVisualization(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair +RimWellPathGeometryDef::findActiveTargetsAroundInsertionPoint(const RimWellPathTarget* targetToInsertBefore) +{ + RimWellPathTarget* before = nullptr; + RimWellPathTarget* after = nullptr; + + bool foundTarget = false; + for (const auto& wt : m_wellTargets) + { + if ( wt == targetToInsertBefore ) + { + foundTarget = true; + } + + if ( wt->isEnabled() && !after && foundTarget ) after = wt; + + if ( wt->isEnabled() && !foundTarget ) before = wt; + } + + return { before, after}; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::insertTarget(const RimWellPathTarget* targetToInsertBefore, RimWellPathTarget* targetToInsert) +{ + size_t index = m_wellTargets.index(targetToInsertBefore); + if (index < m_wellTargets.size()) m_wellTargets.insert(index, targetToInsert); + else m_wellTargets.push_back(targetToInsert); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::deleteTarget(RimWellPathTarget* targetTodelete) +{ + m_wellTargets.removeChildObject(targetTodelete); + delete targetTodelete; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::appendTarget() +{ + RimWellPathTarget* wellPathTarget = nullptr; + + auto targets = m_wellTargets.childObjects(); + if (targets.empty()) + { + wellPathTarget = new RimWellPathTarget; + } + else + { + wellPathTarget = dynamic_cast(targets.back()->xmlCapability()->copyByXmlSerialization(caf::PdmDefaultObjectFactory::instance())); + } + + if (wellPathTarget) + { + m_wellTargets.push_back(wellPathTarget); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimWellPathTarget* RimWellPathGeometryDef::firstActiveTarget() const +{ + for (const RimWellPathTarget* target: m_wellTargets) + { + if (target->isEnabled()) + { + return target; + } + } + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimWellPathTarget* RimWellPathGeometryDef::lastActiveTarget() const +{ + if (!m_wellTargets.size()) return nullptr; + + for (int tIdx = static_cast(m_wellTargets.size() - 1); tIdx >= 0 ; --tIdx) + { + if (m_wellTargets[tIdx]->isEnabled()) + { + return m_wellTargets[tIdx]; + } + } + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::enableTargetPointPicking(bool isEnabling) +{ + if (isEnabling) + { + m_pickPointsEnabled = true; + RiuViewerCommands::setPickEventHandler(m_pickTargetsEventHandler); + updateConnectedEditors(); + } + else + { + RiuViewerCommands::removePickEventHandlerIfActive(m_pickTargetsEventHandler); + m_pickPointsEnabled = false; + updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimWellPathGeometryDef::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly) +{ + QList options; + + if (fieldNeedingOptions == &m_wellStartType) + { + options.push_back(caf::PdmOptionItemInfo("Start at First Target",RimWellPathGeometryDef::START_AT_FIRST_TARGET )); + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) +{ + if (&m_referencePointUtmXyd == changedField) + { + std::cout << "fieldChanged" << std::endl; + } + else if (changedField == &m_pickPointsEnabled) + { + enableTargetPointPicking(m_pickPointsEnabled); + } + + updateWellPathVisualization(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + uiOrdering.add(&m_wellStartType); + if (m_wellStartType == START_FROM_OTHER_WELL) + { + uiOrdering.add(&m_parentWell); + m_kickoffDepthOrMD.uiCapability()->setUiName("Measured Depth"); + uiOrdering.add(&m_kickoffDepthOrMD); + } + + if (m_wellStartType == START_AT_SURFACE) + { + m_kickoffDepthOrMD.uiCapability()->setUiName("Kick-Off Depth"); + uiOrdering.add(&m_kickoffDepthOrMD); + } + + uiOrdering.add(&m_referencePointUtmXyd); + uiOrdering.add(&m_mdrkbAtFirstTarget); + uiOrdering.add(&m_wellTargets); + uiOrdering.add(&m_pickPointsEnabled); + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) +{ + uiTreeOrdering.skipRemainingChildren(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathGeometryDef::activeWellTargets() const +{ + std::vector active; + for (const auto& wt : m_wellTargets) + { + if (wt->isEnabled()) + { + active.push_back(wt); + } + } + + return active; +} + +#if 0 // Kept for reference a bit longer +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPathGeometryDef::lineArcEndpoints() const +{ + double prevSegmentEndAzi = 0; + double prevSegmentEndInc = 0; + + std::vector activeWellPathTargets = activeWellTargets(); + + CVF_ASSERT(activeWellPathTargets.size() > 1); + + std::vector endPoints; + endPoints.push_back( activeWellPathTargets[0]->targetPointXYZ() + referencePointXyz() ); + + for ( size_t tIdx = 0; tIdx < activeWellPathTargets.size() - 1; ++tIdx) + { + RimWellPathTarget* target1 = activeWellPathTargets[tIdx]; + RimWellPathTarget* target2 = activeWellPathTargets[tIdx+1]; + + // Ignore targets in the same place + if ((target1->targetPointXYZ() - target2->targetPointXYZ()).length() < 1e-6) continue; + + target1->flagRadius2AsIncorrect(false, 0); + target2->flagRadius1AsIncorrect(false, 0); + + if ( target1->targetType() == RimWellPathTarget::POINT_AND_TANGENT + && target2->targetType() == RimWellPathTarget::POINT_AND_TANGENT) + { + 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)); + + target1->flagRadius2AsIncorrect(true, sCurveCalc.firstRadius()); + target2->flagRadius1AsIncorrect(true, sCurveCalc.secondRadius()); + } + + endPoints.push_back( sCurveCalc.firstArcEndpoint() + referencePointXyz() ); + endPoints.push_back( sCurveCalc.secondArcStartpoint() + referencePointXyz() ); + endPoints.push_back( target2->targetPointXYZ() + referencePointXyz() ); + + } + else if ( target1->targetType() == RimWellPathTarget::POINT + && target2->targetType() == RimWellPathTarget::POINT_AND_TANGENT) + { + RiaSCurveCalculator sCurveCalc(target1->targetPointXYZ(), + prevSegmentEndAzi, + prevSegmentEndInc, + 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(), + prevSegmentEndAzi, + prevSegmentEndInc, + 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)); + + target1->flagRadius2AsIncorrect(true, sCurveCalc.firstRadius()); + target2->flagRadius1AsIncorrect(true, sCurveCalc.secondRadius()); + } + + endPoints.push_back( sCurveCalc.firstArcEndpoint() + referencePointXyz() ); + endPoints.push_back( sCurveCalc.secondArcStartpoint() + referencePointXyz() ); + endPoints.push_back( target2->targetPointXYZ() + referencePointXyz() ); + } + else if ( target1->targetType() == RimWellPathTarget::POINT_AND_TANGENT + && target2->targetType() == RimWellPathTarget::POINT) + { + RiaJCurveCalculator jCurve(target1->targetPointXYZ(), + target1->azimuth(), + target1->inclination(), + target1->radius2(), + target2->targetPointXYZ()); + + if ( jCurve.curveStatus() == RiaJCurveCalculator::OK ) + { + endPoints.push_back(jCurve.firstArcEndpoint() + referencePointXyz()); + } + else if ( jCurve.curveStatus() == RiaJCurveCalculator::FAILED_RADIUS_TOO_LARGE ) + { + target1->flagRadius2AsIncorrect(true, jCurve.radius()); + } + + endPoints.push_back( target2->targetPointXYZ() + referencePointXyz() ); + prevSegmentEndAzi = jCurve.endAzimuth(); + prevSegmentEndInc = jCurve.endInclination(); + + target2->setDerivedTangent(prevSegmentEndAzi, prevSegmentEndInc); + } + + else if ( target1->targetType() == RimWellPathTarget::POINT + && target2->targetType() == RimWellPathTarget::POINT) + { + RiaJCurveCalculator jCurve(target1->targetPointXYZ(), + prevSegmentEndAzi, + prevSegmentEndInc, + target1->radius2(), + target2->targetPointXYZ()); + + if ( jCurve.curveStatus() == RiaJCurveCalculator::OK ) + { + endPoints.push_back(jCurve.firstArcEndpoint() + referencePointXyz()); + } + else if ( jCurve.curveStatus() == RiaJCurveCalculator::FAILED_RADIUS_TOO_LARGE ) + { + target1->flagRadius2AsIncorrect(true, jCurve.radius()); + } + + endPoints.push_back( target2->targetPointXYZ() + referencePointXyz() ); + prevSegmentEndAzi = jCurve.endAzimuth(); + prevSegmentEndInc = jCurve.endInclination(); + + target2->setDerivedTangent(prevSegmentEndAzi, prevSegmentEndInc); + } + else + { + CVF_ASSERT(false); + } + } + + return endPoints; +} + +#endif + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaLineArcWellPathCalculator RimWellPathGeometryDef::lineArcWellPathCalculator() const +{ + std::vector wellTargets = activeWellTargets(); + + std::vector< RiaLineArcWellPathCalculator::WellTarget> targetDatas; + + for (auto wellTarget : wellTargets) + { + targetDatas.push_back(wellTarget->wellTargetData()); + } + + RiaLineArcWellPathCalculator wellPathCalculator(referencePointXyz(), targetDatas); + const std::vector& targetStatuses = wellPathCalculator.targetStatuses(); + + for ( size_t tIdx = 0 ; tIdx < wellTargets.size(); ++tIdx ) + { + wellTargets[tIdx]->flagRadius1AsIncorrect(false, 0 ); + wellTargets[tIdx]->flagRadius2AsIncorrect(false, 0 ); + + if ( targetStatuses[tIdx].hasDerivedTangent ) + { + wellTargets[tIdx]->setDerivedTangent(targetStatuses[tIdx].resultAzimuth, targetStatuses[tIdx].resultInclination); + } + + if ( targetStatuses[tIdx].hasOverriddenRadius1 ) + { + wellTargets[tIdx]->flagRadius1AsIncorrect(true, targetStatuses[tIdx].resultRadius1); + } + + if ( targetStatuses[tIdx].hasOverriddenRadius2 ) + { + wellTargets[tIdx]->flagRadius2AsIncorrect(true, targetStatuses[tIdx].resultRadius2); + } + } + + return wellPathCalculator; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, + QMenu* menu, + QWidget* fieldEditorWidget) +{ + caf::CmdFeatureMenuBuilder menuBuilder; + + menuBuilder << "RicNewWellPathListTargetFeature"; + menuBuilder << "Separator"; + menuBuilder << "RicDeleteWellPathTargetFeature"; + + menuBuilder.appendToMenu(menu); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_pickPointsEnabled) + { + caf::PdmUiPushButtonEditorAttribute* pbAttribute = dynamic_cast(attribute); + if ( pbAttribute ) + { + if ( !m_pickPointsEnabled ) + { + pbAttribute->m_buttonText = "Start Picking Targets"; + } + else + { + pbAttribute->m_buttonText = "Stop Picking Targets"; + } + } + } + + if (field == &m_wellTargets) + { + auto tvAttribute = dynamic_cast(attribute); + if (tvAttribute) + { + tvAttribute->resizePolicy = caf::PdmUiTableViewEditorAttribute::RESIZE_TO_FIT_CONTENT; + + if (m_pickPointsEnabled) + { + tvAttribute->baseColor.setRgb(255, 220, 255); + tvAttribute->alwaysEnforceResizePolicy = true; + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathGeometryDef::initAfterRead() +{ + // To be removed before release 2018.11 + + if (m_referencePointXyz_OBSOLETE != cvf::Vec3d::ZERO && m_referencePointUtmXyd == cvf::Vec3d::ZERO) + { + m_referencePointUtmXyd = cvf::Vec3d(m_referencePointXyz_OBSOLETE().x(), m_referencePointXyz_OBSOLETE().y(), -m_referencePointXyz_OBSOLETE().z()); + } +} diff --git a/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h b/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h new file mode 100644 index 0000000000..b3cff922fe --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellPathGeometryDef.h @@ -0,0 +1,111 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "cvfBase.h" +#include "cvfObject.h" +#include "cafPdmObject.h" +#include "cafAppEnum.h" +#include "cafPdmField.h" +#include "cafPdmFieldCvfVec3d.h" +#include "cafPdmPtrField.h" +#include "cafPdmChildArrayField.h" +#include "RiaWellPlanCalculator.h" +#include "RiaLineArcWellPathCalculator.h" + + +class RimWellPath; +class RimWellPathTarget; +class RicCreateWellTargetsPickEventHandler; + +class RigWellPath; + +class RimWellPathGeometryDef : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + RimWellPathGeometryDef(); + ~RimWellPathGeometryDef() override; + + enum WellStartType { START_AT_FIRST_TARGET, START_AT_SURFACE, START_FROM_OTHER_WELL, START_AT_AUTO_SURFACE }; + + cvf::Vec3d referencePointXyz() const; + void setReferencePointXyz(const cvf::Vec3d& refPointXyz ); + + double mdrkbAtFirstTarget() const; + void setMdrkbAtFirstTarget(double mdrkb); + + cvf::ref createWellPathGeometry(); + + void updateWellPathVisualization(); + std::pair findActiveTargetsAroundInsertionPoint(const RimWellPathTarget* targetToInsertBefore); + + void insertTarget(const RimWellPathTarget* targetToInsertBefore, + RimWellPathTarget* targetToInsert); + void deleteTarget(RimWellPathTarget* targetTodelete); + void appendTarget(); + + const RimWellPathTarget* firstActiveTarget() const; + const RimWellPathTarget* lastActiveTarget() const; + + void enableTargetPointPicking(bool isEnabling); + + std::vector wellPlan() const; + std::vector activeWellTargets() const; +protected: + void defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, + QMenu* menu, + QWidget* fieldEditorWidget) override; + + + void defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; + + + +private: + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, + caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, + QString uiConfigName) override; + void initAfterRead() override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + + RiaLineArcWellPathCalculator lineArcWellPathCalculator() const; + +private: + caf::PdmField m_referencePointUtmXyd; + caf::PdmField m_referencePointXyz_OBSOLETE; + + caf::PdmField m_mdrkbAtFirstTarget; + caf::PdmChildArrayField m_wellTargets; + + caf::PdmField< bool > m_pickPointsEnabled; + RicCreateWellTargetsPickEventHandler* m_pickTargetsEventHandler; + + // Unused for now. Remove when dust settles + + caf::PdmField > m_wellStartType; + caf::PdmField m_kickoffDepthOrMD; + caf::PdmPtrField m_parentWell; +}; diff --git a/ApplicationCode/ProjectDataModel/RimWellPathTarget.cpp b/ApplicationCode/ProjectDataModel/RimWellPathTarget.cpp new file mode 100644 index 0000000000..77fad44b56 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellPathTarget.cpp @@ -0,0 +1,336 @@ +#include "RimWellPathTarget.h" +#include "RimModeledWellPath.h" + +#include +#include "RimWellPathGeometryDef.h" +#include "cafPdmUiCheckBoxEditor.h" + +CAF_PDM_SOURCE_INIT(RimWellPathTarget, "WellPathTarget"); + +namespace caf +{ +template<> +void caf::AppEnum< RimWellPathTarget::TargetTypeEnum >::setUp() +{ + addItem(RimWellPathTarget::POINT_AND_TANGENT, "POINT_AND_TANGENT", "Point and Tangent"); + addItem(RimWellPathTarget::POINT, "POINT", "Point"); + setDefault(RimWellPathTarget::POINT_AND_TANGENT); +} +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathTarget::RimWellPathTarget() + : m_targetType(POINT_AND_TANGENT) + , m_targetPoint(cvf::Vec3d::ZERO) + , m_azimuth(0.0) + , m_inclination(0.0) + , m_isFullUpdateEnabled(true) +{ + + CAF_PDM_InitField(&m_isEnabled, "IsEnabled", true, "", "", "", ""); + //m_targetType.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_targetPoint, "TargetPoint", "Point", "", "", ""); + CAF_PDM_InitField(&m_dogleg1, "Dogleg1", 3.0, "DL in", "", "[deg/30m]", ""); + CAF_PDM_InitField(&m_dogleg2, "Dogleg2", 3.0, "DL out", "", "[deg/30m]", ""); + CAF_PDM_InitFieldNoDefault(&m_targetType, "TargetType", "Type", "", "", ""); + m_targetType.uiCapability()->setUiHidden(true); + CAF_PDM_InitField(&m_hasTangentConstraintUiField, "HasTangentConstraint", false, "Dir", "", "", ""); + m_hasTangentConstraintUiField.xmlCapability()->disableIO(); + CAF_PDM_InitField(&m_azimuth, "Azimuth", 0.0, "Azi(deg)", "", "", ""); + CAF_PDM_InitField(&m_inclination, "Inclination", 0.0, "Inc(deg)", "", "", ""); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathTarget::~RimWellPathTarget() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellPathTarget::isEnabled() const +{ + return m_isEnabled; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathTarget::setAsPointTargetXYD(const cvf::Vec3d& point) +{ + m_targetType = POINT; + m_targetPoint = point; + m_azimuth = 0.0; + m_inclination = 0.0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathTarget::setAsPointXYZAndTangentTarget(const cvf::Vec3d& point, + double azimuth, + double inclination) +{ + m_targetType = POINT_AND_TANGENT; + m_targetPoint = cvf::Vec3d(point.x(), point.y(), -point.z()); + m_azimuth = cvf::Math::toDegrees(azimuth); + m_inclination = cvf::Math::toDegrees(inclination); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathTarget::setDerivedTangent(double azimuth, double inclination) +{ + if (m_targetType == POINT) + { + m_azimuth = cvf::Math::toDegrees(azimuth); + m_inclination = cvf::Math::toDegrees(inclination); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaLineArcWellPathCalculator::WellTarget RimWellPathTarget::wellTargetData() +{ + RiaLineArcWellPathCalculator::WellTarget targetData; + + targetData.targetPointXYZ = targetPointXYZ(); + targetData.isTangentConstrained = (targetType() == POINT_AND_TANGENT); + targetData.azimuth = azimuth(); + targetData.inclination = inclination(); + targetData.radius1 = radius1(); + targetData.radius2 = radius2(); + + return targetData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathTarget::TargetTypeEnum RimWellPathTarget::targetType() const +{ + return m_targetType(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec3d RimWellPathTarget::targetPointXYZ() const +{ + cvf::Vec3d xyzPoint(m_targetPoint()); + xyzPoint.z() = -xyzPoint.z(); + return xyzPoint; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathTarget::azimuth() const +{ + if ( m_targetType() == POINT_AND_TANGENT ) + { + return cvf::Math::toRadians( m_azimuth); + } + else + { + return std::numeric_limits::infinity(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathTarget::inclination() const +{ + if ( m_targetType() == POINT_AND_TANGENT ) + { + return cvf::Math::toRadians(m_inclination); + } + else + { + return std::numeric_limits::infinity(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec3d RimWellPathTarget::tangent() const +{ + double aziRad = cvf::Math::toRadians(m_azimuth); + double incRad = cvf::Math::toRadians(m_inclination); + return cvf::Vec3d (sin(aziRad) * sin(incRad), + cos(aziRad) * sin(incRad), + -cos(incRad)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathTarget::radius1() const +{ + // Needs to be aware of unit to select correct DLS conversion + // Degrees pr 100 ft + // Degrees pr 10m + + // Degrees pr 30m + if (fabs(m_dogleg1) < 1e-6) return std::numeric_limits::infinity(); + + return 30.0/cvf::Math::toRadians(m_dogleg1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimWellPathTarget::radius2() const +{ + // Needs to be aware of unit to select correct DLS conversion + // Degrees pr 100 ft + // Degrees pr 10m + + // Degrees pr 30m + + if (fabs(m_dogleg2) < 1e-6) return std::numeric_limits::infinity(); + + return 30.0/cvf::Math::toRadians(m_dogleg2); +} + +double doglegFromRadius(double radius) +{ + return cvf::Math::toDegrees(30.0/radius); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathTarget::flagRadius1AsIncorrect(bool isIncorrect, double actualRadius) +{ + if (isIncorrect) + { + m_dogleg1.uiCapability()->setUiContentTextColor(Qt::red); + m_dogleg1.uiCapability()->setUiToolTip("The dogleg constraint is not satisfied! Actual Dogleg: " + QString::number(doglegFromRadius(actualRadius))); + } + else + { + m_dogleg1.uiCapability()->setUiContentTextColor(QColor()); + m_dogleg1.uiCapability()->setUiToolTip(""); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathTarget::flagRadius2AsIncorrect(bool isIncorrect, double actualRadius) +{ + if (isIncorrect) + { + m_dogleg2.uiCapability()->setUiContentTextColor(Qt::red); + m_dogleg2.uiCapability()->setUiToolTip("The dogleg constraint is not satisfied! Actual Dogleg: " + QString::number(doglegFromRadius(actualRadius))); + } + else + { + m_dogleg2.uiCapability()->setUiContentTextColor(QColor()); + m_dogleg2.uiCapability()->setUiToolTip(""); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathTarget::enableFullUpdate(bool enable) +{ + m_isFullUpdateEnabled = enable; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimWellPathTarget::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList options; + if (fieldNeedingOptions == & m_targetType) + { + options.push_back(caf::PdmOptionItemInfo("o->",RimWellPathTarget::POINT_AND_TANGENT));//, false, QIcon(":/WellTargetPointTangent16x16.png") )); + options.push_back(caf::PdmOptionItemInfo("o", RimWellPathTarget::POINT));//, false, QIcon(":/WellTargetPoint16x16.png"))); + } + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathTarget::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &m_hasTangentConstraintUiField) + { + if (m_hasTangentConstraintUiField) m_targetType = POINT_AND_TANGENT; + else m_targetType = POINT; + } + + RimModeledWellPath* wellPath; + firstAncestorOrThisOfTypeAsserted(wellPath); + wellPath->updateWellPathVisualization(); + if (m_isFullUpdateEnabled) + { + wellPath->scheduleUpdateOfDependentVisualization(); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPathTarget::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + m_hasTangentConstraintUiField = (m_targetType == POINT_AND_TANGENT); + + if (m_isEnabled()) + { + m_hasTangentConstraintUiField.uiCapability()->setUiReadOnly(false); + m_targetType.uiCapability()->setUiReadOnly(false); + m_targetPoint.uiCapability()->setUiReadOnly(false); + m_dogleg2.uiCapability()->setUiReadOnly(false); + + if ( m_targetType == POINT ) + { + m_azimuth.uiCapability()->setUiReadOnly(true); + m_inclination.uiCapability()->setUiReadOnly(true); + m_dogleg1.uiCapability()->setUiReadOnly(true); + } + else + { + m_azimuth.uiCapability()->setUiReadOnly(false); + m_inclination.uiCapability()->setUiReadOnly(false); + m_dogleg1.uiCapability()->setUiReadOnly(false); + } + + RimWellPathGeometryDef* geomDef = nullptr; + firstAncestorOrThisOfTypeAsserted(geomDef); + + if ( this == geomDef->firstActiveTarget() ) + { + m_dogleg1.uiCapability()->setUiReadOnly(true); + } + + if ( this == geomDef->lastActiveTarget() ) + { + m_dogleg2.uiCapability()->setUiReadOnly(true); + } + } + else + { + m_dogleg1.uiCapability()->setUiReadOnly(true); + m_targetType.uiCapability()->setUiReadOnly(true); + m_targetPoint.uiCapability()->setUiReadOnly(true); + m_azimuth.uiCapability()->setUiReadOnly(true); + m_inclination.uiCapability()->setUiReadOnly(true); + m_dogleg2.uiCapability()->setUiReadOnly(true); + m_hasTangentConstraintUiField.uiCapability()->setUiReadOnly(true); + } +} diff --git a/ApplicationCode/ProjectDataModel/RimWellPathTarget.h b/ApplicationCode/ProjectDataModel/RimWellPathTarget.h new file mode 100644 index 0000000000..248eb5f99d --- /dev/null +++ b/ApplicationCode/ProjectDataModel/RimWellPathTarget.h @@ -0,0 +1,74 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 - Equinor +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include "cafPdmObject.h" + +#include "cvfBase.h" +#include "cvfVector3.h" +#include "cafAppEnum.h" +#include "cafPdmField.h" +#include "cafPdmCoreVec3d.h" +#include "RiaLineArcWellPathCalculator.h" + +class RimWellPathTarget : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + RimWellPathTarget(); + ~RimWellPathTarget() override; + + bool isEnabled() const; + + void setAsPointTargetXYD(const cvf::Vec3d& point); + void setAsPointXYZAndTangentTarget(const cvf::Vec3d& point, double azimuth, double inclination); + void setDerivedTangent(double azimuth, double inclination); + + RiaLineArcWellPathCalculator::WellTarget wellTargetData(); + + enum TargetTypeEnum { POINT_AND_TANGENT, POINT }; + TargetTypeEnum targetType() const; + cvf::Vec3d targetPointXYZ() const; + double azimuth() const; + double inclination() const; + cvf::Vec3d tangent() const; + double radius1() const; + double radius2() const; + void flagRadius1AsIncorrect(bool isIncorrect, double actualRadius); + void flagRadius2AsIncorrect(bool isIncorrect, double actualRadius); + +private: + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +private: + friend class RicWellTarget3dEditor; + void enableFullUpdate(bool enable); + bool m_isFullUpdateEnabled; + caf::PdmField m_isEnabled; + caf::PdmField > m_targetType; + caf::PdmField m_targetPoint; + caf::PdmField m_azimuth; + caf::PdmField m_inclination; + caf::PdmField m_dogleg1; + caf::PdmField m_dogleg2; + caf::PdmField m_hasTangentConstraintUiField; + +}; + diff --git a/ApplicationCode/ProjectDataModel/Summary/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/Summary/CMakeLists_files.cmake index 09bc668aec..c9f905f1df 100644 --- a/ApplicationCode/ProjectDataModel/Summary/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/Summary/CMakeLists_files.cmake @@ -32,6 +32,12 @@ ${CMAKE_CURRENT_LIST_DIR}/RimSummaryPlotNameHelper.h ${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSetCollection.h ${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSet.h ${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSetColorManager.h +${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilter.h +${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilterCollection.h +${CMAKE_CURRENT_LIST_DIR}/RimEnsembleStatistics.h +${CMAKE_CURRENT_LIST_DIR}/RimEnsembleStatisticsCase.h +${CMAKE_CURRENT_LIST_DIR}/RimDerivedEnsembleCase.h +${CMAKE_CURRENT_LIST_DIR}/RimDerivedEnsembleCaseCollection.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -67,6 +73,12 @@ ${CMAKE_CURRENT_LIST_DIR}/RimSummaryPlotNameHelper.cpp ${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSetCollection.cpp ${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSet.cpp ${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSetColorManager.cpp +${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilter.cpp +${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilterCollection.cpp +${CMAKE_CURRENT_LIST_DIR}/RimEnsembleStatistics.cpp +${CMAKE_CURRENT_LIST_DIR}/RimEnsembleStatisticsCase.cpp +${CMAKE_CURRENT_LIST_DIR}/RimDerivedEnsembleCase.cpp +${CMAKE_CURRENT_LIST_DIR}/RimDerivedEnsembleCaseCollection.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.cpp b/ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.cpp index 1efd3a051c..9cdf023e91 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.cpp @@ -30,7 +30,7 @@ #include "RimSummaryPlot.h" #include "RimSummaryTimeAxisProperties.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuSummaryQwtPlot.h" #include "cafPdmUiComboBoxEditor.h" diff --git a/ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.h b/ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.h index f078fac30e..375e47fb36 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimAsciiDataCurve.h @@ -36,7 +36,7 @@ class RifReaderEclipseSummary; class RimSummaryCase; class RimSummaryFilter; -class RiuLineSegmentQwtPlotCurve; +class RiuQwtPlotCurve; class RimAsciiDataCurveAutoName; //================================================================================================== @@ -49,7 +49,7 @@ class RimAsciiDataCurve : public RimPlotCurve public: RimAsciiDataCurve(); - virtual ~RimAsciiDataCurve(); + ~RimAsciiDataCurve() override; std::vector yValues() const; const std::vector& timeSteps() const; @@ -65,15 +65,15 @@ class RimAsciiDataCurve : public RimPlotCurve protected: // RimPlotCurve overrides - virtual QString createCurveAutoName() override; - virtual void updateZoomInParentPlot() override; - virtual void onLoadDataAndUpdate(bool updateParentPlot) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + QString createCurveAutoName() override; + void updateZoomInParentPlot() override; + void onLoadDataAndUpdate(bool updateParentPlot) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: bool curveData(std::vector* timeSteps, std::vector* values) const; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: // Fields diff --git a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp index 24db8344d4..e8c8075ced 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.cpp @@ -44,7 +44,7 @@ RimCalculatedSummaryCase::~RimCalculatedSummaryCase() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimCalculatedSummaryCase::caseName() +QString RimCalculatedSummaryCase::caseName() const { return "Calculated"; } diff --git a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.h b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.h index e40bb9c386..d0311877dc 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCase.h @@ -38,12 +38,12 @@ class RimCalculatedSummaryCase : public RimSummaryCase public: RimCalculatedSummaryCase(); - virtual ~RimCalculatedSummaryCase(); + ~RimCalculatedSummaryCase() override; - virtual QString caseName() override; - virtual void createSummaryReaderInterface() override; - virtual RifSummaryReaderInterface* summaryReader() override; - virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; + QString caseName() const override; + void createSummaryReaderInterface() override; + RifSummaryReaderInterface* summaryReader() override; + void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; void buildMetaData(); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.cpp b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.cpp index 7aa87631dd..1dda139f88 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.cpp @@ -86,7 +86,7 @@ void RifCalculatedSummaryCurveReader::buildMetaData() for (RimSummaryCalculation* calc : m_calculationCollection->calculations()) { - m_allResultAddresses.push_back(RifEclipseSummaryAddress::calculatedCurveAddress(calc->description().toStdString())); + m_allResultAddresses.insert(RifEclipseSummaryAddress::calculatedAddress(calc->description().toStdString())); } } diff --git a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.h b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.h index 24dc9abd04..325495ecef 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimCalculatedSummaryCurveReader.h @@ -36,9 +36,9 @@ class RifCalculatedSummaryCurveReader : public RifSummaryReaderInterface public: explicit RifCalculatedSummaryCurveReader(RimSummaryCalculationCollection* calculationCollection); - virtual const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; - virtual bool values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const override; - virtual std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; + const std::vector& timeSteps(const RifEclipseSummaryAddress& resultAddress) const override; + bool values(const RifEclipseSummaryAddress& resultAddress, std::vector* values) const override; + std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; void buildMetaData(); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimCsvUserData.h b/ApplicationCode/ProjectDataModel/Summary/RimCsvUserData.h index 06bde1d770..ab4dc57a3f 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimCsvUserData.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimCsvUserData.h @@ -37,13 +37,13 @@ class RimCsvUserData : public RimObservedData CAF_PDM_HEADER_INIT; public: RimCsvUserData(); - virtual ~RimCsvUserData(); + ~RimCsvUserData() override; - virtual void createSummaryReaderInterface() override; + void createSummaryReaderInterface() override; - virtual RifSummaryReaderInterface* summaryReader() override; + RifSummaryReaderInterface* summaryReader() override; - virtual QString errorMessagesFromReader() override; + QString errorMessagesFromReader() override; RicPasteAsciiDataToSummaryPlotFeatureUi* parseOptions() const; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCase.cpp new file mode 100644 index 0000000000..e4218405df --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCase.cpp @@ -0,0 +1,223 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimDerivedEnsembleCase.h" + +#include "RiaSummaryTools.h" +#include "RiaTimeHistoryCurveMerger.h" + +#include "RifDerivedEnsembleReader.h" + +#include "RimDerivedEnsembleCaseCollection.h" +#include "RimMainPlotCollection.h" +#include "RimOilField.h" +#include "RimProject.h" +#include "RimSummaryCaseMainCollection.h" +#include "RimSummaryPlotCollection.h" +#include "RimSummaryCaseCollection.h" + +#include "cvfAssert.h" + +#include + +CAF_PDM_ABSTRACT_SOURCE_INIT(RimDerivedEnsembleCase, "RimDerivedEnsembleCase"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector RimDerivedEnsembleCase::EMPTY_TIME_STEPS_VECTOR; +const std::vector RimDerivedEnsembleCase::EMPTY_VALUES_VECTOR; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimDerivedEnsembleCase::RimDerivedEnsembleCase() : m_summaryCase1(nullptr), m_summaryCase2(nullptr) +{ + CAF_PDM_InitObject("Summary Case",":/SummaryCase16x16.png","",""); + CAF_PDM_InitFieldNoDefault(&m_summaryCase1, "SummaryCase1", "SummaryCase1", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_summaryCase2, "SummaryCase2", "SummaryCase2", "", "", ""); + + m_inUse = false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimDerivedEnsembleCase::~RimDerivedEnsembleCase() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCase::setInUse(bool inUse) +{ + m_inUse = inUse; + + if (!m_inUse) + { + m_summaryCase1 = nullptr; + m_summaryCase2 = nullptr; + m_data.clear(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimDerivedEnsembleCase::isInUse() const +{ + return m_inUse; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCase::setSummaryCases(RimSummaryCase* sumCase1, RimSummaryCase* sumCase2) +{ + if (!sumCase1 || !sumCase2) return; + m_summaryCase1 = sumCase1; + m_summaryCase2 = sumCase2; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimDerivedEnsembleCase::needsCalculation(const RifEclipseSummaryAddress& address) const +{ + return m_data.count(address) == 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RimDerivedEnsembleCase::timeSteps(const RifEclipseSummaryAddress& address) const +{ + if (m_data.count(address) == 0) return EMPTY_TIME_STEPS_VECTOR; + return m_data.at(address).first; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RimDerivedEnsembleCase::values(const RifEclipseSummaryAddress& address) const +{ + if (m_data.count(address) == 0) return EMPTY_VALUES_VECTOR; + return m_data.at(address).second; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCase::calculate(const RifEclipseSummaryAddress& address) +{ + clearData(address); + + RifSummaryReaderInterface* reader1 = m_summaryCase1 ? m_summaryCase1->summaryReader() : nullptr; + RifSummaryReaderInterface* reader2 = m_summaryCase2 ? m_summaryCase2->summaryReader() : nullptr; + if (!reader1 || !reader2 || !parentEnsemble()) return; + + RiaTimeHistoryCurveMerger merger; + std::vector values1; + std::vector values2; + DerivedEnsembleOperator op = parentEnsemble()->op(); + + reader1->values(address, &values1); + reader2->values(address, &values2); + + merger.addCurveData(values1, reader1->timeSteps(address)); + merger.addCurveData(values2, reader2->timeSteps(address)); + merger.computeInterpolatedValues(); + + std::vector& allValues1 = merger.interpolatedCurveValuesForAllTimeSteps(0); + std::vector& allValues2 = merger.interpolatedCurveValuesForAllTimeSteps(1); + + size_t sampleCount = merger.allTimeSteps().size(); + std::vector calculatedValues; + calculatedValues.reserve(sampleCount); + for (size_t i = 0; i < sampleCount; i++) + { + if (op == DERIVED_ENSEMBLE_SUB) + { + calculatedValues.push_back(allValues1[i] - allValues2[i]); + } + else if (op == DERIVED_ENSEMBLE_ADD) + { + calculatedValues.push_back(allValues1[i] + allValues2[i]); + } + } + + auto& dataItem = m_data[address]; + dataItem.first = merger.allTimeSteps(); + dataItem.second = calculatedValues; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimDerivedEnsembleCase::caseName() const +{ + auto case1Name = m_summaryCase1->caseName(); + auto case2Name = m_summaryCase2->caseName(); + + if (case1Name == case2Name) return case1Name; + else return QString("%1/%2").arg(case1Name).arg(case2Name); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCase::createSummaryReaderInterface() +{ + m_reader.reset(new RifDerivedEnsembleReader(this)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifSummaryReaderInterface* RimDerivedEnsembleCase::summaryReader() +{ + return m_reader.get(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCase::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) +{ + // NOP +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimDerivedEnsembleCaseCollection * RimDerivedEnsembleCase::parentEnsemble() const +{ + RimDerivedEnsembleCaseCollection* ensemble; + firstAncestorOrThisOfType(ensemble); + return ensemble; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCase::clearData(const RifEclipseSummaryAddress& address) +{ + m_data.erase(address); +} diff --git a/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCase.h b/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCase.h new file mode 100644 index 0000000000..2383be278a --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCase.h @@ -0,0 +1,82 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include "RimSummaryCase.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +#include + +class RifEclipseSummaryAddress; +class RifSummaryReaderInterface; +class RifDerivedEnsembleReader; +class RimDerivedEnsembleCaseCollection; + +//================================================================================================== +/// +//================================================================================================== +enum DerivedEnsembleOperator +{ + DERIVED_ENSEMBLE_SUB, + DERIVED_ENSEMBLE_ADD +}; + +//================================================================================================== +// +//================================================================================================== + +class RimDerivedEnsembleCase : public RimSummaryCase +{ + CAF_PDM_HEADER_INIT; + + static const std::vector EMPTY_TIME_STEPS_VECTOR; + static const std::vector EMPTY_VALUES_VECTOR; + +public: + RimDerivedEnsembleCase(); + ~RimDerivedEnsembleCase() override; + + void setInUse(bool inUse); + bool isInUse() const; + void setSummaryCases(RimSummaryCase* sumCase1, RimSummaryCase* sumCase2); + bool needsCalculation(const RifEclipseSummaryAddress& address) const; + const std::vector& timeSteps(const RifEclipseSummaryAddress& address) const; + const std::vector& values(const RifEclipseSummaryAddress& address) const; + + void calculate(const RifEclipseSummaryAddress& address); + + QString caseName() const override; + void createSummaryReaderInterface() override; + RifSummaryReaderInterface* summaryReader() override; + void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; + + RimDerivedEnsembleCaseCollection* parentEnsemble() const; + +private: + void clearData(const RifEclipseSummaryAddress& address); + + std::unique_ptr m_reader; + + bool m_inUse; + caf::PdmPtrField m_summaryCase1; + caf::PdmPtrField m_summaryCase2; + std::map, std::vector>> m_data; +}; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCaseCollection.cpp b/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCaseCollection.cpp new file mode 100644 index 0000000000..805bd86ac4 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCaseCollection.cpp @@ -0,0 +1,462 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiaApplication.h" +#include "RiaTimeHistoryCurveMerger.h" + +#include "SummaryPlotCommands/RicNewDerivedEnsembleFeature.h" + +#include "RimDerivedEnsembleCaseCollection.h" +#include "RimDerivedEnsembleCase.h" +#include "RimProject.h" +#include "RimSummaryCaseCollection.h" +#include "RimSummaryCaseMainCollection.h" + +#include "RifSummaryReaderInterface.h" + +#include + +#include + +namespace caf +{ + template<> + void caf::AppEnum::setUp() + { + addItem(DERIVED_ENSEMBLE_SUB, "Sub", "-"); + addItem(DERIVED_ENSEMBLE_ADD, "Add", "+"); + setDefault(DERIVED_ENSEMBLE_SUB); + } +} + +CAF_PDM_SOURCE_INIT(RimDerivedEnsembleCaseCollection, "RimDerivedEnsembleCaseCollection"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimDerivedEnsembleCaseCollection::RimDerivedEnsembleCaseCollection() +{ + CAF_PDM_InitObject("Derived Ensemble", ":/SummaryEnsemble16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_ensemble1, "Ensemble1", "Ensemble 1", "", "", ""); + m_ensemble1.uiCapability()->setUiTreeChildrenHidden(true); + m_ensemble1.uiCapability()->setAutoAddingOptionFromValue(false); + + CAF_PDM_InitFieldNoDefault(&m_ensemble2, "Ensemble2", "Ensemble 2", "", "", ""); + m_ensemble1.uiCapability()->setUiTreeChildrenHidden(true); + m_ensemble2.uiCapability()->setAutoAddingOptionFromValue(false); + + CAF_PDM_InitFieldNoDefault(&m_operator, "Operator", "Operator", "", "", ""); + + CAF_PDM_InitField(&m_swapEnsemblesButton, "SwapEnsembles", false, "SwapEnsembles", "", "", ""); + m_swapEnsemblesButton.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + m_swapEnsemblesButton.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_swapEnsemblesButton.xmlCapability()->disableIO(); + + CAF_PDM_InitField(&m_caseCount, "CaseCount", QString(""), "Matching Cases", "", "", ""); + m_caseCount.uiCapability()->setUiReadOnly(true); + + // Do not show child cases + uiCapability()->setUiTreeChildrenHidden(true); + + // Do not store child cases to project file + m_cases.xmlCapability()->disableIO(); + + setNameAsReadOnly(); + setName("Derived Ensemble"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimDerivedEnsembleCaseCollection::~RimDerivedEnsembleCaseCollection() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCaseCollection::setEnsemble1(RimSummaryCaseCollection* ensemble) +{ + m_ensemble1 = ensemble; + updateAutoName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCaseCollection::setEnsemble2(RimSummaryCaseCollection* ensemble) +{ + m_ensemble2 = ensemble; + updateAutoName(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimDerivedEnsembleCaseCollection::allSummaryCases() const +{ + std::vector cases; + for (auto sumCase : allDerivedCases(true)) cases.push_back(sumCase); + return cases; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RimDerivedEnsembleCaseCollection::ensembleSummaryAddresses() const +{ + std::set addresses; + if (!m_ensemble1 || !m_ensemble2) return addresses; + + addresses = m_ensemble1->ensembleSummaryAddresses(); + auto addrs2 = m_ensemble2->ensembleSummaryAddresses(); + addresses.insert(addrs2.begin(), addrs2.end()); + return addresses; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCaseCollection::updateDerivedEnsembleCases() +{ + if (!m_ensemble1 || !m_ensemble2) return; + + setAllCasesNotInUse(); + + const auto cases1 = m_ensemble1->allSummaryCases(); + const auto cases2 = m_ensemble2->allSummaryCases(); + + for (auto& sumCase1 : cases1) + { + auto crp = sumCase1->caseRealizationParameters(); + if (!crp) continue; + + const auto& sumCase2 = findCaseByParametersHash(cases2, crp->parametersHash()); + if (!sumCase2) continue; + + auto derivedCase = firstCaseNotInUse(); + derivedCase->createSummaryReaderInterface(); + derivedCase->setSummaryCases(sumCase1, sumCase2); + derivedCase->setCaseRealizationParameters(crp); + derivedCase->setInUse(true); + } + + // If other derived ensembles are referring to this ensemble, update their cases as well + for (auto referring : findReferringEnsembles()) + { + referring->updateDerivedEnsembleCases(); + } + + deleteCasesNoInUse(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimDerivedEnsembleCaseCollection::hasCaseReference(const RimSummaryCase* sumCase) const +{ + for (auto currCase : m_ensemble1->allSummaryCases()) + { + if (currCase == sumCase) return true; + } + for (auto currCase : m_ensemble2->allSummaryCases()) + { + if (currCase == sumCase) return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCaseCollection::onLoadDataAndUpdate() +{ + updateDerivedEnsembleCases(); + updateReferringCurveSets(); + updateConnectedEditors(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimDerivedEnsembleCaseCollection::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList options; + + if (fieldNeedingOptions == &m_ensemble1 || fieldNeedingOptions == &m_ensemble2) + { + for (auto ensemble : allEnsembles()) + { + if(ensemble != this) options.push_back(caf::PdmOptionItemInfo(ensemble->name(), ensemble)); + } + } + else if (fieldNeedingOptions == &m_caseCount) + { + size_t caseCount1 = m_ensemble1 ? m_ensemble1->allSummaryCases().size() : 0; + size_t caseCount2 = m_ensemble2 ? m_ensemble2->allSummaryCases().size() : 0; + + m_caseCount = QString("%1 / %2").arg((int)m_cases.size()).arg(std::max(caseCount1, caseCount2)); + } + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCaseCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + RimSummaryCaseCollection::defineUiOrdering(uiConfigName, uiOrdering); + + uiOrdering.add(&m_caseCount); + uiOrdering.add(&m_ensemble1); + uiOrdering.add(&m_operator); + uiOrdering.add(&m_ensemble2); + uiOrdering.add(&m_swapEnsemblesButton); + + uiOrdering.skipRemainingFields(true); + + updateAutoName(); + if (!isValid()) m_caseCount = ""; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCaseCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + bool doUpdate = false; + bool doUpdateCases = false; + bool doShowDialog = false; + + if (changedField == &m_ensemble1 || changedField == &m_ensemble2) + { + doUpdate = true; + doUpdateCases = true; + doShowDialog = true; + } + else if (changedField == &m_operator) + { + doUpdate = true; + doUpdateCases = true; + doShowDialog = false; + } + else if (changedField == &m_swapEnsemblesButton) + { + m_swapEnsemblesButton = false; + auto temp = m_ensemble1(); + m_ensemble1 = m_ensemble2(); + m_ensemble2 = temp; + + doUpdate = true; + doUpdateCases = true; + doShowDialog = false; + } + + if (doUpdate) + { + updateAutoName(); + + if (doUpdateCases) + { + updateDerivedEnsembleCases(); + updateConnectedEditors(); + + if (doShowDialog && m_ensemble1 != nullptr && m_ensemble2 != nullptr && allSummaryCases().empty()) + { + RicNewDerivedEnsembleFeature::showWarningDialog(); + } + } + + updateReferringCurveSets(); + + // If other derived ensembles are referring to this ensemble, update their cases as well + for (auto refering : findReferringEnsembles()) + { + refering->updateReferringCurveSets(); + } + + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCaseCollection::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_swapEnsemblesButton) + { + caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast(attribute); + if (attrib) + { + attrib->m_buttonText = "Swap Ensembles"; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCaseCollection::setAllCasesNotInUse() +{ + for (auto derCase : allDerivedCases(true)) derCase->setInUse(false); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCaseCollection::deleteCasesNoInUse() +{ + std::vector inactiveCases; + auto allCases = allDerivedCases(false); + std::copy_if(allCases.begin(), allCases.end(), std::back_inserter(inactiveCases), [](RimDerivedEnsembleCase* derCase) { return !derCase->isInUse(); }); + + for (auto derCase : inactiveCases) + { + removeCase(derCase); + delete derCase; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimDerivedEnsembleCase* RimDerivedEnsembleCaseCollection::firstCaseNotInUse() +{ + auto allCases = allDerivedCases(false); + auto itr = std::find_if(allCases.begin(), allCases.end(), [](RimDerivedEnsembleCase* derCase) { return !derCase->isInUse(); }); + if (itr != allCases.end()) + { + return *itr; + } + + // If no active case was found, add a new case to the collection + auto newCase = new RimDerivedEnsembleCase(); + m_cases.push_back(newCase); + return newCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimDerivedEnsembleCaseCollection::allDerivedCases(bool activeOnly) const +{ + std::vector activeCases; + for (auto sumCase : RimSummaryCaseCollection::allSummaryCases()) + { + auto derivedCase = dynamic_cast(sumCase); + if (derivedCase && (!activeOnly || derivedCase->isInUse())) + { + activeCases.push_back(derivedCase); + } + } + return activeCases; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimDerivedEnsembleCaseCollection::updateAutoName() +{ + QString op = caf::AppEnum::uiText(m_operator()); + + auto derivedEnsemble1 = dynamic_cast(m_ensemble1()); + auto derivedEnsemble2 = dynamic_cast(m_ensemble2()); + bool isDerived1 = derivedEnsemble1 != nullptr; + bool isDerived2 = derivedEnsemble2 != nullptr; + + QString name = + (isDerived1 ? "(" : "") + + (m_ensemble1 ? m_ensemble1->name() : "") + + (isDerived1 ? ")" : "") + + " " + op + " " + + (isDerived2 ? "(" : "") + + (m_ensemble2 ? m_ensemble2->name() : "") + + (isDerived2 ? ")" : ""); + setName(name); + + // If other derived ensembles are referring to this ensemble, update theirs name as well + for (auto refering : findReferringEnsembles()) + { + refering->updateAutoName(); + refering->updateConnectedEditors(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimSummaryCase* RimDerivedEnsembleCaseCollection::findCaseByParametersHash(const std::vector& cases, size_t hash) const +{ + for (auto sumCase : cases) + { + auto ensembleParameters = sumCase->caseRealizationParameters(); + if (ensembleParameters && ensembleParameters->parametersHash() == hash) return sumCase; + } + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimDerivedEnsembleCaseCollection::findReferringEnsembles() const +{ + std::vector referringEnsembles; + RimSummaryCaseMainCollection* mainColl; + + firstAncestorOrThisOfType(mainColl); + if (mainColl) + { + for (auto group : mainColl->summaryCaseCollections()) + { + auto derivedEnsemble = dynamic_cast(group); + if (derivedEnsemble) + { + if (derivedEnsemble->m_ensemble1() == this || derivedEnsemble->m_ensemble2() == this) + { + referringEnsembles.push_back(derivedEnsemble); + } + } + } + } + return referringEnsembles; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimDerivedEnsembleCaseCollection::allEnsembles() const +{ + std::vector ensembles; + + auto project = RiaApplication::instance()->project(); + + for (auto group : project->summaryGroups()) + { + if (group == this) continue; + + if (!group->isEnsemble()) continue; + + auto derivedEnsemble = dynamic_cast(group); + if (derivedEnsemble && !derivedEnsemble->isValid()) continue; + + ensembles.push_back(group); + } + return ensembles; +} diff --git a/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCaseCollection.h b/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCaseCollection.h new file mode 100644 index 0000000000..f8724cb3f3 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimDerivedEnsembleCaseCollection.h @@ -0,0 +1,86 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2016- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RifEclipseSummaryAddress.h" + +#include "RimDerivedEnsembleCase.h" +#include "RimSummaryCaseCollection.h" + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmPtrField.h" +#include "cafPdmObject.h" +#include "cafPdmProxyValueField.h" + +#include + +class RimSummaryCase; + +//================================================================================================== +/// +//================================================================================================== +class RimDerivedEnsembleCaseCollection : public RimSummaryCaseCollection +{ + CAF_PDM_HEADER_INIT; + +public: + RimDerivedEnsembleCaseCollection(); + ~RimDerivedEnsembleCaseCollection() override; + + RimSummaryCaseCollection* ensemble1() const { return m_ensemble1; } + RimSummaryCaseCollection* ensemble2() const { return m_ensemble2; } + DerivedEnsembleOperator op() const { return m_operator(); } + bool isValid() const { return m_ensemble1 != nullptr && m_ensemble2 != nullptr; } + + void setEnsemble1(RimSummaryCaseCollection* ensemble); + void setEnsemble2(RimSummaryCaseCollection* ensemble); + + std::vector allSummaryCases() const override; + std::set ensembleSummaryAddresses() const override; + void updateDerivedEnsembleCases(); + bool hasCaseReference(const RimSummaryCase* sumCase) const; + + void onLoadDataAndUpdate() override; + +private: + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; + + void setAllCasesNotInUse(); + void deleteCasesNoInUse(); + RimDerivedEnsembleCase* firstCaseNotInUse(); + std::vector allDerivedCases(bool activeOnly) const; + void updateAutoName(); + RimSummaryCase* findCaseByParametersHash(const std::vector& cases, size_t hash) const; + std::vector findReferringEnsembles() const; + +private: + std::vector allEnsembles() const; + +private: + caf::PdmPtrField m_ensemble1; + caf::PdmPtrField m_ensemble2; + caf::PdmField> m_operator; + caf::PdmField m_swapEnsemblesButton; + caf::PdmField m_caseCount; +}; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilter.cpp b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilter.cpp new file mode 100644 index 0000000000..2f6485734c --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilter.cpp @@ -0,0 +1,381 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimEnsembleCurveFilter.h" +#include "RimEnsembleCurveFilterCollection.h" +#include "RimEnsembleCurveSet.h" +#include "RimSummaryCase.h" + +#include "cafPdmUiDoubleSliderEditor.h" +#include "cafPdmUiPushButtonEditor.h" + +#include + + +CAF_PDM_SOURCE_INIT(RimEnsembleCurveFilter, "RimEnsembleCurveFilter"); + + +//-------------------------------------------------------------------------------------------------- +/// Internal constants +//-------------------------------------------------------------------------------------------------- +#define DOUBLE_INF std::numeric_limits::infinity() + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEnsembleCurveFilter::RimEnsembleCurveFilter() : m_lowerLimit(DOUBLE_INF), m_upperLimit(DOUBLE_INF) +{ + CAF_PDM_InitObject("Ensemble Curve Filter", ":/EnsembleCurveSet16x16.png", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_active, "Active", "Active", "", "", ""); + m_active = true; + + CAF_PDM_InitFieldNoDefault(&m_ensembleParameterName, "EnsembleParameter", "Ensemble Parameter", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_minValue, "MinValue", "Min", "", "", ""); + m_minValue.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); + + CAF_PDM_InitFieldNoDefault(&m_maxValue, "MaxValue", "Max", "", "", ""); + m_maxValue.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName()); + + CAF_PDM_InitFieldNoDefault(&m_categories, "Categories", "Categories", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_deleteButton, "DeleteEnsembleFilter", "Delete Filter", "", "", ""); + m_deleteButton = false; + m_deleteButton.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + m_deleteButton.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEnsembleCurveFilter::RimEnsembleCurveFilter(const QString& ensembleParameterName) : RimEnsembleCurveFilter() +{ + m_ensembleParameterName = ensembleParameterName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEnsembleCurveFilter::isActive() const +{ + RimEnsembleCurveFilterCollection* coll; + firstAncestorOrThisOfType(coll); + + return (!coll || coll->isActive()) && m_active; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimEnsembleCurveFilter::minValue() const +{ + return m_minValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RimEnsembleCurveFilter::maxValue() const +{ + return m_maxValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RimEnsembleCurveFilter::categories() const +{ + const auto cs = m_categories(); + return std::set(cs.begin(), cs.end()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEnsembleCurveFilter::ensembleParameterName() const +{ + return m_ensembleParameterName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEnsembleCurveFilter::filterId() const +{ + return QString("%1").arg((int64_t)this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimEnsembleCurveFilter::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList options; + + if (fieldNeedingOptions == &m_ensembleParameterName) + { + auto curveSet = parentCurveSet(); + if (curveSet) + { + auto names = curveSet->ensembleParameterNames(); + for (auto& name : names) + { + options.push_back(caf::PdmOptionItemInfo(name, name)); + } + } + } + else if (fieldNeedingOptions == &m_categories) + { + auto curveSet = parentCurveSet(); + auto ensemble = curveSet ? curveSet->summaryCaseCollection() : nullptr; + auto eParam = ensemble ? ensemble->ensembleParameter(m_ensembleParameterName) : EnsembleParameter(); + + if (eParam.isText()) + { + for (const auto& val : eParam.values) + { + options.push_back(caf::PdmOptionItemInfo(val.toString(), val.toString())); + } + } + } + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + auto curveSet = parentCurveSet(); + + if (changedField == &m_ensembleParameterName) + { + auto eParam = selectedEnsembleParameter(); + if (eParam.isNumeric()) + { + setInitialValues(true); + } + else if (eParam.isText()) + { + m_categories.v().clear(); + for (const auto& val : eParam.values) + { + m_categories.v().push_back(val.toString()); + } + } + curveSet->updateAllCurves(); + + auto collection = parentCurveFilterCollection(); + if (collection) collection->updateConnectedEditors(); + } + else if (changedField == &m_active || + changedField == &m_minValue || + changedField == &m_maxValue || + changedField == &m_categories) + { + if (curveSet) + { + curveSet->updateAllCurves(); + curveSet->filterCollection()->updateConnectedEditors(); + } + } + else if (changedField == &m_deleteButton) + { + m_deleteButton = false; + + if (!curveSet) return; + + curveSet->filterCollection()->removeFilter(this); + curveSet->filterCollection()->updateConnectedEditors(); + curveSet->updateAllCurves(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + setInitialValues(false); + + auto eParam = selectedEnsembleParameter(); + + uiOrdering.add(&m_active); + uiOrdering.add(&m_ensembleParameterName); + + if (eParam.isNumeric()) + { + uiOrdering.add(&m_minValue); + uiOrdering.add(&m_maxValue); + } + else if(eParam.isText()) + { + uiOrdering.add(&m_categories); + } + uiOrdering.add(&m_deleteButton); + + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilter::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_minValue || field == &m_maxValue) + { + caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast(attribute); + if (!myAttr) + { + return; + } + + myAttr->m_minimum = m_lowerLimit; + myAttr->m_maximum = m_upperLimit; + } + else if (field == &m_deleteButton) + { + caf::PdmUiPushButtonEditorAttribute* attr = dynamic_cast(attribute); + if (!attr) return; + + attr->m_buttonText = "Delete"; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimEnsembleCurveFilter::applyFilter(const std::vector& allSumCases) +{ + auto curveSet = parentCurveSet(); + auto ensemble = curveSet ? curveSet->summaryCaseCollection() : nullptr; + if (!ensemble || !isActive()) return allSumCases; + + std::set casesToRemove; + for (const auto& sumCase : allSumCases) + { + auto eParam = ensemble->ensembleParameter(m_ensembleParameterName()); + if (!eParam.isValid()) continue; + if (!sumCase->caseRealizationParameters()) continue; + + auto crpValue = sumCase->caseRealizationParameters()->parameterValue(m_ensembleParameterName()); + + if (eParam.isNumeric()) + { + if (!crpValue.isNumeric() || + crpValue.numericValue() < m_minValue() || + crpValue.numericValue() > m_maxValue()) + { + casesToRemove.insert(sumCase); + } + } + else if (eParam.isText()) + { + const auto& filterCategories = categories(); + if (!crpValue.isText() || + std::count(filterCategories.begin(), filterCategories.end(), crpValue.textValue()) == 0) + { + casesToRemove.insert(sumCase); + } + } + } + + std::vector filteredCases; + std::set allCasesSet(allSumCases.begin(), allSumCases.end()); + std::set_difference(allCasesSet.begin(), allCasesSet.end(), + casesToRemove.begin(), casesToRemove.end(), + std::inserter(filteredCases, filteredCases.end())); + return filteredCases; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilter::loadDataAndUpdate() +{ + setInitialValues(false); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimEnsembleCurveFilter::objectToggleField() +{ + return &m_active; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEnsembleCurveSet * RimEnsembleCurveFilter::parentCurveSet() const +{ + RimEnsembleCurveSet* curveSet; + firstAncestorOrThisOfType(curveSet); + return curveSet; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEnsembleCurveFilterCollection* RimEnsembleCurveFilter::parentCurveFilterCollection() const +{ + RimEnsembleCurveFilterCollection* coll; + firstAncestorOrThisOfType(coll); + return coll; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilter::setInitialValues(bool forceDefault) +{ + if (!selectedEnsembleParameter().isValid()) + { + auto parameterNames = parentCurveSet()->ensembleParameterNames(); + if (!parameterNames.empty()) + { + m_ensembleParameterName = parameterNames.front(); + updateConnectedEditors(); + } + } + + auto eParam = selectedEnsembleParameter(); + if (eParam.isValid() && eParam.isNumeric()) + { + m_lowerLimit = eParam.minValue; + m_upperLimit = eParam.maxValue; + + if (forceDefault || !(m_minValue >= m_lowerLimit && m_minValue <= m_upperLimit)) m_minValue = m_lowerLimit; + if (forceDefault || !(m_maxValue >= m_lowerLimit && m_maxValue <= m_upperLimit)) m_maxValue = m_upperLimit; + + m_minValue.uiCapability()->setUiName(QString("Min (%1)").arg(m_lowerLimit)); + m_maxValue.uiCapability()->setUiName(QString("Max (%1)").arg(m_upperLimit)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +EnsembleParameter RimEnsembleCurveFilter::selectedEnsembleParameter() const +{ + auto curveSet = parentCurveSet(); + auto ensemble = curveSet ? curveSet->summaryCaseCollection() : nullptr; + return ensemble ? ensemble->ensembleParameter(m_ensembleParameterName) : EnsembleParameter(); +} diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilter.h b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilter.h new file mode 100644 index 0000000000..e583cde802 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilter.h @@ -0,0 +1,78 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "cafPdmField.h" +#include "cafPdmObject.h" + +class EnsembleParameter; +class RimEnsembleCurveSet; +class RimSummaryCase; +class RimSummaryPlot; +class RimEnsembleCurveFilterCollection; + +//================================================================================================== +/// +//================================================================================================== +class RimEnsembleCurveFilter : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimEnsembleCurveFilter(); + RimEnsembleCurveFilter(const QString& ensembleParameterName); + + bool isActive() const; + double minValue() const; + double maxValue() const; + std::set categories() const; + QString ensembleParameterName() const; + QString filterId() const; + + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + + std::vector applyFilter(const std::vector& allSumCases); + + void loadDataAndUpdate(); + EnsembleParameter selectedEnsembleParameter() const; + +protected: + caf::PdmFieldHandle* objectToggleField() override; + +private: + RimEnsembleCurveSet * parentCurveSet() const; + RimEnsembleCurveFilterCollection* parentCurveFilterCollection() const; + void setInitialValues(bool forceDefault); + +private: + caf::PdmField m_active; + caf::PdmField m_deleteButton; + caf::PdmField m_ensembleParameterName; + caf::PdmField m_minValue; + caf::PdmField m_maxValue; + caf::PdmField> m_categories; + + double m_lowerLimit; + double m_upperLimit; +}; + diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilterCollection.cpp b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilterCollection.cpp new file mode 100644 index 0000000000..baac562a4e --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilterCollection.cpp @@ -0,0 +1,247 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimEnsembleCurveFilterCollection.h" + +#include "RiaApplication.h" + +#include "RimEnsembleCurveFilter.h" +#include "RimEnsembleCurveSet.h" + +#include +#include +#include + +#include + + +CAF_PDM_SOURCE_INIT(RimEnsembleCurveFilterCollection, "RimEnsembleCurveFilterCollection"); + +//-------------------------------------------------------------------------------------------------- +/// Internal variables +//-------------------------------------------------------------------------------------------------- +static std::vector _removedFilters; + +static void garbageCollectFilters(); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEnsembleCurveFilterCollection::RimEnsembleCurveFilterCollection() +{ + CAF_PDM_InitObject("Curve Filters", ":/SummaryCurveFilter16x16.png", "", ""); + + CAF_PDM_InitField(&m_active, "Active", true, "Active", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_filters, "CurveFilters", "", "", "", ""); + m_filters.uiCapability()->setUiTreeChildrenHidden(true); + //m_filters.uiCapability()->setUiEditorTypeName(caf::PdmUiTableViewEditor::uiEditorTypeName()); + m_filters.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + CAF_PDM_InitFieldNoDefault(&m_newFilterButton, "NewEnsembleFilter", "New Filter", "", "", ""); + m_newFilterButton = false; + m_newFilterButton.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); + m_newFilterButton.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEnsembleCurveFilter* RimEnsembleCurveFilterCollection::addFilter(const QString& ensembleParameterName) +{ + garbageCollectFilters(); + + auto newFilter = new RimEnsembleCurveFilter(ensembleParameterName); + m_filters.push_back(newFilter); + return newFilter; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilterCollection::removeFilter(RimEnsembleCurveFilter* filter) +{ + garbageCollectFilters(); + + size_t sizeBefore = m_filters.size(); + m_filters.removeChildObject(filter); + size_t sizeAfter = m_filters.size(); + + if(sizeAfter < sizeBefore) _removedFilters.push_back(filter); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimEnsembleCurveFilterCollection::filters() const +{ + return m_filters.childObjects(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEnsembleCurveFilterCollection::isActive() const +{ + return m_active; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimEnsembleCurveFilterCollection::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) +{ + QList options; + + return options; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + RimEnsembleCurveSet* curveSet; + firstAncestorOrThisOfType(curveSet); + if (!curveSet) return; + + if (changedField == &m_active) + { + curveSet->updateAllCurves(); + } + else if (changedField == &m_newFilterButton) + { + m_newFilterButton = false; + + addFilter(); + updateConnectedEditors(); + curveSet->updateAllCurves(); + + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilterCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + uiOrdering.add(&m_newFilterButton); + + for (auto& filter : m_filters) + { + QString groupTitle; + auto selEnsembleParam = filter->selectedEnsembleParameter(); + if (selEnsembleParam.isNumeric()) + { + groupTitle = filter->ensembleParameterName(); + + if (!filter->isActive()) + { + groupTitle += " - [Disabled]"; + } + else + { + groupTitle += QString(" [%2 .. %3]") + .arg(QString::number(filter->minValue())) + .arg(QString::number(filter->maxValue())); + } + } + else if (selEnsembleParam.isText()) + { + groupTitle = filter->ensembleParameterName(); + + if (!filter->isActive()) + { + groupTitle += " - [Disabled]"; + } + else + { + groupTitle += " { "; + + bool first = true; + for (auto cat : filter->categories()) + { + if (!first) groupTitle += ", "; + groupTitle += cat; + first = false; + } + groupTitle += " }"; + + if (groupTitle.size() > 45) + { + groupTitle = groupTitle.left(40) + "... }"; + } + } + } + + caf::PdmUiGroup* filterGroup = uiOrdering.addNewGroupWithKeyword(groupTitle, QString("EnsembleFilter_") + filter->filterId()); + filter->defineUiOrdering(uiConfigName, *filterGroup); + } + + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilterCollection::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /* = "" */) +{ + uiTreeOrdering.skipRemainingChildren(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilterCollection::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_newFilterButton) + { + caf::PdmUiPushButtonEditorAttribute* attr = dynamic_cast(attribute); + if (!attr) return; + + attr->m_buttonText = "Add Ensemble Curve Filter"; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveFilterCollection::loadDataAndUpdate() +{ + for (auto& filter : m_filters) filter->loadDataAndUpdate(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimEnsembleCurveFilterCollection::objectToggleField() +{ + return &m_active; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void garbageCollectFilters() +{ + for (auto filter : _removedFilters) + { + delete filter; + } + _removedFilters.clear(); +} diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilterCollection.h b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilterCollection.h new file mode 100644 index 0000000000..abc85dc9cc --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveFilterCollection.h @@ -0,0 +1,59 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "cafPdmChildArrayField.h" +#include "cafPdmField.h" +#include "cafPdmObject.h" + + +class RimEnsembleCurveFilter; + +//================================================================================================== +/// +//================================================================================================== +class RimEnsembleCurveFilterCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimEnsembleCurveFilterCollection(); + + RimEnsembleCurveFilter* addFilter(const QString& ensembleParameterName = ""); + void removeFilter(RimEnsembleCurveFilter* filter); + std::vector filters() const; + + bool isActive() const; + void loadDataAndUpdate(); + +private: + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /* = "" */) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + + caf::PdmFieldHandle* objectToggleField() override; + +private: + caf::PdmField m_active; + caf::PdmChildArrayField m_filters; + caf::PdmField m_newFilterButton; +}; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp index dd352de616..4cb05f2da7 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp @@ -20,11 +20,23 @@ #include "RiaApplication.h" #include "RiaColorTables.h" +#include "RiaStatisticsTools.h" +#include "SummaryPlotCommands/RicSummaryCurveCreator.h" + +#include "RifEnsembleStatisticsReader.h" #include "RifReaderEclipseSummary.h" +#include "RigStatisticsMath.h" +#include "RiaTimeHistoryCurveMerger.h" + +#include "RimDerivedEnsembleCaseCollection.h" +#include "RimEnsembleCurveFilter.h" +#include "RimEnsembleCurveFilterCollection.h" #include "RimEnsembleCurveSetCollection.h" #include "RimEnsembleCurveSetColorManager.h" +#include "RimEnsembleStatistics.h" +#include "RimEnsembleStatisticsCase.h" #include "RimProject.h" #include "RimRegularLegendConfig.h" #include "RimSummaryAddress.h" @@ -35,6 +47,7 @@ #include "RimSummaryFilter.h" #include "RimSummaryPlot.h" +#include "RiuQwtPlotCurve.h" #include "RiuPlotMainWindow.h" #include "RiuSummaryQwtPlot.h" #include "RiuSummaryCurveDefSelectionDialog.h" @@ -49,12 +62,19 @@ #include "qwt_plot_curve.h" #include "qwt_symbol.h" +#include //-------------------------------------------------------------------------------------------------- /// Internal constants //-------------------------------------------------------------------------------------------------- #define DOUBLE_INF std::numeric_limits::infinity() +//-------------------------------------------------------------------------------------------------- +/// Internal functions +//-------------------------------------------------------------------------------------------------- +RiuQwtSymbol::PointSymbolEnum statisticsCurveSymbolFromAddress(const RifEclipseSummaryAddress& address); +int statisticsCurveSymbolSize(RiuQwtSymbol::PointSymbolEnum symbol); + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -129,6 +149,13 @@ RimEnsembleCurveSet::RimEnsembleCurveSet() m_legendConfig = new RimRegularLegendConfig(); m_legendConfig->setColorRange( RimEnsembleCurveSetColorManager::DEFAULT_ENSEMBLE_COLOR_RANGE ); + CAF_PDM_InitFieldNoDefault(&m_curveFilters, "CurveFilters", "Curve Filters", "", "", ""); + m_curveFilters = new RimEnsembleCurveFilterCollection(); + + CAF_PDM_InitFieldNoDefault(&m_statistics, "Statistics", "Statistics", "", "", ""); + m_statistics = new RimEnsembleStatistics(); + m_statistics.uiCapability()->setUiTreeHidden(true); + CAF_PDM_InitField(&m_userDefinedName, "UserDefinedName", QString("Ensemble Curve Set"), "Curve Set Name", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_autoGeneratedName, "AutoGeneratedName", "Curve Set Name", "", "", ""); @@ -145,6 +172,12 @@ RimEnsembleCurveSet::RimEnsembleCurveSet() m_qwtPlotCurveForLegendText = new QwtPlotCurve; m_qwtPlotCurveForLegendText->setLegendAttribute(QwtPlotCurve::LegendShowSymbol, true); + + m_ensembleStatCase.reset(new RimEnsembleStatisticsCase(this)); + m_ensembleStatCase->createSummaryReaderInterface(); + + m_disableStatisticCurves = false; + m_isCurveSetFiltered = false; } //-------------------------------------------------------------------------------------------------- @@ -192,6 +225,15 @@ void RimEnsembleCurveSet::loadDataAndUpdate(bool updateParentPlot) m_yValuesUiFilterResultSelection = m_yValuesCurveVariable->address(); updateAllCurves(); + + if (updateParentPlot) + { + RimSummaryPlot* parentPlot; + firstAncestorOrThisOfTypeAsserted(parentPlot); + parentPlot->updateAll(); + } + + m_curveFilters->loadDataAndUpdate(); } //-------------------------------------------------------------------------------------------------- @@ -203,8 +245,6 @@ void RimEnsembleCurveSet::setParentQwtPlotNoReplot(QwtPlot* plot) { curve->setParentQwtPlotNoReplot(plot); } - - m_qwtPlotCurveForLegendText->attach(plot); } //-------------------------------------------------------------------------------------------------- @@ -220,6 +260,26 @@ void RimEnsembleCurveSet::detachQwtCurves() m_qwtPlotCurveForLegendText->detach(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveSet::reattachQwtCurves() +{ + for (RimSummaryCurve* curve : m_curves) + { + curve->reattachQwtCurve(); + } + + m_qwtPlotCurveForLegendText->detach(); + + RimSummaryPlot* plot = nullptr; + firstAncestorOrThisOfType(plot); + if (plot) + { + m_qwtPlotCurveForLegendText->attach(plot->qwtPlot()); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -244,6 +304,7 @@ void RimEnsembleCurveSet::deleteCurve(RimSummaryCurve* curve) if (curve) { m_curves.removeChildObject(curve); + curve->markCachedDataForPurge(); delete curve; } } @@ -275,9 +336,45 @@ std::vector RimEnsembleCurveSet::curves() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEnsembleCurveSet::deleteAllCurves() +void RimEnsembleCurveSet::deleteEnsembleCurves() { - m_curves.deleteAllChildObjects(); + std::vector curvesIndexesToDelete; + for (size_t c = 0; c < m_curves.size(); c++) + { + RimSummaryCurve* curve = m_curves[c]; + if (curve->summaryAddressY().category() != RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) + curvesIndexesToDelete.push_back(c); + } + + while (curvesIndexesToDelete.size() > 0) + { + size_t currIndex = curvesIndexesToDelete.back(); + delete m_curves[currIndex]; + m_curves.erase(currIndex); + curvesIndexesToDelete.pop_back(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveSet::deleteStatisticsCurves() +{ + std::vector curvesIndexesToDelete; + for (size_t c = 0; c < m_curves.size(); c++) + { + RimSummaryCurve* curve = m_curves[c]; + if (curve->summaryAddressY().category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) + curvesIndexesToDelete.push_back(c); + } + + while (curvesIndexesToDelete.size() > 0) + { + size_t currIndex = curvesIndexesToDelete.back(); + delete m_curves[currIndex]; + m_curves.erase(currIndex); + curvesIndexesToDelete.pop_back(); + } } //-------------------------------------------------------------------------------------------------- @@ -312,6 +409,14 @@ RimSummaryCaseCollection* RimEnsembleCurveSet::summaryCaseCollection() const return m_yValuesSummaryGroup(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEnsembleCurveFilterCollection* RimEnsembleCurveSet::filterCollection() const +{ + return m_curveFilters; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -323,22 +428,40 @@ RimEnsembleCurveSet::ColorMode RimEnsembleCurveSet::colorMode() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimEnsembleCurveSet::EnsembleParameterType RimEnsembleCurveSet::currentEnsembleParameterType() const +EnsembleParameter::Type RimEnsembleCurveSet::currentEnsembleParameterType() const { if (m_colorMode() == BY_ENSEMBLE_PARAM) { RimSummaryCaseCollection* group = m_yValuesSummaryGroup(); QString parameterName = m_ensembleParameter(); - if (group && !parameterName.isEmpty() && !group->allSummaryCases().empty()) + if (group && !parameterName.isEmpty()) { - bool isTextParameter = group->allSummaryCases().front()->caseRealizationParameters() != nullptr ? - group->allSummaryCases().front()->caseRealizationParameters()->parameterValue(parameterName).isText() : false; - - return isTextParameter ? TYPE_TEXT : TYPE_NUMERIC; + auto eParam = group->ensembleParameter(parameterName); + return eParam.type; } } - return TYPE_NONE; + return EnsembleParameter::TYPE_NONE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveSet::updateAllCurves() +{ + RimSummaryCaseCollection* group = m_yValuesSummaryGroup(); + RimSummaryAddress* addr = m_yValuesCurveVariable(); + + if (group && addr->address().category() != RifEclipseSummaryAddress::SUMMARY_INVALID) + { + std::vector allCases = group->allSummaryCases(); + std::vector filteredCases = filterEnsembleCases(allCases); + + m_isCurveSetFiltered = filteredCases.size() < allCases.size(); + + updateEnsembleCurves(filteredCases); + updateStatisticsCurves(m_statistics->basedOnFilteredCases() ? filteredCases : allCases); + } } //-------------------------------------------------------------------------------------------------- @@ -375,9 +498,9 @@ void RimEnsembleCurveSet::fieldChangedByUi(const caf::PdmFieldHandle* changedFie else if (changedField == &m_yValuesSummaryGroup) { // Empty address cache - m_allAddressesCache.clear(); + //m_allAddressesCache.clear(); updateAllCurves(); - + updateTextInPlot = true; } else if (changedField == &m_color) @@ -395,7 +518,7 @@ void RimEnsembleCurveSet::fieldChangedByUi(const caf::PdmFieldHandle* changedFie { if (m_ensembleParameter().isEmpty()) { - auto params = ensembleParameters(); + auto params = ensembleParameterNames(); m_ensembleParameter = !params.empty() ? params.front() : ""; } updateCurveColors(); @@ -471,14 +594,16 @@ void RimEnsembleCurveSet::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder { { QString curveDataGroupName = "Summary Vector"; - caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroupWithKeyword(curveDataGroupName, "Summary Vector Y"); + //caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroupWithKeyword(curveDataGroupName, "Summary Vector Y"); + caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup("Summary Vector Y"); curveDataGroup->add(&m_yValuesSummaryGroup); curveDataGroup->add(&m_yValuesSelectedVariableDisplayField); curveDataGroup->add(&m_plotAxis); curveDataGroup->add(&m_yPushButtonSelectSummaryAddress); QString curveVarSelectionGroupName = "Vector Selection Filter Y"; - caf::PdmUiGroup* curveVarSelectionGroup = curveDataGroup->addNewGroupWithKeyword("Vector Selection Filter", curveVarSelectionGroupName); + //caf::PdmUiGroup* curveVarSelectionGroup = curveDataGroup->addNewGroupWithKeyword("Vector Selection Filter", curveVarSelectionGroupName); + caf::PdmUiGroup* curveVarSelectionGroup = curveDataGroup->addNewGroup(curveVarSelectionGroupName); curveVarSelectionGroup->setCollapsedByDefault(true); m_yValuesSummaryFilter->uiOrdering(uiConfigName, *curveVarSelectionGroup); curveVarSelectionGroup->add(&m_yValuesUiFilterResultSelection); @@ -513,6 +638,9 @@ void RimEnsembleCurveSet::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder } } + caf::PdmUiGroup* statGroup = uiOrdering.addNewGroup("Statistics"); + m_statistics->defineUiOrdering(uiConfigName, *statGroup); + uiOrdering.skipRemainingFields(true); } @@ -525,6 +653,12 @@ void RimEnsembleCurveSet::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrd { uiTreeOrdering.add(m_legendConfig()); } + + if (uiConfigName != RicSummaryCurveCreator::CONFIGURATION_NAME) + { + uiTreeOrdering.add(m_curveFilters); + } + uiTreeOrdering.skipRemainingChildren(true); } @@ -588,14 +722,14 @@ QList RimEnsembleCurveSet::calculateValueOptions(const c auto byEnsParamOption = caf::AppEnum(RimEnsembleCurveSet::BY_ENSEMBLE_PARAM); options.push_back(caf::PdmOptionItemInfo(singleColorOption.uiText(), RimEnsembleCurveSet::SINGLE_COLOR)); - if (!ensembleParameters().empty()) + if (!ensembleParameterNames().empty()) { options.push_back(caf::PdmOptionItemInfo(byEnsParamOption.uiText(), RimEnsembleCurveSet::BY_ENSEMBLE_PARAM)); } } else if (fieldNeedingOptions == &m_ensembleParameter) { - for (const auto& param : ensembleParameters()) + for (const auto& param : ensembleParameterNames()) { options.push_back(caf::PdmOptionItemInfo(param, param)); } @@ -608,30 +742,6 @@ QList RimEnsembleCurveSet::calculateValueOptions(const c return options; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimEnsembleCurveSet::getOptionsForSummaryAddresses(std::map* options, - RimSummaryCase* summaryCase, - RimSummaryFilter* summaryFilter) -{ - if (summaryCase) - { - RifSummaryReaderInterface* reader = summaryCase->summaryReader(); - if (reader) - { - for (const auto& address : reader->allResultAddresses()) - { - if (summaryFilter && !summaryFilter->isIncludedByFilter(address)) continue; - - std::string name = address.uiText(); - QString s = QString::fromStdString(name); - options->insert(std::make_pair(s, address)); - } - } - } -} - //-------------------------------------------------------------------------------------------------- /// Optimization candidate //-------------------------------------------------------------------------------------------------- @@ -641,23 +751,24 @@ void RimEnsembleCurveSet::appendOptionItemsForSummaryAddresses(QList addrSet; + for (RimSummaryCase* summaryCase : summaryCaseGroup->allSummaryCases()) { - for (RimSummaryCase* summaryCase : summaryCaseGroup->allSummaryCases()) + RifSummaryReaderInterface* reader = summaryCase->summaryReader(); + const std::set& addrs = reader ? reader->allResultAddresses() : std::set(); + + for (auto& addr : addrs) { - RifSummaryReaderInterface* reader = summaryCase->summaryReader(); - const std::vector addrs = reader ? reader->allResultAddresses() : std::vector(); - m_allAddressesCache.insert(addrs.begin(), addrs.end()); + if (summaryFilter && !summaryFilter->isIncludedByFilter(addr)) continue; + addrSet.insert(addr); } } - for (auto& address : m_allAddressesCache) + for (auto& addr : addrSet) { - if (summaryFilter && !summaryFilter->isIncludedByFilter(address)) continue; - - std::string name = address.uiText(); + std::string name = addr.uiText(); QString s = QString::fromStdString(name); - options->push_back(caf::PdmOptionItemInfo(s, QVariant::fromValue(address))); + options->push_back(caf::PdmOptionItemInfo(s, QVariant::fromValue(addr))); } options->push_front(caf::PdmOptionItemInfo(RiaDefines::undefinedResultName(), QVariant::fromValue(RifEclipseSummaryAddress()))); @@ -693,23 +804,15 @@ void RimEnsembleCurveSet::updateCurveColors() if (group && !parameterName.isEmpty() && !group->allSummaryCases().empty()) { - bool isTextParameter = group->allSummaryCases().front()->caseRealizationParameters() != nullptr ? - group->allSummaryCases().front()->caseRealizationParameters()->parameterValue(parameterName).isText() : false; + auto ensembleParam = group->ensembleParameter(parameterName); - if (isTextParameter) + if (ensembleParam.isText()) { std::set categories; - for (RimSummaryCase* rimCase : group->allSummaryCases()) + for (auto value : ensembleParam.values) { - if (rimCase->caseRealizationParameters() != nullptr) - { - RigCaseRealizationParameters::Value value = rimCase->caseRealizationParameters()->parameterValue(parameterName); - if (value.isText()) - { - categories.insert(value.textValue()); - } - } + categories.insert(value.toString()); } std::vector categoryNames = std::vector(categories.begin(), categories.end()); @@ -718,6 +821,8 @@ void RimEnsembleCurveSet::updateCurveColors() for (auto& curve : m_curves) { + if (curve->summaryAddressY().category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) continue; + RimSummaryCase* rimCase = curve->summaryCaseY(); QString tValue = rimCase->hasCaseRealizationParameters() ? rimCase->caseRealizationParameters()->parameterValue(parameterName).textValue() : @@ -735,25 +840,18 @@ void RimEnsembleCurveSet::updateCurveColors() curve->updateCurveAppearance(); } } - else + else if(ensembleParam.isNumeric()) { double minValue = DOUBLE_INF; double maxValue = -DOUBLE_INF; - for (RimSummaryCase* rimCase : group->allSummaryCases()) + for (auto value : ensembleParam.values) { - if (rimCase->caseRealizationParameters() != nullptr) + double nValue = value.toDouble(); + if (nValue != DOUBLE_INF) { - RigCaseRealizationParameters::Value value = rimCase->caseRealizationParameters()->parameterValue(parameterName); - if (value.isNumeric()) - { - double nValue = value.numericValue(); - if (nValue != DOUBLE_INF) - { - if (nValue < minValue) minValue = nValue; - if (nValue > maxValue) maxValue = nValue; - } - } + if (nValue < minValue) minValue = nValue; + if (nValue > maxValue) maxValue = nValue; } } @@ -761,6 +859,8 @@ void RimEnsembleCurveSet::updateCurveColors() for (auto& curve : m_curves) { + if (curve->summaryAddressY().category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) continue; + RimSummaryCase* rimCase = curve->summaryCaseY(); double value = rimCase->hasCaseRealizationParameters() ? rimCase->caseRealizationParameters()->parameterValue(parameterName).numericValue() : @@ -776,6 +876,8 @@ void RimEnsembleCurveSet::updateCurveColors() { for (auto& curve : m_curves) { + if (curve->summaryAddressY().category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) continue; + curve->setColor(m_color); curve->updateCurveAppearance(); } @@ -811,21 +913,24 @@ void RimEnsembleCurveSet::updateQwtPlotAxis() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEnsembleCurveSet::updateAllCurves() +void RimEnsembleCurveSet::updateEnsembleCurves(const std::vector& sumCases) { RimSummaryPlot* plot = nullptr; firstAncestorOrThisOfType(plot); CVF_ASSERT(plot); - deleteAllCurves(); + deleteEnsembleCurves(); + m_qwtPlotCurveForLegendText->detach(); + deleteStatisticsCurves(); + + if (m_statistics->hideEnsembleCurves()) return; - RimSummaryCaseCollection* group = m_yValuesSummaryGroup(); RimSummaryAddress* addr = m_yValuesCurveVariable(); - if (group && plot && addr->address().category() != RifEclipseSummaryAddress::SUMMARY_INVALID) + if (plot && addr->address().category() != RifEclipseSummaryAddress::SUMMARY_INVALID) { if(m_showCurves) { - for (auto& sumCase : group->allSummaryCases()) + for (auto& sumCase : sumCases) { RimSummaryCurve* curve = new RimSummaryCurve(); curve->setSummaryCaseY(sumCase); @@ -834,8 +939,9 @@ void RimEnsembleCurveSet::updateAllCurves() addCurve(curve); - curve->updateCurveVisibility(true); - curve->loadDataAndUpdate(true); + curve->updateCurveVisibility(false); + curve->loadDataAndUpdate(false); + curve->updateQwtPlotAxis(); if (curve->qwtPlotCurve()) { @@ -843,19 +949,107 @@ void RimEnsembleCurveSet::updateAllCurves() } } m_yValuesSummaryFilter->updateFromAddress(addr->address()); + + if (plot->qwtPlot()) m_qwtPlotCurveForLegendText->attach(plot->qwtPlot()); } - RimSummaryPlot* plot; - firstAncestorOrThisOfType(plot); if (plot->qwtPlot()) { + plot->qwtPlot()->updateLegend(); plot->qwtPlot()->replot(); plot->updateAxes(); + plot->updatePlotInfoLabel(); } } updateCurveColors(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveSet::updateStatisticsCurves(const std::vector& sumCases) +{ + using SAddr = RifEclipseSummaryAddress; + + RimSummaryCaseCollection* group = m_yValuesSummaryGroup(); + RimSummaryAddress* addr = m_yValuesCurveVariable(); + + if (m_disableStatisticCurves || !group || addr->address().category() == RifEclipseSummaryAddress::SUMMARY_INVALID) return; + + // Calculate + { + std::vector statCases = sumCases; + if (statCases.empty()) + { + if (m_statistics->basedOnFilteredCases()) statCases = filterEnsembleCases(group->allSummaryCases()); + else statCases = group->allSummaryCases(); + } + m_ensembleStatCase->calculate(statCases); + } + + RimSummaryPlot* plot = nullptr; + firstAncestorOrThisOfType(plot); + CVF_ASSERT(plot); + + std::vector addresses; + if (m_statistics->isActive()) + { + RifEclipseSummaryAddress dataAddress = m_yValuesCurveVariable->address(); + + if (m_statistics->showP10Curve() && m_ensembleStatCase->hasP10Data()) + addresses.push_back(SAddr::ensembleStatisticsAddress(ENSEMBLE_STAT_P10_QUANTITY_NAME, dataAddress.quantityName())); + if (m_statistics->showP50Curve() && m_ensembleStatCase->hasP50Data()) + addresses.push_back(SAddr::ensembleStatisticsAddress(ENSEMBLE_STAT_P50_QUANTITY_NAME, dataAddress.quantityName())); + if (m_statistics->showP90Curve() && m_ensembleStatCase->hasP90Data()) + addresses.push_back(SAddr::ensembleStatisticsAddress(ENSEMBLE_STAT_P90_QUANTITY_NAME, dataAddress.quantityName())); + if (m_statistics->showMeanCurve() && m_ensembleStatCase->hasMeanData()) + addresses.push_back(SAddr::ensembleStatisticsAddress(ENSEMBLE_STAT_MEAN_QUANTITY_NAME, dataAddress.quantityName())); + } + + deleteStatisticsCurves(); + for (auto address : addresses) + { + auto curve = new RimSummaryCurve(); + curve->setParentQwtPlotNoReplot(plot->qwtPlot()); + m_curves.push_back(curve); + curve->setColor(m_statistics->color()); + curve->setColor(m_statistics->color()); + + auto symbol = statisticsCurveSymbolFromAddress(address); + curve->setSymbol(symbol); + curve->setSymbolSize(statisticsCurveSymbolSize(symbol)); + curve->setSymbolSkipDistance(150); + if (m_statistics->showCurveLabels()) + { + curve->setSymbolLabel(RiaStatisticsTools::replacePercentileByPValueText( + QString::fromStdString(address.ensembleStatisticsQuantityName()))); + } + curve->setLineStyle(RiuQwtPlotCurve::STYLE_SOLID); + curve->setSummaryCaseY(m_ensembleStatCase.get()); + curve->setSummaryAddressY(address); + curve->setLeftOrRightAxisY(m_plotAxis()); + curve->setZOrder(1000); + + curve->updateCurveVisibility(false); + curve->loadDataAndUpdate(false); + curve->updateQwtPlotAxis(); + } + + if (plot->qwtPlot()) + { + plot->qwtPlot()->updateLegend(); + plot->updateAxes(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveSet::updateStatisticsCurves() +{ + updateStatisticsCurves(std::vector()); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -880,6 +1074,17 @@ void RimEnsembleCurveSet::showCurves(bool show) m_showCurves = show; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveSet::markCachedDataForPurge() +{ + for (const auto curve : m_curves) + { + curve->markCachedDataForPurge(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -895,6 +1100,90 @@ void RimEnsembleCurveSet::updateAllTextInPlot() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimEnsembleCurveSet::ensembleParameterNames() const +{ + RimSummaryCaseCollection* group = m_yValuesSummaryGroup; + + std::set paramSet; + if (group) + { + for (RimSummaryCase* rimCase : group->allSummaryCases()) + { + if (rimCase->caseRealizationParameters() != nullptr) + { + auto ps = rimCase->caseRealizationParameters()->parameters(); + for (auto p : ps) paramSet.insert(p.first); + } + } + } + return std::vector(paramSet.begin(), paramSet.end()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimEnsembleCurveSet::filterEnsembleCases(const std::vector& sumCases) +{ + auto filteredCases = sumCases; + + for (auto& filter : m_curveFilters->filters()) + { + filteredCases = filter->applyFilter(filteredCases); + } + return filteredCases; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveSet::disableStatisticCurves() +{ + m_disableStatisticCurves = true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEnsembleCurveSet::isFiltered() const +{ + return m_isCurveSetFiltered; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEnsembleCurveSet::hasP10Data() const +{ + return m_ensembleStatCase->hasP10Data(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEnsembleCurveSet::hasP50Data() const +{ + return m_ensembleStatCase->hasP50Data(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEnsembleCurveSet::hasP90Data() const +{ + return m_ensembleStatCase->hasP90Data(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEnsembleCurveSet::hasMeanData() const +{ + return m_ensembleStatCase->hasMeanData(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -932,28 +1221,6 @@ void RimEnsembleCurveSet::updateEnsembleLegendItem() m_qwtPlotCurveForLegendText->setItemAttribute(QwtPlotItem::Legend, showLegendItem); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RimEnsembleCurveSet::ensembleParameters() const -{ - RimSummaryCaseCollection* group = m_yValuesSummaryGroup; - - std::set paramSet; - if (group) - { - for (RimSummaryCase* rimCase : group->allSummaryCases()) - { - if (rimCase->caseRealizationParameters() != nullptr) - { - auto ps = rimCase->caseRealizationParameters()->parameters(); - for (auto p : ps) paramSet.insert(p.first); - } - } - } - return std::vector(paramSet.begin(), paramSet.end()); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1001,14 +1268,38 @@ void RimEnsembleCurveSet::updateLegendMappingMode() { switch (currentEnsembleParameterType()) { - case TYPE_TEXT: + case EnsembleParameter::TYPE_TEXT: if (m_legendConfig->mappingMode() != RimRegularLegendConfig::MappingType::CATEGORY_INTEGER) m_legendConfig->setMappingMode(RimRegularLegendConfig::MappingType::CATEGORY_INTEGER); break; - case TYPE_NUMERIC: + case EnsembleParameter::TYPE_NUMERIC: if (m_legendConfig->mappingMode() == RimRegularLegendConfig::MappingType::CATEGORY_INTEGER) m_legendConfig->setMappingMode(RimRegularLegendConfig::MappingType::LINEAR_CONTINUOUS); break; } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuQwtSymbol::PointSymbolEnum statisticsCurveSymbolFromAddress(const RifEclipseSummaryAddress& address) +{ + auto qName = QString::fromStdString(address.quantityName()); + + if (qName.contains(ENSEMBLE_STAT_P10_QUANTITY_NAME)) return RiuQwtSymbol::SYMBOL_TRIANGLE; + if (qName.contains(ENSEMBLE_STAT_P90_QUANTITY_NAME)) return RiuQwtSymbol::SYMBOL_DOWN_TRIANGLE; + if (qName.contains(ENSEMBLE_STAT_P50_QUANTITY_NAME)) return RiuQwtSymbol::SYMBOL_DIAMOND; + return RiuQwtSymbol::SYMBOL_ELLIPSE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int statisticsCurveSymbolSize(RiuQwtSymbol::PointSymbolEnum symbol) +{ + if (symbol == RiuQwtSymbol::SYMBOL_DIAMOND) return 8; + if (symbol == RiuQwtSymbol::SYMBOL_TRIANGLE) return 7; + if (symbol == RiuQwtSymbol::SYMBOL_DOWN_TRIANGLE) return 7; + return 6; +} diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h index a07f9b00c2..273a3fa37b 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h @@ -20,10 +20,13 @@ #pragma once #include "RifEclipseSummaryAddress.h" +#include "RifSummaryReaderInterface.h" #include "RiaDefines.h" #include "RimRegularLegendConfig.h" +#include "RimSummaryCase.h" +#include "RimSummaryCaseCollection.h" #include "cafPdmFieldCvfColor.h" #include "cafPdmChildArrayField.h" @@ -46,7 +49,11 @@ class RimSummaryAddress; class RimSummaryFilter; class RimSummaryPlotSourceStepping; class RimSummaryCurveAutoName; +class RimEnsembleCurveFilterCollection; +class RimEnsembleStatistics; class QKeyEvent; +class RimEnsembleStatisticsCase; + //================================================================================================== /// @@ -57,10 +64,9 @@ class RimEnsembleCurveSet : public caf::PdmObject public: enum ColorMode {SINGLE_COLOR, BY_ENSEMBLE_PARAM}; - enum EnsembleParameterType {TYPE_NONE, TYPE_NUMERIC, TYPE_TEXT}; RimEnsembleCurveSet(); - virtual ~RimEnsembleCurveSet(); + ~RimEnsembleCurveSet() override; bool isCurvesVisible(); void setColor(cvf::Color3f color); @@ -68,6 +74,7 @@ class RimEnsembleCurveSet : public caf::PdmObject void loadDataAndUpdate(bool updateParentPlot); void setParentQwtPlotNoReplot(QwtPlot* plot); void detachQwtCurves(); + void reattachQwtCurves(); void addCurve(RimSummaryCurve* curve); void deleteCurve(RimSummaryCurve* curve); @@ -76,7 +83,8 @@ class RimEnsembleCurveSet : public caf::PdmObject RifEclipseSummaryAddress summaryAddress() const; std::vector curves() const; - void deleteAllCurves(); + void deleteEnsembleCurves(); + void deleteStatisticsCurves(); RimRegularLegendConfig* legendConfig(); void onLegendDefinitionChanged(); @@ -84,39 +92,53 @@ class RimEnsembleCurveSet : public caf::PdmObject void setSummaryCaseCollection(RimSummaryCaseCollection* sumCaseCollection); RimSummaryCaseCollection* summaryCaseCollection() const; + RimEnsembleCurveFilterCollection* filterCollection() const; + ColorMode colorMode() const; void updateEnsembleLegendItem(); - EnsembleParameterType currentEnsembleParameterType() const; + EnsembleParameter::Type currentEnsembleParameterType() const; void updateAllCurves(); + void updateStatisticsCurves(); + RimEnsembleCurveSet* clone() const; void showCurves(bool show); + void markCachedDataForPurge(); + void updateAllTextInPlot(); + std::vector ensembleParameterNames() const; + + std::vector filterEnsembleCases(const std::vector& sumCases); + void disableStatisticCurves(); + bool isFiltered() const; + + bool hasP10Data() const; + bool hasP50Data() const; + bool hasP90Data() const; + bool hasMeanData() const; private: + void updateEnsembleCurves(const std::vector& sumCases); + void updateStatisticsCurves(const std::vector& sumCases); + caf::PdmFieldHandle* userDescriptionField() override; - caf::PdmFieldHandle* objectToggleField(); - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + caf::PdmFieldHandle* objectToggleField() override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - static void getOptionsForSummaryAddresses(std::map* options, - RimSummaryCase* summaryCase, - RimSummaryFilter* summaryFilter); - void appendOptionItemsForSummaryAddresses(QList* options, RimSummaryCaseCollection* summaryCaseGroup, RimSummaryFilter* summaryFilter); void updateCurveColors(); void updateQwtPlotAxis(); - std::vector ensembleParameters() const; QString name() const; QString createAutoName() const; @@ -143,14 +165,19 @@ class RimEnsembleCurveSet : public caf::PdmObject caf::PdmField> m_plotAxis; caf::PdmChildField m_legendConfig; + caf::PdmChildField m_curveFilters; + caf::PdmChildField m_statistics; caf::PdmField m_isUsingAutoName; caf::PdmField m_userDefinedName; caf::PdmProxyValueField m_autoGeneratedName; caf::PdmChildField m_summaryAddressNameTools; - std::set m_allAddressesCache; - QwtPlotCurve* m_qwtPlotCurveForLegendText; + + std::unique_ptr m_ensembleStatCase; + + bool m_disableStatisticCurves; + bool m_isCurveSetFiltered; }; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.cpp b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.cpp index a51722f143..31e76d9ea6 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.cpp @@ -32,7 +32,7 @@ #include "RimSummaryPlot.h" #include "RimSummaryPlotSourceStepping.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuSummaryQwtPlot.h" CAF_PDM_SOURCE_INIT(RimEnsembleCurveSetCollection, "RimEnsembleCurveSetCollection"); @@ -75,20 +75,14 @@ void RimEnsembleCurveSetCollection::loadDataAndUpdate(bool updateParentPlot) { for (RimEnsembleCurveSet* curveSet : m_curveSets) { - curveSet->loadDataAndUpdate(updateParentPlot); + curveSet->loadDataAndUpdate(false); } if (updateParentPlot) { RimSummaryPlot* parentPlot; firstAncestorOrThisOfTypeAsserted(parentPlot); - if (parentPlot->qwtPlot()) - { - parentPlot->updatePlotTitle(); - parentPlot->qwtPlot()->updateLegend(); - parentPlot->updateAxes(); - parentPlot->updateZoomInQwt(); - } + parentPlot->updateAll(); } } @@ -116,6 +110,17 @@ void RimEnsembleCurveSetCollection::detachQwtCurves() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveSetCollection::reattachQwtCurves() +{ + for (const auto& curveSet : m_curveSets) + { + curveSet->reattachQwtCurves(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -155,11 +160,21 @@ void RimEnsembleCurveSetCollection::addCurveSet(RimEnsembleCurveSet* curveSet) //-------------------------------------------------------------------------------------------------- void RimEnsembleCurveSetCollection::deleteCurveSet(RimEnsembleCurveSet* curveSet) { - if (curveSet) + deleteCurveSets({ curveSet }); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleCurveSetCollection::deleteCurveSets(const std::vector curveSets) +{ + for(const auto curveSet : curveSets) { m_curveSets.removeChildObject(curveSet); + curveSet->markCachedDataForPurge(); delete curveSet; } + } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.h b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.h index 423479b553..db962437a0 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.h @@ -37,18 +37,20 @@ class RimEnsembleCurveSetCollection : public caf::PdmObject public: RimEnsembleCurveSetCollection(); - virtual ~RimEnsembleCurveSetCollection(); + ~RimEnsembleCurveSetCollection() override; bool isCurveSetsVisible(); void loadDataAndUpdate(bool updateParentPlot); void setParentQwtPlotAndReplot(QwtPlot* plot); void detachQwtCurves(); + void reattachQwtCurves(); RimEnsembleCurveSet* findRimCurveSetFromQwtCurve(const QwtPlotCurve* qwtCurve) const; void addCurveSet(RimEnsembleCurveSet* curveSet); void deleteCurveSet(RimEnsembleCurveSet* curveSet); + void deleteCurveSets(const std::vector curveSets); std::vector curveSets() const; size_t curveSetCount() const; @@ -60,7 +62,7 @@ class RimEnsembleCurveSetCollection : public caf::PdmObject private: caf::PdmFieldHandle* objectToggleField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatistics.cpp b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatistics.cpp new file mode 100644 index 0000000000..e0f2bff273 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatistics.cpp @@ -0,0 +1,169 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimEnsembleStatistics.h" + +#include "RifSummaryReaderInterface.h" + +#include "RigStatisticsMath.h" +#include "RiaTimeHistoryCurveMerger.h" + +#include "RimEnsembleCurveSet.h" +#include "RimSummaryCase.h" +#include "RimSummaryCaseCollection.h" + + +CAF_PDM_SOURCE_INIT(RimEnsembleStatistics, "RimEnsembleStatistics"); + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEnsembleStatistics::RimEnsembleStatistics() +{ + CAF_PDM_InitObject("Ensemble Curve Filter", ":/EnsembleCurveSet16x16.png", "", ""); + + CAF_PDM_InitField(&m_active, "Active", true, "Show statistics curves", "", "", ""); + CAF_PDM_InitField(&m_hideEnsembleCurves, "HideEnsembleCurves", false, "Hide Ensemble Curves", "", "", ""); + CAF_PDM_InitField(&m_basedOnFilteredCases, "BasedOnFilteredCases", false, "Based on Filtered Cases", "", "", ""); + CAF_PDM_InitField(&m_showP10Curve, "ShowP10Curve", true, "P90", "", "", ""); // Yes, P90 + CAF_PDM_InitField(&m_showP50Curve, "ShowP50Curve", false, "P50", "", "", ""); + CAF_PDM_InitField(&m_showP90Curve, "ShowP90Curve", true, "P10", "", "", ""); // Yes, P10 + CAF_PDM_InitField(&m_showMeanCurve, "ShowMeanCurve", true, "Mean", "", "", ""); + CAF_PDM_InitField(&m_showCurveLabels, "ShowCurveLabels", true, "Show Curve Labels", "", "", ""); + CAF_PDM_InitField(&m_warningLabel, "WarningLabel", QString("Warning: Ensemble time range mismatch"), "", "", "", ""); + CAF_PDM_InitField(&m_color, "Color", cvf::Color3f(cvf::Color3::BLACK), "Color", "", "", ""); + + m_warningLabel.xmlCapability()->disableIO(); + m_warningLabel.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + m_warningLabel.uiCapability()->setUiReadOnly(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimEnsembleStatistics::isActive() const +{ + return m_active; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatistics::disableP10Curve(bool disable) +{ + m_showP10Curve.uiCapability()->setUiReadOnly(disable); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatistics::disableP50Curve(bool disable) +{ + m_showP50Curve.uiCapability()->setUiReadOnly(disable); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatistics::disableP90Curve(bool disable) +{ + m_showP90Curve.uiCapability()->setUiReadOnly(disable); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatistics::disableMeanCurve(bool disable) +{ + m_showMeanCurve.uiCapability()->setUiReadOnly(disable); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatistics::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) +{ + if (changedField == &m_active || + changedField == &m_basedOnFilteredCases || + changedField == &m_showP10Curve || + changedField == &m_showP50Curve || + changedField == &m_showP90Curve || + changedField == &m_showMeanCurve || + changedField == &m_showCurveLabels || + changedField == &m_color) + { + auto curveSet = parentCurveSet(); + if (!curveSet) return; + + curveSet->updateStatisticsCurves(); + + if (changedField == &m_active || changedField == &m_basedOnFilteredCases) curveSet->updateConnectedEditors(); + } + + + if (changedField == &m_hideEnsembleCurves) + { + auto curveSet = parentCurveSet(); + if (!curveSet) return; + + curveSet->updateAllCurves(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatistics::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + auto curveSet = parentCurveSet(); + + uiOrdering.add(&m_active); + uiOrdering.add(&m_hideEnsembleCurves); + uiOrdering.add(&m_basedOnFilteredCases); + uiOrdering.add(&m_showCurveLabels); + uiOrdering.add(&m_color); + + auto group = uiOrdering.addNewGroup("Curves"); + if (!curveSet->hasMeanData()) group->add(&m_warningLabel); + group->add(&m_showP90Curve); + group->add(&m_showP50Curve); + group->add(&m_showMeanCurve); + group->add(&m_showP10Curve); + + disableP10Curve(!m_active || !curveSet->hasP10Data()); + disableP50Curve(!m_active || !curveSet->hasP50Data()); + disableP90Curve(!m_active || !curveSet->hasP90Data()); + disableMeanCurve(!m_active || !curveSet->hasMeanData()); + m_showCurveLabels.uiCapability()->setUiReadOnly(!m_active); + m_color.uiCapability()->setUiReadOnly(!m_active); + + m_showP10Curve.uiCapability()->setUiName(curveSet->hasP10Data() ? "P90" : "P90 (Needs > 8 curves)"); + m_showP90Curve.uiCapability()->setUiName(curveSet->hasP90Data() ? "P10" : "P10 (Needs > 8 curves)"); + + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEnsembleCurveSet* RimEnsembleStatistics::parentCurveSet() const +{ + RimEnsembleCurveSet* curveSet; + firstAncestorOrThisOfType(curveSet); + return curveSet; +} diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatistics.h b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatistics.h new file mode 100644 index 0000000000..ee2adfba81 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatistics.h @@ -0,0 +1,77 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "RimEnsembleCurveSet.h" +#include "RimSummaryCase.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" + +class RifEclipseSummaryAddress; +class RimSummaryCaseCollection; +class RimEnsembleStatisticsCase; + + +//================================================================================================== +/// +//================================================================================================== +class RimEnsembleStatistics : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimEnsembleStatistics(); + + bool isActive() const; + bool hideEnsembleCurves() const { return m_hideEnsembleCurves; } + bool basedOnFilteredCases() const { return m_basedOnFilteredCases; } + bool showP10Curve() const { return m_showP10Curve; } + bool showP50Curve() const { return m_showP50Curve; } + bool showP90Curve() const { return m_showP90Curve; } + bool showMeanCurve() const { return m_showMeanCurve; } + bool showCurveLabels() const { return m_showCurveLabels; } + cvf::Color3f color() const { return m_color; } + + void disableP10Curve(bool disable); + void disableP50Curve(bool disable); + void disableP90Curve(bool disable); + void disableMeanCurve(bool disable); + + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + +private: + RimEnsembleCurveSet* parentCurveSet() const; + + caf::PdmField m_active; + caf::PdmField m_hideEnsembleCurves; + caf::PdmField m_basedOnFilteredCases; + caf::PdmField m_showP10Curve; + caf::PdmField m_showP50Curve; + caf::PdmField m_showP90Curve; + caf::PdmField m_showMeanCurve; + caf::PdmField m_showCurveLabels; + + caf::PdmField m_warningLabel; + + caf::PdmField m_color; +}; + diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.cpp new file mode 100644 index 0000000000..2e86872f69 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.cpp @@ -0,0 +1,290 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimEnsembleStatisticsCase.h" + +#include "RifEnsembleStatisticsReader.h" + +#include "RigStatisticsMath.h" +#include "RiaTimeHistoryCurveMerger.h" +#include "RiaTimeHistoryCurveResampler.h" + +#include "RimEnsembleCurveSet.h" + +#include +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// Internal constants +//-------------------------------------------------------------------------------------------------- +#define DOUBLE_INF std::numeric_limits::infinity() + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimEnsembleStatisticsCase::RimEnsembleStatisticsCase(RimEnsembleCurveSet* curveSet) +{ + m_curveSet = curveSet; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RimEnsembleStatisticsCase::timeSteps() const +{ + return m_timeSteps; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RimEnsembleStatisticsCase::p10() const +{ + return m_p10Data; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RimEnsembleStatisticsCase::p50() const +{ + return m_p50Data; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RimEnsembleStatisticsCase::p90() const +{ + return m_p90Data; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RimEnsembleStatisticsCase::mean() const +{ + return m_meanData; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimEnsembleStatisticsCase::caseName() const +{ + return "Ensemble Statistics"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatisticsCase::createSummaryReaderInterface() +{ + m_statisticsReader.reset(new RifEnsembleStatisticsReader(this)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifSummaryReaderInterface* RimEnsembleStatisticsCase::summaryReader() +{ + return m_statisticsReader.get(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RimEnsembleCurveSet* RimEnsembleStatisticsCase::curveSet() const +{ + return m_curveSet; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatisticsCase::calculate(const std::vector& sumCases) +{ + auto inputAddress = m_curveSet->summaryAddress(); + if (m_statisticsReader && inputAddress.isValid()) + { + calculate(validSummaryCases(sumCases, inputAddress), inputAddress); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatisticsCase::calculate(const std::vector sumCases, const RifEclipseSummaryAddress& inputAddress) +{ + std::vector allTimeSteps; + std::vector> allValues; + + if (!inputAddress.isValid()) return; + + allValues.reserve(sumCases.size()); + for (const auto& sumCase : sumCases) + { + const auto& reader = sumCase->summaryReader(); + if (reader) + { + std::vector timeSteps = reader->timeSteps(inputAddress); + std::vector values; + reader->values(inputAddress, &values); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(values, timeSteps); + if (inputAddress.hasAccumulatedData()) resampler.resampleAndComputePeriodEndValues(DateTimePeriod::DAY); + else resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::DAY); + + if (allTimeSteps.empty()) allTimeSteps = resampler.resampledTimeSteps(); + allValues.push_back(std::vector(resampler.resampledValues().begin(), resampler.resampledValues().end())); + } + } + + clearData(); + m_timeSteps = allTimeSteps; + + for (int t = 0; t < (int)allTimeSteps.size(); t++) + { + std::vector valuesAtTimeStep; + valuesAtTimeStep.reserve(sumCases.size()); + + for (int c = 0; c < (int)sumCases.size(); c++) + { + valuesAtTimeStep.push_back(allValues[c][t]); + } + + double p10, p50, p90, mean; + calculateStatistics(valuesAtTimeStep, &p10, &p50, &p90, &mean); + + if (p10 != DOUBLE_INF) m_p10Data.push_back(p10); + if (p50 != DOUBLE_INF) m_p50Data.push_back(p50); + if (p90 != DOUBLE_INF) m_p90Data.push_back(p90); + m_meanData.push_back(mean); + } + m_addressUsedInLastCalculation = inputAddress; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatisticsCase::clearData() +{ + m_timeSteps.clear(); + m_p10Data.clear(); + m_p50Data.clear(); + m_p90Data.clear(); + m_meanData.clear(); + m_addressUsedInLastCalculation = RifEclipseSummaryAddress(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimEnsembleStatisticsCase::validSummaryCases(const std::vector allSumCases, const RifEclipseSummaryAddress& inputAddress) +{ + std::vector validCases; + std::vector> times; + + time_t minTimeStep = std::numeric_limits::max(); + time_t maxTimeStep = 0; + + for (auto& sumCase : allSumCases) + { + const auto& reader = sumCase->summaryReader(); + if (reader) + { + const std::vector& timeSteps = reader->timeSteps(inputAddress); + if (!timeSteps.empty()) + { + time_t firstTimeStep = timeSteps.front(); + time_t lastTimeStep = timeSteps.back(); + + if (firstTimeStep < minTimeStep) minTimeStep = firstTimeStep; + if (lastTimeStep > maxTimeStep) maxTimeStep = lastTimeStep; + times.push_back(std::make_tuple(sumCase, firstTimeStep, lastTimeStep)); + } + } + } + + for (auto& item : times) + { + RimSummaryCase* sumCase = std::get<0>(item); + time_t firstTimeStep = std::get<1>(item); + time_t lastTimeStep = std::get<2>(item); + + if (firstTimeStep == minTimeStep && lastTimeStep == maxTimeStep) + { + validCases.push_back(sumCase); + } + } + return validCases; +} + +//-------------------------------------------------------------------------------------------------- +/// Algorithm: +/// https://en.wikipedia.org/wiki/Percentile#Third_variant,_'%22%60UNIQ--postMath-00000052-QINU%60%22' +//-------------------------------------------------------------------------------------------------- +void RimEnsembleStatisticsCase::calculateStatistics(const std::vector& values, double* p10, double* p50, double* p90, double* mean) +{ + CVF_ASSERT(p10 && p50 && p90 && mean); + + enum PValue { P10, P50, P90 }; + + std::vector sortedValues; + double valueSum = 0; + + { + std::multiset vSet(values.begin(), values.end()); + for (double v : vSet) + { + sortedValues.push_back(v); + valueSum += v; + } + } + + int valueCount = (int)sortedValues.size(); + double percentiles[] = { 0.1, 0.5, 0.9 }; + double pValues[] = { DOUBLE_INF, DOUBLE_INF, DOUBLE_INF }; + + for (int i = P10; i <= P90; i++) + { + // Check valid params + if ((percentiles[i] < 1.0 / ((double)valueCount + 1)) || (percentiles[i] > (double)valueCount / ((double)valueCount + 1))) continue; + + double rank = percentiles[i] * (valueCount + 1) - 1; + double rankInt; + double rankFrac = std::modf(rank, &rankInt); + + if (rankInt < valueCount - 1) + { + pValues[i] = sortedValues[rankInt] + rankFrac * (sortedValues[rankInt + 1] - sortedValues[rankInt]); + } + else + { + pValues[i] = sortedValues[rankInt]; + } + } + + *p10 = pValues[P10]; + *p50 = pValues[P50]; + *p90 = pValues[P90]; + *mean = valueSum / valueCount; +} + diff --git a/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.h b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.h new file mode 100644 index 0000000000..d9453ddfa4 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.h @@ -0,0 +1,76 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#pragma once + +#include "RifEclipseSummaryAddress.h" + +#include "RimSummaryCase.h" + +class RifEnsembleStatisticsReader; +class RimEnsembleCurveSet; + + +//================================================================================================== +/// +//================================================================================================== +class RimEnsembleStatisticsCase : public RimSummaryCase +{ +public: + RimEnsembleStatisticsCase(RimEnsembleCurveSet* curveSet); + + const std::vector& timeSteps() const; + const std::vector& p10() const; + const std::vector& p50() const; + const std::vector& p90() const; + const std::vector& mean() const; + + bool hasP10Data() const {return !m_p10Data.empty(); } + bool hasP50Data() const { return !m_p50Data.empty(); } + bool hasP90Data() const { return !m_p90Data.empty(); } + bool hasMeanData() const { return !m_meanData.empty(); } + + QString caseName() const override; + void createSummaryReaderInterface() override; + RifSummaryReaderInterface* summaryReader() override; + + void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override {} + + const RimEnsembleCurveSet* curveSet() const; + + void calculate(const std::vector& sumCases); + +private: + void calculate(const std::vector sumCases, const RifEclipseSummaryAddress& inputAddress); + void clearData(); + std::vector validSummaryCases(const std::vector allSumCases, const RifEclipseSummaryAddress& inputAddress); + void calculateStatistics(const std::vector& values, double* p10, double* p50, double* p90, double* mean); + +private: + std::unique_ptr m_statisticsReader; + RimEnsembleCurveSet* m_curveSet; + + std::vector m_timeSteps; + std::vector m_p10Data; + std::vector m_p50Data; + std::vector m_p90Data; + std::vector m_meanData; + + RifEclipseSummaryAddress m_addressUsedInLastCalculation; +}; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp index 6d37600879..43324442f5 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp @@ -64,7 +64,7 @@ QString RimFileSummaryCase::summaryHeaderFilename() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimFileSummaryCase::caseName() +QString RimFileSummaryCase::caseName() const { QFileInfo caseFileName(this->summaryHeaderFilename()); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.h b/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.h index 8ba0c4680e..3d22bbe84a 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimFileSummaryCase.h @@ -34,14 +34,14 @@ class RimFileSummaryCase: public RimSummaryCase CAF_PDM_HEADER_INIT; public: RimFileSummaryCase(); - virtual ~RimFileSummaryCase(); + ~RimFileSummaryCase() override; - virtual QString summaryHeaderFilename() const override; - virtual QString caseName() override; - virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; + QString summaryHeaderFilename() const override; + QString caseName() const override; + void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; - virtual void createSummaryReaderInterface() override; - virtual RifSummaryReaderInterface* summaryReader() override; + void createSummaryReaderInterface() override; + RifSummaryReaderInterface* summaryReader() override; void setIncludeRestartFiles(bool includeRestartFiles); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.cpp index 987a545385..911ea06fcb 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.cpp @@ -147,7 +147,7 @@ QString RimGridSummaryCase::summaryHeaderFilename() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimGridSummaryCase::caseName() +QString RimGridSummaryCase::caseName() const { if (m_eclipseCase()) m_cachedCaseName = caseNameFromEclipseCase(m_eclipseCase()); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.h b/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.h index 4242be37d8..d75ddf8141 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimGridSummaryCase.h @@ -39,17 +39,17 @@ class RimGridSummaryCase : public RimSummaryCase CAF_PDM_HEADER_INIT; public: RimGridSummaryCase(); - virtual ~RimGridSummaryCase(); + ~RimGridSummaryCase() override; void setAssociatedEclipseCase(RimEclipseCase* eclipseCase); RimEclipseCase* associatedEclipseCase(); - virtual QString summaryHeaderFilename() const override; - virtual QString caseName() override; - virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; + QString summaryHeaderFilename() const override; + QString caseName() const override; + void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; - virtual void createSummaryReaderInterface() override; - virtual RifSummaryReaderInterface* summaryReader() override; + void createSummaryReaderInterface() override; + RifSummaryReaderInterface* summaryReader() override; void setIncludeRestartFiles(bool includeRestartFiles); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimObservedData.cpp b/ApplicationCode/ProjectDataModel/Summary/RimObservedData.cpp index fa1a93287b..544b04df2b 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimObservedData.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimObservedData.cpp @@ -50,7 +50,7 @@ RimObservedData::RimObservedData() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimObservedData::caseName() +QString RimObservedData::caseName() const { QFileInfo caseFileName(this->summaryHeaderFilename()); @@ -114,19 +114,6 @@ QString RimObservedData::customWellName() const return ""; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString RimObservedData::customWellGroupName() const -{ - if (m_useCustomIdentifier() && m_summaryCategory() == RifEclipseSummaryAddress::SUMMARY_WELL_GROUP) - { - return m_identifierName(); - } - - return ""; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Summary/RimObservedData.h b/ApplicationCode/ProjectDataModel/Summary/RimObservedData.h index c335bfdab7..f08e6db7f6 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimObservedData.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimObservedData.h @@ -36,8 +36,8 @@ class RimObservedData : public RimSummaryCase public: RimObservedData(); - virtual QString caseName() override; - virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; + QString caseName() const override; + void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override; QString identifierName() const; RifEclipseSummaryAddress::SummaryVarCategory summaryCategory() const; @@ -46,11 +46,10 @@ class RimObservedData : public RimSummaryCase protected: QString customWellName() const; - QString customWellGroupName() const; private: - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: caf::PdmField > m_summaryCategory; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimObservedDataCollection.cpp b/ApplicationCode/ProjectDataModel/Summary/RimObservedDataCollection.cpp index d0f6d8b149..f5a91cbcb1 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimObservedDataCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimObservedDataCollection.cpp @@ -72,14 +72,6 @@ void RimObservedDataCollection::removeObservedData(RimObservedData* observedData caf::PdmUiObjectEditorHandle::updateUiAllObjectEditors(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimObservedDataCollection::addObservedData(RimObservedData* observedData) -{ - m_observedDataArray.push_back(observedData); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -109,6 +101,9 @@ bool RimObservedDataCollection::fileExists(const QString& fileName, QString* err return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- void updateNewSummaryObjectCreated(caf::PdmObject* object) { RiuPlotMainWindowTools::showPlotMainWindow(); @@ -169,10 +164,13 @@ RimObservedData* RimObservedDataCollection::createAndAddCvsObservedDataFromFile( } parseOptions->setUiModeImport(fileName); - caf::PdmUiPropertyViewDialog propertyDialog(nullptr, parseOptions, "CSV Import Options", ""); - if (propertyDialog.exec() != QDialog::Accepted) + if (parseOptions->uiModeImport() != RicPasteAsciiDataToSummaryPlotFeatureUi::UI_MODE_SILENT) { - return nullptr; + caf::PdmUiPropertyViewDialog propertyDialog(nullptr, parseOptions, "CSV Import Options", ""); + if (propertyDialog.exec() != QDialog::Accepted) + { + return nullptr; + } } caf::PdmSettings::writeFieldsToApplicationStore(parseOptions); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimObservedDataCollection.h b/ApplicationCode/ProjectDataModel/Summary/RimObservedDataCollection.h index 4f986d71e3..0bcd4d8b37 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimObservedDataCollection.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimObservedDataCollection.h @@ -34,10 +34,9 @@ class RimObservedDataCollection : public caf::PdmObject public: RimObservedDataCollection(); - virtual ~RimObservedDataCollection(); + ~RimObservedDataCollection() override; void removeObservedData(RimObservedData* observedData); - void addObservedData(RimObservedData* observedData); RimObservedData* createAndAddRsmObservedDataFromFile(const QString& fileName, QString* errorText = nullptr); RimObservedData* createAndAddCvsObservedDataFromFile(const QString& fileName, bool useSavedFieldsValuesInDialog, QString* errorText = nullptr); std::vector allObservedData(); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimObservedEclipseUserData.h b/ApplicationCode/ProjectDataModel/Summary/RimObservedEclipseUserData.h index e0a91db65b..a8f891ddaa 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimObservedEclipseUserData.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimObservedEclipseUserData.h @@ -34,13 +34,13 @@ class RimObservedEclipseUserData : public RimObservedData CAF_PDM_HEADER_INIT; public: RimObservedEclipseUserData(); - virtual ~RimObservedEclipseUserData(); + ~RimObservedEclipseUserData() override; - virtual void createSummaryReaderInterface() override; + void createSummaryReaderInterface() override; - virtual RifSummaryReaderInterface* summaryReader() override; + RifSummaryReaderInterface* summaryReader() override; - virtual QString errorMessagesFromReader() override; + QString errorMessagesFromReader() override; private: cvf::ref m_summeryReader; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryAddress.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryAddress.cpp index 3f3830a594..0c86d2aede 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryAddress.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryAddress.cpp @@ -40,6 +40,7 @@ namespace caf addItem(RifEclipseSummaryAddress::SUMMARY_BLOCK_LGR, "SUMMARY_BLOCK_LGR", "Lgr-Block"); addItem(RifEclipseSummaryAddress::SUMMARY_CALCULATED, "SUMMARY_CALCULATED", "Calculated"); addItem(RifEclipseSummaryAddress::SUMMARY_IMPORTED, "SUMMARY_IMPORTED", "Imported"); + addItem(RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS, "SUMMARY_ENSEMBLE_STATISTICS", "Ensemble Statistics"); setDefault(RifEclipseSummaryAddress::SUMMARY_FIELD); } @@ -67,6 +68,7 @@ RimSummaryAddress::RimSummaryAddress() CAF_PDM_InitFieldNoDefault(&m_cellJ, "SummaryCellJ", "J", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_cellK, "SummaryCellK", "K", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_aquiferNumber, "SummaryAquifer", "Aquifer", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_isErrorResult, "IsErrorResult", "Is Error Result", "", "", ""); m_category = RifEclipseSummaryAddress::SUMMARY_INVALID; m_regionNumber = -1; @@ -76,6 +78,7 @@ RimSummaryAddress::RimSummaryAddress() m_cellJ = -1; m_cellK = -1; m_aquiferNumber = -1; + m_isErrorResult = false; } //-------------------------------------------------------------------------------------------------- @@ -100,6 +103,7 @@ void RimSummaryAddress::setAddress(const RifEclipseSummaryAddress& addr) m_wellSegmentNumber = addr.wellSegmentNumber(); m_lgrName = addr.lgrName().c_str(); m_aquiferNumber = addr.aquiferNumber(); + m_isErrorResult = addr.isErrorResult(); m_cellI = addr.cellI(); m_cellJ = addr.cellJ(); m_cellK = addr.cellK(); } @@ -118,6 +122,7 @@ RifEclipseSummaryAddress RimSummaryAddress::address() m_wellSegmentNumber(), m_lgrName().toStdString(), m_cellI(), m_cellJ(), m_cellK(), - m_aquiferNumber); + m_aquiferNumber, + m_isErrorResult); } diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryAddress.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryAddress.h index dfded3189e..e4bb39819a 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryAddress.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryAddress.h @@ -34,7 +34,7 @@ class RifSummaryReaderInterface; class RimSummaryCase; class RimSummaryFilter; -class RiuLineSegmentQwtPlotCurve; +class RiuQwtPlotCurve; class RimSummaryCurveAutoName; @@ -43,7 +43,7 @@ class RimSummaryAddress: public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimSummaryAddress();; - virtual ~RimSummaryAddress(); + ~RimSummaryAddress() override; void setAddress(const RifEclipseSummaryAddress& addr); RifEclipseSummaryAddress address(); @@ -63,5 +63,6 @@ class RimSummaryAddress: public caf::PdmObject caf::PdmField m_cellJ; caf::PdmField m_cellK; caf::PdmField m_aquiferNumber; + caf::PdmField m_isErrorResult; }; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryAxisProperties.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryAxisProperties.h index 2c56271a18..81d47587be 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryAxisProperties.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryAxisProperties.h @@ -80,14 +80,14 @@ class RimSummaryAxisProperties : public caf::PdmObject bool isActive() const; protected: - virtual void initAfterRead() override; - virtual caf::PdmFieldHandle* userDescriptionField() override; - virtual caf::PdmFieldHandle* objectToggleField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, + void initAfterRead() override; + caf::PdmFieldHandle* userDescriptionField() override; + caf::PdmFieldHandle* objectToggleField() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; private: diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp index 563c87501f..976427dc4a 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.cpp @@ -115,15 +115,7 @@ RimSummaryCaseCollection* RimSummaryCase::ensemble() const { RimSummaryCaseCollection* e; firstAncestorOrThisOfType(e); - return e; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RimSummaryCase::isEnsembleCase() const -{ - return ensemble() != nullptr; + return e && e->isEnsemble() ? e : nullptr; } //-------------------------------------------------------------------------------------------------- @@ -140,6 +132,14 @@ void RimSummaryCase::copyFrom(const RimSummaryCase& rhs) this->updateOptionSensitivity(); } +//-------------------------------------------------------------------------------------------------- +/// Sorting operator for sets and maps. Sorts by summary case short name. +//-------------------------------------------------------------------------------------------------- +bool RimSummaryCase::operator<(const RimSummaryCase& rhs) const +{ + return this->caseName() < rhs.caseName(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.h index 44d661febd..7aab31c7d8 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCase.h @@ -38,10 +38,10 @@ class RimSummaryCase : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimSummaryCase(); - virtual ~RimSummaryCase(); + ~RimSummaryCase() override; virtual QString summaryHeaderFilename() const; - virtual QString caseName() = 0; + virtual QString caseName() const = 0; QString shortName() const; void updateAutoShortName(); @@ -61,11 +61,11 @@ class RimSummaryCase : public caf::PdmObject std::shared_ptr caseRealizationParameters() const; bool hasCaseRealizationParameters() const; RimSummaryCaseCollection* ensemble() const; - bool isEnsembleCase() const; void copyFrom(const RimSummaryCase& rhs); + bool operator<(const RimSummaryCase& rhs) const; protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; void updateTreeItemName(); caf::PdmField m_shortName; @@ -76,5 +76,5 @@ class RimSummaryCase : public caf::PdmObject std::shared_ptr m_crlParameters; private: - virtual void initAfterRead() override; + void initAfterRead() override; }; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp index 6d962faaff..92345b2073 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.cpp @@ -18,6 +18,9 @@ #include "RimSummaryCaseCollection.h" +#include "RiaFieldHandleTools.h" + +#include "RimDerivedEnsembleCaseCollection.h" #include "RimEnsembleCurveSet.h" #include "RimGridSummaryCase.h" #include "RimProject.h" @@ -25,6 +28,12 @@ #include "RifSummaryReaderInterface.h" +#include +#include + +#include +#include + CAF_PDM_SOURCE_INIT(RimSummaryCaseCollection, "SummaryCaseSubCollection"); //-------------------------------------------------------------------------------------------------- @@ -41,11 +50,12 @@ RimSummaryCaseCollection::RimSummaryCaseCollection() CAF_PDM_InitFieldNoDefault(&m_nameAndItemCount, "NameCount", "Name", "", "", ""); m_nameAndItemCount.registerGetMethod(this, &RimSummaryCaseCollection::nameAndItemCount); - m_nameAndItemCount.uiCapability()->setUiHidden(true); - m_nameAndItemCount.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_nameAndItemCount); CAF_PDM_InitField(&m_isEnsemble, "IsEnsemble", false, "Is Ensemble", "", "", ""); m_isEnsemble.uiCapability()->setUiHidden(true); + + m_commonAddressCount = 0; } //-------------------------------------------------------------------------------------------------- @@ -53,7 +63,7 @@ RimSummaryCaseCollection::RimSummaryCaseCollection() //-------------------------------------------------------------------------------------------------- RimSummaryCaseCollection::~RimSummaryCaseCollection() { - m_cases.deleteAllChildObjects(); + m_cases.deleteAllChildObjectsAsync(); updateReferringCurveSets(); } @@ -62,23 +72,48 @@ RimSummaryCaseCollection::~RimSummaryCaseCollection() //-------------------------------------------------------------------------------------------------- void RimSummaryCaseCollection::removeCase(RimSummaryCase* summaryCase) { + size_t caseCountBeforeRemove = m_cases.size(); m_cases.removeChildObject(summaryCase); updateReferringCurveSets(); + + if (m_isEnsemble && m_cases.size() != caseCountBeforeRemove) + { + if(dynamic_cast(summaryCase) == nullptr) + calculateEnsembleParametersIntersectionHash(); + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryCaseCollection::addCase(RimSummaryCase* summaryCase) +void RimSummaryCaseCollection::addCase(RimSummaryCase* summaryCase, bool updateCurveSets) { m_cases.push_back(summaryCase); - updateReferringCurveSets(); + + // Update derived ensemble cases (if any) + std::vector referringObjects; + objectsWithReferringPtrFieldsOfType(referringObjects); + for (auto derEnsemble : referringObjects) + { + if (!derEnsemble) continue; + + derEnsemble->updateDerivedEnsembleCases(); + if (updateCurveSets) derEnsemble->updateReferringCurveSets(); + } + + if (m_isEnsemble) + { + validateEnsembleCases({ summaryCase }); + calculateEnsembleParametersIntersectionHash(); + } + + if(updateCurveSets) updateReferringCurveSets(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimSummaryCaseCollection::allSummaryCases() +std::vector RimSummaryCaseCollection::allSummaryCases() const { return m_cases.childObjects(); } @@ -112,31 +147,291 @@ bool RimSummaryCaseCollection::isEnsemble() const //-------------------------------------------------------------------------------------------------- void RimSummaryCaseCollection::setAsEnsemble(bool isEnsemble) { - m_isEnsemble = isEnsemble; - updateIcon(); + if (isEnsemble != m_isEnsemble) + { + m_isEnsemble = isEnsemble; + updateIcon(); + + if (m_isEnsemble && dynamic_cast(this) == nullptr) + { + validateEnsembleCases(allSummaryCases()); + calculateEnsembleParametersIntersectionHash(); + } + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::set RimSummaryCaseCollection::calculateUnionOfSummaryAddresses() const +std::set RimSummaryCaseCollection::ensembleSummaryAddresses() const { - std::set addressUnion; + std::set addresses; + size_t maxAddrCount = 0; + int maxAddrIndex = -1; - for (RimSummaryCase* currCase: m_cases) + for (int i = 0; i < (int)m_cases.size(); i++) { - if ( !currCase ) continue; - + RimSummaryCase* currCase = m_cases[i]; + if (!currCase) continue; + RifSummaryReaderInterface* reader = currCase->summaryReader(); + if (!reader) continue; + + size_t addrCount = reader->allResultAddresses().size(); + if (addrCount > maxAddrCount) + { + maxAddrCount = addrCount; + maxAddrIndex = (int)i; + } + } + + if (maxAddrIndex >= 0) + { + const std::set& addrs = m_cases[maxAddrIndex]->summaryReader()->allResultAddresses(); + addresses.insert(addrs.begin(), addrs.end()); + } + return addresses; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +EnsembleParameter RimSummaryCaseCollection::ensembleParameter(const QString& paramName) const +{ + if (!isEnsemble() || paramName.isEmpty()) return EnsembleParameter(); + + EnsembleParameter eParam; + eParam.name = paramName; + + bool numericValuesCount = 0; + bool textValuesCount = 0; - if ( !reader ) continue; + // Prepare case realization params, and check types + for (const auto& rimCase : allSummaryCases()) + { + auto crp = rimCase->caseRealizationParameters(); + if (!crp) continue; - const std::vector& readerAddresses = reader->allResultAddresses(); - addressUnion.insert(readerAddresses.begin(), readerAddresses.end()); + auto value = crp->parameterValue(paramName); + if (!value.isValid()) continue; + if (value.isNumeric()) + { + double numVal = value.numericValue(); + eParam.values.push_back(QVariant(numVal)); + if (numVal < eParam.minValue) eParam.minValue = numVal; + if (numVal > eParam.maxValue) eParam.maxValue = numVal; + numericValuesCount++; + } + else if (value.isText()) + { + eParam.values.push_back(QVariant(value.textValue())); + textValuesCount++; + } } - return addressUnion; + if (numericValuesCount && !textValuesCount) + { + eParam.type = EnsembleParameter::TYPE_NUMERIC; + } + else if (textValuesCount && !numericValuesCount) + { + eParam.type = EnsembleParameter::TYPE_TEXT; + } + if (numericValuesCount && textValuesCount) + { + // A mix of types have been added to parameter values + if (numericValuesCount > textValuesCount) + { + // Use numeric type + for (auto& val : eParam.values) + { + if (val.type() == QVariant::String) + { + val.setValue(std::numeric_limits::infinity()); + } + } + eParam.type = EnsembleParameter::TYPE_NUMERIC; + } + else + { + // Use text type + for (auto& val : eParam.values) + { + if (val.type() == QVariant::Double) + { + val.setValue(QString::number(val.value())); + } + } + eParam.type = EnsembleParameter::TYPE_TEXT; + eParam.minValue = std::numeric_limits::infinity(); + eParam.maxValue = -std::numeric_limits::infinity(); + } + } + + if (eParam.isText()) + { + // Remove duplicate texts + std::set valueSet; + for (const auto& val : eParam.values) + { + valueSet.insert(val.toString()); + } + eParam.values.clear(); + for (const auto& val : valueSet) + { + eParam.values.push_back(QVariant(val)); + } + } + return eParam; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryCaseCollection::calculateEnsembleParametersIntersectionHash() +{ + clearEnsembleParametersHashes(); + + // Find ensemble parameters intersection + std::set paramNames; + auto sumCases = allSummaryCases(); + + for (size_t i = 0; i < sumCases.size(); i++) + { + auto crp = sumCases[i]->caseRealizationParameters(); + if (!crp) continue; + + auto caseParamNames = crp->parameterNames(); + + if (i == 0) paramNames = caseParamNames; + else + { + std::set newIntersection; + std::set_intersection(paramNames.begin(), paramNames.end(), + caseParamNames.begin(), caseParamNames.end(), + std::inserter(newIntersection, newIntersection.end())); + + if(paramNames.size() != newIntersection.size()) paramNames = newIntersection; + } + } + + for (auto sumCase : sumCases) + { + auto crp = sumCase->caseRealizationParameters(); + if(crp) crp->calculateParametersHash(paramNames); + } + + // Find common addess count + for (const auto sumCase : sumCases) + { + const auto reader = sumCase->summaryReader(); + if(!reader) continue; + auto currAddrCount = reader->allResultAddresses().size(); + + if (m_commonAddressCount == 0) + { + m_commonAddressCount = currAddrCount; + } + else + { + if (currAddrCount != m_commonAddressCount) + { + m_commonAddressCount = 0; + break; + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryCaseCollection::clearEnsembleParametersHashes() +{ + for (auto sumCase : allSummaryCases()) + { + auto crp = sumCase->caseRealizationParameters(); + if (crp) crp->clearParametersHash(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryCaseCollection::loadDataAndUpdate() +{ + onLoadDataAndUpdate(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimSummaryCaseCollection::validateEnsembleCases(const std::vector cases) +{ + // Validate ensemble parameters + try + { + QString errors; + std::hash paramsHasher; + size_t paramsHash = 0; + + for (RimSummaryCase* rimCase : cases) + { + if (rimCase->caseRealizationParameters() == nullptr || rimCase->caseRealizationParameters()->parameters().empty()) + { + errors.append(QString("The case %1 has no ensemble parameters\n").arg(QFileInfo(rimCase->summaryHeaderFilename()).fileName())); + } + else + { + QString paramNames; + for (std::pair paramPair : rimCase->caseRealizationParameters()->parameters()) + { + paramNames.append(paramPair.first); + } + + size_t currHash = paramsHasher(paramNames.toStdString()); + if (paramsHash == 0) + { + paramsHash = currHash; + } + else if (paramsHash != currHash) + { + throw QString("Ensemble parameters differ between cases"); + } + } + } + + + if (!errors.isEmpty()) + { + errors.prepend("Missing ensemble parameters\n\n"); + + errors.append("\n"); + errors.append("No parameters file (parameters.txt or runspecification.xml) was found in \n"); + errors.append("the searched folders. ResInsight searches the home folder of the summary \n"); + errors.append("case file and the three folder levels above that.\n"); + + throw errors; + } + return true; + } + catch (QString errorMessage) + { + QMessageBox mbox; + mbox.setIcon(QMessageBox::Icon::Warning); + mbox.setText(errorMessage); + mbox.exec(); + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// Sorting operator for sets and maps. Sorts by name. +//-------------------------------------------------------------------------------------------------- +bool RimSummaryCaseCollection::operator<(const RimSummaryCaseCollection& rhs) const +{ + return name() < rhs.name(); } //-------------------------------------------------------------------------------------------------- @@ -147,18 +442,25 @@ caf::PdmFieldHandle* RimSummaryCaseCollection::userDescriptionField() return &m_name; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryCaseCollection::onLoadDataAndUpdate() +{ + if (m_isEnsemble) calculateEnsembleParametersIntersectionHash(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryCaseCollection::updateReferringCurveSets() const +void RimSummaryCaseCollection::updateReferringCurveSets() { // Update curve set referring to this group - std::vector referringObjects; - objectsWithReferringPtrFields(referringObjects); + std::vector referringObjects; + objectsWithReferringPtrFieldsOfType(referringObjects); - for (PdmObjectHandle* obj : referringObjects) + for (auto curveSet : referringObjects) { - RimEnsembleCurveSet* curveSet = dynamic_cast(obj); if (curveSet) curveSet->updateAllCurves(); } } @@ -204,3 +506,20 @@ void RimSummaryCaseCollection::fieldChangedByUi(const caf::PdmFieldHandle* chang updateIcon(); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryCaseCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) +{ + uiOrdering.add(&m_name); + uiOrdering.skipRemainingFields(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryCaseCollection::setNameAsReadOnly() +{ + m_name.uiCapability()->setUiReadOnly(true); +} diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.h index 7c35fa1b77..af6ac1aed6 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseCollection.h @@ -29,34 +29,77 @@ class RimSummaryCase; +//================================================================================================== +/// +//================================================================================================== +class EnsembleParameter +{ +public: + enum Type { TYPE_NONE, TYPE_NUMERIC, TYPE_TEXT }; + + QString name; + Type type; + std::vector values; + double minValue; + double maxValue; + + EnsembleParameter() : + type(TYPE_NONE), + minValue(std::numeric_limits::infinity()), + maxValue(-std::numeric_limits::infinity()) { } + + bool isValid() const { return !name.isEmpty() && type != TYPE_NONE; } + bool isNumeric() const { return type == TYPE_NUMERIC; } + bool isText() const { return type == TYPE_TEXT; } +}; + +//================================================================================================== +/// +//================================================================================================== class RimSummaryCaseCollection : public caf::PdmObject { CAF_PDM_HEADER_INIT; public: RimSummaryCaseCollection(); - virtual ~RimSummaryCaseCollection(); + ~RimSummaryCaseCollection() override; void removeCase(RimSummaryCase* summaryCase); - void addCase(RimSummaryCase* summaryCase); - std::vector allSummaryCases(); + void addCase(RimSummaryCase* summaryCase, bool updateCurveSets = true); + virtual std::vector allSummaryCases() const; void setName(const QString& name); QString name() const; bool isEnsemble() const; void setAsEnsemble(bool isEnsemble); - std::set calculateUnionOfSummaryAddresses() const; + virtual std::set ensembleSummaryAddresses() const; + EnsembleParameter ensembleParameter(const QString& paramName) const; + void calculateEnsembleParametersIntersectionHash(); + void clearEnsembleParametersHashes(); + + void loadDataAndUpdate(); + + static bool validateEnsembleCases(const std::vector cases); + bool operator<(const RimSummaryCaseCollection& rhs) const; private: caf::PdmFieldHandle* userDescriptionField() override; - void updateReferringCurveSets() const; QString nameAndItemCount() const; void updateIcon(); - virtual void initAfterRead() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void initAfterRead() override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + +protected: + virtual void onLoadDataAndUpdate(); + void updateReferringCurveSets(); + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void setNameAsReadOnly(); -private: caf::PdmChildArrayField m_cases; + +private: caf::PdmField m_name; caf::PdmProxyValueField m_nameAndItemCount; - caf::PdmField m_isEnsemble; + caf::PdmField m_isEnsemble; + + size_t m_commonAddressCount; // if different address count among cases, set to 0 }; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseMainCollection.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseMainCollection.cpp index 45b2a78c0c..8edfc58ce3 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseMainCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseMainCollection.cpp @@ -21,6 +21,7 @@ #include "RifSummaryCaseRestartSelector.h" #include "RifCaseRealizationParametersReader.h" +#include "RimDerivedEnsembleCaseCollection.h" #include "RimEclipseResultCase.h" #include "RimFileSummaryCase.h" #include "RimGridSummaryCase.h" @@ -43,15 +44,17 @@ void addCaseRealizationParametersIfFound(RimSummaryCase& sumCase, const QString QString parametersFile = RifCaseRealizationParametersFileLocator::locate(modelFolderOrFile); if (!parametersFile.isEmpty()) { - RifCaseRealizationParametersReader reader(parametersFile); - - // Try parse case realization parameters - try + auto reader = RifCaseRealizationReader::createReaderFromFileName(parametersFile); + if (reader) { - reader.parse(); - sumCase.setCaseRealizationParameters(reader.parameters()); + // Try parse case realization parameters + try + { + reader->parse(); + sumCase.setCaseRealizationParameters(reader->parameters()); + } + catch (...) {} } - catch (...) {} } } @@ -75,14 +78,14 @@ RimSummaryCaseMainCollection::RimSummaryCaseMainCollection() //-------------------------------------------------------------------------------------------------- RimSummaryCaseMainCollection::~RimSummaryCaseMainCollection() { - m_cases.deleteAllChildObjects(); - m_caseCollections.deleteAllChildObjects(); + m_cases.deleteAllChildObjectsAsync(); + m_caseCollections.deleteAllChildObjectsAsync(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimSummaryCase* RimSummaryCaseMainCollection::findSummaryCaseFromEclipseResultCase(RimEclipseResultCase* eclipseResultCase) const +RimSummaryCase* RimSummaryCaseMainCollection::findSummaryCaseFromEclipseResultCase(const RimEclipseResultCase* eclipseResultCase) const { for (RimSummaryCase* summaryCase : m_cases) { @@ -201,21 +204,44 @@ void RimSummaryCaseMainCollection::addCase(RimSummaryCase* summaryCase) //-------------------------------------------------------------------------------------------------- void RimSummaryCaseMainCollection::removeCase(RimSummaryCase* summaryCase) { + std::vector derivedEnsembles; + + // Build a list of derived ensembles that must be updated after delete + for (auto group : summaryCaseCollections()) + { + auto derEnsemble = dynamic_cast(group); + if (derEnsemble) + { + if (derEnsemble->hasCaseReference(summaryCase)) + { + derivedEnsembles.push_back(derEnsemble); + } + } + } + m_cases.removeChildObject(summaryCase); for (RimSummaryCaseCollection* summaryCaseCollection : m_caseCollections) { summaryCaseCollection->removeCase(summaryCase); } + + // Update derived ensemble cases (if any) + for (auto derEnsemble : derivedEnsembles) + { + derEnsemble->updateDerivedEnsembleCases(); + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryCaseMainCollection::addCaseCollection(std::vector summaryCases, const QString& collectionName, bool isEnsemble) +RimSummaryCaseCollection* RimSummaryCaseMainCollection::addCaseCollection(std::vector summaryCases, + const QString& collectionName, + bool isEnsemble, + std::function allocator) { - RimSummaryCaseCollection* summaryCaseCollection = new RimSummaryCaseCollection(); + RimSummaryCaseCollection* summaryCaseCollection = allocator(); if(!collectionName.isEmpty()) summaryCaseCollection->setName(collectionName); - summaryCaseCollection->setAsEnsemble(isEnsemble); for (RimSummaryCase* summaryCase : summaryCases) { @@ -234,7 +260,11 @@ void RimSummaryCaseMainCollection::addCaseCollection(std::vectoraddCase(summaryCase); } + summaryCaseCollection->setAsEnsemble(isEnsemble); + m_caseCollections.push_back(summaryCaseCollection); + + return summaryCaseCollection; } //-------------------------------------------------------------------------------------------------- @@ -333,11 +363,9 @@ void RimSummaryCaseMainCollection::loadSummaryCaseData(std::vector RimSummaryCaseMainCollection::createAndAddSummaryCasesFromFileInfos(const std::vector& summaryHeaderFileInfos) +RimSummaryCaseCollection* RimSummaryCaseMainCollection::defaultAllocator() { - std::vector newCases = createSummaryCasesFromFileInfos(summaryHeaderFileInfos); - addCases(newCases); - return newCases; + return new RimSummaryCaseCollection(); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseMainCollection.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseMainCollection.h index 45f837edd8..4254207fe1 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseMainCollection.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCaseMainCollection.h @@ -21,6 +21,7 @@ #include "cafPdmObject.h" #include +#include class RimGridSummaryCase; class RimSummaryCase; @@ -36,7 +37,7 @@ class RimSummaryCaseMainCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimSummaryCaseMainCollection(); - virtual ~RimSummaryCaseMainCollection(); + ~RimSummaryCaseMainCollection() override; RimSummaryCase* summaryCase(size_t idx); size_t summaryCaseCount() const; @@ -45,10 +46,9 @@ class RimSummaryCaseMainCollection : public caf::PdmObject std::vector topLevelSummaryCases() const; std::vector summaryCaseCollections() const; - std::vector createAndAddSummaryCasesFromFileInfos(const std::vector& summaryHeaderFileInfos); std::vector createSummaryCasesFromFileInfos(const std::vector& summaryHeaderFileInfos, bool showProgress = false); - RimSummaryCase* findSummaryCaseFromEclipseResultCase(RimEclipseResultCase* eclResCase) const; + RimSummaryCase* findSummaryCaseFromEclipseResultCase(const RimEclipseResultCase* eclResCase) const; RimSummaryCase* findSummaryCaseFromFileName(const QString& fileName) const; void convertGridSummaryCasesToFileSummaryCases(RimGridSummaryCase* gridSummaryCase); @@ -56,7 +56,10 @@ class RimSummaryCaseMainCollection : public caf::PdmObject void addCase(RimSummaryCase* summaryCase); void removeCase(RimSummaryCase* summaryCase); - void addCaseCollection(std::vector summaryCases, const QString& coolectionName, bool isEnsemble); + RimSummaryCaseCollection* addCaseCollection(std::vector summaryCases, + const QString& coolectionName, + bool isEnsemble, + std::function allocator = defaultAllocator); void removeCaseCollection(RimSummaryCaseCollection* caseCollection); void loadAllSummaryCaseData(); @@ -67,6 +70,7 @@ class RimSummaryCaseMainCollection : public caf::PdmObject private: static void loadSummaryCaseData(std::vector summaryCases); + static RimSummaryCaseCollection* defaultAllocator(); private: caf::PdmChildArrayField m_cases; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCrossPlotCollection.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCrossPlotCollection.h index 472802f90d..1e99120791 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCrossPlotCollection.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCrossPlotCollection.h @@ -32,7 +32,7 @@ class RimSummaryCrossPlotCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimSummaryCrossPlotCollection(); - virtual ~RimSummaryCrossPlotCollection(); + ~RimSummaryCrossPlotCollection() override; void deleteAllChildObjects(); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp index fd52dbec7b..3f06e82ace 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.cpp @@ -23,13 +23,16 @@ #include "RifReaderEclipseSummary.h" -#include "RigTimeHistoryCurveMerger.h" +#include "RiaTimeHistoryCurveMerger.h" #include "RimEclipseResultCase.h" +#include "RimEnsembleCurveSet.h" +#include "RimEnsembleCurveSetCollection.h" #include "RimProject.h" #include "RimSummaryAddress.h" #include "RimSummaryCalculationCollection.h" #include "RimSummaryCase.h" +#include "RimSummaryCaseCollection.h" #include "RimSummaryCrossPlot.h" #include "RimSummaryCurveAutoName.h" #include "RimSummaryCurveCollection.h" @@ -39,7 +42,7 @@ #include "RimSummaryTimeAxisProperties.h" #include "RimTools.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuPlotMainWindow.h" #include "RiuSummaryCurveDefSelectionDialog.h" #include "RiuSummaryQwtPlot.h" @@ -155,6 +158,11 @@ RimSummaryCurve::~RimSummaryCurve() //-------------------------------------------------------------------------------------------------- void RimSummaryCurve::setSummaryCaseY(RimSummaryCase* sumCase) { + if (m_yValuesSummaryCase != sumCase) + { + m_qwtPlotCurve->clearErrorBars(); + } + m_yValuesSummaryCase = sumCase; } @@ -197,6 +205,11 @@ RifEclipseSummaryAddress RimSummaryCurve::summaryAddressY() const //-------------------------------------------------------------------------------------------------- void RimSummaryCurve::setSummaryAddressY(const RifEclipseSummaryAddress& address) { + if (m_yValuesCurveVariable->address() != address) + { + m_qwtPlotCurve->clearErrorBars(); + } + m_yValuesCurveVariable->setAddress(address); m_yValuesSummaryFilter->updateFromAddress(address); @@ -243,6 +256,33 @@ std::vector RimSummaryCurve::valuesY() const return values; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RimSummaryCurve::errorSummaryAddressY() const +{ + auto addr = summaryAddressY(); + addr.setAsErrorResult(); + return addr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimSummaryCurve::errorValuesY() const +{ + std::vector values; + + RifSummaryReaderInterface* reader = valuesSummaryReaderY(); + + if (!reader) return values; + + RifEclipseSummaryAddress addr = errorSummaryAddressY(); + reader->values(addr, &values); + + return values; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -433,7 +473,7 @@ void RimSummaryCurve::onLoadDataAndUpdate(bool updateParentPlot) } else { - RigTimeHistoryCurveMerger curveMerger; + RiaTimeHistoryCurveMerger curveMerger; curveMerger.addCurveData(curveValuesX, curveTimeStepsX); curveMerger.addCurveData(curveValuesY, curveTimeStepsY); curveMerger.computeInterpolatedValues(); @@ -457,7 +497,18 @@ void RimSummaryCurve::onLoadDataAndUpdate(bool updateParentPlot) { if (plot->timeAxisProperties()->timeMode() == RimSummaryTimeAxisProperties::DATE) { - m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, isLogCurve); + auto reader = summaryCaseY()->summaryReader(); + auto errAddress = reader->errorAddress(summaryAddressY()); + if (errAddress.isValid()) + { + std::vector errValues; + reader->values(errAddress, &errValues); + m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, errValues, isLogCurve); + } + else + { + m_qwtPlotCurve->setSamplesFromTimeTAndYValues(curveTimeStepsY, curveValuesY, isLogCurve); + } } else { @@ -492,11 +543,23 @@ void RimSummaryCurve::onLoadDataAndUpdate(bool updateParentPlot) updateZoomInParentPlot(); m_parentQwtPlot->replot(); } + + m_qwtPlotCurve->showErrorBars(m_showErrorBars); } if (updateParentPlot) updateQwtPlotAxis(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryCurve::updateLegendsInPlot() +{ + RimSummaryPlot* plot = nullptr; + firstAncestorOrThisOfTypeAsserted(plot); + plot->updateAllLegendItems(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -535,6 +598,8 @@ void RimSummaryCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& m_yValuesSummaryFilter->uiOrdering(uiConfigName, *curveVarSelectionGroup); curveVarSelectionGroup->add(&m_yValuesUiFilterResultSelection); + if (isCrossPlotCurve()) m_showErrorBars = false; + else curveDataGroup->add(&m_showErrorBars); } if (isCrossPlotCurve()) @@ -578,10 +643,11 @@ void RimSummaryCurve::appendOptionItemsForSummaryAddresses(QListsummaryReader(); if (reader) { - const std::vector allAddresses = reader->allResultAddresses(); + const std::set allAddresses = reader->allResultAddresses(); for (auto& address : allAddresses) { + if (address.isErrorResult()) continue; if (summaryFilter && !summaryFilter->isIncludedByFilter(address)) continue; std::string name = address.uiText(); @@ -594,18 +660,6 @@ void RimSummaryCurve::appendOptionItemsForSummaryAddresses(QListfirstAncestorOrThisOfType(crossPlot); - if (crossPlot) return true; - - return false; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -632,6 +686,67 @@ void RimSummaryCurve::applyCurveAutoNameSettings(const RimSummaryCurveAutoName& m_curveNameConfig->applySettings(autoNameSettings); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimSummaryCurve::curveExportDescription(const RifEclipseSummaryAddress& address) const +{ + auto addr = address.isValid() ? address : m_yValuesCurveVariable->address(); + + RimEnsembleCurveSetCollection* coll; + firstAncestorOrThisOfType(coll); + + auto curveSet = coll ? coll->findRimCurveSetFromQwtCurve(m_qwtPlotCurve) : nullptr; + auto group = curveSet ? curveSet->summaryCaseCollection() : nullptr; + + if (group && group->isEnsemble()) + { + return QString("%1.%2.%3") + .arg(QString::fromStdString(addr.uiText())) + .arg(m_yValuesSummaryCase->caseName()) + .arg(group->name()); + } + else + { + return QString("%1.%2") + .arg(QString::fromStdString(addr.uiText())) + .arg(m_yValuesSummaryCase->caseName()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryCurve::forceUpdateCurveAppearanceFromCaseType() +{ + if (m_yValuesSummaryCase) + { + if (m_yValuesSummaryCase->isObservedData()) + { + setLineStyle(RiuQwtPlotCurve::STYLE_NONE); + + if (symbol() == RiuQwtSymbol::SYMBOL_NONE) + { + setSymbol(RiuQwtSymbol::SYMBOL_XCROSS); + } + } + else + { + setLineStyle(RiuQwtPlotCurve::STYLE_SOLID); + setSymbol(RiuQwtSymbol::SYMBOL_NONE); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryCurve::markCachedDataForPurge() +{ + auto reader = valuesSummaryReaderY(); + if(reader) reader->markForCachePurge(m_yValuesCurveVariable->address()); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -679,6 +794,13 @@ void RimSummaryCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, } else if (changedField == &m_yValuesSummaryCase) { + PdmObjectHandle* oldVal = oldValue.value>().rawPtr(); + if (oldVal == nullptr && m_yValuesSummaryCase->isObservedData()) + { + // If no previous case selected and observed data, use symbols to indicate observed data curve + setLineStyle(RiuQwtPlotCurve::STYLE_NONE); + setSymbol(RiuQwtSymbol::SYMBOL_XCROSS); + } plot->updateCaseNameHasChanged(); this->onLoadDataAndUpdate(true); } @@ -761,7 +883,7 @@ void RimSummaryCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, if (!curveValuesX.empty() && !curveValuesY.empty()) { - RigTimeHistoryCurveMerger curveMerger; + RiaTimeHistoryCurveMerger curveMerger; curveMerger.addCurveData(curveValuesX, curveTimeStepsX); curveMerger.addCurveData(curveValuesY, curveTimeStepsY); curveMerger.computeInterpolatedValues(); @@ -879,14 +1001,14 @@ void RimSummaryCurve::calculateCurveInterpolationFromAddress() { if (m_yValuesCurveVariable()) { - QString quantityName = QString::fromUtf8(m_yValuesCurveVariable()->address().quantityName().c_str()); - if (quantityName.endsWith("T")) + auto address = m_yValuesCurveVariable()->address(); + if (address.hasAccumulatedData()) { - m_curveInterpolation = INTERPOLATION_POINT_TO_POINT; + m_curveInterpolation = RiuQwtPlotCurve::INTERPOLATION_POINT_TO_POINT; } else { - m_curveInterpolation = INTERPOLATION_STEP_LEFT; + m_curveInterpolation = RiuQwtPlotCurve::INTERPOLATION_STEP_LEFT; } } } diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.h index 43a745edd8..7ae8d0ea0a 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurve.h @@ -34,7 +34,7 @@ class RifSummaryReaderInterface; class RimSummaryCase; class RimSummaryFilter; -class RiuLineSegmentQwtPlotCurve; +class RiuQwtPlotCurve; class RimSummaryCurveAutoName; class RimSummaryAddress; @@ -49,7 +49,7 @@ class RimSummaryCurve : public RimPlotCurve public: RimSummaryCurve(); - virtual ~RimSummaryCurve(); + ~RimSummaryCurve() override; // Y Axis functions void setSummaryCaseY(RimSummaryCase* sumCase); @@ -58,6 +58,8 @@ class RimSummaryCurve : public RimPlotCurve RifEclipseSummaryAddress summaryAddressY() const; std::string unitNameY() const; std::vector valuesY() const; + RifEclipseSummaryAddress errorSummaryAddressY() const; + std::vector errorValuesY() const; void setLeftOrRightAxisY(RiaDefines::PlotAxis plotAxis); RiaDefines::PlotAxis axisY() const; const std::vector& timeStepsY() const; @@ -74,11 +76,19 @@ class RimSummaryCurve : public RimPlotCurve void updateQwtPlotAxis(); void applyCurveAutoNameSettings(const RimSummaryCurveAutoName& autoNameSettings); + QString curveExportDescription(const RifEclipseSummaryAddress& address = RifEclipseSummaryAddress()) const override; + void forceUpdateCurveAppearanceFromCaseType(); + + void markCachedDataForPurge(); + protected: // RimPlotCurve overrides - virtual QString createCurveAutoName() override; - virtual void updateZoomInParentPlot() override; - virtual void onLoadDataAndUpdate(bool updateParentPlot) override; + QString createCurveAutoName() override; + void updateZoomInParentPlot() override; + void onLoadDataAndUpdate(bool updateParentPlot) override; + + + void updateLegendsInPlot() override; private: RifSummaryReaderInterface* valuesSummaryReaderX() const; @@ -88,17 +98,15 @@ class RimSummaryCurve : public RimPlotCurve void calculateCurveInterpolationFromAddress(); // Overridden PDM methods - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + QList 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; static void appendOptionItemsForSummaryAddresses(QList* options, RimSummaryCase* summaryCase, RimSummaryFilter* summaryFilter); - bool isCrossPlotCurve() const; - private: // Y values caf::PdmPtrField m_yValuesSummaryCase; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp index e28dcbcc22..270c76b6e2 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.cpp @@ -20,6 +20,7 @@ #include "RiaColorTables.h" #include "RiaSummaryCurveDefinition.h" +#include "RiuQwtPlotCurve.h" #include "RimSummaryCurve.h" #include "RimSummaryCase.h" @@ -152,7 +153,6 @@ void RimSummaryCurveAppearanceCalculator::updateApperanceIndices() { { std::map caseAppearanceIndices = mapNameToAppearanceIndex(m_caseAppearanceType, m_allSummaryCaseNames); - int idx = 0; for (auto& pair : m_caseToAppearanceIdxMap) { pair.second = static_cast(caseAppearanceIndices[pair.first->summaryHeaderFilename().toUtf8().constData()]); @@ -160,7 +160,6 @@ void RimSummaryCurveAppearanceCalculator::updateApperanceIndices() } { std::map wellAppearanceIndices = mapNameToAppearanceIndex(m_wellAppearanceType, m_allSummaryWellNames); - int idx = 0; for (auto& pair : m_welToAppearanceIdxMap) { pair.second = static_cast(wellAppearanceIndices[pair.first]); @@ -191,11 +190,11 @@ std::map RimSummaryCurveAppearanceCalculator::mapNameToAppe } else if (appearance == CurveAppearanceType::SYMBOL) { - numOptions = caf::AppEnum::size() - 1; // -1 since the No symbol option is not counted see cycledSymbol() + numOptions = caf::AppEnum::size() - 1; // -1 since the No symbol option is not counted see cycledSymbol() } else if (appearance == CurveAppearanceType::LINE_STYLE) { - numOptions = caf::AppEnum::size() - 1; // -1 since the No symbol option is not counted see cycledLineStyle() + numOptions = caf::AppEnum::size() - 1; // -1 since the No symbol option is not counted see cycledLineStyle() } else { // If none of these styles are used, fall back to a simply incrementing index @@ -355,12 +354,7 @@ void RimSummaryCurveAppearanceCalculator::setupCurveLook(RimSummaryCurve* curve) if ( curve->summaryCaseY()->isObservedData() ) { - curve->setLineStyle(RimPlotCurve::STYLE_NONE); - - if ( curve->symbol() == RimPlotCurve::SYMBOL_NONE ) - { - curve->setSymbol(RimPlotCurve::SYMBOL_XCROSS); - } + curve->forceUpdateCurveAppearanceFromCaseType(); } } @@ -457,21 +451,21 @@ cvf::Color3f RimSummaryCurveAppearanceCalculator::cycledBrownColor(int colorInde //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimPlotCurve::LineStyleEnum RimSummaryCurveAppearanceCalculator::cycledLineStyle(int index) +RiuQwtPlotCurve::LineStyleEnum RimSummaryCurveAppearanceCalculator::cycledLineStyle(int index) { - if (index < 0) return RimPlotCurve::STYLE_SOLID; + if (index < 0) return RiuQwtPlotCurve::STYLE_SOLID; - return caf::AppEnum::fromIndex(1 + (index % (caf::AppEnum::size() - 1))); + return caf::AppEnum::fromIndex(1 + (index % (caf::AppEnum::size() - 1))); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimPlotCurve::PointSymbolEnum RimSummaryCurveAppearanceCalculator::cycledSymbol(int index) +RiuQwtSymbol::PointSymbolEnum RimSummaryCurveAppearanceCalculator::cycledSymbol(int index) { - if (index < 0) return RimPlotCurve::SYMBOL_NONE; + if (index < 0) return RiuQwtSymbol::SYMBOL_NONE; - return caf::AppEnum::fromIndex(1 + (index % (caf::AppEnum::size() - 1))); + return caf::AppEnum::fromIndex(1 + (index % (caf::AppEnum::size() - 1))); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h index 0980661538..0b5ff28430 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAppearanceCalculator.h @@ -64,7 +64,7 @@ class RimSummaryCurveAppearanceCalculator static cvf::Color3f cycledBlueColor(int colorIndex); static cvf::Color3f cycledRedColor(int colorIndex); static cvf::Color3f cycledBrownColor(int colorIndex); - static RimPlotCurve::PointSymbolEnum cycledSymbol(int index); + static RiuQwtSymbol::PointSymbolEnum cycledSymbol(int index); private: template @@ -74,7 +74,7 @@ class RimSummaryCurveAppearanceCalculator std::map mapNameToAppearanceIndex(CurveAppearanceType & appearance, const std::set& names); - RimPlotCurve::LineStyleEnum cycledLineStyle(int index); + RiuQwtPlotCurve::LineStyleEnum cycledLineStyle(int index); int cycledLineThickness(int index); float gradient(size_t totalCount, int index); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp index 8a84b18399..ea8bb162fe 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.cpp @@ -18,6 +18,8 @@ #include "RimSummaryCurveAutoName.h" +#include "RiaStatisticsTools.h" + #include "RifEclipseSummaryAddress.h" #include "RimEnsembleCurveSet.h" @@ -73,6 +75,11 @@ QString RimSummaryCurveAutoName::curveNameY(const RifEclipseSummaryAddress& summ { text += summaryAddress.quantityName(); + if (summaryAddress.category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) + { + text = RiaStatisticsTools::replacePercentileByPValueText(QString::fromStdString(text)).toStdString(); + } + if (m_unit && summaryCurve && !summaryCurve->unitNameY().empty()) { text += "[" + summaryCurve->unitNameY() + "]"; @@ -141,17 +148,14 @@ QString RimSummaryCurveAutoName::curveNameX(const RifEclipseSummaryAddress& summ if (summaryCurve && summaryCurve->summaryCaseX()) { - QString caseName = summaryCurve->summaryCaseX()->caseName(); - bool skipSubString = nameHelper && nameHelper->isCaseInTitle(); if (m_caseName && !skipSubString) { - if (summaryCurve && summaryCurve->summaryCaseX()) - { - if (!text.empty()) text += ", "; - text += caseName.toStdString(); - } + QString caseName = summaryCurve->summaryCaseX()->caseName(); + + if (!text.empty()) text += ", "; + text += caseName.toStdString(); } } @@ -301,7 +305,7 @@ void RimSummaryCurveAutoName::appendAddressDetails(std::string& if (m_wellSegmentNumber) { if (!text.empty()) text += ":"; - text += ":" + summaryAddress.wellSegmentNumber(); + text += std::to_string(summaryAddress.wellSegmentNumber()); } } break; @@ -343,7 +347,7 @@ void RimSummaryCurveAutoName::fieldChangedByUi(const caf::PdmFieldHandle* change RimSummaryCurve* summaryCurve = dynamic_cast(this->parentField()->ownerObject()); if (summaryCurve) { - summaryCurve->updateCurveNameAndUpdatePlotLegend(); + summaryCurve->updateCurveNameAndUpdatePlotLegendAndTitle(); summaryCurve->updateConnectedEditors(); return; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.h index 8397aa9569..8867f06e1d 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveAutoName.h @@ -39,9 +39,9 @@ class RimSummaryCurveAutoName : public caf::PdmObject private: friend class RimSummaryCurve; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; void appendAddressDetails(std::string& text, const RifEclipseSummaryAddress& summaryAddress, const RimSummaryPlotNameHelper* nameHelper) const; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp index 42ec50d008..c218bb1159 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveCollection.cpp @@ -29,7 +29,7 @@ #include "RimSummaryPlot.h" #include "RimSummaryPlotSourceStepping.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuSummaryQwtPlot.h" #include "cafPdmUiTreeViewEditor.h" @@ -105,13 +105,7 @@ void RimSummaryCurveCollection::loadDataAndUpdate(bool updateParentPlot) { RimSummaryPlot* parentPlot; firstAncestorOrThisOfTypeAsserted(parentPlot); - if ( parentPlot->qwtPlot() ) - { - parentPlot->updatePlotTitle(); - parentPlot->qwtPlot()->updateLegend(); - parentPlot->updateAxes(); - parentPlot->updateZoomInQwt(); - } + parentPlot->updateAll(); } } @@ -139,6 +133,17 @@ void RimSummaryCurveCollection::detachQwtCurves() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryCurveCollection::reattachQwtCurves() +{ + for (RimSummaryCurve* curve : m_curves) + { + curve->reattachQwtCurve(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -174,8 +179,8 @@ void RimSummaryCurveCollection::deleteCurve(RimSummaryCurve* curve) if (curve) { m_curves.removeChildObject(curve); + curve->markCachedDataForPurge(); delete curve; - updateCaseNameHasChanged(); } } @@ -371,7 +376,7 @@ void RimSummaryCurveCollection::defineUiOrdering(QString uiConfigName, caf::PdmU } else { - auto group = uiOrdering.addNewGroup("Plot Source Stepping"); + auto group = uiOrdering.addNewGroup("Data Source"); m_ySourceStepping()->uiOrdering(uiConfigName, *group); } diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveCollection.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveCollection.h index a1c2fd89ec..66539de4be 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveCollection.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveCollection.h @@ -41,13 +41,14 @@ class RimSummaryCurveCollection : public caf::PdmObject public: RimSummaryCurveCollection(); - virtual ~RimSummaryCurveCollection(); + ~RimSummaryCurveCollection() override; bool isCurvesVisible(); void loadDataAndUpdate(bool updateParentPlot); void setParentQwtPlotAndReplot(QwtPlot* plot); void detachQwtCurves(); + void reattachQwtCurves(); RimSummaryCurve* findRimCurveFromQwtCurve(const QwtPlotCurve* qwtCurve) const; @@ -67,13 +68,13 @@ class RimSummaryCurveCollection : public caf::PdmObject void handleKeyPressEvent(QKeyEvent* keyEvent); private: - caf::PdmFieldHandle* objectToggleField(); - virtual void defineObjectEditorAttribute(QString uiConfigName, + caf::PdmFieldHandle* objectToggleField() override; + void defineObjectEditorAttribute(QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveFilter.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveFilter.cpp index dbce0f9190..624894a642 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveFilter.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveFilter.cpp @@ -53,8 +53,7 @@ RimSummaryCurveFilter_OBSOLETE::RimSummaryCurveFilter_OBSOLETE() m_selectedSummaryCases.uiCapability()->setUiTreeChildrenHidden(true); m_selectedSummaryCases.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); m_selectedSummaryCases.uiCapability()->setAutoAddingOptionFromValue(false); - m_selectedSummaryCases.xmlCapability()->setIOWritable(false); - m_selectedSummaryCases.xmlCapability()->setIOReadable(false); + m_selectedSummaryCases.xmlCapability()->disableIO(); m_selectedSummaryCases.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); CAF_PDM_InitFieldNoDefault(&m_summaryFilter, "VarListFilter", "Filter", "", "", ""); @@ -64,8 +63,7 @@ RimSummaryCurveFilter_OBSOLETE::RimSummaryCurveFilter_OBSOLETE() m_summaryFilter = new RimSummaryFilter; CAF_PDM_InitFieldNoDefault(&m_uiFilterResultMultiSelection, "FilterResultSelection", "Filter Result", "", "Ctrl-A : Select All", ""); - m_uiFilterResultMultiSelection.xmlCapability()->setIOWritable(false); - m_uiFilterResultMultiSelection.xmlCapability()->setIOReadable(false); + m_uiFilterResultMultiSelection.xmlCapability()->disableIO(); m_uiFilterResultMultiSelection.uiCapability()->setUiEditorTypeName(caf::PdmUiListEditor::uiEditorTypeName()); m_uiFilterResultMultiSelection.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); m_uiFilterResultMultiSelection.uiCapability()->setAutoAddingOptionFromValue(false); @@ -75,8 +73,7 @@ RimSummaryCurveFilter_OBSOLETE::RimSummaryCurveFilter_OBSOLETE() m_curves.uiCapability()->setUiTreeChildrenHidden(false); CAF_PDM_InitFieldNoDefault(&m_applyButtonField, "ApplySelection", "", "", "", ""); - m_applyButtonField.xmlCapability()->setIOWritable(false); - m_applyButtonField.xmlCapability()->setIOReadable(false); + m_applyButtonField.xmlCapability()->disableIO(); m_applyButtonField = false; m_applyButtonField.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName()); m_applyButtonField.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::LEFT); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveFilter.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveFilter.h index 78de78bbd3..edd01a75ec 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveFilter.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurveFilter.h @@ -46,7 +46,7 @@ class RimSummaryCurveFilter_OBSOLETE : public caf::PdmObject public: RimSummaryCurveFilter_OBSOLETE(); - virtual ~RimSummaryCurveFilter_OBSOLETE(); + ~RimSummaryCurveFilter_OBSOLETE() override; std::vector curves(); void clearCurvesWithoutDelete(); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurvesCalculator.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurvesCalculator.cpp index 19f1259b38..6d68260a3e 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurvesCalculator.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryCurvesCalculator.cpp @@ -53,7 +53,7 @@ class DecimalScaleDraw : public QwtScaleDraw m_numberOfDecimals = numberOfDecimals; } - virtual QwtText label(double value) const override + QwtText label(double value) const override { if (qFuzzyCompare(scaledValue(value) + 1.0, 1.0)) value = 0.0; @@ -83,7 +83,7 @@ class ScientificScaleDraw : public QwtScaleDraw m_numberOfDecimals = numberOfDecimals; } - virtual QwtText label(double value) const override + QwtText label(double value) const override { if (qFuzzyCompare(scaledValue(value) + 1.0, 1.0)) value = 0.0; @@ -208,7 +208,11 @@ QString RimSummaryPlotYAxisFormatter::autoAxisTitle() const RifEclipseSummaryAddress sumAddress; std::string unitText; - if (m_axisProperties->plotAxisType() == RiaDefines::PLOT_AXIS_BOTTOM) + if (rimCurve->summaryAddressY().category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) + { + continue; + } + else if (m_axisProperties->plotAxisType() == RiaDefines::PLOT_AXIS_BOTTOM) { sumAddress = rimCurve->summaryAddressX(); unitText = rimCurve->unitNameX(); @@ -235,7 +239,7 @@ QString RimSummaryPlotYAxisFormatter::autoAxisTitle() const { if (m_axisProperties->showDescription()) { - quantityNameForDisplay = RiuSummaryVectorDescriptionMap::instance()->fieldInfo(quantityName); + quantityNameForDisplay = RiuSummaryVectorDescriptionMap::instance()->vectorLongName(quantityName, true); } if (m_axisProperties->showAcronym()) diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryFilter.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryFilter.cpp index dfaa93805c..2ae8ad6411 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryFilter.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryFilter.cpp @@ -357,8 +357,6 @@ void RimSummaryFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering { uiOrdering.add(&m_filterType); - caf::PdmUiGroup* curveVarFilterGroup = nullptr; - if(m_filterType() == SUM_FILTER_VAR_STRING) { uiOrdering.add(&m_completeVarStringFilter); @@ -463,12 +461,3 @@ void RimSummaryFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedField, } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimSummaryFilter::setCompleteVarStringFilter(const QString& stringFilter) -{ - m_filterType = SUM_FILTER_VAR_STRING; - m_completeVarStringFilter = stringFilter; -} - diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryFilter.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryFilter.h index aa31b65516..bd974ce444 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryFilter.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryFilter.h @@ -49,21 +49,20 @@ class RimSummaryFilter: public caf::PdmObject }; RimSummaryFilter(); - virtual ~RimSummaryFilter(); + ~RimSummaryFilter() override; void updateFromAddress(const RifEclipseSummaryAddress& address); - void setCompleteVarStringFilter(const QString& stringFilter); bool isIncludedByFilter(const RifEclipseSummaryAddress& addr) const; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; private: friend class RimSummaryCurve; static bool isSumVarTypeMatchingFilterType(SummaryFilterType sumFilterType, RifEclipseSummaryAddress::SummaryVarCategory sumVarType); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; private: caf::PdmField > diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryObservedDataFile.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryObservedDataFile.cpp index cfe28fde9e..7d6f49064c 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryObservedDataFile.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryObservedDataFile.cpp @@ -43,17 +43,6 @@ RimSummaryObservedDataFile::~RimSummaryObservedDataFile() } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimSummaryObservedDataFile::setSummaryHeaderFilename(const QString& fileName) -{ - m_summaryHeaderFilename = fileName; - - this->updateAutoShortName(); - this->updateTreeItemName(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryObservedDataFile.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryObservedDataFile.h index 26113c8b68..a2b8e6136b 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryObservedDataFile.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryObservedDataFile.h @@ -34,12 +34,10 @@ class RimSummaryObservedDataFile : public RimObservedData CAF_PDM_HEADER_INIT; public: RimSummaryObservedDataFile(); - virtual ~RimSummaryObservedDataFile(); + ~RimSummaryObservedDataFile() override; - void setSummaryHeaderFilename(const QString& fileName); - - virtual void createSummaryReaderInterface() override; - virtual RifSummaryReaderInterface* summaryReader() override; + void createSummaryReaderInterface() override; + RifSummaryReaderInterface* summaryReader() override; private: cvf::ref m_summaryReader; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index 6947a80619..8908b83320 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -19,7 +19,9 @@ #include "RimSummaryPlot.h" #include "RiaApplication.h" +#include "RiaFieldHandleTools.h" #include "RiaSummaryCurveAnalyzer.h" +#include "RiaTimeHistoryCurveResampler.h" #include "SummaryPlotCommands/RicSummaryCurveCreator.h" @@ -51,16 +53,71 @@ #include "qwt_legend.h" #include "qwt_plot_curve.h" #include "qwt_plot_renderer.h" +#include "qwt_plot_textlabel.h" #include #include #include #include - +#include +#include CAF_PDM_SOURCE_INIT(RimSummaryPlot, "SummaryPlot"); +//-------------------------------------------------------------------------------------------------- +/// Internal types +//-------------------------------------------------------------------------------------------------- +enum class ResampleAlgorithm +{ + NONE, + DATA_DECIDES, + PERIOD_END +}; + +struct CurveData +{ + QString name; + RifEclipseSummaryAddress address; + std::vector values; +}; + +class CurvesData +{ +public: + CurvesData() : resamplePeriod(DateTimePeriod::NONE) {} + void clear() + { + resamplePeriod = DateTimePeriod::NONE; + caseNames.clear(); + timeSteps.clear(); + allCurveData.clear(); + } + + DateTimePeriod resamplePeriod; + std::vector caseNames; + std::vector > timeSteps; + std::vector> allCurveData; +}; + + +//-------------------------------------------------------------------------------------------------- +/// Internal functions +//-------------------------------------------------------------------------------------------------- +enum SummaryCurveType {CURVE_TYPE_GRID = 0x1, CURVE_TYPE_OBSERVED = 0x2}; + +void populateSummaryCurvesData(std::vector curves, SummaryCurveType curveType, CurvesData* curvesData); +void populateTimeHistoryCurvesData(std::vector curves, CurvesData* curvesData); +void populateAsciiDataCurvesData(std::vector curves, CurvesData* curvesData); + +void prepareCaseCurvesForExport(DateTimePeriod period, ResampleAlgorithm algorithm, + const CurvesData& inputCurvesData, + CurvesData* resultCurvesData); + +void appendToExportDataForCase(QString& out, const std::vector& timeSteps, const std::vector& curveData); +void appendToExportData(QString& out, const std::vector& curvesData); +CurvesData concatCurvesData(const std::vector& curvesData); + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -121,12 +178,13 @@ RimSummaryPlot::RimSummaryPlot() m_timeAxisProperties = new RimSummaryTimeAxisProperties; CAF_PDM_InitField(&m_isAutoZoom_OBSOLETE, "AutoZoom", true, "Auto Zoom", "", "", ""); - m_isAutoZoom_OBSOLETE.uiCapability()->setUiHidden(true); - m_isAutoZoom_OBSOLETE.xmlCapability()->setIOWritable(false); + RiaFieldhandleTools::disableWriteAndSetFieldHidden(&m_isAutoZoom_OBSOLETE); m_isCrossPlot = false; m_nameHelperAllCurves.reset(new RimSummaryPlotNameHelper); + + setPlotInfoLabel("Filters Active"); } //-------------------------------------------------------------------------------------------------- @@ -243,225 +301,51 @@ QWidget* RimSummaryPlot::viewWidget() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimSummaryPlot::asciiDataForPlotExport() const +QString RimSummaryPlot::asciiDataForPlotExport(DateTimePeriod resamplingPeriod) const { QString out; + RiaTimeHistoryCurveResampler resampler; - out += description(); - + // Summary and time history (from grid) curves { std::vector curves; this->descendantsIncludingThisOfType(curves); - std::vector caseNames; - std::vector > timeSteps; - - std::vector > > allCurveData; - std::vector > allCurveNames; - //Vectors containing cases - curves - data points/curve name - - for (RimSummaryCurve* curve : curves) - { - if (!curve->isCurveVisible()) continue; - QString curveCaseName = curve->summaryCaseY()->caseName(); + CurvesData summaryCurvesGridData; + CurvesData summaryCurvesObsData; + populateSummaryCurvesData(curves, CURVE_TYPE_GRID, &summaryCurvesGridData); + populateSummaryCurvesData(curves, CURVE_TYPE_OBSERVED, &summaryCurvesObsData); - size_t casePosInList = cvf::UNDEFINED_SIZE_T; - for (size_t i = 0; i < caseNames.size(); i++) - { - if (curveCaseName == caseNames[i]) casePosInList = i; - } + CurvesData timeHistoryCurvesData; + populateTimeHistoryCurvesData(m_gridTimeHistoryCurves.childObjects(), &timeHistoryCurvesData); - if (casePosInList == cvf::UNDEFINED_SIZE_T) - { - caseNames.push_back(curveCaseName); - - std::vector curveTimeSteps = curve->timeStepsY(); - timeSteps.push_back(curveTimeSteps); - - std::vector > curveDataForCase; - std::vector curveYData = curve->valuesY(); - curveDataForCase.push_back(curveYData); - allCurveData.push_back(curveDataForCase); - - std::vector curveNamesForCase; - curveNamesForCase.push_back(curve->curveName()); - allCurveNames.push_back(curveNamesForCase); - } - else - { - std::vector curveYData = curve->valuesY(); - allCurveData[casePosInList].push_back(curveYData); + // Export observed data + appendToExportData(out, { summaryCurvesObsData }); - QString curveName = curve->curveName(); - allCurveNames[casePosInList].push_back(curveName); - } - } + std::vector exportData(2); - for (size_t i = 0; i < timeSteps.size(); i++) //cases - { - out += "\n\n"; - out += "Case: " + caseNames[i]; - out += "\n"; + // Summary grid data for export + prepareCaseCurvesForExport(resamplingPeriod, + ResampleAlgorithm::DATA_DECIDES, + summaryCurvesGridData, + &exportData[0]); - for (size_t j = 0; j < timeSteps[i].size(); j++) //time steps & data points - { - if (j == 0) - { - out += "Date and time"; - for (size_t k = 0; k < allCurveNames[i].size(); k++) // curves - { - out += "\t" + (allCurveNames[i][k]); - } - } - out += "\n"; - out += QDateTime::fromTime_t(timeSteps[i][j]).toUTC().toString("yyyy-MM-dd hh:mm:ss "); + // Time history data for export + prepareCaseCurvesForExport(resamplingPeriod, + ResampleAlgorithm::PERIOD_END, + timeHistoryCurvesData, + &exportData[1]); - for (size_t k = 0; k < allCurveData[i].size(); k++) // curves - { - QString valueText; - if (j < allCurveData[i][k].size()) - { - valueText = QString::number(allCurveData[i][k][j], 'g', 6); - } - out += "\t" + valueText; - } - } - } + // Export resampled summary and time history data + appendToExportData(out, exportData); } - + // Pasted observed data { - std::vector caseNames; - std::vector > timeSteps; - - std::vector > > allCurveData; - std::vector > allCurveNames; - //Vectors containing cases - curves - data points/curve name - - for (RimGridTimeHistoryCurve* curve : m_gridTimeHistoryCurves) - { - if (!curve->isCurveVisible()) continue; - QString curveCaseName = curve->caseName(); - - size_t casePosInList = cvf::UNDEFINED_SIZE_T; - for (size_t i = 0; i < caseNames.size(); i++) - { - if (curveCaseName == caseNames[i]) casePosInList = i; - } - - if (casePosInList == cvf::UNDEFINED_SIZE_T) - { - caseNames.push_back(curveCaseName); - - std::vector curveTimeSteps = curve->timeStepValues(); - timeSteps.push_back(curveTimeSteps); - - std::vector > curveDataForCase; - std::vector curveYData = curve->yValues(); - curveDataForCase.push_back(curveYData); - allCurveData.push_back(curveDataForCase); - - std::vector curveNamesForCase; - curveNamesForCase.push_back(curve->curveName()); - allCurveNames.push_back(curveNamesForCase); - } - else - { - std::vector curveYData = curve->yValues(); - allCurveData[casePosInList].push_back(curveYData); - - QString curveName = curve->curveName(); - allCurveNames[casePosInList].push_back(curveName); - } - } + CurvesData asciiCurvesData; + populateAsciiDataCurvesData(m_asciiDataCurves.childObjects(), &asciiCurvesData); - for (size_t i = 0; i < timeSteps.size(); i++) //cases - { - out += "\n\n"; - out += "Case: " + caseNames[i]; - out += "\n"; - - for (size_t j = 0; j < timeSteps[i].size(); j++) //time steps & data points - { - if (j == 0) - { - out += "Date and time"; - for (size_t k = 0; k < allCurveNames[i].size(); k++) // curves - { - out += "\t" + (allCurveNames[i][k]); - } - } - out += "\n"; - out += QDateTime::fromTime_t(timeSteps[i][j]).toUTC().toString("yyyy-MM-dd hh:mm:ss "); - - for (size_t k = 0; k < allCurveData[i].size(); k++) // curves - { - out += "\t" + QString::number(allCurveData[i][k][j], 'g', 6); - } - } - } - } - - { - std::vector > timeSteps; - - std::vector > > allCurveData; - std::vector > allCurveNames; - //Vectors containing cases - curves - data points/curve name - - for (RimAsciiDataCurve* curve : m_asciiDataCurves) - { - if (!curve->isCurveVisible()) continue; - - size_t casePosInList = cvf::UNDEFINED_SIZE_T; - - if (casePosInList == cvf::UNDEFINED_SIZE_T) - { - std::vector curveTimeSteps = curve->timeSteps(); - timeSteps.push_back(curveTimeSteps); - - std::vector > curveDataForCase; - std::vector curveYData = curve->yValues(); - curveDataForCase.push_back(curveYData); - allCurveData.push_back(curveDataForCase); - - std::vector curveNamesForCase; - curveNamesForCase.push_back(curve->curveName()); - allCurveNames.push_back(curveNamesForCase); - } - else - { - std::vector curveYData = curve->yValues(); - allCurveData[casePosInList].push_back(curveYData); - - QString curveName = curve->curveName(); - allCurveNames[casePosInList].push_back(curveName); - } - } - - for (size_t i = 0; i < timeSteps.size(); i++) //cases - { - out += "\n\n"; - - for (size_t j = 0; j < timeSteps[i].size(); j++) //time steps & data points - { - if (j == 0) - { - out += "Date and time"; - for (size_t k = 0; k < allCurveNames[i].size(); k++) // curves - { - out += "\t" + (allCurveNames[i][k]); - } - } - out += "\n"; - out += QDateTime::fromTime_t(timeSteps[i][j]).toUTC().toString("yyyy-MM-dd hh:mm:ss "); - - for (size_t k = 0; k < allCurveData[i].size(); k++) // curves - { - out += "\t" + QString::number(allCurveData[i][k][j], 'g', 6); - } - } - } + appendToExportData(out, { asciiCurvesData }); } return out; @@ -516,6 +400,14 @@ RiuSummaryQwtPlot* RimSummaryPlot::qwtPlot() const return m_qwtPlot; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimSummaryPlot::curveSets() const +{ + return ensembleCurveSetCollection()->curveSets(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -573,6 +465,90 @@ void RimSummaryPlot::copyAxisPropertiesFromOther(const RimSummaryPlot& sourceSum } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryPlot::updateAll() +{ + if (qwtPlot()) + { + updatePlotTitle(); + qwtPlot()->updateLegend(); + updateAxes(); + updateZoomInQwt(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryPlot::updateAllLegendItems() +{ + reattachAllCurves(); + if (qwtPlot()) + { + qwtPlot()->updateLegend(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryPlot::setPlotInfoLabel(const QString& label) +{ + auto qwtText = QwtText(label); + qwtText.setRenderFlags(Qt::AlignBottom | Qt::AlignRight); + + QFont font; + font.setBold(true); + qwtText.setFont(font); + + m_plotInfoLabel.reset(new QwtPlotTextLabel()); + m_plotInfoLabel->setText(qwtText); + m_plotInfoLabel->setMargin(10); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryPlot::showPlotInfoLabel(bool show) +{ + if (show) m_plotInfoLabel->attach(m_qwtPlot); + else m_plotInfoLabel->detach(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryPlot::updatePlotInfoLabel() +{ + bool anyCurveSetFiltered = false; + for (auto group : m_ensembleCurveSetCollection->curveSets()) + { + if (group->isFiltered()) + { + anyCurveSetFiltered = true; + break; + } + } + showPlotInfoLabel(anyCurveSetFiltered); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimSummaryPlot::containsResamplableCurves() const +{ + std::vector summaryCurves = summaryAndEnsembleCurves(); + size_t resamplableSummaryCurveCount = std::count_if(summaryCurves.begin(), summaryCurves.end(), + [](RimSummaryCurve* curve) + { + return curve->summaryCaseY() ? !curve->summaryCaseY()->isObservedData() : false; + }); + + return !m_gridTimeHistoryCurves.empty() || resamplableSummaryCurveCount > 0; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -980,7 +956,15 @@ void RimSummaryPlot::addCurveNoUpdate(RimSummaryCurve* curve) //-------------------------------------------------------------------------------------------------- void RimSummaryPlot::deleteCurve(RimSummaryCurve* curve) { - if (curve) + deleteCurves({ curve }); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryPlot::deleteCurves(const std::vector& curves) +{ + for(const auto curve : curves) { if (m_summaryCurveCollection) { @@ -989,7 +973,7 @@ void RimSummaryPlot::deleteCurve(RimSummaryCurve* curve) if (c == curve) { m_summaryCurveCollection->deleteCurve(curve); - return; + continue; } } } @@ -1004,18 +988,19 @@ void RimSummaryPlot::deleteCurve(RimSummaryCurve* curve) curveSet->deleteCurve(curve); if (curveSet->curves().empty()) { - if (curveSet->colorMode() == RimEnsembleCurveSet::BY_ENSEMBLE_PARAM) + if (curveSet->colorMode() == RimEnsembleCurveSet::BY_ENSEMBLE_PARAM && qwtPlot()) { qwtPlot()->removeEnsembleCurveSetLegend(curveSet); } m_ensembleCurveSetCollection->deleteCurveSet(curveSet); } - return; + continue; } } } } } + updateCaseNameHasChanged(); } //-------------------------------------------------------------------------------------------------- @@ -1037,25 +1022,6 @@ RimEnsembleCurveSetCollection* RimSummaryPlot::ensembleCurveSetCollection() cons return m_ensembleCurveSetCollection; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimSummaryPlot::setCurveCollection(RimSummaryCurveCollection* curveCollection) -{ - if (curveCollection) - { - // Delete current curve coll ? - - - m_summaryCurveCollection = curveCollection; - if (m_qwtPlot) - { - m_summaryCurveCollection->setParentQwtPlotAndReplot(m_qwtPlot); - this->updateAxes(); - } - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1254,7 +1220,6 @@ void RimSummaryPlot::onLoadDataAndUpdate() if (m_qwtPlot) m_qwtPlot->updateLegend(); this->updateAxes(); updateZoomInQwt(); - if(m_qwtPlot) m_qwtPlot->replot(); } //-------------------------------------------------------------------------------------------------- @@ -1564,8 +1529,8 @@ void RimSummaryPlot::updateNameHelperWithCurveData(RimSummaryPlotNameHelper* nam nameHelper->clear(); nameHelper->appendAddresses(addresses); - nameHelper->appendSummaryCases(sumCases); - nameHelper->appendEnsembleCases(ensembleCases); + nameHelper->setSummaryCases(sumCases); + nameHelper->setEnsembleCases(ensembleCases); } //-------------------------------------------------------------------------------------------------- @@ -1610,6 +1575,29 @@ void RimSummaryPlot::detachAllCurves() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimSummaryPlot::reattachAllCurves() +{ + if (m_summaryCurveCollection) + { + m_summaryCurveCollection->reattachQwtCurves(); + } + + m_ensembleCurveSetCollection->reattachQwtCurves(); + + for (RimGridTimeHistoryCurve* curve : m_gridTimeHistoryCurves) + { + curve->reattachQwtCurve(); + } + + for (RimAsciiDataCurve* curve : m_asciiDataCurves) + { + curve->reattachQwtCurve(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1681,3 +1669,324 @@ void RimSummaryPlot::defineEditorAttribute(const caf::PdmFieldHandle* field, QSt } } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void populateTimeHistoryCurvesData(std::vector curves, CurvesData* curvesData) +{ + CVF_ASSERT(curvesData); + + curvesData->caseNames.clear(); + curvesData->timeSteps.clear(); + curvesData->allCurveData.clear(); + + for (RimGridTimeHistoryCurve* curve : curves) + { + if (!curve->isCurveVisible()) continue; + QString curveCaseName = curve->caseName(); + + size_t casePosInList = cvf::UNDEFINED_SIZE_T; + for (size_t i = 0; i < curvesData->caseNames.size(); i++) + { + if (curveCaseName == curvesData->caseNames[i]) casePosInList = i; + } + + CurveData curveData = { curve->curveExportDescription(), RifEclipseSummaryAddress(), curve->yValues() }; + + if (casePosInList == cvf::UNDEFINED_SIZE_T) + { + curvesData->caseNames.push_back(curveCaseName); + curvesData->timeSteps.push_back(curve->timeStepValues()); + curvesData->allCurveData.push_back(std::vector({ curveData })); + } + else + { + curvesData->allCurveData[casePosInList].push_back(curveData); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void populateAsciiDataCurvesData(std::vector curves, CurvesData* curvesData) +{ + CVF_ASSERT(curvesData); + + curvesData->caseNames.clear(); + curvesData->timeSteps.clear(); + curvesData->allCurveData.clear(); + + for (RimAsciiDataCurve* curve : curves) + { + if (!curve->isCurveVisible()) continue; + + size_t casePosInList = cvf::UNDEFINED_SIZE_T; + + CurveData curveData = { curve->curveExportDescription(), RifEclipseSummaryAddress(), curve->yValues() }; + + if (casePosInList == cvf::UNDEFINED_SIZE_T) + { + curvesData->caseNames.push_back(""); + curvesData->timeSteps.push_back(curve->timeSteps()); + curvesData->allCurveData.push_back(std::vector({ curveData })); + } + else + { + curvesData->allCurveData[casePosInList].push_back(curveData); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void populateSummaryCurvesData(std::vector curves, SummaryCurveType curveType, CurvesData* curvesData) +{ + CVF_ASSERT(curvesData); + + curvesData->caseNames.clear(); + curvesData->timeSteps.clear(); + curvesData->allCurveData.clear(); + + for (RimSummaryCurve* curve : curves) + { + bool isObservedCurve = curve->summaryCaseY() ? curve->summaryCaseY()->isObservedData() : false; + + if (!curve->isCurveVisible()) continue; + if (isObservedCurve && (curveType & CURVE_TYPE_OBSERVED) == 0) continue; + if (!isObservedCurve && (curveType & CURVE_TYPE_GRID) == 0) continue; + + QString curveCaseName = curve->summaryCaseY()->caseName(); + + size_t casePosInList = cvf::UNDEFINED_SIZE_T; + for (size_t i = 0; i < curvesData->caseNames.size(); i++) + { + if (curveCaseName == curvesData->caseNames[i]) casePosInList = i; + } + + CurveData curveData = { curve->curveExportDescription(), curve->summaryAddressY(), curve->valuesY() }; + CurveData errorCurveData; + + // Error data + auto errorValues = curve->errorValuesY(); + bool hasErrorData = !errorValues.empty(); + + if (hasErrorData) + { + errorCurveData.name = curve->curveExportDescription(curve->errorSummaryAddressY()); + errorCurveData.address = curve->errorSummaryAddressY(); + errorCurveData.values = errorValues; + } + + if (casePosInList == cvf::UNDEFINED_SIZE_T) + { + auto curveDataList = std::vector({ curveData }); + if (hasErrorData) curveDataList.push_back(errorCurveData); + + curvesData->caseNames.push_back(curveCaseName); + curvesData->timeSteps.push_back(curve->timeStepsY()); + curvesData->allCurveData.push_back(curveDataList); + } + else + { + curvesData->allCurveData[casePosInList].push_back(curveData); + if(hasErrorData) curvesData->allCurveData[casePosInList].push_back(errorCurveData); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void prepareCaseCurvesForExport(DateTimePeriod period, ResampleAlgorithm algorithm, + const CurvesData& inputCurvesData, + CurvesData* resultCurvesData) +{ + RiaTimeHistoryCurveResampler resampler; + + resultCurvesData->clear(); + + if (period != DateTimePeriod::NONE) + { + // Prepare result data + resultCurvesData->resamplePeriod = period; + + for (size_t i = 0; i < inputCurvesData.caseNames.size(); i++) + { + // Shortcuts to input data + auto& caseName = inputCurvesData.caseNames[i]; + auto& caseTimeSteps = inputCurvesData.timeSteps[i]; + auto& caseCurveData = inputCurvesData.allCurveData[i]; + + // Prepare result data + resultCurvesData->caseNames.push_back(caseName); + resultCurvesData->allCurveData.push_back(std::vector()); + + for (auto& curveDataItem : caseCurveData) + { + resampler.setCurveData(curveDataItem.values, caseTimeSteps); + + if (curveDataItem.address.hasAccumulatedData() || algorithm == ResampleAlgorithm::PERIOD_END) + { + resampler.resampleAndComputePeriodEndValues(period); + } + else + { + resampler.resampleAndComputeWeightedMeanValues(period); + } + + auto cd = curveDataItem; + cd.values = resampler.resampledValues(); + auto& currResultCurveDataList = resultCurvesData->allCurveData[i]; + currResultCurveDataList.push_back(cd); + } + + resultCurvesData->timeSteps.push_back(resampler.resampledTimeSteps()); + } + } + else + { + *resultCurvesData = inputCurvesData; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void appendToExportDataForCase(QString& out, const std::vector& timeSteps, const std::vector& curveData) +{ + for (size_t j = 0; j < timeSteps.size(); j++) //time steps & data points + { + if (j == 0) + { + out += "Date and time"; + for (size_t k = 0; k < curveData.size(); k++) // curves + { + out += "\t" + (curveData[k].name); + } + } + out += "\n"; + out += QDateTime::fromTime_t(timeSteps[j]).toUTC().toString("yyyy-MM-dd hh:mm:ss "); + + for (size_t k = 0; k < curveData.size(); k++) // curves + { + QString valueText; + if (j < curveData[k].values.size()) + { + valueText = QString::number(curveData[k].values[j], 'g', 6); + + } + out += "\t" + valueText.rightJustified(13); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void appendToExportData(QString& out, const std::vector& curvesData) +{ + CurvesData data = concatCurvesData(curvesData); + + if (data.resamplePeriod != DateTimePeriod::NONE) + { + time_t minTimeStep = std::numeric_limits::max(); + time_t maxTimeStep = 0; + + for (auto& timeSteps : data.timeSteps) + { + if (!timeSteps.empty()) + { + if (timeSteps.front() < minTimeStep) minTimeStep = timeSteps.front(); + if (timeSteps.back() > maxTimeStep) maxTimeStep = timeSteps.back(); + } + } + + auto allTimeSteps = RiaTimeHistoryCurveResampler::timeStepsFromTimeRange(data.resamplePeriod, minTimeStep, maxTimeStep); + + out += "\n\n"; + out += "Date and time"; + for (size_t i = 0; i < data.caseNames.size(); i++) + { + for (size_t j = 0; j < data.allCurveData[i].size(); j++) + { + out += "\t" + data.allCurveData[i][j].name; + } + } + out += "\n"; + + std::vector currIndexes(data.caseNames.size()); + for (auto& i : currIndexes) i = 0; + + for (auto timeStep : allTimeSteps) + { + QString tt = QDateTime::fromTime_t(timeStep).toUTC().toString("yyyy-MM-dd hh:mm:ss "); + out += QDateTime::fromTime_t(timeStep).toUTC().toString("yyyy-MM-dd hh:mm:ss "); + + for (size_t i = 0; i < data.caseNames.size(); i++) // cases + { + // Check is time step exists in curr case + size_t& currIndex = currIndexes[i]; + bool timeStepExists = currIndex < data.timeSteps[i].size() && timeStep == data.timeSteps[i][currIndex]; + + for (size_t j = 0; j < data.allCurveData[i].size(); j++) // vectors + { + QString valueText; + if (timeStepExists) + { + valueText = QString::number(data.allCurveData[i][j].values[currIndex], 'g', 6); + } + else + { + valueText = "NULL"; + } + out += "\t" + valueText.rightJustified(13); + } + + if (timeStepExists && currIndex < data.timeSteps[i].size()) currIndex++; + } + out += "\n"; + } + } + else + { + for (size_t i = 0; i < data.caseNames.size(); i++) + { + out += "\n\n"; + if (!data.caseNames[i].isEmpty()) + { + out += "Case: " + data.caseNames[i]; + out += "\n"; + } + + appendToExportDataForCase(out, data.timeSteps[i], data.allCurveData[i]); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +CurvesData concatCurvesData(const std::vector& curvesData) +{ + CVF_ASSERT(!curvesData.empty()); + + DateTimePeriod period = curvesData.front().resamplePeriod; + CurvesData resultCurvesData; + + resultCurvesData.resamplePeriod = period; + + for (auto curvesDataItem : curvesData) + { + if (curvesDataItem.caseNames.empty()) continue; + + CVF_ASSERT(curvesDataItem.resamplePeriod == period); + + resultCurvesData.caseNames.insert(resultCurvesData.caseNames.end(), curvesDataItem.caseNames.begin(), curvesDataItem.caseNames.end()); + resultCurvesData.timeSteps.insert(resultCurvesData.timeSteps.end(), curvesDataItem.timeSteps.begin(), curvesDataItem.timeSteps.end()); + resultCurvesData.allCurveData.insert(resultCurvesData.allCurveData.end(), curvesDataItem.allCurveData.begin(), curvesDataItem.allCurveData.end()); + } + return resultCurvesData; +} diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.h index 9049ed8373..3b76f856a5 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.h @@ -22,11 +22,13 @@ #include "cafPdmChildArrayField.h" #include "RiaDefines.h" +#include "RiaQDateTimeTools.h" #include "RifEclipseSummaryAddress.h" #include "RimViewWindow.h" +#include "qwt_plot_textlabel.h" #include #include @@ -59,7 +61,7 @@ class RimSummaryPlot : public RimViewWindow public: RimSummaryPlot(); - virtual ~RimSummaryPlot(); + ~RimSummaryPlot() override; void setDescription(const QString& description); QString description() const; @@ -72,7 +74,8 @@ class RimSummaryPlot : public RimViewWindow void addCurveNoUpdate(RimSummaryCurve* curve); void deleteCurve(RimSummaryCurve* curve); - void setCurveCollection(RimSummaryCurveCollection* curveCollection); + void deleteCurves(const std::vector& curves); + void deleteCurvesAssosiatedWithCase(RimSummaryCase* summaryCase); RimEnsembleCurveSetCollection* ensembleCurveSetCollection() const; @@ -85,10 +88,11 @@ class RimSummaryPlot : public RimViewWindow size_t curveCount() const; void detachAllCurves(); + void reattachAllCurves(); void updateCaseNameHasChanged(); void updateAxes(); - virtual void zoomAll() override; + void zoomAll() override; void updateZoomInQwt(); void updateZoomWindowFromQwt(); @@ -100,9 +104,9 @@ class RimSummaryPlot : public RimViewWindow void selectAxisInPropertyEditor(int axis); - virtual QWidget* viewWidget() override; + QWidget* viewWidget() override; - QString asciiDataForPlotExport() const; + QString asciiDataForPlotExport(DateTimePeriod resamplingPeriod = DateTimePeriod::NONE) const; std::vector summaryAndEnsembleCurves() const; std::vector summaryCurves() const; @@ -110,6 +114,8 @@ class RimSummaryPlot : public RimViewWindow RimSummaryCurveCollection* summaryCurveCollection() const; RiuSummaryQwtPlot* qwtPlot() const; + std::vector curveSets() const; + void updatePlotTitle(); const RimSummaryPlotNameHelper* activePlotTitleHelperAllCurves() const; @@ -118,11 +124,19 @@ class RimSummaryPlot : public RimViewWindow void copyAxisPropertiesFromOther(const RimSummaryPlot& sourceSummaryPlot); + void updateAll(); + void updateAllLegendItems(); + + void setPlotInfoLabel(const QString& label); + void showPlotInfoLabel(bool show); + void updatePlotInfoLabel(); + + bool containsResamplableCurves() const; // RimViewWindow overrides public: - virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; - virtual void deleteViewWidget() override; - virtual void initAfterRead() override; + QWidget* createViewWidget(QWidget* mainWindowParent) override; + void deleteViewWidget() override; + void initAfterRead() override; private: void updateMdiWindowTitle() override; @@ -130,15 +144,15 @@ class RimSummaryPlot : public RimViewWindow protected: // Overridden PDM methods - virtual caf::PdmFieldHandle* userDescriptionField() override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void onLoadDataAndUpdate() override; + caf::PdmFieldHandle* userDescriptionField() override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void onLoadDataAndUpdate() override; - virtual QImage snapshotWindowContent() override; + QImage snapshotWindowContent() override; void setAsCrossPlot(); @@ -180,7 +194,7 @@ class RimSummaryPlot : public RimViewWindow caf::PdmChildField m_timeAxisProperties; QPointer m_qwtPlot; - + std::unique_ptr m_plotInfoLabel; bool m_isCrossPlot; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotCollection.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotCollection.h index 49312a1e37..e08eba19ee 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotCollection.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotCollection.h @@ -32,7 +32,7 @@ class RimSummaryPlotCollection : public caf::PdmObject CAF_PDM_HEADER_INIT; public: RimSummaryPlotCollection(); - virtual ~RimSummaryPlotCollection(); + ~RimSummaryPlotCollection() override; caf::PdmChildArrayField summaryPlots; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp index e7cd195bd5..367f19f6cb 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.cpp @@ -36,7 +36,7 @@ RimSummaryPlotNameHelper::RimSummaryPlotNameHelper() {} void RimSummaryPlotNameHelper::clear() { m_summaryCases.clear(); - + m_ensembleCases.clear(); m_analyzer.clear(); clearTitleSubStrings(); @@ -55,13 +55,15 @@ void RimSummaryPlotNameHelper::appendAddresses(const std::vector& summaryCases) +void RimSummaryPlotNameHelper::setSummaryCases(const std::vector& summaryCases) { m_summaryCases.clear(); - for (auto summaryCase : summaryCases) + m_summaryCases.resize(summaryCases.size()); + + for (size_t i = 0; i < summaryCases.size(); i++) { - if (summaryCase) m_summaryCases.insert(summaryCase); + m_summaryCases[i] = summaryCases[i]; } extractPlotTitleSubStrings(); @@ -70,13 +72,15 @@ void RimSummaryPlotNameHelper::appendSummaryCases(const std::vector& ensembleCases) +void RimSummaryPlotNameHelper::setEnsembleCases(const std::vector& ensembleCases) { m_ensembleCases.clear(); - for (auto ensembleCase : ensembleCases) + m_ensembleCases.resize(ensembleCases.size()); + + for (size_t i = 0; i < ensembleCases.size(); i++) { - if (ensembleCase) m_ensembleCases.insert(ensembleCase); + m_ensembleCases[i] = ensembleCases[i]; } extractPlotTitleSubStrings(); @@ -116,7 +120,7 @@ QString RimSummaryPlotNameHelper::plotTitle() const if (!m_titleQuantity.empty()) { if (!title.isEmpty()) title += ", "; - title += QString::fromStdString(RiuSummaryVectorDescriptionMap::instance()->fieldInfo(m_titleQuantity)); + title += QString::fromStdString(RiuSummaryVectorDescriptionMap::instance()->vectorLongName(m_titleQuantity, true)); } if (title.isEmpty()) @@ -216,21 +220,54 @@ void RimSummaryPlotNameHelper::extractPlotTitleSubStrings() } } - if (m_summaryCases.size() == 1 && m_ensembleCases.empty()) + auto summaryCases = setOfSummaryCases(); + auto ensembleCases = setOfEnsembleCases(); + + if (summaryCases.size() == 1 && ensembleCases.empty()) { - auto summaryCase = *(m_summaryCases.begin()); + auto summaryCase = *(summaryCases.begin()); if (summaryCase) { m_titleCaseName = summaryCase->caseName(); } } - else if (m_ensembleCases.size() == 1 && m_summaryCases.empty()) + else if (ensembleCases.size() == 1 && summaryCases.empty()) { - auto ensembleCase = *(m_ensembleCases.begin()); + auto ensembleCase = *(ensembleCases.begin()); if (ensembleCase) { m_titleCaseName = ensembleCase->name(); } } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RimSummaryPlotNameHelper::setOfSummaryCases() const +{ + std::set summaryCases; + + for (const auto& sumCase : m_summaryCases) + { + if (sumCase) summaryCases.insert(sumCase); + } + + return summaryCases; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RimSummaryPlotNameHelper::setOfEnsembleCases() const +{ + std::set ensembleCases; + + for (const auto& ensemble : m_ensembleCases) + { + if (ensemble) ensembleCases.insert(ensemble); + } + + return ensembleCases; +} diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.h index 7698dada30..6c4bc4d237 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotNameHelper.h @@ -22,6 +22,8 @@ #include "RifEclipseSummaryAddress.h" +#include "cafPdmPointer.h" + #include #include @@ -42,8 +44,8 @@ class RimSummaryPlotNameHelper void clear(); void appendAddresses(const std::vector& addresses); - void appendSummaryCases(const std::vector& summaryCases); - void appendEnsembleCases(const std::vector& ensembleCases); + void setSummaryCases(const std::vector& summaryCases); + void setEnsembleCases(const std::vector& ensembleCases); QString plotTitle() const; @@ -57,11 +59,15 @@ class RimSummaryPlotNameHelper void clearTitleSubStrings(); void extractPlotTitleSubStrings(); + std::set setOfSummaryCases() const; + std::set setOfEnsembleCases() const; + + private: RiaSummaryCurveAnalyzer m_analyzer; - std::set m_summaryCases; - std::set m_ensembleCases; + std::vector> m_summaryCases; + std::vector> m_ensembleCases; std::string m_titleQuantity; std::string m_titleWellName; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp index bf02610c2c..8e83d82db3 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp @@ -24,6 +24,7 @@ #include "RifSummaryReaderInterface.h" +#include "RimDataSourceSteppingTools.h" #include "RimProject.h" #include "RimSummaryCase.h" #include "RimSummaryCaseMainCollection.h" @@ -43,7 +44,8 @@ CAF_PDM_SOURCE_INIT(RimSummaryPlotSourceStepping, "RimSummaryCurveCollectionModi //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimSummaryPlotSourceStepping::RimSummaryPlotSourceStepping() : m_sourceSteppingType(Y_AXIS) +RimSummaryPlotSourceStepping::RimSummaryPlotSourceStepping() + : m_sourceSteppingType(Y_AXIS) { // clang-format off CAF_PDM_InitObject("Summary Curves Modifier", "", "", ""); @@ -75,33 +77,7 @@ void RimSummaryPlotSourceStepping::setSourceSteppingType(SourceSteppingType sour //-------------------------------------------------------------------------------------------------- void RimSummaryPlotSourceStepping::applyNextCase() { - RimProject* proj = RiaApplication::instance()->project(); - - auto summaryCases = proj->allSummaryCases(); - if (summaryCases.size() < 1) return; - - auto currentCase = std::find(summaryCases.begin(), summaryCases.end(), m_summaryCase()); - - if (currentCase != summaryCases.end()) - { - currentCase++; - if (currentCase != summaryCases.end()) - { - m_summaryCase = *currentCase; - } - } - else - { - m_summaryCase = summaryCases[0]; - } - - fieldChangedByUi(&m_summaryCase, QVariant(), QVariant()); - m_summaryCase.uiCapability()->updateConnectedEditors(); - - RimSummaryCurveCollection* curveCollection = nullptr; - this->firstAncestorOrThisOfTypeAsserted(curveCollection); - - curveCollection->updateConnectedEditors(); + modifyCurrentIndex(&m_summaryCase, 1); } //-------------------------------------------------------------------------------------------------- @@ -109,30 +85,7 @@ void RimSummaryPlotSourceStepping::applyNextCase() //-------------------------------------------------------------------------------------------------- void RimSummaryPlotSourceStepping::applyPrevCase() { - RimProject* proj = RiaApplication::instance()->project(); - - auto summaryCases = proj->allSummaryCases(); - if (summaryCases.size() < 1) return; - - auto currentCase = std::find(summaryCases.begin(), summaryCases.end(), m_summaryCase()); - - if (currentCase != summaryCases.end() && currentCase != summaryCases.begin()) - { - currentCase--; - m_summaryCase = *currentCase; - } - else - { - m_summaryCase = summaryCases[0]; - } - - fieldChangedByUi(&m_summaryCase, QVariant(), QVariant()); - m_summaryCase.uiCapability()->updateConnectedEditors(); - - RimSummaryCurveCollection* curveCollection = nullptr; - this->firstAncestorOrThisOfTypeAsserted(curveCollection); - - curveCollection->updateConnectedEditors(); + modifyCurrentIndex(&m_summaryCase, -1); } //-------------------------------------------------------------------------------------------------- @@ -229,10 +182,10 @@ QList RimSummaryPlotSourceStepping::calculateValueOption std::vector identifierTexts; - RifSummaryReaderInterface* reader = firstSummaryReaderForCurves(); - if (reader) + std::vector readers = summaryReadersForCurves(); + if (!readers.empty()) { - RiaSummaryCurveAnalyzer* analyzer = analyzerForReader(reader); + RiaSummaryCurveAnalyzer* analyzer = analyzerForReader(readers.front()); if (fieldNeedingOptions == &m_wellName) { @@ -260,9 +213,12 @@ QList RimSummaryPlotSourceStepping::calculateValueOption RiaSummaryCurveAnalyzer quantityAnalyzer; - auto subset = RiaSummaryCurveAnalyzer::addressesForCategory(reader->allResultAddresses(), category); + for (auto reader : readers) + { + auto subset = RiaSummaryCurveAnalyzer::addressesForCategory(reader->allResultAddresses(), category); + quantityAnalyzer.appendAdresses(subset); + } - quantityAnalyzer.appendAdresses(subset); for (const auto& quantity : quantityAnalyzer.quantities()) { identifierTexts.push_back(QString::fromStdString(quantity)); @@ -289,8 +245,9 @@ QList RimSummaryPlotSourceStepping::calculateValueOption //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, - const QVariant& newValue) +void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* changedField, + const QVariant& oldValue, + const QVariant& newValue) { RimSummaryCurveCollection* curveCollection = nullptr; this->firstAncestorOrThisOfTypeAsserted(curveCollection); @@ -305,7 +262,9 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* c { if (isYAxisStepping()) { + bool doSetAppearance = curve->summaryCaseY()->isObservedData() != m_summaryCase->isObservedData(); curve->setSummaryCaseY(m_summaryCase); + if (doSetAppearance) curve->forceUpdateCurveAppearanceFromCaseType(); } if (isXAxisStepping()) @@ -329,7 +288,7 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* c if (isYAxisStepping()) { RifEclipseSummaryAddress adr = curve->summaryAddressY(); - if (adr.category() == RifEclipseSummaryAddress::SUMMARY_WELL) + if (RifEclipseSummaryAddress::isDependentOnWellName(adr)) { adr.setWellName(m_wellName().toStdString()); @@ -340,7 +299,7 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* c if (isXAxisStepping()) { RifEclipseSummaryAddress adr = curve->summaryAddressX(); - if (adr.category() == RifEclipseSummaryAddress::SUMMARY_WELL) + if (RifEclipseSummaryAddress::isDependentOnWellName(adr)) { adr.setWellName(m_wellName().toStdString()); @@ -457,25 +416,26 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi(const caf::PdmFieldHandle* c //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifSummaryReaderInterface* RimSummaryPlotSourceStepping::firstSummaryReaderForCurves() const +std::vector RimSummaryPlotSourceStepping::summaryReadersForCurves() const { - RimSummaryCurveCollection* curveCollection = nullptr; + std::vector readers; + RimSummaryCurveCollection* curveCollection = nullptr; this->firstAncestorOrThisOfTypeAsserted(curveCollection); for (auto curve : curveCollection->curves()) { if (isYAxisStepping() && curve->summaryCaseY()) { - return curve->summaryCaseY()->summaryReader(); + readers.push_back(curve->summaryCaseY()->summaryReader()); } if (isXAxisStepping() && curve->summaryCaseX()) { - return curve->summaryCaseX()->summaryReader(); + readers.push_back(curve->summaryCaseX()->summaryReader()); } } - return nullptr; + return readers; } //-------------------------------------------------------------------------------------------------- @@ -688,50 +648,16 @@ RiaSummaryCurveAnalyzer* RimSummaryPlotSourceStepping::analyzerForReader(RifSumm //-------------------------------------------------------------------------------------------------- void RimSummaryPlotSourceStepping::modifyCurrentIndex(caf::PdmValueField* valueField, int indexOffset) { - if (valueField) - { - bool useOptionsOnly = true; - - QList options = calculateValueOptions(valueField, nullptr); - if (options.isEmpty()) - { - return; - } - - auto uiVariant = valueField->uiCapability()->toUiBasedQVariant(); - - int currentIndex = -1; - for (int i = 0; i < options.size(); i++) - { - if (uiVariant == options[i].optionUiText()) - { - currentIndex = i; - } - } - - if (currentIndex == -1) - { - currentIndex = 0; - } - - int nextIndex = currentIndex + indexOffset; - if (nextIndex < options.size() && nextIndex > -1) - { - auto optionValue = options[nextIndex].value(); - - QVariant currentValue = valueField->toQVariant(); - - valueField->setFromQVariant(optionValue); - - valueField->uiCapability()->notifyFieldChanged(currentValue, optionValue); - } - } + bool useOptionsOnly; + QList options = calculateValueOptions(valueField, &useOptionsOnly); + RimDataSourceSteppingTools::modifyCurrentIndex(valueField, options, indexOffset); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimSummaryPlotSourceStepping::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, +void RimSummaryPlotSourceStepping::defineEditorAttribute(const caf::PdmFieldHandle* field, + QString uiConfigName, caf::PdmUiEditorAttribute* attribute) { caf::PdmUiComboBoxEditorAttribute* myAttr = dynamic_cast(attribute); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.h index 65601060e1..e6526f902d 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.h @@ -65,19 +65,19 @@ class RimSummaryPlotSourceStepping : public caf::PdmObject std::vector fieldsToShowInToolbar(); private: - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; private: - RifSummaryReaderInterface* firstSummaryReaderForCurves() const; + std::vector summaryReadersForCurves() const; caf::PdmValueField* fieldToModify(); std::set addressesCurveCollection() const; diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryTimeAxisProperties.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryTimeAxisProperties.h index 451236dca2..252c0c5623 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryTimeAxisProperties.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryTimeAxisProperties.h @@ -84,10 +84,10 @@ class RimSummaryTimeAxisProperties : public caf::PdmObject bool isActive() const; protected: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; - virtual caf::PdmFieldHandle* objectToggleField() override; - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override; + caf::PdmFieldHandle* objectToggleField() override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; double fromDateToDisplayTime(const QDateTime& displayTime); QDateTime fromDisplayTimeToDate(double displayTime); diff --git a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake index 6ba9315bff..804817e441 100644 --- a/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake +++ b/ApplicationCode/ReservoirDataModel/CMakeLists_files.cmake @@ -37,7 +37,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigNNCData.h ${CMAKE_CURRENT_LIST_DIR}/cvfGeometryTools.h ${CMAKE_CURRENT_LIST_DIR}/cvfGeometryTools.inl ${CMAKE_CURRENT_LIST_DIR}/RigPipeInCellEvaluator.h -${CMAKE_CURRENT_LIST_DIR}/RigTernaryResultAccessor2d.h +${CMAKE_CURRENT_LIST_DIR}/RigTernaryResultAccessor.h ${CMAKE_CURRENT_LIST_DIR}/RigEclipseNativeStatCalc.h ${CMAKE_CURRENT_LIST_DIR}/RigEclipseNativeVisibleCellsStatCalc.h ${CMAKE_CURRENT_LIST_DIR}/RigEclipseMultiPropertyStatCalc.h @@ -45,7 +45,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RigWellLogCurveData.h ${CMAKE_CURRENT_LIST_DIR}/RigWellLogExtractionTools.h ${CMAKE_CURRENT_LIST_DIR}/RigHexIntersectionTools.h ${CMAKE_CURRENT_LIST_DIR}/RigTimeHistoryResultAccessor.h -${CMAKE_CURRENT_LIST_DIR}/RigCurveDataTools.h ${CMAKE_CURRENT_LIST_DIR}/RigObservedData.h ${CMAKE_CURRENT_LIST_DIR}/RigLasFileExporter.h ${CMAKE_CURRENT_LIST_DIR}/RigSimulationWellCoordsAndMD.h @@ -58,7 +57,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RigTofAccumulatedPhaseFractionsCalculator.h ${CMAKE_CURRENT_LIST_DIR}/RigTransmissibilityEquations.h ${CMAKE_CURRENT_LIST_DIR}/RigNumberOfFloodedPoreVolumesCalculator.h ${CMAKE_CURRENT_LIST_DIR}/RigWeightedMeanCalc.h -${CMAKE_CURRENT_LIST_DIR}/RigTimeHistoryCurveMerger.h ${CMAKE_CURRENT_LIST_DIR}/RigWellPathFormations.h ${CMAKE_CURRENT_LIST_DIR}/RigStimPlanFractureDefinition.h ${CMAKE_CURRENT_LIST_DIR}/RigFractureGrid.h @@ -66,6 +64,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigFractureCell.h ${CMAKE_CURRENT_LIST_DIR}/RigWellResultPoint.h ${CMAKE_CURRENT_LIST_DIR}/RigWellPathGeometryTools.h ${CMAKE_CURRENT_LIST_DIR}/RigCaseRealizationParameters.h +${CMAKE_CURRENT_LIST_DIR}/RigGeoMechBoreHoleStressCalculator.h ) @@ -103,14 +102,13 @@ ${CMAKE_CURRENT_LIST_DIR}/RigWellPath.cpp ${CMAKE_CURRENT_LIST_DIR}/RigFault.cpp ${CMAKE_CURRENT_LIST_DIR}/RigNNCData.cpp ${CMAKE_CURRENT_LIST_DIR}/cvfGeometryTools.cpp -${CMAKE_CURRENT_LIST_DIR}/RigTernaryResultAccessor2d.cpp +${CMAKE_CURRENT_LIST_DIR}/RigTernaryResultAccessor.cpp ${CMAKE_CURRENT_LIST_DIR}/RigEclipseNativeStatCalc.cpp ${CMAKE_CURRENT_LIST_DIR}/RigEclipseNativeVisibleCellsStatCalc.cpp ${CMAKE_CURRENT_LIST_DIR}/RigEclipseMultiPropertyStatCalc.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellLogCurveData.cpp ${CMAKE_CURRENT_LIST_DIR}/RigHexIntersectionTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RigTimeHistoryResultAccessor.cpp -${CMAKE_CURRENT_LIST_DIR}/RigCurveDataTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RigObservedData.cpp ${CMAKE_CURRENT_LIST_DIR}/RigLasFileExporter.cpp ${CMAKE_CURRENT_LIST_DIR}/RigSimulationWellCoordsAndMD.cpp @@ -123,7 +121,6 @@ ${CMAKE_CURRENT_LIST_DIR}/RigTofAccumulatedPhaseFractionsCalculator.cpp ${CMAKE_CURRENT_LIST_DIR}/RigTransmissibilityEquations.cpp ${CMAKE_CURRENT_LIST_DIR}/RigNumberOfFloodedPoreVolumesCalculator.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWeightedMeanCalc.cpp -${CMAKE_CURRENT_LIST_DIR}/RigTimeHistoryCurveMerger.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellPathFormations.cpp ${CMAKE_CURRENT_LIST_DIR}/RigStimPlanFractureDefinition.cpp ${CMAKE_CURRENT_LIST_DIR}/RigFractureGrid.cpp @@ -131,6 +128,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigFractureCell.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellResultPoint.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellPathGeometryTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RigCaseRealizationParameters.cpp +${CMAKE_CURRENT_LIST_DIR}/RigGeoMechBoreHoleStressCalculator.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ReservoirDataModel/Completions/CMakeLists_files.cmake b/ApplicationCode/ReservoirDataModel/Completions/CMakeLists_files.cmake index 02d025e364..0f956a1c82 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/CMakeLists_files.cmake +++ b/ApplicationCode/ReservoirDataModel/Completions/CMakeLists_files.cmake @@ -7,6 +7,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RigTransmissibilityCondenser.h ${CMAKE_CURRENT_LIST_DIR}/RigFractureTransmissibilityEquations.h ${CMAKE_CURRENT_LIST_DIR}/RigWellPathStimplanIntersector.h ${CMAKE_CURRENT_LIST_DIR}/RigVirtualPerforationTransmissibilities.h +${CMAKE_CURRENT_LIST_DIR}/RigEclipseToStimPlanCalculator.h +${CMAKE_CURRENT_LIST_DIR}/RigPerforationTransmissibilityEquations.h ) @@ -18,6 +20,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RigTransmissibilityCondenser.cpp ${CMAKE_CURRENT_LIST_DIR}/RigFractureTransmissibilityEquations.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellPathStimplanIntersector.cpp ${CMAKE_CURRENT_LIST_DIR}/RigVirtualPerforationTransmissibilities.cpp +${CMAKE_CURRENT_LIST_DIR}/RigEclipseToStimPlanCalculator.cpp +${CMAKE_CURRENT_LIST_DIR}/RigPerforationTransmissibilityEquations.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.cpp b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.cpp index c83f33515d..79014a9e4d 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.cpp +++ b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.cpp @@ -24,7 +24,7 @@ #include -#include // Needed for HUGE_VAL on Linux +#include //================================================================================================== /// @@ -32,20 +32,20 @@ RigCompletionData::RigCompletionData(const QString wellName, const RigCompletionDataGridCell& cellIndex, double orderingValue) : m_wellName(wellName) , m_cellIndex(cellIndex) - , m_saturation(HUGE_VAL) - , m_transmissibility(HUGE_VAL) - , m_diameter(HUGE_VAL) - , m_kh(HUGE_VAL) - , m_skinFactor(HUGE_VAL) - , m_dFactor(HUGE_VAL) + , m_saturation(std::numeric_limits::infinity()) + , m_transmissibility(std::numeric_limits::infinity()) + , m_diameter(std::numeric_limits::infinity()) + , m_kh(std::numeric_limits::infinity()) + , m_skinFactor(std::numeric_limits::infinity()) + , m_dFactor(std::numeric_limits::infinity()) , m_direction(DIR_UNDEF) , m_connectionState(OPEN) , m_count(1) - , m_wpimult(HUGE_VAL) + , m_wpimult(std::numeric_limits::infinity()) , m_isMainBore(false) , m_completionType(CT_UNDEFINED) , m_firstOrderingValue(orderingValue) - , m_secondOrderingValue(HUGE_VAL) + , m_secondOrderingValue(std::numeric_limits::infinity()) { } @@ -160,13 +160,17 @@ void RigCompletionData::setTransAndWPImultBackgroundDataFromFishbone(double void RigCompletionData::setTransAndWPImultBackgroundDataFromPerforation(double transmissibility, double skinFactor, double diameter, + double dFactor, + double kh, CellDirection direction) { m_completionType = PERFORATION; m_transmissibility = transmissibility; m_skinFactor = skinFactor; m_diameter = diameter; + m_dFactor = dFactor; m_direction = direction; + m_kh = kh; m_isMainBore = true; } @@ -240,9 +244,17 @@ void RigCompletionData::addMetadata(const QString& name, const QString& comment) //================================================================================================== /// //================================================================================================== -bool RigCompletionData::isDefaultValue(double val) +double RigCompletionData::defaultValue() { - return val == HUGE_VAL; + return std::numeric_limits::infinity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigCompletionData::isDefaultValue(double num) +{ + return num == defaultValue(); } //-------------------------------------------------------------------------------------------------- @@ -381,32 +393,20 @@ double RigCompletionData::secondOrderingValue() const return m_secondOrderingValue; } -//================================================================================================== +//-------------------------------------------------------------------------------------------------- /// -//================================================================================================== -bool RigCompletionData::onlyOneIsDefaulted(double first, double second) +//-------------------------------------------------------------------------------------------------- +void RigCompletionData::setSourcePdmObject(const caf::PdmObject* object) { - if (first == HUGE_VAL) - { - if (second == HUGE_VAL) - { - // Both have default values - return false; - } - else - { - // First has default value, second does not - return true; - } - } - if (second == HUGE_VAL) - { - // Second has default value, first does not - return true; - } + m_sourcePdmObject = const_cast(object); +} - // Neither has default values - return false; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const caf::PdmObject* RigCompletionData::sourcePdmObject() const +{ + return m_sourcePdmObject; } //================================================================================================== @@ -431,4 +431,5 @@ void RigCompletionData::copy(RigCompletionData& target, const RigCompletionData& target.m_completionType = from.m_completionType; target.m_firstOrderingValue = from.m_firstOrderingValue; target.m_secondOrderingValue = from.m_secondOrderingValue; + target.m_sourcePdmObject = from.m_sourcePdmObject; } diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.h b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.h index de8c255c75..c4ee7f9d3c 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.h +++ b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionData.h @@ -22,9 +22,10 @@ #include -#include +#include +#include -class RimEclipseCase; +#include //================================================================================================== /// @@ -65,6 +66,7 @@ class RigCompletionData FISHBONES, FRACTURE, PERFORATION, + ICD, CT_UNDEFINED }; @@ -90,6 +92,8 @@ class RigCompletionData void setTransAndWPImultBackgroundDataFromPerforation(double transmissibility, double skinFactor, double diameter, + double dFactor, + double kh, CellDirection direction); void setCombinedValuesExplicitTrans(double transmissibility, @@ -109,8 +113,9 @@ class RigCompletionData void setKh(double kh); void addMetadata(const QString& name, const QString& comment); - static bool isDefaultValue(double val); - + + static double defaultValue(); + static bool isDefaultValue(double num); const std::vector& metadata() const; const QString& wellName() const; const RigCompletionDataGridCell& completionDataGridCell() const; @@ -130,6 +135,9 @@ class RigCompletionData double firstOrderingValue() const; double secondOrderingValue() const; + void setSourcePdmObject(const caf::PdmObject* object); + const caf::PdmObject* sourcePdmObject() const; + std::vector m_metadata; private: @@ -154,7 +162,8 @@ class RigCompletionData double m_firstOrderingValue; double m_secondOrderingValue; + caf::PdmPointer m_sourcePdmObject; + private: - static bool onlyOneIsDefaulted(double first, double second); static void copy(RigCompletionData& target, const RigCompletionData& from); }; diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionDataGridCell.cpp b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionDataGridCell.cpp index 5e2c3a8c2a..23b305025e 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionDataGridCell.cpp +++ b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionDataGridCell.cpp @@ -23,7 +23,15 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigCompletionDataGridCell::RigCompletionDataGridCell() {} +RigCompletionDataGridCell::RigCompletionDataGridCell() + : m_globalCellIndex(0) + , m_lgrName("") + , m_gridIndex(0) + , m_localCellIndexI(0) + , m_localCellIndexJ(0) + , m_localCellIndexK(0) +{ +} //-------------------------------------------------------------------------------------------------- /// @@ -33,9 +41,9 @@ RigCompletionDataGridCell::RigCompletionDataGridCell(size_t globalCellIndex, con { if (mainGrid) { - size_t gridLocalCellIndex; + size_t gridLocalCellIndex; const RigGridBase* grid = mainGrid->gridAndGridLocalIdxFromGlobalCellIdx(globalCellIndex, &gridLocalCellIndex); - + if (grid) { size_t i = 0; @@ -51,6 +59,8 @@ RigCompletionDataGridCell::RigCompletionDataGridCell(size_t globalCellIndex, con { m_lgrName = QString::fromStdString(grid->gridName()); } + + m_gridIndex = grid->gridIndex(); } } } @@ -68,11 +78,13 @@ bool RigCompletionDataGridCell::operator==(const RigCompletionDataGridCell& othe //-------------------------------------------------------------------------------------------------- bool RigCompletionDataGridCell::operator<(const RigCompletionDataGridCell& other) const { + if (m_gridIndex != other.m_gridIndex) return m_gridIndex < other.m_gridIndex; + if (m_localCellIndexI != other.m_localCellIndexI) return m_localCellIndexI < other.m_localCellIndexI; if (m_localCellIndexJ != other.m_localCellIndexJ) return m_localCellIndexJ < other.m_localCellIndexJ; if (m_localCellIndexK != other.m_localCellIndexK) return m_localCellIndexK < other.m_localCellIndexK; - return false; + return m_globalCellIndex < other.m_globalCellIndex; } //-------------------------------------------------------------------------------------------------- @@ -124,3 +136,11 @@ QString RigCompletionDataGridCell::lgrName() const { return m_lgrName; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigCompletionDataGridCell::isMainGridCell() const +{ + return m_lgrName.isEmpty(); +} diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionDataGridCell.h b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionDataGridCell.h index 91637fa48c..b2565e1bed 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigCompletionDataGridCell.h +++ b/ApplicationCode/ReservoirDataModel/Completions/RigCompletionDataGridCell.h @@ -46,10 +46,13 @@ class RigCompletionDataGridCell QString lgrName() const; + bool isMainGridCell() const; + private: size_t m_globalCellIndex; QString m_lgrName; + size_t m_gridIndex; size_t m_localCellIndexI; size_t m_localCellIndexJ; size_t m_localCellIndexK; diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.cpp b/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.cpp new file mode 100644 index 0000000000..9f3cd5396a --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.cpp @@ -0,0 +1,266 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigEclipseToStimPlanCalculator.h" + +#include "RiaLogging.h" + +#include "RigActiveCellInfo.h" +#include "RigCaseCellResultsData.h" +#include "RigCellGeometryTools.h" +#include "RigEclipseCaseData.h" +#include "RigFractureCell.h" +#include "RigFractureGrid.h" +#include "RigFractureTransmissibilityEquations.h" +#include "RigHexIntersectionTools.h" +#include "RigMainGrid.h" +#include "RigResultAccessorFactory.h" +#include "RigTransmissibilityCondenser.h" + +#include "RiaWeightedMeanCalculator.h" +#include "RimEclipseCase.h" +#include "RimEllipseFractureTemplate.h" +#include "RimFracture.h" +#include "RimFractureContainmentTools.h" +#include "RimStimPlanFractureTemplate.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigEclipseToStimPlanCalculator::RigEclipseToStimPlanCalculator(const RimEclipseCase* caseToApply, + cvf::Mat4d fractureTransform, + double skinFactor, + double cDarcy, + const RigFractureGrid& fractureGrid, + const RimFracture* fracture) + : m_case(caseToApply) + , m_fractureTransform(fractureTransform) + , m_fractureSkinFactor(skinFactor) + , m_cDarcy(cDarcy) + , m_fractureGrid(fractureGrid) + , m_fracture(fracture) +{ + computeValues(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseToStimPlanCalculator::computeValues() +{ + auto reservoirCellIndicesOpenForFlow = RimFractureContainmentTools::reservoirCellIndicesOpenForFlow(m_case, m_fracture); + + for (size_t i = 0; i < m_fractureGrid.fractureCells().size(); i++) + { + const RigFractureCell& fractureCell = m_fractureGrid.fractureCells()[i]; + if (!fractureCell.hasNonZeroConductivity()) continue; + + RigEclipseToStimPlanCellTransmissibilityCalculator eclToFractureTransCalc(m_case, + m_fractureTransform, + m_fractureSkinFactor, + m_cDarcy, + fractureCell, + reservoirCellIndicesOpenForFlow, + m_fracture); + + const std::vector& fractureCellContributingEclipseCells = + eclToFractureTransCalc.globalIndiciesToContributingEclipseCells(); + + if (!fractureCellContributingEclipseCells.empty()) + { + m_singleFractureCellCalculators.emplace(i, eclToFractureTransCalc); + } + } +} + +using CellIdxSpace = RigTransmissibilityCondenser::CellAddress; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseToStimPlanCalculator::appendDataToTransmissibilityCondenser(bool useFiniteConductivityInFracture, + RigTransmissibilityCondenser* condenser) const +{ + for (const auto& eclToFractureTransCalc : m_singleFractureCellCalculators) + { + const std::vector& fractureCellContributingEclipseCells = + eclToFractureTransCalc.second.globalIndiciesToContributingEclipseCells(); + + const std::vector& fractureCellContributingEclipseCellTransmissibilities = + eclToFractureTransCalc.second.contributingEclipseCellTransmissibilities(); + + size_t stimPlanCellIndex = eclToFractureTransCalc.first; + + for (size_t i = 0; i < fractureCellContributingEclipseCells.size(); i++) + { + if (useFiniteConductivityInFracture) + { + condenser->addNeighborTransmissibility({true, CellIdxSpace::ECLIPSE, fractureCellContributingEclipseCells[i]}, + {false, CellIdxSpace::STIMPLAN, stimPlanCellIndex}, + fractureCellContributingEclipseCellTransmissibilities[i]); + } + else + { + condenser->addNeighborTransmissibility({true, CellIdxSpace::ECLIPSE, fractureCellContributingEclipseCells[i]}, + {true, CellIdxSpace::WELL, 1}, + fractureCellContributingEclipseCellTransmissibilities[i]); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigEclipseToStimPlanCalculator::totalEclipseAreaOpenForFlow() const +{ + double area = 0.0; + + for (const auto& singleCellCalc : m_singleFractureCellCalculators) + { + double cellArea = singleCellCalc.second.areaOpenForFlow(); + + area += cellArea; + } + + return area; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigEclipseToStimPlanCalculator::areaWeightedMatrixPermeability() const +{ + RiaWeightedMeanCalculator calc; + + { + std::map reservoirCellAndIntersectedArea; + + for (const auto& singleCellCalc : m_singleFractureCellCalculators) + { + const RigEclipseToStimPlanCellTransmissibilityCalculator& calulator = singleCellCalc.second; + + const std::vector& areas = calulator.contributingEclipseCellIntersectionAreas(); + const std::vector& permeabilities = calulator.contributingEclipseCellPermeabilities(); + + if (areas.size() == permeabilities.size()) + { + for (size_t i = 0; i < areas.size(); i++) + { + calc.addValueAndWeight(permeabilities[i], areas[i]); + } + } + } + } + + return calc.weightedMean(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigEclipseToStimPlanCalculator::areaWeightedWidth() const +{ + double width = 0.0; + + auto ellipseFractureTemplate = dynamic_cast(m_fracture->fractureTemplate()); + if (ellipseFractureTemplate) + { + width = ellipseFractureTemplate->width(); + } + + auto stimPlanFractureTemplate = dynamic_cast(m_fracture->fractureTemplate()); + if (stimPlanFractureTemplate) + { + auto widthValues = stimPlanFractureTemplate->widthResultValues(); + if (!widthValues.empty()) + { + RiaWeightedMeanCalculator calc; + + for (const auto& singleCellCalc : m_singleFractureCellCalculators) + { + double cellArea = singleCellCalc.second.areaOpenForFlow(); + + size_t globalStimPlanCellIndex = singleCellCalc.first; + double widthValue = widthValues[globalStimPlanCellIndex]; + + calc.addValueAndWeight(widthValue, cellArea); + } + + width = calc.weightedMean(); + } + else + { + width = stimPlanFractureTemplate->computeFractureWidth(m_fracture); + } + } + + return width; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigEclipseToStimPlanCalculator::areaWeightedConductivity() const +{ + RiaWeightedMeanCalculator calc; + + for (const auto& singleCellCalc : m_singleFractureCellCalculators) + { + double cellArea = singleCellCalc.second.areaOpenForFlow(); + + calc.addValueAndWeight(singleCellCalc.second.fractureCell().getConductivityValue(), cellArea); + } + + return calc.weightedMean(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigEclipseToStimPlanCalculator::longestYSectionOpenForFlow() const +{ + // For each I, find the longest aggregated distance along J with continuous fracture cells with conductivity above + // zero connected to Eclipse cells open for flow + + double longestRange = 0.0; + + for (size_t i = 0; i < m_fractureGrid.iCellCount(); i++) + { + double currentAggregatedDistanceY = 0.0; + for (size_t j = 0; j < m_fractureGrid.jCellCount(); j++) + { + size_t globalStimPlanCellIndex = m_fractureGrid.getGlobalIndexFromIJ(i, j); + + auto calculatorForCell = m_singleFractureCellCalculators.find(globalStimPlanCellIndex); + if (calculatorForCell != m_singleFractureCellCalculators.end()) + { + currentAggregatedDistanceY += calculatorForCell->second.fractureCell().cellSizeZ(); + } + else + { + longestRange = std::max(longestRange, currentAggregatedDistanceY); + currentAggregatedDistanceY = 0.0; + } + } + + longestRange = std::max(longestRange, currentAggregatedDistanceY); + } + + return longestRange; +} diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.h b/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.h new file mode 100644 index 0000000000..9e93c1dac8 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCalculator.h @@ -0,0 +1,74 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018 Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaPorosityModel.h" + +#include "RigEclipseToStimPlanCellTransmissibilityCalculator.h" + +#include "cvfBase.h" +#include "cvfMatrix4.h" + +#include + +class QString; + +class RimEclipseCase; +class RigFractureGrid; +class RigTransmissibilityCondenser; +class RimFracture; + +//================================================================================================== +/// +//================================================================================================== +class RigEclipseToStimPlanCalculator +{ +public: + explicit RigEclipseToStimPlanCalculator(const RimEclipseCase* caseToApply, + cvf::Mat4d fractureTransform, + double skinFactor, + double cDarcy, + const RigFractureGrid& fractureGrid, + const RimFracture* fracture); + + void appendDataToTransmissibilityCondenser(bool useFiniteConductivityInFracture, + RigTransmissibilityCondenser* condenser) const; + + // Returns the area intersecting eclipse cells open for flow, from both active and inactive cells + // Truncated parts of the fracture are not included + double totalEclipseAreaOpenForFlow() const; + + double areaWeightedMatrixPermeability() const; + double areaWeightedWidth() const; + double areaWeightedConductivity() const; + double longestYSectionOpenForFlow() const; + +private: + void computeValues(); + +private: + const RimEclipseCase* m_case; + const RimFracture* m_fracture; + double m_cDarcy; + double m_fractureSkinFactor; + cvf::Mat4d m_fractureTransform; + const RigFractureGrid& m_fractureGrid; + + std::map m_singleFractureCellCalculators; +}; diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCellTransmissibilityCalculator.cpp b/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCellTransmissibilityCalculator.cpp index 70a27dcf21..c80668a664 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCellTransmissibilityCalculator.cpp +++ b/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCellTransmissibilityCalculator.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -24,75 +24,171 @@ #include "RigEclipseCaseData.h" #include "RigFractureCell.h" #include "RigFractureTransmissibilityEquations.h" +#include "RigHexIntersectionTools.h" #include "RigMainGrid.h" #include "RigResultAccessorFactory.h" -#include "RigHexIntersectionTools.h" #include "RimEclipseCase.h" +#include "RimFracture.h" + +#include "RiaLogging.h" #include "cvfGeometryTools.h" +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigEclipseToStimPlanCellTransmissibilityCalculator::RigEclipseToStimPlanCellTransmissibilityCalculator( + const RimEclipseCase* caseToApply, + cvf::Mat4d fractureTransform, + double skinFactor, + double cDarcy, + const RigFractureCell& stimPlanCell, + const std::set& reservoirCellIndicesOpenForFlow, + const RimFracture* fracture) + : m_case(caseToApply) + , m_fractureTransform(fractureTransform) + , m_fractureSkinFactor(skinFactor) + , m_cDarcy(cDarcy) + , m_stimPlanCell(stimPlanCell) + , m_fracture(fracture) +{ + calculateStimPlanCellsMatrixTransmissibility(reservoirCellIndicesOpenForFlow); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigEclipseToStimPlanCellTransmissibilityCalculator::globalIndiciesToContributingEclipseCells() const +{ + return m_globalIndiciesToContributingEclipseCells; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigEclipseToStimPlanCellTransmissibilityCalculator::contributingEclipseCellTransmissibilities() const +{ + return m_contributingEclipseCellTransmissibilities; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigEclipseToStimPlanCellTransmissibilityCalculator::RigEclipseToStimPlanCellTransmissibilityCalculator(RimEclipseCase* caseToApply, - cvf::Mat4d fractureTransform, - double skinFactor, - double cDarcy, - const RigFractureCell& stimPlanCell) - : m_case(caseToApply), - m_fractureTransform(fractureTransform), - m_fractureSkinFactor(skinFactor), - m_cDarcy(cDarcy), - m_stimPlanCell(stimPlanCell) +const std::vector& RigEclipseToStimPlanCellTransmissibilityCalculator::contributingEclipseCellIntersectionAreas() const { + return m_contributingEclipseCellAreas; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector& RigEclipseToStimPlanCellTransmissibilityCalculator::globalIndeciesToContributingEclipseCells() +const std::vector& RigEclipseToStimPlanCellTransmissibilityCalculator::contributingEclipseCellPermeabilities() const +{ + return m_contributingEclipseCellPermeabilities; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigEclipseToStimPlanCellTransmissibilityCalculator::areaOpenForFlow() const { - if (m_globalIndeciesToContributingEclipseCells.size() < 1) + double area = 0.0; + + for (const auto& areaForOneEclipseCell : m_contributingEclipseCellAreas) { - calculateStimPlanCellsMatrixTransmissibility(); + area += areaForOneEclipseCell; } - return m_globalIndeciesToContributingEclipseCells; + return area; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const std::vector& RigEclipseToStimPlanCellTransmissibilityCalculator::contributingEclipseCellTransmissibilities() +double RigEclipseToStimPlanCellTransmissibilityCalculator::aggregatedMatrixTransmissibility() const { - if (m_globalIndeciesToContributingEclipseCells.size() < 1) + double totalTransmissibility = 0.0; + + for (const auto& trans : m_contributingEclipseCellTransmissibilities) { - calculateStimPlanCellsMatrixTransmissibility(); + totalTransmissibility += trans; } - return m_contributingEclipseCellTransmissibilities; + return totalTransmissibility; } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +const RigFractureCell& RigEclipseToStimPlanCellTransmissibilityCalculator::fractureCell() const +{ + return m_stimPlanCell; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigEclipseToStimPlanCellTransmissibilityCalculator::requiredResultNames() +{ + std::vector resultNames; + resultNames.push_back("PERMX"); + resultNames.push_back("PERMY"); + resultNames.push_back("PERMZ"); + + resultNames.push_back("DX"); + resultNames.push_back("DY"); + resultNames.push_back("DZ"); + + return resultNames; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigEclipseToStimPlanCellTransmissibilityCalculator::optionalResultNames() +{ + std::vector resultNames; + resultNames.push_back("NTG"); + + return resultNames; +} + //-------------------------------------------------------------------------------------------------- -void RigEclipseToStimPlanCellTransmissibilityCalculator::calculateStimPlanCellsMatrixTransmissibility() +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseToStimPlanCellTransmissibilityCalculator::calculateStimPlanCellsMatrixTransmissibility( + const std::set& reservoirCellIndicesOpenForFlow) { // Not calculating flow into fracture if stimPlan cell cond value is 0 (assumed to be outside the fracture): - if (m_stimPlanCell.getConductivtyValue() < 1e-7) return; + if (m_stimPlanCell.getConductivityValue() < 1e-7) return; const RigEclipseCaseData* eclipseCaseData = m_case->eclipseCaseData(); RiaDefines::PorosityModelType porosityModel = RiaDefines::MATRIX_MODEL; - cvf::ref dataAccessObjectDx = loadResultAndCreateResultAccessor(m_case, porosityModel, "DX"); - cvf::ref dataAccessObjectDy = loadResultAndCreateResultAccessor(m_case, porosityModel, "DY"); - cvf::ref dataAccessObjectDz = loadResultAndCreateResultAccessor(m_case, porosityModel, "DZ"); - cvf::ref dataAccessObjectPermX = loadResultAndCreateResultAccessor(m_case, porosityModel, "PERMX"); - cvf::ref dataAccessObjectPermY = loadResultAndCreateResultAccessor(m_case, porosityModel, "PERMY"); - cvf::ref dataAccessObjectPermZ = loadResultAndCreateResultAccessor(m_case, porosityModel, "PERMZ"); - cvf::ref dataAccessObjectNTG = loadResultAndCreateResultAccessor(m_case, porosityModel, "NTG"); + cvf::ref dataAccessObjectDx = createResultAccessor(m_case, "DX"); + cvf::ref dataAccessObjectDy = createResultAccessor(m_case, "DY"); + cvf::ref dataAccessObjectDz = createResultAccessor(m_case, "DZ"); + if (dataAccessObjectDx.isNull() || dataAccessObjectDy.isNull() || dataAccessObjectDz.isNull()) + { + RiaLogging::error("Data for DX/DY/DZ is not complete, and these values are required for export of COMPDAT. Make sure " + "'Preferences->Compute DEPTH Related Properties' is checked."); + + return; + } + + cvf::ref dataAccessObjectPermX = createResultAccessor(m_case, "PERMX"); + cvf::ref dataAccessObjectPermY = createResultAccessor(m_case, "PERMY"); + cvf::ref dataAccessObjectPermZ = createResultAccessor(m_case, "PERMZ"); + if (dataAccessObjectPermX.isNull() || dataAccessObjectPermY.isNull() || dataAccessObjectPermZ.isNull()) + { + RiaLogging::error("Data for PERMX/PERMY/PERMZ is not complete, and these values are required for export of COMPDAT."); + + return; + } + + cvf::ref dataAccessObjectNTG = createResultAccessor(m_case, "NTG"); const RigActiveCellInfo* activeCellInfo = eclipseCaseData->activeCellInfo(porosityModel); @@ -103,42 +199,28 @@ void RigEclipseToStimPlanCellTransmissibilityCalculator::calculateStimPlanCellsM stimPlanPolygonTransformed.push_back(v); } - std::vector fracCells = getPotentiallyFracturedCellsForPolygon(stimPlanPolygonTransformed); - for (size_t fracCell : fracCells) + std::vector reservoirCellIndices = getPotentiallyFracturedCellsForPolygon(stimPlanPolygonTransformed); + for (size_t reservoirCellIndex : reservoirCellIndices) { - bool cellIsActive = activeCellInfo->isActive(fracCell); - if (!cellIsActive) continue; - - double permX = dataAccessObjectPermX->cellScalarGlobIdx(fracCell); - double permY = dataAccessObjectPermY->cellScalarGlobIdx(fracCell); - double permZ = dataAccessObjectPermZ->cellScalarGlobIdx(fracCell); - - double dx = dataAccessObjectDx->cellScalarGlobIdx(fracCell); - double dy = dataAccessObjectDy->cellScalarGlobIdx(fracCell); - double dz = dataAccessObjectDz->cellScalarGlobIdx(fracCell); - - double NTG = 1.0; - if (dataAccessObjectNTG.notNull()) - { - NTG = dataAccessObjectNTG->cellScalarGlobIdx(fracCell); - } - const RigMainGrid* mainGrid = m_case->eclipseCaseData()->mainGrid(); + if (!m_fracture->isEclipseCellOpenForFlow(mainGrid, reservoirCellIndicesOpenForFlow, reservoirCellIndex)) continue; + std::array hexCorners; - mainGrid->cellCornerVertices(fracCell, hexCorners.data()); + mainGrid->cellCornerVertices(reservoirCellIndex, hexCorners.data()); - std::vector > planeCellPolygons; - bool isPlanIntersected = RigHexIntersectionTools::planeHexIntersectionPolygons(hexCorners, m_fractureTransform, planeCellPolygons); - if (!isPlanIntersected || planeCellPolygons.size() == 0) continue; + std::vector> planeCellPolygons; + bool isPlanIntersected = + RigHexIntersectionTools::planeHexIntersectionPolygons(hexCorners, m_fractureTransform, planeCellPolygons); + if (!isPlanIntersected || planeCellPolygons.empty()) continue; cvf::Vec3d localX; cvf::Vec3d localY; cvf::Vec3d localZ; RigCellGeometryTools::findCellLocalXYZ(hexCorners, localX, localY, localZ); - //Transform planCell polygon(s) and averageZdirection to x/y coordinate system (where fracturePolygon already is located) + // Transform planCell polygon(s) and averageZdirection to x/y coordinate system (where fracturePolygon already is located) cvf::Mat4d invertedTransMatrix = m_fractureTransform.getInverted(); - for (std::vector & planeCellPolygon : planeCellPolygons) + for (std::vector& planeCellPolygon : planeCellPolygons) { for (cvf::Vec3d& v : planeCellPolygon) { @@ -146,31 +228,33 @@ void RigEclipseToStimPlanCellTransmissibilityCalculator::calculateStimPlanCellsM } } - std::vector > polygonsForStimPlanCellInEclipseCell; - cvf::Vec3d areaVector; - std::vector stimPlanPolygon = m_stimPlanCell.getPolygon(); + std::vector> polygonsForStimPlanCellInEclipseCell; + cvf::Vec3d areaVector; + std::vector stimPlanPolygon = m_stimPlanCell.getPolygon(); - for (std::vector planeCellPolygon : planeCellPolygons) + for (const std::vector& planeCellPolygon : planeCellPolygons) { - std::vector >clippedPolygons = RigCellGeometryTools::intersectPolygons(planeCellPolygon, stimPlanPolygon); - for (std::vector clippedPolygon : clippedPolygons) + std::vector> clippedPolygons = + RigCellGeometryTools::intersectPolygons(planeCellPolygon, stimPlanPolygon); + for (const std::vector& clippedPolygon : clippedPolygons) { polygonsForStimPlanCellInEclipseCell.push_back(clippedPolygon); } } - if (polygonsForStimPlanCellInEclipseCell.size() == 0) continue; + if (polygonsForStimPlanCellInEclipseCell.empty()) continue; - double area; std::vector areaOfFractureParts; - double length; + double length; std::vector lengthXareaOfFractureParts; - double Ax = 0.0, Ay = 0.0, Az = 0.0; + double Ax = 0.0; + double Ay = 0.0; + double Az = 0.0; - for (std::vector fracturePartPolygon : polygonsForStimPlanCellInEclipseCell) + for (const std::vector& fracturePartPolygon : polygonsForStimPlanCellInEclipseCell) { - areaVector = cvf::GeometryTools::polygonAreaNormal3D(fracturePartPolygon); - area = areaVector.length(); + areaVector = cvf::GeometryTools::polygonAreaNormal3D(fracturePartPolygon); + double area = areaVector.length(); areaOfFractureParts.push_back(area); length = RigCellGeometryTools::polygonLengthInLocalXdirWeightedByArea(fracturePartPolygon); @@ -180,37 +264,81 @@ void RigEclipseToStimPlanCellTransmissibilityCalculator::calculateStimPlanCellsM fracturePlane.setFromPointAndNormal(static_cast(m_fractureTransform.translation()), static_cast(m_fractureTransform.col(2))); - Ax += fabs(area*(fracturePlane.normal().dot(localY))); - Ay += fabs(area*(fracturePlane.normal().dot(localX))); - Az += fabs(area*(fracturePlane.normal().dot(localZ))); + Ax += fabs(area * (fracturePlane.normal().dot(localY))); + Ay += fabs(area * (fracturePlane.normal().dot(localX))); + Az += fabs(area * (fracturePlane.normal().dot(localZ))); } double fractureArea = 0.0; - for (double area : areaOfFractureParts) fractureArea += area; + for (double area : areaOfFractureParts) + fractureArea += area; double totalAreaXLength = 0.0; - for (double lengtXarea : lengthXareaOfFractureParts) totalAreaXLength += lengtXarea; + for (double lengtXarea : lengthXareaOfFractureParts) + totalAreaXLength += lengtXarea; double fractureAreaWeightedlength = totalAreaXLength / fractureArea; - double transmissibility_X = RigFractureTransmissibilityEquations::matrixToFractureTrans(permY, NTG, Ay, dx, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy); - double transmissibility_Y = RigFractureTransmissibilityEquations::matrixToFractureTrans(permX, NTG, Ax, dy, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy); - double transmissibility_Z = RigFractureTransmissibilityEquations::matrixToFractureTrans(permZ, 1.0, Az, dz, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy); + // Transmissibility for inactive cells is set to zero + // Inactive cells must be include in order to compute the fractured area correctly + double transmissibility = 0.0; + + bool isActive = true; + { + // Use main grid cell to evaluate if a cell is active or not. + // All cells in temporary grids are active + const RigCell& cell = mainGrid->globalCellArray()[reservoirCellIndex]; + size_t mainGridReservoirIndex = cell.mainGridCellIndex(); + + if (!activeCellInfo->isActive(mainGridReservoirIndex)) + { + isActive = false; + } + } + + double matrixPermeability = 0.0; + + if (isActive) + { + double permX = dataAccessObjectPermX->cellScalarGlobIdx(reservoirCellIndex); + double permY = dataAccessObjectPermY->cellScalarGlobIdx(reservoirCellIndex); + double permZ = dataAccessObjectPermZ->cellScalarGlobIdx(reservoirCellIndex); + + double dx = dataAccessObjectDx->cellScalarGlobIdx(reservoirCellIndex); + double dy = dataAccessObjectDy->cellScalarGlobIdx(reservoirCellIndex); + double dz = dataAccessObjectDz->cellScalarGlobIdx(reservoirCellIndex); - double transmissibility = sqrt(transmissibility_X * transmissibility_X - + transmissibility_Y * transmissibility_Y - + transmissibility_Z * transmissibility_Z); + double NTG = 1.0; + if (dataAccessObjectNTG.notNull()) + { + NTG = dataAccessObjectNTG->cellScalarGlobIdx(reservoirCellIndex); + } + + double transmissibility_X = RigFractureTransmissibilityEquations::matrixToFractureTrans( + permY, NTG, Ay, dx, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy); + double transmissibility_Y = RigFractureTransmissibilityEquations::matrixToFractureTrans( + permX, NTG, Ax, dy, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy); + double transmissibility_Z = RigFractureTransmissibilityEquations::matrixToFractureTrans( + permZ, 1.0, Az, dz, m_fractureSkinFactor, fractureAreaWeightedlength, m_cDarcy); + transmissibility = sqrt(transmissibility_X * transmissibility_X + transmissibility_Y * transmissibility_Y + + transmissibility_Z * transmissibility_Z); - m_globalIndeciesToContributingEclipseCells.push_back(fracCell); + matrixPermeability = RigFractureTransmissibilityEquations::matrixPermeability(permX, permY, NTG); + } + + m_globalIndiciesToContributingEclipseCells.push_back(reservoirCellIndex); m_contributingEclipseCellTransmissibilities.push_back(transmissibility); + m_contributingEclipseCellAreas.push_back(fractureArea); + m_contributingEclipseCellPermeabilities.push_back(matrixPermeability); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector RigEclipseToStimPlanCellTransmissibilityCalculator::getPotentiallyFracturedCellsForPolygon(std::vector polygon) +std::vector RigEclipseToStimPlanCellTransmissibilityCalculator::getPotentiallyFracturedCellsForPolygon( + const std::vector& polygon) const { std::vector cellIndices; @@ -218,29 +346,35 @@ std::vector RigEclipseToStimPlanCellTransmissibilityCalculator::getPoten if (!mainGrid) return cellIndices; cvf::BoundingBox polygonBBox; - for (cvf::Vec3d nodeCoord : polygon) polygonBBox.add(nodeCoord); + for (const cvf::Vec3d& nodeCoord : polygon) + { + polygonBBox.add(nodeCoord); + } mainGrid->findIntersectingCells(polygonBBox, &cellIndices); - return cellIndices; + std::vector cellIndicesToLeafCells; + for (const size_t& index : cellIndices) + { + const RigCell& cell = mainGrid->globalCellArray()[index]; + if (!cell.subGrid()) + { + cellIndicesToLeafCells.push_back(index); + } + } + + return cellIndicesToLeafCells; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -cvf::ref RigEclipseToStimPlanCellTransmissibilityCalculator::loadResultAndCreateResultAccessor( - RimEclipseCase* eclipseCase, - RiaDefines::PorosityModelType porosityModel, - const QString& uiResultName) +cvf::ref + RigEclipseToStimPlanCellTransmissibilityCalculator::createResultAccessor(const RimEclipseCase* eclipseCase, + const QString& uiResultName) { - CVF_ASSERT(eclipseCase); - - RigCaseCellResultsData* gridCellResults = eclipseCase->results(porosityModel); - - // Calling this function will force loading of result from file - gridCellResults->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, uiResultName); - - const RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); + RiaDefines::PorosityModelType porosityModel = RiaDefines::MATRIX_MODEL; + const RigEclipseCaseData* eclipseCaseData = eclipseCase->eclipseCaseData(); // Create result accessor object for main grid at time step zero (static result date is always at first time step return RigResultAccessorFactory::createFromUiResultName(eclipseCaseData, 0, porosityModel, 0, uiResultName); diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCellTransmissibilityCalculator.h b/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCellTransmissibilityCalculator.h index 6800ebc301..e6b759c081 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCellTransmissibilityCalculator.h +++ b/ApplicationCode/ReservoirDataModel/Completions/RigEclipseToStimPlanCellTransmissibilityCalculator.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -21,8 +21,8 @@ #include "RiaPorosityModel.h" #include "cvfBase.h" -#include "cvfObject.h" #include "cvfMatrix4.h" +#include "cvfObject.h" #include @@ -30,40 +30,59 @@ class QString; class RimEclipseCase; class RigFractureCell; -class RigEclipseCaseData; class RigResultAccessor; +class RimFracture; //================================================================================================== /// +/// Calculator used to compute the intersection areas between one RigFractureCell and Eclipse cells +/// Both active and inactive Eclipse cells are included. The transmissibility value for inactive cells are set to zero. +/// Eclipse reservoir cells open for flow is defined by reservoirCellIndicesOpenForFlow +/// //================================================================================================== - class RigEclipseToStimPlanCellTransmissibilityCalculator { public: - explicit RigEclipseToStimPlanCellTransmissibilityCalculator(RimEclipseCase* caseToApply, - cvf::Mat4d fractureTransform, - double skinFactor, - double cDarcy, - const RigFractureCell& stimPlanCell); + explicit RigEclipseToStimPlanCellTransmissibilityCalculator(const RimEclipseCase* caseToApply, + cvf::Mat4d fractureTransform, + double skinFactor, + double cDarcy, + const RigFractureCell& stimPlanCell, + const std::set& reservoirCellIndicesOpenForFlow, + const RimFracture* fracture); + + // These three vectors have the same size + const std::vector& globalIndiciesToContributingEclipseCells() const; + const std::vector& contributingEclipseCellTransmissibilities() const; + const std::vector& contributingEclipseCellIntersectionAreas() const; + const std::vector& contributingEclipseCellPermeabilities() const; + + double areaOpenForFlow() const; + double aggregatedMatrixTransmissibility() const; - const std::vector& globalIndeciesToContributingEclipseCells(); - const std::vector& contributingEclipseCellTransmissibilities(); + const RigFractureCell& fractureCell() const; + + static std::vector requiredResultNames(); + static std::vector optionalResultNames(); private: - void calculateStimPlanCellsMatrixTransmissibility(); - std::vector getPotentiallyFracturedCellsForPolygon(std::vector polygon); + void calculateStimPlanCellsMatrixTransmissibility(const std::set& reservoirCellIndicesOpenForFlow); + std::vector getPotentiallyFracturedCellsForPolygon(const std::vector& polygon) const; - static cvf::ref - loadResultAndCreateResultAccessor(RimEclipseCase* eclipseCase, - RiaDefines::PorosityModelType porosityModel, - const QString& uiResultName); + static cvf::ref createResultAccessor(const RimEclipseCase* eclipseCase, const QString& uiResultName); private: - RimEclipseCase* m_case; + const RimEclipseCase* m_case; + const RimFracture* m_fracture; + double m_cDarcy; double m_fractureSkinFactor; cvf::Mat4d m_fractureTransform; const RigFractureCell& m_stimPlanCell; - std::vector m_globalIndeciesToContributingEclipseCells; - std::vector m_contributingEclipseCellTransmissibilities; + + // These three vectors have the same size + std::vector m_globalIndiciesToContributingEclipseCells; + std::vector m_contributingEclipseCellTransmissibilities; + std::vector m_contributingEclipseCellAreas; + std::vector m_contributingEclipseCellPermeabilities; }; diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigFractureTransmissibilityEquations.cpp b/ApplicationCode/ReservoirDataModel/Completions/RigFractureTransmissibilityEquations.cpp index fd7aa599a6..40145f63ec 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigFractureTransmissibilityEquations.cpp +++ b/ApplicationCode/ReservoirDataModel/Completions/RigFractureTransmissibilityEquations.cpp @@ -20,9 +20,11 @@ #include "cvfBase.h" #include "cvfMath.h" +#include "cvfVector2.h" #include +const double RigFractureTransmissibilityEquations::EPSILON = 1.0e-9; //-------------------------------------------------------------------------------------------------- /// @@ -44,7 +46,7 @@ double RigFractureTransmissibilityEquations::centerToCenterFractureCellTrans(dou } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RigFractureTransmissibilityEquations::fractureCellToWellRadialTrans(double fractureCellConductivity, double fractureCellSizeX, @@ -69,27 +71,52 @@ double RigFractureTransmissibilityEquations::fractureCellToWellRadialTrans(doubl } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RigFractureTransmissibilityEquations::fractureCellToWellLinearTrans(double fractureCellConductivity, +double RigFractureTransmissibilityEquations::fractureCellToWellLinearTrans(double fractureConductivity, double fractureCellSizeX, double fractureCellSizeZ, double perforationLengthVertical, double perforationLengthHorizontal, double perforationEfficiency, double skinfactor, - double cDarcyForRelevantUnit) + double cDarcyForRelevantUnit, + double wellRadius) { - double TcPrefix = 8 * cDarcyForRelevantUnit * fractureCellConductivity; + const double invalidTrans = 1.0e9; + const double epsilon = 1.0e-8; + + double TcPrefix = 8 * cDarcyForRelevantUnit * fractureConductivity; - double DzPerf = perforationLengthVertical * perforationEfficiency; + cvf::Vec2d wellOrientation = cvf::Vec2d(perforationLengthHorizontal, perforationLengthVertical).getNormalized(); + cvf::Vec2d wellRadialVector = wellOrientation.perpendicularVector() * wellRadius; + + double DzPerf = perforationLengthVertical * perforationEfficiency; double DxPerf = perforationLengthHorizontal * perforationEfficiency; - double TcZ = TcPrefix * DzPerf / - (fractureCellSizeX + skinfactor * DzPerf / cvf::PI_D); + double TcZ = 0.0; + if (DzPerf > epsilon) + { + double effectiveFlowLengthHorizontal = fractureCellSizeX - 4.0 * std::abs(wellRadialVector.x()); + double denominatorZ = effectiveFlowLengthHorizontal + skinfactor * DzPerf / cvf::PI_D; + if (denominatorZ < epsilon) + { + return invalidTrans; + } + TcZ = TcPrefix * DzPerf / denominatorZ; + } - double TcX = TcPrefix * DxPerf / - (fractureCellSizeZ + skinfactor* DxPerf / cvf::PI_D); + double TcX = 0.0; + if (DxPerf > epsilon) + { + double effectiveFlowLengthVertical = fractureCellSizeZ - 4.0 * std::abs(wellRadialVector.y()); + double denominatorX = effectiveFlowLengthVertical + skinfactor * DxPerf / cvf::PI_D; + if (denominatorX < epsilon) + { + return invalidTrans; + } + TcX = TcPrefix * DxPerf / denominatorX; + } double Tc = cvf::Math::sqrt(pow(TcX, 2) + pow(TcZ, 2)); return Tc; @@ -97,7 +124,7 @@ double RigFractureTransmissibilityEquations::fractureCellToWellLinearTrans(doubl //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RigFractureTransmissibilityEquations::matrixToFractureTrans(double perm, double NTG, @@ -110,7 +137,7 @@ double RigFractureTransmissibilityEquations::matrixToFractureTrans(double perm, double transmissibility; double slDivPi = 0.0; - if ( cvf::Math::abs(skinfactor) > 1e-9) + if ( cvf::Math::abs(skinfactor) > EPSILON) { slDivPi = (skinfactor * fractureAreaWeightedlength) / cvf::PI_D; } @@ -121,6 +148,44 @@ double RigFractureTransmissibilityEquations::matrixToFractureTrans(double perm, return transmissibility; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigFractureTransmissibilityEquations::effectiveInternalFractureToWellTransPDDHC(double sumScaledMatrixToFractureTrans, + double scaledMatrixToWellTrans) +{ + double divisor = sumScaledMatrixToFractureTrans - scaledMatrixToWellTrans; + if (cvf::Math::abs(divisor) > EPSILON) + { + return (sumScaledMatrixToFractureTrans * scaledMatrixToWellTrans) / divisor; + } + return 0.0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigFractureTransmissibilityEquations::effectiveMatrixToWellTransPDDHC(double sumOriginalMatrixToFractureTrans, + double effectiveInternalFractureToWellTrans) +{ + double divisor = sumOriginalMatrixToFractureTrans + effectiveInternalFractureToWellTrans; + if (cvf::Math::abs(divisor) > EPSILON) + { + return (sumOriginalMatrixToFractureTrans * effectiveInternalFractureToWellTrans) / divisor; + } + return 0.0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigFractureTransmissibilityEquations::matrixPermeability(double permx, double permy, double NTG) +{ + double permxy = cvf::Math::sqrt(permx * permy); + + return permxy * NTG; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -133,3 +198,4 @@ double RigFractureTransmissibilityEquations::centerToEdgeFractureCellTrans(doubl return transmissibility; } + diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigFractureTransmissibilityEquations.h b/ApplicationCode/ReservoirDataModel/Completions/RigFractureTransmissibilityEquations.h index 48073997e0..9d30337964 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigFractureTransmissibilityEquations.h +++ b/ApplicationCode/ReservoirDataModel/Completions/RigFractureTransmissibilityEquations.h @@ -1,26 +1,25 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- class RigFractureTransmissibilityEquations { @@ -33,35 +32,45 @@ class RigFractureTransmissibilityEquations double sideLengthNormalTransCell2, double cDarcyForRelevantUnit); - static double fractureCellToWellRadialTrans(double fractureCellConductivity, + static double fractureCellToWellRadialTrans(double fractureCellConductivity, double fractureCellSizeX, double fractureCellSizeZ, - double wellRadius, - double skinFactor, + double wellRadius, + double skinFactor, double cDarcyForRelevantUnit); static double fractureCellToWellLinearTrans(double fractureConductivity, double fractureCellSizeX, double fractureCellSizeZ, - double perforationLengthVertical, - double perforationLengthHorizontal, + double perforationLengthVertical, + double perforationLengthHorizontal, double perforationEfficiency, double skinfactor, - double cDarcyForRelevantUnit); + double cDarcyForRelevantUnit, + double wellRadius); - static double matrixToFractureTrans(double permX, - double NTG, - double Ay, - double dx, - double skinfactor, - double fractureAreaWeightedlength, + static double matrixToFractureTrans(double permX, + double NTG, + double Ay, + double dx, + double skinfactor, + double fractureAreaWeightedlength, double cDarcy); + static double effectiveInternalFractureToWellTransPDDHC(double sumScaledMatrixToFractureTrans, + double scaledMatrixToWellTrans); + + static double effectiveMatrixToWellTransPDDHC(double sumOriginalMatrixToFractureTrans, + double effectiveInternalFractureToWellTrans); + + static double matrixPermeability(double permx, double permy, double NTG); + private: - static double centerToEdgeFractureCellTrans(double conductivity, - double sideLengthParallellTrans, + static double centerToEdgeFractureCellTrans(double conductivity, + double sideLengthParallellTrans, double sideLengthNormalTrans, double cDarcyForRelevantUnit); - +private: + static const double EPSILON; }; diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigPerforationTransmissibilityEquations.cpp b/ApplicationCode/ReservoirDataModel/Completions/RigPerforationTransmissibilityEquations.cpp new file mode 100644 index 0000000000..d0df5b8a31 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/Completions/RigPerforationTransmissibilityEquations.cpp @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RigPerforationTransmissibilityEquations.h" + +#include "cvfBase.h" +#include "cvfMath.h" + +#include + +const double RigPerforationTransmissibilityEquations::EPSILON = 1.0e-9; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigPerforationTransmissibilityEquations::betaFactor(double intertialCoefficient, + double effectivePermeability, + double permeabilityScalingFactor, + double porosity, + double porosityScalingFactor) +{ + const double scaledEffectivePermeability = std::pow(effectivePermeability, permeabilityScalingFactor); + const double scaledPorosity = std::pow(porosity, porosityScalingFactor); + + return intertialCoefficient * scaledEffectivePermeability * scaledPorosity; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigPerforationTransmissibilityEquations::dFactor(double unitConstant, + double betaFactor, + double effectivePermeability, + double perforationLengthInCell, + double wellRadius, + double gasDenity, + double gasViscosity) +{ + // clang-format off + // + // Ke 1 gasDensity + // D = alpha * beta * -- * -- * ------------ + // h rw gasViscosity + // + // clang-format on + + const double keOverH = effectivePermeability / perforationLengthInCell; + const double oneOverRw = 1.0 / wellRadius; + const double gasDensityOverGasViscosity = gasDenity / gasViscosity; + + const double D = unitConstant * betaFactor * keOverH * oneOverRw * gasDensityOverGasViscosity; + + return D; +} diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigPerforationTransmissibilityEquations.h b/ApplicationCode/ReservoirDataModel/Completions/RigPerforationTransmissibilityEquations.h new file mode 100644 index 0000000000..cc2438ff94 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/Completions/RigPerforationTransmissibilityEquations.h @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RigPerforationTransmissibilityEquations +{ +public: + static double betaFactor(double intertialCoefficient, + double effectivePermeability, + double permeabilityScalingFactor, + double porosity, + double porosityScalingFactor); + + static double dFactor(double unitConstant, + double betaFactor, + double effectivePermeability, + double perforationLengthInCell, + double wellRadius, + double gasDensity, + double gasViscosity); + +private: + static const double EPSILON; +}; diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigTransmissibilityCondenser.cpp b/ApplicationCode/ReservoirDataModel/Completions/RigTransmissibilityCondenser.cpp index 41143b0dc6..c1f425c8cb 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigTransmissibilityCondenser.cpp +++ b/ApplicationCode/ReservoirDataModel/Completions/RigTransmissibilityCondenser.cpp @@ -18,12 +18,54 @@ #include "RigTransmissibilityCondenser.h" +#include "RigActiveCellInfo.h" +#include "RigFractureTransmissibilityEquations.h" #include "RiaLogging.h" +#include "RiaWeightedMeanCalculator.h" + +#include "cvfAssert.h" +#include "cvfBase.h" +#include "cvfMath.h" #include #include #include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigTransmissibilityCondenser::RigTransmissibilityCondenser() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigTransmissibilityCondenser::RigTransmissibilityCondenser(const RigTransmissibilityCondenser& copyFrom) + : m_neighborTransmissibilities(copyFrom.m_neighborTransmissibilities) + , m_condensedTransmissibilities(copyFrom.m_condensedTransmissibilities) + , m_externalCellAddrSet(copyFrom.m_externalCellAddrSet) + , m_TiiInv(copyFrom.m_TiiInv) + , m_Tie(copyFrom.m_Tie) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigTransmissibilityCondenser& RigTransmissibilityCondenser::operator=(const RigTransmissibilityCondenser& rhs) +{ + m_neighborTransmissibilities = rhs.m_neighborTransmissibilities; + m_condensedTransmissibilities = rhs.m_condensedTransmissibilities; + m_externalCellAddrSet = rhs.m_externalCellAddrSet; + m_TiiInv = rhs.m_TiiInv; + m_Tie = rhs.m_Tie; + return *this; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -44,7 +86,10 @@ void RigTransmissibilityCondenser::addNeighborTransmissibility(CellAddress cell1 //-------------------------------------------------------------------------------------------------- std::set RigTransmissibilityCondenser::externalCells() { - calculateCondensedTransmissibilitiesIfNeeded(); + if (m_externalCellAddrSet.empty()) + { + calculateCondensedTransmissibilities(); + } return m_externalCellAddrSet; } @@ -56,7 +101,10 @@ double RigTransmissibilityCondenser::condensedTransmissibility(CellAddress exter { CAF_ASSERT(!(externalCell1 == externalCell2)); - calculateCondensedTransmissibilitiesIfNeeded(); + if (m_condensedTransmissibilities.empty()) + { + calculateCondensedTransmissibilities(); + } if ( externalCell2 < externalCell1 ) std::swap(externalCell1, externalCell2); @@ -72,12 +120,155 @@ double RigTransmissibilityCondenser::condensedTransmissibility(CellAddress exter return 0.0; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map RigTransmissibilityCondenser::scaleMatrixToFracTransByMatrixWellDP( + const RigActiveCellInfo* actCellInfo, double currentWellPressure, const std::vector& currentMatrixPressures, + double* minPressureDrop, double* maxPressureDrop) +{ + std::map originalLumpedMatrixToFractureTrans; // Sum(T_mf) + + double epsilonDeltaPressure = 1.0e-6; + + double minNonZeroDeltaPressure = std::numeric_limits::infinity(); + double maxNonZeroDeltaPressure = -std::numeric_limits::infinity(); + + for (auto it = m_neighborTransmissibilities.begin(); it != m_neighborTransmissibilities.end(); ++it) + { + if (it->first.m_cellIndexSpace == CellAddress::STIMPLAN) + { + for (auto jt = it->second.begin(); jt != it->second.end(); ++jt) + { + if (jt->first.m_cellIndexSpace == CellAddress::ECLIPSE) + { + size_t globalMatrixCellIdx = jt->first.m_globalCellIdx; + size_t eclipseResultIndex = actCellInfo->cellResultIndex(globalMatrixCellIdx); + CVF_ASSERT(eclipseResultIndex < currentMatrixPressures.size()); + double unsignedDeltaPressure = std::abs(currentMatrixPressures[eclipseResultIndex] - currentWellPressure); + double nonZeroDeltaPressure = std::max(epsilonDeltaPressure, unsignedDeltaPressure); + maxNonZeroDeltaPressure = std::max(maxNonZeroDeltaPressure, nonZeroDeltaPressure); + minNonZeroDeltaPressure = std::min(minNonZeroDeltaPressure, nonZeroDeltaPressure); + } + } + } + } + + for (auto it = m_neighborTransmissibilities.begin(); it != m_neighborTransmissibilities.end(); ++it) + { + if (it->first.m_cellIndexSpace == CellAddress::STIMPLAN) + { + for (auto jt = it->second.begin(); jt != it->second.end(); ++jt) + { + if (jt->first.m_cellIndexSpace == CellAddress::ECLIPSE) + { + size_t globalMatrixCellIdx = jt->first.m_globalCellIdx; + size_t eclipseResultIndex = actCellInfo->cellResultIndex(globalMatrixCellIdx); + CVF_ASSERT(eclipseResultIndex < currentMatrixPressures.size()); + + originalLumpedMatrixToFractureTrans[globalMatrixCellIdx] += jt->second; + + double unsignedDeltaPressure = std::abs(currentMatrixPressures[eclipseResultIndex] - currentWellPressure); + double nonZeroDeltaPressure = std::max(epsilonDeltaPressure, unsignedDeltaPressure); + + jt->second *= nonZeroDeltaPressure / maxNonZeroDeltaPressure; + } + } + } + } + + if (minPressureDrop && minNonZeroDeltaPressure != std::numeric_limits::infinity()) + { + *minPressureDrop = minNonZeroDeltaPressure; + } + if (maxPressureDrop && maxNonZeroDeltaPressure != std::numeric_limits::infinity()) + { + *maxPressureDrop = maxNonZeroDeltaPressure; + } + + return originalLumpedMatrixToFractureTrans; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map RigTransmissibilityCondenser::calculateFicticiousFractureToWellTransmissibilities() +{ + std::map matrixToAllFracturesTrans; + for (auto it = m_neighborTransmissibilities.begin(); it != m_neighborTransmissibilities.end(); ++it) + { + if (it->first.m_cellIndexSpace == CellAddress::STIMPLAN) + { + for (auto jt = it->second.begin(); jt != it->second.end(); ++jt) + { + if (jt->first.m_cellIndexSpace == CellAddress::ECLIPSE) + { + size_t globalMatrixCellIdx = jt->first.m_globalCellIdx; + // T'_mf + double matrixToFractureTrans = jt->second; + // Sum(T'_mf) + matrixToAllFracturesTrans[globalMatrixCellIdx] += matrixToFractureTrans; + } + } + } + } + + std::map fictitiousFractureToWellTrans; // T'_fjw + for (const CellAddress& externalCell : m_externalCellAddrSet) + { + if (externalCell.m_cellIndexSpace == CellAddress::ECLIPSE) + { + size_t globalMatrixCellIdx = externalCell.m_globalCellIdx; + // Sum(T'_mf) + double scaledMatrixToFractureTrans = matrixToAllFracturesTrans[globalMatrixCellIdx]; + // T'mw + double scaledMatrixToWellTrans = + condensedTransmissibility(externalCell, {true, RigTransmissibilityCondenser::CellAddress::WELL, 1}); + // T'_fjw + fictitiousFractureToWellTrans[globalMatrixCellIdx] = + RigFractureTransmissibilityEquations::effectiveInternalFractureToWellTransPDDHC(scaledMatrixToFractureTrans, + scaledMatrixToWellTrans); + } + } + return fictitiousFractureToWellTrans; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::map RigTransmissibilityCondenser::calculateEffectiveMatrixToWellTransmissibilities( + const std::map& originalLumpedMatrixToFractureTrans, + const std::map& ficticuousFractureToWellTransMap) +{ + std::map effectiveMatrixToWellTrans; + for (const CellAddress& externalCell : m_externalCellAddrSet) + { + if (externalCell.m_cellIndexSpace == CellAddress::ECLIPSE) + { + size_t globalMatrixCellIdx = externalCell.m_globalCellIdx; + + auto matrixToFractureIt = originalLumpedMatrixToFractureTrans.find(globalMatrixCellIdx); + CVF_ASSERT(matrixToFractureIt != originalLumpedMatrixToFractureTrans.end()); + // Sum(T_mf) + double lumpedOriginalMatrixToFractureT = matrixToFractureIt->second; + // T'_fjw + auto fictitiousFractureToWellIt = ficticuousFractureToWellTransMap.find(globalMatrixCellIdx); + CVF_ASSERT(fictitiousFractureToWellIt != ficticuousFractureToWellTransMap.end()); + double fictitiousFractureToWellTrans = fictitiousFractureToWellIt->second; + // T^dp_mw + effectiveMatrixToWellTrans[globalMatrixCellIdx] = + RigFractureTransmissibilityEquations::effectiveMatrixToWellTransPDDHC(lumpedOriginalMatrixToFractureT, fictitiousFractureToWellTrans); + } + } + return effectiveMatrixToWellTrans; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigTransmissibilityCondenser::calculateCondensedTransmissibilitiesIfNeeded() +void RigTransmissibilityCondenser::calculateCondensedTransmissibilities() { - if (m_condensedTransmissibilities.size()) return; + if (m_neighborTransmissibilities.empty()) return; // Find all equations, and their total ordering @@ -145,10 +336,22 @@ void RigTransmissibilityCondenser::calculateCondensedTransmissibilitiesIfNeeded( // std::cout << "T = " << std::endl << totalSystem << std::endl; int externalEquationCount = totalEquationCount - internalEquationCount; - MatrixXd condensedSystem = totalSystem.bottomRightCorner(externalEquationCount, externalEquationCount) - - totalSystem.bottomLeftCorner(externalEquationCount, internalEquationCount) - * totalSystem.topLeftCorner(internalEquationCount, internalEquationCount).inverse() - * totalSystem.topRightCorner(internalEquationCount, externalEquationCount ); + + MatrixXd condensedSystem; + MatrixXd Tee = totalSystem.bottomRightCorner(externalEquationCount, externalEquationCount); + + if (internalEquationCount == 0) + { + condensedSystem = Tee; + } + else + { + MatrixXd Tei = totalSystem.bottomLeftCorner(externalEquationCount, internalEquationCount); + m_TiiInv = totalSystem.topLeftCorner(internalEquationCount, internalEquationCount).inverse(); + m_Tie = totalSystem.topRightCorner(internalEquationCount, externalEquationCount); + condensedSystem = Tee - Tei * m_TiiInv * m_Tie; + } + // std::cout << "Te = " << std::endl << condensedSystem << std::endl << std::endl; @@ -172,10 +375,6 @@ void RigTransmissibilityCondenser::calculateCondensedTransmissibilitiesIfNeeded( } } - - - - #include "RimStimPlanFractureTemplate.h" #include "RigMainGrid.h" #include "RigFractureCell.h" diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigTransmissibilityCondenser.h b/ApplicationCode/ReservoirDataModel/Completions/RigTransmissibilityCondenser.h index 7664b5f87c..3a8078fd5b 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigTransmissibilityCondenser.h +++ b/ApplicationCode/ReservoirDataModel/Completions/RigTransmissibilityCondenser.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -20,54 +20,68 @@ #include "cafAssert.h" +#include + #include -#include #include +#include +class RigActiveCellInfo; class RigMainGrid; class RimStimPlanFractureTemplate; class RigFractureGrid; //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- class RigTransmissibilityCondenser { public: + RigTransmissibilityCondenser(); + RigTransmissibilityCondenser(const RigTransmissibilityCondenser& copyFrom); + RigTransmissibilityCondenser& operator=(const RigTransmissibilityCondenser& rhs); + class CellAddress { - public: - enum CellIndexSpace { ECLIPSE, STIMPLAN, WELL}; - - CellAddress(): m_isExternal(false), - m_cellIndexSpace(STIMPLAN), - m_globalCellIdx(-1) - {} - CellAddress(bool isExternal, - CellIndexSpace cellType, - size_t globalCellIdx) - : m_isExternal(isExternal), - m_cellIndexSpace(cellType), - m_globalCellIdx(globalCellIdx) - {} + public: + enum CellIndexSpace + { + ECLIPSE, + STIMPLAN, + WELL + }; + + CellAddress() + : m_isExternal(false) + , m_cellIndexSpace(STIMPLAN) + , m_globalCellIdx(-1) + { + } + CellAddress(bool isExternal, CellIndexSpace cellType, size_t globalCellIdx) + : m_isExternal(isExternal) + , m_cellIndexSpace(cellType) + , m_globalCellIdx(globalCellIdx) + { + } bool m_isExternal; CellIndexSpace m_cellIndexSpace; size_t m_globalCellIdx; - bool operator==(const CellAddress& o) { - return (m_isExternal == o.m_isExternal) && (m_cellIndexSpace == o.m_cellIndexSpace) && (m_globalCellIdx == o.m_globalCellIdx); + return (m_isExternal == o.m_isExternal) && (m_cellIndexSpace == o.m_cellIndexSpace) && + (m_globalCellIdx == o.m_globalCellIdx); } // Ordering external after internal is important for the matrix order internally bool operator<(const CellAddress& other) const { - if (m_isExternal != other.m_isExternal) return !m_isExternal; // Internal cells < External cells - if (m_cellIndexSpace != other.m_cellIndexSpace)return m_cellIndexSpace < other.m_cellIndexSpace; // Eclipse < StimPlan - if (m_globalCellIdx != other.m_globalCellIdx) return m_globalCellIdx < other.m_globalCellIdx; + if (m_isExternal != other.m_isExternal) return !m_isExternal; // Internal cells < External cells + if (m_cellIndexSpace != other.m_cellIndexSpace) + return m_cellIndexSpace < other.m_cellIndexSpace; // Eclipse < StimPlan + if (m_globalCellIdx != other.m_globalCellIdx) return m_globalCellIdx < other.m_globalCellIdx; return false; } }; @@ -76,15 +90,29 @@ class RigTransmissibilityCondenser std::set externalCells(); - double condensedTransmissibility( CellAddress externalCell1, CellAddress externalCell2); + double condensedTransmissibility(CellAddress externalCell1, CellAddress externalCell2); std::string neighborTransDebugOutput(const RigMainGrid* mainGrid, const RigFractureGrid* fractureGrid); std::string condensedTransDebugOutput(const RigMainGrid* mainGrid, const RigFractureGrid* fractureGrid); -private: - void calculateCondensedTransmissibilitiesIfNeeded(); + std::map scaleMatrixToFracTransByMatrixWellDP(const RigActiveCellInfo* actCellInfo, double currentWellPressure, const std::vector& currentMatrixPressures, double* minPressureDrop, double* maxPressureDrop); + + std::map calculateFicticiousFractureToWellTransmissibilities(); + std::map + calculateEffectiveMatrixToWellTransmissibilities(const std::map& originalLumpedMatrixToFractureTrans, + const std::map& ficticuousFractureToWellTransMap); + + void calculateCondensedTransmissibilities(); + +protected: + typedef std::pair> ConnectionTransmissibility; + typedef std::map> ConnectionTransmissibilities; + + ConnectionTransmissibilities m_neighborTransmissibilities; + ConnectionTransmissibilities m_condensedTransmissibilities; - std::map > m_neighborTransmissibilities; - std::map > m_condensedTransmissibilities; std::set m_externalCellAddrSet; -}; + + Eigen::MatrixXd m_TiiInv; + Eigen::MatrixXd m_Tie; +}; diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigVirtualPerforationTransmissibilities.cpp b/ApplicationCode/ReservoirDataModel/Completions/RigVirtualPerforationTransmissibilities.cpp index 12a4fafd3d..0c885c2465 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigVirtualPerforationTransmissibilities.cpp +++ b/ApplicationCode/ReservoirDataModel/Completions/RigVirtualPerforationTransmissibilities.cpp @@ -32,15 +32,15 @@ void CompletionDataFrame::setCompletionData(const std::vector { for (auto& completion : completions) { - auto it = m_multipleCompletionsPerEclipseCell.find(completion.completionDataGridCell()); + auto it = m_multipleCompletionsPerEclipseCell.find(completion.completionDataGridCell().globalCellIndex()); if (it != m_multipleCompletionsPerEclipseCell.end()) { it->second.push_back(completion); } else { - m_multipleCompletionsPerEclipseCell.insert(std::pair>( - completion.completionDataGridCell(), std::vector{completion})); + m_multipleCompletionsPerEclipseCell.insert(std::pair>( + completion.completionDataGridCell().globalCellIndex(), std::vector{completion})); } } } @@ -48,8 +48,7 @@ void CompletionDataFrame::setCompletionData(const std::vector //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::map>& - CompletionDataFrame::multipleCompletionsPerEclipseCell() const +const std::map>& CompletionDataFrame::multipleCompletionsPerEclipseCell() const { return m_multipleCompletionsPerEclipseCell; } @@ -94,11 +93,11 @@ void RigVirtualPerforationTransmissibilities::setCompletionDataForWellPath( //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::map>& +const std::map>& RigVirtualPerforationTransmissibilities::multipleCompletionsPerEclipseCell(const RimWellPath* wellPath, size_t timeStepIndex) const { - static std::map> dummy; + static std::map> dummy; auto item = m_mapFromWellToCompletionData.find(wellPath); if (item != m_mapFromWellToCompletionData.end()) diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigVirtualPerforationTransmissibilities.h b/ApplicationCode/ReservoirDataModel/Completions/RigVirtualPerforationTransmissibilities.h index 411d2a28be..a3a9b86e2b 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigVirtualPerforationTransmissibilities.h +++ b/ApplicationCode/ReservoirDataModel/Completions/RigVirtualPerforationTransmissibilities.h @@ -41,10 +41,10 @@ class CompletionDataFrame void setCompletionData(const std::vector& completions); - const std::map>& multipleCompletionsPerEclipseCell() const; + const std::map>& multipleCompletionsPerEclipseCell() const; private: - std::map> m_multipleCompletionsPerEclipseCell; + std::map> m_multipleCompletionsPerEclipseCell; }; //-------------------------------------------------------------------------------------------------- @@ -54,20 +54,22 @@ class RigVirtualPerforationTransmissibilities : public cvf::Object { public: RigVirtualPerforationTransmissibilities(); - ~RigVirtualPerforationTransmissibilities(); + ~RigVirtualPerforationTransmissibilities() override; - void setCompletionDataForWellPath(const RimWellPath* wellPath, const std::vector>& completionsPerTimeStep); + void setCompletionDataForWellPath(const RimWellPath* wellPath, + const std::vector>& completionsPerTimeStep); - const std::map>& - multipleCompletionsPerEclipseCell(const RimWellPath* wellPath, size_t timeStepIndex) const; + const std::map>& multipleCompletionsPerEclipseCell(const RimWellPath* wellPath, + size_t timeStepIndex) const; - void setCompletionDataForSimWell(const RigSimWellData* simWellData, const std::vector>& completionsPerTimeStep); - - const std::vector& - completionsForSimWell(const RigSimWellData* simWellData, size_t timeStepIndex) const; + void setCompletionDataForSimWell(const RigSimWellData* simWellData, + const std::vector>& completionsPerTimeStep); + + const std::vector& completionsForSimWell(const RigSimWellData* simWellData, size_t timeStepIndex) const; void computeMinMax(double* minValue, double* maxValue, double* posClosestToZero, double* negClosestToZero) const; + private: - std::map> m_mapFromWellToCompletionData; + std::map> m_mapFromWellToCompletionData; std::map>> m_mapFromSimWellToCompletionData; }; diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigWellPathStimplanIntersector.cpp b/ApplicationCode/ReservoirDataModel/Completions/RigWellPathStimplanIntersector.cpp index 78c39ad3a2..a3c5ccb0e0 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigWellPathStimplanIntersector.cpp +++ b/ApplicationCode/ReservoirDataModel/Completions/RigWellPathStimplanIntersector.cpp @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -34,109 +34,122 @@ #include - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RigWellPathStimplanIntersector::RigWellPathStimplanIntersector(const RigWellPath* wellpathGeom, const RimFracture* rimFracture) +RigWellPathStimplanIntersector::RigWellPathStimplanIntersector(const RigWellPath* wellPathGeom, const RimFracture* rimFracture) { - std::vector wellPathPoints = wellpathGeom->wellPathPointsIncludingInterpolatedIntersectionPoint(rimFracture->fractureMD()); - cvf::Mat4d fractureXf = rimFracture->transformMatrix(); - double wellRadius = rimFracture->wellRadius(); - std::vector > stpCellPolygons; + std::vector wellPathPoints = + wellPathGeom->wellPathPointsIncludingInterpolatedIntersectionPoint(rimFracture->fractureMD()); + cvf::Mat4d fractureXf = rimFracture->transformMatrix(); + double wellRadius = rimFracture->wellRadius(); + + std::vector> fractureGridCellPolygons; { RimFractureTemplate* fractureTemplate = rimFracture->fractureTemplate(); - if(fractureTemplate) + if (fractureTemplate && fractureTemplate->fractureGrid()) { const std::vector& stpCells = fractureTemplate->fractureGrid()->fractureCells(); - for ( const auto& stpCell: stpCells ) stpCellPolygons.push_back(stpCell.getPolygon()); + for (const auto& stpCell : stpCells) + { + fractureGridCellPolygons.push_back(stpCell.getPolygon()); + } } } double perforationLength = rimFracture->perforationLength(); - calculate(fractureXf, wellPathPoints, wellRadius, perforationLength, stpCellPolygons, m_stimPlanCellIdxToIntersectionInfoMap); + calculate(fractureXf, + wellPathPoints, + wellRadius, + perforationLength, + fractureGridCellPolygons, + m_stimPlanCellIdxToIntersectionInfoMap); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const std::map& RigWellPathStimplanIntersector::intersections() const +const std::map& + RigWellPathStimplanIntersector::intersections() const { return m_stimPlanCellIdxToIntersectionInfoMap; } //-------------------------------------------------------------------------------------------------- -/// Todo: Use only the perforated parts of the well path +/// //-------------------------------------------------------------------------------------------------- -void RigWellPathStimplanIntersector::calculate(const cvf::Mat4d &fractureXf, - const std::vector& wellPathPointsOrg, - double wellRadius, - double perforationLength, - const std::vector >& stpCellPolygons, - std::map& m_stimPlanCellIdxToIntersectionInfoMap) +void RigWellPathStimplanIntersector::calculate(const cvf::Mat4d& fractureXf, + const std::vector& wellPathPointsDomainCoords, + double wellRadius, + double perforationLength, + const std::vector>& fractureGridCellPolygons, + std::map& m_stimPlanCellIdxToIntersectionInfoMap) { cvf::Mat4d toFractureXf = fractureXf.getInverted(); std::vector perforationLengthBoundingBoxPolygon; - double cicleRadius = perforationLength / 2; - int pointsInCirclePolygon = 20; - for (int i = 0; i < pointsInCirclePolygon; i++) { - double x = cicleRadius * cvf::Math::cos(i * (2 * cvf::PI_D / pointsInCirclePolygon)); - double y = cicleRadius * cvf::Math::sin(i * (2 * cvf::PI_D / pointsInCirclePolygon)); - perforationLengthBoundingBoxPolygon.push_back(cvf::Vec3d(x, y, 0)); + double cicleRadius = perforationLength / 2; + int pointsInCirclePolygon = 20; + + for (int i = 0; i < pointsInCirclePolygon; i++) + { + double x = cicleRadius * cvf::Math::cos(i * (2 * cvf::PI_D / pointsInCirclePolygon)); + double y = cicleRadius * cvf::Math::sin(i * (2 * cvf::PI_D / pointsInCirclePolygon)); + perforationLengthBoundingBoxPolygon.push_back(cvf::Vec3d(x, y, 0)); + } } // Convert well path to fracture template system std::vector fractureRelativeWellPathPoints; - for ( auto & wellPPoint : wellPathPointsOrg ) fractureRelativeWellPathPoints.push_back(wellPPoint.getTransformedPoint( toFractureXf)); + for (const auto& wellPPoint : wellPathPointsDomainCoords) + { + fractureRelativeWellPathPoints.push_back(wellPPoint.getTransformedPoint(toFractureXf)); + } - // Clip well path to fracture domain + // Clip well path to fracture domain - std::vector > wellPathPartsWithinFracture = - RigCellGeometryTools::clipPolylineByPolygon(fractureRelativeWellPathPoints, - perforationLengthBoundingBoxPolygon, - RigCellGeometryTools::INTERPOLATE_LINE_Z); + std::vector> wellPathPartsWithinFracture = RigCellGeometryTools::clipPolylineByPolygon( + fractureRelativeWellPathPoints, perforationLengthBoundingBoxPolygon, RigCellGeometryTools::INTERPOLATE_LINE_Z); // Remove the part of the well path that is more than well radius away from the fracture plane - std::vector< std::vector< cvf::Vec3d > > intersectingWellPathParts; + std::vector> intersectingWellPathParts; - for ( const auto& part : wellPathPartsWithinFracture ) + for (const auto& part : wellPathPartsWithinFracture) { - std::vector< cvf::Vec3d > currentIntersectingWpPart; - for ( size_t vxIdx = 0; vxIdx < part.size() -1; ++vxIdx ) + std::vector currentIntersectingWpPart; + for (size_t vxIdx = 0; vxIdx < part.size() - 1; ++vxIdx) { double thisAbsZ = fabs(part[vxIdx].z()); double nextAbsZ = fabs(part[vxIdx + 1].z()); - double thisZ = part[vxIdx].z(); - double nextZ = part[vxIdx + 1].z(); + double thisZ = part[vxIdx].z(); + double nextZ = part[vxIdx + 1].z(); - if ( thisAbsZ >= wellRadius && nextAbsZ >= wellRadius ) + if (thisAbsZ >= wellRadius && nextAbsZ >= wellRadius) { - if ( (thisZ >= 0 && nextZ >= 0) - || (thisZ <= 0 && nextZ <= 0 ) ) + if ((thisZ >= 0 && nextZ >= 0) || (thisZ <= 0 && nextZ <= 0)) { continue; // Outside } else // In and out { { - double wellRadiusDistFromPlane = thisZ > 0 ? wellRadius: -wellRadius; + double wellRadiusDistFromPlane = thisZ > 0 ? wellRadius : -wellRadius; - double fraction = (wellRadiusDistFromPlane - thisZ)/ (nextZ - thisZ); + double fraction = (wellRadiusDistFromPlane - thisZ) / (nextZ - thisZ); - cvf::Vec3d intersectPoint = part[vxIdx] + fraction * (part[vxIdx+1] - part[vxIdx]); + cvf::Vec3d intersectPoint = part[vxIdx] + fraction * (part[vxIdx + 1] - part[vxIdx]); currentIntersectingWpPart.push_back(intersectPoint); } { - double wellRadiusDistFromPlane = nextZ > 0 ? wellRadius: -wellRadius; + double wellRadiusDistFromPlane = nextZ > 0 ? wellRadius : -wellRadius; - double fraction = (wellRadiusDistFromPlane - thisZ)/ (nextZ - thisZ); + double fraction = (wellRadiusDistFromPlane - thisZ) / (nextZ - thisZ); - cvf::Vec3d intersectPoint = part[vxIdx] + fraction * (part[vxIdx+1] - part[vxIdx]); + cvf::Vec3d intersectPoint = part[vxIdx] + fraction * (part[vxIdx + 1] - part[vxIdx]); currentIntersectingWpPart.push_back(intersectPoint); intersectingWellPathParts.push_back(currentIntersectingWpPart); @@ -145,21 +158,21 @@ void RigWellPathStimplanIntersector::calculate(const cvf::Mat4d &fractureXf, continue; } } - if ( thisAbsZ < wellRadius && nextAbsZ < wellRadius ) // Inside + if (thisAbsZ < wellRadius && nextAbsZ < wellRadius) // Inside { currentIntersectingWpPart.push_back(part[vxIdx]); continue; } - if ( thisAbsZ < wellRadius && nextAbsZ >= wellRadius ) // Going out + if (thisAbsZ < wellRadius && nextAbsZ >= wellRadius) // Going out { currentIntersectingWpPart.push_back(part[vxIdx]); - double wellRadiusDistFromPlane = nextZ > 0 ? wellRadius: -wellRadius; + double wellRadiusDistFromPlane = nextZ > 0 ? wellRadius : -wellRadius; + + double fraction = (wellRadiusDistFromPlane - thisZ) / (nextZ - thisZ); - double fraction = (wellRadiusDistFromPlane - thisZ)/ (nextZ - thisZ); - - cvf::Vec3d intersectPoint = part[vxIdx] + fraction * (part[vxIdx+1] - part[vxIdx]); + cvf::Vec3d intersectPoint = part[vxIdx] + fraction * (part[vxIdx + 1] - part[vxIdx]); currentIntersectingWpPart.push_back(intersectPoint); intersectingWellPathParts.push_back(currentIntersectingWpPart); @@ -167,54 +180,51 @@ void RigWellPathStimplanIntersector::calculate(const cvf::Mat4d &fractureXf, continue; } - if ( thisAbsZ >= wellRadius && nextAbsZ < wellRadius ) // Going in + if (thisAbsZ >= wellRadius && nextAbsZ < wellRadius) // Going in { - double wellRadiusDistFromPlane = thisZ > 0 ? wellRadius: -wellRadius; + double wellRadiusDistFromPlane = thisZ > 0 ? wellRadius : -wellRadius; - double fraction = (wellRadiusDistFromPlane - thisZ)/ (nextZ - thisZ); + double fraction = (wellRadiusDistFromPlane - thisZ) / (nextZ - thisZ); - cvf::Vec3d intersectPoint = part[vxIdx] + fraction * (part[vxIdx+1] - part[vxIdx]); + cvf::Vec3d intersectPoint = part[vxIdx] + fraction * (part[vxIdx + 1] - part[vxIdx]); currentIntersectingWpPart.push_back(intersectPoint); continue; } - } // Add last point if it is within the radius - if (part.size() > 1 && fabs(part.back().z()) < wellRadius) + if (part.size() > 1 && fabs(part.back().z()) < wellRadius) { currentIntersectingWpPart.push_back(part.back()); } - if ( !currentIntersectingWpPart.empty() ) + if (!currentIntersectingWpPart.empty()) { intersectingWellPathParts.push_back(currentIntersectingWpPart); } } - // Find the StimPlan cells touched by the intersecting well path parts + // Find the StimPlan cells touched by the intersecting well path parts - for ( size_t cIdx = 0; cIdx < stpCellPolygons.size(); ++ cIdx ) + for (size_t cIdx = 0; cIdx < fractureGridCellPolygons.size(); ++cIdx) { - const std::vector& cellPolygon = stpCellPolygons[cIdx]; - for ( const auto& wellpathPart :intersectingWellPathParts ) + const std::vector& cellPolygon = fractureGridCellPolygons[cIdx]; + for (const auto& wellpathPart : intersectingWellPathParts) { - std::vector > wellPathPartsInPolygon = - RigCellGeometryTools::clipPolylineByPolygon(wellpathPart, - cellPolygon, - RigCellGeometryTools::USE_HUGEVAL); - for ( const auto& wellPathPartInCell: wellPathPartsInPolygon ) + std::vector> wellPathPartsInPolygon = + RigCellGeometryTools::clipPolylineByPolygon(wellpathPart, cellPolygon, RigCellGeometryTools::USE_HUGEVAL); + for (const auto& wellPathPartInCell : wellPathPartsInPolygon) { - if ( !wellPathPartInCell.empty() ) + if (!wellPathPartInCell.empty()) { int endpointCount = 0; - if ( wellPathPartInCell.front().z() != HUGE_VAL ) ++endpointCount; - if ( wellPathPartInCell.back().z() != HUGE_VAL ) ++endpointCount; + if (wellPathPartInCell.front().z() != HUGE_VAL) ++endpointCount; + if (wellPathPartInCell.back().z() != HUGE_VAL) ++endpointCount; cvf::Vec3d intersectionLength = (wellPathPartInCell.back() - wellPathPartInCell.front()); - double xLengthInCell = fabs(intersectionLength.x()); - double yLengthInCell = fabs(intersectionLength.y()); + double xLengthInCell = fabs(intersectionLength.x()); + double yLengthInCell = fabs(intersectionLength.y()); m_stimPlanCellIdxToIntersectionInfoMap[cIdx].endpointCount += endpointCount; m_stimPlanCellIdxToIntersectionInfoMap[cIdx].hlength += xLengthInCell; diff --git a/ApplicationCode/ReservoirDataModel/Completions/RigWellPathStimplanIntersector.h b/ApplicationCode/ReservoirDataModel/Completions/RigWellPathStimplanIntersector.h index dc5d38e823..e85005db8a 100644 --- a/ApplicationCode/ReservoirDataModel/Completions/RigWellPathStimplanIntersector.h +++ b/ApplicationCode/ReservoirDataModel/Completions/RigWellPathStimplanIntersector.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -28,52 +28,61 @@ class RigWellPath; class RimFracture; class RigWellPathStimplanIntersectorTester; - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- class RigWellPathStimplanIntersector { public: - struct WellCellIntersection - { - WellCellIntersection():hlength(0.0), vlength(0.0), endpointCount(0) {} - double hlength; - double vlength; - int endpointCount; + struct WellCellIntersection + { + WellCellIntersection() + : hlength(0.0) + , vlength(0.0) + , endpointCount(0) + { + } + double hlength; + double vlength; + int endpointCount; + + double computeLength() const + { + return cvf::Math::sqrt(hlength * hlength + vlength * vlength); + } }; RigWellPathStimplanIntersector(const RigWellPath* wellpathGeom, const RimFracture* rimFracture); - const std::map& intersections() const; + const std::map& intersections() const; private: friend class RigWellPathStimplanIntersectorTester; - static void calculate(const cvf::Mat4d& fractureXf, - const std::vector& wellPathPoints, - double wellRadius, - double perforationLength, - const std::vector >& stpCellPolygons, - std::map& stimPlanCellIdxToIntersectionInfoMap); + static void calculate(const cvf::Mat4d& fractureXf, + const std::vector& wellPathPoints, + double wellRadius, + double perforationLength, + const std::vector>& stpCellPolygons, + std::map& stimPlanCellIdxToIntersectionInfoMap); - std::map m_stimPlanCellIdxToIntersectionInfoMap; + std::map m_stimPlanCellIdxToIntersectionInfoMap; }; - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- class RigWellPathStimplanIntersectorTester { public: - static void testCalculate(const cvf::Mat4d& fractureXf, - const std::vector& wellPathPoints, - double wellRadius, - double perforationLength, - const std::vector >& stpCellPolygons, - std::map& stimPlanCellIdxToIntersectionInfoMap) + static void testCalculate( + const cvf::Mat4d& fractureXf, + const std::vector& wellPathPoints, + double wellRadius, + double perforationLength, + const std::vector>& stpCellPolygons, + std::map& stimPlanCellIdxToIntersectionInfoMap) { - RigWellPathStimplanIntersector::calculate(fractureXf, wellPathPoints, wellRadius, perforationLength, stpCellPolygons, stimPlanCellIdxToIntersectionInfoMap); + RigWellPathStimplanIntersector::calculate( + fractureXf, wellPathPoints, wellRadius, perforationLength, stpCellPolygons, stimPlanCellIdxToIntersectionInfoMap); } - }; diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp index 0ff7038692..f2fe73a522 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.cpp @@ -3,38 +3,36 @@ // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RigActiveCellInfo.h" - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RigActiveCellInfo::RigActiveCellInfo() - : m_reservoirActiveCellCount(0), - m_reservoirCellResultCount(0), - m_activeCellPositionMin(cvf::Vec3d::ZERO), - m_activeCellPositionMax(cvf::Vec3d::ZERO) + : m_reservoirActiveCellCount(0) + , m_reservoirCellResultCount(0) + , m_activeCellPositionMin(cvf::Vec3d::ZERO) + , m_activeCellPositionMax(cvf::Vec3d::ZERO) { - } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::setReservoirCellCount(size_t reservoirCellCount) { @@ -58,7 +56,7 @@ size_t RigActiveCellInfo::reservoirCellResultCount() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RigActiveCellInfo::isActive(size_t reservoirCellIndex) const { @@ -73,7 +71,7 @@ bool RigActiveCellInfo::isActive(size_t reservoirCellIndex) const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigActiveCellInfo::cellResultIndex(size_t reservoirCellIndex) const { @@ -88,7 +86,7 @@ size_t RigActiveCellInfo::cellResultIndex(size_t reservoirCellIndex) const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::setCellResultIndex(size_t reservoirCellIndex, size_t reservoirCellResultIndex) { @@ -103,7 +101,7 @@ void RigActiveCellInfo::setCellResultIndex(size_t reservoirCellIndex, size_t res } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::setGridCount(size_t gridCount) { @@ -111,7 +109,7 @@ void RigActiveCellInfo::setGridCount(size_t gridCount) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::setGridActiveCellCounts(size_t gridIndex, size_t activeCellCount) { @@ -121,7 +119,7 @@ void RigActiveCellInfo::setGridActiveCellCounts(size_t gridIndex, size_t activeC } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::computeDerivedData() { @@ -134,7 +132,7 @@ void RigActiveCellInfo::computeDerivedData() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigActiveCellInfo::reservoirActiveCellCount() const { @@ -142,7 +140,7 @@ size_t RigActiveCellInfo::reservoirActiveCellCount() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::setIJKBoundingBox(const cvf::Vec3st& min, const cvf::Vec3st& max) { @@ -151,7 +149,7 @@ void RigActiveCellInfo::setIJKBoundingBox(const cvf::Vec3st& min, const cvf::Vec } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::IJKBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const { @@ -160,14 +158,14 @@ void RigActiveCellInfo::IJKBoundingBox(cvf::Vec3st& min, cvf::Vec3st& max) const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::gridActiveCellCounts(size_t gridIndex, size_t& activeCellCount) const { activeCellCount = m_perGridActiveCellInfo[gridIndex].activeCellCount(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::BoundingBox RigActiveCellInfo::geometryBoundingBox() const { @@ -175,7 +173,7 @@ cvf::BoundingBox RigActiveCellInfo::geometryBoundingBox() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::setGeometryBoundingBox(cvf::BoundingBox bb) { @@ -183,20 +181,41 @@ void RigActiveCellInfo::setGeometryBoundingBox(cvf::BoundingBox bb) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::clear() { m_perGridActiveCellInfo.clear(); m_cellIndexToResultIndex.clear(); m_reservoirActiveCellCount = 0; - m_activeCellPositionMin = cvf::Vec3st(0,0,0); - m_activeCellPositionMax = cvf::Vec3st(0,0,0); + m_activeCellPositionMin = cvf::Vec3st(0, 0, 0); + m_activeCellPositionMax = cvf::Vec3st(0, 0, 0); m_activeCellsBoundingBox.reset(); } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void RigActiveCellInfo::addLgr(size_t cellCount) +{ + size_t currentGridCount = m_perGridActiveCellInfo.size(); + size_t currentActiveCellCount = reservoirActiveCellCount(); + size_t currentReservoirCellCount = reservoirCellCount(); + + setGridCount(currentGridCount + 1); + setGridActiveCellCounts(currentGridCount, cellCount); + setReservoirCellCount(currentReservoirCellCount + cellCount); + + computeDerivedData(); + + for (size_t i = 0; i < cellCount; i++) + { + setCellResultIndex(currentReservoirCellCount + i, currentActiveCellCount + i); + } +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- bool RigActiveCellInfo::isCoarseningActive() const { @@ -204,15 +223,15 @@ bool RigActiveCellInfo::isCoarseningActive() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RigActiveCellInfo::GridActiveCellCounts::GridActiveCellCounts() -: m_activeCellCount(0) + : m_activeCellCount(0) { } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigActiveCellInfo::GridActiveCellCounts::activeCellCount() const { @@ -220,7 +239,7 @@ size_t RigActiveCellInfo::GridActiveCellCounts::activeCellCount() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigActiveCellInfo::GridActiveCellCounts::setActiveCellCount(size_t activeCellCount) { diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h index 0a2b3e7b8a..c3d6cf1fca 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellInfo.h @@ -28,7 +28,6 @@ #include - class RigActiveCellInfo : public cvf::Object { public: @@ -57,6 +56,8 @@ class RigActiveCellInfo : public cvf::Object void clear(); + void addLgr(size_t cellCount); + private: class GridActiveCellCounts { diff --git a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h index 41a27903a3..745d658969 100644 --- a/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigActiveCellsResultAccessor.h @@ -33,11 +33,11 @@ class RigActiveCellsResultAccessor : public RigResultAccessor public: RigActiveCellsResultAccessor(const RigGridBase* grid, const std::vector* reservoirResultValues, const RigActiveCellInfo* activeCellInfo); - virtual double cellScalar(size_t gridLocalCellIndex) const; - virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + double cellScalar(size_t gridLocalCellIndex) const override; + double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const override; - virtual double cellScalarGlobIdx(size_t globCellIndex) const; - virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; + double cellScalarGlobIdx(size_t globCellIndex) const override; + double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const override; private: const RigActiveCellInfo* m_activeCellInfo; diff --git a/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h index 81c9298b33..7fcc726eac 100644 --- a/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigAllGridCellsResultAccessor.h @@ -32,10 +32,10 @@ class RigAllGridCellsResultAccessor : public RigResultAccessor public: RigAllGridCellsResultAccessor(const RigGridBase* grid, const std::vector* reservoirResultValues); - virtual double cellScalar(size_t gridLocalCellIndex) const; - virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; - virtual double cellScalarGlobIdx(size_t globCellIndex) const; - virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; + double cellScalar(size_t gridLocalCellIndex) const override; + double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const override; + double cellScalarGlobIdx(size_t globCellIndex) const override; + double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const override; private: const RigGridBase* m_grid; diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp index f7bbe9defe..156fac906c 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.cpp @@ -3,28 +3,31 @@ // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RigCaseCellResultsData.h" +#include "RiaApplication.h" +#include "RiaLogging.h" + #include "RigEclipseCaseData.h" #include "RigEclipseMultiPropertyStatCalc.h" #include "RigEclipseNativeStatCalc.h" -#include "RigMainGrid.h" #include "RigEclipseResultInfo.h" +#include "RigMainGrid.h" #include "RigStatisticsDataCache.h" #include "RigStatisticsMath.h" @@ -39,12 +42,14 @@ #include +#include #include //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RigCaseCellResultsData::RigCaseCellResultsData(RigEclipseCaseData* ownerCaseData) : m_activeCellInfo(nullptr) +RigCaseCellResultsData::RigCaseCellResultsData(RigEclipseCaseData* ownerCaseData) + : m_activeCellInfo(nullptr) { CVF_ASSERT(ownerCaseData != nullptr); CVF_ASSERT(ownerCaseData->mainGrid() != nullptr); @@ -54,7 +59,7 @@ RigCaseCellResultsData::RigCaseCellResultsData(RigEclipseCaseData* ownerCaseData } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setMainGrid(RigMainGrid* ownerGrid) { @@ -62,7 +67,15 @@ void RigCaseCellResultsData::setMainGrid(RigMainGrid* ownerGrid) } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::setActiveCellInfo(RigActiveCellInfo* activeCellInfo) +{ + m_activeCellInfo = activeCellInfo; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, double& min, double& max) { @@ -70,7 +83,7 @@ void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, do } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max) { @@ -78,7 +91,7 @@ void RigCaseCellResultsData::minMaxCellScalarValues(size_t scalarResultIndex, si } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, double& pos, double& neg) { @@ -86,7 +99,7 @@ void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, doubl } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, size_t timeStepIndex, double& pos, double& neg) { @@ -94,7 +107,7 @@ void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, size_ } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const std::vector& RigCaseCellResultsData::cellScalarValuesHistogram(size_t scalarResultIndex) { @@ -102,7 +115,7 @@ const std::vector& RigCaseCellResultsData::cellScalarValuesHistogram(siz } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const std::vector& RigCaseCellResultsData::cellScalarValuesHistogram(size_t scalarResultIndex, size_t timeStepIndex) { @@ -110,7 +123,7 @@ const std::vector& RigCaseCellResultsData::cellScalarValuesHistogram(siz } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90) { @@ -118,7 +131,7 @@ void RigCaseCellResultsData::p10p90CellScalarValues(size_t scalarResultIndex, do } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::p10p90CellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& p10, double& p90) { @@ -126,7 +139,7 @@ void RigCaseCellResultsData::p10p90CellScalarValues(size_t scalarResultIndex, si } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::meanCellScalarValues(size_t scalarResultIndex, double& meanValue) { @@ -134,7 +147,7 @@ void RigCaseCellResultsData::meanCellScalarValues(size_t scalarResultIndex, doub } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::meanCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& meanValue) { @@ -142,7 +155,7 @@ void RigCaseCellResultsData::meanCellScalarValues(size_t scalarResultIndex, size } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const std::vector& RigCaseCellResultsData::uniqueCellScalarValues(size_t scalarResultIndex) { @@ -150,7 +163,7 @@ const std::vector& RigCaseCellResultsData::uniqueCellScalarValues(size_t sc } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::sumCellScalarValues(size_t scalarResultIndex, double& sumValue) { @@ -158,7 +171,7 @@ void RigCaseCellResultsData::sumCellScalarValues(size_t scalarResultIndex, doubl } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::sumCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& sumValue) { @@ -166,7 +179,7 @@ void RigCaseCellResultsData::sumCellScalarValues(size_t scalarResultIndex, size_ } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::mobileVolumeWeightedMean(size_t scalarResultIndex, double& meanValue) { @@ -174,7 +187,7 @@ void RigCaseCellResultsData::mobileVolumeWeightedMean(size_t scalarResultIndex, } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::mobileVolumeWeightedMean(size_t scalarResultIndex, size_t timeStepIndex, double& meanValue) { @@ -182,7 +195,7 @@ void RigCaseCellResultsData::mobileVolumeWeightedMean(size_t scalarResultIndex, } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::resultCount() const { @@ -190,7 +203,7 @@ size_t RigCaseCellResultsData::resultCount() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::timeStepCount(size_t scalarResultIndex) const { @@ -200,9 +213,9 @@ size_t RigCaseCellResultsData::timeStepCount(size_t scalarResultIndex) const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const std::vector< std::vector > & RigCaseCellResultsData::cellScalarResults( size_t scalarResultIndex ) const +const std::vector>& RigCaseCellResultsData::cellScalarResults(size_t scalarResultIndex) const { CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); @@ -210,9 +223,9 @@ const std::vector< std::vector > & RigCaseCellResultsData::cellScalarRes } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -std::vector< std::vector > & RigCaseCellResultsData::cellScalarResults( size_t scalarResultIndex ) +std::vector>& RigCaseCellResultsData::cellScalarResults(size_t scalarResultIndex) { CVF_TIGHT_ASSERT(scalarResultIndex < resultCount()); @@ -220,7 +233,7 @@ std::vector< std::vector > & RigCaseCellResultsData::cellScalarResults( } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector& RigCaseCellResultsData::cellScalarResults(size_t scalarResultIndex, size_t timeStepIndex) { @@ -231,16 +244,16 @@ std::vector& RigCaseCellResultsData::cellScalarResults(size_t scalarResu } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::findScalarResultIndex(RiaDefines::ResultCatType type, const QString& resultName) const { std::vector::const_iterator it; for (it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it) { - if (it->m_resultType == type && it->m_resultName == resultName) + if (it->resultType() == type && it->resultName() == resultName) { - return it->m_gridScalarResultIndex; + return it->gridScalarResultIndex(); } } @@ -248,7 +261,7 @@ size_t RigCaseCellResultsData::findScalarResultIndex(RiaDefines::ResultCatType t } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::findScalarResultIndex(const QString& resultName) const { @@ -274,7 +287,7 @@ size_t RigCaseCellResultsData::findScalarResultIndex(const QString& resultName) scalarResultIndex = this->findScalarResultIndex(RiaDefines::INPUT_PROPERTY, resultName); } - if(scalarResultIndex == cvf::UNDEFINED_SIZE_T) + if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) { scalarResultIndex = this->findScalarResultIndex(RiaDefines::FORMATION_NAMES, resultName); } @@ -286,7 +299,9 @@ size_t RigCaseCellResultsData::findScalarResultIndex(const QString& resultName) /// Adds an empty scalar set, and returns the scalarResultIndex to it. /// if resultName already exists, it just returns the scalarResultIndex to the existing result. //-------------------------------------------------------------------------------------------------- -size_t RigCaseCellResultsData::findOrCreateScalarResultIndex(RiaDefines::ResultCatType type, const QString& resultName, bool needsToBeStored) +size_t RigCaseCellResultsData::findOrCreateScalarResultIndex(RiaDefines::ResultCatType type, + const QString& resultName, + bool needsToBeStored) { size_t scalarResultIndex = this->findScalarResultIndex(type, resultName); @@ -300,8 +315,8 @@ size_t RigCaseCellResultsData::findOrCreateScalarResultIndex(RiaDefines::ResultC // Create the new empty result with metadata scalarResultIndex = this->resultCount(); - m_cellScalarResults.push_back(std::vector >()); - RigEclipseResultInfo resInfo(type, needsToBeStored, false, resultName, scalarResultIndex); + m_cellScalarResults.push_back(std::vector>()); + RigEclipseResultInfo resInfo(type, resultName, needsToBeStored, false, scalarResultIndex); m_resultInfos.push_back(resInfo); // Create statistics calculator and add statistics cache object @@ -335,25 +350,34 @@ size_t RigCaseCellResultsData::findOrCreateScalarResultIndex(RiaDefines::ResultC else if (resultName == RiaDefines::combinedRiTranResultName()) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); - calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranXResultName())); - calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranYResultName())); - calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranZResultName())); + calc->addNativeStatisticsCalculator(this, + findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranXResultName())); + calc->addNativeStatisticsCalculator(this, + findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranYResultName())); + calc->addNativeStatisticsCalculator(this, + findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranZResultName())); statisticsCalculator = calc; } else if (resultName == RiaDefines::combinedRiMultResultName()) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); - calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riMultXResultName())); - calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riMultYResultName())); - calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riMultZResultName())); + calc->addNativeStatisticsCalculator(this, + findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riMultXResultName())); + calc->addNativeStatisticsCalculator(this, + findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riMultYResultName())); + calc->addNativeStatisticsCalculator(this, + findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riMultZResultName())); statisticsCalculator = calc; } else if (resultName == RiaDefines::combinedRiAreaNormTranResultName()) { cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); - calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranXResultName())); - calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranYResultName())); - calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranZResultName())); + calc->addNativeStatisticsCalculator( + this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranXResultName())); + calc->addNativeStatisticsCalculator( + this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranYResultName())); + calc->addNativeStatisticsCalculator( + this, findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riAreaNormTranZResultName())); statisticsCalculator = calc; } else if (resultName == RiaDefines::combinedWaterFluxResultName()) @@ -382,8 +406,8 @@ size_t RigCaseCellResultsData::findOrCreateScalarResultIndex(RiaDefines::ResultC } else if (resultName.endsWith("IJK")) { - cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); - QString baseName = resultName.left(resultName.size() - 3); + cvf::ref calc = new RigEclipseMultiPropertyStatCalc(); + QString baseName = resultName.left(resultName.size() - 3); calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::GENERATED, QString("%1I").arg(baseName))); calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::GENERATED, QString("%1J").arg(baseName))); calc->addNativeStatisticsCalculator(this, findScalarResultIndex(RiaDefines::GENERATED, QString("%1K").arg(baseName))); @@ -401,24 +425,40 @@ size_t RigCaseCellResultsData::findOrCreateScalarResultIndex(RiaDefines::ResultC } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QStringList RigCaseCellResultsData::resultNames(RiaDefines::ResultCatType resType) const { - QStringList varList; + QStringList varList; std::vector::const_iterator it; for (it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it) { - if (it->m_resultType == resType ) + if (it->resultType() == resType) { - varList.push_back(it->m_resultName); + varList.push_back(it->resultName()); } - } + } return varList; } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +RigActiveCellInfo* RigCaseCellResultsData::activeCellInfo() +{ + return m_activeCellInfo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigActiveCellInfo* RigCaseCellResultsData::activeCellInfo() const +{ + return m_activeCellInfo; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::recalculateStatistics(size_t scalarResultIndex) { @@ -433,7 +473,7 @@ bool RigCaseCellResultsData::isUsingGlobalActiveIndex(size_t scalarResultIndex) CVF_TIGHT_ASSERT(scalarResultIndex < m_cellScalarResults.size()); if (!m_cellScalarResults[scalarResultIndex].size()) return true; - + size_t firstTimeStepResultValueCount = m_cellScalarResults[scalarResultIndex][0].size(); if (firstTimeStepResultValueCount == m_ownerMainGrid->globalCellArray().size()) return false; @@ -441,21 +481,21 @@ bool RigCaseCellResultsData::isUsingGlobalActiveIndex(size_t scalarResultIndex) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::hasFlowDiagUsableFluxes() const { QStringList dynResVarNames = resultNames(RiaDefines::DYNAMIC_NATIVE); bool hasFlowFluxes = true; - hasFlowFluxes = dynResVarNames.contains("FLRWATI+"); - hasFlowFluxes = hasFlowFluxes && (dynResVarNames.contains("FLROILI+") || dynResVarNames.contains("FLRGASI+")); + hasFlowFluxes = dynResVarNames.contains("FLRWATI+"); + hasFlowFluxes = hasFlowFluxes && (dynResVarNames.contains("FLROILI+") || dynResVarNames.contains("FLRGASI+")); return hasFlowFluxes; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::allTimeStepDatesFromEclipseReader() const { @@ -463,7 +503,7 @@ std::vector RigCaseCellResultsData::allTimeStepDatesFromEclipseReader if (rifReaderOutput) { return rifReaderOutput->allTimeSteps(); - } + } else { return std::vector(); @@ -471,18 +511,7 @@ std::vector RigCaseCellResultsData::allTimeStepDatesFromEclipseReader } //-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QDateTime RigCaseCellResultsData::timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const -{ - if (scalarResultIndex < m_resultInfos.size() && m_resultInfos[scalarResultIndex].m_timeStepInfos.size() > timeStepIndex) - return m_resultInfos[scalarResultIndex].m_timeStepInfos[timeStepIndex].m_date; - else - return QDateTime(); -} - -//-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::timeStepDates(size_t scalarResultIndex) const { @@ -495,7 +524,7 @@ std::vector RigCaseCellResultsData::timeStepDates(size_t scalarResult } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::timeStepDates() const { @@ -506,7 +535,7 @@ std::vector RigCaseCellResultsData::timeStepDates() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::daysSinceSimulationStart() const { @@ -517,7 +546,7 @@ std::vector RigCaseCellResultsData::daysSinceSimulationStart() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::daysSinceSimulationStart(size_t scalarResultIndex) const { @@ -532,64 +561,53 @@ std::vector RigCaseCellResultsData::daysSinceSimulationStart(size_t scal } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- int RigCaseCellResultsData::reportStepNumber(size_t scalarResultIndex, size_t timeStepIndex) const { - if (scalarResultIndex < m_resultInfos.size() && m_resultInfos[scalarResultIndex].m_timeStepInfos.size() > timeStepIndex) - return m_resultInfos[scalarResultIndex].m_timeStepInfos[timeStepIndex].m_reportNumber; + if (scalarResultIndex < m_resultInfos.size() && m_resultInfos[scalarResultIndex].timeStepInfos().size() > timeStepIndex) + return m_resultInfos[scalarResultIndex].timeStepInfos()[timeStepIndex].m_reportNumber; else return -1; } //-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RigCaseCellResultsData::reportStepNumbers(size_t scalarResultIndex) const -{ - if (scalarResultIndex < m_resultInfos.size() ) - return m_resultInfos[scalarResultIndex].reportNumbers(); - else - return std::vector(); -} - -//-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector RigCaseCellResultsData::timeStepInfos(size_t scalarResultIndex) const { if (scalarResultIndex < m_resultInfos.size()) - return m_resultInfos[scalarResultIndex].m_timeStepInfos; + return m_resultInfos[scalarResultIndex].timeStepInfos(); else return std::vector(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setTimeStepInfos(size_t scalarResultIndex, const std::vector& timeStepInfos) { - CVF_ASSERT(scalarResultIndex < m_resultInfos.size() ); + CVF_ASSERT(scalarResultIndex < m_resultInfos.size()); - m_resultInfos[scalarResultIndex].m_timeStepInfos = timeStepInfos; + m_resultInfos[scalarResultIndex].setTimeStepInfos(timeStepInfos); - std::vector< std::vector >& dataValues = this->cellScalarResults(scalarResultIndex); + std::vector>& dataValues = this->cellScalarResults(scalarResultIndex); dataValues.resize(timeStepInfos.size()); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::maxTimeStepCount(size_t* scalarResultIndexWithMostTimeSteps) const { - size_t maxTsCount = 0; + size_t maxTsCount = 0; size_t scalarResultIndexWithMaxTsCount = cvf::UNDEFINED_SIZE_T; for (size_t i = 0; i < m_resultInfos.size(); i++) { - if (m_resultInfos[i].m_timeStepInfos.size() > maxTsCount) + if (m_resultInfos[i].timeStepInfos().size() > maxTsCount) { - maxTsCount = m_resultInfos[i].m_timeStepInfos.size(); + maxTsCount = m_resultInfos[i].timeStepInfos().size(); scalarResultIndexWithMaxTsCount = i; } } @@ -603,15 +621,15 @@ size_t RigCaseCellResultsData::maxTimeStepCount(size_t* scalarResultIndexWithMos } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QString RigCaseCellResultsData::makeResultNameUnique(const QString& resultNameProposal) const { QString newResultName = resultNameProposal; - size_t resultIndex = cvf::UNDEFINED_SIZE_T; - int nameNum = 1; - int stringLength = newResultName.size(); - while (true) + size_t resultIndex = cvf::UNDEFINED_SIZE_T; + int nameNum = 1; + int stringLength = newResultName.size(); + while (true) { resultIndex = this->findScalarResultIndex(newResultName); if (resultIndex == cvf::UNDEFINED_SIZE_T) break; @@ -625,21 +643,32 @@ QString RigCaseCellResultsData::makeResultNameUnique(const QString& resultNamePr } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RigCaseCellResultsData::clearScalarResult(RiaDefines::ResultCatType type, const QString & resultName) +void RigCaseCellResultsData::clearScalarResult(RiaDefines::ResultCatType type, const QString& resultName) { size_t scalarResultIndex = this->findScalarResultIndex(type, resultName); if (scalarResultIndex == cvf::UNDEFINED_SIZE_T) return; - m_cellScalarResults[scalarResultIndex].clear(); + for (size_t tsIdx = 0; tsIdx < m_cellScalarResults[scalarResultIndex].size(); ++tsIdx) + { + std::vector empty; + m_cellScalarResults[scalarResultIndex][tsIdx].swap(empty); + } + recalculateStatistics(scalarResultIndex); +} - //m_resultInfos[scalarResultIndex].m_resultType = RiaDefines::REMOVED; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::clearScalarResult(const RigEclipseResultInfo& resultInfo) +{ + clearScalarResult(resultInfo.resultType(), resultInfo.resultName()); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::clearAllResults() { @@ -649,7 +678,7 @@ void RigCaseCellResultsData::clearAllResults() } //-------------------------------------------------------------------------------------------------- -/// Removes all the actual numbers put into this object, and frees up the memory. +/// Removes all the actual numbers put into this object, and frees up the memory. /// Does not touch the metadata in any way //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::freeAllocatedResultsData() @@ -666,13 +695,30 @@ void RigCaseCellResultsData::freeAllocatedResultsData() } //-------------------------------------------------------------------------------------------------- -/// Make sure we have a result with given type and name, and make sure one "timestep" result vector +/// +//-------------------------------------------------------------------------------------------------- +bool RigCaseCellResultsData::isResultLoaded(const RigEclipseResultInfo& resultInfo) const +{ + size_t scalarResultIndex = this->findScalarResultIndex(resultInfo.resultType(), resultInfo.resultName()); + CVF_TIGHT_ASSERT(scalarResultIndex != cvf::UNDEFINED_SIZE_T); + if (scalarResultIndex != cvf::UNDEFINED_SIZE_T) + { + return isDataPresent(scalarResultIndex); + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// Make sure we have a result with given type and name, and make sure one "timestep" result vector // for the static result values are allocated //-------------------------------------------------------------------------------------------------- -size_t RigCaseCellResultsData::addStaticScalarResult(RiaDefines::ResultCatType type, const QString& resultName, bool needsToBeStored, size_t resultValueCount) +size_t RigCaseCellResultsData::addStaticScalarResult(RiaDefines::ResultCatType type, + const QString& resultName, + bool needsToBeStored, + size_t resultValueCount) { size_t resultIdx = findOrCreateScalarResultIndex(type, resultName, needsToBeStored); - + m_cellScalarResults[resultIdx].resize(1, std::vector()); m_cellScalarResults[resultIdx][0].resize(resultValueCount, HUGE_VAL); @@ -680,7 +726,7 @@ size_t RigCaseCellResultsData::addStaticScalarResult(RiaDefines::ResultCatType t } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::updateResultName(RiaDefines::ResultCatType resultType, QString& oldName, const QString& newName) { @@ -688,10 +734,10 @@ bool RigCaseCellResultsData::updateResultName(RiaDefines::ResultCatType resultTy for (auto& it : m_resultInfos) { - if (it.m_resultType == resultType && it.m_resultName == oldName) + if (it.resultType() == resultType && it.resultName() == oldName) { anyNameUpdated = true; - it.m_resultName = newName; + it.setResultName(newName); } } @@ -699,11 +745,15 @@ bool RigCaseCellResultsData::updateResultName(RiaDefines::ResultCatType resultTy } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const std::vector* RigCaseCellResultsData::getResultIndexableStaticResult(RigActiveCellInfo* actCellInfo, RigCaseCellResultsData* gridCellResults, QString porvResultName, std::vector &activeCellsResultsTempContainer) +const std::vector* + RigCaseCellResultsData::getResultIndexableStaticResult(RigActiveCellInfo* actCellInfo, + RigCaseCellResultsData* gridCellResults, + QString porvResultName, + std::vector& activeCellsResultsTempContainer) { - size_t resultCellCount = actCellInfo->reservoirCellResultCount(); + size_t resultCellCount = actCellInfo->reservoirCellResultCount(); size_t reservoirCellCount = actCellInfo->reservoirCellCount(); size_t scalarResultIndexPorv = gridCellResults->findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, porvResultName); @@ -735,16 +785,24 @@ const std::vector* RigCaseCellResultsData::getResultIndexableStaticResul } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigCaseCellResultsData::infoForEachResultIndex() +{ + return m_resultInfos; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::mustBeCalculated(size_t scalarResultIndex) const { std::vector::const_iterator it; for (it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it) { - if (it->m_gridScalarResultIndex == scalarResultIndex) + if (it->gridScalarResultIndex() == scalarResultIndex) { - return it->m_mustBeCalculated; + return it->mustBeCalculated(); } } @@ -752,37 +810,37 @@ bool RigCaseCellResultsData::mustBeCalculated(size_t scalarResultIndex) const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setMustBeCalculated(size_t scalarResultIndex) { std::vector::iterator it; for (it = m_resultInfos.begin(); it != m_resultInfos.end(); ++it) { - if (it->m_gridScalarResultIndex == scalarResultIndex) + if (it->gridScalarResultIndex() == scalarResultIndex) { - it->m_mustBeCalculated = true; + it->setMustBeCalculated(true); } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::eraseAllSourSimData() { for (size_t i = 0; i < m_resultInfos.size(); i++) { RigEclipseResultInfo& ri = m_resultInfos[i]; - if (ri.m_resultType == RiaDefines::SOURSIMRL) + if (ri.resultType() == RiaDefines::SOURSIMRL) { - ri.m_resultType = RiaDefines::REMOVED; + ri.setResultType(RiaDefines::REMOVED); } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::createPlaceholderResultEntries() { @@ -802,6 +860,16 @@ void RigCaseCellResultsData::createPlaceholderResultEntries() } } + // Oil Volume + if (RiaApplication::enableDevelopmentFeatures()) + { + size_t soilIndex = findOrCreateScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, "SOIL", false); + if (soilIndex != cvf::UNDEFINED_SIZE_T) + { + findOrCreateScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::riOilVolumeResultName(), false); + } + } + // Completion type { size_t completionTypeIndex = findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::completionTypeResultName()); @@ -854,9 +922,9 @@ void RigCaseCellResultsData::createPlaceholderResultEntries() // riTRANSXYZ and X,Y,Z { - if ( findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PERMX") != cvf::UNDEFINED_SIZE_T - && findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PERMY") != cvf::UNDEFINED_SIZE_T - && findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PERMZ") != cvf::UNDEFINED_SIZE_T) + if (findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PERMX") != cvf::UNDEFINED_SIZE_T && + findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PERMY") != cvf::UNDEFINED_SIZE_T && + findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PERMZ") != cvf::UNDEFINED_SIZE_T) { addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riTranXResultName(), false, 0); addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riTranYResultName(), false, 0); @@ -868,10 +936,10 @@ void RigCaseCellResultsData::createPlaceholderResultEntries() // riMULTXYZ and X, Y, Z { size_t tranX, tranY, tranZ; - if (findTransmissibilityResults(tranX, tranY, tranZ) - && findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranXResultName()) != cvf::UNDEFINED_SIZE_T - && findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranYResultName()) != cvf::UNDEFINED_SIZE_T - && findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranZResultName()) != cvf::UNDEFINED_SIZE_T) + if (findTransmissibilityResults(tranX, tranY, tranZ) && + findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranXResultName()) != cvf::UNDEFINED_SIZE_T && + findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranYResultName()) != cvf::UNDEFINED_SIZE_T && + findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riTranZResultName()) != cvf::UNDEFINED_SIZE_T) { addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riMultXResultName(), false, 0); addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riMultYResultName(), false, 0); @@ -904,7 +972,12 @@ void RigCaseCellResultsData::createPlaceholderResultEntries() } } - //Mobile Pore Volume + // Cell Volume + { + addStaticScalarResult(RiaDefines::STATIC_NATIVE, RiaDefines::riCellVolumeResultName(), false, 0); + } + + // Mobile Pore Volume { if (findScalarResultIndex(RiaDefines::STATIC_NATIVE, "PORV") != cvf::UNDEFINED_SIZE_T) { @@ -914,7 +987,7 @@ void RigCaseCellResultsData::createPlaceholderResultEntries() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool RigCaseCellResultsData::findTransmissibilityResults(size_t& tranX, size_t& tranY, size_t& tranZ) const { @@ -922,9 +995,7 @@ bool RigCaseCellResultsData::findTransmissibilityResults(size_t& tranX, size_t& tranY = findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANY"); tranZ = findScalarResultIndex(RiaDefines::STATIC_NATIVE, "TRANZ"); - if (tranX == cvf::UNDEFINED_SIZE_T || - tranY == cvf::UNDEFINED_SIZE_T || - tranZ == cvf::UNDEFINED_SIZE_T) + if (tranX == cvf::UNDEFINED_SIZE_T || tranY == cvf::UNDEFINED_SIZE_T || tranZ == cvf::UNDEFINED_SIZE_T) { return false; } @@ -932,9 +1003,8 @@ bool RigCaseCellResultsData::findTransmissibilityResults(size_t& tranX, size_t& return true; } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::findOrLoadScalarResult(const QString& resultName) { @@ -964,7 +1034,7 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(const QString& resultName) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType type, const QString& resultName) { @@ -997,9 +1067,8 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType computeRiTransComponent(RiaDefines::riTranZResultName()); computeNncCombRiTrans(); } - else if (resultName == RiaDefines::riTranXResultName() - || resultName == RiaDefines::riTranYResultName() - || resultName == RiaDefines::riTranZResultName()) + else if (resultName == RiaDefines::riTranXResultName() || resultName == RiaDefines::riTranYResultName() || + resultName == RiaDefines::riTranZResultName()) { computeRiTransComponent(resultName); } @@ -1011,9 +1080,8 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType computeNncCombRiTrans(); computeNncCombRiMULT(); } - else if (resultName == RiaDefines::riMultXResultName() - || resultName == RiaDefines::riMultYResultName() - || resultName == RiaDefines::riMultZResultName()) + else if (resultName == RiaDefines::riMultXResultName() || resultName == RiaDefines::riMultYResultName() || + resultName == RiaDefines::riMultZResultName()) { computeRiMULTComponent(resultName); } @@ -1024,9 +1092,8 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType computeRiTRANSbyAreaComponent(RiaDefines::riAreaNormTranZResultName()); computeNncCombRiTRANSbyArea(); } - else if (resultName == RiaDefines::riAreaNormTranXResultName() - || resultName == RiaDefines::riAreaNormTranYResultName() - || resultName == RiaDefines::riAreaNormTranZResultName()) + else if (resultName == RiaDefines::riAreaNormTranXResultName() || resultName == RiaDefines::riAreaNormTranYResultName() || + resultName == RiaDefines::riAreaNormTranZResultName()) { computeRiTRANSbyAreaComponent(resultName); } @@ -1102,10 +1169,12 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType if (m_readerInterface.notNull()) { // Add one more result to result container - size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].m_timeStepInfos.size(); + size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].timeStepInfos().size(); bool resultLoadingSucess = true; + size_t tempGridCellCount = m_ownerMainGrid->totalTemporaryGridCellCount(); + if (type == RiaDefines::DYNAMIC_NATIVE && timeStepCount > 0) { this->cellScalarResults(scalarResultIndex).resize(timeStepCount); @@ -1118,6 +1187,15 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType { resultLoadingSucess = false; } + else if (tempGridCellCount > 0) + { + if (!values.empty()) + { + values.resize(values.size() + tempGridCellCount, std::numeric_limits::infinity()); + + assignValuesToTemporaryLgrs(resultName, values); + } + } } } else if (type == RiaDefines::STATIC_NATIVE) @@ -1129,6 +1207,15 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType { resultLoadingSucess = false; } + else if (tempGridCellCount > 0) + { + if (!values.empty()) + { + values.resize(values.size() + tempGridCellCount, std::numeric_limits::infinity()); + + assignValuesToTemporaryLgrs(resultName, values); + } + } } if (!resultLoadingSucess) @@ -1138,6 +1225,18 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType } } + + if (resultName == RiaDefines::riCellVolumeResultName()) + { + computeCellVolumes(); + } + else if (resultName == RiaDefines::riOilVolumeResultName()) + { + computeCellVolumes(); + computeOilVolumes(); + } + + // Handle SourSimRL reading if (type == RiaDefines::SOURSIMRL) @@ -1145,27 +1244,29 @@ size_t RigCaseCellResultsData::findOrLoadScalarResult(RiaDefines::ResultCatType RifReaderEclipseOutput* eclReader = dynamic_cast(m_readerInterface.p()); if (eclReader) { - size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].m_timeStepInfos.size(); + size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].timeStepInfos().size(); this->cellScalarResults(scalarResultIndex).resize(timeStepCount); size_t i; - for ( i = 0; i < timeStepCount; i++ ) + for (i = 0; i < timeStepCount; i++) { std::vector& values = this->cellScalarResults(scalarResultIndex)[i]; eclReader->sourSimRlResult(resultName, i, &values); } - } + } } return scalarResultIndex; } //-------------------------------------------------------------------------------------------------- -/// This method is intended to be used for multicase cross statistical calculations, when +/// This method is intended to be used for multicase cross statistical calculations, when /// we need process one timestep at a time, freeing memory as we go. //-------------------------------------------------------------------------------------------------- -size_t RigCaseCellResultsData::findOrLoadScalarResultForTimeStep(RiaDefines::ResultCatType type, const QString& resultName, size_t timeStepIndex) +size_t RigCaseCellResultsData::findOrLoadScalarResultForTimeStep(RiaDefines::ResultCatType type, + const QString& resultName, + size_t timeStepIndex) { // Special handling for SOIL if (type == RiaDefines::DYNAMIC_NATIVE && resultName.toUpper() == "SOIL") @@ -1202,7 +1303,7 @@ size_t RigCaseCellResultsData::findOrLoadScalarResultForTimeStep(RiaDefines::Res if (m_readerInterface.notNull()) { - size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].m_timeStepInfos.size(); + size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].timeStepInfos().size(); bool resultLoadingSucess = true; @@ -1244,35 +1345,33 @@ size_t RigCaseCellResultsData::findOrLoadScalarResultForTimeStep(RiaDefines::Res RifReaderEclipseOutput* eclReader = dynamic_cast(m_readerInterface.p()); if (eclReader) { - size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].m_timeStepInfos.size(); + size_t timeStepCount = this->infoForEachResultIndex()[scalarResultIndex].timeStepInfos().size(); this->cellScalarResults(scalarResultIndex).resize(timeStepCount); std::vector& values = this->cellScalarResults(scalarResultIndex)[timeStepIndex]; - if ( values.size() == 0) + if (values.size() == 0) { eclReader->sourSimRlResult(resultName, timeStepIndex, &values); } - } + } } return scalarResultIndex; - } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeSOILForTimeStep(size_t timeStepIndex) { // Compute SGAS based on SWAT if the simulation contains no oil testAndComputeSgasForTimeStep(timeStepIndex); - size_t scalarIndexSWAT = findOrLoadScalarResultForTimeStep(RiaDefines::DYNAMIC_NATIVE, "SWAT", timeStepIndex); - size_t scalarIndexSGAS = findOrLoadScalarResultForTimeStep(RiaDefines::DYNAMIC_NATIVE, "SGAS", timeStepIndex); - size_t scalarIndexSSOL = findOrLoadScalarResultForTimeStep(RiaDefines::DYNAMIC_NATIVE, "SSOL", timeStepIndex); + size_t scalarIndexSWAT = findOrLoadScalarResultForTimeStep(RiaDefines::DYNAMIC_NATIVE, "SWAT", timeStepIndex); + size_t scalarIndexSGAS = findOrLoadScalarResultForTimeStep(RiaDefines::DYNAMIC_NATIVE, "SGAS", timeStepIndex); + size_t scalarIndexSSOL = findOrLoadScalarResultForTimeStep(RiaDefines::DYNAMIC_NATIVE, "SSOL", timeStepIndex); // Early exit if none of SWAT or SGAS is present if (scalarIndexSWAT == cvf::UNDEFINED_SIZE_T && scalarIndexSGAS == cvf::UNDEFINED_SIZE_T) @@ -1281,7 +1380,7 @@ void RigCaseCellResultsData::computeSOILForTimeStep(size_t timeStepIndex) } size_t soilResultValueCount = 0; - size_t soilTimeStepCount = 0; + size_t soilTimeStepCount = 0; if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) { @@ -1289,7 +1388,7 @@ void RigCaseCellResultsData::computeSOILForTimeStep(size_t timeStepIndex) if (swatForTimeStep.size() > 0) { soilResultValueCount = swatForTimeStep.size(); - soilTimeStepCount = this->infoForEachResultIndex()[scalarIndexSWAT].m_timeStepInfos.size(); + soilTimeStepCount = this->infoForEachResultIndex()[scalarIndexSWAT].timeStepInfos().size(); } } @@ -1300,8 +1399,8 @@ void RigCaseCellResultsData::computeSOILForTimeStep(size_t timeStepIndex) { soilResultValueCount = qMax(soilResultValueCount, sgasForTimeStep.size()); - size_t sgasTimeStepCount = this->infoForEachResultIndex()[scalarIndexSGAS].m_timeStepInfos.size(); - soilTimeStepCount = qMax(soilTimeStepCount, sgasTimeStepCount); + size_t sgasTimeStepCount = this->infoForEachResultIndex()[scalarIndexSGAS].timeStepInfos().size(); + soilTimeStepCount = qMax(soilTimeStepCount, sgasTimeStepCount); } } @@ -1318,8 +1417,8 @@ void RigCaseCellResultsData::computeSOILForTimeStep(size_t timeStepIndex) this->cellScalarResults(soilResultScalarIndex, timeStepIndex).resize(soilResultValueCount); - std::vector* swatForTimeStep = nullptr; - std::vector* sgasForTimeStep = nullptr; + std::vector* swatForTimeStep = nullptr; + std::vector* sgasForTimeStep = nullptr; std::vector* ssolForTimeStep = nullptr; if (scalarIndexSWAT != cvf::UNDEFINED_SIZE_T) @@ -1351,7 +1450,7 @@ void RigCaseCellResultsData::computeSOILForTimeStep(size_t timeStepIndex) std::vector& soilForTimeStep = this->cellScalarResults(soilResultScalarIndex, timeStepIndex); - #pragma omp parallel for +#pragma omp parallel for for (int idx = 0; idx < static_cast(soilResultValueCount); idx++) { double soilValue = 1.0; @@ -1374,9 +1473,8 @@ void RigCaseCellResultsData::computeSOILForTimeStep(size_t timeStepIndex) } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::testAndComputeSgasForTimeStep(size_t timeStepIndex) { @@ -1402,14 +1500,14 @@ void RigCaseCellResultsData::testAndComputeSgasForTimeStep(size_t timeStepIndex) } size_t swatResultValueCount = 0; - size_t swatTimeStepCount = 0; + size_t swatTimeStepCount = 0; { std::vector& swatForTimeStep = this->cellScalarResults(scalarIndexSWAT, timeStepIndex); if (swatForTimeStep.size() > 0) { swatResultValueCount = swatForTimeStep.size(); - swatTimeStepCount = this->infoForEachResultIndex()[scalarIndexSWAT].m_timeStepInfos.size(); + swatTimeStepCount = this->infoForEachResultIndex()[scalarIndexSWAT].timeStepInfos().size(); } } @@ -1449,134 +1547,182 @@ void RigCaseCellResultsData::testAndComputeSgasForTimeStep(size_t timeStepIndex) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeDepthRelatedResults() { - size_t depthResultGridIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DEPTH"); - size_t dxResultGridIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DX"); - size_t dyResultGridIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DY"); - size_t dzResultGridIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DZ"); - size_t topsResultGridIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "TOPS"); - size_t bottomResultGridIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "BOTTOM"); - - bool computeDepth = false; - bool computeDx = false; - bool computeDy = false; - bool computeDz = false; - bool computeTops = false; + size_t actCellCount = activeCellInfo()->reservoirActiveCellCount(); + if (actCellCount == 0) return; + + size_t depthResultIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DEPTH"); + size_t dxResultIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DX"); + size_t dyResultIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DY"); + size_t dzResultIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "DZ"); + size_t topsResultIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "TOPS"); + size_t bottomResultIndex = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "BOTTOM"); + + bool computeDepth = false; + bool computeDx = false; + bool computeDy = false; + bool computeDz = false; + bool computeTops = false; bool computeBottom = false; - size_t resultValueCount = m_ownerMainGrid->globalCellArray().size(); - - if (depthResultGridIndex == cvf::UNDEFINED_SIZE_T) + if (depthResultIndex == cvf::UNDEFINED_SIZE_T) { - depthResultGridIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "DEPTH", false, resultValueCount); - computeDepth = true; + depthResultIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "DEPTH", false, actCellCount); + computeDepth = true; } - if (dxResultGridIndex == cvf::UNDEFINED_SIZE_T) + if (dxResultIndex == cvf::UNDEFINED_SIZE_T) { - dxResultGridIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "DX", false, resultValueCount); - computeDx = true; + dxResultIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "DX", false, actCellCount); + computeDx = true; } - if (dyResultGridIndex == cvf::UNDEFINED_SIZE_T) + if (dyResultIndex == cvf::UNDEFINED_SIZE_T) { - dyResultGridIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "DY", false, resultValueCount); - computeDy = true; + dyResultIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "DY", false, actCellCount); + computeDy = true; } - if (dzResultGridIndex == cvf::UNDEFINED_SIZE_T) + if (dzResultIndex == cvf::UNDEFINED_SIZE_T) { - dzResultGridIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "DZ", false, resultValueCount); - computeDz = true; + dzResultIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "DZ", false, actCellCount); + computeDz = true; } - if (topsResultGridIndex == cvf::UNDEFINED_SIZE_T) + if (topsResultIndex == cvf::UNDEFINED_SIZE_T) { - topsResultGridIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "TOPS", false, resultValueCount); - computeTops = true; + topsResultIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "TOPS", false, actCellCount); + computeTops = true; } - if (bottomResultGridIndex == cvf::UNDEFINED_SIZE_T) + if (bottomResultIndex == cvf::UNDEFINED_SIZE_T) { - bottomResultGridIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "BOTTOM", false, resultValueCount); - computeBottom = true; + bottomResultIndex = this->addStaticScalarResult(RiaDefines::STATIC_NATIVE, "BOTTOM", false, actCellCount); + computeBottom = true; } - std::vector< std::vector >& depth = this->cellScalarResults(depthResultGridIndex); - std::vector< std::vector >& dx = this->cellScalarResults(dxResultGridIndex); - std::vector< std::vector >& dy = this->cellScalarResults(dyResultGridIndex); - std::vector< std::vector >& dz = this->cellScalarResults(dzResultGridIndex); - std::vector< std::vector >& tops = this->cellScalarResults(topsResultGridIndex); - std::vector< std::vector >& bottom = this->cellScalarResults(bottomResultGridIndex); + std::vector>& depth = this->cellScalarResults(depthResultIndex); + std::vector>& dx = this->cellScalarResults(dxResultIndex); + std::vector>& dy = this->cellScalarResults(dyResultIndex); + std::vector>& dz = this->cellScalarResults(dzResultIndex); + std::vector>& tops = this->cellScalarResults(topsResultIndex); + std::vector>& bottom = this->cellScalarResults(bottomResultIndex); - size_t cellIdx = 0; - for (cellIdx = 0; cellIdx < m_ownerMainGrid->globalCellArray().size(); cellIdx++) + // Make sure the size is at least active cells + { + if (depth[0].size() < actCellCount) + { + depth[0].resize(actCellCount, std::numeric_limits::max()); + computeDepth = true; + } + + if (dx[0].size() < actCellCount) + { + dx[0].resize(actCellCount, std::numeric_limits::max()); + computeDx = true; + } + + if (dy[0].size() < actCellCount) + { + dy[0].resize(actCellCount, std::numeric_limits::max()); + computeDy = true; + } + + if (dz[0].size() < actCellCount) + { + dz[0].resize(actCellCount, std::numeric_limits::max()); + computeDz = true; + } + + if (tops[0].size() < actCellCount) + { + tops[0].resize(actCellCount, std::numeric_limits::max()); + computeTops = true; + } + + if (bottom[0].size() < actCellCount) + { + bottom[0].resize(actCellCount, std::numeric_limits::max()); + computeBottom = true; + } + } + + for (size_t cellIdx = 0; cellIdx < m_ownerMainGrid->globalCellArray().size(); cellIdx++) { const RigCell& cell = m_ownerMainGrid->globalCellArray()[cellIdx]; - if (computeDepth) + size_t resultIndex = activeCellInfo()->cellResultIndex(cellIdx); + if (resultIndex == cvf::UNDEFINED_SIZE_T) continue; + + bool isTemporaryGrid = cell.hostGrid()->isTempGrid(); + + if (computeDepth || isTemporaryGrid) { - depth[0][cellIdx] = cvf::Math::abs(cell.center().z()); + depth[0][resultIndex] = cvf::Math::abs(cell.center().z()); } - if (computeDx) + if (computeDx || isTemporaryGrid) { - cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_I) - cell.faceCenter(cvf::StructGridInterface::POS_I); - dx[0][cellIdx] = cellWidth.length(); + cvf::Vec3d cellWidth = + cell.faceCenter(cvf::StructGridInterface::NEG_I) - cell.faceCenter(cvf::StructGridInterface::POS_I); + dx[0][resultIndex] = cellWidth.length(); } - if (computeDy) + if (computeDy || isTemporaryGrid) { - cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_J) - cell.faceCenter(cvf::StructGridInterface::POS_J); - dy[0][cellIdx] = cellWidth.length(); + cvf::Vec3d cellWidth = + cell.faceCenter(cvf::StructGridInterface::NEG_J) - cell.faceCenter(cvf::StructGridInterface::POS_J); + dy[0][resultIndex] = cellWidth.length(); } - if (computeDz) + if (computeDz || isTemporaryGrid) { - cvf::Vec3d cellWidth = cell.faceCenter(cvf::StructGridInterface::NEG_K) - cell.faceCenter(cvf::StructGridInterface::POS_K); - dz[0][cellIdx] = cellWidth.length(); + cvf::Vec3d cellWidth = + cell.faceCenter(cvf::StructGridInterface::NEG_K) - cell.faceCenter(cvf::StructGridInterface::POS_K); + dz[0][resultIndex] = cellWidth.length(); } - if (computeTops) + if (computeTops || isTemporaryGrid) { - tops[0][cellIdx] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::NEG_K).z()); + tops[0][resultIndex] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::NEG_K).z()); } - if (computeBottom) + if (computeBottom || isTemporaryGrid) { - bottom[0][cellIdx] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::POS_K).z()); + bottom[0][resultIndex] = cvf::Math::abs(cell.faceCenter(cvf::StructGridInterface::POS_K).z()); } } } namespace RigTransmissibilityCalcTools { -void calculateConnectionGeometry(const RigCell& c1, const RigCell& c2, const std::vector& nodes, - cvf::StructGridInterface::FaceType faceId, cvf::Vec3d* faceAreaVec) +void calculateConnectionGeometry(const RigCell& c1, + const RigCell& c2, + const std::vector& nodes, + cvf::StructGridInterface::FaceType faceId, + cvf::Vec3d* faceAreaVec) { CVF_TIGHT_ASSERT(faceAreaVec); *faceAreaVec = cvf::Vec3d::ZERO; - std::vector polygon; + std::vector polygon; std::vector intersections; - caf::SizeTArray4 face1; - caf::SizeTArray4 face2; + std::array face1; + std::array face2; c1.faceIndices(faceId, &face1); c2.faceIndices(cvf::StructGridInterface::oppositeFace(faceId), &face2); - bool foundOverlap = cvf::GeometryTools::calculateOverlapPolygonOfTwoQuads( - &polygon, - &intersections, - (cvf::EdgeIntersectStorage*)nullptr, - cvf::wrapArrayConst(&nodes), - face1.data(), - face2.data(), - 1e-6); - + bool foundOverlap = cvf::GeometryTools::calculateOverlapPolygonOfTwoQuads(&polygon, + &intersections, + (cvf::EdgeIntersectStorage*)nullptr, + cvf::wrapArrayConst(&nodes), + face1.data(), + face2.data(), + 1e-6); if (foundOverlap) { @@ -1593,21 +1739,19 @@ void calculateConnectionGeometry(const RigCell& c1, const RigCell& c2, const std // Polygon area vector *faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D(realPolygon); - } - } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double halfCellTransmissibility(double perm, double ntg, const cvf::Vec3d& centerToFace, const cvf::Vec3d& faceAreaVec) { - return perm*ntg*(faceAreaVec*centerToFace) / (centerToFace*centerToFace); + return perm * ntg * (faceAreaVec * centerToFace) / (centerToFace * centerToFace); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double newtran(double cdarchy, double mult, double halfCellTrans, double neighborHalfCellTrans) { @@ -1622,12 +1766,12 @@ double newtran(double cdarchy, double mult, double halfCellTrans, double neighbo } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -typedef size_t(*ResultIndexFunction)(const RigActiveCellInfo* activeCellinfo, size_t reservoirCellIndex); +typedef size_t (*ResultIndexFunction)(const RigActiveCellInfo* activeCellinfo, size_t reservoirCellIndex); //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t directReservoirCellIndex(const RigActiveCellInfo* activeCellinfo, size_t reservoirCellIndex) @@ -1636,41 +1780,41 @@ size_t directReservoirCellIndex(const RigActiveCellInfo* activeCellinfo, size_t } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t reservoirActiveCellIndex(const RigActiveCellInfo* activeCellinfo, size_t reservoirCellIndex) { return activeCellinfo->cellResultIndex(reservoirCellIndex); } -} +} // namespace RigTransmissibilityCalcTools using namespace RigTransmissibilityCalcTools; //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransComponentResultName) { // Set up which component to compute cvf::StructGridInterface::FaceType faceId = cvf::StructGridInterface::NO_FACE; - QString permCompName; + QString permCompName; if (riTransComponentResultName == RiaDefines::riTranXResultName()) { permCompName = "PERMX"; - faceId = cvf::StructGridInterface::POS_I; + faceId = cvf::StructGridInterface::POS_I; } else if (riTransComponentResultName == RiaDefines::riTranYResultName()) { permCompName = "PERMY"; - faceId = cvf::StructGridInterface::POS_J; + faceId = cvf::StructGridInterface::POS_J; } else if (riTransComponentResultName == RiaDefines::riTranZResultName()) { permCompName = "PERMZ"; - faceId = cvf::StructGridInterface::POS_K; + faceId = cvf::StructGridInterface::POS_K; } else { @@ -1682,7 +1826,7 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo // Get the needed result indices we depend on size_t permResultIdx = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, permCompName); - size_t ntgResultIdx = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "NTG"); + size_t ntgResultIdx = findOrLoadScalarResult(RiaDefines::STATIC_NATIVE, "NTG"); bool hasNTGResults = ntgResultIdx != cvf::UNDEFINED_SIZE_T; @@ -1694,18 +1838,18 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo // Get the result count, to handle that one of them might be globally defined size_t permxResultValueCount = this->cellScalarResults(permResultIdx)[0].size(); - size_t resultValueCount = permxResultValueCount; + size_t resultValueCount = permxResultValueCount; if (hasNTGResults) { size_t ntgResultValueCount = this->cellScalarResults(ntgResultIdx)[0].size(); - resultValueCount = CVF_MIN(permxResultValueCount, ntgResultValueCount); + resultValueCount = CVF_MIN(permxResultValueCount, ntgResultValueCount); } // Get all the actual result values - std::vector & permResults = this->cellScalarResults(permResultIdx)[0]; - std::vector & riTransResults = this->cellScalarResults(riTransResultIdx)[0]; - std::vector * ntgResults = nullptr; + std::vector& permResults = this->cellScalarResults(permResultIdx)[0]; + std::vector& riTransResults = this->cellScalarResults(riTransResultIdx)[0]; + std::vector* ntgResults = nullptr; if (hasNTGResults) { ntgResults = &(this->cellScalarResults(ntgResultIdx)[0]); @@ -1731,16 +1875,16 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo // Set up result index function pointers riTranIdxFunc = isTransUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; - permIdxFunc = isPermUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; + permIdxFunc = isPermUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; if (hasNTGResults) { ntgIdxFunc = isNtgUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; } } - const RigActiveCellInfo* activeCellInfo = this->activeCellInfo(); - const std::vector& nodes = m_ownerMainGrid->nodes(); - bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); + const RigActiveCellInfo* activeCellInfo = this->activeCellInfo(); + const std::vector& nodes = m_ownerMainGrid->nodes(); + bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); for (size_t nativeResvCellIndex = 0; nativeResvCellIndex < m_ownerMainGrid->globalCellArray().size(); nativeResvCellIndex++) { @@ -1750,7 +1894,7 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo if (tranResIdx == cvf::UNDEFINED_SIZE_T) continue; const RigCell& nativeCell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex]; - RigGridBase* grid = nativeCell.hostGrid(); + RigGridBase* grid = nativeCell.hostGrid(); size_t gridLocalNativeCellIndex = nativeCell.gridLocalCellIndex(); @@ -1760,8 +1904,8 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo if (grid->cellIJKNeighbor(i, j, k, faceId, &gridLocalNeighborCellIdx)) { - size_t neighborResvCellIdx = grid->reservoirCellIndex(gridLocalNeighborCellIdx); - const RigCell& neighborCell = m_ownerMainGrid->globalCellArray()[neighborResvCellIdx]; + size_t neighborResvCellIdx = grid->reservoirCellIndex(gridLocalNeighborCellIdx); + const RigCell& neighborCell = m_ownerMainGrid->globalCellArray()[neighborResvCellIdx]; // Do nothing if neighbor cell has no results size_t neighborCellPermResIdx = (*permIdxFunc)(activeCellInfo, neighborResvCellIdx); @@ -1769,9 +1913,8 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo // Connection geometry - const RigFault* fault = grid->mainGrid()->findFaultFromCellIndexAndCellFace(nativeResvCellIndex, faceId); - bool isOnFault = fault; - + const RigFault* fault = grid->mainGrid()->findFaultFromCellIndexAndCellFace(nativeResvCellIndex, faceId); + bool isOnFault = fault; cvf::Vec3d faceAreaVec; cvf::Vec3d faceCenter; @@ -1782,13 +1925,12 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo } else { - faceAreaVec = nativeCell.faceNormalWithAreaLenght(faceId); } if (!isFaceNormalsOutwards) faceAreaVec = -faceAreaVec; - double halfCellTrans = 0; + double halfCellTrans = 0; double neighborHalfCellTrans = 0; // Native cell half cell transm @@ -1796,13 +1938,13 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo cvf::Vec3d centerToFace = nativeCell.faceCenter(faceId) - nativeCell.center(); size_t permResIdx = (*permIdxFunc)(activeCellInfo, nativeResvCellIndex); - double perm = permResults[permResIdx]; + double perm = permResults[permResIdx]; double ntg = 1.0; if (hasNTGResults && faceId != cvf::StructGridInterface::POS_K) { size_t ntgResIdx = (*ntgIdxFunc)(activeCellInfo, nativeResvCellIndex); - ntg = (*ntgResults)[ntgResIdx]; + ntg = (*ntgResults)[ntgResIdx]; } halfCellTrans = halfCellTransmissibility(perm, ntg, centerToFace, faceAreaVec); @@ -1810,7 +1952,8 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo // Neighbor cell half cell transm { - cvf::Vec3d centerToFace = neighborCell.faceCenter(cvf::StructGridInterface::oppositeFace(faceId)) - neighborCell.center(); + cvf::Vec3d centerToFace = + neighborCell.faceCenter(cvf::StructGridInterface::oppositeFace(faceId)) - neighborCell.center(); double perm = permResults[neighborCellPermResIdx]; @@ -1818,7 +1961,7 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo if (hasNTGResults && faceId != cvf::StructGridInterface::POS_K) { size_t ntgResIdx = (*ntgIdxFunc)(activeCellInfo, neighborResvCellIdx); - ntg = (*ntgResults)[ntgResIdx]; + ntg = (*ntgResults)[ntgResIdx]; } neighborHalfCellTrans = halfCellTransmissibility(perm, ntg, centerToFace, -faceAreaVec); @@ -1826,16 +1969,16 @@ void RigCaseCellResultsData::computeRiTransComponent(const QString& riTransCompo riTransResults[tranResIdx] = newtran(cdarchy, 1.0, halfCellTrans, neighborHalfCellTrans); } - } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeNncCombRiTrans() { - size_t riCombTransScalarResultIndex = this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiTranResultName()); + size_t riCombTransScalarResultIndex = + this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiTranResultName()); if (m_ownerMainGrid->nncData()->staticConnectionScalarResult(riCombTransScalarResultIndex)) return; double cdarchy = darchysValue(); @@ -1852,13 +1995,14 @@ void RigCaseCellResultsData::computeNncCombRiTrans() // Get all the actual result values - std::vector & permXResults = this->cellScalarResults(permXResultIdx)[0]; - std::vector & permYResults = this->cellScalarResults(permYResultIdx)[0]; - std::vector & permZResults = this->cellScalarResults(permZResultIdx)[0]; - std::vector & riCombTransResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombTrans()); + std::vector& permXResults = this->cellScalarResults(permXResultIdx)[0]; + std::vector& permYResults = this->cellScalarResults(permYResultIdx)[0]; + std::vector& permZResults = this->cellScalarResults(permZResultIdx)[0]; + std::vector& riCombTransResults = + m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombTrans()); m_ownerMainGrid->nncData()->setScalarResultIndex(RigNNCData::propertyNameRiCombTrans(), riCombTransScalarResultIndex); - std::vector * ntgResults = nullptr; + std::vector* ntgResults = nullptr; if (hasNTGResults) { ntgResults = &(this->cellScalarResults(ntgResultIdx)[0]); @@ -1876,7 +2020,7 @@ void RigCaseCellResultsData::computeNncCombRiTrans() bool isNtgUsingResIdx = false; if (hasNTGResults) { - isNtgUsingResIdx = this->isUsingGlobalActiveIndex(ntgResultIdx); + isNtgUsingResIdx = this->isUsingGlobalActiveIndex(ntgResultIdx); } // Set up result index function pointers @@ -1886,23 +2030,23 @@ void RigCaseCellResultsData::computeNncCombRiTrans() permZIdxFunc = isPermZUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; if (hasNTGResults) { - ntgIdxFunc = isNtgUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; + ntgIdxFunc = isNtgUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; } } - const RigActiveCellInfo* activeCellInfo = this->activeCellInfo(); - bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); + const RigActiveCellInfo* activeCellInfo = this->activeCellInfo(); + bool isFaceNormalsOutwards = m_ownerMainGrid->isFaceNormalsOutwards(); // NNC calculation std::vector& nncConnections = m_ownerMainGrid->nncData()->connections(); for (size_t connIdx = 0; connIdx < nncConnections.size(); connIdx++) { - size_t nativeResvCellIndex = nncConnections[connIdx].m_c1GlobIdx; - size_t neighborResvCellIdx = nncConnections[connIdx].m_c2GlobIdx; - cvf::StructGridInterface::FaceType faceId = nncConnections[connIdx].m_c1Face; + size_t nativeResvCellIndex = nncConnections[connIdx].m_c1GlobIdx; + size_t neighborResvCellIdx = nncConnections[connIdx].m_c2GlobIdx; + cvf::StructGridInterface::FaceType faceId = nncConnections[connIdx].m_c1Face; - ResultIndexFunction permIdxFunc = nullptr; - std::vector * permResults; + ResultIndexFunction permIdxFunc = nullptr; + std::vector* permResults = nullptr; switch (faceId) { @@ -1921,7 +2065,8 @@ void RigCaseCellResultsData::computeNncCombRiTrans() permIdxFunc = permZIdxFunc; permResults = &permZResults; break; - default: break; + default: + break; } if (!permIdxFunc) continue; @@ -1934,15 +2079,13 @@ void RigCaseCellResultsData::computeNncCombRiTrans() size_t neighborCellPermResIdx = (*permIdxFunc)(activeCellInfo, neighborResvCellIdx); if (neighborCellPermResIdx == cvf::UNDEFINED_SIZE_T) continue; - - const RigCell& nativeCell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex]; + const RigCell& nativeCell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex]; const RigCell& neighborCell = m_ownerMainGrid->globalCellArray()[neighborResvCellIdx]; - // Connection geometry - cvf::Vec3d faceAreaVec = cvf::Vec3d::ZERO;; - cvf::Vec3d faceCenter = cvf::Vec3d::ZERO;; + cvf::Vec3d faceAreaVec = cvf::Vec3d::ZERO; + cvf::Vec3d faceCenter = cvf::Vec3d::ZERO; // Polygon center const std::vector& realPolygon = nncConnections[connIdx].m_polygon; @@ -1959,7 +2102,7 @@ void RigCaseCellResultsData::computeNncCombRiTrans() if (!isFaceNormalsOutwards) faceAreaVec = -faceAreaVec; - double halfCellTrans = 0; + double halfCellTrans = 0; double neighborHalfCellTrans = 0; // Native cell half cell transm @@ -1972,7 +2115,7 @@ void RigCaseCellResultsData::computeNncCombRiTrans() if (hasNTGResults && faceId != cvf::StructGridInterface::POS_K) { size_t ntgResIdx = (*ntgIdxFunc)(activeCellInfo, nativeResvCellIndex); - ntg = (*ntgResults)[ntgResIdx]; + ntg = (*ntgResults)[ntgResIdx]; } halfCellTrans = halfCellTransmissibility(perm, ntg, centerToFace, faceAreaVec); @@ -1980,7 +2123,8 @@ void RigCaseCellResultsData::computeNncCombRiTrans() // Neighbor cell half cell transm { - cvf::Vec3d centerToFace = neighborCell.faceCenter(cvf::StructGridInterface::oppositeFace(faceId)) - neighborCell.center(); + cvf::Vec3d centerToFace = + neighborCell.faceCenter(cvf::StructGridInterface::oppositeFace(faceId)) - neighborCell.center(); double perm = (*permResults)[neighborCellPermResIdx]; @@ -1988,27 +2132,25 @@ void RigCaseCellResultsData::computeNncCombRiTrans() if (hasNTGResults && faceId != cvf::StructGridInterface::POS_K) { size_t ntgResIdx = (*ntgIdxFunc)(activeCellInfo, neighborResvCellIdx); - ntg = (*ntgResults)[ntgResIdx]; + ntg = (*ntgResults)[ntgResIdx]; } neighborHalfCellTrans = halfCellTransmissibility(perm, ntg, centerToFace, -faceAreaVec); } - double newtranTemp = newtran(cdarchy, 1.0, halfCellTrans, neighborHalfCellTrans); + double newtranTemp = newtran(cdarchy, 1.0, halfCellTrans, neighborHalfCellTrans); riCombTransResults[connIdx] = newtranTemp; } - } - double riMult(double transResults, double riTransResults) { if (transResults == HUGE_VAL || riTransResults == HUGE_VAL) return HUGE_VAL; // To make 0.0 values give 1.0 in mult value - if (cvf::Math::abs (riTransResults) < 1e-12) + if (cvf::Math::abs(riTransResults) < 1e-12) { - if (cvf::Math::abs (transResults) < 1e-12) + if (cvf::Math::abs(transResults) < 1e-12) { return 1.0; } @@ -2016,14 +2158,13 @@ double riMult(double transResults, double riTransResults) return HUGE_VAL; } - double result = transResults / riTransResults; return result; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeRiMULTComponent(const QString& riMultCompName) { @@ -2035,17 +2176,17 @@ void RigCaseCellResultsData::computeRiMULTComponent(const QString& riMultCompNam if (riMultCompName == RiaDefines::riMultXResultName()) { riTransCompName = RiaDefines::riTranXResultName(); - transCompName = "TRANX"; + transCompName = "TRANX"; } else if (riMultCompName == RiaDefines::riMultYResultName()) { riTransCompName = RiaDefines::riTranYResultName(); - transCompName = "TRANY"; + transCompName = "TRANY"; } else if (riMultCompName == RiaDefines::riMultZResultName()) { riTransCompName = RiaDefines::riTranZResultName(); - transCompName = "TRANZ"; + transCompName = "TRANZ"; } else { @@ -2070,10 +2211,10 @@ void RigCaseCellResultsData::computeRiMULTComponent(const QString& riMultCompNam // Get all the actual result values - std::vector & riTransResults = this->cellScalarResults(riTransResultIdx)[0]; - std::vector & transResults = this->cellScalarResults(transResultIdx)[0]; + std::vector& riTransResults = this->cellScalarResults(riTransResultIdx)[0]; + std::vector& transResults = this->cellScalarResults(transResultIdx)[0]; - std::vector & riMultResults = this->cellScalarResults(riMultResultIdx)[0]; + std::vector& riMultResults = this->cellScalarResults(riMultResultIdx)[0]; // Set up output container to correct number of results @@ -2086,19 +2227,25 @@ void RigCaseCellResultsData::computeRiMULTComponent(const QString& riMultCompNam } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeNncCombRiMULT() { - size_t riCombMultScalarResultIndex = this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiMultResultName()); - size_t riCombTransScalarResultIndex = this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiTranResultName()); - size_t combTransScalarResultIndex = this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName()); + size_t riCombMultScalarResultIndex = + this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiMultResultName()); + size_t riCombTransScalarResultIndex = + this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiTranResultName()); + size_t combTransScalarResultIndex = + this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName()); if (m_ownerMainGrid->nncData()->staticConnectionScalarResult(riCombMultScalarResultIndex)) return; - std::vector & riMultResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombMult()); - const std::vector * riTransResults = m_ownerMainGrid->nncData()->staticConnectionScalarResult(riCombTransScalarResultIndex); - const std::vector * transResults = m_ownerMainGrid->nncData()->staticConnectionScalarResult(combTransScalarResultIndex); + std::vector& riMultResults = + m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombMult()); + const std::vector* riTransResults = + m_ownerMainGrid->nncData()->staticConnectionScalarResult(riCombTransScalarResultIndex); + const std::vector* transResults = + m_ownerMainGrid->nncData()->staticConnectionScalarResult(combTransScalarResultIndex); m_ownerMainGrid->nncData()->setScalarResultIndex(RigNNCData::propertyNameRiCombMult(), riCombMultScalarResultIndex); for (size_t nncConIdx = 0; nncConIdx < riMultResults.size(); ++nncConIdx) @@ -2108,29 +2255,29 @@ void RigCaseCellResultsData::computeNncCombRiMULT() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeRiTRANSbyAreaComponent(const QString& riTransByAreaCompResultName) { // Set up which component to compute cvf::StructGridInterface::FaceType faceId = cvf::StructGridInterface::NO_FACE; - QString transCompName; + QString transCompName; if (riTransByAreaCompResultName == RiaDefines::riAreaNormTranXResultName()) { transCompName = "TRANX"; - faceId = cvf::StructGridInterface::POS_I; + faceId = cvf::StructGridInterface::POS_I; } else if (riTransByAreaCompResultName == RiaDefines::riAreaNormTranYResultName()) { transCompName = "TRANY"; - faceId = cvf::StructGridInterface::POS_J; + faceId = cvf::StructGridInterface::POS_J; } else if (riTransByAreaCompResultName == RiaDefines::riAreaNormTranZResultName()) { transCompName = "TRANZ"; - faceId = cvf::StructGridInterface::POS_K; + faceId = cvf::StructGridInterface::POS_K; } else { @@ -2152,8 +2299,8 @@ void RigCaseCellResultsData::computeRiTRANSbyAreaComponent(const QString& riTran // Get all the actual result values - std::vector & transResults = this->cellScalarResults(tranCompScResIdx)[0]; - std::vector & riTransByAreaResults = this->cellScalarResults(riTranByAreaScResIdx)[0]; + std::vector& transResults = this->cellScalarResults(tranCompScResIdx)[0]; + std::vector& riTransByAreaResults = this->cellScalarResults(riTranByAreaScResIdx)[0]; // Set up output container to correct number of results @@ -2167,8 +2314,8 @@ void RigCaseCellResultsData::computeRiTRANSbyAreaComponent(const QString& riTran ResultIndexFunction resValIdxFunc = isUsingResIdx ? &reservoirActiveCellIndex : &directReservoirCellIndex; - const RigActiveCellInfo* activeCellInfo = this->activeCellInfo(); - const std::vector& nodes = m_ownerMainGrid->nodes(); + const RigActiveCellInfo* activeCellInfo = this->activeCellInfo(); + const std::vector& nodes = m_ownerMainGrid->nodes(); for (size_t nativeResvCellIndex = 0; nativeResvCellIndex < m_ownerMainGrid->globalCellArray().size(); nativeResvCellIndex++) { @@ -2178,7 +2325,7 @@ void RigCaseCellResultsData::computeRiTRANSbyAreaComponent(const QString& riTran if (nativeCellResValIdx == cvf::UNDEFINED_SIZE_T) continue; const RigCell& nativeCell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex]; - RigGridBase* grid = nativeCell.hostGrid(); + RigGridBase* grid = nativeCell.hostGrid(); size_t gridLocalNativeCellIndex = nativeCell.gridLocalCellIndex(); @@ -2188,13 +2335,13 @@ void RigCaseCellResultsData::computeRiTRANSbyAreaComponent(const QString& riTran if (grid->cellIJKNeighbor(i, j, k, faceId, &gridLocalNeighborCellIdx)) { - size_t neighborResvCellIdx = grid->reservoirCellIndex(gridLocalNeighborCellIdx); - const RigCell& neighborCell = m_ownerMainGrid->globalCellArray()[neighborResvCellIdx]; + size_t neighborResvCellIdx = grid->reservoirCellIndex(gridLocalNeighborCellIdx); + const RigCell& neighborCell = m_ownerMainGrid->globalCellArray()[neighborResvCellIdx]; // Connection geometry - const RigFault* fault = grid->mainGrid()->findFaultFromCellIndexAndCellFace(nativeResvCellIndex, faceId); - bool isOnFault = fault; + const RigFault* fault = grid->mainGrid()->findFaultFromCellIndexAndCellFace(nativeResvCellIndex, faceId); + bool isOnFault = fault; cvf::Vec3d faceAreaVec; @@ -2207,47 +2354,51 @@ void RigCaseCellResultsData::computeRiTRANSbyAreaComponent(const QString& riTran faceAreaVec = nativeCell.faceNormalWithAreaLenght(faceId); } - double areaOfOverlap = faceAreaVec.length(); + double areaOfOverlap = faceAreaVec.length(); double transCompValue = transResults[nativeCellResValIdx]; riTransByAreaResults[nativeCellResValIdx] = transCompValue / areaOfOverlap; } - } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeNncCombRiTRANSbyArea() { - size_t riCombTransByAreaScResIdx = this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiAreaNormTranResultName()); - size_t combTransScalarResultIndex = this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName()); + size_t riCombTransByAreaScResIdx = + this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedRiAreaNormTranResultName()); + size_t combTransScalarResultIndex = + this->findScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::combinedTransmissibilityResultName()); if (m_ownerMainGrid->nncData()->staticConnectionScalarResult(riCombTransByAreaScResIdx)) return; - std::vector & riAreaNormTransResults = m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombTransByArea()); + std::vector& riAreaNormTransResults = + m_ownerMainGrid->nncData()->makeStaticConnectionScalarResult(RigNNCData::propertyNameRiCombTransByArea()); m_ownerMainGrid->nncData()->setScalarResultIndex(RigNNCData::propertyNameRiCombTransByArea(), riCombTransByAreaScResIdx); - const std::vector * transResults = m_ownerMainGrid->nncData()->staticConnectionScalarResult(combTransScalarResultIndex); + const std::vector* transResults = + m_ownerMainGrid->nncData()->staticConnectionScalarResult(combTransScalarResultIndex); const std::vector& connections = m_ownerMainGrid->nncData()->connections(); for (size_t nncConIdx = 0; nncConIdx < riAreaNormTransResults.size(); ++nncConIdx) { - const std::vector& realPolygon = connections[nncConIdx].m_polygon; - cvf::Vec3d faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D(realPolygon); - double areaOfOverlap = faceAreaVec.length(); + const std::vector& realPolygon = connections[nncConIdx].m_polygon; + cvf::Vec3d faceAreaVec = cvf::GeometryTools::polygonAreaNormal3D(realPolygon); + double areaOfOverlap = faceAreaVec.length(); riAreaNormTransResults[nncConIdx] = (*transResults)[nncConIdx] / areaOfOverlap; } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeCompletionTypeForTimeStep(size_t timeStep) { - size_t completionTypeResultIndex = this->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::completionTypeResultName()); + size_t completionTypeResultIndex = + this->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::completionTypeResultName()); if (this->cellScalarResults(completionTypeResultIndex).size() < this->maxTimeStepCount()) { @@ -2273,9 +2424,8 @@ void RigCaseCellResultsData::computeCompletionTypeForTimeStep(size_t timeStep) RimCompletionCellIntersectionCalc::calculateCompletionTypeResult(eclipseCase, completionTypeResult, timeStep); } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- double RigCaseCellResultsData::darchysValue() { @@ -2283,43 +2433,118 @@ double RigCaseCellResultsData::darchysValue() } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::computeCellVolumes() +{ + size_t cellVolIdx = this->findOrCreateScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riCellVolumeResultName(), false); + + if (this->cellScalarResults(cellVolIdx).empty()) + { + this->cellScalarResults(cellVolIdx).resize(1); + } + std::vector& cellVolumeResults = this->cellScalarResults(cellVolIdx)[0]; + + size_t cellResultCount = m_activeCellInfo->reservoirCellResultCount(); + cellVolumeResults.resize(cellResultCount, std::numeric_limits::infinity()); + +#pragma omp parallel for + for (int nativeResvCellIndex = 0; nativeResvCellIndex < static_cast(m_ownerMainGrid->globalCellArray().size()); nativeResvCellIndex++) + { + size_t resultIndex = activeCellInfo()->cellResultIndex(nativeResvCellIndex); + if (resultIndex != cvf::UNDEFINED_SIZE_T) + { + const RigCell& cell = m_ownerMainGrid->globalCellArray()[nativeResvCellIndex]; + if (!cell.subGrid()) + { + cellVolumeResults[resultIndex] = cell.volume(); + } + } + } + + // Clear oil volume so it will have to be recalculated. + clearScalarResult(RiaDefines::DYNAMIC_NATIVE, RiaDefines::riOilVolumeResultName()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::computeOilVolumes() +{ + size_t cellVolIdx = this->findOrCreateScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::riCellVolumeResultName(), false); + const std::vector& cellVolumeResults = this->cellScalarResults(cellVolIdx)[0]; + + size_t soilIdx = this->findOrLoadScalarResult(RiaDefines::DYNAMIC_NATIVE, "SOIL"); + size_t oilVolIdx = this->findOrCreateScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, RiaDefines::riOilVolumeResultName(), false); + this->cellScalarResults(oilVolIdx).resize(this->maxTimeStepCount()); + + size_t cellResultCount = m_activeCellInfo->reservoirCellResultCount(); + for (size_t timeStepIdx = 0; timeStepIdx < this->maxTimeStepCount(); timeStepIdx++) + { + const std::vector& soilResults = this->cellScalarResults(soilIdx)[timeStepIdx]; + std::vector& oilVolumeResults = this->cellScalarResults(oilVolIdx)[timeStepIdx]; + oilVolumeResults.resize(cellResultCount, 0u); + +#pragma omp parallel for + for (int nativeResvCellIndex = 0; nativeResvCellIndex < static_cast(m_ownerMainGrid->globalCellArray().size()); nativeResvCellIndex++) + { + size_t resultIndex = activeCellInfo()->cellResultIndex(nativeResvCellIndex); + if (resultIndex != cvf::UNDEFINED_SIZE_T) + { + CVF_ASSERT(soilResults.at(resultIndex) <= 1.01); + oilVolumeResults[resultIndex] = std::max(0.0, soilResults.at(resultIndex) * cellVolumeResults.at(resultIndex)); + } + } + } +} + + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::computeMobilePV() { std::vector porvDataTemp; std::vector swcrDataTemp; std::vector multpvDataTemp; - - const std::vector* porvResults = nullptr; - const std::vector* swcrResults = nullptr; + + const std::vector* porvResults = nullptr; + const std::vector* swcrResults = nullptr; const std::vector* multpvResults = nullptr; - porvResults = RigCaseCellResultsData::getResultIndexableStaticResult(this->activeCellInfo(), this, "PORV", porvDataTemp); - swcrResults = RigCaseCellResultsData::getResultIndexableStaticResult(this->activeCellInfo(), this, "SWCR", swcrDataTemp); - multpvResults = RigCaseCellResultsData::getResultIndexableStaticResult(this->activeCellInfo(), this, "MULTPV", multpvDataTemp); + porvResults = RigCaseCellResultsData::getResultIndexableStaticResult(this->activeCellInfo(), this, "PORV", porvDataTemp); + if (!porvResults || porvResults->empty()) + { + RiaLogging::error("Assumed PORV, but not data was found."); + return; + } - CVF_ASSERT(!porvResults->empty()); + swcrResults = RigCaseCellResultsData::getResultIndexableStaticResult(this->activeCellInfo(), this, "SWCR", swcrDataTemp); + multpvResults = + RigCaseCellResultsData::getResultIndexableStaticResult(this->activeCellInfo(), this, "MULTPV", multpvDataTemp); size_t mobPVIdx = this->findOrCreateScalarResultIndex(RiaDefines::STATIC_NATIVE, RiaDefines::mobilePoreVolumeName(), false); - std::vector &mobPVResults = this->cellScalarResults(mobPVIdx)[0]; + std::vector& mobPVResults = this->cellScalarResults(mobPVIdx)[0]; // Set up output container to correct number of results mobPVResults.resize(porvResults->size()); - if (!(multpvResults || swcrResults)) + if (multpvResults && swcrResults) { - mobPVResults.assign(porvResults->begin(), porvResults->end()); + for (size_t vIdx = 0; vIdx < porvResults->size(); ++vIdx) + { + mobPVResults[vIdx] = (*multpvResults)[vIdx] * (*porvResults)[vIdx] * (1.0 - (*swcrResults)[vIdx]); + } } - else if (!multpvResults) + else if (!multpvResults && swcrResults) { for (size_t vIdx = 0; vIdx < porvResults->size(); ++vIdx) { mobPVResults[vIdx] = (*porvResults)[vIdx] * (1.0 - (*swcrResults)[vIdx]); } } - else if (!swcrResults) + else if (!swcrResults && multpvResults) { for (size_t vIdx = 0; vIdx < porvResults->size(); ++vIdx) { @@ -2328,24 +2553,20 @@ void RigCaseCellResultsData::computeMobilePV() } else { - for (size_t vIdx = 0; vIdx < porvResults->size(); ++vIdx) - { - mobPVResults[vIdx] = (*multpvResults)[vIdx] * (*porvResults)[vIdx] * (1.0 - (*swcrResults)[vIdx]); - } + mobPVResults.assign(porvResults->begin(), porvResults->end()); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setReaderInterface(RifReaderInterface* readerInterface) { m_readerInterface = readerInterface; } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigCaseCellResultsData::setHdf5Filename(const QString& hdf5SourSimFilename) { @@ -2366,7 +2587,7 @@ bool RigCaseCellResultsData::isDataPresent(size_t scalarResultIndex) const return false; } - const std::vector< std::vector >& data = this->cellScalarResults(scalarResultIndex); + const std::vector>& data = this->cellScalarResults(scalarResultIndex); for (size_t tsIdx = 0; tsIdx < data.size(); ++tsIdx) { @@ -2379,3 +2600,59 @@ bool RigCaseCellResultsData::isDataPresent(size_t scalarResultIndex) const return false; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseCellResultsData::assignValuesToTemporaryLgrs(const QString& resultName, + std::vector& valuesForAllReservoirCells) +{ + CVF_ASSERT(m_activeCellInfo); + + static std::vector excludedProperties = { + "MOBPROV", "PORV", "FIPOIL", "FIPGAS", "FIPWAT", "FLROILI+", "FLROILJ+", "FLROILK+", "FLRGASI+", + "FLRGASJ+", "FLRGASK+", "FLRWATI+", "FLRWATJ+", "FLRWATK+", "FLOOILI+", "FLOWATI+", "FLOGASI+", "FLOOILJ+", + "FLOWATJ+", "FLOGASJ+", "FLOOILK+", "FLOWATK+", "FLOGASK+", "SFIPGAS", "SFIPOIL", "SFIPWAT", "AREAX", + "AREAY", "AREAZ", "DIFFX", "DIFFY", "DIFFZ", "DZNET", "HEATTX", "HEATTY", "HEATTZ", + "LX", "LY", "LZ", "MINPVV", "TRANX", "TRANY", "TRANZ", + }; + + if (std::find(excludedProperties.begin(), excludedProperties.end(), resultName) != excludedProperties.end()) + { + return; + } + + bool invalidCellsDetected = false; + for (size_t gridIdx = 0; gridIdx < m_ownerMainGrid->gridCount(); gridIdx++) + { + const auto& grid = m_ownerMainGrid->gridByIndex(gridIdx); + if (grid->isTempGrid()) + { + for (size_t localCellIdx = 0; localCellIdx < grid->cellCount(); localCellIdx++) + { + const RigCell& cell = grid->cell(localCellIdx); + + size_t mainGridCellIndex = cell.mainGridCellIndex(); + size_t reservoirCellIndex = grid->reservoirCellIndex(localCellIdx); + + size_t mainGridCellResultIndex = m_activeCellInfo->cellResultIndex(mainGridCellIndex); + size_t cellResultIndex = m_activeCellInfo->cellResultIndex(reservoirCellIndex); + + if (mainGridCellResultIndex != cvf::UNDEFINED_SIZE_T && cellResultIndex != cvf::UNDEFINED_SIZE_T) + { + double mainGridValue = valuesForAllReservoirCells[mainGridCellResultIndex]; + + valuesForAllReservoirCells[cellResultIndex] = mainGridValue; + } + else + { + invalidCellsDetected = true; + } + } + } + } + + if (invalidCellsDetected) + { + RiaLogging::warning("Detected invalid/undefined cells when assigning result values to temporary LGRs"); + } +} diff --git a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h index 5d0d420319..6b7a04516c 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h +++ b/ApplicationCode/ReservoirDataModel/RigCaseCellResultsData.h @@ -20,8 +20,6 @@ #pragma once -#include "RifReaderInterface.h" - #include "RiaDefines.h" #include "cvfCollection.h" @@ -37,6 +35,7 @@ class RigMainGrid; class RigEclipseResultInfo; class RigStatisticsDataCache; class RigEclipseTimeStepInfo; +class RigEclipseCaseData; //================================================================================================== /// Class containing the results for the complete number of active cells. Both main grid and LGR's @@ -50,9 +49,9 @@ class RigCaseCellResultsData : public cvf::Object void setHdf5Filename(const QString& hdf5SourSimFilename ); void setMainGrid(RigMainGrid* ownerGrid); - void setActiveCellInfo(RigActiveCellInfo* activeCellInfo) { m_activeCellInfo = activeCellInfo;} - RigActiveCellInfo* activeCellInfo() { return m_activeCellInfo;} - const RigActiveCellInfo* activeCellInfo() const { return m_activeCellInfo;} + void setActiveCellInfo(RigActiveCellInfo* activeCellInfo); + RigActiveCellInfo* activeCellInfo(); + const RigActiveCellInfo* activeCellInfo() const; // Max and min values of the results void recalculateStatistics(size_t scalarResultIndex); @@ -81,12 +80,10 @@ class RigCaseCellResultsData : public cvf::Object std::vector allTimeStepDatesFromEclipseReader() const; std::vector timeStepDates() const; - QDateTime timeStepDate(size_t scalarResultIndex, size_t timeStepIndex) const; std::vector timeStepDates(size_t scalarResultIndex) const; std::vector daysSinceSimulationStart() const; std::vector daysSinceSimulationStart(size_t scalarResultIndex) const; int reportStepNumber(size_t scalarResultIndex, size_t timeStepIndex) const; - std::vector reportStepNumbers(size_t scalarResultIndex) const; std::vector timeStepInfos(size_t scalarResultIndex) const; void setTimeStepInfos(size_t scalarResultIndex, const std::vector& timeStepInfos); @@ -105,10 +102,14 @@ class RigCaseCellResultsData : public cvf::Object void createPlaceholderResultEntries(); void computeDepthRelatedResults(); + void computeCellVolumes(); void clearScalarResult(RiaDefines::ResultCatType type, const QString & resultName); + void clearScalarResult(const RigEclipseResultInfo& resultInfo); void clearAllResults(); void freeAllocatedResultsData(); + bool isResultLoaded(const RigEclipseResultInfo& resultInfo) const; + // Access the results data @@ -124,7 +125,7 @@ class RigCaseCellResultsData : public cvf::Object std::vector &activeCellsResultsTempContainer); public: - const std::vector& infoForEachResultIndex() { return m_resultInfos;} + const std::vector& infoForEachResultIndex(); bool mustBeCalculated(size_t scalarResultIndex) const; void setMustBeCalculated(size_t scalarResultIndex); @@ -154,10 +155,13 @@ class RigCaseCellResultsData : public cvf::Object void computeCompletionTypeForTimeStep(size_t timeStep); double darchysValue(); + void computeOilVolumes(); void computeMobilePV(); bool isDataPresent(size_t scalarResultIndex) const; + void assignValuesToTemporaryLgrs(const QString& resultName, std::vector& values); + cvf::ref m_readerInterface; private: @@ -169,5 +173,5 @@ class RigCaseCellResultsData : public cvf::Object RigMainGrid* m_ownerMainGrid; RigEclipseCaseData* m_ownerCaseData; - RigActiveCellInfo* m_activeCellInfo; + RigActiveCellInfo* m_activeCellInfo; }; diff --git a/ApplicationCode/ReservoirDataModel/RigCaseRealizationParameters.cpp b/ApplicationCode/ReservoirDataModel/RigCaseRealizationParameters.cpp index 9c24814311..f1bef50200 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseRealizationParameters.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseRealizationParameters.cpp @@ -17,12 +17,17 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RigCaseRealizationParameters.h" -#include + +#include +#include + +#include +#include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigCaseRealizationParameters::Value::Value() : m_valueType(TYPE_NONE), m_numericValue(HUGE_VAL) +RigCaseRealizationParameters::Value::Value() : m_valueType(TYPE_NONE), m_numericValue(std::numeric_limits::infinity()) { } @@ -98,7 +103,7 @@ void RigCaseRealizationParameters::addParameter(const QString& name, const QStri //-------------------------------------------------------------------------------------------------- RigCaseRealizationParameters::Value RigCaseRealizationParameters::parameterValue(const QString& name) { - if (m_parameters.count(name) == 0) return HUGE_VAL; + if (m_parameters.count(name) == 0) return Value(); return m_parameters[name]; } @@ -109,3 +114,86 @@ std::map RigCaseRealizationParamet { return m_parameters; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set RigCaseRealizationParameters::parameterNames() const +{ + std::set names; + for (auto& par : parameters()) names.insert(par.first); + return names; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigCaseRealizationParameters::parameterHash(const QString& name) const +{ + auto itr = m_parameters.find(name); + if (itr == m_parameters.end() || !itr->second.isValid()) return 0; + + std::hash stringHasher; + std::hash doubleHasher; + size_t nameHash; + size_t valueHash = 0; + + nameHash = stringHasher(name.toStdString()); + + auto value = itr->second; + if (value.isNumeric()) + { + valueHash = doubleHasher(value.numericValue()); + } + else if (value.isText()) + { + valueHash = stringHasher(value.textValue().toStdString()); + } + + QString s = QString::number(nameHash) + QString::number(valueHash); + return stringHasher((QString::number(nameHash) + QString::number(valueHash)).toStdString()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigCaseRealizationParameters::parametersHash() +{ + if (m_parametersHash == 0) calculateParametersHash(); + return m_parametersHash; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseRealizationParameters::clearParametersHash() +{ + m_parametersHash = 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigCaseRealizationParameters::calculateParametersHash(const std::set& paramNames /*= std::set()*/) +{ + QStringList hashes; + + if (paramNames.empty()) + { + for (auto param : m_parameters) + { + hashes.push_back(QString::number(parameterHash(param.first))); + } + } + else + { + for (auto paramName : paramNames) + { + if (m_parameters.find(paramName) == m_parameters.end()) return; + hashes.push_back(QString::number(parameterHash(paramName))); + } + } + + std::hash stringHasher; + m_parametersHash = stringHasher(hashes.join("").toStdString()); +} diff --git a/ApplicationCode/ReservoirDataModel/RigCaseRealizationParameters.h b/ApplicationCode/ReservoirDataModel/RigCaseRealizationParameters.h index 0ad579281a..b4cc1bc0ad 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseRealizationParameters.h +++ b/ApplicationCode/ReservoirDataModel/RigCaseRealizationParameters.h @@ -24,9 +24,9 @@ #include #include +#include #include - //================================================================================================== // // @@ -47,7 +47,7 @@ class RigCaseRealizationParameters void setValue(double value); void setValue(const QString& value); - bool isEmpty() const { return m_valueType == TYPE_NONE; } + bool isValid() const { return m_valueType != TYPE_NONE; } bool isNumeric() const { return m_valueType == TYPE_NUMERIC; } bool isText() const { return m_valueType == TYPE_TEXT; } @@ -60,12 +60,22 @@ class RigCaseRealizationParameters QString m_textValue; }; + RigCaseRealizationParameters() : m_parametersHash(0) { } + void addParameter(const QString& name, double value); void addParameter(const QString& name, const QString& value); Value parameterValue(const QString& name); std::map parameters() const; + std::set parameterNames() const; + + size_t parameterHash(const QString& name) const; + size_t parametersHash(); + + void clearParametersHash(); + void calculateParametersHash(const std::set& paramNames = std::set()); private: std::map m_parameters; + size_t m_parametersHash; }; diff --git a/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapperTools.cpp b/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapperTools.cpp index 2ea21dd336..2c59722392 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapperTools.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseToCaseCellMapperTools.cpp @@ -39,7 +39,7 @@ class RigNeighborCornerFinder m_baseK(baseK) {} - const caf::SizeTArray8* neighborIndices(int offsetI, int offsetJ, int offsetK) + const std::array* neighborIndices(int offsetI, int offsetJ, int offsetK) { if (offsetI < 0 && m_baseI == 0) return nullptr; if (offsetJ < 0 && m_baseJ == 0) return nullptr; @@ -88,35 +88,35 @@ void RigCaseToCaseCellMapperTools::estimatedFemCellFromEclCell(const RigMainGrid // 6 <- PI[7] PIPJ[4] PJ[5] PK[2] PIPK[3] PIPJPK[0] PJPK[1] // 7 <- PJ[4] NIPJ[5] NI[6] PK[3] PJPK[0] NIPJPK[1] NIPK[2] - const caf::SizeTArray8* IJK = nbFinder.neighborIndices( 0, 0, 0); - const caf::SizeTArray8* NI = nbFinder.neighborIndices(-1, 0, 0); - const caf::SizeTArray8* NJ = nbFinder.neighborIndices( 0,-1, 0); - const caf::SizeTArray8* PI = nbFinder.neighborIndices( 1, 0, 0); - const caf::SizeTArray8* PJ = nbFinder.neighborIndices( 0, 1, 0); - const caf::SizeTArray8* NK = nbFinder.neighborIndices( 0, 0,-1); - const caf::SizeTArray8* PK = nbFinder.neighborIndices( 0, 0, 1); - const caf::SizeTArray8* NINJ = nbFinder.neighborIndices(-1,-1, 0); - const caf::SizeTArray8* PINJ = nbFinder.neighborIndices( 1,-1, 0); - - const caf::SizeTArray8* PIPJ = nbFinder.neighborIndices( 1, 1, 0); - const caf::SizeTArray8* NIPJ = nbFinder.neighborIndices(-1, 1, 0); - const caf::SizeTArray8* NINK = nbFinder.neighborIndices(-1, 0,-1); - const caf::SizeTArray8* NJNK = nbFinder.neighborIndices( 0,-1,-1); - const caf::SizeTArray8* PINK = nbFinder.neighborIndices( 1, 0,-1); - const caf::SizeTArray8* PJNK = nbFinder.neighborIndices( 0, 1,-1); - const caf::SizeTArray8* NIPK = nbFinder.neighborIndices(-1, 0, 1); - const caf::SizeTArray8* NJPK = nbFinder.neighborIndices( 0,-1, 1); - const caf::SizeTArray8* PIPK = nbFinder.neighborIndices( 1, 0, 1); - - const caf::SizeTArray8* PJPK = nbFinder.neighborIndices( 0, 1, 1); - const caf::SizeTArray8* NINJNK = nbFinder.neighborIndices(-1,-1,-1); - const caf::SizeTArray8* PINJNK = nbFinder.neighborIndices( 1,-1,-1); - const caf::SizeTArray8* PIPJNK = nbFinder.neighborIndices( 1, 1,-1); - const caf::SizeTArray8* NIPJNK = nbFinder.neighborIndices(-1, 1,-1); - const caf::SizeTArray8* NINJPK = nbFinder.neighborIndices(-1,-1, 1); - const caf::SizeTArray8* PINJPK = nbFinder.neighborIndices( 1,-1, 1); - const caf::SizeTArray8* PIPJPK = nbFinder.neighborIndices( 1, 1, 1); - const caf::SizeTArray8* NIPJPK = nbFinder.neighborIndices(-1, 1, 1); + const std::array* IJK = nbFinder.neighborIndices( 0, 0, 0); + const std::array* NI = nbFinder.neighborIndices(-1, 0, 0); + const std::array* NJ = nbFinder.neighborIndices( 0,-1, 0); + const std::array* PI = nbFinder.neighborIndices( 1, 0, 0); + const std::array* PJ = nbFinder.neighborIndices( 0, 1, 0); + const std::array* NK = nbFinder.neighborIndices( 0, 0,-1); + const std::array* PK = nbFinder.neighborIndices( 0, 0, 1); + const std::array* NINJ = nbFinder.neighborIndices(-1,-1, 0); + const std::array* PINJ = nbFinder.neighborIndices( 1,-1, 0); + + const std::array* PIPJ = nbFinder.neighborIndices( 1, 1, 0); + const std::array* NIPJ = nbFinder.neighborIndices(-1, 1, 0); + const std::array* NINK = nbFinder.neighborIndices(-1, 0,-1); + const std::array* NJNK = nbFinder.neighborIndices( 0,-1,-1); + const std::array* PINK = nbFinder.neighborIndices( 1, 0,-1); + const std::array* PJNK = nbFinder.neighborIndices( 0, 1,-1); + const std::array* NIPK = nbFinder.neighborIndices(-1, 0, 1); + const std::array* NJPK = nbFinder.neighborIndices( 0,-1, 1); + const std::array* PIPK = nbFinder.neighborIndices( 1, 0, 1); + + const std::array* PJPK = nbFinder.neighborIndices( 0, 1, 1); + const std::array* NINJNK = nbFinder.neighborIndices(-1,-1,-1); + const std::array* PINJNK = nbFinder.neighborIndices( 1,-1,-1); + const std::array* PIPJNK = nbFinder.neighborIndices( 1, 1,-1); + const std::array* NIPJNK = nbFinder.neighborIndices(-1, 1,-1); + const std::array* NINJPK = nbFinder.neighborIndices(-1,-1, 1); + const std::array* PINJPK = nbFinder.neighborIndices( 1,-1, 1); + const std::array* PIPJPK = nbFinder.neighborIndices( 1, 1, 1); + const std::array* NIPJPK = nbFinder.neighborIndices(-1, 1, 1); std::vector contributingNodeIndicesPrCellCorner[8]; @@ -432,7 +432,7 @@ if ( ( (es.x() + xyTolerance) >= cs.x() && (el.x() - xyTolerance) <= cl.x()) { const std::vector& eclNodes = eclGrid->nodes(); const RigCell& cell = eclGrid->cells()[reservoirCellIndex]; - const caf::SizeTArray8& cornerIndices = cell.cornerIndices(); + const std::array& cornerIndices = cell.cornerIndices(); int faceNodeCount; const int* localElmNodeIndicesForTopZFace = RigFemTypes::localElmNodeIndicesForFace(HEX8, 4, &faceNodeCount); const int* localElmNodeIndicesForBotZFace = RigFemTypes::localElmNodeIndicesForFace(HEX8, 5, &faceNodeCount); diff --git a/ApplicationCode/ReservoirDataModel/RigCaseToCaseRangeFilterMapper.cpp b/ApplicationCode/ReservoirDataModel/RigCaseToCaseRangeFilterMapper.cpp index f8b2a55099..fc99f16db9 100644 --- a/ApplicationCode/ReservoirDataModel/RigCaseToCaseRangeFilterMapper.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCaseToCaseRangeFilterMapper.cpp @@ -108,9 +108,9 @@ void RigCaseToCaseRangeFilterMapper::convertRangeFilter(const RimCellRangeFilter } else { - maxIIndex = femPart->structGrid()->cellCountI()- 1; - maxJIndex = femPart->structGrid()->cellCountJ()- 1; - maxKIndex = femPart->structGrid()->cellCountK()- 1; + maxIIndex = femPart->getOrCreateStructGrid()->cellCountI()- 1; + maxJIndex = femPart->getOrCreateStructGrid()->cellCountJ()- 1; + maxKIndex = femPart->getOrCreateStructGrid()->cellCountK()- 1; } src.EndI = CVF_MIN(src.EndI, maxIIndex); @@ -398,7 +398,8 @@ RigCaseToCaseRangeFilterMapper::findBestFemCellFromEclCell(const RigMainGrid* ma if (elmIdxToBestMatch != -1) { - dependentFemPart->structGrid()->ijkFromCellIndex(elmIdxToBestMatch, fi, fj, fk); + bool validIndex = dependentFemPart->getOrCreateStructGrid()->ijkFromCellIndex(elmIdxToBestMatch, fi, fj, fk); + CVF_ASSERT(validIndex); } else { @@ -428,7 +429,7 @@ RigCaseToCaseRangeFilterMapper::findBestEclCellFromFemCell(const RigFemPart* dep bool isEclFaceNormalsOutwards = masterEclGrid->isFaceNormalsOutwards(); - int elementIdx = static_cast(dependentFemPart->structGrid()->cellIndexFromIJK(fi, fj, fk)); + int elementIdx = static_cast(dependentFemPart->getOrCreateStructGrid()->cellIndexFromIJK(fi, fj, fk)); cvf::Vec3d elmCorners[8]; RigCaseToCaseCellMapperTools::elementCorners(dependentFemPart, elementIdx, elmCorners); diff --git a/ApplicationCode/ReservoirDataModel/RigCell.cpp b/ApplicationCode/ReservoirDataModel/RigCell.cpp index de3c29aca6..fa68e9cd1e 100644 --- a/ApplicationCode/ReservoirDataModel/RigCell.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCell.cpp @@ -20,6 +20,7 @@ #include "RigCell.h" +#include "RigCellGeometryTools.h" #include "RigMainGrid.h" #include "cvfPlane.h" #include "cvfRay.h" @@ -301,6 +302,21 @@ cvf::Vec3d RigCell::faceNormalWithAreaLenght(cvf::StructGridInterface::FaceType ( nodeCoords[m_cornerIndices[faceVertexIndices[3]]] - nodeCoords[m_cornerIndices[faceVertexIndices[1]]]); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigCell::volume() const +{ + const std::vector& nodeCoords = m_hostGrid->mainGrid()->nodes(); + + std::array hexCorners; + for (size_t i = 0; i < 8; ++i) + { + hexCorners[i] = nodeCoords.at(m_cornerIndices[i]); + } + return RigCellGeometryTools::calculateCellVolume(hexCorners); +} + //-------------------------------------------------------------------------------------------------- /// Find the intersection between the cell and the ray. The point closest to the ray origin is returned /// in \a intersectionPoint, while the return value is the total number of intersections with the 24 triangles @@ -355,7 +371,7 @@ int RigCell::firstIntersectionPoint(const cvf::Ray& ray, cvf::Vec3d* intersectio //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigCell::faceIndices(cvf::StructGridInterface::FaceType face, caf::SizeTArray4* indices) const +void RigCell::faceIndices(cvf::StructGridInterface::FaceType face, std::array* indices) const { cvf::ubyte faceVertexIndices[4]; cvf::StructGridInterface::cellFaceVertexIndices(face, faceVertexIndices); diff --git a/ApplicationCode/ReservoirDataModel/RigCell.h b/ApplicationCode/ReservoirDataModel/RigCell.h index 22887b2c73..bb8974b3cc 100644 --- a/ApplicationCode/ReservoirDataModel/RigCell.h +++ b/ApplicationCode/ReservoirDataModel/RigCell.h @@ -20,8 +20,10 @@ #pragma once #include "RigLocalGrid.h" + #include "cvfStructGrid.h" -#include "cafFixedArray.h" + +#include namespace cvf { @@ -36,9 +38,10 @@ class RigCell RigCell(); ~RigCell(); // Not virtual, to save space. Do not inherit from this class - caf::SizeTArray8& cornerIndices() { return m_cornerIndices;} - const caf::SizeTArray8& cornerIndices() const { return m_cornerIndices;} - void faceIndices(cvf::StructGridInterface::FaceType face, caf::SizeTArray4 * faceIndices) const ; + std::array& cornerIndices() { return m_cornerIndices;} + const std::array& cornerIndices() const { return m_cornerIndices;} + + void faceIndices(cvf::StructGridInterface::FaceType face, std::array* faceIndices) const ; bool isInvalid() const { return m_isInvalid; } void setInvalid( bool val ) { m_isInvalid = val; } @@ -48,6 +51,7 @@ class RigCell RigLocalGrid* subGrid() const { return m_subGrid; } void setSubGrid(RigLocalGrid* subGrid) { m_subGrid = subGrid; } + void removeSubGrid(RigLocalGrid* subGrid) { m_subGrid = nullptr; } RigGridBase* hostGrid() const { return m_hostGrid; } void setHostGrid(RigGridBase* hostGrid) { m_hostGrid = hostGrid; } @@ -66,12 +70,14 @@ class RigCell cvf::Vec3d center() const; cvf::Vec3d faceCenter(cvf::StructGridInterface::FaceType face) const; cvf::Vec3d faceNormalWithAreaLenght(cvf::StructGridInterface::FaceType face) const; + double volume() const; + int firstIntersectionPoint(const cvf::Ray& ray, cvf::Vec3d* intersectionPoint) const; bool isLongPyramidCell(double maxHeightFactor = 5, double nodeNearTolerance = 1e-3 ) const; bool isCollapsedCell( double nodeNearTolerance = 1e-3) const; private: - caf::SizeTArray8 m_cornerIndices; + std::array m_cornerIndices; size_t m_gridLocalCellIndex; ///< This cells index in the grid it belongs to. RigGridBase* m_hostGrid; diff --git a/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h index ce21dcb42c..4e3f062eb2 100644 --- a/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigCellEdgeResultAccessor.h @@ -21,7 +21,7 @@ #include "RigResultAccessor.h" -#include "cafFixedArray.h" +#include //================================================================================================== @@ -34,12 +34,12 @@ class RigCellEdgeResultAccessor : public RigResultAccessor void setDataAccessObjectForFace(cvf::StructGridInterface::FaceType faceId, RigResultAccessor* resultAccessObject); - virtual double cellScalar(size_t gridLocalCellIndex) const; - virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; + double cellScalar(size_t gridLocalCellIndex) const override; + double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const override; - virtual double cellScalarGlobIdx(size_t globCellIndex) const; - virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; + double cellScalarGlobIdx(size_t globCellIndex) const override; + double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const override; private: - caf::FixedArray, 6> m_resultAccessObjects; + std::array, 6> m_resultAccessObjects; }; diff --git a/ApplicationCode/ReservoirDataModel/RigCellGeometryTools.cpp b/ApplicationCode/ReservoirDataModel/RigCellGeometryTools.cpp index 5986063465..6bf94fe9fa 100644 --- a/ApplicationCode/ReservoirDataModel/RigCellGeometryTools.cpp +++ b/ApplicationCode/ReservoirDataModel/RigCellGeometryTools.cpp @@ -23,11 +23,103 @@ #include "cafHexGridIntersectionTools/cafHexGridIntersectionTools.h" #include "cvfBoundingBox.h" +#include "cvfMatrix3.h" #include "clipper/clipper.hpp" +#include "cvfMath.h" + #include +#include +//-------------------------------------------------------------------------------------------------- +/// Efficient Computation of Volume of Hexahedral Cells +/// Jeffrey Grandy, Lawrence Livermore National Laboratory +/// https://www.osti.gov/servlets/purl/632793/ +/// +/// Note that in the paper the following vertex numbering is used +/// 6---------7 +/// /| /| |k +/// / | / | | /j +/// 4---------5 | |/ +/// | 2------|--3 *---i +/// | / | / +/// |/ |/ +/// 0---------1 +/// +/// While in ResInsight, this is the numbering. Thus we need to swap 2<->3, 6<->7 in the equations. +/// Note the negative k! This causes an additional set of 0<->4, 1<->5, etc. index swaps. +/// 7---------6 +/// /| /| |-k +/// / | / | | /j +/// 4---------5 | |/ +/// | 3------|--2 *---i +/// | / | / +/// |/ |/ +/// 0---------1 +//-------------------------------------------------------------------------------------------------- +double RigCellGeometryTools::calculateCellVolume(const std::array& x) +{ + // 6 * 3 flops = 18 flops + + // Perform index swap when retrieving corners but keep indices in variable names matching paper. + cvf::Vec3d x3mx0 = x[6] - x[4]; // Swap 3->2, then negate z by 2->6 and 0->4 + cvf::Vec3d x5mx0 = x[1] - x[4]; // Negate z by Swap 5->1 and 0->4 + cvf::Vec3d x6mx0 = x[3] - x[4]; // Swap 6->7, then negate z by 7->3 and 0->4 + cvf::Vec3d x7mx1 = x[2] - x[5]; // Swap 7->6, then negate z by 6->2 and 1->5 + cvf::Vec3d x7mx2 = x[2] - x[7]; // Swap 7->6, 2->3, then negate z by 6->2 and 3->7 + cvf::Vec3d x7mx4 = x[2] - x[0]; // Swap 7->6 then negate z by 6->2 and 4->0 + + // 3 flops for summation + 5 for dot product + 9 flops for cross product = 17 flops + double det1 = (x7mx1 + x6mx0) * (x7mx2 ^ x3mx0); + // 3 flops for summation + 5 for dot product + 9 flops for cross product = 17 flops + double det2 = x6mx0 * ((x7mx2 + x5mx0) ^ x7mx4); + // 3 flops for summation + 5 for dot product + 9 flops for cross product = 17 flops + double det3 = x7mx1 * (x5mx0 ^ (x7mx4 + x3mx0)); + + // 2 flops for summation + 1 for division = 3 flops + double volume = (det1 + det2 + det3) / 12.0; + + // In order for this to work in any rotation of the cell, we need the absolute value. 1 flop. + return std::abs(volume); // Altogether 18 + 3*17 + 3 + 1 flops = 73 flops. +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::array RigCellGeometryTools::estimateHexOverlapWithBoundingBox(const std::array& hexCorners, const cvf::BoundingBox& boundingBox, cvf::BoundingBox* overlapBoundingBox) +{ + CVF_ASSERT(overlapBoundingBox); + *overlapBoundingBox = cvf::BoundingBox(); + std::array overlapCorners = hexCorners; + // A reasonable approximation to the overlap volume + cvf::Plane topPlane; topPlane.setFromPoints(hexCorners[0], hexCorners[1], hexCorners[2]); + cvf::Plane bottomPlane; bottomPlane.setFromPoints(hexCorners[4], hexCorners[5], hexCorners[6]); + + for (size_t i = 0; i < 4; ++i) + { + cvf::Vec3d& corner = overlapCorners[i]; + corner.x() = cvf::Math::clamp(corner.x(), boundingBox.min().x(), boundingBox.max().x()); + corner.y() = cvf::Math::clamp(corner.y(), boundingBox.min().y(), boundingBox.max().y()); + corner.z() = cvf::Math::clamp(corner.z(), boundingBox.min().z(), boundingBox.max().z()); + cvf::Vec3d maxZCorner = corner; maxZCorner.z() = boundingBox.max().z(); + cvf::Vec3d minZCorner = corner; minZCorner.z() = boundingBox.min().z(); + topPlane.intersect(minZCorner, maxZCorner, &corner); + overlapBoundingBox->add(corner); + } + for (size_t i = 4; i < 8; ++i) + { + cvf::Vec3d& corner = overlapCorners[i]; + corner.x() = cvf::Math::clamp(corner.x(), boundingBox.min().x(), boundingBox.max().x()); + corner.y() = cvf::Math::clamp(corner.y(), boundingBox.min().y(), boundingBox.max().y()); + corner.z() = cvf::Math::clamp(corner.z(), boundingBox.min().z(), boundingBox.max().z()); + cvf::Vec3d maxZCorner = corner; maxZCorner.z() = boundingBox.max().z(); + cvf::Vec3d minZCorner = corner; minZCorner.z() = boundingBox.min().z(); + bottomPlane.intersect(minZCorner, maxZCorner, &corner); + overlapBoundingBox->add(corner); + } + return overlapCorners; +} //-------------------------------------------------------------------------------------------------- /// @@ -151,7 +243,7 @@ void RigCellGeometryTools::findCellLocalXYZ(const std::array& hex //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RigCellGeometryTools::polygonLengthInLocalXdirWeightedByArea(std::vector polygonToCalcLengthOf) +double RigCellGeometryTools::polygonLengthInLocalXdirWeightedByArea(const std::vector& polygonToCalcLengthOf) { //Find bounding box cvf::BoundingBox polygonBBox; @@ -250,19 +342,20 @@ cvf::Vec3d fromClipperPoint(const ClipperLib::IntPoint& clipPoint) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector > RigCellGeometryTools::intersectPolygons(std::vector polygon1, std::vector polygon2) +std::vector > RigCellGeometryTools::intersectPolygons(const std::vector& polygon1, + const std::vector& polygon2) { std::vector > clippedPolygons; // Convert to int for clipper library and store as clipper "path" ClipperLib::Path polygon1path; - for (cvf::Vec3d& v : polygon1) + for (const cvf::Vec3d& v : polygon1) { polygon1path.push_back(toClipperPoint(v)); } ClipperLib::Path polygon2path; - for (cvf::Vec3d& v : polygon2) + for (const cvf::Vec3d& v : polygon2) { polygon2path.push_back(toClipperPoint(v)); } @@ -288,6 +381,56 @@ std::vector > RigCellGeometryTools::intersectPolygons(st return clippedPolygons; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector> + RigCellGeometryTools::subtractPolygons(const std::vector& sourcePolygon, + const std::vector>& polygonsToSubtract) +{ + ClipperLib::Clipper clpr; + + { + // Convert to int for clipper library and store as clipper "path" + ClipperLib::Path polygon1path; + for (const auto& v : sourcePolygon) + { + polygon1path.push_back(toClipperPoint(v)); + } + clpr.AddPath(polygon1path, ClipperLib::ptSubject, true); + } + + for (const auto& path : polygonsToSubtract) + { + ClipperLib::Path polygon2path; + for (const auto& v : path) + { + polygon2path.push_back(toClipperPoint(v)); + } + + clpr.AddPath(polygon2path, ClipperLib::ptClip, true); + } + + ClipperLib::Paths solution; + clpr.Execute(ClipperLib::ctDifference, solution, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); + + std::vector> clippedPolygons; + + // Convert back to std::vector > + for (ClipperLib::Path pathInSol : solution) + { + std::vector clippedPolygon; + for (ClipperLib::IntPoint IntPosition : pathInSol) + { + clippedPolygon.push_back(fromClipperPoint(IntPosition)); + } + + clippedPolygons.push_back(clippedPolygon); + } + + return clippedPolygons; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -408,28 +551,30 @@ std::vector > RigCellGeometryTools::clipPolylineByPolygo //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::pair RigCellGeometryTools::getLineThroughBoundingBox(cvf::Vec3d lineDirection, cvf::BoundingBox polygonBBox, cvf::Vec3d pointOnLine) +std::pair RigCellGeometryTools::getLineThroughBoundingBox(const cvf::Vec3d& lineDirection, + const cvf::BoundingBox& polygonBBox, + const cvf::Vec3d& pointOnLine) { cvf::Vec3d bboxCorners[8]; polygonBBox.cornerVertices(bboxCorners); cvf::Vec3d startPoint = pointOnLine; cvf::Vec3d endPoint = pointOnLine; - + cvf::Vec3d lineDir = lineDirection; //To avoid doing many iterations in loops below linedirection should be quite large. - lineDirection.normalize(); - lineDirection = lineDirection * polygonBBox.extent().length() / 5; + lineDir.normalize(); + lineDir = lineDir * polygonBBox.extent().length() / 5; //Extend line in positive direction while (polygonBBox.contains(startPoint)) { - startPoint = startPoint + lineDirection; + startPoint = startPoint + lineDir; } //Extend line in negative direction while (polygonBBox.contains(endPoint)) { - endPoint = endPoint - lineDirection; + endPoint = endPoint - lineDir; } std::pair line; @@ -458,7 +603,7 @@ double RigCellGeometryTools::getLengthOfPolygonAlongLine(const std::pair RigCellGeometryTools::unionOfPolygons(std::vector> polygons) +std::vector RigCellGeometryTools::unionOfPolygons(const std::vector>& polygons) { // Convert to int for clipper library and store as clipper "path" std::vector polygonPaths; diff --git a/ApplicationCode/ReservoirDataModel/RigCellGeometryTools.h b/ApplicationCode/ReservoirDataModel/RigCellGeometryTools.h index 24fc67fbf7..9de7ae10d8 100644 --- a/ApplicationCode/ReservoirDataModel/RigCellGeometryTools.h +++ b/ApplicationCode/ReservoirDataModel/RigCellGeometryTools.h @@ -1,17 +1,17 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// @@ -28,33 +28,50 @@ #include #include - - class RigCellGeometryTools { public: + static double calculateCellVolume(const std::array& hexCorners); + static std::array estimateHexOverlapWithBoundingBox(const std::array& hexCorners, + const cvf::BoundingBox& boundingBox2dExtrusion, + cvf::BoundingBox* overlapBoundingBox); + + static void createPolygonFromLineSegments(std::list>& intersectionLineSegments, + std::vector>& polygons); - static void createPolygonFromLineSegments(std::list> &intersectionLineSegments, std::vector> &polygons); + static void findCellLocalXYZ(const std::array& hexCorners, + cvf::Vec3d& localXdirection, + cvf::Vec3d& localYdirection, + cvf::Vec3d& localZdirection); - static void findCellLocalXYZ(const std::array& hexCorners, cvf::Vec3d &localXdirection, cvf::Vec3d &localYdirection, cvf::Vec3d &localZdirection); + static double polygonLengthInLocalXdirWeightedByArea(const std::vector& polygon2d); - static double polygonLengthInLocalXdirWeightedByArea(std::vector polygon2d); - - static std::vector > intersectPolygons(std::vector polygon1, std::vector polygon2); + static std::vector> intersectPolygons(const std::vector& polygon1, + const std::vector& polygon2); - enum ZInterpolationType { INTERPOLATE_LINE_Z, USE_HUGEVAL, USE_ZERO}; - static std::vector > clipPolylineByPolygon(const std::vector& polyLine, - const std::vector& polygon, - ZInterpolationType interpolType = USE_ZERO); + static std::vector> subtractPolygons(const std::vector& sourcePolygon, + const std::vector>& polygonToSubtract); - static std::pair getLineThroughBoundingBox(cvf::Vec3d lineDirection, cvf::BoundingBox polygonBBox, cvf::Vec3d pointOnLine); + enum ZInterpolationType + { + INTERPOLATE_LINE_Z, + USE_HUGEVAL, + USE_ZERO + }; + static std::vector> clipPolylineByPolygon(const std::vector& polyLine, + const std::vector& polygon, + ZInterpolationType interpolType = USE_ZERO); - static double getLengthOfPolygonAlongLine(const std::pair& line, const std::vector& polygon); + static std::pair getLineThroughBoundingBox(const cvf::Vec3d& lineDirection, + const cvf::BoundingBox& polygonBBox, + const cvf::Vec3d& pointOnLine); - static std::vector unionOfPolygons(std::vector> polygons); + static double getLengthOfPolygonAlongLine(const std::pair& line, + const std::vector& polygon); + + static std::vector unionOfPolygons(const std::vector>& polygons); private: - static std::vector ajustPolygonToAvoidIntersectionsAtVertex(const std::vector& polyLine, + static std::vector ajustPolygonToAvoidIntersectionsAtVertex(const std::vector& polyLine, const std::vector& polygon); - }; diff --git a/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h index a3362c2da0..3f0d67d31e 100644 --- a/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigCombMultResultAccessor.h @@ -42,10 +42,10 @@ class RigCombMultResultAccessor : public RigResultAccessor RigResultAccessor* multZPosAccessor, RigResultAccessor* multZNegAccessor); - virtual double cellScalar(size_t gridLocalCellIndex) const; - virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; - virtual double cellScalarGlobIdx(size_t globCellIndex) const; - virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; + double cellScalar(size_t gridLocalCellIndex) const override; + double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const override; + double cellScalarGlobIdx(size_t globCellIndex) const override; + double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const override; private: double nativeMultScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; diff --git a/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h index 61c50235d6..f1a6ffe56c 100644 --- a/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigCombTransResultAccessor.h @@ -38,10 +38,10 @@ class RigCombTransResultAccessor : public RigResultAccessor RigResultAccessor* yTransAccessor, RigResultAccessor* zTransAccessor); - virtual double cellScalar(size_t gridLocalCellIndex) const; - virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; - virtual double cellScalarGlobIdx(size_t globCellIndex) const; - virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; + double cellScalar(size_t gridLocalCellIndex) const override; + double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const override; + double cellScalarGlobIdx(size_t globCellIndex) const override; + double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const override; private: double neighborCellTran(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId, const RigResultAccessor* transAccessor) const; diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.cpp b/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.cpp index f826c41094..c61253611d 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.cpp @@ -151,6 +151,30 @@ RigGridBase* RigEclipseCaseData::grid(size_t index) return m_mainGrid->gridByIndex(index); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigGridBase* RigEclipseCaseData::grid(const QString& gridName) const +{ + if (m_mainGrid.isNull()) + { + return nullptr; + } + + if (gridName.isEmpty()) + { + return m_mainGrid.p(); + } + + size_t i; + for (i = 0; i < m_mainGrid->gridCount(); i++) + { + const RigGridBase* grid = m_mainGrid->gridByIndex(i); + if (QString::fromStdString(grid->gridName()) == gridName) return grid; + } + return nullptr; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -626,17 +650,15 @@ void RigEclipseCaseData::computeActiveCellsGeometryBoundingBox() } else { + std::array hexCorners; for (size_t i = 0; i < m_mainGrid->cellCount(); i++) { if (activeInfos[acIdx]->isActive(i)) { - const RigCell& c = m_mainGrid->globalCellArray()[i]; - const caf::SizeTArray8& indices = c.cornerIndices(); - - size_t idx; - for (idx = 0; idx < 8; idx++) + m_mainGrid->cellCornerVertices(i, hexCorners.data()); + for (const auto& corner : hexCorners) { - bb.add(m_mainGrid->nodes()[indices[idx]]); + bb.add(corner); } } } diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.h b/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.h index 1b760d8cd3..d136f0e952 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseCaseData.h @@ -58,7 +58,7 @@ class RigEclipseCaseData : public cvf::Object { public: explicit RigEclipseCaseData(RimEclipseCase* ownerCase); - ~RigEclipseCaseData(); + ~RigEclipseCaseData() override; RimEclipseCase* ownerCase() const { return m_ownerCase; } @@ -71,6 +71,7 @@ class RigEclipseCaseData : public cvf::Object const RigGridBase* grid(size_t index) const; RigGridBase* grid(size_t index); size_t gridCount() const; + const RigGridBase* grid(const QString& gridName) const; RigCaseCellResultsData* results(RiaDefines::PorosityModelType porosityModel); const RigCaseCellResultsData* results(RiaDefines::PorosityModelType porosityModel) const; @@ -114,6 +115,8 @@ class RigEclipseCaseData : public cvf::Object void setVirtualPerforationTransmissibilities(RigVirtualPerforationTransmissibilities* virtualPerforationTransmissibilities); const RigVirtualPerforationTransmissibilities* virtualPerforationTransmissibilities() const; + void clearWellCellsInGridCache() { m_wellCellsInGrid.clear(); } + private: void computeActiveCellIJKBBox(); void computeWellCellsPrGrid(); diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseMultiPropertyStatCalc.h b/ApplicationCode/ReservoirDataModel/RigEclipseMultiPropertyStatCalc.h index 8c664611a7..3bd91f5f7e 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseMultiPropertyStatCalc.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseMultiPropertyStatCalc.h @@ -41,16 +41,16 @@ class RigEclipseMultiPropertyStatCalc : public RigStatisticsCalculator void addStatisticsCalculator(RigStatisticsCalculator* statisticsCalculator); void addNativeStatisticsCalculator(RigCaseCellResultsData* cellResultsData, size_t scalarResultIndices); - virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); - virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); + void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) override; + void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) override; - virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount); + void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount) override; - virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator); + void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator) override; - virtual void uniqueValues(size_t timeStepIndex, std::set& values); + void uniqueValues(size_t timeStepIndex, std::set& values) override; - virtual size_t timeStepCount(); + size_t timeStepCount() override; private: std::vector m_nativeStatisticsCalculators; diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseNativeStatCalc.h b/ApplicationCode/ReservoirDataModel/RigEclipseNativeStatCalc.h index 04fd59e4d0..84271c83f7 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseNativeStatCalc.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseNativeStatCalc.h @@ -35,13 +35,13 @@ class RigEclipseNativeStatCalc : public RigStatisticsCalculator public: RigEclipseNativeStatCalc(RigCaseCellResultsData* cellResultsData, size_t scalarResultIndex); - virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); - virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); - virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount); - virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator); - virtual void uniqueValues(size_t timeStepIndex, std::set& values); - virtual size_t timeStepCount(); - virtual void mobileVolumeWeightedMean(size_t timeStepIndex, double& mean); + void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) override; + void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) override; + void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount) override; + void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator) override; + void uniqueValues(size_t timeStepIndex, std::set& values) override; + size_t timeStepCount() override; + void mobileVolumeWeightedMean(size_t timeStepIndex, double& mean) override; private: RigCaseCellResultsData* m_resultsData; diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseNativeVisibleCellsStatCalc.h b/ApplicationCode/ReservoirDataModel/RigEclipseNativeVisibleCellsStatCalc.h index e67bf1daec..65b921cfc3 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseNativeVisibleCellsStatCalc.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseNativeVisibleCellsStatCalc.h @@ -39,13 +39,13 @@ class RigEclipseNativeVisibleCellsStatCalc : public RigStatisticsCalculator size_t scalarResultIndex, const cvf::UByteArray* cellVisibilities); - virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); - virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); - virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount); - virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator); - virtual void uniqueValues(size_t timeStepIndex, std::set& values); - virtual size_t timeStepCount(); - virtual void mobileVolumeWeightedMean(size_t timeStepIndex, double &result); + void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) override; + void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) override; + void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount) override; + void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator) override; + void uniqueValues(size_t timeStepIndex, std::set& values) override; + size_t timeStepCount() override; + void mobileVolumeWeightedMean(size_t timeStepIndex, double &result) override; private: diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseResultInfo.cpp b/ApplicationCode/ReservoirDataModel/RigEclipseResultInfo.cpp index 249ac41204..817749a334 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseResultInfo.cpp +++ b/ApplicationCode/ReservoirDataModel/RigEclipseResultInfo.cpp @@ -53,9 +53,8 @@ std::vector RigEclipseTimeStepInfo::createTimeStepInfos( //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigEclipseResultInfo::RigEclipseResultInfo(RiaDefines::ResultCatType resultType, bool needsToBeStored, bool mustBeCalculated, - QString resultName, size_t gridScalarResultIndex) - : m_resultType(resultType), +RigEclipseResultInfo::RigEclipseResultInfo(RiaDefines::ResultCatType resultType, + QString resultName, bool needsToBeStored, bool mustBeCalculated, size_t gridScalarResultIndex) : m_resultType(resultType), m_needsToBeStored(needsToBeStored), m_mustBeCalculated(mustBeCalculated), m_resultName(resultName), @@ -63,6 +62,88 @@ RigEclipseResultInfo::RigEclipseResultInfo(RiaDefines::ResultCatType resultType, { } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::ResultCatType RigEclipseResultInfo::resultType() const +{ + return m_resultType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseResultInfo::setResultType(RiaDefines::ResultCatType newType) +{ + m_resultType = newType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QString& RigEclipseResultInfo::resultName() const +{ + return m_resultName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseResultInfo::setResultName(const QString& name) +{ + m_resultName = name; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigEclipseResultInfo::needsToBeStored() const +{ + return m_needsToBeStored; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigEclipseResultInfo::mustBeCalculated() const +{ + return m_mustBeCalculated; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseResultInfo::setMustBeCalculated(bool mustCalculate) +{ + m_mustBeCalculated = mustCalculate; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigEclipseResultInfo::gridScalarResultIndex() const +{ + return m_gridScalarResultIndex; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigEclipseResultInfo::timeStepInfos() const +{ + return m_timeStepInfos; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigEclipseResultInfo::setTimeStepInfos(const std::vector& timeSteps) +{ + m_timeStepInfos = timeSteps; +} + + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -108,3 +189,18 @@ std::vector RigEclipseResultInfo::reportNumbers() const return values; } +//-------------------------------------------------------------------------------------------------- +/// Ordering operator for set storage. Just the type and name are used to find unique addresses. +//-------------------------------------------------------------------------------------------------- +bool RigEclipseResultInfo::operator<(const RigEclipseResultInfo& rhs) const +{ + if (m_resultType != rhs.resultType()) + { + return m_resultType < rhs.resultType(); + } + if (m_resultName != rhs.resultName()) + { + return m_resultName < rhs.resultName(); + } + return false; +} diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseResultInfo.h b/ApplicationCode/ReservoirDataModel/RigEclipseResultInfo.h index 009442e2eb..62c920712a 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseResultInfo.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseResultInfo.h @@ -49,14 +49,30 @@ class RigEclipseTimeStepInfo class RigEclipseResultInfo { public: - RigEclipseResultInfo(RiaDefines::ResultCatType resultType, bool needsToBeStored, bool mustBeCalculated, - QString resultName, size_t gridScalarResultIndex); + RigEclipseResultInfo(RiaDefines::ResultCatType resultType, + QString resultName, + bool needsToBeStored = false, + bool mustBeCalculated = false, + size_t gridScalarResultIndex = 0u); - std::vector dates() const; - std::vector daysSinceSimulationStarts() const; - std::vector reportNumbers() const; + RiaDefines::ResultCatType resultType() const; + void setResultType(RiaDefines::ResultCatType newType); + const QString& resultName() const; + void setResultName(const QString& name); + bool needsToBeStored() const; + bool mustBeCalculated() const; + void setMustBeCalculated(bool mustCalculate); + size_t gridScalarResultIndex() const; + + const std::vector& timeStepInfos() const; + void setTimeStepInfos(const std::vector& timeSteps); -public: + std::vector dates() const; + std::vector daysSinceSimulationStarts() const; + std::vector reportNumbers() const; + + bool operator<(const RigEclipseResultInfo& rhs) const; +private: RiaDefines::ResultCatType m_resultType; bool m_needsToBeStored; bool m_mustBeCalculated; diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp index 5b5079c5bb..5b66c60d15 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.cpp @@ -75,7 +75,7 @@ void RigEclipseWellLogExtractor::calculateIntersection() { const RigCell& cell = m_caseData->mainGrid()->globalCellArray()[globalCellIndex]; - if (cell.isInvalid()) continue; + if (cell.isInvalid() || cell.subGrid() != nullptr) continue; m_caseData->mainGrid()->cellCornerVertices(globalCellIndex, hexCorners); diff --git a/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h index e6067d0616..e269e46f11 100644 --- a/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h +++ b/ApplicationCode/ReservoirDataModel/RigEclipseWellLogExtractor.h @@ -44,7 +44,7 @@ class RigEclipseWellLogExtractor : public RigWellLogExtractor private: void calculateIntersection(); std::vector findCloseCellIndices(const cvf::BoundingBox& bb); - virtual cvf::Vec3d calculateLengthInCell(size_t cellIndex, + cvf::Vec3d calculateLengthInCell(size_t cellIndex, const cvf::Vec3d& startPoint, const cvf::Vec3d& endPoint) const override; diff --git a/ApplicationCode/ReservoirDataModel/RigFault.cpp b/ApplicationCode/ReservoirDataModel/RigFault.cpp index 2b86d45bd8..aa43dca582 100644 --- a/ApplicationCode/ReservoirDataModel/RigFault.cpp +++ b/ApplicationCode/ReservoirDataModel/RigFault.cpp @@ -2,35 +2,34 @@ // // Copyright (C) Statoil ASA // Copyright (C) Ceetron Solutions AS -// +// // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RigFault.h" + #include "RigMainGrid.h" cvf::ref RigFault::m_faultsPrCellAcc; //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RigFault::RigFault() -{ -} +RigFault::RigFault() {} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigFault::addCellRangeForFace(cvf::StructGridInterface::FaceType face, const cvf::CellRange& cellRange) { @@ -41,7 +40,7 @@ void RigFault::addCellRangeForFace(cvf::StructGridInterface::FaceType face, cons } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigFault::setName(const QString& name) { @@ -49,7 +48,7 @@ void RigFault::setName(const QString& name) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QString RigFault::name() const { @@ -57,7 +56,7 @@ QString RigFault::name() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector& RigFault::faultFaces() { @@ -65,7 +64,7 @@ std::vector& RigFault::faultFaces() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const std::vector& RigFault::faultFaces() const { @@ -73,7 +72,23 @@ const std::vector& RigFault::faultFaces() const } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +std::vector& RigFault::connectionIndices() +{ + return m_connectionIndices; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigFault::connectionIndices() const +{ + return m_connectionIndices; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RigFault::computeFaultFacesFromCellRanges(const RigMainGrid* mainGrid) { @@ -87,10 +102,8 @@ void RigFault::computeFaultFacesFromCellRanges(const RigMainGrid* mainGrid) const std::vector& cellRanges = m_cellRangesForFaces[faceType]; - for (size_t i = 0; i < cellRanges.size(); i++) + for (const cvf::CellRange& cellRange : cellRanges) { - const cvf::CellRange& cellRange = cellRanges[i]; - cvf::Vec3st min, max; cellRange.range(min, max); @@ -116,20 +129,20 @@ void RigFault::computeFaultFacesFromCellRanges(const RigMainGrid* mainGrid) } // Do not need to compute global grid cell index as for a maingrid localIndex == globalIndex - //size_t reservoirCellIndex = grid->reservoirCellIndex(gridLocalCellIndex); + // size_t reservoirCellIndex = grid->reservoirCellIndex(gridLocalCellIndex); size_t ni, nj, nk; mainGrid->neighborIJKAtCellFace(i, j, k, faceEnum, &ni, &nj, &nk); if (ni < mainGrid->cellCountI() && nj < mainGrid->cellCountJ() && nk < mainGrid->cellCountK()) { size_t gridLocalCellIndex = mainGrid->cellIndexFromIJK(i, j, k); - size_t oppositeCellIndex = mainGrid->cellIndexFromIJK(ni, nj, nk); + size_t oppositeCellIndex = mainGrid->cellIndexFromIJK(ni, nj, nk); m_faultFaces.push_back(FaultFace(gridLocalCellIndex, faceEnum, oppositeCellIndex)); } else { - //cvf::Trace::show("Warning: Undefined Fault neighbor detected."); + // cvf::Trace::show("Warning: Undefined Fault neighbor detected."); } } } @@ -138,18 +151,18 @@ void RigFault::computeFaultFacesFromCellRanges(const RigMainGrid* mainGrid) } } - -void RigFault::accumulateFaultsPrCell(RigFaultsPrCellAccumulator* faultsPrCellAcc, int faultIdx) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigFault::accumulateFaultsPrCell(RigFaultsPrCellAccumulator* faultsPrCellAcc, int faultIdx) { - - for (size_t ffIdx = 0; ffIdx < m_faultFaces.size(); ++ffIdx) + for (const FaultFace& ff : m_faultFaces) { - const FaultFace& ff = m_faultFaces[ffIdx]; - - // Could detect overlapping faults here .... if (faultsPrCellAcc->faultIdx(ff.m_nativeReservoirCellIndex, ff.m_nativeFace) >= 0) + // Could detect overlapping faults here .... if (faultsPrCellAcc->faultIdx(ff.m_nativeReservoirCellIndex, ff.m_nativeFace) + // >= 0) faultsPrCellAcc->setFaultIdx(ff.m_nativeReservoirCellIndex, ff.m_nativeFace, faultIdx); - faultsPrCellAcc->setFaultIdx(ff.m_oppositeReservoirCellIndex, cvf::StructGridInterface::oppositeFace(ff.m_nativeFace), faultIdx); - + faultsPrCellAcc->setFaultIdx( + ff.m_oppositeReservoirCellIndex, cvf::StructGridInterface::oppositeFace(ff.m_nativeFace), faultIdx); } } diff --git a/ApplicationCode/ReservoirDataModel/RigFault.h b/ApplicationCode/ReservoirDataModel/RigFault.h index dbb79ad832..06bb609c74 100644 --- a/ApplicationCode/ReservoirDataModel/RigFault.h +++ b/ApplicationCode/ReservoirDataModel/RigFault.h @@ -23,20 +23,19 @@ #include "cvfObject.h" #include "cvfVector3.h" #include "cvfBoundingBox.h" - -#include - -#include #include "cvfStructGrid.h" #include "cvfCellRange.h" -#include "cafFixedArray.h" + +#include + +#include +#include class RigMainGrid; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - class RigFaultsPrCellAccumulator : public cvf::Object { public: @@ -45,15 +44,18 @@ class RigFaultsPrCellAccumulator : public cvf::Object public: explicit RigFaultsPrCellAccumulator(size_t reservoirCellCount) { - const int initVals[6] = { NO_FAULT, NO_FAULT, NO_FAULT, NO_FAULT, NO_FAULT, NO_FAULT}; - caf::IntArray6 initVal; - initVal = initVals; - m_faultIdxForCellFace.resize(reservoirCellCount, initVal); + std::array initVals = { NO_FAULT, NO_FAULT, NO_FAULT, NO_FAULT, NO_FAULT, NO_FAULT}; + m_faultIdxForCellFace.resize(reservoirCellCount, initVals); } inline int faultIdx(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const { - return m_faultIdxForCellFace[reservoirCellIndex][face]; + // Ensure no crash after creating temporary LGRs + if (reservoirCellIndex < m_faultIdxForCellFace.size()) + { + return m_faultIdxForCellFace[reservoirCellIndex][face]; + } + return NO_FAULT; } inline void setFaultIdx(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face, int faultIdx) @@ -62,7 +64,7 @@ class RigFaultsPrCellAccumulator : public cvf::Object } private: - std::vector< caf::IntArray6 > m_faultIdxForCellFace; + std::vector> m_faultIdxForCellFace; }; @@ -70,7 +72,6 @@ class RigFaultsPrCellAccumulator : public cvf::Object //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - class RigFault : public cvf::Object { public: @@ -102,13 +103,13 @@ class RigFault : public cvf::Object std::vector& faultFaces(); const std::vector& faultFaces() const; - std::vector& connectionIndices() { return m_connectionIndices; } - const std::vector& connectionIndices() const { return m_connectionIndices; } + std::vector& connectionIndices(); + const std::vector& connectionIndices() const; private: QString m_name; - caf::FixedArray, 6> m_cellRangesForFaces; + std::array, 6> m_cellRangesForFaces; std::vector m_faultFaces; std::vector m_connectionIndices; diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResultFrames.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagResultFrames.h index 95cbec99bd..84d926c576 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagResultFrames.h +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResultFrames.h @@ -26,7 +26,7 @@ class RigFlowDiagResultFrames: public cvf::Object { public: explicit RigFlowDiagResultFrames(size_t frameCount); - virtual ~RigFlowDiagResultFrames(); + ~RigFlowDiagResultFrames() override; const std::vector& frameData(size_t frameIndex) const; diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h index 14f855dfdb..51e384b09f 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagResults.h @@ -54,7 +54,7 @@ class RigFlowDiagResults: public cvf::Object typedef caf::AppEnum CellFilterEnum; public: RigFlowDiagResults(RimFlowDiagSolution* flowSolution, size_t timeStepCount); - virtual ~RigFlowDiagResults(); + ~RigFlowDiagResults() override; const std::vector* resultValues(const RigFlowDiagResultAddress& resVarAddr, size_t timeStepIndex); size_t timeStepCount() { return m_timeStepCount; } diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp index daf17bec06..50d3d9bad8 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.cpp @@ -269,10 +269,10 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI QString gridFileName = m_eclipseCase->gridFileName(); if ( !RifEclipseOutputFileTools::findSiblingFilesWithSameBaseName(gridFileName, &m_filesWithSameBaseName) ) return result; - QString restartFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE); - if ( !restartFileName.isEmpty() ) + QString firstRestartFileName = RifEclipseOutputFileTools::firstFileNameOfType(m_filesWithSameBaseName, ECL_UNIFIED_RESTART_FILE); + if ( !firstRestartFileName.isEmpty() ) { - m_opmFlowDiagStaticData->m_unifiedRestartData.reset(new Opm::ECLRestartData(Opm::ECLRestartData(restartFileName.toStdString()))); + m_opmFlowDiagStaticData->m_unifiedRestartData.reset(new Opm::ECLRestartData(Opm::ECLRestartData(firstRestartFileName.toStdString()))); m_opmFlowDiagStaticData->m_hasUnifiedRestartFile = true; } else @@ -291,7 +291,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI restartFileNames.sort(); // To make sure they are sorted in increasing *.X000N order. Hack. Should probably be actual time stored on file. m_opmFlowDiagStaticData->m_hasUnifiedRestartFile = false; - for (auto restartFileName : restartFileNames) + for (const auto& restartFileName : restartFileNames) { m_opmFlowDiagStaticData->m_singleRestartDataTimeSteps.push_back(Opm::ECLRestartData(restartFileName.toStdString())); } @@ -480,7 +480,7 @@ RigFlowDiagTimeStepResult RigFlowDiagSolverInterface::calculate(size_t timeStepI } - #pragma omp critical + #pragma omp critical(critical_section_RigFlowDiagSolverInterface_calculate) { result.setInjProdWellPairFlux(uiInjectorTracerName, uiProducerTracerName, @@ -511,15 +511,16 @@ bool RigFlowDiagSolverInterface::ensureStaticDataObjectInstanceCreated() if (initFileName.empty()) return false; const RigEclipseCaseData* eclipseCaseData = m_eclipseCase->eclipseCaseData(); - - if (eclipseCaseData->hasFractureResults()) + if (eclipseCaseData) { - return false; - } + if (eclipseCaseData->hasFractureResults()) + { + return false; + } - RiaEclipseUnitTools::UnitSystem caseUnitSystem = eclipseCaseData ? eclipseCaseData->unitsType() : RiaEclipseUnitTools::UNITS_UNKNOWN; - - m_opmFlowDiagStaticData = new RigOpmFlowDiagStaticData(gridFileName.toStdString(), initFileName, caseUnitSystem); + RiaEclipseUnitTools::UnitSystem caseUnitSystem = eclipseCaseData->unitsType(); + m_opmFlowDiagStaticData = new RigOpmFlowDiagStaticData(gridFileName.toStdString(), initFileName, caseUnitSystem); + } } return m_opmFlowDiagStaticData.notNull() ? true : false; @@ -681,7 +682,6 @@ std::vector RigFlowDiagSolverInterface if (!useEps) { scaling.enable = static_cast(0); } - scaling.invalid = Opm::SatFunc::EPSEvalInterface::InvalidEndpointBehaviour::IgnorePoint; std::vector graphArr = m_opmFlowDiagStaticData->m_eclSaturationFunc->getSatFuncCurve(satFuncRequests, static_cast(activeCellIndex), scaling); for (size_t i = 0; i < graphArr.size(); i++) { diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h index 49f94be389..81b4a7ab3a 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagSolverInterface.h @@ -107,7 +107,7 @@ class RigFlowDiagSolverInterface : public cvf::Object public: explicit RigFlowDiagSolverInterface(RimEclipseResultCase * eclipseCase); - virtual ~RigFlowDiagSolverInterface(); + ~RigFlowDiagSolverInterface() override; RigFlowDiagTimeStepResult calculate(size_t timeStepIdx, RigFlowDiagResultAddress::PhaseSelection phaseSelection, diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.h index 14993cd7d5..9266f08ce3 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.h +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagStatCalc.h @@ -34,13 +34,13 @@ class RigFlowDiagStatCalc : public RigStatisticsCalculator public: RigFlowDiagStatCalc(RigFlowDiagResults* flowDiagResults, const RigFlowDiagResultAddress& resVarAddr); - virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); - virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); - virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount); - virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator); - virtual void uniqueValues(size_t timeStepIndex, std::set& values); - virtual size_t timeStepCount(); - virtual void mobileVolumeWeightedMean(size_t timeStepIndex, double& mean); + void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) override; + void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) override; + void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount) override; + void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator) override; + void uniqueValues(size_t timeStepIndex, std::set& values) override; + size_t timeStepCount() override; + void mobileVolumeWeightedMean(size_t timeStepIndex, double& mean) override; private: RigFlowDiagResults* m_resultsData; diff --git a/ApplicationCode/ReservoirDataModel/RigFlowDiagVisibleCellsStatCalc.h b/ApplicationCode/ReservoirDataModel/RigFlowDiagVisibleCellsStatCalc.h index 3c403c2cc1..c3dafa93d1 100644 --- a/ApplicationCode/ReservoirDataModel/RigFlowDiagVisibleCellsStatCalc.h +++ b/ApplicationCode/ReservoirDataModel/RigFlowDiagVisibleCellsStatCalc.h @@ -39,13 +39,13 @@ class RigFlowDiagVisibleCellsStatCalc : public RigStatisticsCalculator const RigFlowDiagResultAddress& resVarAddr, const cvf::UByteArray* cellVisibilities); - virtual void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max); - virtual void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg); - virtual void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount); - virtual void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator); - virtual void uniqueValues(size_t timeStepIndex, std::set& values); - virtual size_t timeStepCount(); - virtual void mobileVolumeWeightedMean(size_t timeStepIndex, double &result); + void minMaxCellScalarValues(size_t timeStepIndex, double& min, double& max) override; + void posNegClosestToZero(size_t timeStepIndex, double& pos, double& neg) override; + void valueSumAndSampleCount(size_t timeStepIndex, double& valueSum, size_t& sampleCount) override; + void addDataToHistogramCalculator(size_t timeStepIndex, RigHistogramCalculator& histogramCalculator) override; + void uniqueValues(size_t timeStepIndex, std::set& values) override; + size_t timeStepCount() override; + void mobileVolumeWeightedMean(size_t timeStepIndex, double &result) override; private: RigFlowDiagResults* m_resultsData; diff --git a/ApplicationCode/ReservoirDataModel/RigFormationNames.h b/ApplicationCode/ReservoirDataModel/RigFormationNames.h index a984421256..87a951df45 100644 --- a/ApplicationCode/ReservoirDataModel/RigFormationNames.h +++ b/ApplicationCode/ReservoirDataModel/RigFormationNames.h @@ -28,7 +28,7 @@ class RigFormationNames: public cvf::Object { public: RigFormationNames(); - ~RigFormationNames(); + ~RigFormationNames() override; int formationIndexFromKLayerIdx(size_t Kidx) { diff --git a/ApplicationCode/ReservoirDataModel/RigFractureCell.cpp b/ApplicationCode/ReservoirDataModel/RigFractureCell.cpp index 9da6e3faa5..4cdceabd6a 100644 --- a/ApplicationCode/ReservoirDataModel/RigFractureCell.cpp +++ b/ApplicationCode/ReservoirDataModel/RigFractureCell.cpp @@ -29,7 +29,7 @@ RigFractureCell::RigFractureCell(std::vector polygon, size_t i, size : m_polygon(polygon) , m_i(i) , m_j(j) - , m_concutivityValue(0.0) + , m_conductivityValue(0.0) { } @@ -44,9 +44,9 @@ const std::vector& RigFractureCell::getPolygon() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RigFractureCell::getConductivtyValue() const +double RigFractureCell::getConductivityValue() const { - return m_concutivityValue; + return m_conductivityValue; } //-------------------------------------------------------------------------------------------------- @@ -70,7 +70,7 @@ size_t RigFractureCell::getJ() const //-------------------------------------------------------------------------------------------------- bool RigFractureCell::hasNonZeroConductivity() const { - return m_concutivityValue > 1e-7; + return m_conductivityValue > 1e-7; } //-------------------------------------------------------------------------------------------------- @@ -78,7 +78,7 @@ bool RigFractureCell::hasNonZeroConductivity() const //-------------------------------------------------------------------------------------------------- void RigFractureCell::setConductivityValue(double cond) { - m_concutivityValue = cond; + m_conductivityValue = cond; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigFractureCell.h b/ApplicationCode/ReservoirDataModel/RigFractureCell.h index fc1a4d9907..4a42e26a65 100644 --- a/ApplicationCode/ReservoirDataModel/RigFractureCell.h +++ b/ApplicationCode/ReservoirDataModel/RigFractureCell.h @@ -34,7 +34,7 @@ class RigFractureCell RigFractureCell(std::vector polygon, size_t i, size_t j); const std::vector& getPolygon() const; - double getConductivtyValue() const; + double getConductivityValue() const; size_t getI() const; size_t getJ() const; @@ -46,7 +46,7 @@ class RigFractureCell private: std::vector m_polygon; - double m_concutivityValue; + double m_conductivityValue; size_t m_i; size_t m_j; }; diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechBoreHoleStressCalculator.cpp b/ApplicationCode/ReservoirDataModel/RigGeoMechBoreHoleStressCalculator.cpp new file mode 100644 index 0000000000..b2f142beac --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechBoreHoleStressCalculator.cpp @@ -0,0 +1,252 @@ +#include "RigGeoMechBoreHoleStressCalculator.h" + +//================================================================================================== +/// Internal root finding class to find a Well Pressure that gives: +/// a) a zero SigmaT for estimating the fracture gradient. +/// b) a solution to the Stassi-d'Alia failure criterion for estimating the shear failure gradient. +//================================================================================================== + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigGeoMechBoreHoleStressCalculator::RigGeoMechBoreHoleStressCalculator(const caf::Ten3d& tensor, + double porePressure, + double poissonRatio, + double uniaxialCompressiveStrength, + int nThetaSubSamples) + : m_tensor(tensor) + , m_porePressure(porePressure) + , m_poissonRatio(poissonRatio) + , m_uniaxialCompressiveStrength(uniaxialCompressiveStrength) + , m_nThetaSubSamples(nThetaSubSamples) +{ + calculateStressComponents(); +} + + +//-------------------------------------------------------------------------------------------------- +/// Simple bisection method for now +//-------------------------------------------------------------------------------------------------- +double RigGeoMechBoreHoleStressCalculator::solveFractureGradient(double* thetaOut) +{ + MemberFunc fn = &RigGeoMechBoreHoleStressCalculator::sigmaTMinOfMin; + return solveSecant(fn, thetaOut); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigGeoMechBoreHoleStressCalculator::solveStassiDalia(double* thetaOut) +{ + MemberFunc fn = &RigGeoMechBoreHoleStressCalculator::stassiDalia; + return solveSecant(fn, thetaOut); +} + +//-------------------------------------------------------------------------------------------------- +/// Bi-section root finding method: https://en.wikipedia.org/wiki/Bisection_method +/// Used as fall-back in case the secant method doesn't converge. +//-------------------------------------------------------------------------------------------------- +double RigGeoMechBoreHoleStressCalculator::solveBisection(double minPw, double maxPw, MemberFunc fn, double* thetaOut) +{ + const int N = 50; + const double epsilon = 1.0e-10; + + double theta = 0.0; + + std::pair largestNegativeValue(0.0, -std::numeric_limits::infinity()); + std::pair smallestPositiveValue (0.0, std::numeric_limits::infinity()); + + for (int i = 0; i <= N; ++i) + { + double pw = minPw + (maxPw - minPw) * i / static_cast(N); + double f_pw = (this->*fn)(pw, &theta); + if (f_pw >= 0.0 && f_pw < smallestPositiveValue.second) + { + smallestPositiveValue = std::make_pair(pw, f_pw); + } + if (f_pw < 0.0 && f_pw > largestNegativeValue.second) + { + largestNegativeValue = std::make_pair(pw, f_pw); + } + } + + // TODO: Provide a warning if there was no solution to the equation + if (largestNegativeValue.second == -std::numeric_limits::infinity()) + { + // No solution. Function is always positive. Pick smallest value. + return smallestPositiveValue.first; + } + if (smallestPositiveValue.second == std::numeric_limits::infinity()) + { + // No solution. Function is always negative. Pick largest value. + return largestNegativeValue.first; + } + minPw = largestNegativeValue.first; + double minPwFuncVal = largestNegativeValue.second; + maxPw = smallestPositiveValue.first; + double maxPwFuncVal = smallestPositiveValue.second; + + double range = std::abs(maxPw - minPw); + + int i = 0; + for (; i <= N && range > m_porePressure * epsilon; ++i) + { + double midPw = (minPw + maxPw) * 0.5; + double midPwFuncVal = (this->*fn)(midPw, &theta); + if (midPwFuncVal * minPwFuncVal < 0.0) + { + maxPw = midPw; + maxPwFuncVal = midPwFuncVal; + } + else + { + minPw = midPw; + minPwFuncVal = midPwFuncVal; + } + range = std::abs(maxPw - minPw); + } + CVF_ASSERT(i < N); // Otherwise it hasn't converged + + if (thetaOut) + { + *thetaOut = theta; + } + + // Return average of minPw and maxPw. + return 0.5 * (maxPw + minPw); +} + +//-------------------------------------------------------------------------------------------------- +/// Secant root finding method: https://en.wikipedia.org/wiki/Secant_method +/// Basically a Newton's method using finite differences for the derivative. +//-------------------------------------------------------------------------------------------------- +double RigGeoMechBoreHoleStressCalculator::solveSecant(MemberFunc fn, double* thetaOut) +{ + const double epsilon = 1.0e-10; + const int N = 50; + double theta = 0.0; + + double x_0 = 0.0; + double f_x0 = (this->*fn)(x_0, &theta); + double x_1 = m_porePressure; + double f_x1 = (this->*fn)(x_1, &theta); + double x = 0.0; + double f_x = 0.0; + int i = 0; + for (; i <= N && std::abs(f_x1 - f_x0) > epsilon; ++i) + { + x = x_1 - f_x1 * (x_1 - x_0) / (f_x1 - f_x0); + f_x = (this->*fn)(x, &theta); + if (std::abs(f_x) < epsilon * m_porePressure) break; + + // Update iteration variables + x_0 = x_1; + f_x0 = f_x1; + x_1 = x; + f_x1 = f_x; + } + + if (i == N || std::abs(f_x) > epsilon * m_porePressure) + { + // Fallback to bisection if secant doesn't converge or converged to a wrong solution. + return solveBisection(0.0, m_porePressure * 2.0, fn, thetaOut); + } + + if (thetaOut) + { + *thetaOut = theta; + } + return x; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigGeoMechBoreHoleStressCalculator::sigmaTMinOfMin(double wellPressure, double* thetaAtMin) const +{ + CVF_ASSERT(thetaAtMin); + double sigma_t_min_min = std::numeric_limits::max(); + for (const cvf::Vec4d& stressComponentsForAngle : m_stressComponents) + { + // Perform all these internal calculations in double to reduce significance errors + double sigma_theta = stressComponentsForAngle[1] - wellPressure; + const double& sigma_z = stressComponentsForAngle[2]; + double tauSqrx4 = std::pow(stressComponentsForAngle[3], 2) * 4.0; + double sigma_t_min = 0.5 * ((sigma_z + sigma_theta) - std::sqrt(std::pow(sigma_z - sigma_theta, 2) + tauSqrx4)) - m_porePressure; + if (sigma_t_min < sigma_t_min_min) + { + sigma_t_min_min = sigma_t_min; + *thetaAtMin = stressComponentsForAngle[0]; + } + } + return sigma_t_min_min; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigGeoMechBoreHoleStressCalculator::stassiDalia(double wellPressure, double* thetaAtMin) const +{ + CVF_ASSERT(thetaAtMin); + double minStassiDalia = std::numeric_limits::max(); + for (const cvf::Vec4d& stressComponentsForAngle : m_stressComponents) + { + double sigma_theta = stressComponentsForAngle[1] - wellPressure; + const double& sigma_z = stressComponentsForAngle[2]; + double tauSqrx4 = std::pow(stressComponentsForAngle[3], 2) * 4.0; + + double sigma_1 = wellPressure - m_porePressure; + double sigma_2 = 0.5 * ((sigma_z + sigma_theta) + std::sqrt(std::pow(sigma_z - sigma_theta, 2) + tauSqrx4)) - m_porePressure; + double sigma_3 = 0.5 * ((sigma_z + sigma_theta) - std::sqrt(std::pow(sigma_z - sigma_theta, 2) + tauSqrx4)) - m_porePressure; + + double stassiDalia = std::pow(sigma_1 - sigma_2, 2) + std::pow(sigma_2 - sigma_3, 2) + std::pow(sigma_1 - sigma_3, 2) + - 2 * m_uniaxialCompressiveStrength * (sigma_1 + sigma_2 + sigma_3); + + if (stassiDalia < minStassiDalia) + { + minStassiDalia = stassiDalia; + *thetaAtMin = stressComponentsForAngle[0]; + } + } + return minStassiDalia; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechBoreHoleStressCalculator::calculateStressComponents() +{ + m_stressComponents.reserve(m_nThetaSubSamples); + + for (int i = 0; i < m_nThetaSubSamples; ++i) + { + double theta = (i *cvf::PI_F) / (m_nThetaSubSamples - 1.0); + cvf::Vec4d stressComponentsForAngle = calculateStressComponentsForSegmentAngle(theta); + m_stressComponents.push_back(stressComponentsForAngle); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec4d RigGeoMechBoreHoleStressCalculator::calculateStressComponentsForSegmentAngle(double theta) const +{ + cvf::Vec4d stressComponents; + + const double& sx = m_tensor[caf::Ten3d::SXX]; + const double& sy = m_tensor[caf::Ten3d::SYY]; + const double& sz = m_tensor[caf::Ten3d::SZZ]; + const double& txy = m_tensor[caf::Ten3d::SXY]; + const double& txz = m_tensor[caf::Ten3d::SZX]; + const double& tyz = m_tensor[caf::Ten3d::SYZ]; + + stressComponents[0] = theta; + stressComponents[1] = sx + sy - 2 * (sx - sy) * cos(2 * theta) - 4 * txy * sin(2 * theta); + stressComponents[2] = sz - m_poissonRatio * (2 * (sx - sy) * cos(2 * theta) + 4 * txy * sin(2 * theta)); + stressComponents[3] = 2 * (tyz * cos(theta) - txz * sin(theta)); + + return stressComponents; +} + + + diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechBoreHoleStressCalculator.h b/ApplicationCode/ReservoirDataModel/RigGeoMechBoreHoleStressCalculator.h new file mode 100644 index 0000000000..27222d9993 --- /dev/null +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechBoreHoleStressCalculator.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafTensor3.h" +#include "cvfVector3.h" +#include "cvfVector4.h" + +#include + +class RigGeoMechBoreHoleStressCalculator +{ +public: + RigGeoMechBoreHoleStressCalculator(const caf::Ten3d& tensor, double porePressure, double poissonRatio, double uniaxialCompressiveStrength, int nThetaSubSamples); + double solveFractureGradient(double* thetaOut = nullptr); + double solveStassiDalia(double* thetaOut = nullptr); + +private: + typedef double (RigGeoMechBoreHoleStressCalculator::*MemberFunc)(double pw, double* thetaOut) const; + double solveBisection(double minPw, double maxPw, MemberFunc fn, double* thetaOut); + double solveSecant(MemberFunc fn, double* thetaOut); + double sigmaTMinOfMin(double wellPressure, double* thetaAtMin) const; + double stassiDalia(double wellPressure, double* thetaAtMin) const; + void calculateStressComponents(); + cvf::Vec4d calculateStressComponentsForSegmentAngle(double theta) const; + + caf::Ten3d m_tensor; + double m_porePressure; + double m_poissonRatio; + double m_uniaxialCompressiveStrength; + int m_nThetaSubSamples; + std::vector m_stressComponents; +}; + diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp index db430a0537..bf147f136b 100644 --- a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp @@ -21,6 +21,11 @@ /// //================================================================================================== #include "RigGeoMechWellLogExtractor.h" + +#include "RiaDefines.h" +#include "RiaWeightedMeanCalculator.h" +#include "RigFemTypes.h" +#include "RigGeoMechBoreHoleStressCalculator.h" #include "RigFemPart.h" #include "RigFemPartCollection.h" #include "RigGeoMechCaseData.h" @@ -28,9 +33,16 @@ #include "RigWellLogExtractionTools.h" #include "RigWellPath.h" -#include "cvfGeometryTools.h" #include "RigWellPathIntersectionTools.h" +#include "cafTensor3.h" +#include "cvfGeometryTools.h" +#include "cvfMath.h" + +#include + +const double RigGeoMechWellLogExtractor::UNIT_WEIGHT_OF_WATER = 9.81 * 1000.0; // N / m^3 + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -50,7 +62,27 @@ void RigGeoMechWellLogExtractor::curveData(const RigFemResultAddress& resAddr, i { CVF_TIGHT_ASSERT(values); - if (!resAddr.isValid()) return ; + if (resAddr.resultPosType == RIG_WELLPATH_DERIVED) + { + if (resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() || resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString()) + { + wellBoreWallCurveData(resAddr, frameIndex, values); + return; + } + else if (resAddr.fieldName == "PP" || resAddr.fieldName == "OBG" || resAddr.fieldName == "SH") + { + wellPathScaledCurveData(resAddr, frameIndex, values); + return; + } + else if (resAddr.fieldName == "Azimuth" || resAddr.fieldName == "Inclination") + { + wellPathAngles(resAddr, values); + return; + } + + } + + if (!resAddr.isValid()) return; RigFemResultAddress convResAddr = resAddr; @@ -59,69 +91,508 @@ void RigGeoMechWellLogExtractor::curveData(const RigFemResultAddress& resAddr, i if (convResAddr.fieldName == "POR-Bar") convResAddr.resultPosType = RIG_ELEMENT_NODAL; - const RigFemPart* femPart = m_caseData->femParts()->part(0); - const std::vector& nodeCoords = femPart->nodes().coordinates; + CVF_ASSERT(resAddr.resultPosType != RIG_WELLPATH_DERIVED); + const std::vector& resultValues = m_caseData->femPartResults()->resultValues(convResAddr, 0, frameIndex); if (!resultValues.size()) return; values->resize(m_intersections.size()); - for (size_t cpIdx = 0; cpIdx < m_intersections.size(); ++cpIdx) + for (size_t intersectionIdx = 0; intersectionIdx < m_intersections.size(); ++intersectionIdx) + { + (*values)[intersectionIdx] = static_cast(interpolateGridResultValue(convResAddr.resultPosType, resultValues, intersectionIdx, false)); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +float RigGeoMechWellLogExtractor::calculatePorePressureInSegment(int64_t intersectionIdx, float averageSegmentPorePressureBar, double hydroStaticPorePressureBar, double effectiveDepthMeters, const std::vector& poreElementPressuresPascal) const +{ + double porePressure = hydroStaticPorePressureBar; + + // 1: Try pore pressure from the grid + if (porePressure == hydroStaticPorePressureBar && averageSegmentPorePressureBar > 0.0) + { + porePressure = averageSegmentPorePressureBar; + } + + // 2: Try mud weight from LAS-file to generate pore pressure + if (porePressure == hydroStaticPorePressureBar && !m_wellLogMdAndMudWeightKgPerM3.empty()) + { + double lasMudWeightKgPerM3 = getWellLogSegmentValue(intersectionIdx, m_wellLogMdAndMudWeightKgPerM3); + if (lasMudWeightKgPerM3 != std::numeric_limits::infinity()) + { + double specificMudWeightNPerM3 = lasMudWeightKgPerM3 * 9.81; + double porePressurePascal = specificMudWeightNPerM3 * effectiveDepthMeters; + porePressure = pascalToBar(porePressurePascal); + } + } + size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx]; + // 3: Try pore pressure from element property tables + if (porePressure == hydroStaticPorePressureBar && elmIdx < poreElementPressuresPascal.size()) + { + // Pore pressure from element property tables are in pascal. + porePressure = pascalToBar(poreElementPressuresPascal[elmIdx]); + } + // 4: If no pore-pressure was found, the default value of hydrostatic pore pressure is used. + + CVF_ASSERT(porePressure >= 0.0); + return porePressure; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +float RigGeoMechWellLogExtractor::calculatePoissonRatio(int64_t intersectionIdx, const std::vector& poissonRatios) const +{ + const double defaultPoissonRatio = 0.25; + + double poissonRatio = defaultPoissonRatio; + + if (!m_wellLogMdAndPoissonRatios.empty()) + { + double lasPoissionRatio = getWellLogSegmentValue(intersectionIdx, m_wellLogMdAndPoissonRatios); + if (lasPoissionRatio != std::numeric_limits::infinity()) + { + poissonRatio = lasPoissionRatio; + } + } + + size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx]; + if (poissonRatio == defaultPoissonRatio && elmIdx < poissonRatios.size()) + { + poissonRatio = poissonRatios[elmIdx]; + } + return poissonRatio; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +float RigGeoMechWellLogExtractor::calculateUcs(int64_t intersectionIdx, const std::vector& ucsValuesPascal) const +{ + // Typical UCS: http://ceae.colorado.edu/~amadei/CVEN5768/PDF/NOTES8.pdf + // Typical UCS for Shale is 5 - 100 MPa -> 50 - 1000 bar. + const double defaultUniaxialStrengthInBar = 100.0; + + double uniaxialStrengthInBar = defaultUniaxialStrengthInBar; + if (!m_wellLogMdAndUcsBar.empty()) + { + double lasUniaxialStrengthInBar = getWellLogSegmentValue(intersectionIdx, m_wellLogMdAndUcsBar); + if (lasUniaxialStrengthInBar != std::numeric_limits::infinity()) + { + uniaxialStrengthInBar = lasUniaxialStrengthInBar; + } + } + + size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx]; + if (uniaxialStrengthInBar == defaultUniaxialStrengthInBar && elmIdx < ucsValuesPascal.size()) + { + // Read UCS from element table in Pascal + uniaxialStrengthInBar = pascalToBar(ucsValuesPascal[elmIdx]); + } + return uniaxialStrengthInBar; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::wellPathAngles(const RigFemResultAddress& resAddr, std::vector* values) +{ + CVF_ASSERT(values); + CVF_ASSERT(resAddr.fieldName == "Azimuth" || resAddr.fieldName == "Inclination"); + values->resize(m_intersections.size(), 0.0f); + const double epsilon = 1.0e-6 * 360; + const cvf::Vec3d trueNorth(0.0, 1.0, 0.0); + const cvf::Vec3d up(0.0, 0.0, 1.0); + for (int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx) { - size_t elmIdx = m_intersectedCellsGlobIdx[cpIdx]; + cvf::Vec3d wellPathTangent = calculateWellPathTangent(intersectionIdx, TangentFollowWellPathSegments); + + // Deviation from vertical. Since well path is tending downwards we compare with negative z. + double inclination = cvf::Math::toDegrees(std::acos(cvf::Vec3d(0.0, 0.0, -1.0) * wellPathTangent.getNormalized())); + + if (resAddr.fieldName == "Azimuth") + { + double azimuth = HUGE_VAL; + + // Azimuth is not defined when well path is vertical. We define it as infinite to avoid it showing up in the plot. + if (cvf::Math::valueInRange(inclination, epsilon, 180.0 - epsilon)) + { + cvf::Vec3d projectedTangentXY = wellPathTangent; + projectedTangentXY.z() = 0.0; + + // Do tangentXY to true north for clockwise angles. + double dotProduct = projectedTangentXY * trueNorth; + double crossProduct = (projectedTangentXY ^ trueNorth) * up; + // http://www.glossary.oilfield.slb.com/Terms/a/azimuth.aspx + azimuth = cvf::Math::toDegrees(std::atan2(crossProduct, dotProduct)); + if (azimuth < 0.0) + { + // Straight atan2 gives angle from -PI to PI yielding angles from -180 to 180 + // where the negative angles are counter clockwise. + // To get all positive clockwise angles, we add 360 degrees to negative angles. + azimuth = azimuth + 360.0; + } + } + + (*values)[intersectionIdx] = azimuth; + } + else + { + (*values)[intersectionIdx] = inclination; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::wellPathScaledCurveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector* values) +{ + CVF_ASSERT(values); + + const RigFemPart* femPart = m_caseData->femParts()->part(0); + RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults(); + + std::string nativeFieldName; + std::string nativeCompName; + if (resAddr.fieldName == "PP") + { + nativeFieldName = "POR-Bar"; // More likely to be in memory than POR + } + else if (resAddr.fieldName == "OBG") + { + nativeFieldName = "ST"; + nativeCompName = "S33"; + } + else if (resAddr.fieldName == "SH") + { + nativeFieldName = "ST"; + nativeCompName = "S3"; + } + + RigFemResultAddress nativeAddr(RIG_ELEMENT_NODAL, nativeFieldName, nativeCompName); + RigFemResultAddress porElementResAddr(RIG_ELEMENT, "POR", ""); + + std::vector unscaledResultValues = resultCollection->resultValues(nativeAddr, 0, frameIndex); + std::vector poreElementPressuresPascal = resultCollection->resultValues(porElementResAddr, 0, frameIndex); + + std::vector interpolatedInterfaceValues; + interpolatedInterfaceValues.resize(m_intersections.size(), std::numeric_limits::infinity()); + +#pragma omp parallel for + for (int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx) + { + size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx]; + RigElementType elmType = femPart->elementType(elmIdx); + if (!(elmType == HEX8 || elmType == HEX8P)) continue; + + interpolatedInterfaceValues[intersectionIdx] = interpolateGridResultValue(nativeAddr.resultPosType, unscaledResultValues, intersectionIdx, false); + } + + values->resize(m_intersections.size(), 0.0f); + +#pragma omp parallel for + for (int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx) + { + // Set the value to invalid by default + (*values)[intersectionIdx] = std::numeric_limits::infinity(); + + size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx]; RigElementType elmType = femPart->elementType(elmIdx); - if (!(elmType == HEX8 || elmType == HEX8P)) continue; + if (!(elmType == HEX8 || elmType == HEX8P)) continue; + + cvf::Vec3f centroid = cellCentroid(intersectionIdx); + + double trueVerticalDepth = -centroid.z(); + + double effectiveDepthMeters = trueVerticalDepth + m_rkbDiff; + double hydroStaticPorePressureBar = pascalToBar(effectiveDepthMeters * UNIT_WEIGHT_OF_WATER); + + float averageUnscaledValue = std::numeric_limits::infinity(); + bool validAverage = averageIntersectionValuesToSegmentValue(intersectionIdx, interpolatedInterfaceValues, std::numeric_limits::infinity(), &averageUnscaledValue); - if (convResAddr.resultPosType == RIG_ELEMENT) + if (resAddr.fieldName == "PP" && validAverage) { - (*values)[cpIdx] = resultValues[elmIdx]; - continue; + double segmentPorePressureFromGrid = averageUnscaledValue; + averageUnscaledValue = calculatePorePressureInSegment(intersectionIdx, segmentPorePressureFromGrid, hydroStaticPorePressureBar, effectiveDepthMeters, poreElementPressuresPascal); + } - cvf::StructGridInterface::FaceType cellFace = m_intersectedCellFaces[cpIdx]; + (*values)[intersectionIdx] = static_cast(averageUnscaledValue) / hydroStaticPorePressureBar; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::wellBoreWallCurveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector* values) +{ + CVF_ASSERT(values); + CVF_ASSERT(resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() || resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString()); + + // The result addresses needed + RigFemResultAddress stressResAddr(RIG_ELEMENT_NODAL, "ST", ""); + RigFemResultAddress porBarResAddr(RIG_ELEMENT_NODAL, "POR-Bar", ""); + // Allow POR as an element property value + RigFemResultAddress porElementResAddr(RIG_ELEMENT, "POR", ""); + RigFemResultAddress poissonResAddr(RIG_ELEMENT, "RATIO", ""); + RigFemResultAddress ucsResAddr(RIG_ELEMENT, "UCS", ""); + + const RigFemPart* femPart = m_caseData->femParts()->part(0); + RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults(); + + // Load results + std::vector vertexStressesFloat = resultCollection->tensors(stressResAddr, 0, frameIndex); + if (!vertexStressesFloat.size()) return; + + std::vector vertexStresses; vertexStresses.reserve(vertexStressesFloat.size()); + for (const caf::Ten3f& floatTensor : vertexStressesFloat) + { + vertexStresses.push_back(caf::Ten3d(floatTensor)); + } + std::vector porePressures = resultCollection->resultValues(porBarResAddr, 0, frameIndex); + std::vector poreElementPressuresPascal = resultCollection->resultValues(porElementResAddr, 0, frameIndex); + std::vector poissonRatios = resultCollection->resultValues(poissonResAddr, 0, frameIndex); + std::vector ucsValuesPascal = resultCollection->resultValues(ucsResAddr, 0, frameIndex); + + std::vector interpolatedInterfacePorePressureBar; + interpolatedInterfacePorePressureBar.resize(m_intersections.size(), std::numeric_limits::infinity()); + + std::vector interpolatedInterfaceStressBar; + interpolatedInterfaceStressBar.resize(m_intersections.size()); +#pragma omp parallel for + for (int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx) + { + size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx]; + RigElementType elmType = femPart->elementType(elmIdx); + if (!(elmType == HEX8 || elmType == HEX8P)) continue; + + interpolatedInterfacePorePressureBar[intersectionIdx] = interpolateGridResultValue(porBarResAddr.resultPosType, porePressures, intersectionIdx, false); + interpolatedInterfaceStressBar[intersectionIdx] = interpolateGridResultValue(stressResAddr.resultPosType, vertexStresses, intersectionIdx, false); + } + + values->resize(m_intersections.size(), 0.0f); + +#pragma omp parallel for + for (int64_t intersectionIdx = 0; intersectionIdx < (int64_t) m_intersections.size(); ++intersectionIdx) + { + size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx]; + RigElementType elmType = femPart->elementType(elmIdx); + + if (!(elmType == HEX8 || elmType == HEX8P)) continue; + + cvf::Vec3f centroid = cellCentroid(intersectionIdx); - int faceNodeCount = 0; - const int* faceLocalIndices = RigFemTypes::localElmNodeIndicesForFace(elmType, cellFace, &faceNodeCount); - const int* elmNodeIndices = femPart->connectivities(elmIdx); + double trueVerticalDepth = -centroid.z(); + double effectiveDepthMeters = trueVerticalDepth + m_rkbDiff; + double hydroStaticPorePressureBar = pascalToBar(effectiveDepthMeters * UNIT_WEIGHT_OF_WATER); - cvf::Vec3d v0(nodeCoords[elmNodeIndices[faceLocalIndices[0]]]); - cvf::Vec3d v1(nodeCoords[elmNodeIndices[faceLocalIndices[1]]]); - cvf::Vec3d v2(nodeCoords[elmNodeIndices[faceLocalIndices[2]]]); - cvf::Vec3d v3(nodeCoords[elmNodeIndices[faceLocalIndices[3]]]); + float averagePorePressureBar = std::numeric_limits::infinity(); + bool validGridPorePressure = averageIntersectionValuesToSegmentValue(intersectionIdx, interpolatedInterfacePorePressureBar, std::numeric_limits::infinity(), &averagePorePressureBar); + bool isFGregion = validGridPorePressure; // FG is for sands, SFG for shale. Sands has PP, shale does not. - size_t resIdx0 = cvf::UNDEFINED_SIZE_T; - size_t resIdx1 = cvf::UNDEFINED_SIZE_T; - size_t resIdx2 = cvf::UNDEFINED_SIZE_T; - size_t resIdx3 = cvf::UNDEFINED_SIZE_T; + double porePressureBar = calculatePorePressureInSegment(intersectionIdx, averagePorePressureBar, hydroStaticPorePressureBar, effectiveDepthMeters, poreElementPressuresPascal); + double poissonRatio = calculatePoissonRatio(intersectionIdx, poissonRatios); + double ucsBar = calculateUcs(intersectionIdx, ucsValuesPascal); - if (convResAddr.resultPosType == RIG_NODAL) + caf::Ten3d segmentStress; + bool validSegmentStress = averageIntersectionValuesToSegmentValue(intersectionIdx, interpolatedInterfaceStressBar, caf::Ten3d::invalid(), &segmentStress); + + cvf::Vec3d wellPathTangent = calculateWellPathTangent(intersectionIdx, TangentConstantWithinCell); + caf::Ten3d wellPathStressFloat = transformTensorToWellPathOrientation(wellPathTangent, segmentStress); + caf::Ten3d wellPathStressDouble(wellPathStressFloat); + + RigGeoMechBoreHoleStressCalculator sigmaCalculator(wellPathStressDouble, porePressureBar, poissonRatio, ucsBar, 32); + double resultValue = std::numeric_limits::infinity(); + if (resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString()) { - resIdx0 = elmNodeIndices[faceLocalIndices[0]]; - resIdx1 = elmNodeIndices[faceLocalIndices[1]]; - resIdx2 = elmNodeIndices[faceLocalIndices[2]]; - resIdx3 = elmNodeIndices[faceLocalIndices[3]]; + if (isFGregion && validSegmentStress) + { + resultValue = sigmaCalculator.solveFractureGradient(); + } } else { - resIdx0 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[0]); - resIdx1 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[1]); - resIdx2 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[2]); - resIdx3 = (size_t)femPart->elementNodeResultIdx((int)elmIdx, faceLocalIndices[3]); + CVF_ASSERT(resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString()); + if (!isFGregion && validSegmentStress) + { + resultValue = sigmaCalculator.solveStassiDalia(); + } + } + if (resultValue != std::numeric_limits::infinity()) + { + if (hydroStaticPorePressureBar > 1.0e-8) + { + resultValue /= hydroStaticPorePressureBar; + } } + (*values)[intersectionIdx] = resultValue; + } +} - double interpolatedValue = cvf::GeometryTools::interpolateQuad( - v0, resultValues[resIdx0], - v1, resultValues[resIdx1], - v2, resultValues[resIdx2], - v3, resultValues[resIdx3], - m_intersections[cpIdx] - ); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigGeoMechCaseData* RigGeoMechWellLogExtractor::caseData() +{ + return m_caseData.p(); +} - (*values)[cpIdx] = interpolatedValue; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::setRkbDiff(double rkbDiff) +{ + m_rkbDiff = rkbDiff; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::setWellLogMdAndMudWeightKgPerM3(const std::vector>& porePressures) +{ + m_wellLogMdAndMudWeightKgPerM3 = porePressures; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::setWellLogMdAndUcsBar(const std::vector>& ucsValues) +{ + m_wellLogMdAndUcsBar = ucsValues; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::setWellLogMdAndPoissonRatio(const std::vector>& poissonRatios) +{ + m_wellLogMdAndPoissonRatios = poissonRatios; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +T RigGeoMechWellLogExtractor::interpolateGridResultValue(RigFemResultPosEnum resultPosType, + const std::vector& gridResultValues, + int64_t intersectionIdx, + bool averageNodeElementResults) const +{ + const RigFemPart* femPart = m_caseData->femParts()->part(0); + const std::vector& nodeCoords = femPart->nodes().coordinates; + + size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx]; + RigElementType elmType = femPart->elementType(elmIdx); + + if (!(elmType == HEX8 || elmType == HEX8P)) return T(); + + if (resultPosType == RIG_FORMATION_NAMES) + { + resultPosType = RIG_ELEMENT_NODAL; // formation indices are stored per element node result. } - + + if (resultPosType == RIG_ELEMENT) + { + return gridResultValues[elmIdx]; + } + + cvf::StructGridInterface::FaceType cellFace = m_intersectedCellFaces[intersectionIdx]; + + if (cellFace == cvf::StructGridInterface::NO_FACE) + { + if (resultPosType == RIG_ELEMENT_NODAL_FACE) + { + return std::numeric_limits::infinity(); // undefined value. ELEMENT_NODAL_FACE values are only defined on a face. + } + // TODO: Should interpolate within the whole hexahedron. This requires converting to locals coordinates. + // For now just pick the average value for the cell. + size_t gridResultValueIdx = femPart->resultValueIdxFromResultPosType(resultPosType, static_cast(elmIdx), 0); + T sumOfVertexValues = gridResultValues[gridResultValueIdx]; + for (int i = 1; i < 8; ++i) + { + gridResultValueIdx = femPart->resultValueIdxFromResultPosType(resultPosType, static_cast(elmIdx), i); + sumOfVertexValues = sumOfVertexValues + gridResultValues[gridResultValueIdx]; + } + return sumOfVertexValues * (1.0 / 8.0); + } + + int faceNodeCount = 0; + const int* elementLocalIndicesForFace = RigFemTypes::localElmNodeIndicesForFace(elmType, cellFace, &faceNodeCount); + const int* elmNodeIndices = femPart->connectivities(elmIdx); + + cvf::Vec3d v0(nodeCoords[elmNodeIndices[elementLocalIndicesForFace[0]]]); + cvf::Vec3d v1(nodeCoords[elmNodeIndices[elementLocalIndicesForFace[1]]]); + cvf::Vec3d v2(nodeCoords[elmNodeIndices[elementLocalIndicesForFace[2]]]); + cvf::Vec3d v3(nodeCoords[elmNodeIndices[elementLocalIndicesForFace[3]]]); + + std::vector nodeResIdx(4, cvf::UNDEFINED_SIZE_T); + + for (size_t i = 0; i < nodeResIdx.size(); ++i) + { + if (resultPosType == RIG_ELEMENT_NODAL_FACE) + { + nodeResIdx[i] = gridResultIndexFace(elmIdx, cellFace, static_cast(i)); + } + else + { + nodeResIdx[i] = femPart->resultValueIdxFromResultPosType(resultPosType, static_cast(elmIdx), elementLocalIndicesForFace[i]); + } + } + + std::vector nodeResultValues; + nodeResultValues.reserve(4); + if (resultPosType == RIG_ELEMENT_NODAL && averageNodeElementResults) + { + // Estimate nodal values as the average of the node values from each connected element. + for (size_t i = 0; i < nodeResIdx.size(); ++i) + { + int nodeIndex = femPart->nodeIdxFromElementNodeResultIdx(nodeResIdx[i]); + const std::vector& elements = femPart->elementsUsingNode(nodeIndex); + const std::vector& localIndices = femPart->elementLocalIndicesForNode(nodeIndex); + size_t otherGridResultValueIdx = femPart->resultValueIdxFromResultPosType(resultPosType, elements[0], static_cast(localIndices[0])); + T nodeResultValue = gridResultValues[otherGridResultValueIdx]; + for (size_t j = 1; j < elements.size(); ++j) + { + otherGridResultValueIdx = femPart->resultValueIdxFromResultPosType(resultPosType, elements[j], static_cast(localIndices[j])); + nodeResultValue = nodeResultValue + gridResultValues[otherGridResultValueIdx]; + } + nodeResultValue = nodeResultValue * (1.0 / elements.size()); + nodeResultValues.push_back(nodeResultValue); + } + } + else { + for (size_t i = 0; i < nodeResIdx.size(); ++i) + { + nodeResultValues.push_back(gridResultValues[nodeResIdx[i]]); + } + } + + T interpolatedValue = cvf::GeometryTools::interpolateQuad( + v0, nodeResultValues[0], + v1, nodeResultValues[1], + v2, nodeResultValues[2], + v3, nodeResultValues[3], + m_intersections[intersectionIdx] + ); + + return interpolatedValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigGeoMechWellLogExtractor::gridResultIndexFace(size_t elementIdx, cvf::StructGridInterface::FaceType cellFace, int faceLocalNodeIdx) const +{ + CVF_ASSERT(cellFace != cvf::StructGridInterface::NO_FACE && faceLocalNodeIdx < 4); + return elementIdx * 24 + static_cast(cellFace) * 4 + faceLocalNodeIdx; } //-------------------------------------------------------------------------------------------------- @@ -224,3 +695,161 @@ cvf::Vec3d RigGeoMechWellLogExtractor::calculateLengthInCell(size_t cellIndex, c return RigWellPathIntersectionTools::calculateLengthInCell(hexCorners, startPoint, endPoint); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec3d RigGeoMechWellLogExtractor::calculateWellPathTangent(int64_t intersectionIdx, + WellPathTangentCalculation calculationType) const +{ + if (calculationType == TangentFollowWellPathSegments) + { + cvf::Vec3d segmentStart, segmentEnd; + m_wellPath->twoClosestPoints(m_intersections[intersectionIdx], &segmentStart, &segmentEnd); + return (segmentEnd - segmentStart).getNormalized(); + } + else + { + cvf::Vec3d wellPathTangent; + if (intersectionIdx % 2 == 0) + { + wellPathTangent = m_intersections[intersectionIdx + 1] - m_intersections[intersectionIdx]; + } + else + { + wellPathTangent = m_intersections[intersectionIdx] - m_intersections[intersectionIdx - 1]; + } + CVF_ASSERT(wellPathTangent.length() > 1.0e-7); + return wellPathTangent.getNormalized(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::Ten3d RigGeoMechWellLogExtractor::transformTensorToWellPathOrientation(const cvf::Vec3d& wellPathTangent, + const caf::Ten3d& tensor) +{ + // Create local coordinate system for well path segment + cvf::Vec3d local_z = wellPathTangent; + cvf::Vec3d local_x = local_z.perpendicularVector().getNormalized(); + cvf::Vec3d local_y = (local_z ^ local_x).getNormalized(); + // Calculate the rotation matrix from global i, j, k to local x, y, z. + cvf::Mat4d rotationMatrix = cvf::Mat4d::fromCoordSystemAxes(&local_x, &local_y, &local_z); + + return tensor.rotated(rotationMatrix.toMatrix3()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Vec3f RigGeoMechWellLogExtractor::cellCentroid(size_t intersectionIdx) const +{ + const RigFemPart* femPart = m_caseData->femParts()->part(0); + const std::vector& nodeCoords = femPart->nodes().coordinates; + + size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx]; + RigElementType elmType = femPart->elementType(elmIdx); + int elementNodeCount = RigFemTypes::elmentNodeCount(elmType); + + const int* elmNodeIndices = femPart->connectivities(elmIdx); + + cvf::Vec3f centroid(0.0, 0.0, 0.0); + for (int i = 0; i < elementNodeCount; ++i) + { + centroid += nodeCoords[elmNodeIndices[i]]; + } + return centroid / elementNodeCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigGeoMechWellLogExtractor::getWellLogSegmentValue(size_t intersectionIdx, const std::vector>& wellLogValues) const +{ + double startMD, endMD; + if (intersectionIdx % 2 == 0) + { + startMD = m_intersectionMeasuredDepths[intersectionIdx]; + endMD = m_intersectionMeasuredDepths[intersectionIdx + 1]; + } + else + { + startMD = m_intersectionMeasuredDepths [intersectionIdx - 1]; + endMD = m_intersectionMeasuredDepths[intersectionIdx]; + } + + RiaWeightedMeanCalculator averageCalc; + for (auto& depthAndValue : wellLogValues) + { + if (cvf::Math::valueInRange(depthAndValue.first, startMD, endMD)) + { + cvf::Vec3d position = m_wellPath->interpolatedPointAlongWellPath(depthAndValue.first); + cvf::Vec3d centroid(cellCentroid(intersectionIdx)); + double weight = 1.0; + double dist = (position - centroid).length(); + if (dist > 1.0) + { + weight = 1.0 / dist; + } + averageCalc.addValueAndWeight(depthAndValue.second, weight); + } + } + if (averageCalc.validAggregatedWeight()) + { + return averageCalc.weightedMean(); + } + + return std::numeric_limits::infinity(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigGeoMechWellLogExtractor::pascalToBar(double pascalValue) +{ + return pascalValue * 1.0e-5; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +bool RigGeoMechWellLogExtractor::averageIntersectionValuesToSegmentValue(size_t intersectionIdx, const std::vector& values, const T& invalidValue, T* averagedCellValue) const +{ + CVF_ASSERT(values.size() >= 2); + + *averagedCellValue = invalidValue; + + T value1, value2; + cvf::Vec3d centroid(cellCentroid(intersectionIdx)); + double dist1 = 0.0, dist2 = 0.0; + if (intersectionIdx % 2 == 0) + { + value1 = values[intersectionIdx]; + value2 = values[intersectionIdx + 1]; + + dist1 = (centroid - m_intersections[intersectionIdx]).length(); + dist2 = (centroid - m_intersections[intersectionIdx + 1]).length(); + } + else { + value1 = values[intersectionIdx - 1]; + value2 = values[intersectionIdx]; + + dist1 = (centroid - m_intersections[intersectionIdx - 1]).length(); + dist2 = (centroid - m_intersections[intersectionIdx]).length(); + } + + if (invalidValue == value1 || invalidValue == value2) + { + return false; + } + + RiaWeightedMeanCalculator averageCalc; + averageCalc.addValueAndWeight(value1, dist2); + averageCalc.addValueAndWeight(value2, dist1); + if (averageCalc.validAggregatedWeight()) + { + *averagedCellValue = averageCalc.weightedMean(); + } + return true; +} diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h index e93db4dcfa..83af692aa8 100644 --- a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h @@ -21,17 +21,22 @@ #include "RigWellLogExtractor.h" +#include "RigFemResultPosEnum.h" + +#include "cafTensor3.h" + #include "cvfBase.h" #include "cvfObject.h" #include "cvfMath.h" +#include "cvfStructGrid.h" #include "cvfVector3.h" #include -#include "cvfStructGrid.h" -class RigWellPath; -class RigGeoMechCaseData; +class RigFemPart; class RigFemResultAddress; +class RigGeoMechCaseData; +class RigWellPath; namespace cvf { class BoundingBox; @@ -46,16 +51,56 @@ class RigGeoMechWellLogExtractor : public RigWellLogExtractor RigGeoMechWellLogExtractor(RigGeoMechCaseData* aCase, const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName); void curveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector* values ); - const RigGeoMechCaseData* caseData() { return m_caseData.p();} + const RigGeoMechCaseData* caseData(); + void setRkbDiff(double rkbDiff); + + void setWellLogMdAndMudWeightKgPerM3(const std::vector>& mudWeightKgPerM3); + void setWellLogMdAndUcsBar(const std::vector>& ucsValues); + void setWellLogMdAndPoissonRatio(const std::vector>& poissonRatio); + private: + enum WellPathTangentCalculation + { + TangentFollowWellPathSegments, + TangentConstantWithinCell + }; + + float calculatePorePressureInSegment(int64_t intersectionIdx, float averageSegmentPorePressureBar, double hydroStaticPorePressureBar, double effectiveDepthMeters, const std::vector& poreElementPressuresPascal) const; + float calculatePoissonRatio(int64_t intersectionIdx, const std::vector& poissonRatios) const; + float calculateUcs(int64_t intersectionIdx, const std::vector& ucsValuesPascal) const; + + void wellPathAngles(const RigFemResultAddress& resAddr, std::vector* values); + void wellPathScaledCurveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector* values); + + + void wellBoreWallCurveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector* values); + + template + T interpolateGridResultValue(RigFemResultPosEnum resultPosType, const std::vector& gridResultValues, int64_t intersectionIdx, bool averageNodeElementResults) const; + size_t gridResultIndexFace(size_t elementIdx, cvf::StructGridInterface::FaceType cellFace, int faceLocalNodeIdx) const; void calculateIntersection(); std::vector findCloseCells(const cvf::BoundingBox& bb); - virtual cvf::Vec3d calculateLengthInCell(size_t cellIndex, + cvf::Vec3d calculateLengthInCell(size_t cellIndex, const cvf::Vec3d& startPoint, const cvf::Vec3d& endPoint) const override; + cvf::Vec3d calculateWellPathTangent(int64_t intersectionIdx, WellPathTangentCalculation calculationType) const; + static caf::Ten3d transformTensorToWellPathOrientation(const cvf::Vec3d& wellPathTangent, + const caf::Ten3d& wellPathTensor); + cvf::Vec3f cellCentroid(size_t intersectionIdx) const; + double getWellLogSegmentValue(size_t intersectionIdx, const std::vector>& wellLogValues) const; + + template + bool averageIntersectionValuesToSegmentValue(size_t intersectionIdx, const std::vector& intersectionValues, const T& invalidValue, T* averagedSegmentValue) const; + static double pascalToBar(double pascalValue); +private: cvf::ref m_caseData; -}; + double m_rkbDiff; + std::vector> m_wellLogMdAndMudWeightKgPerM3; + std::vector> m_wellLogMdAndUcsBar; + std::vector> m_wellLogMdAndPoissonRatios; + static const double UNIT_WEIGHT_OF_WATER; +}; diff --git a/ApplicationCode/ReservoirDataModel/RigGridBase.cpp b/ApplicationCode/ReservoirDataModel/RigGridBase.cpp index 6e42c71bfd..22e8d369fb 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridBase.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGridBase.cpp @@ -154,7 +154,7 @@ void RigGridBase::initSubCellsMainGridCellIndex() //-------------------------------------------------------------------------------------------------- void RigGridBase::cellCornerVertices(size_t cellIndex, cvf::Vec3d vertices[8]) const { - const caf::SizeTArray8& indices = cell(cellIndex).cornerIndices(); + const std::array& indices = cell(cellIndex).cornerIndices(); vertices[0].set(m_mainGrid->nodes()[indices[0]]); vertices[1].set(m_mainGrid->nodes()[indices[1]]); @@ -379,7 +379,7 @@ size_t RigGridBase::reservoirCellIndex(size_t gridLocalCellIndex) const //-------------------------------------------------------------------------------------------------- size_t RigGridBase::addCoarseningBox(size_t i1, size_t i2, size_t j1, size_t j2, size_t k1, size_t k2) { - caf::SizeTArray6 box; + std::array box; box[0] = i1; box[1] = i2; box[2] = j1; @@ -419,7 +419,7 @@ void RigGridBase::coarseningBox(size_t coarseningBoxIndex, size_t* i1, size_t* i CVF_ASSERT(i1 && i2 && j1 && j2 && k1 && k2); - caf::SizeTArray6 box = m_coarseningBoxInfo[coarseningBoxIndex]; + const std::array& box = m_coarseningBoxInfo[coarseningBoxIndex]; *i1 = box[0]; *i2 = box[1]; *j1 = box[2]; diff --git a/ApplicationCode/ReservoirDataModel/RigGridBase.h b/ApplicationCode/ReservoirDataModel/RigGridBase.h index b36dc4c284..9600f322e8 100644 --- a/ApplicationCode/ReservoirDataModel/RigGridBase.h +++ b/ApplicationCode/ReservoirDataModel/RigGridBase.h @@ -20,6 +20,9 @@ #pragma once +#include "RifReaderInterface.h" +#include "RigFault.h" + #include "cvfBase.h" #include "cvfVector3.h" @@ -27,14 +30,9 @@ #include "cvfStructGrid.h" #include "cvfStructGridGeometryGenerator.h" -#include "cafFixedArray.h" - #include #include -#include "RifReaderInterface.h" -#include "RigFault.h" - class RigMainGrid; class RigCell; @@ -44,7 +42,7 @@ class RigGridBase : public cvf::StructGridInterface { public: explicit RigGridBase(RigMainGrid* mainGrid); - virtual ~RigGridBase(void); + ~RigGridBase() override; void setGridPointDimensions(const cvf::Vec3st& gridDimensions) { m_gridPointDimensions = gridDimensions;} cvf::Vec3st gridPointDimensions() { return m_gridPointDimensions; } @@ -77,7 +75,9 @@ class RigGridBase : public cvf::StructGridInterface cvf::BoundingBox boundingBox(); - + virtual bool isTempGrid() const = 0; + virtual const std::string& associatedWellPathName() const = 0; + protected: friend class RigMainGrid;//::initAllSubGridsParentGridPointer(); void initSubGridParentPointer(); @@ -85,28 +85,28 @@ class RigGridBase : public cvf::StructGridInterface // Interface implementation public: - virtual size_t gridPointCountI() const; - virtual size_t gridPointCountJ() const; - virtual size_t gridPointCountK() const; + size_t gridPointCountI() const override; + size_t gridPointCountJ() const override; + size_t gridPointCountK() const override; - virtual cvf::Vec3d minCoordinate() const; - virtual cvf::Vec3d maxCoordinate() const; - virtual cvf::Vec3d displayModelOffset() const; + cvf::Vec3d minCoordinate() const override; + cvf::Vec3d maxCoordinate() const override; + cvf::Vec3d displayModelOffset() const override; - virtual size_t cellIndexFromIJK( size_t i, size_t j, size_t k ) const; - virtual bool ijkFromCellIndex( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const; + size_t cellIndexFromIJK( size_t i, size_t j, size_t k ) const override; + bool ijkFromCellIndex( size_t cellIndex, size_t* i, size_t* j, size_t* k ) const override; - virtual bool cellIJKFromCoordinate( const cvf::Vec3d& coord, size_t* i, size_t* j, size_t* k ) const; - virtual void cellCornerVertices( size_t cellIndex, cvf::Vec3d vertices[8] ) const; - virtual cvf::Vec3d cellCentroid( size_t cellIndex ) const; + bool cellIJKFromCoordinate( const cvf::Vec3d& coord, size_t* i, size_t* j, size_t* k ) const override; + void cellCornerVertices( size_t cellIndex, cvf::Vec3d vertices[8] ) const override; + cvf::Vec3d cellCentroid( size_t cellIndex ) const override; - virtual void cellMinMaxCordinates( size_t cellIndex, cvf::Vec3d* minCoordinate, cvf::Vec3d* maxCoordinate ) const; + void cellMinMaxCordinates( size_t cellIndex, cvf::Vec3d* minCoordinate, cvf::Vec3d* maxCoordinate ) const override; - virtual size_t gridPointIndexFromIJK( size_t i, size_t j, size_t k ) const; - virtual cvf::Vec3d gridPointCoordinate( size_t i, size_t j, size_t k ) const; + size_t gridPointIndexFromIJK( size_t i, size_t j, size_t k ) const override; + cvf::Vec3d gridPointCoordinate( size_t i, size_t j, size_t k ) const override; - virtual bool isCellValid( size_t i, size_t j, size_t k ) const; - virtual bool cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex ) const; + bool isCellValid( size_t i, size_t j, size_t k ) const override; + bool cellIJKNeighbor(size_t i, size_t j, size_t k, FaceType face, size_t* neighborCellIndex ) const override; private: std::string m_gridName; @@ -117,8 +117,7 @@ class RigGridBase : public cvf::StructGridInterface RigMainGrid* m_mainGrid; cvf::BoundingBox m_boundingBox; - std::vector m_coarseningBoxInfo; - + std::vector> m_coarseningBoxInfo; }; @@ -130,7 +129,7 @@ class RigGridCellFaceVisibilityFilter : public cvf::CellFaceVisibilityFilter { } - virtual bool isFaceVisible( size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility ) const; + bool isFaceVisible( size_t i, size_t j, size_t k, cvf::StructGridInterface::FaceType face, const cvf::UByteArray* cellVisibility ) const override; private: const RigGridBase* m_grid; diff --git a/ApplicationCode/ReservoirDataModel/RigHexIntersectionTools.cpp b/ApplicationCode/ReservoirDataModel/RigHexIntersectionTools.cpp index 3d51738c39..0be8cee130 100644 --- a/ApplicationCode/ReservoirDataModel/RigHexIntersectionTools.cpp +++ b/ApplicationCode/ReservoirDataModel/RigHexIntersectionTools.cpp @@ -80,6 +80,42 @@ int RigHexIntersectionTools::lineHexCellIntersection(const cvf::Vec3d p1, return intersectionCount; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigHexIntersectionTools::lineIntersectsHexCell(const cvf::Vec3d p1, const cvf::Vec3d p2, const cvf::Vec3d hexCorners[8]) +{ + for (int face = 0; face < 6; ++face) + { + cvf::ubyte faceVertexIndices[4]; + cvf::StructGridInterface::cellFaceVertexIndices(static_cast(face), faceVertexIndices); + + cvf::Vec3d intersection; + bool isEntering = false; + cvf::Vec3d faceCenter = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]], + hexCorners[faceVertexIndices[1]], + hexCorners[faceVertexIndices[2]], + hexCorners[faceVertexIndices[3]]); + + for (int i = 0; i < 4; ++i) + { + int next = i < 3 ? i + 1 : 0; + + int intsStatus = cvf::GeometryTools::intersectLineSegmentTriangle(p1, p2, + hexCorners[faceVertexIndices[i]], + hexCorners[faceVertexIndices[next]], + faceCenter, + &intersection, + &isEntering); + if (intsStatus == 1) + { + return true; + } + } + } + return false; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -114,12 +150,16 @@ bool RigHexIntersectionTools::isPointInCell(const cvf::Vec3d point, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigHexIntersectionTools::planeHexCellIntersection(cvf::Vec3d* hexCorners, cvf::Plane fracturePlane, std::list >& intersectionLineSegments) +bool RigHexIntersectionTools::planeHexCellIntersection(cvf::Vec3d* hexCorners, const cvf::Plane& fracturePlane, std::list >& intersectionLineSegments) { - bool isCellIntersected = false; + bool isCellIntersected = false; + cvf::ubyte faceVertexIndices[4]; + caf::HexGridIntersectionTools::ClipVx triangleIntersectionPoint1; + caf::HexGridIntersectionTools::ClipVx triangleIntersectionPoint2; + bool isMostVxesOnPositiveSideOfP1 = false; + for (int face = 0; face < 6; ++face) { - cvf::ubyte faceVertexIndices[4]; cvf::StructGridInterface::cellFaceVertexIndices(static_cast(face), faceVertexIndices); cvf::Vec3d faceCenter = cvf::GeometryTools::computeFaceCenter(hexCorners[faceVertexIndices[0]], hexCorners[faceVertexIndices[1]], hexCorners[faceVertexIndices[2]], hexCorners[faceVertexIndices[3]]); @@ -127,10 +167,6 @@ bool RigHexIntersectionTools::planeHexCellIntersection(cvf::Vec3d* hexCorners, c for (int i = 0; i < 4; i++) { int next = i < 3 ? i + 1 : 0; - caf::HexGridIntersectionTools::ClipVx triangleIntersectionPoint1; - caf::HexGridIntersectionTools::ClipVx triangleIntersectionPoint2; - - bool isMostVxesOnPositiveSideOfP1 = false; bool isIntersectingPlane = caf::HexGridIntersectionTools::planeTriangleIntersection(fracturePlane, hexCorners[faceVertexIndices[i]], 0, @@ -141,7 +177,7 @@ bool RigHexIntersectionTools::planeHexCellIntersection(cvf::Vec3d* hexCorners, c if (isIntersectingPlane) { isCellIntersected = true; - intersectionLineSegments.push_back({ triangleIntersectionPoint1.vx, triangleIntersectionPoint2.vx }); + intersectionLineSegments.emplace_back( triangleIntersectionPoint1.vx, triangleIntersectionPoint2.vx ); } } } return isCellIntersected; diff --git a/ApplicationCode/ReservoirDataModel/RigHexIntersectionTools.h b/ApplicationCode/ReservoirDataModel/RigHexIntersectionTools.h index e40bd6507c..afb9a789c5 100644 --- a/ApplicationCode/ReservoirDataModel/RigHexIntersectionTools.h +++ b/ApplicationCode/ReservoirDataModel/RigHexIntersectionTools.h @@ -61,10 +61,14 @@ struct RigHexIntersectionTools const size_t hexIndex, std::vector* intersections); + static bool lineIntersectsHexCell(const cvf::Vec3d p1, + const cvf::Vec3d p2, + const cvf::Vec3d hexCorners[8]); + static bool isPointInCell(const cvf::Vec3d point, const cvf::Vec3d hexCorners[8]); static bool planeHexCellIntersection(cvf::Vec3d* hexCorners, - cvf::Plane fracturePlane, + const cvf::Plane& fracturePlane, std::list >& intersectionLineSegments); static bool planeHexIntersectionPolygons(std::array hexCorners, diff --git a/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp b/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp index 652574913d..0a597ec0f2 100644 --- a/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp +++ b/ApplicationCode/ReservoirDataModel/RigLocalGrid.cpp @@ -23,7 +23,9 @@ RigLocalGrid::RigLocalGrid(RigMainGrid* mainGrid): RigGridBase(mainGrid), m_parentGrid(nullptr), - m_positionInParentGrid(cvf::UNDEFINED_SIZE_T) + m_positionInParentGrid(cvf::UNDEFINED_SIZE_T), + m_isTempGrid(false), + m_associatedWellPathName("") { } @@ -32,3 +34,67 @@ RigLocalGrid::RigLocalGrid(RigMainGrid* mainGrid): RigLocalGrid::~RigLocalGrid() { } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RigGridBase * RigLocalGrid::parentGrid() const +{ + return m_parentGrid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigLocalGrid::setParentGrid(RigGridBase * parentGrid) +{ + m_parentGrid = parentGrid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigLocalGrid::positionInParentGrid() const +{ + return m_positionInParentGrid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigLocalGrid::setPositionInParentGrid(size_t positionInParentGrid) +{ + m_positionInParentGrid = positionInParentGrid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigLocalGrid::setAsTempGrid(bool isTemp) +{ + m_isTempGrid = isTemp; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigLocalGrid::isTempGrid() const +{ + return m_isTempGrid; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigLocalGrid::setAssociatedWellPathName(const std::string& wellPathName) +{ + m_associatedWellPathName = wellPathName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::string& RigLocalGrid::associatedWellPathName() const +{ + return m_associatedWellPathName; +} diff --git a/ApplicationCode/ReservoirDataModel/RigLocalGrid.h b/ApplicationCode/ReservoirDataModel/RigLocalGrid.h index 7371afe7ee..2ce563522b 100644 --- a/ApplicationCode/ReservoirDataModel/RigLocalGrid.h +++ b/ApplicationCode/ReservoirDataModel/RigLocalGrid.h @@ -23,17 +23,24 @@ class RigLocalGrid : public RigGridBase { public: explicit RigLocalGrid(RigMainGrid* mainGrid); - virtual ~RigLocalGrid(); + ~RigLocalGrid() override; - RigGridBase * parentGrid() const { return m_parentGrid; } - void setParentGrid(RigGridBase * parentGrid) { m_parentGrid = parentGrid; } + RigGridBase * parentGrid() const; + void setParentGrid(RigGridBase * parentGrid); - size_t positionInParentGrid() const { return m_positionInParentGrid; } - void setPositionInParentGrid(size_t positionInParentGrid) { m_positionInParentGrid = positionInParentGrid; } + size_t positionInParentGrid() const; + void setPositionInParentGrid(size_t positionInParentGrid); + + void setAsTempGrid(bool isTemp); + bool isTempGrid() const override; + + void setAssociatedWellPathName(const std::string& wellPathName); + const std::string& associatedWellPathName() const override; private: RigGridBase * m_parentGrid; size_t m_positionInParentGrid; - + bool m_isTempGrid; + std::string m_associatedWellPathName; }; diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp index adcd09cd42..5786191508 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.cpp @@ -3,87 +3,126 @@ // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RigMainGrid.h" -#include "RiaLogging.h" #include "RiaDefines.h" -#include "RigFault.h" +#include "RiaLogging.h" #include "RigActiveCellInfo.h" +#include "RigHexIntersectionTools.h" -#include "cvfBoundingBoxTree.h" #include "cvfAssert.h" +#include "cvfBoundingBoxTree.h" - -RigMainGrid::RigMainGrid(void) +RigMainGrid::RigMainGrid() : RigGridBase(this) { m_displayModelOffset = cvf::Vec3d::ZERO; - + m_gridIndex = 0; - m_gridId = 0; - m_gridIdToIndexMapping.push_back(0); + m_gridId = 0; + m_gridIdToIndexMapping.push_back(0); m_flipXAxis = false; m_flipYAxis = false; -} +} + +RigMainGrid::~RigMainGrid() {} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector& RigMainGrid::nodes() +{ + return m_nodes; +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigMainGrid::nodes() const +{ + return m_nodes; +} -RigMainGrid::~RigMainGrid(void) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector& RigMainGrid::globalCellArray() { + return m_cells; } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigMainGrid::globalCellArray() const +{ + return m_cells; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- RigGridBase* RigMainGrid::gridAndGridLocalIdxFromGlobalCellIdx(size_t globalCellIdx, size_t* gridLocalCellIdx) { CVF_ASSERT(globalCellIdx < m_cells.size()); - RigCell& cell = m_cells[globalCellIdx]; + + RigCell& cell = m_cells[globalCellIdx]; RigGridBase* hostGrid = cell.hostGrid(); CVF_ASSERT(hostGrid); - *gridLocalCellIdx = cell.gridLocalCellIndex(); + + if (gridLocalCellIdx) + { + *gridLocalCellIdx = cell.gridLocalCellIndex(); + } + return hostGrid; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const RigGridBase* RigMainGrid::gridAndGridLocalIdxFromGlobalCellIdx(size_t globalCellIdx, size_t* gridLocalCellIdx) const { CVF_ASSERT(globalCellIdx < m_cells.size()); - const RigCell& cell = m_cells[globalCellIdx]; + + const RigCell& cell = m_cells[globalCellIdx]; const RigGridBase* hostGrid = cell.hostGrid(); CVF_ASSERT(hostGrid); - *gridLocalCellIdx = cell.gridLocalCellIndex(); + + if (gridLocalCellIdx) + { + *gridLocalCellIdx = cell.gridLocalCellIndex(); + } + return hostGrid; } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const RigCell& RigMainGrid::cellByGridAndGridLocalCellIdx(size_t gridIdx, size_t gridLocalCellIdx) const { - return gridByIndex(gridIdx)->cell(gridLocalCellIdx); + return gridByIndex(gridIdx)->cell(gridLocalCellIdx); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- size_t RigMainGrid::reservoirCellIndexByGridAndGridLocalCellIndex(size_t gridIdx, size_t gridLocalCellIdx) const { @@ -91,7 +130,65 @@ size_t RigMainGrid::reservoirCellIndexByGridAndGridLocalCellIndex(size_t gridIdx } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +size_t RigMainGrid::findReservoirCellIndexFromPoint(const cvf::Vec3d& point) const +{ + size_t cellContainingPoint = cvf::UNDEFINED_SIZE_T; + + cvf::BoundingBox pointBBox; + pointBBox.add(point); + + std::vector cellIndices; + m_mainGrid->findIntersectingCells(pointBBox, &cellIndices); + + cvf::Vec3d hexCorners[8]; + for (size_t cellIndex : cellIndices) + { + m_mainGrid->cellCornerVertices(cellIndex, hexCorners); + + if (RigHexIntersectionTools::isPointInCell(point, hexCorners)) + { + cellContainingPoint = cellIndex; + break; + } + } + + return cellContainingPoint; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RigMainGrid::findAllReservoirCellIndicesMatching2dPoint(const cvf::Vec2d& point2d) const +{ + cvf::BoundingBox gridBoundingVox = boundingBox(); + cvf::Vec3d highestPoint(point2d, gridBoundingVox.max().z()); + cvf::Vec3d lowestPoint(point2d, gridBoundingVox.min().z()); + + cvf::BoundingBox rayBBox; + rayBBox.add(highestPoint); + rayBBox.add(lowestPoint); + + std::vector cellIndices; + m_mainGrid->findIntersectingCells(rayBBox, &cellIndices); + + cvf::Vec3d hexCorners[8]; + for (size_t cellIndex : cellIndices) + { + m_mainGrid->cellCornerVertices(cellIndex, hexCorners); + + if (RigHexIntersectionTools::lineIntersectsHexCell(highestPoint, lowestPoint, hexCorners)) + { + cellIndices.push_back(cellIndex); + } + } + + return cellIndices; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RigMainGrid::addLocalGrid(RigLocalGrid* localGrid) { @@ -101,7 +198,6 @@ void RigMainGrid::addLocalGrid(RigLocalGrid* localGrid) m_localGrids.push_back(localGrid); localGrid->setGridIndex(m_localGrids.size()); // Maingrid itself has grid index 0 - if (m_gridIdToIndexMapping.size() <= static_cast(localGrid->gridId())) { m_gridIdToIndexMapping.resize(localGrid->gridId() + 1, cvf::UNDEFINED_SIZE_T); @@ -111,24 +207,49 @@ void RigMainGrid::addLocalGrid(RigLocalGrid* localGrid) } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +size_t RigMainGrid::gridCountOnFile() const +{ + size_t gridCount = 1; + + for (const auto& grid : m_localGrids) + { + if (!grid->isTempGrid()) + { + gridCount++; + } + } + + return gridCount; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RigMainGrid::gridCount() const +{ + return m_localGrids.size() + 1; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- void RigMainGrid::initAllSubGridsParentGridPointer() { - if ( m_localGrids.size() && m_localGrids[0]->parentGrid() == nullptr ) + if (m_localGrids.size() && m_localGrids[0]->parentGrid() == nullptr) { initSubGridParentPointer(); size_t i; - for ( i = 0; i < m_localGrids.size(); ++i ) + for (i = 0; i < m_localGrids.size(); ++i) { m_localGrids[i]->initSubGridParentPointer(); } } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigMainGrid::initAllSubCellsMainGridCellIndex() { @@ -136,12 +257,12 @@ void RigMainGrid::initAllSubCellsMainGridCellIndex() size_t i; for (i = 0; i < m_localGrids.size(); ++i) { - m_localGrids[i]->initSubCellsMainGridCellIndex(); + m_localGrids[i]->initSubCellsMainGridCellIndex(); } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::Vec3d RigMainGrid::displayModelOffset() const { @@ -149,7 +270,7 @@ cvf::Vec3d RigMainGrid::displayModelOffset() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigMainGrid::setDisplayModelOffset(cvf::Vec3d offset) { @@ -166,6 +287,7 @@ void RigMainGrid::computeCachedData() initAllSubGridsParentGridPointer(); initAllSubCellsMainGridCellIndex(); + m_cellSearchTree = nullptr; buildCellSearchTree(); } @@ -175,8 +297,8 @@ void RigMainGrid::computeCachedData() RigGridBase* RigMainGrid::gridByIndex(size_t localGridIndex) { if (localGridIndex == 0) return this; - CVF_ASSERT(localGridIndex - 1 < m_localGrids.size()) ; - return m_localGrids[localGridIndex-1].p(); + CVF_ASSERT(localGridIndex - 1 < m_localGrids.size()); + return m_localGrids[localGridIndex - 1].p(); } //-------------------------------------------------------------------------------------------------- @@ -185,12 +307,12 @@ RigGridBase* RigMainGrid::gridByIndex(size_t localGridIndex) const RigGridBase* RigMainGrid::gridByIndex(size_t localGridIndex) const { if (localGridIndex == 0) return this; - CVF_ASSERT(localGridIndex - 1 < m_localGrids.size()) ; - return m_localGrids[localGridIndex-1].p(); + CVF_ASSERT(localGridIndex - 1 < m_localGrids.size()); + return m_localGrids[localGridIndex - 1].p(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigMainGrid::setFlipAxis(bool flipXAxis, bool flipYAxis) { @@ -228,35 +350,53 @@ void RigMainGrid::setFlipAxis(bool flipXAxis, bool flipYAxis) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- RigGridBase* RigMainGrid::gridById(int localGridId) { - CVF_ASSERT (localGridId >= 0 && static_cast(localGridId) < m_gridIdToIndexMapping.size()); + CVF_ASSERT(localGridId >= 0 && static_cast(localGridId) < m_gridIdToIndexMapping.size()); return this->gridByIndex(m_gridIdToIndexMapping[localGridId]); } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +size_t RigMainGrid::totalTemporaryGridCellCount() const +{ + size_t cellCount = 0; + + for (const auto& grid : m_localGrids) + { + if (grid->isTempGrid()) + { + cellCount += grid->cellCount(); + } + } + + return cellCount; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- RigNNCData* RigMainGrid::nncData() { - if (m_nncData.isNull()) - { + if (m_nncData.isNull()) + { m_nncData = new RigNNCData; - } - + } + return m_nncData.p(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigMainGrid::setFaults(const cvf::Collection& faults) { m_faults = faults; -#pragma omp parallel for +#pragma omp parallel for for (int i = 0; i < static_cast(m_faults.size()); i++) { m_faults[i]->computeFaultFacesFromCellRanges(this->mainGrid()); @@ -264,7 +404,15 @@ void RigMainGrid::setFaults(const cvf::Collection& faults) } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +const cvf::Collection& RigMainGrid::faults() +{ + return m_faults; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- bool RigMainGrid::hasFaultWithName(const QString& name) const { @@ -279,20 +427,22 @@ bool RigMainGrid::hasFaultWithName(const QString& name) const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo) { - if (hasFaultWithName(RiaDefines::undefinedGridFaultName()) - && hasFaultWithName(RiaDefines::undefinedGridFaultWithInactiveName())) + if (hasFaultWithName(RiaDefines::undefinedGridFaultName()) && + hasFaultWithName(RiaDefines::undefinedGridFaultWithInactiveName())) { - //RiaLogging::debug(QString("Calculate faults already run for grid.")); + // RiaLogging::debug(QString("Calculate faults already run for grid.")); + return; } + m_faultsPrCellAcc = new RigFaultsPrCellAccumulator(m_cells.size()); // Spread fault idx'es on the cells from the faults - for (size_t fIdx = 0 ; fIdx < m_faults.size(); ++fIdx) + for (size_t fIdx = 0; fIdx < m_faults.size(); ++fIdx) { m_faults[fIdx]->accumulateFaultsPrCell(m_faultsPrCellAcc.p(), static_cast(fIdx)); } @@ -312,19 +462,22 @@ void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo) const std::vector& vxs = m_mainGrid->nodes(); - for (int gcIdx = 0 ; gcIdx < static_cast(m_cells.size()); ++gcIdx) + for (int gcIdx = 0; gcIdx < static_cast(m_cells.size()); ++gcIdx) { - if ( m_cells[gcIdx].isInvalid()) + if (m_cells[gcIdx].isInvalid()) { continue; } size_t neighborReservoirCellIdx; size_t neighborGridCellIdx; - size_t i, j, k; - RigGridBase* hostGrid = nullptr; - bool firstNO_FAULTFaceForCell = true; - bool isCellActive = true; + size_t i = 0; + size_t j = 0; + size_t k = 0; + + RigGridBase* hostGrid = nullptr; + bool firstNO_FAULTFaceForCell = true; + bool isCellActive = true; char upperLimitForFaceType = cvf::StructGridInterface::FaceType::POS_K; @@ -343,13 +496,13 @@ void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo) size_t gridLocalCellIndex; hostGrid = this->gridAndGridLocalIdxFromGlobalCellIdx(gcIdx, &gridLocalCellIndex); - hostGrid->ijkFromCellIndex(gridLocalCellIndex, &i,&j, &k); + hostGrid->ijkFromCellIndex(gridLocalCellIndex, &i, &j, &k); isCellActive = activeCellInfo->isActive(gcIdx); firstNO_FAULTFaceForCell = false; } - if(!hostGrid->cellIJKNeighbor(i, j, k, face, &neighborGridCellIdx)) + if (!hostGrid->cellIJKNeighbor(i, j, k, face, &neighborGridCellIdx)) { continue; } @@ -364,24 +517,27 @@ void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo) double tolerance = 1e-6; - caf::SizeTArray4 faceIdxs; + std::array faceIdxs; m_cells[gcIdx].faceIndices(face, &faceIdxs); - caf::SizeTArray4 nbFaceIdxs; + std::array nbFaceIdxs; m_cells[neighborReservoirCellIdx].faceIndices(StructGridInterface::oppositeFace(face), &nbFaceIdxs); - bool sharedFaceVertices = true; - if (sharedFaceVertices && vxs[faceIdxs[0]].pointDistance(vxs[nbFaceIdxs[0]]) > tolerance ) sharedFaceVertices = false; - if (sharedFaceVertices && vxs[faceIdxs[1]].pointDistance(vxs[nbFaceIdxs[3]]) > tolerance ) sharedFaceVertices = false; - if (sharedFaceVertices && vxs[faceIdxs[2]].pointDistance(vxs[nbFaceIdxs[2]]) > tolerance ) sharedFaceVertices = false; - if (sharedFaceVertices && vxs[faceIdxs[3]].pointDistance(vxs[nbFaceIdxs[1]]) > tolerance ) sharedFaceVertices = false; + if (sharedFaceVertices && vxs[faceIdxs[0]].pointDistance(vxs[nbFaceIdxs[0]]) > tolerance) + sharedFaceVertices = false; + if (sharedFaceVertices && vxs[faceIdxs[1]].pointDistance(vxs[nbFaceIdxs[3]]) > tolerance) + sharedFaceVertices = false; + if (sharedFaceVertices && vxs[faceIdxs[2]].pointDistance(vxs[nbFaceIdxs[2]]) > tolerance) + sharedFaceVertices = false; + if (sharedFaceVertices && vxs[faceIdxs[3]].pointDistance(vxs[nbFaceIdxs[1]]) > tolerance) + sharedFaceVertices = false; if (sharedFaceVertices) { continue; } - // To avoid doing this calculation for the opposite face + // To avoid doing this calculation for the opposite face int faultIdx = unNamedFaultIdx; if (!(isCellActive && isNeighborCellActive)) faultIdx = unNamedFaultWithInactiveIdx; @@ -393,7 +549,7 @@ void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo) if (static_cast(gcIdx) < neighborReservoirCellIdx) { RigFault::FaultFace ff(gcIdx, cvf::StructGridInterface::FaceType(faceIdx), neighborReservoirCellIdx); - if(isCellActive && isNeighborCellActive) + if (isCellActive && isNeighborCellActive) { unNamedFault->faultFaces().push_back(ff); } @@ -404,7 +560,10 @@ void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo) } else { - CVF_FAIL_MSG("Found fault with global neighbor index less than the native index. "); // Should never occur. because we flag the opposite face in the faultsPrCellAcc + CVF_FAIL_MSG( + "Found fault with global neighbor index less than the native index. "); // Should never occur. because we + // flag the opposite face in the + // faultsPrCellAcc } } } @@ -414,7 +573,7 @@ void RigMainGrid::calculateFaults(const RigActiveCellInfo* activeCellInfo) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigMainGrid::distributeNNCsToFaults() { @@ -422,9 +581,9 @@ void RigMainGrid::distributeNNCsToFaults() for (size_t nncIdx = 0; nncIdx < nncs.size(); ++nncIdx) { // Find the fault for each side of the nnc - const RigConnection& conn = nncs[nncIdx]; - int fIdx1 = RigFaultsPrCellAccumulator::NO_FAULT; - int fIdx2 = RigFaultsPrCellAccumulator::NO_FAULT; + const RigConnection& conn = nncs[nncIdx]; + int fIdx1 = RigFaultsPrCellAccumulator::NO_FAULT; + int fIdx2 = RigFaultsPrCellAccumulator::NO_FAULT; if (conn.m_c1Face != StructGridInterface::NO_FACE) { @@ -440,7 +599,8 @@ void RigMainGrid::distributeNNCsToFaults() lgrString = "Different Grid"; } - //cvf::Trace::show("NNC: No Fault for NNC C1: " + cvf::String((int)conn.m_c1GlobIdx) + " C2: " + cvf::String((int)conn.m_c2GlobIdx) + " Grid: " + lgrString); + // cvf::Trace::show("NNC: No Fault for NNC C1: " + cvf::String((int)conn.m_c1GlobIdx) + " C2: " + + // cvf::String((int)conn.m_c2GlobIdx) + " Grid: " + lgrString); } if (fIdx1 >= 0) @@ -460,13 +620,12 @@ void RigMainGrid::distributeNNCsToFaults() } //-------------------------------------------------------------------------------------------------- -/// The cell is normally inverted due to Depth becoming -Z at import, +/// The cell is normally inverted due to Depth becoming -Z at import, /// but if (only) one of the flipX/Y is done, the cell is back to normal //-------------------------------------------------------------------------------------------------- bool RigMainGrid::isFaceNormalsOutwards() const { - - for (int gcIdx = 0 ; gcIdx < static_cast(m_cells.size()); ++gcIdx) + for (int gcIdx = 0; gcIdx < static_cast(m_cells.size()); ++gcIdx) { if (!m_cells[gcIdx].isInvalid()) { @@ -474,12 +633,12 @@ bool RigMainGrid::isFaceNormalsOutwards() const cvf::Vec3d faceCenter = m_cells[gcIdx].faceCenter(StructGridInterface::POS_I); cvf::Vec3d faceNormal = m_cells[gcIdx].faceNormalWithAreaLenght(StructGridInterface::POS_I); - double typicalIJCellSize = characteristicIJCellSize(); + double typicalIJCellSize = characteristicIJCellSize(); double dummy, dummy2, typicalKSize; characteristicCellSizes(&dummy, &dummy2, &typicalKSize); - if ( (faceCenter - cellCenter).length() > 0.2 * typicalIJCellSize - && (faceNormal.length() > (0.2 * typicalIJCellSize * 0.2* typicalKSize))) + if ((faceCenter - cellCenter).length() > 0.2 * typicalIJCellSize && + (faceNormal.length() > (0.2 * typicalIJCellSize * 0.2 * typicalKSize))) { // Cell is assumed ok to use, so calculate whether the normals are outwards or inwards @@ -499,16 +658,17 @@ bool RigMainGrid::isFaceNormalsOutwards() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const RigFault* RigMainGrid::findFaultFromCellIndexAndCellFace(size_t reservoirCellIndex, cvf::StructGridInterface::FaceType face) const +const RigFault* RigMainGrid::findFaultFromCellIndexAndCellFace(size_t reservoirCellIndex, + cvf::StructGridInterface::FaceType face) const { CVF_TIGHT_ASSERT(m_faultsPrCellAcc.notNull()); if (face == cvf::StructGridInterface::NO_FACE) return nullptr; int faultIdx = m_faultsPrCellAcc->faultIdx(reservoirCellIndex, face); - if (faultIdx != RigFaultsPrCellAccumulator::NO_FAULT ) + if (faultIdx != RigFaultsPrCellAccumulator::NO_FAULT) { return m_faults.at(faultIdx); } @@ -543,7 +703,7 @@ const RigFault* RigMainGrid::findFaultFromCellIndexAndCellFace(size_t reservoirC } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigMainGrid::findIntersectingCells(const cvf::BoundingBox& inputBB, std::vector* cellIndices) const { @@ -553,7 +713,7 @@ void RigMainGrid::findIntersectingCells(const cvf::BoundingBox& inputBB, std::ve } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RigMainGrid::buildCellSearchTree() { @@ -568,10 +728,10 @@ void RigMainGrid::buildCellSearchTree() for (size_t cIdx = 0; cIdx < cellCount; ++cIdx) { - const caf::SizeTArray8& cellIndices = m_cells[cIdx].cornerIndices(); - if (m_cells[cIdx].isInvalid()) continue; + const std::array& cellIndices = m_cells[cIdx].cornerIndices(); + cvf::BoundingBox& cellBB = cellBoundingBoxes[cIdx]; cellBB.add(m_nodes[cellIndices[0]]); cellBB.add(m_nodes[cellIndices[1]]); @@ -589,15 +749,33 @@ void RigMainGrid::buildCellSearchTree() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- cvf::BoundingBox RigMainGrid::boundingBox() const { if (m_boundingBox.isValid()) return m_boundingBox; - for (size_t i = 0; i < m_nodes.size(); ++i) + for (const auto& node : m_nodes) { - m_boundingBox.add(m_nodes[i]); + m_boundingBox.add(node); } + return m_boundingBox; } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RigMainGrid::isTempGrid() const +{ + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::string& RigMainGrid::associatedWellPathName() const +{ + static const std::string EMPTY_STRING; + return EMPTY_STRING; +} diff --git a/ApplicationCode/ReservoirDataModel/RigMainGrid.h b/ApplicationCode/ReservoirDataModel/RigMainGrid.h index 7e1fdb6098..7bcc725fbe 100644 --- a/ApplicationCode/ReservoirDataModel/RigMainGrid.h +++ b/ApplicationCode/ReservoirDataModel/RigMainGrid.h @@ -19,16 +19,17 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "RigGridBase.h" -#include + + #include "RigCell.h" +#include "RigGridBase.h" #include "RigLocalGrid.h" -#include "cvfCollection.h" +#include "RigNNCData.h" + #include "cvfBoundingBox.h" -#include "RifReaderInterface.h" +#include "cvfCollection.h" -#include -#include "RigNNCData.h" +#include class RigActiveCellInfo; @@ -42,30 +43,35 @@ class RigMainGrid : public RigGridBase { public: RigMainGrid(); - virtual ~RigMainGrid(); + ~RigMainGrid() override; public: - std::vector& nodes() {return m_nodes;} - const std::vector& nodes() const {return m_nodes;} + std::vector& nodes(); + const std::vector& nodes() const; - std::vector& globalCellArray() {return m_cells;} - const std::vector& globalCellArray() const {return m_cells;} + std::vector& globalCellArray(); + const std::vector& globalCellArray() const; RigGridBase* gridAndGridLocalIdxFromGlobalCellIdx(size_t globalCellIdx, size_t* gridLocalCellIdx); const RigGridBase* gridAndGridLocalIdxFromGlobalCellIdx(size_t globalCellIdx, size_t* gridLocalCellIdx) const; const RigCell& cellByGridAndGridLocalCellIdx(size_t gridIdx, size_t gridLocalCellIdx) const; size_t reservoirCellIndexByGridAndGridLocalCellIndex(size_t gridIdx, size_t gridLocalCellIdx) const; - + size_t findReservoirCellIndexFromPoint(const cvf::Vec3d& point) const; + std::vector findAllReservoirCellIndicesMatching2dPoint(const cvf::Vec2d& point2d) const; void addLocalGrid(RigLocalGrid* localGrid); - size_t gridCount() const { return m_localGrids.size() + 1; } + + size_t gridCountOnFile() const; + size_t gridCount() const; RigGridBase* gridByIndex(size_t localGridIndex); const RigGridBase* gridByIndex(size_t localGridIndex) const; RigGridBase* gridById(int localGridId); + + size_t totalTemporaryGridCellCount() const; RigNNCData* nncData(); void setFaults(const cvf::Collection& faults); - const cvf::Collection& faults() { return m_faults; } + const cvf::Collection& faults(); void calculateFaults(const RigActiveCellInfo* activeCellInfo); void distributeNNCsToFaults(); @@ -76,14 +82,17 @@ class RigMainGrid : public RigGridBase void computeCachedData(); void initAllSubGridsParentGridPointer(); - // Overrides - virtual cvf::Vec3d displayModelOffset() const; + cvf::Vec3d displayModelOffset() const override; void setDisplayModelOffset(cvf::Vec3d offset); void setFlipAxis(bool flipXAxis, bool flipYAxis); void findIntersectingCells(const cvf::BoundingBox& inputBB, std::vector* cellIndices) const; cvf::BoundingBox boundingBox() const; + + bool isTempGrid() const override; + const std::string& associatedWellPathName() const override; + private: void initAllSubCellsMainGridCellIndex(); void buildCellSearchTree(); diff --git a/ApplicationCode/ReservoirDataModel/RigNNCData.cpp b/ApplicationCode/ReservoirDataModel/RigNNCData.cpp index 9d9ce21efa..89ef3b8705 100644 --- a/ApplicationCode/ReservoirDataModel/RigNNCData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigNNCData.cpp @@ -161,8 +161,8 @@ cvf::StructGridInterface::FaceType RigNNCData::calculateCellFaceOverlap(const Ri std::vector polygon; std::vector intersections; - caf::SizeTArray4 face1; - caf::SizeTArray4 face2; + std::array face1; + std::array face2; c1.faceIndices((cvf::StructGridInterface::FaceType)(fIdx), &face1); c2.faceIndices(cvf::StructGridInterface::oppositeFace((cvf::StructGridInterface::FaceType)(fIdx)), &face2); diff --git a/ApplicationCode/ReservoirDataModel/RigNNCData.h b/ApplicationCode/ReservoirDataModel/RigNNCData.h index 6d5df68289..49816a6147 100644 --- a/ApplicationCode/ReservoirDataModel/RigNNCData.h +++ b/ApplicationCode/ReservoirDataModel/RigNNCData.h @@ -24,8 +24,6 @@ #include "cvfVector3.h" #include "cvfStructGrid.h" -#include "cafFixedArray.h" - #include // Needed for HUGE_VAL on Linux #include #include diff --git a/ApplicationCode/ReservoirDataModel/RigObservedData.h b/ApplicationCode/ReservoirDataModel/RigObservedData.h index e3081fcb0a..6d23c53e7b 100644 --- a/ApplicationCode/ReservoirDataModel/RigObservedData.h +++ b/ApplicationCode/ReservoirDataModel/RigObservedData.h @@ -27,7 +27,7 @@ class RigObservedData: public cvf::Object { public: explicit RigObservedData(const QString& observedDataFileName ); - ~RigObservedData(); + ~RigObservedData() override; void openOrReloadCase(const QString& observedDataFileName); diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp index 07505ad984..24dcf8ffa7 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirBuilderMock.cpp @@ -83,10 +83,10 @@ void RigReservoirBuilderMock::appendNodes(const cvf::Vec3d& min, const cvf::Vec3 size_t i; for (i = 0; i < cubeDimension.x(); i++) { - cvf::Vec3d min(xPos, yPos, zPos); - cvf::Vec3d max(xPos + dx, yPos + dy, zPos + dz); + cvf::Vec3d cornerA(xPos, yPos, zPos); + cvf::Vec3d cornerB(xPos + dx, yPos + dy, zPos + dz); - appendCubeNodes(min, max, nodes); + appendCubeNodes(cornerA, cornerB, nodes); xPos += dx; } @@ -206,6 +206,7 @@ void RigReservoirBuilderMock::populateReservoir(RigEclipseCaseData* eclipseCase) // Create local grid and set local grid dimensions RigLocalGrid* localGrid = new RigLocalGrid(eclipseCase->mainGrid()); localGrid->setGridId(1); + localGrid->setGridName("LGR_1"); eclipseCase->mainGrid()->addLocalGrid(localGrid); localGrid->setParentGrid(eclipseCase->mainGrid()); @@ -222,7 +223,7 @@ void RigReservoirBuilderMock::populateReservoir(RigEclipseCaseData* eclipseCase) { RigCell& cell = eclipseCase->mainGrid()->globalCellArray()[mainGridIndicesWithSubGrid[cellIdx]]; - caf::SizeTArray8& indices = cell.cornerIndices(); + std::array& indices = cell.cornerIndices(); int nodeIdx; for (nodeIdx = 0; nodeIdx < 8; nodeIdx++) { diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirGridTools.cpp b/ApplicationCode/ReservoirDataModel/RigReservoirGridTools.cpp index 08b6d551a5..c61c2e7ca0 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirGridTools.cpp +++ b/ApplicationCode/ReservoirDataModel/RigReservoirGridTools.cpp @@ -74,7 +74,7 @@ const cvf::StructGridInterface* RigReservoirGridTools::gridByIndex(RimCase* rimC } else if (geoMechPartCollection) { - return geoMechPartCollection->part(gridIndex)->structGrid(); + return geoMechPartCollection->part(gridIndex)->getOrCreateStructGrid(); } return nullptr; @@ -103,7 +103,7 @@ QString RigReservoirGridTools::gridName(RimCase* rimCase, int gridIndex) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigActiveCellInfo* RigReservoirGridTools::activeCellInfo(Rim3dView* rimView) +const RigActiveCellInfo* RigReservoirGridTools::activeCellInfo(Rim3dView* rimView) { RimEclipseView* eclipseView = dynamic_cast(rimView); if (eclipseView) diff --git a/ApplicationCode/ReservoirDataModel/RigReservoirGridTools.h b/ApplicationCode/ReservoirDataModel/RigReservoirGridTools.h index 4682a0c396..1dde9a155c 100644 --- a/ApplicationCode/ReservoirDataModel/RigReservoirGridTools.h +++ b/ApplicationCode/ReservoirDataModel/RigReservoirGridTools.h @@ -1,23 +1,27 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once +#include "RigMainGrid.h" + +#include + class RigActiveCellInfo; class RigFemPartCollection; class RigMainGrid; @@ -26,14 +30,14 @@ class Rim3dView; namespace cvf { - class StructGridInterface; +class StructGridInterface; } class QString; //================================================================================================== -/// -/// +/// +/// //================================================================================================== class RigReservoirGridTools { @@ -43,10 +47,36 @@ class RigReservoirGridTools static const cvf::StructGridInterface* gridByIndex(RimCase* rimCase, int gridIndex); static QString gridName(RimCase* rimCase, int gridIndex); - static RigActiveCellInfo* activeCellInfo(Rim3dView* rimView); + static const RigActiveCellInfo* activeCellInfo(Rim3dView* rimView); + + template + static QString globalCellIndicesToOneBasedIJKText(InputIterator first, InputIterator last, const RigMainGrid* mainGrid) + { + QString txt; + + if (mainGrid) + { + while (first != last) + { + size_t globalCellIndex = *first; + size_t i, j, k; + mainGrid->ijkFromCellIndex(globalCellIndex, &i, &j, &k); + i++; + j++; + k++; + + QString itemText = QString("%1 %2 %3").arg(i).arg(j).arg(k); + + txt += itemText + "\n"; + + ++first; + } + } + + return txt; + } private: - static RigMainGrid* eclipseMainGrid(RimCase* rimCase); - static RigFemPartCollection* geoMechPartCollection(RimCase* rimCase); + static RigMainGrid* eclipseMainGrid(RimCase* rimCase); + static RigFemPartCollection* geoMechPartCollection(RimCase* rimCase); }; - diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessor.h b/ApplicationCode/ReservoirDataModel/RigResultAccessor.h index cc416da9a4..616aafbf16 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultAccessor.h +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessor.h @@ -44,8 +44,8 @@ class RigResultAccessor : public cvf::Object class RigHugeValResultAccessor : public RigResultAccessor { public: - virtual double cellScalar(size_t gridLocalCellIndex) const; - virtual double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const; - virtual double cellScalarGlobIdx(size_t globCellIndex) const; - virtual double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const; + double cellScalar(size_t gridLocalCellIndex) const override; + double cellFaceScalar(size_t gridLocalCellIndex, cvf::StructGridInterface::FaceType faceId) const override; + double cellScalarGlobIdx(size_t globCellIndex) const override; + double cellFaceScalarGlobIdx(size_t globCellIndex, cvf::StructGridInterface::FaceType faceId) const override; }; diff --git a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp index 5500061ec6..696d70be35 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp +++ b/ApplicationCode/ReservoirDataModel/RigResultAccessorFactory.cpp @@ -66,11 +66,6 @@ cvf::ref RigResultAccessorFactory::createFromNameAndType(cons const QString& uiResultName, RiaDefines::ResultCatType resultType) { - CVF_ASSERT(gridIndex < eclipseCase->gridCount()); - CVF_ASSERT(eclipseCase); - CVF_ASSERT(eclipseCase->results(porosityModel)); - CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); - if (!eclipseCase || !eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) { return nullptr; @@ -148,11 +143,6 @@ cvf::ref RigResultAccessorFactory::createNativeFromUiResultNa size_t timeStepIndex, const QString& uiResultName) { - CVF_ASSERT(gridIndex < eclipseCase->gridCount()); - CVF_ASSERT(eclipseCase); - CVF_ASSERT(eclipseCase->results(porosityModel)); - CVF_ASSERT(eclipseCase->activeCellInfo(porosityModel)); - if (!eclipseCase || !eclipseCase->results(porosityModel) || !eclipseCase->activeCellInfo(porosityModel)) { return nullptr; diff --git a/ApplicationCode/ReservoirDataModel/RigResultModifier.h b/ApplicationCode/ReservoirDataModel/RigResultModifier.h index 93e54ce1b3..27a58b7a8d 100644 --- a/ApplicationCode/ReservoirDataModel/RigResultModifier.h +++ b/ApplicationCode/ReservoirDataModel/RigResultModifier.h @@ -46,7 +46,7 @@ class RigAllGridCellsResultModifier : public RigResultModifier { } - virtual void setCellScalar(size_t gridLocalCellIndex, double scalarValue) + void setCellScalar(size_t gridLocalCellIndex, double scalarValue) override { size_t reservoirCellIndex = m_grid->reservoirCellIndex(gridLocalCellIndex); CVF_TIGHT_ASSERT(reservoirCellIndex < m_reservoirResultValues->size()); @@ -75,12 +75,12 @@ class RigActiveCellsResultModifier : public RigResultModifier { } - virtual void setCellScalar(size_t gridLocalCellIndex, double scalarValue) + void setCellScalar(size_t gridLocalCellIndex, double scalarValue) override { size_t reservoirCellIndex = m_grid->reservoirCellIndex(gridLocalCellIndex); size_t resultValueIndex = m_activeCellInfo->cellResultIndex(reservoirCellIndex); - CVF_TIGHT_ASSERT(m_reservoirResultValues != NULL && resultValueIndex < m_reservoirResultValues->size()); + CVF_TIGHT_ASSERT(m_reservoirResultValues != nullptr && resultValueIndex < m_reservoirResultValues->size()); (*m_reservoirResultValues)[resultValueIndex] = scalarValue; } diff --git a/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp b/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp index 2d47615e51..3316fcc70d 100644 --- a/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp +++ b/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.cpp @@ -429,27 +429,6 @@ void RigSimulationWellCenterLineCalculator::addCellCenterPoints(const RigEclipse } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RigSimulationWellCenterLineCalculator::hasAnyResultCells(const std::vector &resBranches) -{ - bool hasResultCells = false; - if ( resBranches.size() ) - { - for ( size_t i = 0 ; i < resBranches.size(); ++i ) - { - if ( resBranches[i].m_branchResultPoints.size() != 0 ) - { - hasResultCells = true; - break; - } - } - } - return hasResultCells; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -754,7 +733,7 @@ class BranchSplitter if ( wellCell.isInvalid() ) continue; - const caf::SizeTArray8& cellIndices = wellCell.cornerIndices(); + const std::array& cellIndices = wellCell.cornerIndices(); cvf::BoundingBox& cellBB = m_cellBoundingBoxes[cIdx]; cellBB.add(nodes[cellIndices[0]]); diff --git a/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.h b/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.h index ec87e69112..bb3e9a5229 100644 --- a/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.h +++ b/ApplicationCode/ReservoirDataModel/RigSimulationWellCenterLineCalculator.h @@ -46,7 +46,6 @@ class RigSimulationWellCenterLineCalculator std::vector>& pipeBranchesCellIds); private: - static bool hasAnyResultCells(const std::vector &resBranches); static bool hasAnyValidDataCells(const RigWellResultBranch& branch); static void finishPipeCenterLine( std::vector< std::vector > &pipeBranchesCLCoords, const cvf::Vec3d& lastCellCenter ) ; diff --git a/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp b/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp index 8cd4e1a6fb..205b5e80dc 100644 --- a/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp +++ b/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.cpp @@ -42,10 +42,13 @@ size_t findMirrorXIndex(std::vector xs); const double RigStimPlanFractureDefinition::THRESHOLD_VALUE = 1e-5; //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -RigStimPlanFractureDefinition::RigStimPlanFractureDefinition() : - m_unitSet(RiaEclipseUnitTools::UNITS_UNKNOWN), m_topPerfTvd(HUGE_VAL), m_bottomPerfTvd(HUGE_VAL) +RigStimPlanFractureDefinition::RigStimPlanFractureDefinition() + : m_unitSet(RiaEclipseUnitTools::UNITS_UNKNOWN) + , m_topPerfTvd(HUGE_VAL) + , m_bottomPerfTvd(HUGE_VAL) + , m_xMirrorMode(false) { } @@ -200,7 +203,7 @@ void RigStimPlanFractureDefinition::generateXsFromFileXs(bool xMirrorMode) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector> RigStimPlanFractureDefinition::generateDataLayoutFromFileDataLayout(std::vector> fileXYData) +std::vector> RigStimPlanFractureDefinition::generateDataLayoutFromFileDataLayout(std::vector> fileXYData) const { if (m_xMirrorMode) { @@ -231,12 +234,12 @@ std::vector> RigStimPlanFractureDefinition::generateDataLayo //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigStimPlanFractureDefinition::numberOfParameterValuesOK(std::vector> propertyValuesAtTimestep) +bool RigStimPlanFractureDefinition::numberOfParameterValuesOK(std::vector> propertyValuesAtTimestep) const { size_t xCount = m_Xs.size(); if ( propertyValuesAtTimestep.size() != yCount()) return false; - for ( std::vector valuesAtDepthVector : propertyValuesAtTimestep ) + for ( const std::vector& valuesAtDepthVector : propertyValuesAtTimestep ) { if ( valuesAtDepthVector.size() != xCount ) return false; } @@ -308,27 +311,17 @@ std::vector> // The conductivity value is used in the computations of transmissibility when exporting COMPDAT, and has unit md-m or md-ft // This unit must match the unit used to represent coordinates of the grid used for export - QString conversionUnitText; - if (conductivityUnitTextOnFile == "md-m") - { - conversionUnitText = "m"; - } - else if (conductivityUnitTextOnFile == "md-ft") - { - conversionUnitText = "ft"; - } - for (auto& yValues : conductivityValues) { for (auto& xVal : yValues) { if (requiredUnitSet == RiaEclipseUnitTools::UNITS_FIELD) { - xVal = RiaEclipseUnitTools::convertToFeet(xVal, conversionUnitText); + xVal = RiaEclipseUnitTools::convertToFeet(xVal, conductivityUnitTextOnFile); } else if (requiredUnitSet == RiaEclipseUnitTools::UNITS_METRIC) { - xVal = RiaEclipseUnitTools::convertToMeter(xVal, conversionUnitText); + xVal = RiaEclipseUnitTools::convertToMeter(xVal, conductivityUnitTextOnFile); } } } @@ -342,7 +335,7 @@ std::vector> cvf::ref RigStimPlanFractureDefinition::createFractureGrid(const QString& resultName, int activeTimeStepIndex, double wellPathIntersectionAtFractureDepth, - RiaEclipseUnitTools::UnitSystem requiredUnitSet) + RiaEclipseUnitTools::UnitSystem requiredUnitSet) const { std::vector> conductivityValues = conductivityValuesAtTimeStep(resultName, activeTimeStepIndex, requiredUnitSet); if (conductivityValues.empty()) @@ -374,7 +367,7 @@ cvf::ref RigStimPlanFractureDefinition::createFractureGrid(cons cellPolygon.push_back(cvf::Vec3d(xCoords[i], depthCoords[j + 1], 0.0)); RigFractureCell stimPlanCell(cellPolygon, i, j); - if ( conductivityValues.size() > 0 ) //Assuming vector to be of correct length, or no values + if ( !conductivityValues.empty() ) //Assuming vector to be of correct length, or no values { stimPlanCell.setConductivityValue(conductivityValues[j + 1][i + 1]); } @@ -452,7 +445,7 @@ std::vector RigStimPlanFractureDefinition::fractureGridResults(const QSt void RigStimPlanFractureDefinition::createFractureTriangleGeometry(double wellPathIntersectionAtFractureDepth, const QString& fractureUserName, std::vector* vertices, - std::vector* triangleIndices) + std::vector* triangleIndices) const { std::vector xCoords = this->m_Xs; cvf::uint lenXcoords = static_cast(xCoords.size()); @@ -496,35 +489,6 @@ void RigStimPlanFractureDefinition::createFractureTriangleGeometry(double wellPa } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void sortPolygon(std::vector &polygon) -{ - if (polygon.size() == 0) return; - - for (int i = 1; i < static_cast(polygon.size()) - 1; i++) - { - cvf::Vec3f lastNode = polygon[i - 1]; - cvf::Vec3f node = polygon[i]; - cvf::Vec3f nextNode = polygon[i + 1]; - - if (node.y() == nextNode.y()) - { - if (lastNode.x() < node.x() && node.x() > nextNode.x()) - { - polygon[i] = nextNode; - polygon[i + 1] = node; - } - else if (lastNode.x() > node.x() && node.x() < nextNode.x()) - { - polygon[i] = nextNode; - polygon[i + 1] = node; - } - } - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -544,7 +508,7 @@ void RigStimPlanFractureDefinition::addTimeStep(double time) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RigStimPlanFractureDefinition::timeStepExists(double timeStepValueToCheck) +bool RigStimPlanFractureDefinition::timeStepExists(double timeStepValueToCheck) const { for (double timeStep : m_timeSteps) { @@ -556,7 +520,7 @@ bool RigStimPlanFractureDefinition::timeStepExists(double timeStepValueToCheck) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigStimPlanFractureDefinition::getTimeStepIndex(double timeStepValue) +size_t RigStimPlanFractureDefinition::getTimeStepIndex(double timeStepValue) const { size_t index = 0; while (index < m_timeSteps.size()) @@ -573,7 +537,7 @@ size_t RigStimPlanFractureDefinition::getTimeStepIndex(double timeStepValue) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -size_t RigStimPlanFractureDefinition::totalNumberTimeSteps() +size_t RigStimPlanFractureDefinition::totalNumberTimeSteps() const { return m_timeSteps.size(); } diff --git a/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.h b/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.h index 880fa6e60f..70f4a6c3fc 100644 --- a/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.h +++ b/ApplicationCode/ReservoirDataModel/RigStimPlanFractureDefinition.h @@ -59,7 +59,7 @@ class RigStimPlanFractureDefinition: public cvf::Object static const double THRESHOLD_VALUE; RigStimPlanFractureDefinition(); - ~RigStimPlanFractureDefinition(); + ~RigStimPlanFractureDefinition() override; RiaEclipseUnitTools::UnitSystem unitSet() const; size_t xCount() const; @@ -74,16 +74,16 @@ class RigStimPlanFractureDefinition: public cvf::Object cvf::ref createFractureGrid(const QString& resultName, int activeTimeStepIndex, double wellPathIntersectionAtFractureDepth, - RiaEclipseUnitTools::UnitSystem requiredUnitSet); + RiaEclipseUnitTools::UnitSystem requiredUnitSet) const; void createFractureTriangleGeometry(double wellPathIntersectionAtFractureDepth, const QString& fractureUserName, std::vector* vertices, - std::vector* triangleIndices); + std::vector* triangleIndices) const; const std::vector& timeSteps() const; void addTimeStep(double time); - size_t totalNumberTimeSteps(); + size_t totalNumberTimeSteps() const; std::vector> getStimPlanPropertyNamesUnits() const; @@ -106,13 +106,13 @@ class RigStimPlanFractureDefinition: public cvf::Object QStringList conductivityResultNames() const; private: - bool timeStepExists(double timeStepValue); - size_t getTimeStepIndex(double timeStepValue); + bool timeStepExists(double timeStepValue) const; + size_t getTimeStepIndex(double timeStepValue) const; size_t resultIndex(const QString& resultName, const QString& unit) const; void generateXsFromFileXs(bool xMirrorMode); - std::vector> generateDataLayoutFromFileDataLayout(std::vector> rawXYData); + std::vector> generateDataLayoutFromFileDataLayout(std::vector> rawXYData) const; std::vector adjustedYCoordsAroundWellPathPosition(double wellPathIntersectionAtFractureDepth) const; - bool numberOfParameterValuesOK(std::vector> propertyValuesAtTimestep); + bool numberOfParameterValuesOK(std::vector> propertyValuesAtTimestep) const; double minY() const; double maxY() const; void scaleXs(double scaleFactor); diff --git a/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.cpp b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor.cpp similarity index 98% rename from ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.cpp rename to ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor.cpp index 3bb0d18e0a..4cc4454456 100644 --- a/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.cpp +++ b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor.cpp @@ -17,7 +17,7 @@ // ///////////////////////////////////////////////////////////////////////////////// -#include "RigTernaryResultAccessor2d.h" +#include "RigTernaryResultAccessor.h" #include "RigResultAccessor.h" @@ -32,7 +32,7 @@ RigTernaryResultAccessor::RigTernaryResultAccessor() } //-------------------------------------------------------------------------------------------------- -/// Requires at least two data objects present, asserts if more than one data accessor is NULL +/// Requires at least two data objects present, asserts if more than one data accessor is nullptr //-------------------------------------------------------------------------------------------------- void RigTernaryResultAccessor::setTernaryResultAccessors(RigResultAccessor* soil, RigResultAccessor* sgas, RigResultAccessor* swat) { diff --git a/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.h b/ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor.h similarity index 100% rename from ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor2d.h rename to ApplicationCode/ReservoirDataModel/RigTernaryResultAccessor.h diff --git a/ApplicationCode/ReservoirDataModel/RigTransmissibilityEquations.cpp b/ApplicationCode/ReservoirDataModel/RigTransmissibilityEquations.cpp index 2e75e24bc9..cb4de77e89 100644 --- a/ApplicationCode/ReservoirDataModel/RigTransmissibilityEquations.cpp +++ b/ApplicationCode/ReservoirDataModel/RigTransmissibilityEquations.cpp @@ -1,82 +1,158 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RigTransmissibilityEquations.h" -#include "cvfBase.h" -#include "cvfMath.h" - #include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigTransmissibilityEquations::wellBoreTransmissibilityComponent(double cellPerforationVectorComponent, + double permeabilityNormalDirection1, + double permeabilityNormalDirection2, + double cellSizeNormalDirection1, + double cellSizeNormalDirection2, + double wellRadius, + double skinFactor, + double cDarcyForRelevantUnit) +{ + double K = cvf::Math::sqrt(permeabilityNormalDirection1 * permeabilityNormalDirection2); + + double nominator = cDarcyForRelevantUnit * 2 * cvf::PI_D * K * cellPerforationVectorComponent; + + double peaceManRad = peacemanRadius( + permeabilityNormalDirection1, permeabilityNormalDirection2, cellSizeNormalDirection1, cellSizeNormalDirection2); + + double denominator = log(peaceManRad / wellRadius) + skinFactor; + double trans = nominator / denominator; + return trans; +} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RigTransmissibilityEquations::peacemanRadius(double permeabilityNormalDirection1, - double permeabilityNormalDirection2, - double cellSizeNormalDirection1, - double cellSizeNormalDirection2) +double RigTransmissibilityEquations::totalConnectionFactor(double transX, double transY, double transZ) { - double numerator = cvf::Math::sqrt( - pow(cellSizeNormalDirection2, 2.0) * pow(permeabilityNormalDirection1 / permeabilityNormalDirection2, 0.5) - + pow(cellSizeNormalDirection1, 2.0) * pow(permeabilityNormalDirection2 / permeabilityNormalDirection1, 0.5) ); + return cvf::Math::sqrt(pow(transX, 2.0) + pow(transY, 2.0) + pow(transZ, 2.0)); +} - double denominator = pow((permeabilityNormalDirection1 / permeabilityNormalDirection2), 0.25 ) - + pow((permeabilityNormalDirection2 / permeabilityNormalDirection1), 0.25 ); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigTransmissibilityEquations::totalKh(double cellPermX, + double cellPermY, + double cellPermZ, + const cvf::Vec3d& internalCellLengths, + double lateralNtg, + double ntg) +{ + // Compute kh for each local grid cell axis + // Use permeability values for the two other axis + double khx = sqrt(cellPermY * cellPermZ) * internalCellLengths.x() * lateralNtg; + double khy = sqrt(cellPermX * cellPermZ) * internalCellLengths.y() * lateralNtg; + double khz = sqrt(cellPermX * cellPermY) * internalCellLengths.z() * ntg; - double r0 = 0.28 * numerator / denominator; + const double totKh = cvf::Math::sqrt(khx * khx + khy * khy + khz * khz); - return r0; + return totKh; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -double RigTransmissibilityEquations::wellBoreTransmissibilityComponent(double cellPerforationVectorComponent, - double permeabilityNormalDirection1, - double permeabilityNormalDirection2, - double cellSizeNormalDirection1, - double cellSizeNormalDirection2, - double wellRadius, - double skinFactor, - double cDarcyForRelevantUnit) +double RigTransmissibilityEquations::effectiveK(double cellPermX, + double cellPermY, + double cellPermZ, + const cvf::Vec3d& internalCellLengths, + double lateralNtg, + double ntg) { - double K = cvf::Math::sqrt(permeabilityNormalDirection1 * permeabilityNormalDirection2); + // Compute kh for each local grid cell axis + // Use permeability values for the two other axis - double nominator = cDarcyForRelevantUnit * 2 * cvf::PI_D * K * cellPerforationVectorComponent; - - double peaceManRad = peacemanRadius(permeabilityNormalDirection1, - permeabilityNormalDirection2, - cellSizeNormalDirection1, - cellSizeNormalDirection2); + double lx = internalCellLengths.x() * lateralNtg; + double ly = internalCellLengths.y() * lateralNtg; + double lz = internalCellLengths.z() * ntg; - double denominator = log(peaceManRad / wellRadius) + skinFactor; + double khx = sqrt(cellPermY * cellPermZ) * lx; + double khy = sqrt(cellPermX * cellPermZ) * ly; + double khz = sqrt(cellPermX * cellPermY) * lz; - double trans = nominator / denominator; - return trans; + double nominator = khx + khy + khz; + double denominator = lx + ly + lz; + + const double effK = nominator / denominator; + + return effK; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RigTransmissibilityEquations::totalConnectionFactor(double transX, double transY, double transZ) +double RigTransmissibilityEquations::effectiveH(const cvf::Vec3d& internalCellLengths, double lateralNtg, double ntg) +{ + double lx = internalCellLengths.x() * lateralNtg; + double ly = internalCellLengths.y() * lateralNtg; + double lz = internalCellLengths.z() * ntg; + + double effH = cvf::Math::sqrt(lx*lx + ly*ly + lz*lz); + + return effH; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigTransmissibilityEquations::permeability(const double conductivity, const double width) { - return cvf::Math::sqrt( - pow(transX, 2.0) + pow(transY, 2.0) + pow(transZ, 2.0)); + double threshold = 1e-7; + + if (std::fabs(width) > threshold) + { + double perm = conductivity / width; + + return perm; + } + else + { + return 0.0; + } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigTransmissibilityEquations::peacemanRadius(double permeabilityNormalDirection1, + double permeabilityNormalDirection2, + double cellSizeNormalDirection1, + double cellSizeNormalDirection2) +{ + double numerator = cvf::Math::sqrt( + pow(cellSizeNormalDirection2, 2.0) * pow(permeabilityNormalDirection1 / permeabilityNormalDirection2, 0.5) + + pow(cellSizeNormalDirection1, 2.0) * pow(permeabilityNormalDirection2 / permeabilityNormalDirection1, 0.5)); + + double denominator = pow((permeabilityNormalDirection1 / permeabilityNormalDirection2), 0.25) + + pow((permeabilityNormalDirection2 / permeabilityNormalDirection1), 0.25); + + double r0 = 0.28 * numerator / denominator; + + return r0; +} diff --git a/ApplicationCode/ReservoirDataModel/RigTransmissibilityEquations.h b/ApplicationCode/ReservoirDataModel/RigTransmissibilityEquations.h index e9695dd32c..009cd7c4c4 100644 --- a/ApplicationCode/ReservoirDataModel/RigTransmissibilityEquations.h +++ b/ApplicationCode/ReservoirDataModel/RigTransmissibilityEquations.h @@ -1,52 +1,69 @@ ///////////////////////////////////////////////////////////////////////////////// // // 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 +// +// See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #pragma once +#include "cvfBase.h" +#include "cvfMath.h" +#include "cvfVector3.h" class RigTransmissibilityEquations { public: - // Calculations are assuming an orthogonal coordinate system - // If using wellBoreTransmissibilityComponent to calculate Tx (transmissibility in x direction), - // perforationVectorComponent is the x component (in the cell local coordinate system) of the perforation vector - // permeability and cell size for Z and Y are to be specified as "normal directions" 1 and 2 - // but normal directions 1 and 2 are interchangeable (so Z=1, Y=2 and Z=2, Y=1 gives same result) + static double wellBoreTransmissibilityComponent(double cellPerforationVectorComponent, + double permeabilityNormalDirection1, + double permeabilityNormalDirection2, + double cellSizeNormalDirection1, + double cellSizeNormalDirection2, + double wellRadius, + double skinFactor, + double cDarcyForRelevantUnit); - static double peacemanRadius(double permeabilityNormalDirection1, - double permeabilityNormalDirection2, - double cellSizeNormalDirection1, - double cellSizeNormalDirection2); + static double totalConnectionFactor(double transX, double transY, double transZ); - static double wellBoreTransmissibilityComponent(double cellPerforationVectorComponent, - double permeabilityNormalDirection1, - double permeabilityNormalDirection2, - double cellSizeNormalDirection1, - double cellSizeNormalDirection2, - double wellRadius, - double skinFactor, - double cDarcyForRelevantUnit); + static double totalKh(double cellPermX, + double cellPermY, + double cellPermZ, + const cvf::Vec3d& internalCellLengths, + double lateralNtg, + double ntg); - static double totalConnectionFactor(double transX, - double transY, - double transZ); + static double effectiveK(double cellPermX, + double cellPermY, + double cellPermZ, + const cvf::Vec3d& internalCellLengths, + double lateralNtg, + double ntg); -}; + static double effectiveH(const cvf::Vec3d& internalCellLengths, double lateralNtg, double ntg); + + static double permeability(const double conductivity, const double width); +private: + // If using wellBoreTransmissibilityComponent to calculate Tx (transmissibility in x direction), + // perforationVectorComponent is the x component (in the cell local coordinate system) of the perforation vector + // permeability and cell size for Z and Y are to be specified as "normal directions" 1 and 2 + // but normal directions 1 and 2 are interchangeable (so Z=1, Y=2 and Z=2, Y=1 gives same result) + + static double peacemanRadius(double permeabilityNormalDirection1, + double permeabilityNormalDirection2, + double cellSizeNormalDirection1, + double cellSizeNormalDirection2); +}; diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.cpp b/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.cpp index 674a6bc46d..75a54ba227 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.cpp @@ -19,7 +19,7 @@ #include "RigWellLogCurveData.h" -#include "RigCurveDataTools.h" +#include "RiaCurveDataTools.h" #include "RiaEclipseUnitTools.h" @@ -118,7 +118,7 @@ const std::vector& RigWellLogCurveData::tvDepths() const std::vector RigWellLogCurveData::xPlotValues() const { std::vector filteredValues; - RigCurveDataTools::getValuesByIntervals(m_xValues, m_intervalsOfContinousValidValues, &filteredValues); + RiaCurveDataTools::getValuesByIntervals(m_xValues, m_intervalsOfContinousValidValues, &filteredValues); return filteredValues; } @@ -133,12 +133,12 @@ std::vector RigWellLogCurveData::trueDepthPlotValues(RiaDefines::DepthUn { if(destinationDepthUnit == m_depthUnit) { - RigCurveDataTools::getValuesByIntervals(m_tvDepths, m_intervalsOfContinousValidValues, &filteredValues); + RiaCurveDataTools::getValuesByIntervals(m_tvDepths, m_intervalsOfContinousValidValues, &filteredValues); } else { std::vector convertedValues = convertDepthValues(destinationDepthUnit, m_tvDepths); - RigCurveDataTools::getValuesByIntervals(convertedValues, m_intervalsOfContinousValidValues, &filteredValues); + RiaCurveDataTools::getValuesByIntervals(convertedValues, m_intervalsOfContinousValidValues, &filteredValues); } } @@ -154,12 +154,12 @@ std::vector RigWellLogCurveData::measuredDepthPlotValues(RiaDefines::Dep if(destinationDepthUnit == m_depthUnit) { - RigCurveDataTools::getValuesByIntervals(m_measuredDepths, m_intervalsOfContinousValidValues, &filteredValues); + RiaCurveDataTools::getValuesByIntervals(m_measuredDepths, m_intervalsOfContinousValidValues, &filteredValues); } else { std::vector convertedValues = convertDepthValues(destinationDepthUnit, m_measuredDepths); - RigCurveDataTools::getValuesByIntervals(convertedValues, m_intervalsOfContinousValidValues, &filteredValues); + RiaCurveDataTools::getValuesByIntervals(convertedValues, m_intervalsOfContinousValidValues, &filteredValues); } return filteredValues; @@ -170,7 +170,7 @@ std::vector RigWellLogCurveData::measuredDepthPlotValues(RiaDefines::Dep //-------------------------------------------------------------------------------------------------- std::vector> RigWellLogCurveData::polylineStartStopIndices() const { - return RigCurveDataTools::computePolyLineStartStopIndices(m_intervalsOfContinousValidValues); + return RiaCurveDataTools::computePolyLineStartStopIndices(m_intervalsOfContinousValidValues); } //-------------------------------------------------------------------------------------------------- @@ -246,7 +246,7 @@ cvf::ref RigWellLogCurveData::calculateResampledCurveData(d //-------------------------------------------------------------------------------------------------- void RigWellLogCurveData::calculateIntervalsOfContinousValidValues() { - std::vector> intervalsOfValidValues = RigCurveDataTools::calculateIntervalsOfValidValues(m_xValues, false); + std::vector> intervalsOfValidValues = RiaCurveDataTools::calculateIntervalsOfValidValues(m_xValues, false); m_intervalsOfContinousValidValues.clear(); diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.h b/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.h index c2a355deeb..19d1e99cec 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.h +++ b/ApplicationCode/ReservoirDataModel/RigWellLogCurveData.h @@ -35,7 +35,7 @@ class RigWellLogCurveData : public cvf::Object { public: RigWellLogCurveData(); - virtual ~RigWellLogCurveData(); + ~RigWellLogCurveData() override; void setValuesAndMD(const std::vector& xValues, const std::vector& measuredDepths, diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp index f51c6999b0..0e3630f7b1 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellLogExtractor.cpp @@ -40,6 +40,22 @@ RigWellLogExtractor::~RigWellLogExtractor() } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigWellLogExtractor::cellIntersectionMDs() +{ + return m_intersectionMeasuredDepths; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& RigWellLogExtractor::cellIntersectionTVDs() +{ + return m_intersectionTVDs; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -57,8 +73,8 @@ std::vector RigWellLogExtractor::cellIntersectionI cellInfo.globCellIndex = m_intersectedCellsGlobIdx[i]; cellInfo.startPoint = m_intersections[i]; cellInfo.endPoint = m_intersections[i+1]; - cellInfo.startMD = m_measuredDepth[i]; - cellInfo.endMD = m_measuredDepth[i+1]; + cellInfo.startMD = m_intersectionMeasuredDepths[i]; + cellInfo.endMD = m_intersectionMeasuredDepths[i+1]; cellInfo.intersectedCellFaceIn = m_intersectedCellFaces[i]; cellInfo.intersectedCellFaceOut = m_intersectedCellFaces[i+1]; @@ -79,6 +95,14 @@ const std::vector& RigWellLogExtractor::intersectedCellsGlobIdx() return m_intersectedCellsGlobIdx; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const RigWellPath* RigWellLogExtractor::wellPathData() +{ + return m_wellPath.p(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -271,8 +295,6 @@ void RigWellLogExtractor::populateReturnArrays(std::map& measuredDepth() { return m_measuredDepth; } - const std::vector& trueVerticalDepth() { return m_trueVerticalDepth; } + const std::vector& cellIntersectionMDs(); + const std::vector& cellIntersectionTVDs(); const std::vector& intersectedCellsGlobIdx(); - const RigWellPath* wellPathData() { return m_wellPath.p();} + const RigWellPath* wellPathData(); std::vector cellIntersectionInfosAlongWellPath() const; @@ -89,9 +89,8 @@ class RigWellLogExtractor : public cvf::Object cvf::cref m_wellPath; -private: - std::vector m_measuredDepth; - std::vector m_trueVerticalDepth; + std::vector m_intersectionMeasuredDepths; + std::vector m_intersectionTVDs; std::string m_wellCaseErrorMsgName; }; diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogFile.cpp b/ApplicationCode/ReservoirDataModel/RigWellLogFile.cpp index 9d9f9d843a..2f537f9d65 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellLogFile.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellLogFile.cpp @@ -35,23 +35,6 @@ #include // Needed for HUGE_VAL on Linux -//-------------------------------------------------------------------------------------------------- -/// Find the largest possible "ususal" value to use for absent data (-999.25, -9999.25, etc.) -//-------------------------------------------------------------------------------------------------- -static double sg_createAbsentValue(double lowestDataValue) -{ - double absentValue = -999.0; - - while (absentValue > lowestDataValue) - { - absentValue *= 10; - absentValue -= 9; - } - - return absentValue - 0.25; -} - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -114,7 +97,8 @@ bool RigWellLogFile::open(const QString& fileName, QString* errorMessage) QString logName = QString::fromStdString(itCL->first); wellLogNames.append(logName); - if (logName.toUpper() == "DEPT" || logName.toUpper() == "DEPTH") + // 2018-11-09 Added MD https://github.com/OPM/ResInsight/issues/3641 + if (logName.toUpper() == "DEPT" || logName.toUpper() == "DEPTH" || logName.toUpper() == "MD") { m_depthLogName = logName; } @@ -265,95 +249,6 @@ QString RigWellLogFile::wellLogChannelUnitString(const QString& wellLogChannelNa return unit; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RigWellLogFile::exportToLasFile(const RimWellLogCurve* curve, const QString& fileName) -{ - CVF_ASSERT(curve); - - const RigWellLogCurveData* curveData = curve->curveData(); - if (!curveData) - { - return false; - } - - double minX, maxX; - curve->valueRange(&minX, &maxX); - double absentValue = sg_createAbsentValue(minX); - - std::vector wellLogValues = curveData->xValues(); - for (size_t vIdx = 0; vIdx < wellLogValues.size(); vIdx++) - { - double value = wellLogValues[vIdx]; - if (value == HUGE_VAL || value == -HUGE_VAL || value != value) - { - wellLogValues[vIdx] = absentValue; - } - } - - QString wellLogChannelName = curve->wellLogChannelName().trimmed(); - wellLogChannelName.replace(".", "_"); - - QString wellLogDate = curve->wellDate().trimmed(); - wellLogDate.replace(".", "_"); - wellLogDate.replace(" ", "_"); - - NRLib::LasWell lasFile; - lasFile.addWellInfo("WELL", curve->wellName().trimmed().toStdString()); - lasFile.addWellInfo("DATE", wellLogDate.toStdString()); - - if (curveData->depthUnit() == RiaDefines::UNIT_METER) - { - lasFile.AddLog("DEPTH", "M", "Depth in meters", curveData->measuredDepths()); - } - else if (curveData->depthUnit() == RiaDefines::UNIT_FEET) - { - lasFile.AddLog("DEPTH", "FT", "Depth in feet", curveData->measuredDepths()); - } - else if (curveData->depthUnit() == RiaDefines::UNIT_NONE) - { - CVF_ASSERT(false); - lasFile.AddLog("DEPTH", "", "Depth in connection number", curveData->measuredDepths()); - } - - if(curveData->tvDepths().size()) - { - lasFile.AddLog("TVDMSL", "M", "True vertical depth in meters", curveData->tvDepths()); - } - - lasFile.AddLog(wellLogChannelName.trimmed().toStdString(), "NO_UNIT", "", wellLogValues); - lasFile.SetMissing(absentValue); - - double minDepth = 0.0; - double maxDepth = 0.0; - curveData->calculateMDRange(&minDepth, &maxDepth); - - lasFile.setStartDepth(minDepth); - lasFile.setStopDepth(maxDepth); - - if (curveData->depthUnit() == RiaDefines::UNIT_METER) - { - lasFile.setDepthUnit("M"); - } - else if (curveData->depthUnit() == RiaDefines::UNIT_FEET) - { - lasFile.setDepthUnit("FT"); - } - else if ( curveData->depthUnit() == RiaDefines::UNIT_NONE ) - { - CVF_ASSERT(false); - lasFile.setDepthUnit(""); - } - - lasFile.setVersionInfo("2.0"); - - std::vector commentHeader; - lasFile.WriteToFile(fileName.toStdString(), commentHeader); - - return true; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigWellLogFile.h b/ApplicationCode/ReservoirDataModel/RigWellLogFile.h index 411fa8e2d2..c7d3f720b4 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellLogFile.h +++ b/ApplicationCode/ReservoirDataModel/RigWellLogFile.h @@ -41,7 +41,7 @@ class RigWellLogFile : public cvf::Object { public: RigWellLogFile(); - virtual ~RigWellLogFile(); + ~RigWellLogFile() override; bool open(const QString& fileName, QString* errorMessage); @@ -56,8 +56,6 @@ class RigWellLogFile : public cvf::Object QString wellLogChannelUnitString(const QString& wellLogChannelName, RiaDefines::DepthUnitType displayDepthUnit) const; RiaDefines::DepthUnitType depthUnit() const; - static bool exportToLasFile(const RimWellLogCurve* curve, const QString& fileName); - bool hasTvdChannel() const; private: diff --git a/ApplicationCode/ReservoirDataModel/RigWellPath.cpp b/ApplicationCode/ReservoirDataModel/RigWellPath.cpp index 73697b9d73..6cae524e8e 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPath.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellPath.cpp @@ -56,14 +56,40 @@ double RigWellPath::datumElevation() const return m_datumElevation; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RigWellPath::rkbDiff() const +{ + if (hasDatumElevation()) + { + return datumElevation(); + } + + // If measured depth is zero, use the z-value of the well path points + if (m_wellPathPoints.size() > 0 && m_measuredDepths.size() > 0) + { + double epsilon = 1e-3; + + if (cvf::Math::abs(m_measuredDepths[0]) < epsilon) + { + double diff = m_measuredDepths[0] - (-wellPathPoints()[0].z()); + + return diff; + } + } + return HUGE_VAL; +} + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -cvf::Vec3d RigWellPath::interpolatedVectorAlongWellPath(const std::vector& vectors, +cvf::Vec3d RigWellPath::interpolatedVectorValuesAlongWellPath(const std::vector& vectorValuesAlongWellPath, double measuredDepth, double * horizontalLengthAlongWellToStartClipPoint /*= nullptr*/) const { - CVF_ASSERT(vectors.size() == m_wellPathPoints.size()); + CVF_ASSERT(vectorValuesAlongWellPath.size() == m_wellPathPoints.size()); cvf::Vec3d interpolatedVector = cvf::Vec3d::ZERO; if (horizontalLengthAlongWellToStartClipPoint) *horizontalLengthAlongWellToStartClipPoint = 0.0; @@ -85,7 +111,7 @@ cvf::Vec3d RigWellPath::interpolatedVectorAlongWellPath(const std::vector m_wellPathPoints; std::vector m_measuredDepths; + const std::vector& wellPathPoints() const; + const std::vector& measureDepths() const; + RigWellPath(); void setDatumElevation(double value); bool hasDatumElevation() const; double datumElevation() const; - cvf::Vec3d interpolatedVectorAlongWellPath(const std::vector& vectors, + double rkbDiff() const; + cvf::Vec3d interpolatedVectorValuesAlongWellPath(const std::vector& vectors, double measuredDepth, double * horizontalLengthAlongWellToStartClipPoint = nullptr) const; cvf::Vec3d interpolatedPointAlongWellPath(double measuredDepth, @@ -66,9 +70,6 @@ class RigWellPath : public cvf::Object double maxZ, double * horizontalLengthAlongWellToClipPoint, size_t * indexToFirstVisibleSegment); - const std::vector& wellPathPoints() const; - const std::vector& measureDepths() const; - private: bool m_hasDatumElevation; double m_datumElevation; diff --git a/ApplicationCode/ReservoirDataModel/RigWellPathFormations.cpp b/ApplicationCode/ReservoirDataModel/RigWellPathFormations.cpp index 3ecb300e73..830a30e5b5 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPathFormations.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellPathFormations.cpp @@ -414,8 +414,6 @@ RigWellPathFormations::FormationLevel RigWellPathFormations::detectLevel(QString int dotCount = levelDescriptor.count('.'); - size_t level = dotCount + 1; - switch (dotCount) { case 0: return RigWellPathFormations::LEVEL1; diff --git a/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.cpp b/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.cpp index bdd4b033b4..c4cdbabbd2 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellPathGeometryTools.cpp @@ -38,14 +38,16 @@ std::vector RigWellPathGeometryTools::calculateLineSegmentNormals(co pointNormals.reserve(vertices.size()); - cvf::Vec3d up(0, 0, 1); + const cvf::Vec3d up(0, 0, 1); + const cvf::Vec3d rotatedUp = up.getTransformedVector(cvf::Mat3d::fromRotation(cvf::Vec3d(0.0, 1.0, 0.0), planeAngle)); - cvf::Vec3d dominantDirection = estimateDominantDirectionInXYPlane(vertices); + + const cvf::Vec3d dominantDirection = estimateDominantDirectionInXYPlane(vertices); const cvf::Vec3d projectionPlaneNormal = (up ^ dominantDirection).getNormalized(); CVF_ASSERT(projectionPlaneNormal * dominantDirection <= std::numeric_limits::epsilon()); - cvf::Vec3d lastNormal; + double sumDotWithRotatedUp = 0.0; for (size_t i = 0; i < vertices.size() - 1; ++i) { cvf::Vec3d p1 = vertices[i]; @@ -60,10 +62,19 @@ std::vector RigWellPathGeometryTools::calculateLineSegmentNormals(co normal = normal.getTransformedVector(cvf::Mat3d::fromRotation(tangent, planeAngle)); } pointNormals.push_back(normal); - lastNormal = normal; + sumDotWithRotatedUp += normal * rotatedUp; + } + + pointNormals.push_back(pointNormals.back()); + + if (sumDotWithRotatedUp < 0.0) + { + for (cvf::Vec3d& normal : pointNormals) + { + normal *= -1.0; + } } - pointNormals.push_back(lastNormal); return interpolateUndefinedNormals(up, pointNormals, vertices); } @@ -73,7 +84,8 @@ std::vector RigWellPathGeometryTools::interpolateUndefinedNormals(co const std::vector& vertices) { std::vector interpolated(normals); - cvf::Vec3d lastNormal(0, 0, 0); + cvf::Vec3d lastNormalNonInterpolated(0, 0, 0); + cvf::Vec3d lastNormalAny(0, 0, 0); double distanceFromLast = 0.0; for (size_t i = 0; i < normals.size(); ++i) @@ -98,29 +110,30 @@ std::vector RigWellPathGeometryTools::interpolateUndefinedNormals(co distanceToNext += (vertices[j] - vertices[j - 1]).length(); } - if (lastNormal.length() > 0.0 && nextNormal.length() > 0.0) + if (lastNormalNonInterpolated.length() > 0.0 && nextNormal.length() > 0.0) { // Both last and next are acceptable, interpolate! - currentNormal = (distanceToNext * lastNormal + distanceFromLast * nextNormal).getNormalized(); + currentNormal = (distanceToNext * lastNormalNonInterpolated + distanceFromLast * nextNormal).getNormalized(); } - else if (lastNormal.length() > 0.0) + else if (lastNormalNonInterpolated.length() > 0.0) { - currentNormal = lastNormal; + currentNormal = lastNormalNonInterpolated; } else if (nextNormal.length() > 0.0) { currentNormal = nextNormal; } } - if (i > 0 && currentNormal * lastNormal < -std::numeric_limits::epsilon()) + if (i > 0 && currentNormal * lastNormalAny < -std::numeric_limits::epsilon()) { currentNormal *= -1.0; } if (!currentInterpolated) { - lastNormal = currentNormal; + lastNormalNonInterpolated = currentNormal; distanceFromLast = 0.0; // Reset distance } + lastNormalAny = currentNormal; interpolated[i] = currentNormal; } return interpolated; diff --git a/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.cpp b/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.cpp index ed05ffae6c..178a7b2616 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellPathIntersectionTools.cpp @@ -39,7 +39,6 @@ std::vector RigWellPathIntersectionTools::findCell const std::vector& pathMds) { std::vector intersectionInfos; - const RigMainGrid* grid = caseData->mainGrid(); if (pathCoords.size() < 2) return intersectionInfos; diff --git a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp index f316e305ca..1214a187cd 100644 --- a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp +++ b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.cpp @@ -201,7 +201,6 @@ GeometryTools::IntersectionStatus inPlaneLineIntersect( if (length12 < EPS ) { - cvf::Vec3d p34(x4-x3, y4-y3, 0); *x = x1; *y = y1; *fractionAlongLine1 = 1; @@ -429,8 +428,8 @@ int GeometryTools::intersectLineSegmentTriangle( const cvf::Vec3d p0, const cvf: const cvf::Vec3d t0, const cvf::Vec3d t1, const cvf::Vec3d t2, cvf::Vec3d* intersectionPoint , bool * isLineDirDotNormalNegative) { - CVF_TIGHT_ASSERT(intersectionPoint != NULL); - CVF_TIGHT_ASSERT(isLineDirDotNormalNegative != NULL); + CVF_TIGHT_ASSERT(intersectionPoint != nullptr); + CVF_TIGHT_ASSERT(isLineDirDotNormalNegative != nullptr); cvf::Vec3d u, v, n; // triangle vectors cvf::Vec3d dir, w0, w; // ray vectors @@ -589,20 +588,6 @@ cvf::Vec4d GeometryTools::barycentricCoords(const cvf::Vec3d& v0, return w; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -double GeometryTools::interpolateQuad(const cvf::Vec3d& v1, double s1, - const cvf::Vec3d& v2, double s2, - const cvf::Vec3d& v3, double s3, - const cvf::Vec3d& v4, double s4, - const cvf::Vec3d& point) -{ - cvf::Vec4d bc = barycentricCoords(v1, v2, v3, v4, point); - - return s1*bc[0] + s2*bc[1] + s3*bc[2] + s4*bc[3]; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -996,14 +981,6 @@ FanEarClipTesselator::FanEarClipTesselator() : } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void FanEarClipTesselator::setCenterNode(size_t centerNodeIndex) -{ - m_centerNodeIndex = centerNodeIndex; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h index 8722f13259..a96c366e0b 100644 --- a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h +++ b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.h @@ -47,11 +47,12 @@ class GeometryTools bool * isLineDirDotNormalNegative); static cvf::Vec3d barycentricCoords(const cvf::Vec3d& t0, const cvf::Vec3d& t1, const cvf::Vec3d& t2, const cvf::Vec3d& p); static cvf::Vec4d barycentricCoords(const cvf::Vec3d& v0, const cvf::Vec3d& v1, const cvf::Vec3d& v2, const cvf::Vec3d& v3, const cvf::Vec3d& p); - static double interpolateQuad(const cvf::Vec3d& v1, double s1, - const cvf::Vec3d& v2, double s2, - const cvf::Vec3d& v3, double s3, - const cvf::Vec3d& v4, double s4, - const cvf::Vec3d& point); + template + static DataType interpolateQuad(const cvf::Vec3d& v1, DataType s1, + const cvf::Vec3d& v2, DataType s2, + const cvf::Vec3d& v3, DataType s3, + const cvf::Vec3d& v4, DataType s4, + const cvf::Vec3d& point); static int findClosestAxis(const cvf::Vec3d& vec ); static double getAngle(const cvf::Vec3d& positiveNormalAxis, const cvf::Vec3d& v1, const cvf::Vec3d& v2); @@ -186,9 +187,8 @@ class FanEarClipTesselator : public EarClipTesselator { public: FanEarClipTesselator(); - void setCenterNode(size_t centerNodeIndex ); - virtual bool calculateTriangles(std::vector* triangles); + bool calculateTriangles(std::vector* triangles) override; private: bool isTriangleValid( size_t u, size_t v, size_t w); size_t m_centerNodeIndex; diff --git a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl index b1ecbebecd..e1d517395d 100644 --- a/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl +++ b/ApplicationCode/ReservoirDataModel/cvfGeometryTools.inl @@ -24,6 +24,22 @@ namespace cvf { + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +DataType GeometryTools::interpolateQuad(const cvf::Vec3d& v1, DataType s1, + const cvf::Vec3d& v2, DataType s2, + const cvf::Vec3d& v3, DataType s3, + const cvf::Vec3d& v4, DataType s4, + const cvf::Vec3d& point) +{ + cvf::Vec4d bc = barycentricCoords(v1, v2, v3, v4, point); + + return s1 * bc[0] + s2 * bc[1] + s3 * bc[2] + s4 * bc[3]; +} + //-------------------------------------------------------------------------------------------------- /// Inserts the vertex into the polygon if it fits along one of the edges within the tolerance. /// The method returns true if it was inserted, or if it was already in the polygon, or if it was diff --git a/ApplicationCode/Resources/2DMap16x16.png b/ApplicationCode/Resources/2DMap16x16.png new file mode 100644 index 0000000000..63fa2ca553 Binary files /dev/null and b/ApplicationCode/Resources/2DMap16x16.png differ diff --git a/ApplicationCode/Resources/2DMaps16x16.png b/ApplicationCode/Resources/2DMaps16x16.png new file mode 100644 index 0000000000..6c842a6a9b Binary files /dev/null and b/ApplicationCode/Resources/2DMaps16x16.png differ diff --git a/ApplicationCode/Resources/AICDValve16x16.png b/ApplicationCode/Resources/AICDValve16x16.png new file mode 100644 index 0000000000..ab767fc34b Binary files /dev/null and b/ApplicationCode/Resources/AICDValve16x16.png differ diff --git a/ApplicationCode/Resources/CasingDesign16x16.png b/ApplicationCode/Resources/CasingDesign16x16.png new file mode 100644 index 0000000000..1cac96aa19 Binary files /dev/null and b/ApplicationCode/Resources/CasingDesign16x16.png differ diff --git a/ApplicationCode/Resources/EditableWell.png b/ApplicationCode/Resources/EditableWell.png new file mode 100644 index 0000000000..55cefe214a Binary files /dev/null and b/ApplicationCode/Resources/EditableWell.png differ diff --git a/ApplicationCode/Resources/ExportCompletionsSymbol16x16.png b/ApplicationCode/Resources/ExportCompletionsSymbol16x16.png new file mode 100644 index 0000000000..99c766582f Binary files /dev/null and b/ApplicationCode/Resources/ExportCompletionsSymbol16x16.png differ diff --git a/ApplicationCode/Resources/ICDValve16x16.png b/ApplicationCode/Resources/ICDValve16x16.png new file mode 100644 index 0000000000..a30294cae1 Binary files /dev/null and b/ApplicationCode/Resources/ICDValve16x16.png differ diff --git a/ApplicationCode/Resources/ICVValve16x16.png b/ApplicationCode/Resources/ICVValve16x16.png new file mode 100644 index 0000000000..53893d84e8 Binary files /dev/null and b/ApplicationCode/Resources/ICVValve16x16.png differ diff --git a/ApplicationCode/Resources/LGR16x16.png b/ApplicationCode/Resources/LGR16x16.png new file mode 100644 index 0000000000..3e2761e0f5 Binary files /dev/null and b/ApplicationCode/Resources/LGR16x16.png differ diff --git a/ApplicationCode/Resources/MainGrid16x16.png b/ApplicationCode/Resources/MainGrid16x16.png new file mode 100644 index 0000000000..7a80832202 Binary files /dev/null and b/ApplicationCode/Resources/MainGrid16x16.png differ diff --git a/ApplicationCode/Resources/ResInsight.qrc b/ApplicationCode/Resources/ResInsight.qrc index 1973989f83..2441691d61 100644 --- a/ApplicationCode/Resources/ResInsight.qrc +++ b/ApplicationCode/Resources/ResInsight.qrc @@ -18,6 +18,8 @@ Minus.png Save.png Well.png + EditableWell.png + WellTargets.png WellCollection.png octave.png OctaveScriptFile16x16.png @@ -118,6 +120,26 @@ SplitterV.png calculator.png statistics.png + WellTargetPoint16x16.png + WellTargetPointTangent16x16.png + hololens.png + minus-sign-red.png + plus-sign-green.png + arrow-right-green.png + 2DMap16x16.png + 2DMaps16x16.png + AICDValve16x16.png + ICDValve16x16.png + ICVValve16x16.png + CasingDesign16x16.png + LGR16x16.png + MainGrid16x16.png + TempLGR16x16.png + ToggleOff16x16.png + ToggleOn16x16.png + ToggleOnOff16x16.png + ToggleOnOthersOff16x16.png + ExportCompletionsSymbol16x16.png fs_CellFace.glsl diff --git a/ApplicationCode/Resources/TempLGR16x16.png b/ApplicationCode/Resources/TempLGR16x16.png new file mode 100644 index 0000000000..84d9fe2f24 Binary files /dev/null and b/ApplicationCode/Resources/TempLGR16x16.png differ diff --git a/ApplicationCode/Resources/ToggleOff16x16.png b/ApplicationCode/Resources/ToggleOff16x16.png new file mode 100644 index 0000000000..19830a105a Binary files /dev/null and b/ApplicationCode/Resources/ToggleOff16x16.png differ diff --git a/ApplicationCode/Resources/ToggleOn16x16.png b/ApplicationCode/Resources/ToggleOn16x16.png new file mode 100644 index 0000000000..e5127a8344 Binary files /dev/null and b/ApplicationCode/Resources/ToggleOn16x16.png differ diff --git a/ApplicationCode/Resources/ToggleOnOff16x16.png b/ApplicationCode/Resources/ToggleOnOff16x16.png new file mode 100644 index 0000000000..217b744556 Binary files /dev/null and b/ApplicationCode/Resources/ToggleOnOff16x16.png differ diff --git a/ApplicationCode/Resources/ToggleOnOthersOff16x16.png b/ApplicationCode/Resources/ToggleOnOthersOff16x16.png new file mode 100644 index 0000000000..eb92a8baed Binary files /dev/null and b/ApplicationCode/Resources/ToggleOnOthersOff16x16.png differ diff --git a/ApplicationCode/Resources/WellTargetPoint16x16.png b/ApplicationCode/Resources/WellTargetPoint16x16.png new file mode 100644 index 0000000000..c7361dd13a Binary files /dev/null and b/ApplicationCode/Resources/WellTargetPoint16x16.png differ diff --git a/ApplicationCode/Resources/WellTargetPointTangent16x16.png b/ApplicationCode/Resources/WellTargetPointTangent16x16.png new file mode 100644 index 0000000000..6e577d39b3 Binary files /dev/null and b/ApplicationCode/Resources/WellTargetPointTangent16x16.png differ diff --git a/ApplicationCode/Resources/WellTargets.png b/ApplicationCode/Resources/WellTargets.png new file mode 100644 index 0000000000..df0379467b Binary files /dev/null and b/ApplicationCode/Resources/WellTargets.png differ diff --git a/ApplicationCode/Resources/arrow-right-green.png b/ApplicationCode/Resources/arrow-right-green.png new file mode 100644 index 0000000000..cc9f9b22b8 Binary files /dev/null and b/ApplicationCode/Resources/arrow-right-green.png differ diff --git a/ApplicationCode/Resources/hololens.png b/ApplicationCode/Resources/hololens.png new file mode 100644 index 0000000000..a30781563e Binary files /dev/null and b/ApplicationCode/Resources/hololens.png differ diff --git a/ApplicationCode/Resources/minus-sign-red.png b/ApplicationCode/Resources/minus-sign-red.png new file mode 100644 index 0000000000..2c1fc25e08 Binary files /dev/null and b/ApplicationCode/Resources/minus-sign-red.png differ diff --git a/ApplicationCode/Resources/plus-sign-green.png b/ApplicationCode/Resources/plus-sign-green.png new file mode 100644 index 0000000000..f0f33c46a6 Binary files /dev/null and b/ApplicationCode/Resources/plus-sign-green.png differ diff --git a/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.cpp b/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.cpp index 3ad923335c..08c16ad958 100644 --- a/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.cpp +++ b/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.cpp @@ -42,7 +42,7 @@ void RigStatisticsMath::calculateBasicStatistics(const std::vector& valu for (size_t i = 0; i < values.size(); i++) { double val = values[i]; - if (val == HUGE_VAL) continue; + if (RiaStatisticsTools::isInvalidNumber(val)) continue; validValueCount++; @@ -57,7 +57,6 @@ void RigStatisticsMath::calculateBasicStatistics(const std::vector& valu { m_mean = m_sum / validValueCount; - // http://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods // Running standard deviation @@ -91,7 +90,7 @@ std::vector RigStatisticsMath::calculateNearestRankPercentiles(const std for (size_t i = 0; i < inputValues.size(); ++i) { - if (inputValues[i] != HUGE_VAL) + if (RiaStatisticsTools::isValidNumber(inputValues[i])) { sortedValues.push_back(inputValues[i]); } @@ -130,7 +129,7 @@ std::vector RigStatisticsMath::calculateInterpolatedPercentiles(const st for (size_t i = 0; i < inputValues.size(); ++i) { - if (inputValues[i] != HUGE_VAL) + if (RiaStatisticsTools::isValidNumber(inputValues[i])) { sortedValues.push_back(inputValues[i]); } @@ -195,10 +194,7 @@ RigHistogramCalculator::RigHistogramCalculator(double min, double max, size_t nB //-------------------------------------------------------------------------------------------------- void RigHistogramCalculator::addValue(double value) { - if (value == HUGE_VAL || value != value) - { - return; - } + if (RiaStatisticsTools::isInvalidNumber(value)) return; size_t index = 0; @@ -262,5 +258,6 @@ double RigHistogramCalculator::calculatePercentil(double pVal) } } assert(false); + return HUGE_VAL; } diff --git a/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.h b/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.h index e583533b9c..042c058c27 100644 --- a/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.h +++ b/ApplicationCode/ResultStatisticsCache/RigStatisticsMath.h @@ -17,6 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once +#include "RiaStatisticsTools.h" + #include #include #include @@ -82,19 +84,17 @@ class MinMaxAccumulator void addValue(double value) { - if (value == HUGE_VAL) // TODO - { - return; - } - - if (value < min) + if (RiaStatisticsTools::isValidNumber(value)) { - min = value; - } - - if (value > max) - { - max = value; + if (value < min) + { + min = value; + } + + if (value > max) + { + max = value; + } } } @@ -126,19 +126,17 @@ class PosNegAccumulator void addValue(double value) { - if (value == HUGE_VAL) - { - return; - } - - if (value < pos && value > 0) - { - pos = value; - } - - if (value > neg && value < 0) + if (RiaStatisticsTools::isValidNumber(value)) { - neg = value; + if (value < pos && value > 0) + { + pos = value; + } + + if (value > neg && value < 0) + { + neg = value; + } } } @@ -170,13 +168,11 @@ class SumCountAccumulator void addValue(double value) { - if (value == HUGE_VAL || value != value) + if (RiaStatisticsTools::isValidNumber(value)) { - return; + valueSum += value; + ++sampleCount; } - - valueSum += value; - ++sampleCount; } double valueSum; @@ -208,7 +204,10 @@ class UniqueValueAccumulator void addValue(double value) { - uniqueValues.insert(static_cast(value)); + if (RiaStatisticsTools::isValidNumber(value)) + { + uniqueValues.insert(static_cast(value)); + } } std::set uniqueValues; diff --git a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp index 851cc99adf..24ab4caf6b 100644 --- a/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaCaseInfoCommands.cpp @@ -50,6 +50,8 @@ #include +#include + @@ -61,7 +63,7 @@ class RiaGetMainGridDimensions: public RiaSocketCommand public: static QString commandName () { return QString("GetMainGridDimensions"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); @@ -98,7 +100,7 @@ class RiaGetActiveCellInfo: public RiaSocketCommand public: static QString commandName () { return QString("GetActiveCellInfo"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); if (!rimCase) return true; @@ -116,7 +118,7 @@ class RiaGetActiveCellInfo: public RiaSocketCommand // Write data back to octave: columnCount, bytesPrTimestep, GridNr I J K ParentGridNr PI PJ PK CoarseBoxIdx - caf::FixedArray, 9> activeCellInfo; + std::array, 9> activeCellInfo; if (!(rimCase && rimCase->eclipseCaseData() && rimCase->eclipseCaseData()->mainGrid()) ) { // No data available @@ -268,7 +270,7 @@ class RiaGetCoarseningInfo : public RiaSocketCommand public: static QString commandName () { return QString("GetCoarseningInfo"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int argCaseGroupId = -1; @@ -340,7 +342,7 @@ class RiaGetGridDimensions : public RiaSocketCommand public: static QString commandName () { return QString("GetGridDimensions"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int argCaseGroupId = -1; @@ -399,7 +401,7 @@ class RiaGetTimeStepDates : public RiaSocketCommand { public: static QString commandName () { return QString("GetTimeStepDates"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int argCaseGroupId = -1; @@ -486,7 +488,7 @@ class RiaGetTimeStepDays : public RiaSocketCommand { public: static QString commandName () { return QString("GetTimeStepDays"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int argCaseGroupId = -1; @@ -554,7 +556,7 @@ class RiaGetSelectedCells: public RiaSocketCommand public: static QString commandName () { return QString("GetSelectedCells"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { // findCaseFromArgs only returns RimEclipseCase, so geomech cases are not supported because of this. // The rest of the function supports geomech cases, so using a findCaseFromArgs that supports geomech @@ -604,6 +606,7 @@ class RiaGetSelectedCells: public RiaSocketCommand size_t i, j, k; size_t gridIndex; int caseId; + bool validIndex = true; if (item->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT) { const RiuEclipseSelectionItem* eclipseItem = static_cast(item); @@ -615,8 +618,8 @@ class RiaGetSelectedCells: public RiaSocketCommand else if (item->type() == RiuSelectionItem::GEOMECH_SELECTION_OBJECT) { const RiuGeoMechSelectionItem* geomechItem = static_cast(item); - - geomechItem->m_view->femParts()->part(geomechItem->m_gridIndex)->structGrid()->ijkFromCellIndex(geomechItem->m_cellIndex, &i, &j, &k); + validIndex = geomechItem->m_view->femParts()->part(geomechItem->m_gridIndex)->getOrCreateStructGrid()->ijkFromCellIndex(geomechItem->m_cellIndex, &i, &j, &k); + CVF_ASSERT(validIndex); gridIndex = geomechItem->m_gridIndex; caseId = geomechItem->m_view->geoMechCase()->caseId; } @@ -625,7 +628,7 @@ class RiaGetSelectedCells: public RiaSocketCommand continue; } - if (caseId == reservoirCase->caseId) + if (caseId == reservoirCase->caseId && validIndex) { caseNumber.push_back(static_cast(caseId)); gridNumber.push_back(static_cast(gridIndex)); diff --git a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp index 746cc179f5..09f1284037 100644 --- a/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaGeometryCommands.cpp @@ -75,7 +75,7 @@ class RiaGetCellCenters : public RiaSocketCommand public: static QString commandName () { return QString("GetCellCenters"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); size_t argGridIndex = args[2].toUInt(); @@ -158,7 +158,7 @@ class RiaGetActiveCellCenters : public RiaSocketCommand public: static QString commandName () { return QString("GetActiveCellCenters"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); @@ -240,7 +240,7 @@ class RiaGetCellCorners : public RiaSocketCommand public: static QString commandName () { return QString("GetCellCorners"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); size_t argGridIndex = args[2].toUInt(); @@ -329,7 +329,7 @@ class RiaGetActiveCellCorners : public RiaSocketCommand public: static QString commandName () { return QString("GetActiveCellCorners"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); diff --git a/ApplicationCode/SocketInterface/RiaNNCCommands.cpp b/ApplicationCode/SocketInterface/RiaNNCCommands.cpp index c006605691..1948c05051 100644 --- a/ApplicationCode/SocketInterface/RiaNNCCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaNNCCommands.cpp @@ -54,7 +54,7 @@ class RiaGetNNCConnections: public RiaSocketCommand public: static QString commandName () { return QString("GetNNCConnections"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); // Write data back to octave: columnCount, GridNr I J K GridNr I J K @@ -105,7 +105,7 @@ class RiaGetDynamicNNCValues: public RiaSocketCommand public: static QString commandName () { return QString("GetDynamicNNCValues"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); // Write data back to octave: connectionCount, timeStepCount, property values @@ -186,7 +186,7 @@ class RiaGetStaticNNCValues: public RiaSocketCommand public: static QString commandName () { return QString("GetStaticNNCValues"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); QString propertyName = args[2]; @@ -228,7 +228,7 @@ class RiaGetNNCPropertyNames: public RiaSocketCommand public: static QString commandName () { return QString("GetNNCPropertyNames"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); @@ -309,7 +309,7 @@ class RiaSetNNCProperty: public RiaSocketCommand static QString commandName () { return QString("SetNNCProperty"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); @@ -443,7 +443,7 @@ class RiaSetNNCProperty: public RiaSocketCommand return false; } - virtual bool interpretMore(RiaSocketServer* server, QTcpSocket* currentClient) + bool interpretMore(RiaSocketServer* server, QTcpSocket* currentClient) override { if (m_invalidConnectionCountDetected) return true; @@ -521,15 +521,15 @@ class RiaSetNNCProperty: public RiaSocketCommand RimEclipseInputCase* inputRes = dynamic_cast(m_currentReservoir); if (inputRes) { - RimEclipseInputProperty* inputProperty = inputRes->m_inputPropertyCollection->findInputProperty(m_currentPropertyName); + RimEclipseInputProperty* inputProperty = inputRes->inputPropertyCollection()->findInputProperty(m_currentPropertyName); if (!inputProperty) { inputProperty = new RimEclipseInputProperty; inputProperty->resultName = m_currentPropertyName; inputProperty->eclipseKeyword = ""; inputProperty->fileName = ""; - inputRes->m_inputPropertyCollection->inputProperties.push_back(inputProperty); - inputRes->m_inputPropertyCollection()->updateConnectedEditors(); + inputRes->inputPropertyCollection()->inputProperties.push_back(inputProperty); + inputRes->inputPropertyCollection()->updateConnectedEditors(); } inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED_NOT_SAVED; } diff --git a/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp b/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp index 3db077693b..92d0df87fc 100644 --- a/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaProjectInfoCommands.cpp @@ -76,7 +76,7 @@ class RiaGetCurrentCase : public RiaSocketCommand { public: static QString commandName () { return QString("GetCurrentCase"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { qint64 caseId = server->currentCaseId(); QString caseName; @@ -119,7 +119,7 @@ class RiaGetSelectedCases: public RiaSocketCommand public: static QString commandName () { return QString("GetSelectedCases"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { { std::vector cases; @@ -168,7 +168,7 @@ class RiaGetCaseGroups : public RiaSocketCommand { public: static QString commandName () { return QString("GetCaseGroups"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimProject* proj = RiaApplication::instance()->project(); RimEclipseCaseCollection* analysisModels = (proj && proj->activeOilField()) ? proj->activeOilField()->analysisModels() : nullptr; @@ -226,7 +226,7 @@ class RiaGetCases : public RiaSocketCommand public: static QString commandName () { return QString("GetCases"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int argCaseGroupId = -1; diff --git a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp index fe13dadc8c..7dae447c82 100644 --- a/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaPropertyDataCommands.cpp @@ -58,7 +58,7 @@ class RiaGetActiveCellProperty: public RiaSocketCommand public: static QString commandName () { return QString("GetActiveCellProperty"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); @@ -222,7 +222,7 @@ class RiaGetGridProperty: public RiaSocketCommand public: static QString commandName () { return QString("GetGridProperty"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int caseId = args[1].toInt(); int gridIdx = args[2].toInt(); @@ -394,7 +394,7 @@ class RiaSetActiveCellProperty: public RiaSocketCommand static QString commandName () { return QString("SetActiveCellProperty"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); @@ -510,7 +510,7 @@ class RiaSetActiveCellProperty: public RiaSocketCommand return false; } - virtual bool interpretMore(RiaSocketServer* server, QTcpSocket* currentClient) + bool interpretMore(RiaSocketServer* server, QTcpSocket* currentClient) override { // std::cout << "RiaSetActiveCellProperty, interpretMore: scalarIndex : " << m_currentScalarIndex; @@ -641,15 +641,15 @@ class RiaSetActiveCellProperty: public RiaSocketCommand RimEclipseInputCase* inputRes = dynamic_cast(m_currentReservoir); if (inputRes) { - RimEclipseInputProperty* inputProperty = inputRes->m_inputPropertyCollection->findInputProperty(m_currentPropertyName); + RimEclipseInputProperty* inputProperty = inputRes->inputPropertyCollection()->findInputProperty(m_currentPropertyName); if (!inputProperty) { inputProperty = new RimEclipseInputProperty; inputProperty->resultName = m_currentPropertyName; inputProperty->eclipseKeyword = ""; inputProperty->fileName = ""; - inputRes->m_inputPropertyCollection->inputProperties.push_back(inputProperty); - inputRes->m_inputPropertyCollection()->updateConnectedEditors(); + inputRes->inputPropertyCollection()->inputProperties.push_back(inputProperty); + inputRes->inputPropertyCollection()->updateConnectedEditors(); } inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED_NOT_SAVED; } @@ -741,7 +741,7 @@ class RiaSetGridProperty : public RiaSocketCommand static QString commandName () { return QString("SetGridProperty"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int caseId = args[1].toInt(); RimEclipseCase* rimCase = server->findReservoir(caseId); @@ -887,7 +887,7 @@ class RiaSetGridProperty : public RiaSocketCommand return false; } - virtual bool interpretMore(RiaSocketServer* server, QTcpSocket* currentClient) + bool interpretMore(RiaSocketServer* server, QTcpSocket* currentClient) override { if (m_invalidDataDetected){ @@ -1005,15 +1005,15 @@ class RiaSetGridProperty : public RiaSocketCommand RimEclipseInputCase* inputRes = dynamic_cast(m_currentReservoir); if (inputRes) { - RimEclipseInputProperty* inputProperty = inputRes->m_inputPropertyCollection->findInputProperty(m_currentPropertyName); + RimEclipseInputProperty* inputProperty = inputRes->inputPropertyCollection()->findInputProperty(m_currentPropertyName); if (!inputProperty) { inputProperty = new RimEclipseInputProperty; inputProperty->resultName = m_currentPropertyName; inputProperty->eclipseKeyword = ""; inputProperty->fileName = ""; - inputRes->m_inputPropertyCollection->inputProperties.push_back(inputProperty); - inputRes->m_inputPropertyCollection()->updateConnectedEditors(); + inputRes->inputPropertyCollection()->inputProperties.push_back(inputProperty); + inputRes->inputPropertyCollection()->updateConnectedEditors(); } inputProperty->resolvedState = RimEclipseInputProperty::RESOLVED_NOT_SAVED; } @@ -1094,7 +1094,7 @@ class RiaGetPropertyNames : public RiaSocketCommand public: static QString commandName () { return QString("GetPropertyNames"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int caseId = args[1].toInt(); RimEclipseCase* rimCase = server->findReservoir(caseId); @@ -1180,7 +1180,7 @@ class RiaGetGridPropertyForSelectedCells: public RiaSocketCommand public: static QString commandName() { return QString("GetGridPropertyForSelectedCells"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); if (!rimCase) return true; @@ -1261,9 +1261,6 @@ class RiaGetGridPropertyForSelectedCells: public RiaSocketCommand for (size_t timeStep : requestedTimesteps) { - const std::vector& scalarResults = rimCase->results(porosityModel)->cellScalarResults(scalarResultIndex, timeStep); - - for (const std::pair selectedCell : selectedCells) { cvf::ref resultAccessor = RigResultAccessorFactory::createFromUiResultName(rimCase->eclipseCaseData(), selectedCell.first, porosityModel, timeStep, propertyName); diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.cpp b/ApplicationCode/SocketInterface/RiaSocketServer.cpp index ff12893afe..9a75a92faa 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.cpp +++ b/ApplicationCode/SocketInterface/RiaSocketServer.cpp @@ -82,7 +82,7 @@ RiaSocketServer::RiaSocketServer(QObject* parent) //-------------------------------------------------------------------------------------------------- RiaSocketServer::~RiaSocketServer() { - assert (m_currentCommand == NULL); + assert (m_currentCommand == nullptr); } //-------------------------------------------------------------------------------------------------- @@ -136,10 +136,10 @@ RimEclipseCase* RiaSocketServer::findReservoir(int caseId) if (currCaseId < 0) { - RimEclipseView* riv = dynamic_cast(RiaApplication::instance()->activeReservoirView()); - if (riv) + RimEclipseView* eclipseView = dynamic_cast(RiaApplication::instance()->activeReservoirView()); + if (eclipseView) { - return riv->eclipseCase(); + return eclipseView->eclipseCase(); } // If the active mdi window is different from an Eclipse view, search through available mdi windows to find the last activated diff --git a/ApplicationCode/SocketInterface/RiaSocketServer.h b/ApplicationCode/SocketInterface/RiaSocketServer.h index c556cbebc8..5a76ed119d 100644 --- a/ApplicationCode/SocketInterface/RiaSocketServer.h +++ b/ApplicationCode/SocketInterface/RiaSocketServer.h @@ -48,7 +48,7 @@ class RiaSocketServer : public QObject public: explicit RiaSocketServer(QObject *parent = nullptr); - ~RiaSocketServer(); + ~RiaSocketServer() override; unsigned short serverPort(); RimEclipseCase* findReservoir(int caseId); diff --git a/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp b/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp index 00a13d926e..747004997f 100644 --- a/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp +++ b/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp @@ -42,7 +42,7 @@ class RiaGetWellNames : public RiaSocketCommand public: static QString commandName () { return QString("GetWellNames"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int caseId = args[1].toInt(); RimEclipseCase* rimCase = server->findReservoir(caseId); @@ -94,7 +94,7 @@ class RiaGetWellStatus : public RiaSocketCommand public: static QString commandName () { return QString("GetWellStatus"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int caseId = args[1].toInt(); QString wellName = args[2]; @@ -232,7 +232,7 @@ class RiaGetWellCells : public RiaSocketCommand public: static QString commandName () { return QString("GetWellCells"); } - virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) override { int caseId = args[1].toInt(); QString wellName = args[2]; diff --git a/ApplicationCode/UnitTests/CMakeLists_files.cmake b/ApplicationCode/UnitTests/CMakeLists_files.cmake index dacb8749a3..e9b22f7853 100644 --- a/ApplicationCode/UnitTests/CMakeLists_files.cmake +++ b/ApplicationCode/UnitTests/CMakeLists_files.cmake @@ -42,6 +42,16 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaEclipseUnitTools-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RiaTextFileCompare-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RifCaseRealizationParametersReader-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellLogExtractor-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/RifEclipseSummaryAddress-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveTools-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/SolveSpaceSolver-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/RiaPolyArcLineSampler-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/RifEclipseDataTableFormatter-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/RiaWeightedMean-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/RiaWeightedGeometricMeanCalculator-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/RiaWeightedHarmonicMeanCalculator-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/RiaCellDividingTools-Test.cpp +${CMAKE_CURRENT_LIST_DIR}/Intersect-Test.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/UnitTests/Intersect-Test.cpp b/ApplicationCode/UnitTests/Intersect-Test.cpp new file mode 100644 index 0000000000..376966165c --- /dev/null +++ b/ApplicationCode/UnitTests/Intersect-Test.cpp @@ -0,0 +1,43 @@ +#include "gtest/gtest.h" + +#include "RifEclipseOutputFileTools.h" + +#include + +#include "ert/ecl/ecl_file.h" +#include "ert/ecl/ecl_kw_magic.h" +#include "ert/ecl/ecl_kw.hpp" + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(IntersectDataImport, DISABLED_TestImportPORV) +{ + QString baseFolder = "d:/Models/Statoil/IX_output_files/"; + QString filename = baseFolder + "NORNE_IX2.INIT"; + + std::string porv_kw("PORV"); + + ecl_file_type* ecl_file = ecl_file_open(filename.toStdString().data(), ECL_FILE_CLOSE_STREAM); + + bool isIntersect = RifEclipseOutputFileTools::isExportedFromIntersect(ecl_file); + EXPECT_TRUE(isIntersect); + + if (ecl_file_has_kw(ecl_file, porv_kw.data())) + { + ecl_file_load_all(ecl_file); + + int keywordCount = ecl_file_get_num_named_kw(ecl_file, porv_kw.data()); + for (int index = 0; index < keywordCount; index++) + { + auto fileKeyword = ecl_file_iget_named_file_kw(ecl_file, porv_kw.data(), index); + + float porvThreshold = 0.0f; + auto actnumFromPorv = ecl_kw_alloc_actnum(ecl_file_kw_get_kw_ptr(fileKeyword), porvThreshold); + + EXPECT_TRUE(actnumFromPorv != nullptr); + } + } +} diff --git a/ApplicationCode/UnitTests/ListKeywordsForObjectsAndFields-Test.cpp b/ApplicationCode/UnitTests/ListKeywordsForObjectsAndFields-Test.cpp index 58f3d21b1f..43aa9bd7af 100644 --- a/ApplicationCode/UnitTests/ListKeywordsForObjectsAndFields-Test.cpp +++ b/ApplicationCode/UnitTests/ListKeywordsForObjectsAndFields-Test.cpp @@ -16,7 +16,7 @@ void writeTextToFile(const QString& filePath, const QString& text) { QFile exportFile(filePath); - if (exportFile.open(QIODevice::WriteOnly)) + if (exportFile.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream stream(&exportFile); diff --git a/ApplicationCode/UnitTests/ObservedDataParser-Test.cpp b/ApplicationCode/UnitTests/ObservedDataParser-Test.cpp index f75ad54b31..6b54ae4087 100644 --- a/ApplicationCode/UnitTests/ObservedDataParser-Test.cpp +++ b/ApplicationCode/UnitTests/ObservedDataParser-Test.cpp @@ -36,7 +36,7 @@ TEST(RifColumnBasedAsciiParserTest, TestDateFormatYyyymmddWithDash) ASSERT_TRUE(parser.parse(parseOptions)); ASSERT_TRUE(parser.dateTimeColumn() != nullptr); - std::vector timeSteps = parser.dateTimeColumn()->dateTimeValues; + std::vector timeSteps = parser.dateTimeColumn()->qDateTimeValues(); ASSERT_EQ(size_t(4), timeSteps.size()); EXPECT_EQ("1993-02-23", timeSteps[0].toString(parseOptions.dateFormat).toStdString()); @@ -69,7 +69,7 @@ TEST(RifColumnBasedAsciiParserTest, TestDateFormatYymmddWithDot) ASSERT_TRUE(parser.parse(parseOptions)); ASSERT_TRUE(parser.dateTimeColumn() != nullptr); - std::vector timeSteps = parser.dateTimeColumn()->dateTimeValues; + std::vector timeSteps = parser.dateTimeColumn()->qDateTimeValues(); ASSERT_EQ(size_t(4), timeSteps.size()); EXPECT_EQ("93.02.23", timeSteps[0].toString(parseOptions.dateFormat).toStdString()); @@ -98,7 +98,7 @@ TEST(RifColumnBasedAsciiParserTest, TestDateFormatDdmmyyWithDot) ASSERT_TRUE(parser.parse(parseOptions)); ASSERT_TRUE(parser.dateTimeColumn() != nullptr); - std::vector timeSteps = parser.dateTimeColumn()->dateTimeValues; + std::vector timeSteps = parser.dateTimeColumn()->qDateTimeValues(); ASSERT_EQ(size_t(4), timeSteps.size()); EXPECT_EQ("23.02.93", timeSteps[0].toString(parseOptions.dateFormat).toStdString()); @@ -351,7 +351,7 @@ TEST(RifColumnBasedRsmspecParserTest, TestTableValues) out << "---------------------------------------\n"; out << "SUMMARY OF RUN SIP USER FILE DATA VECTORS\n"; out << "---------------------------------------\n"; - out << "TIME WLVP WPLT WTEST WFOFF WBUP\n"; + out << "TIME WOPR WOPRA WOPRB WOPTA WOPTB\n"; out << "DAYS BARSA BARSA BARSA BARSA BARSA\n"; out << "\n"; out << " P-15P P-15P P-15P P-15P P-15P \n"; @@ -377,7 +377,7 @@ TEST(RifColumnBasedRsmspecParserTest, TestTableValues) out << "---------------------------------------\n"; out << "SUMMARY OF RUN SIP USER FILE DATA VECTORS\n"; out << "---------------------------------------\n"; - out << "TIME WLVP WPLT WTEST WFOFF WBUP\n"; + out << "TIME WOPR WOPRA WOPRB WOPTA WOPTB\n"; out << "DAYS BARSA BARSA BARSA BARSA BARSA\n"; out << "\n"; out << " P-9P P-9P P-9P P-9P P-9P \n"; @@ -404,7 +404,7 @@ TEST(RifColumnBasedRsmspecParserTest, TestTableValues) EXPECT_EQ(3.0, tables.at(1).columnInfos().at(0).values.at(2)); EXPECT_EQ(370.0, tables.at(1).columnInfos().at(3).values.at(3)); - EXPECT_EQ("WLVP", tables.at(0).columnInfos().at(1).summaryAddress.quantityName()); + EXPECT_EQ("WOPR", tables.at(0).columnInfos().at(1).summaryAddress.quantityName()); EXPECT_EQ("P-15P", tables.at(0).columnInfos().at(5).summaryAddress.wellName()); EXPECT_EQ("P-9P", tables.at(1).columnInfos().at(1).summaryAddress.wellName()); EXPECT_NE("P-9P", tables.at(1).columnInfos().at(0).summaryAddress.wellName()); @@ -412,7 +412,7 @@ TEST(RifColumnBasedRsmspecParserTest, TestTableValues) RifColumnBasedUserData userData; userData.parse(data); - RifEclipseSummaryAddress adr(RifEclipseSummaryAddress::SUMMARY_WELL, "WLVP", -1, -1, "", "P-15P", -1, "", -1, -1, -1, -1); + RifEclipseSummaryAddress adr(RifEclipseSummaryAddress::SUMMARY_WELL, "WOPR", -1, -1, "", "P-15P", -1, "", -1, -1, -1, -1, false); QDateTime firstTimeStep = RiaQDateTimeTools::addDays(RiaQDateTimeTools::epoch(), 1.0); auto timeSteps = userData.timeSteps(adr); @@ -434,7 +434,7 @@ TEST(RifColumnBasedRsmspecParserTest, TestTableMissingWellNames) out << "---------------------------------------\n"; out << "SUMMARY OF RUN SIP USER FILE DATA VECTORS\n"; out << "---------------------------------------\n"; - out << "TIME WLVP WPLT WTEST WFOFF WBUP\n"; + out << "TIME WOPR WOPRA WOPRB WOPTA WOPTB\n"; out << "DAYS BARSA BARSA BARSA BARSA BARSA\n"; out << "\n"; out << " 1 0.0 0.0 0.0 0.0 0.0\n"; @@ -680,10 +680,10 @@ TEST(RifKeywordBasedRsmspecParserTest, TestShutins) out << "-- Created running the command shutin_pressures\n"; out << "\n"; out << "PAGE 1\n"; - out << "ORIGIN OP-1_WBP9L\n"; + out << "ORIGIN OP-1_WOPR\n"; out << "STARTDATE 01 01 2004 -- DD MM YYYY\n"; out << "\n"; - out << "TIME YEARX WBP9L\n"; + out << "TIME YEARX WOPR\n"; out << "DAYS YEARS BARSA\n"; out << "1 1 1\n"; out << " OP-1\n"; @@ -720,7 +720,7 @@ TEST(RifKeywordBasedRsmspecParserTest, TestShutins) EXPECT_EQ(2014.39, tables.at(0).columnInfos().at(1).values[2]); - EXPECT_EQ("WBP9L", tables.at(0).columnInfos().at(2).summaryAddress.quantityName()); + EXPECT_EQ("WOPR", tables.at(0).columnInfos().at(2).summaryAddress.quantityName()); EXPECT_EQ("OP-1", tables.at(0).columnInfos().at(2).summaryAddress.wellName()); EXPECT_NE("OP-1", tables.at(0).columnInfos().at(1).summaryAddress.wellName()); @@ -739,10 +739,10 @@ TEST(RifKeywordBasedRsmspecParserTest, TestTimeSteps) out << "-- Created running the command shutin_pressures\n"; out << "\n"; out << "PAGE 1\n"; - out << "ORIGIN OP-1_WBP9L\n"; + out << "ORIGIN OP-1_WOPR\n"; out << "STARTDATE 01 01 2004 -- DD MM YYYY\n"; out << "\n"; - out << "TIME YEARX WBP9L\n"; + out << "TIME YEARX WOPR\n"; out << "DAYS YEARS BARSA\n"; out << "1 1 1\n"; out << " OP-1\n"; @@ -768,7 +768,7 @@ TEST(RifKeywordBasedRsmspecParserTest, TestTimeSteps) out << "3493 2015.55 219.0 -- Measured\n"; out << "\n"; - std::string quantityName = "WBP9L"; + std::string quantityName = "WOPR"; std::vector< std::string > headerColumn; headerColumn.push_back("OP-1"); @@ -784,6 +784,24 @@ TEST(RifKeywordBasedRsmspecParserTest, TestTimeSteps) EXPECT_TRUE(firstDate == QDateTime::fromTime_t(timeSteps[0])); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RifKeywordBasedRsmspecParserTest, TestAddressCreation) +{ + std::string quantityName = "LCABC"; + std::vector< std::string > headerColumn; + headerColumn.push_back("wellName"); + headerColumn.push_back("lgrName"); + headerColumn.push_back("12 14 16"); + + RifEclipseSummaryAddress address = RifEclipseUserDataKeywordTools::makeAndFillAddress(quantityName, headerColumn); + + EXPECT_TRUE(address.isValid()); + EXPECT_EQ(address.category(), RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION_LGR); + EXPECT_EQ(address.uiText(), "LCABC:lgrName:wellName:12, 14, 16"); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UnitTests/RiaCellDividingTools-Test.cpp b/ApplicationCode/UnitTests/RiaCellDividingTools-Test.cpp new file mode 100644 index 0000000000..a38c9d9b5a --- /dev/null +++ b/ApplicationCode/UnitTests/RiaCellDividingTools-Test.cpp @@ -0,0 +1,111 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "gtest/gtest.h" + +#include "RiaCellDividingTools.h" +#include "RigMainGrid.h" + +//-------------------------------------------------------------------------------------------------- +/// Helper +//-------------------------------------------------------------------------------------------------- +std::array createRegularCellCoords(cvf::Vec3d refPt, double xLen, double yLen, double zLen) +{ + std::array coords = { + refPt + cvf::Vec3d(0, 0, 0), + refPt + cvf::Vec3d(xLen, 0, 0), + refPt + cvf::Vec3d(xLen, yLen, 0), + refPt + cvf::Vec3d(0, yLen, 0), + refPt + cvf::Vec3d(0, 0, zLen), + refPt + cvf::Vec3d(xLen, 0, zLen), + refPt + cvf::Vec3d(xLen, yLen, zLen), + refPt + cvf::Vec3d(0, yLen, zLen), + }; + return coords; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaCellDividingTools, flowDistanceCubicMainCell_AreaPointInCenter) +{ + std::array mainCellCorners = createRegularCellCoords(cvf::Vec3d(10, 10, 10), 10, 10, 10); + cvf::Vec3d point(15, 15, 15); + + double dist = RiaCellDividingTools::computeFlowDistance(mainCellCorners, point); + + double expectedDist = + ( + (cvf::Vec3d(12.5, 12.5, 12.5) - point).length() + (cvf::Vec3d(17.5, 12.5, 12.5) - point).length() + + (cvf::Vec3d(12.5, 17.5, 12.5) - point).length() + (cvf::Vec3d(17.5, 17.5, 12.5) - point).length() + + (cvf::Vec3d(12.5, 12.5, 17.5) - point).length() + (cvf::Vec3d(17.5, 12.5, 17.5) - point).length() + + (cvf::Vec3d(12.5, 17.5, 17.5) - point).length() + (cvf::Vec3d(17.5, 17.5, 17.5) - point).length() + ) / 8; + + EXPECT_NEAR(expectedDist, dist, 1e-6); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaCellDividingTools, flowDistanceCubicMainCell_AreaPointNearCorner) +{ + std::array mainCellCorners = createRegularCellCoords(cvf::Vec3d(10, 10, 10), 10, 10, 10); + cvf::Vec3d point(11, 11, 11); + + double dist = RiaCellDividingTools::computeFlowDistance(mainCellCorners, point); + + double expectedDist = ((cvf::Vec3d(12.5, 12.5, 12.5) - point).length() + (cvf::Vec3d(17.5, 12.5, 12.5) - point).length() + + (cvf::Vec3d(12.5, 17.5, 12.5) - point).length() + (cvf::Vec3d(17.5, 17.5, 12.5) - point).length() + + (cvf::Vec3d(12.5, 12.5, 17.5) - point).length() + (cvf::Vec3d(17.5, 12.5, 17.5) - point).length() + + (cvf::Vec3d(12.5, 17.5, 17.5) - point).length() + (cvf::Vec3d(17.5, 17.5, 17.5) - point).length()) / + 8; + + EXPECT_NEAR(expectedDist, dist, 1e-6); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaCellDividingTools, flowDistanceHighMainCell_AreaPointNearLowerCorner) +{ + std::array mainCellCorners = createRegularCellCoords(cvf::Vec3d(10, 10, 10), 10, 10, 100); + cvf::Vec3d point(11, 11, 11); + + double dist = RiaCellDividingTools::computeFlowDistance(mainCellCorners, point); + + double expectedDist = ((cvf::Vec3d(12.5, 12.5, 35) - point).length() + (cvf::Vec3d(17.5, 12.5, 35) - point).length() + + (cvf::Vec3d(12.5, 17.5, 35) - point).length() + (cvf::Vec3d(17.5, 17.5, 35) - point).length() + + (cvf::Vec3d(12.5, 12.5, 85) - point).length() + (cvf::Vec3d(17.5, 12.5, 85) - point).length() + + (cvf::Vec3d(12.5, 17.5, 85) - point).length() + (cvf::Vec3d(17.5, 17.5, 85) - point).length()) / + 8; + + EXPECT_NEAR(expectedDist, dist, 1e-6); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- + TEST(RigCellGeometryTools, lgrNodesTest) +{ + std::array mainCellCorners = createRegularCellCoords(cvf::Vec3d(10, 10, 10), 36, 18, 18); + auto coords = RiaCellDividingTools::createHexCornerCoords(mainCellCorners, 6, 3, 3); + + +} diff --git a/ApplicationCode/UnitTests/RiaEclipseUnitTools-Test.cpp b/ApplicationCode/UnitTests/RiaEclipseUnitTools-Test.cpp index 30cdad6a7d..31ab0494b9 100644 --- a/ApplicationCode/UnitTests/RiaEclipseUnitTools-Test.cpp +++ b/ApplicationCode/UnitTests/RiaEclipseUnitTools-Test.cpp @@ -37,6 +37,13 @@ TEST(RiaEclipseUnitTools, TestConversionToMeter) double destValue = RiaEclipseUnitTools::convertToMeter(sourceValue, unitText); EXPECT_NEAR(1.0, destValue, deltaRange); } + + { + double sourceValue = 123.0; + QString unitText = "mm"; + double destValue = RiaEclipseUnitTools::convertToMeter(sourceValue, unitText); + EXPECT_NEAR(0.123, destValue, deltaRange); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UnitTests/RiaPolyArcLineSampler-Test.cpp b/ApplicationCode/UnitTests/RiaPolyArcLineSampler-Test.cpp new file mode 100644 index 0000000000..7b7e9760ba --- /dev/null +++ b/ApplicationCode/UnitTests/RiaPolyArcLineSampler-Test.cpp @@ -0,0 +1,77 @@ +#include "gtest/gtest.h" + +#include "RiaPolyArcLineSampler.h" +#include + +//-------------------------------------------------------------------------------------------------- +TEST(RiaPolyArcLineSampler, Basic) +{ + std::vector points{{0, 0, 0}, {0, 0, -10}, {0, 10, -20}, {0, 20, -20}, {0, 30, -30}}; + + RiaPolyArcLineSampler sampler({0, 0, -1}, points); + + std::vector sampledPoints; + std::vector mds; + + sampler.sampledPointsAndMDs(2, true, &sampledPoints, &mds); +#if 0 + for (size_t pIdx = 0; pIdx < sampledPoints.size(); ++pIdx) + { + std::cout << sampledPoints[pIdx].x() << " " + << sampledPoints[pIdx].y() << " " + << sampledPoints[pIdx].z() << " md: " << mds[pIdx] << std::endl; + } +#endif + EXPECT_EQ(27, (int)sampledPoints.size()); + EXPECT_NEAR(51.4159, mds.back(), 1e-4); + + EXPECT_NEAR(points[2].y(), sampledPoints[12].y(), 2); + EXPECT_NEAR(points[2].z(), sampledPoints[12].z(), 2); + + EXPECT_NEAR(points[4].y(), sampledPoints[25].y(), 2); + EXPECT_NEAR(points[4].z(), sampledPoints[25].z(), 2); +} + +//-------------------------------------------------------------------------------------------------- +TEST(RiaPolyArcLineSampler, TestInvalidInput) +{ + { + // Two identical points after each other + std::vector points{{0, 0, -20}, {0, 0, -20}}; + + RiaPolyArcLineSampler sampler({0, 0, -1}, points); + + std::vector sampledPoints; + std::vector mds; + + sampler.sampledPointsAndMDs(2, true, &sampledPoints, &mds); + + EXPECT_EQ(0, (int)sampledPoints.size()); + } + + { + std::vector points; + + RiaPolyArcLineSampler sampler({0, 0, -1}, points); + + std::vector sampledPoints; + std::vector mds; + + sampler.sampledPointsAndMDs(2, true, &sampledPoints, &mds); + + EXPECT_EQ(0, (int)sampledPoints.size()); + } + + { + std::vector points{{0, 0, 0}}; + + RiaPolyArcLineSampler sampler({0, 0, -1}, points); + + std::vector sampledPoints; + std::vector mds; + + sampler.sampledPointsAndMDs(2, true, &sampledPoints, &mds); + + EXPECT_EQ(0, (int)sampledPoints.size()); + } +} diff --git a/ApplicationCode/UnitTests/RiaProjectFileVersionTools-Test.cpp b/ApplicationCode/UnitTests/RiaProjectFileVersionTools-Test.cpp index dfa708cee1..39be9c75aa 100644 --- a/ApplicationCode/UnitTests/RiaProjectFileVersionTools-Test.cpp +++ b/ApplicationCode/UnitTests/RiaProjectFileVersionTools-Test.cpp @@ -148,8 +148,10 @@ TEST(RiaProjectFileVersionTools, OrderKnownVersionStrings) qSort(sortedVersionList.begin(), sortedVersionList.end(), RiaProjectFileVersionTools::isCandidateVersionNewerThanOther); } +/* for (const auto& s : sortedVersionList) { - // std::cout << s.toStdString() << "\n"; + std::cout << s.toStdString() << "\n"; } +*/ } diff --git a/ApplicationCode/UnitTests/RiaTextFileCompare-Test.cpp b/ApplicationCode/UnitTests/RiaTextFileCompare-Test.cpp index a80e2f5a35..df317a81a3 100644 --- a/ApplicationCode/UnitTests/RiaTextFileCompare-Test.cpp +++ b/ApplicationCode/UnitTests/RiaTextFileCompare-Test.cpp @@ -1,5 +1,6 @@ #include "gtest/gtest.h" +#include "RiaGitDiff.h" #include "RiaRegressionTest.h" #include "RiaTestDataDirectory.h" #include "RiaTextFileCompare.h" @@ -66,3 +67,20 @@ TEST(RiaTextFileCompareTest, BasicCompareError) QString error = compare.errorMessage(); EXPECT_FALSE(error.isEmpty()); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaGitDiffTest, BasicCompare) +{ + RiaRegressionTest regTestConfig; + regTestConfig.readSettingsFromApplicationStore(); + QString folderContainingDiff = regTestConfig.folderContainingGitTool(); + + RiaGitDiff compare(folderContainingDiff); + + QString baseFolder = QString("d:/gitroot-ceesol/ResInsight-regression-test/ProjectFiles/CommandFileTests"); + + compare.executeDiff(baseFolder); + compare.diffOutput(); +} diff --git a/ApplicationCode/UnitTests/RiaTimeHistoryCurveTools-Test.cpp b/ApplicationCode/UnitTests/RiaTimeHistoryCurveTools-Test.cpp new file mode 100644 index 0000000000..dba21de765 --- /dev/null +++ b/ApplicationCode/UnitTests/RiaTimeHistoryCurveTools-Test.cpp @@ -0,0 +1,782 @@ +#include "gtest/gtest.h" + +#include "RiaTimeHistoryCurveResampler.h" +#include "RiaQDateTimeTools.h" + + +//-------------------------------------------------------------------------------------------------- +/// Constants +//-------------------------------------------------------------------------------------------------- +static int SECS_PER_DAY = 60 * 60 * 24; + +//-------------------------------------------------------------------------------------------------- +/// Helpers +//-------------------------------------------------------------------------------------------------- +static time_t toTime_t(const QString& timeString) +{ + return RiaQDateTimeTools::fromString(timeString, "yyyy-MM-dd").toTime_t(); +} + +static std::vector toTime_tVector(const std::vector& timeStrings) +{ + std::vector tv; + for (auto& ts : timeStrings) tv.push_back(toTime_t(ts)); + return tv; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_Resampling_NoPeriod) +{ + std::vector timeStrings( + { + "2018-02-03", + "2018-02-27" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::MONTH); + + EXPECT_EQ(1, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2018-03-01"), resampler.resampledTimeSteps()[0]); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_Resampling_Decade) +{ + std::vector timeStrings( + { + "1989-02-03", + "2005-06-06", + "2012-02-07" + } + ); + + std::vector dataValues( + { + 0.0, + 0.0, + 0.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::DECADE); + + EXPECT_EQ(4, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("1990-01-01"), resampler.resampledTimeSteps()[0]); + EXPECT_EQ(toTime_t("2000-01-01"), resampler.resampledTimeSteps()[1]); + EXPECT_EQ(toTime_t("2010-01-01"), resampler.resampledTimeSteps()[2]); + EXPECT_EQ(toTime_t("2020-01-01"), resampler.resampledTimeSteps()[3]); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_Resampling_Year) +{ + std::vector timeStrings( + { + "2014-06-06", + "2015-12-02", + "2018-02-07" + } + ); + + std::vector dataValues( + { + 0.0, + 0.0, + 0.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::YEAR); + + EXPECT_EQ(5, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2015-01-01"), resampler.resampledTimeSteps()[0]); + EXPECT_EQ(toTime_t("2016-01-01"), resampler.resampledTimeSteps()[1]); + EXPECT_EQ(toTime_t("2017-01-01"), resampler.resampledTimeSteps()[2]); + EXPECT_EQ(toTime_t("2018-01-01"), resampler.resampledTimeSteps()[3]); + EXPECT_EQ(toTime_t("2019-01-01"), resampler.resampledTimeSteps()[4]); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_Resampling_HalfYear) +{ + std::vector timeStrings( + { + "2016-06-06", + "2017-03-02", + "2018-02-07" + } + ); + + std::vector dataValues( + { + 0.0, + 0.0, + 0.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::HALFYEAR); + + EXPECT_EQ(5, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2016-07-01"), resampler.resampledTimeSteps()[0]); + EXPECT_EQ(toTime_t("2017-01-01"), resampler.resampledTimeSteps()[1]); + EXPECT_EQ(toTime_t("2017-07-01"), resampler.resampledTimeSteps()[2]); + EXPECT_EQ(toTime_t("2018-01-01"), resampler.resampledTimeSteps()[3]); + EXPECT_EQ(toTime_t("2018-07-01"), resampler.resampledTimeSteps()[4]); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_Resampling_Quarter) +{ + std::vector timeStrings( + { + "2016-09-06", + "2017-03-02", + "2018-02-07" + } + ); + + std::vector dataValues( + { + 0.0, + 0.0, + 0.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::QUARTER); + + EXPECT_EQ(7, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2016-10-01"), resampler.resampledTimeSteps()[0]); + EXPECT_EQ(toTime_t("2017-01-01"), resampler.resampledTimeSteps()[1]); + EXPECT_EQ(toTime_t("2017-04-01"), resampler.resampledTimeSteps()[2]); + EXPECT_EQ(toTime_t("2017-07-01"), resampler.resampledTimeSteps()[3]); + EXPECT_EQ(toTime_t("2017-10-01"), resampler.resampledTimeSteps()[4]); + EXPECT_EQ(toTime_t("2018-01-01"), resampler.resampledTimeSteps()[5]); + EXPECT_EQ(toTime_t("2018-04-01"), resampler.resampledTimeSteps()[6]); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_Resampling_Month) +{ + std::vector timeStrings( + { + "2017-09-06", + "2017-12-02", + "2018-02-07" + } + ); + + std::vector dataValues( + { + 0.0, + 0.0, + 0.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::MONTH); + + EXPECT_EQ(6, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2017-10-01"), resampler.resampledTimeSteps()[0]); + EXPECT_EQ(toTime_t("2017-11-01"), resampler.resampledTimeSteps()[1]); + EXPECT_EQ(toTime_t("2017-12-01"), resampler.resampledTimeSteps()[2]); + EXPECT_EQ(toTime_t("2018-01-01"), resampler.resampledTimeSteps()[3]); + EXPECT_EQ(toTime_t("2018-02-01"), resampler.resampledTimeSteps()[4]); + EXPECT_EQ(toTime_t("2018-03-01"), resampler.resampledTimeSteps()[5]); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_Resampling_Week) +{ + std::vector timeStrings( + { + "2017-11-02", + "2017-12-24", + "2018-01-07" + } + ); + + std::vector dataValues( + { + 0.0, + 0.0, + 0.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::WEEK); + + EXPECT_EQ(10, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2017-11-06"), resampler.resampledTimeSteps()[0]); + EXPECT_EQ(toTime_t("2017-11-13"), resampler.resampledTimeSteps()[1]); + EXPECT_EQ(toTime_t("2017-11-20"), resampler.resampledTimeSteps()[2]); + EXPECT_EQ(toTime_t("2017-11-27"), resampler.resampledTimeSteps()[3]); + EXPECT_EQ(toTime_t("2017-12-04"), resampler.resampledTimeSteps()[4]); + EXPECT_EQ(toTime_t("2017-12-11"), resampler.resampledTimeSteps()[5]); + EXPECT_EQ(toTime_t("2017-12-18"), resampler.resampledTimeSteps()[6]); + EXPECT_EQ(toTime_t("2017-12-25"), resampler.resampledTimeSteps()[7]); + EXPECT_EQ(toTime_t("2018-01-01"), resampler.resampledTimeSteps()[8]); + EXPECT_EQ(toTime_t("2018-01-08"), resampler.resampledTimeSteps()[9]); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_Resampling_NoSampleCrossingPeriodBoundary) +{ + std::vector timeStrings( + { + "2017-01-02", + "2017-06-15", + "2017-12-24" + } + ); + + std::vector dataValues( + { + 0.0, + 0.0, + 0.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::YEAR); + + EXPECT_EQ(1, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2018-01-01"), resampler.resampledTimeSteps()[0]); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_WeightedMean_SingleSample) +{ + std::vector timeStrings( + { + "2018-02-07" + } + ); + + std::vector dataValues( + { + 3.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::MONTH); + + EXPECT_EQ(1, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2018-03-01"), resampler.resampledTimeSteps()[0]); + + double value = 0.0; + EXPECT_NEAR(value, resampler.resampledValues()[0], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_WeightedMean_Days) +{ + std::vector timeStrings( + { + "2018-02-03", + "2018-02-07" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::DAY); + + EXPECT_EQ(5, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2018-02-03"), resampler.resampledTimeSteps()[0]); + EXPECT_EQ(toTime_t("2018-02-04"), resampler.resampledTimeSteps()[1]); + EXPECT_EQ(toTime_t("2018-02-05"), resampler.resampledTimeSteps()[2]); + EXPECT_EQ(toTime_t("2018-02-06"), resampler.resampledTimeSteps()[3]); + EXPECT_EQ(toTime_t("2018-02-07"), resampler.resampledTimeSteps()[4]); + + EXPECT_NEAR(3.0, resampler.resampledValues()[0], 1e-12); + EXPECT_NEAR(5.0, resampler.resampledValues()[1], 1e-12); + EXPECT_NEAR(5.0, resampler.resampledValues()[2], 1e-12); + EXPECT_NEAR(5.0, resampler.resampledValues()[3], 1e-12); + EXPECT_NEAR(5.0, resampler.resampledValues()[4], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_WeightedMean_Decade) +{ + std::vector timeStrings( + { + "1999-02-03", + "2005-06-06", + "2012-02-07" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0, + 7.0 + } + ); + + time_t t0 = toTime_t("1999-02-03"); + time_t t1 = toTime_t("2005-06-06"); + time_t t2 = toTime_t("2012-02-07"); + time_t tp0 = toTime_t("2000-01-01"); + time_t tp1 = toTime_t("2010-01-01"); + time_t tp2 = toTime_t("2020-01-01"); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::DECADE); + + EXPECT_EQ(3, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(tp0, resampler.resampledTimeSteps()[0]); + EXPECT_EQ(tp1, resampler.resampledTimeSteps()[1]); + EXPECT_EQ(tp2, resampler.resampledTimeSteps()[2]); + + double value0 = 5.0 * (tp0 - t0) / (tp0 - toTime_t("1990-01-01")); + double value1 = (5.0 * (t1 - tp0) + 7.0 * (tp1 - t1)) / (tp1 - tp0); + double value2 = 7.0 * (t2 - tp1) / (tp2 - tp1); + + EXPECT_NEAR(value0, resampler.resampledValues()[0], 1e-12); + EXPECT_NEAR(value1, resampler.resampledValues()[1], 1e-12); + EXPECT_NEAR(value2, resampler.resampledValues()[2], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_WeightedMean_SamplesStartBeforePeriod) +{ + std::vector timeStrings( + { + "2018-01-20", + "2018-01-29", + "2018-02-03", + "2018-02-27", + "2018-03-02" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0, + 7.0, + 11.0, + 13.0 + } + ); + + time_t tp0 = toTime_t("2018-02-01"); + time_t tp1 = toTime_t("2018-03-01"); + time_t tp2 = toTime_t("2018-04-01"); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::MONTH); + + EXPECT_EQ(3, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(tp0, resampler.resampledTimeSteps()[0]); + EXPECT_EQ(tp1, resampler.resampledTimeSteps()[1]); + EXPECT_EQ(tp2, resampler.resampledTimeSteps()[2]); + + double value0 = + (5.0 * 9 + + 7.0 * 3) * SECS_PER_DAY / (tp0 - toTime_t("2018-01-01")); + + double value1 = + (7.0 * 2 + + 11.0 * 24 + + 13.0 * 2) * SECS_PER_DAY / (tp1 - tp0); + + double value2 = 13.0 * 1 * SECS_PER_DAY / (tp2 - tp1); + + EXPECT_NEAR(value0, resampler.resampledValues()[0], 1e-12); + EXPECT_NEAR(value1, resampler.resampledValues()[1], 1e-12); + EXPECT_NEAR(value2, resampler.resampledValues()[2], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_WeightedMean_SamplesStartBeforePeriod_TimeStepsMatchPeriod) +{ + std::vector timeStrings( + { + "2018-01-20", + "2018-02-01", + "2018-02-03", + "2018-03-01", + "2018-03-02" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0, + 7.0, + 11.0, + 13.0 + } + ); + + time_t tp0 = toTime_t("2018-02-01"); + time_t tp1 = toTime_t("2018-03-01"); + time_t tp2 = toTime_t("2018-04-01"); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::MONTH); + + EXPECT_EQ(3, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(tp0, resampler.resampledTimeSteps()[0]); + EXPECT_EQ(tp1, resampler.resampledTimeSteps()[1]); + EXPECT_EQ(tp2, resampler.resampledTimeSteps()[2]); + + double value0 = + (5.0 * 12) * SECS_PER_DAY / (tp0 - toTime_t("2018-01-01")); + + double value1 = + (7.0 * 2 + + 11.0 * 26) * SECS_PER_DAY / (tp1 - tp0); + + double value2 = 13.0 * 1 * SECS_PER_DAY / (tp2 - tp1); + + EXPECT_NEAR(value0, resampler.resampledValues()[0], 1e-12); + EXPECT_NEAR(value1, resampler.resampledValues()[1], 1e-12); + EXPECT_NEAR(value2, resampler.resampledValues()[2], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_WeightedMean_SamplesStartAndEndMatchPeriod) +{ + std::vector timeStrings( + { + "2018-02-01", + "2018-02-10", + "2018-03-01" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0, + 7.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::MONTH); + + EXPECT_EQ(2, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2018-02-01"), resampler.resampledTimeSteps().front()); + EXPECT_EQ(toTime_t("2018-03-01"), resampler.resampledTimeSteps().back()); + + time_t timePeriod = toTime_t("2018-03-01") - toTime_t("2018-02-01"); + + double value1 = 3.0; + double value2 = + (5.0 * 9 + + 7.0 * 19) * SECS_PER_DAY / timePeriod; + + EXPECT_NEAR(value1, resampler.resampledValues()[0], 1e-12); + EXPECT_NEAR(value2, resampler.resampledValues()[1], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_WeightedMean_SamplesStartMatchPeriodStart) +{ + std::vector timeStrings( + { + "2018-02-01", + "2018-02-10", + "2018-03-01", + "2018-03-02" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0, + 7.0, + 11.0 + } + ); + + time_t tp0 = toTime_t("2018-02-01"); + time_t tp1 = toTime_t("2018-03-01"); + time_t tp2 = toTime_t("2018-04-01"); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::MONTH); + + EXPECT_EQ(3, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(tp0, resampler.resampledTimeSteps()[0]); + EXPECT_EQ(tp1, resampler.resampledTimeSteps()[1]); + EXPECT_EQ(tp2, resampler.resampledTimeSteps()[2]); + + double value0 = 3.0; + double value1 = + (5.0 * 9 + + 7.0 * 19) * SECS_PER_DAY / (tp1 - tp0); + double value2 = 11.0 * 1 * SECS_PER_DAY / (tp2 - tp1); + + EXPECT_NEAR(value0, resampler.resampledValues()[0], 1e-12); + EXPECT_NEAR(value1, resampler.resampledValues()[1], 1e-12); + EXPECT_NEAR(value2, resampler.resampledValues()[2], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_WeightedMean_MultipleSamplesInLastPeriod) +{ + std::vector timeStrings( + { + "2018-02-10", + "2018-03-02", + "2018-03-05", + "2018-03-15" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0, + 7.0, + 11.0 + } + ); + + time_t tp0 = toTime_t("2018-03-01"); + time_t tp1 = toTime_t("2018-04-01"); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputeWeightedMeanValues(DateTimePeriod::MONTH); + + EXPECT_EQ(2, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(tp0, resampler.resampledTimeSteps()[0]); + EXPECT_EQ(tp1, resampler.resampledTimeSteps()[1]); + + double value0 = 5.0 * 19 * SECS_PER_DAY / (tp0 - toTime_t("2018-02-01")); + double value1 = + (0.0 * 17 + + 11.0 * 10 + + 7.0 * 3 + + 5.0 * 1) * SECS_PER_DAY / (tp1 - tp0); + + EXPECT_NEAR(value0, resampler.resampledValues()[0], 1e-12); + EXPECT_NEAR(value1, resampler.resampledValues()[1], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_PeriodEndValues_SingleSample) +{ + std::vector timeStrings( + { + "2018-02-10" + } + ); + + std::vector dataValues( + { + 3.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputePeriodEndValues(DateTimePeriod::MONTH); + + EXPECT_EQ(1, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2018-03-01"), resampler.resampledTimeSteps()[0]); + + EXPECT_NEAR(3.0, resampler.resampledValues()[0], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_PeriodEndValues_SamplesStartBeforePeriod) +{ + std::vector timeStrings( + { + "2018-01-30", + "2018-02-10", + "2018-03-05", + "2018-03-02" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0, + 7.0, + 11.0 + } + ); + + time_t t0 = toTime_t("2018-01-30"); + time_t t1 = toTime_t("2018-02-10"); + time_t t2 = toTime_t("2018-03-05"); + time_t tp0 = toTime_t("2018-02-01"); + time_t tp1 = toTime_t("2018-03-01"); + time_t tp2 = toTime_t("2018-04-01"); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputePeriodEndValues(DateTimePeriod::MONTH); + + EXPECT_EQ(3, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(tp0, resampler.resampledTimeSteps()[0]); + EXPECT_EQ(tp1, resampler.resampledTimeSteps()[1]); + EXPECT_EQ(tp2, resampler.resampledTimeSteps()[2]); + + double value0 = (5.0 - 3.0) * (tp0 - t0) / (t1 - t0) + 3.0; + double value1 = (7.0 - 5.0) * (tp1 - t1) / (t2 - t1) + 5.0; + double value2 = 11.0; + + EXPECT_NEAR(value0, resampler.resampledValues()[0], 1e-12); + EXPECT_NEAR(value1, resampler.resampledValues()[1], 1e-12); + EXPECT_NEAR(value2, resampler.resampledValues()[2], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_PeriodEndValues_SamplesStartMatchPeriod) +{ + std::vector timeStrings( + { + "2018-02-01", + "2018-02-10", + "2018-03-01", + "2018-03-02" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0, + 7.0, + 11.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputePeriodEndValues(DateTimePeriod::MONTH); + + EXPECT_EQ(3, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2018-02-01"), resampler.resampledTimeSteps()[0]); + EXPECT_EQ(toTime_t("2018-03-01"), resampler.resampledTimeSteps()[1]); + EXPECT_EQ(toTime_t("2018-04-01"), resampler.resampledTimeSteps()[2]); + + EXPECT_NEAR(3.0, resampler.resampledValues()[0], 1e-12); + EXPECT_NEAR(7.0, resampler.resampledValues()[1], 1e-12); + EXPECT_NEAR(11.0, resampler.resampledValues()[2], 1e-12); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaTimeHistoryCurveResampler, Test_PeriodEndValues_SamplesStartAndEndMatchPeriod) +{ + std::vector timeStrings( + { + "2018-02-01", + "2018-02-10", + "2018-03-01" + } + ); + + std::vector dataValues( + { + 3.0, + 5.0, + 7.0 + } + ); + + RiaTimeHistoryCurveResampler resampler; + resampler.setCurveData(dataValues, toTime_tVector(timeStrings)); + resampler.resampleAndComputePeriodEndValues(DateTimePeriod::MONTH); + + EXPECT_EQ(2, (int)resampler.resampledTimeSteps().size()); + EXPECT_EQ(toTime_t("2018-02-01"), resampler.resampledTimeSteps().front()); + EXPECT_EQ(toTime_t("2018-03-01"), resampler.resampledTimeSteps().back()); + + EXPECT_NEAR(3.0, resampler.resampledValues()[0], 1e-12); + EXPECT_NEAR(7.0, resampler.resampledValues()[1], 1e-12); +} + diff --git a/ApplicationCode/UnitTests/RiaWeightedGeometricMeanCalculator-Test.cpp b/ApplicationCode/UnitTests/RiaWeightedGeometricMeanCalculator-Test.cpp new file mode 100644 index 0000000000..c5c4f74bc5 --- /dev/null +++ b/ApplicationCode/UnitTests/RiaWeightedGeometricMeanCalculator-Test.cpp @@ -0,0 +1,62 @@ +#include "gtest/gtest.h" + +#include "RiaWeightedGeometricMeanCalculator.h" +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaWeightedGeometricMeanCalculator, BasicUsage) +{ + { + RiaWeightedGeometricMeanCalculator calc; + + EXPECT_DOUBLE_EQ(0.0, calc.aggregatedWeight()); + EXPECT_DOUBLE_EQ(0.0, calc.weightedMean()); + } + + + { + RiaWeightedGeometricMeanCalculator calc; + + std::vector values {30.0, 60.0}; + std::vector weights {1.5, 3.5}; + + for (size_t i = 0; i< values.size(); i++) + { + calc.addValueAndWeight(values[i], weights[i]); + } + + double expectedValue = std::pow( + std::pow(30.0, 1.5) * std::pow(60.0, 3.5), + 1 / (1.5 + 3.5) + ); + + EXPECT_DOUBLE_EQ(5.0, calc.aggregatedWeight()); + EXPECT_NEAR(expectedValue, calc.weightedMean(), 1e-10); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaWeightedGeometricMeanCalculator, BigValues) +{ + RiaWeightedGeometricMeanCalculator calc; + + std::vector values{ 3000000.0, 6000000.0, 1250000, 2200000 }; + std::vector weights{ 1.5, 3.5, 7, 5 }; + + for (size_t i = 0; i < values.size(); i++) + { + calc.addValueAndWeight(values[i], weights[i]); + } + + double expectedValue = std::pow( + std::pow(3000000.0, 1.5) * std::pow(6000000.0, 3.5) * std::pow(1250000.0, 7) * std::pow(2200000.0, 5), + 1 / (1.5 + 3.5 + 7 + 5) + ); + + EXPECT_DOUBLE_EQ(17.0, calc.aggregatedWeight()); + EXPECT_NEAR(expectedValue, calc.weightedMean(), 1e-8); +} diff --git a/ApplicationCode/UnitTests/RiaWeightedHarmonicMeanCalculator-Test.cpp b/ApplicationCode/UnitTests/RiaWeightedHarmonicMeanCalculator-Test.cpp new file mode 100644 index 0000000000..7271150975 --- /dev/null +++ b/ApplicationCode/UnitTests/RiaWeightedHarmonicMeanCalculator-Test.cpp @@ -0,0 +1,76 @@ +#include "gtest/gtest.h" + +#include "RiaWeightedHarmonicMeanCalculator.h" +#include + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaWeightedHarmonicMeanCalculator, BasicUsage) +{ + { + RiaWeightedHarmonicMeanCalculator calc; + + EXPECT_DOUBLE_EQ(0.0, calc.aggregatedWeight()); + EXPECT_FALSE(calc.validAggregatedWeight()); + } + + + { + RiaWeightedHarmonicMeanCalculator calc; + + std::vector values {1, 4, 4}; + std::vector weights {1, 1, 1}; + + for (size_t i = 0; i< values.size(); i++) + { + calc.addValueAndWeight(values[i], weights[i]); + } + + double expectedValue = 2.0; + + EXPECT_DOUBLE_EQ(3.0, calc.aggregatedWeight()); + EXPECT_NEAR(expectedValue, calc.weightedMean(), 1e-10); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaWeightedHarmonicMeanCalculator, WeightedValues) +{ + { + RiaWeightedHarmonicMeanCalculator calc; + + std::vector values{ 10, 5, 4, 3 }; + std::vector weights{ 10, 5, 4, 3 }; + + for (size_t i = 0; i < values.size(); i++) + { + calc.addValueAndWeight(values[i], weights[i]); + } + + double sumWeights = std::accumulate(weights.begin(), weights.end(), 0.0); + + + EXPECT_DOUBLE_EQ(sumWeights, calc.aggregatedWeight()); + EXPECT_NEAR(sumWeights / weights.size(), calc.weightedMean(), 1e-8); + } + { + RiaWeightedHarmonicMeanCalculator calc; + + std::vector values{ 2.0, 3.0, 1.0, 4.0 }; + std::vector weights{ 1.0, 2.0, 7.0, 3.0 }; + for (size_t i = 0; i < values.size(); i++) + { + calc.addValueAndWeight(values[i], weights[i]); + } + double sumWeights = std::accumulate(weights.begin(), weights.end(), 0.0); + double aggregatedWeightAndValues = 1.0 / 2.0 + 2.0 / 3.0 + 7.0 / 1.0 + 3.0 / 4.0; + double expectedValue = sumWeights / aggregatedWeightAndValues; + EXPECT_DOUBLE_EQ(sumWeights, calc.aggregatedWeight()); + EXPECT_NEAR(expectedValue, calc.weightedMean(), 1.0e-8); + } +} diff --git a/ApplicationCode/UnitTests/RiaWeightedMean-Test.cpp b/ApplicationCode/UnitTests/RiaWeightedMean-Test.cpp new file mode 100644 index 0000000000..0a7b53a878 --- /dev/null +++ b/ApplicationCode/UnitTests/RiaWeightedMean-Test.cpp @@ -0,0 +1,32 @@ +#include "gtest/gtest.h" + +#include "RiaWeightedMeanCalculator.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaWeightedMeanCalculator, BasicUsage) +{ + { + RiaWeightedMeanCalculator calc; + + EXPECT_DOUBLE_EQ(0.0, calc.aggregatedWeight()); + EXPECT_FALSE(calc.validAggregatedWeight()); + } + + { + RiaWeightedMeanCalculator calc; + + std::vector values {3.0, 6.0}; + std::vector weights {1.0, 2.0}; + + for (size_t i = 0; i< values.size(); i++) + { + calc.addValueAndWeight(values[i], weights[i]); + } + EXPECT_TRUE(calc.validAggregatedWeight()); + EXPECT_DOUBLE_EQ(3.0, calc.aggregatedWeight()); + EXPECT_DOUBLE_EQ(5.0, calc.weightedMean()); + } +} diff --git a/ApplicationCode/UnitTests/RifCaseRealizationParametersReader-Test.cpp b/ApplicationCode/UnitTests/RifCaseRealizationParametersReader-Test.cpp index 0f004f0a3d..7488094fb4 100644 --- a/ApplicationCode/UnitTests/RifCaseRealizationParametersReader-Test.cpp +++ b/ApplicationCode/UnitTests/RifCaseRealizationParametersReader-Test.cpp @@ -16,7 +16,7 @@ static const QString TEST_DATA_DIRECTORY = QString("%1/RifCaseRealizationParamet //-------------------------------------------------------------------------------------------------- TEST(RifCaseRealizationParametersReaderTest, LocatorTestSuccess) { - QString file = RifCaseRealizationParametersFileLocator::locate(TEST_DATA_DIRECTORY + "3/2"); + QString file = RifCaseRealizationParametersFileLocator::locate(TEST_DATA_DIRECTORY + "4/3/2"); QString expected = TEST_DATA_DIRECTORY + "parameters.txt"; EXPECT_EQ(expected.toStdString(), file.toStdString()); } @@ -26,7 +26,7 @@ TEST(RifCaseRealizationParametersReaderTest, LocatorTestSuccess) //-------------------------------------------------------------------------------------------------- TEST(RifCaseRealizationParametersReaderTest, LocatorTestFailure) { - QString file = RifCaseRealizationParametersFileLocator::locate(TEST_DATA_DIRECTORY + "3/2/1"); + QString file = RifCaseRealizationParametersFileLocator::locate(TEST_DATA_DIRECTORY + "4/3/2/1"); QString expected = ""; EXPECT_EQ(expected.toStdString(), file.toStdString()); } diff --git a/ApplicationCode/UnitTests/RifEclipseDataTableFormatter-Test.cpp b/ApplicationCode/UnitTests/RifEclipseDataTableFormatter-Test.cpp new file mode 100644 index 0000000000..c26b592a2a --- /dev/null +++ b/ApplicationCode/UnitTests/RifEclipseDataTableFormatter-Test.cpp @@ -0,0 +1,75 @@ +#include "gtest/gtest.h" + +#include "RifEclipseDataTableFormatter.h" + +TEST(RifEclipseDataTableFormatter, BasicUsage) +{ + QString tableText; + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + + + std::vector header = { + RifEclipseOutputTableColumn("Well"), + RifEclipseOutputTableColumn("Integer Number"), + RifEclipseOutputTableColumn("IntNumer 2"), + RifEclipseOutputTableColumn("IntNumer 3"), + }; + + formatter.header(header); + + formatter.add("well a"); + formatter.add(1); + formatter.add(2); + formatter.add(3); + formatter.rowCompleted(); + + formatter.add("well B"); + formatter.add(12); + formatter.add(23); + formatter.add(233); + formatter.rowCompleted(); + + formatter.tableCompleted(); + + std::cout << tableText.toStdString(); + +} + + +TEST(RifEclipseDataTableFormatter, NoPrefix) +{ + QString tableText; + QTextStream stream(&tableText); + RifEclipseDataTableFormatter formatter(stream); + + formatter.setTableRowPrependText(" "); + formatter.setTableRowLineAppendText(""); + + + std::vector header = { + RifEclipseOutputTableColumn("Well"), + RifEclipseOutputTableColumn("Integer Number", RifEclipseOutputTableDoubleFormatting(), RIGHT), + RifEclipseOutputTableColumn("IntNumer 2", RifEclipseOutputTableDoubleFormatting(), RIGHT), + RifEclipseOutputTableColumn("IntNumer 3", RifEclipseOutputTableDoubleFormatting(), RIGHT), + }; + + formatter.header(header); + + formatter.add("well a"); + formatter.add(1); + formatter.add(2); + formatter.add(3); + formatter.rowCompleted(); + + formatter.add("well B"); + formatter.add(12); + formatter.add(231); + formatter.add(23123); + formatter.rowCompleted(); + + formatter.tableCompleted(); + + std::cout << tableText.toStdString(); + +} diff --git a/ApplicationCode/UnitTests/RifEclipseSummaryAddress-Test.cpp b/ApplicationCode/UnitTests/RifEclipseSummaryAddress-Test.cpp new file mode 100644 index 0000000000..904e2bd956 --- /dev/null +++ b/ApplicationCode/UnitTests/RifEclipseSummaryAddress-Test.cpp @@ -0,0 +1,299 @@ +#include "gtest/gtest.h" + +#include "RifEclipseSummaryAddress.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_Field) +{ + std::string addrString = "FOPT"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_FIELD, addr.category()); + EXPECT_EQ("FOPT", addr.quantityName()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_Aquifer) +{ + std::string addrString = "AAQR:456"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_AQUIFER, addr.category()); + EXPECT_EQ("AAQR", addr.quantityName()); + EXPECT_EQ(456, addr.aquiferNumber()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_Network) +{ + std::string addrString = "NETW"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_NETWORK, addr.category()); + EXPECT_EQ("NETW", addr.quantityName()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, DISABLED_TestEclipseAddressParsing_Misc) +{ + std::string addrString = "CPU"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_MISC, addr.category()); + EXPECT_EQ("CPU", addr.quantityName()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_Region) +{ + std::string addrString = "RPR:7081"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_REGION, addr.category()); + EXPECT_EQ("RPR", addr.quantityName()); + EXPECT_EQ(7081, addr.regionNumber()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_RegionToRegion) +{ + std::string addrString = "ROFR:7081-8001"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_REGION_2_REGION, addr.category()); + EXPECT_EQ("ROFR", addr.quantityName()); + EXPECT_EQ(7081, addr.regionNumber()); + EXPECT_EQ(8001, addr.regionNumber2()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_WellGroup) +{ + std::string addrString = "GOPR:WELLS1"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_WELL_GROUP, addr.category()); + EXPECT_EQ("GOPR", addr.quantityName()); + EXPECT_EQ("WELLS1", addr.wellGroupName()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_Well) +{ + std::string addrString = "WOPR:B-2H"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_WELL, addr.category()); + EXPECT_EQ("WOPR", addr.quantityName()); + EXPECT_EQ("B-2H", addr.wellName()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_WellCompletion) +{ + std::string addrString = "COFRL:B-1H:15,13,14"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION, addr.category()); + EXPECT_EQ("COFRL", addr.quantityName()); + EXPECT_EQ("B-1H", addr.wellName()); + EXPECT_EQ(15, addr.cellI()); + EXPECT_EQ(13, addr.cellJ()); + EXPECT_EQ(14, addr.cellK()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_WellLgr) +{ + std::string addrString = "LWABC:LGRNA:B-10H"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_WELL_LGR, addr.category()); + EXPECT_EQ("LWABC", addr.quantityName()); + EXPECT_EQ("LGRNA", addr.lgrName()); + EXPECT_EQ("B-10H", addr.wellName()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_WellCompletionLgr) +{ + std::string addrString = "LCGAS:LGR1:B-1H:11,12,13"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION_LGR, addr.category()); + EXPECT_EQ("LCGAS", addr.quantityName()); + EXPECT_EQ("LGR1", addr.lgrName()); + EXPECT_EQ("B-1H", addr.wellName()); + EXPECT_EQ(11, addr.cellI()); + EXPECT_EQ(12, addr.cellJ()); + EXPECT_EQ(13, addr.cellK()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_WellSegment) +{ + std::string addrString = "SOFR:B-5H:32"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT, addr.category()); + EXPECT_EQ("SOFR", addr.quantityName()); + EXPECT_EQ("B-5H", addr.wellName()); + EXPECT_EQ(32, addr.wellSegmentNumber()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_Block) +{ + std::string addrString = "BPR:123,122,121"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_BLOCK, addr.category()); + EXPECT_EQ("BPR", addr.quantityName()); + EXPECT_EQ(123, addr.cellI()); + EXPECT_EQ(122, addr.cellJ()); + EXPECT_EQ(121, addr.cellK()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_BlockLgr) +{ + std::string addrString = "LBABC:LGRN:45,47,49"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_BLOCK_LGR, addr.category()); + EXPECT_EQ("LBABC", addr.quantityName()); + EXPECT_EQ("LGRN", addr.lgrName()); + EXPECT_EQ(45, addr.cellI()); + EXPECT_EQ(47, addr.cellJ()); + EXPECT_EQ(49, addr.cellK()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_Imported) +{ + std::string addrString = "FAULT (Imp)"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_IMPORTED, addr.category()); + EXPECT_EQ("FAULT (Imp)", addr.quantityName()); + EXPECT_FALSE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_ErrorResult1) +{ + std::string addrString = "ER:AAQR:456"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_AQUIFER, addr.category()); + EXPECT_EQ("AAQR", addr.quantityName()); + EXPECT_EQ(456, addr.aquiferNumber()); + EXPECT_TRUE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_ErrorResult2) +{ + std::string addrString = "ERR:LCGAS:LGR1:B-1H:11,12,13"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION_LGR, addr.category()); + EXPECT_EQ("LCGAS", addr.quantityName()); + EXPECT_EQ("LGR1", addr.lgrName()); + EXPECT_EQ("B-1H", addr.wellName()); + EXPECT_EQ(11, addr.cellI()); + EXPECT_EQ(12, addr.cellJ()); + EXPECT_EQ(13, addr.cellK()); + EXPECT_TRUE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressParsing_ErrorResult3) +{ + std::string addrString = "ERROR:FAULT (Imp)"; + + RifEclipseSummaryAddress addr = RifEclipseSummaryAddress::fromEclipseTextAddress(addrString); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_IMPORTED, addr.category()); + EXPECT_EQ("FAULT (Imp)", addr.quantityName()); + EXPECT_TRUE(addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressIjkParsing) +{ + RifEclipseSummaryAddress::SummaryVarCategory cat = RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION; + std::map identifiers( + { + { RifEclipseSummaryAddress::INPUT_WELL_NAME, "1-BH" }, + { RifEclipseSummaryAddress::INPUT_CELL_IJK, "6, 7, 8" }, + { RifEclipseSummaryAddress::INPUT_VECTOR_NAME, "WOPR" }, + } + ); + + RifEclipseSummaryAddress addr(cat, identifiers); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION, addr.category()); + EXPECT_EQ("WOPR", addr.quantityName()); + EXPECT_EQ("1-BH", addr.wellName()); + EXPECT_EQ(6, addr.cellI()); + EXPECT_EQ(7, addr.cellJ()); + EXPECT_EQ(8, addr.cellK()); + EXPECT_TRUE(!addr.isErrorResult()); +} + +TEST(RifEclipseSummaryAddressTest, TestEclipseAddressRegToRegParsing) +{ + RifEclipseSummaryAddress::SummaryVarCategory cat = RifEclipseSummaryAddress::SUMMARY_REGION_2_REGION; + std::map identifiers( + { + { RifEclipseSummaryAddress::INPUT_REGION_2_REGION, "123 - 456" }, + { RifEclipseSummaryAddress::INPUT_VECTOR_NAME, "ROFR" }, + } + ); + + RifEclipseSummaryAddress addr(cat, identifiers); + + EXPECT_TRUE(addr.isValid()); + EXPECT_EQ(RifEclipseSummaryAddress::SUMMARY_REGION_2_REGION, addr.category()); + EXPECT_EQ("ROFR", addr.quantityName()); + EXPECT_EQ(123, addr.regionNumber()); + EXPECT_EQ(456, addr.regionNumber2()); + EXPECT_TRUE(!addr.isErrorResult()); +} diff --git a/ApplicationCode/UnitTests/RifReaderEclipseOutput-Test.cpp b/ApplicationCode/UnitTests/RifReaderEclipseOutput-Test.cpp index 952d73c082..a7b2e38b9f 100644 --- a/ApplicationCode/UnitTests/RifReaderEclipseOutput-Test.cpp +++ b/ApplicationCode/UnitTests/RifReaderEclipseOutput-Test.cpp @@ -206,7 +206,7 @@ TEST(RigReservoirTest, DISABLED_FileOutputToolsTest) } ecl_file_close(ertFile); - ertFile = NULL; + ertFile = nullptr; timer.reportTime(); //qDebug() << timer.lapt; diff --git a/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp b/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp index 4ce0cf87ae..020f873705 100644 --- a/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp +++ b/ApplicationCode/UnitTests/RifcCommandCore-Test.cpp @@ -16,15 +16,18 @@ class TestCommand1: public RicfCommandObject RICF_InitField(&m_textArgument, "TextArgument", QString(), "TextArgument", "", "", ""); RICF_InitField(&m_doubleArgument, "DoubleArgument", 0.0, "DoubleArgument", "", "", ""); RICF_InitField(&m_intArgument, "IntArgument", 0, "IntArgument", "", "", ""); + RICF_InitField(&m_boolArgument, "BoolArgument", false, "BoolArgument", "", "", ""); } - virtual void execute() override { std::cout << "TestCommand1::execute(" << "\"" << m_textArgument().toStdString() << "\", " + void execute() override { std::cout << "TestCommand1::execute(" << "\"" << m_textArgument().toStdString() << "\", " << m_doubleArgument() << ", " - << m_intArgument << ");" << std::endl; } + << m_intArgument << ", " + << m_boolArgument << ");" << std::endl; } caf::PdmField m_textArgument; caf::PdmField m_doubleArgument; caf::PdmField m_intArgument; + caf::PdmField m_boolArgument; }; CAF_PDM_SOURCE_INIT(TestCommand1, "TestCommand1"); @@ -39,15 +42,17 @@ class TC2: public RicfCommandObject RICF_InitField(&m_textArgument, "ta", QString(), "TextArgument", "", "", ""); RICF_InitField(&m_doubleArgument, "da", 0.0, "DoubleArgument", "", "", ""); RICF_InitField(&m_intArgument, "ia", 0,"IntArgument", "", "", ""); + RICF_InitField(&m_boolArgument, "ba", false,"BoolArgument", "", "", ""); } - virtual void execute() override { std::cout << "TC2::execute(" << "\"" << m_textArgument().toStdString() << "\", " + void execute() override { std::cout << "TC2::execute(" << "\"" << m_textArgument().toStdString() << "\", " << m_doubleArgument() << ", " - << m_intArgument << ");" << std::endl; } + << m_intArgument() << ", " << m_boolArgument() << ");" << std::endl; } caf::PdmField m_textArgument; caf::PdmField m_doubleArgument; caf::PdmField m_intArgument; + caf::PdmField m_boolArgument; }; CAF_PDM_SOURCE_INIT(TC2, "TC2"); @@ -60,8 +65,9 @@ TEST(RicfCommands, Test1) { QString commandString("TestCommand1(IntArgument=3, TextArgument=\"Dette er en tekst, \\\"og\\\" jeg er: (happy)\", DoubleArgument=5.0e3) \n" "TestCommand1 ( IntArgument = 4 , \n TextArgument = \"Dette er en tekst, \\\"og\\\" jeg er: (happy)\", \n DoubleArgument = 5.0e-3 ) \n" - " TestCommand1(TextArgument=\"Litt kortere tekst.\") \n" - "TC2 ( ta = \"Hepp\", ia = 3, da= 0.123)"); + " TestCommand1(TextArgument=\"Litt kortere tekst.\", BoolArgument=true) \n" + "TC2( ia = -12, ba=True, ta = \"Floff\", da =-662.518)\n" + "TC2 ( ta = \"Hepp\", ia = 3, ba = false, da= 0.123)"); //std::cout << commandString.toStdString() << std::endl; @@ -69,24 +75,34 @@ TEST(RicfCommands, Test1) RicfMessages errors; auto objects = RicfCommandFileReader::readCommands(inputStream, caf::PdmDefaultObjectFactory::instance(), &errors); - EXPECT_EQ((size_t)4, objects.size()); + EXPECT_EQ((size_t)5, objects.size()); - auto tc2 = dynamic_cast(objects[0]); - EXPECT_EQ(39, tc2->m_textArgument().size()); - EXPECT_EQ(5.0e3, tc2->m_doubleArgument()); + auto tc1 = dynamic_cast(objects[0]); + EXPECT_EQ(39, tc1->m_textArgument().size()); + EXPECT_EQ(5.0e3, tc1->m_doubleArgument()); + EXPECT_FALSE(tc1->m_boolArgument()); - tc2 = dynamic_cast(objects[1]); - EXPECT_EQ(39, tc2->m_textArgument().size()); - EXPECT_EQ(5e-3, tc2->m_doubleArgument()); + tc1 = dynamic_cast(objects[1]); + EXPECT_EQ(39, tc1->m_textArgument().size()); + EXPECT_EQ(5e-3, tc1->m_doubleArgument()); + EXPECT_FALSE(tc1->m_boolArgument()); - tc2 = dynamic_cast(objects[2]); - EXPECT_EQ(19, tc2->m_textArgument().size()); - EXPECT_EQ(0.0, tc2->m_doubleArgument()); - - auto tc3 = dynamic_cast(objects[3]); - EXPECT_EQ(4, tc3->m_textArgument().size()); - EXPECT_EQ(0.123, tc3->m_doubleArgument()); - EXPECT_EQ(3, tc3->m_intArgument()); + tc1 = dynamic_cast(objects[2]); + EXPECT_EQ(19, tc1->m_textArgument().size()); + EXPECT_EQ(0.0, tc1->m_doubleArgument()); + EXPECT_TRUE(tc1->m_boolArgument()); + + auto tc2 = dynamic_cast(objects[3]); + EXPECT_EQ(5, tc2->m_textArgument().size()); + EXPECT_EQ(-662.518, tc2->m_doubleArgument()); + EXPECT_EQ(-12, tc2->m_intArgument()); + EXPECT_TRUE(tc2->m_boolArgument()); + + tc2 = dynamic_cast(objects[4]); + EXPECT_EQ(4, tc2->m_textArgument().size()); + EXPECT_EQ(0.123, tc2->m_doubleArgument()); + EXPECT_EQ(3, tc2->m_intArgument()); + EXPECT_FALSE(tc2->m_boolArgument()); for (auto obj: objects) { @@ -265,3 +281,43 @@ TEST(RicfCommands, IgnoreCommentLinesShowErrorLine) EXPECT_EQ((size_t)1, errors.m_messages.size()); EXPECT_EQ((size_t)6, objects.size()); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RicfCommands, WriteCommand) +{ + TestCommand1 testCmd; + testCmd.m_textArgument = "My Test"; + testCmd.m_doubleArgument = 1.123; + testCmd.m_intArgument = -123; + testCmd.m_boolArgument = true; + + QString commandString; + { + QTextStream inputStream(&commandString); + + std::vector cmdObjects; + cmdObjects.push_back(&testCmd); + + RicfCommandFileReader::writeCommands(inputStream, cmdObjects); + + EXPECT_FALSE(commandString.isEmpty()); + } + + { + QTextStream inputStream(&commandString); + RicfMessages errors; + + auto objects = RicfCommandFileReader::readCommands(inputStream, caf::PdmDefaultObjectFactory::instance(), &errors); + EXPECT_EQ((size_t)1, objects.size()); + + TestCommand1* myObj = dynamic_cast(objects.front()); + EXPECT_TRUE(myObj != nullptr); + + EXPECT_STREQ(testCmd.m_textArgument().toStdString().data(), myObj->m_textArgument().toStdString().data()); + EXPECT_EQ(testCmd.m_doubleArgument, myObj->m_doubleArgument); + EXPECT_EQ(testCmd.m_intArgument, myObj->m_intArgument); + EXPECT_EQ(testCmd.m_boolArgument, myObj->m_boolArgument); + } +} diff --git a/ApplicationCode/UnitTests/RigCellGeometryTools-Test.cpp b/ApplicationCode/UnitTests/RigCellGeometryTools-Test.cpp index faa0fcf4ba..3ec9fbdc24 100644 --- a/ApplicationCode/UnitTests/RigCellGeometryTools-Test.cpp +++ b/ApplicationCode/UnitTests/RigCellGeometryTools-Test.cpp @@ -21,6 +21,107 @@ #include "RigCellGeometryTools.h" #include "RigMainGrid.h" +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigCellGeometryTools, calculateCellVolumeTest) +{ + cvf::BoundingBox bbox(cvf::Vec3d(1.0, -2.0, 5.0), cvf::Vec3d(500.0, 3.0, 1500.0)); + cvf::Vec3d extent = bbox.extent(); + double bboxVolume = extent.x() * extent.y() * extent.z(); + + std::array cornerVertices; + bbox.cornerVertices(cornerVertices.data()); + + // This is a cuboid. The result should be exact + EXPECT_DOUBLE_EQ(bboxVolume, RigCellGeometryTools::calculateCellVolume(cornerVertices)); + + // Distort it by adding a tetrahedron to the volume + cornerVertices[1].x() += bbox.extent().x() / 3.0; + cornerVertices[2].x() += bbox.extent().x() / 3.0; + + double extraVolume = 0.5 * extent.z() * bbox.extent().x() / 3.0 * extent.y(); + + EXPECT_DOUBLE_EQ(bboxVolume + extraVolume, RigCellGeometryTools::calculateCellVolume(cornerVertices)); + + // The overlap with the original bounding box should just yield the original bounding box + cvf::BoundingBox overlapBoundingBox; + std::array overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, bbox, &overlapBoundingBox); + + EXPECT_DOUBLE_EQ(bboxVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices)); + + cvf::Vec3d overlapExtent = overlapBoundingBox.extent(); + double overlapBBoxVolume = overlapExtent.x() * overlapExtent.y() * overlapExtent.z(); + EXPECT_DOUBLE_EQ(bboxVolume, overlapBBoxVolume); + + // Shift bounding box by half the original extent in x-direction. + // It should now contain the full tetrahedron + half the original bounding box + std::array tetrahedronBoxVertices; + bbox.cornerVertices(tetrahedronBoxVertices.data()); + cvf::BoundingBox tetrahedronBBox; + for (cvf::Vec3d& corner : tetrahedronBoxVertices) + { + corner.x() += 0.5 * bbox.extent().x(); + tetrahedronBBox.add(corner); + } + overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, tetrahedronBBox, &overlapBoundingBox); + + EXPECT_DOUBLE_EQ(bboxVolume * 0.5 + extraVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices)); + + // Shift it the rest of the original extent in x-direction. + // The bounding box should now contain only the tetrahedron. + tetrahedronBBox = cvf::BoundingBox(); + for (cvf::Vec3d& corner : tetrahedronBoxVertices) + { + corner.x() += 0.5 * bbox.extent().x(); + tetrahedronBBox.add(corner); + } + overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, tetrahedronBBox, &overlapBoundingBox); + + EXPECT_DOUBLE_EQ(extraVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices)); + + // Expand original bounding box to be much larger than the hex + bbox.expand(2000); + overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, bbox, &overlapBoundingBox); + EXPECT_DOUBLE_EQ(bboxVolume + extraVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigCellGeometryTools, calculateCellVolumeTest2) +{ + cvf::BoundingBox bbox(cvf::Vec3d(0.0, 0.0, 0.0), cvf::Vec3d(100.0, 100.0, 100.0)); + std::array cornerVertices; + bbox.cornerVertices(cornerVertices.data()); + + cornerVertices[5].z() = cornerVertices[1].z(); + cornerVertices[6].z() = cornerVertices[2].z(); + + double totalCellVolume = 0.5 * 100.0 * 100.0 * 100.0; + EXPECT_DOUBLE_EQ(totalCellVolume, RigCellGeometryTools::calculateCellVolume(cornerVertices)); + cvf::BoundingBox innerBBox(cvf::Vec3d(25.0, 25.0, -10.0), cvf::Vec3d(75.0, 75.0, 110.0)); + + double expectedOverlap = 50 * 50 * 25 + 0.5 * 50 * 50 * 50; + + cvf::BoundingBox overlapBoundingBox; + std::array overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, innerBBox, &overlapBoundingBox); + EXPECT_DOUBLE_EQ(expectedOverlap, RigCellGeometryTools::calculateCellVolume(overlapVertices)); + + cvf::BoundingBox smallerInnerBBox(cvf::Vec3d(25.0, 25.0, -10.0), cvf::Vec3d(75.0, 75.0, 25.0)); + overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, smallerInnerBBox, &overlapBoundingBox); + EXPECT_DOUBLE_EQ(50 * 50 * 25, RigCellGeometryTools::calculateCellVolume(overlapVertices)); + + cvf::BoundingBox smallerBBox(cvf::Vec3d(50.0, 50.0, 0.0), cvf::Vec3d(100.0, 100.0, 100.0)); + overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, smallerBBox, &overlapBoundingBox); + double tipVolume = 50 * 50 * 50 * 0.5; + EXPECT_DOUBLE_EQ(tipVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices)); + + cvf::BoundingBox smallerBBox2(cvf::Vec3d(0.0, 0.0, 0.0), cvf::Vec3d(50.0, 50.0, 100.0)); + overlapVertices = RigCellGeometryTools::estimateHexOverlapWithBoundingBox(cornerVertices, smallerBBox2, &overlapBoundingBox); + double expectedVolume = (totalCellVolume - 2*tipVolume) * 0.5; + EXPECT_DOUBLE_EQ(expectedVolume, RigCellGeometryTools::calculateCellVolume(overlapVertices)); +} //-------------------------------------------------------------------------------------------------- /// diff --git a/ApplicationCode/UnitTests/RigHexIntersectionTools-Test.cpp b/ApplicationCode/UnitTests/RigHexIntersectionTools-Test.cpp index 3a0175df77..426af26bc4 100644 --- a/ApplicationCode/UnitTests/RigHexIntersectionTools-Test.cpp +++ b/ApplicationCode/UnitTests/RigHexIntersectionTools-Test.cpp @@ -19,6 +19,8 @@ #include "gtest/gtest.h" #include "RigHexIntersectionTools.h" +#include "QDateTime" +#include "QDebug" //-------------------------------------------------------------------------------------------------- /// @@ -48,3 +50,48 @@ TEST(RigHexIntersectionTools, planeHexCellIntersectionTest) EXPECT_FALSE(isCellIntersected); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigHexIntersectionTools, DISABLED_planeHexCellIntersectionPerformanceTest) +{ + cvf::Vec3d hexCorners[8]; + hexCorners[0] = cvf::Vec3d(0, 0, 0); + hexCorners[1] = cvf::Vec3d(1, 0, 0); + hexCorners[2] = cvf::Vec3d(0, 1, 0); + hexCorners[3] = cvf::Vec3d(0, 0, 1); + hexCorners[4] = cvf::Vec3d(0, 1, 1); + hexCorners[5] = cvf::Vec3d(1, 1, 0); + hexCorners[6] = cvf::Vec3d(1, 0, 1); + hexCorners[7] = cvf::Vec3d(1, 1, 1); + + bool isCellIntersected = false; + cvf::Plane fracturePlaneIntersecting; + cvf::Plane fracturePlaneNotIntersecting; + + fracturePlaneNotIntersecting.setFromPointAndNormal(cvf::Vec3d(1.5, 1.5, 1.5), cvf::Vec3d(1, 0, 0)); + fracturePlaneIntersecting.setFromPointAndNormal(cvf::Vec3d(0.5, 0.5, 0.5), cvf::Vec3d(1, 0, 0)); + + QTime timeTotal; + timeTotal.start(); + + for (int run = 0; run < 5; run++) + { + QTime timeLocal; + timeLocal.start(); + + for (int i = 0; i < 2000000; i++) + { + std::list > intersectionLineSegments; + + isCellIntersected = RigHexIntersectionTools::planeHexCellIntersection(hexCorners, fracturePlaneIntersecting, intersectionLineSegments); + isCellIntersected = RigHexIntersectionTools::planeHexCellIntersection(hexCorners, fracturePlaneNotIntersecting, intersectionLineSegments); + } + + qDebug() << "Time rim elapsed: " << timeLocal.elapsed(); + } + + qDebug() << "Time total elapsed: " << timeTotal.elapsed(); +} + diff --git a/ApplicationCode/UnitTests/RigStatisticsMath-Test.cpp b/ApplicationCode/UnitTests/RigStatisticsMath-Test.cpp index d441785fa8..bdca2ba252 100644 --- a/ApplicationCode/UnitTests/RigStatisticsMath-Test.cpp +++ b/ApplicationCode/UnitTests/RigStatisticsMath-Test.cpp @@ -44,7 +44,7 @@ TEST(RigStatisticsMath, BasicTest) values.push_back(80720.4378655615000); values.push_back(-98649.8109937874000); values.push_back(99372.9362079615000); - values.push_back(HUGE_VAL); + values.push_back(-HUGE_VAL); values.push_back(-57020.4389966513000); double min, max, sum, range, mean, stdev; @@ -65,7 +65,7 @@ TEST(RigStatisticsMath, BasicTest) TEST(RigStatisticsMath, RankPercentiles) { std::vector values; - values.push_back(HUGE_VAL); + values.push_back(-HUGE_VAL); values.push_back(2788.2723335651900); values.push_back(-22481.0927881701000); values.push_back(68778.6851686236000); @@ -113,8 +113,8 @@ TEST(RigStatisticsMath, HistogramPercentiles) values.push_back(6391.97999909729003); values.push_back(65930.1200169780000); values.push_back(-27696.2320267235000); - values.push_back(HUGE_VAL); - values.push_back(HUGE_VAL); + values.push_back(-HUGE_VAL); + values.push_back(-HUGE_VAL); values.push_back(96161.7546348456000); values.push_back(73875.6716288563000); values.push_back(80720.4378655615000); @@ -179,3 +179,52 @@ TEST(RigStatisticsMath, InterpolatedPercentiles) EXPECT_DOUBLE_EQ( 6391.9799990972897, pVals[2]); EXPECT_DOUBLE_EQ( 93073.49128098879, pVals[3]); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RigStatisticsMath, Accumulators) +{ + std::vector values; + + const double v1 = 2788.2723335651900; + const double v2 = 68778.6851686236000; + const double v3 = -98649.8109937874000; + const double v4 = -57020.4389966513000; + + values.push_back(HUGE_VAL); + values.push_back(v1); + values.push_back(v2); + values.push_back(-HUGE_VAL); + values.push_back(v3); + values.push_back(HUGE_VAL); + values.push_back(v4); + + { + MinMaxAccumulator acc; + acc.addData(values); + + EXPECT_DOUBLE_EQ(v3, acc.min); + EXPECT_DOUBLE_EQ(v2, acc.max); + } + + { + PosNegAccumulator acc; + acc.addData(values); + + EXPECT_DOUBLE_EQ(v1, acc.pos); + EXPECT_DOUBLE_EQ(v4, acc.neg); + } + + { + SumCountAccumulator acc; + acc.addData(values); + + const double sum = v1 + v2 + v3 + v4; + + EXPECT_FALSE(std::isinf(acc.valueSum)); + + EXPECT_DOUBLE_EQ(sum, acc.valueSum); + EXPECT_EQ(4u, acc.sampleCount); + } +} \ No newline at end of file diff --git a/ApplicationCode/UnitTests/RigTimeCurveHistoryMerger-Test.cpp b/ApplicationCode/UnitTests/RigTimeCurveHistoryMerger-Test.cpp index 3754a87b1c..922e8937d9 100644 --- a/ApplicationCode/UnitTests/RigTimeCurveHistoryMerger-Test.cpp +++ b/ApplicationCode/UnitTests/RigTimeCurveHistoryMerger-Test.cpp @@ -1,37 +1,37 @@ #include "gtest/gtest.h" -#include "RigTimeHistoryCurveMerger.h" +#include "RiaTimeHistoryCurveMerger.h" #include // Needed for HUGE_VAL on Linux //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -TEST(RigTimeHistoryCurveMergerTest, TestDateInterpolation) +TEST(RiaTimeHistoryCurveMergerTest, TestDateInterpolation) { std::vector values{ 2.0, 3.5, 5.0, 6.0}; std::vector timeSteps{ 1, 5, 10, 15}; { - double val = RigTimeHistoryCurveMerger::interpolationValue(1, values, timeSteps); + double val = RiaTimeHistoryCurveMerger::interpolationValue(1, values, timeSteps); EXPECT_EQ(2.0, val); } { - double val = RigTimeHistoryCurveMerger::interpolationValue(0, values, timeSteps); + double val = RiaTimeHistoryCurveMerger::interpolationValue(0, values, timeSteps); EXPECT_EQ(HUGE_VAL, val); } { - double val = RigTimeHistoryCurveMerger::interpolationValue(20, values, timeSteps); + double val = RiaTimeHistoryCurveMerger::interpolationValue(20, values, timeSteps); EXPECT_EQ(HUGE_VAL, val); } { - double val = RigTimeHistoryCurveMerger::interpolationValue(3, values, timeSteps); + double val = RiaTimeHistoryCurveMerger::interpolationValue(3, values, timeSteps); EXPECT_EQ(2.75, val); } @@ -40,7 +40,7 @@ TEST(RigTimeHistoryCurveMergerTest, TestDateInterpolation) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeSteps) +TEST(RiaTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeSteps) { std::vector valuesA { HUGE_VAL, 1.0, HUGE_VAL, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, HUGE_VAL }; std::vector valuesB { 10, 20, 30, 40, 45, HUGE_VAL, HUGE_VAL, 5.0, 6.0, HUGE_VAL }; @@ -53,7 +53,7 @@ TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeSteps) timeSteps.push_back(i); } - RigTimeHistoryCurveMerger interpolate; + RiaTimeHistoryCurveMerger interpolate; interpolate.addCurveData(valuesA, timeSteps); interpolate.addCurveData(valuesB, timeSteps); interpolate.computeInterpolatedValues(); @@ -68,7 +68,7 @@ TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeSteps) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsOneComplete) +TEST(RiaTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsOneComplete) { std::vector valuesA { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 }; std::vector valuesB { 10, 20, 30, HUGE_VAL, 50, HUGE_VAL, 70 }; @@ -81,7 +81,7 @@ TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsOneComplete timeSteps.push_back(i); } - RigTimeHistoryCurveMerger interpolate; + RiaTimeHistoryCurveMerger interpolate; interpolate.addCurveData(valuesA, timeSteps); interpolate.addCurveData(valuesB, timeSteps); interpolate.computeInterpolatedValues(); @@ -96,7 +96,7 @@ TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsOneComplete //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsBothComplete) +TEST(RiaTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsBothComplete) { std::vector valuesA{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 }; std::vector valuesB{ 10, 20, 30, 40, 50, 60, 70 }; @@ -109,7 +109,7 @@ TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsBothComplet timeSteps.push_back(i); } - RigTimeHistoryCurveMerger interpolate; + RiaTimeHistoryCurveMerger interpolate; interpolate.addCurveData(valuesA, timeSteps); interpolate.addCurveData(valuesB, timeSteps); interpolate.computeInterpolatedValues(); @@ -124,7 +124,7 @@ TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsBothComplet //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -TEST(RigTimeHistoryCurveMergerTest, OverlappintTimes) +TEST(RiaTimeHistoryCurveMergerTest, OverlappintTimes) { std::vector valuesA{ 1, 2, 3, 4, 5 }; std::vector valuesB{ 10, 20, 30, 40, 50 }; @@ -134,7 +134,7 @@ TEST(RigTimeHistoryCurveMergerTest, OverlappintTimes) std::vector timeStepsA{ 0, 10, 11, 15, 20 }; std::vector timeStepsB{ 1, 2, 3, 5, 7 }; - RigTimeHistoryCurveMerger interpolate; + RiaTimeHistoryCurveMerger interpolate; interpolate.addCurveData(valuesA, timeStepsA); interpolate.addCurveData(valuesB, timeStepsB); interpolate.computeInterpolatedValues(); @@ -149,10 +149,10 @@ TEST(RigTimeHistoryCurveMergerTest, OverlappintTimes) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -TEST(RigTimeHistoryCurveMergerTest, RobustUse) +TEST(RiaTimeHistoryCurveMergerTest, RobustUse) { { - RigTimeHistoryCurveMerger curveMerger; + RiaTimeHistoryCurveMerger curveMerger; curveMerger.computeInterpolatedValues(); EXPECT_EQ(0, static_cast(curveMerger.allTimeSteps().size())); } @@ -164,7 +164,7 @@ TEST(RigTimeHistoryCurveMergerTest, RobustUse) std::vector timeStepsB{ 1, 2, 3 }; { - RigTimeHistoryCurveMerger curveMerger; + RiaTimeHistoryCurveMerger curveMerger; curveMerger.addCurveData(valuesA, timeStepsA); curveMerger.computeInterpolatedValues(); EXPECT_EQ(timeStepsA.size(), curveMerger.allTimeSteps().size()); @@ -172,7 +172,7 @@ TEST(RigTimeHistoryCurveMergerTest, RobustUse) } { - RigTimeHistoryCurveMerger curveMerger; + RiaTimeHistoryCurveMerger curveMerger; curveMerger.addCurveData(valuesA, timeStepsA); curveMerger.addCurveData(valuesB, timeStepsB); @@ -188,7 +188,7 @@ TEST(RigTimeHistoryCurveMergerTest, RobustUse) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -TEST(RigTimeHistoryCurveMergerTest, NoTimeStepOverlap) +TEST(RiaTimeHistoryCurveMergerTest, NoTimeStepOverlap) { std::vector valuesA{ 1, 2, 3, 4, 5 }; std::vector valuesB{ 10, 20, 30 }; @@ -197,7 +197,7 @@ TEST(RigTimeHistoryCurveMergerTest, NoTimeStepOverlap) std::vector timeStepsB{ 100, 200, 300 }; { - RigTimeHistoryCurveMerger curveMerger; + RiaTimeHistoryCurveMerger curveMerger; curveMerger.addCurveData(valuesA, timeStepsA); curveMerger.addCurveData(valuesB, timeStepsB); diff --git a/ApplicationCode/UnitTests/RimRelocatePath-Test.cpp b/ApplicationCode/UnitTests/RimRelocatePath-Test.cpp index 7a54760e80..7a66765137 100644 --- a/ApplicationCode/UnitTests/RimRelocatePath-Test.cpp +++ b/ApplicationCode/UnitTests/RimRelocatePath-Test.cpp @@ -1,11 +1,13 @@ #include "gtest/gtest.h" +#include "RiaQDateTimeTools.h" #include "RiaTestDataDirectory.h" #include "RimProject.h" -#include "cafPdmObjectHandle.h" #include "cafFilePath.h" +#include "cafPdmObjectHandle.h" +#include #include #include @@ -71,3 +73,28 @@ TEST(RimRelocatePathTest, findPathsInProjectFile) std::cout << filePath->path().toStdString() << std::endl; } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RimRelocatePathTest, DISABLED_LocaleDateStringTest) +{ + // Set a non-english system locale on local machine for this test to be useful + + QDateTime dt; + { + QDate d(2018, 10, 1); + dt.setDate(d); + } + + QString formatString("ddd MMM yyyy"); + + // Change the default locale on your system to get a different text then the english formatted text + QString defaultString = dt.toString(formatString); + + std::cout << "default " << defaultString.toStdString() << std::endl; + + QString englishString = RiaQDateTimeTools::toStringUsingApplicationLocale(dt, formatString); + + std::cout << "english " << englishString.toStdString() << std::endl; +} diff --git a/ApplicationCode/UnitTests/RimWellLogExtractionCurveImpl-Test.cpp b/ApplicationCode/UnitTests/RimWellLogExtractionCurveImpl-Test.cpp index 9f3d65ccc1..9368b14054 100644 --- a/ApplicationCode/UnitTests/RimWellLogExtractionCurveImpl-Test.cpp +++ b/ApplicationCode/UnitTests/RimWellLogExtractionCurveImpl-Test.cpp @@ -1,6 +1,6 @@ #include "gtest/gtest.h" -#include "RigCurveDataTools.h" +#include "RiaCurveDataTools.h" #include // Needed for HUGE_VAL on Linux #include @@ -19,7 +19,7 @@ TEST(RimWellLogExtractionCurveImplTest, StripOffInvalidValAtEndsOfVector) values.push_back(3.0); values.push_back(HUGE_VAL); - auto valuesIntervals = RigCurveDataTools::calculateIntervalsOfValidValues(values, false); + auto valuesIntervals = RiaCurveDataTools::calculateIntervalsOfValidValues(values, false); EXPECT_EQ(1, static_cast(valuesIntervals.size())); EXPECT_EQ(2, static_cast(valuesIntervals[0].first)); @@ -42,7 +42,7 @@ TEST(RimWellLogExtractionCurveImplTest, StripOffHugeValAtEndsAndInteriorOfVector values.push_back(3.0); values.push_back(HUGE_VAL); - auto valuesIntervals = RigCurveDataTools::calculateIntervalsOfValidValues(values, false); + auto valuesIntervals = RiaCurveDataTools::calculateIntervalsOfValidValues(values, false); EXPECT_EQ(2, static_cast(valuesIntervals.size())); EXPECT_EQ(2, static_cast(valuesIntervals[0].first)); diff --git a/ApplicationCode/UnitTests/RiuSummaryVectorDescriptionMap-Test.cpp b/ApplicationCode/UnitTests/RiuSummaryVectorDescriptionMap-Test.cpp index 11250e37ce..5d3f198143 100644 --- a/ApplicationCode/UnitTests/RiuSummaryVectorDescriptionMap-Test.cpp +++ b/ApplicationCode/UnitTests/RiuSummaryVectorDescriptionMap-Test.cpp @@ -10,15 +10,59 @@ TEST(RiuSummaryVectorDescriptionMap, TestInit) { { std::string s("SRSFC"); - auto test = RiuSummaryVectorDescriptionMap::instance()->fieldInfo(s); + auto test = RiuSummaryVectorDescriptionMap::instance()->vectorInfo(s); + + EXPECT_TRUE(test.category == RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT); + EXPECT_TRUE(test.longName == "Reach brine concentration"); + } + + { + std::string s("SRSFC"); + auto test = RiuSummaryVectorDescriptionMap::instance()->vectorLongName(s); EXPECT_TRUE(test == "Reach brine concentration"); } { std::string s("does not exist"); - auto test = RiuSummaryVectorDescriptionMap::instance()->fieldInfo(s); + auto test = RiuSummaryVectorDescriptionMap::instance()->vectorInfo(s); + + EXPECT_TRUE(test.category == RifEclipseSummaryAddress::SUMMARY_INVALID); + EXPECT_TRUE(test.longName == ""); + } + + { + std::string s("does not exist"); + auto test = RiuSummaryVectorDescriptionMap::instance()->vectorLongName(s); + + EXPECT_TRUE(test == ""); + } + + { + std::string s("does not exist"); + auto test = RiuSummaryVectorDescriptionMap::instance()->vectorLongName(s, true); EXPECT_TRUE(test == s); } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiuSummaryVectorDescriptionMap, TestCustomNaming) +{ + { + std::string s("SRSFCABC"); + auto test = RiuSummaryVectorDescriptionMap::instance()->vectorInfo(s); + + EXPECT_TRUE(test.category == RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT); + EXPECT_TRUE(test.longName == "Reach brine concentration"); + } + + { + std::string s("BHD__ABC"); + auto test = RiuSummaryVectorDescriptionMap::instance()->vectorLongName(s); + + EXPECT_TRUE(test == "Hydraulic head"); + } +} diff --git a/ApplicationCode/UnitTests/ScalarMapper-Test.cpp b/ApplicationCode/UnitTests/ScalarMapper-Test.cpp index b376a32205..5c7afed118 100644 --- a/ApplicationCode/UnitTests/ScalarMapper-Test.cpp +++ b/ApplicationCode/UnitTests/ScalarMapper-Test.cpp @@ -4,8 +4,8 @@ #include -#include "RigFemPartResultsCollection.h" #include "cafTickMarkGenerator.h" +#include "RiaOffshoreSphericalCoords.h" //-------------------------------------------------------------------------------------------------- /// @@ -103,11 +103,11 @@ TEST(ScalarMapperTest, TestHumanReadableTickmarks) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -TEST(OffshoreSphericalCoords, OffshoreSphericalCoords) +TEST(RiaOffshoreSphericalCoords, RiaOffshoreSphericalCoords) { { cvf::Vec3f vec(0, 0, 0); - OffshoreSphericalCoords spCoord(vec); + RiaOffshoreSphericalCoords spCoord(vec); EXPECT_NEAR(spCoord.inc(), 0.0, 1e-10); EXPECT_NEAR(spCoord.azi(), 0.0, 1e-10); EXPECT_NEAR(spCoord.r(), 0.0, 1e-10); @@ -115,23 +115,23 @@ TEST(OffshoreSphericalCoords, OffshoreSphericalCoords) { cvf::Vec3f vec(1, 0, 0); - OffshoreSphericalCoords spCoord(vec); + RiaOffshoreSphericalCoords spCoord(vec); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.inc()), 90.0, 1e-10); - EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), 90.0, 1e-10); + EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), 90.0, 1e-5); EXPECT_NEAR(spCoord.r(), 1.0, 1e-10); } { cvf::Vec3f vec(-1, 0, 0); - OffshoreSphericalCoords spCoord(vec); + RiaOffshoreSphericalCoords spCoord(vec); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.inc()), 90.0, 1e-10); - EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), -90.0, 1e-10); + EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), -90.0, 1e-5); EXPECT_NEAR(spCoord.r(), 1.0, 1e-10); } { cvf::Vec3f vec(0, 1, 0); - OffshoreSphericalCoords spCoord(vec); + RiaOffshoreSphericalCoords spCoord(vec); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.inc()), 90.0, 1e-10); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), 0.0, 1e-10); EXPECT_NEAR(spCoord.r(), 1.0, 1e-10); @@ -139,14 +139,14 @@ TEST(OffshoreSphericalCoords, OffshoreSphericalCoords) { cvf::Vec3f vec(0.000001f, -3, 0); - OffshoreSphericalCoords spCoord(vec); + RiaOffshoreSphericalCoords spCoord(vec); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.inc()), 90.0, 1e-10); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), 179.9999, 1e-4); EXPECT_NEAR(spCoord.r(), 3.0, 1e-5); } { cvf::Vec3f vec(-0.000001f, -3, 0); - OffshoreSphericalCoords spCoord(vec); + RiaOffshoreSphericalCoords spCoord(vec); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.inc()), 90.0, 1e-10); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), -179.9999, 1e-4); EXPECT_NEAR(spCoord.r(), 3.0, 1e-5); @@ -154,7 +154,7 @@ TEST(OffshoreSphericalCoords, OffshoreSphericalCoords) { cvf::Vec3f vec(0, 0, 1); - OffshoreSphericalCoords spCoord(vec); + RiaOffshoreSphericalCoords spCoord(vec); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.inc()), 180.0, 1e-10); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), 0.0, 1e-4); EXPECT_NEAR(spCoord.r(), 1.0, 1e-5); @@ -162,7 +162,7 @@ TEST(OffshoreSphericalCoords, OffshoreSphericalCoords) { cvf::Vec3f vec(0, 0, -1); - OffshoreSphericalCoords spCoord(vec); + RiaOffshoreSphericalCoords spCoord(vec); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.inc()), 0.0, 1e-10); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), 0.0, 1e-4); EXPECT_NEAR(spCoord.r(), 1.0, 1e-5); @@ -170,7 +170,7 @@ TEST(OffshoreSphericalCoords, OffshoreSphericalCoords) { cvf::Vec3f vec(1, 0, -1); - OffshoreSphericalCoords spCoord(vec); + RiaOffshoreSphericalCoords spCoord(vec); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.inc()), 45.0, 1e-5); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), 90.0, 1e-4); EXPECT_NEAR(spCoord.r(), sqrt(2), 1e-5); @@ -178,7 +178,7 @@ TEST(OffshoreSphericalCoords, OffshoreSphericalCoords) { cvf::Vec3f vec(1.5f, 1.5f, 1.5f); - OffshoreSphericalCoords spCoord(vec); + RiaOffshoreSphericalCoords spCoord(vec); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.inc()), 125.264396, 1e-5); EXPECT_NEAR(cvf::Math::toDegrees(spCoord.azi()), 45.0, 1e-4); EXPECT_NEAR(spCoord.r(), vec.length(), 1e-6); diff --git a/ApplicationCode/UnitTests/SolveSpaceSolver-Test.cpp b/ApplicationCode/UnitTests/SolveSpaceSolver-Test.cpp new file mode 100644 index 0000000000..d0fc148554 --- /dev/null +++ b/ApplicationCode/UnitTests/SolveSpaceSolver-Test.cpp @@ -0,0 +1,633 @@ +#include "gtest/gtest.h" + +#include +#include + +#include "RiaSCurveCalculator.h" + +#define M_PI 3.14159265358979323846 // pi + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Test1) + +{ + RiaSCurveCalculator sCurveCalc({ 100, 100, 0 }, + 0, + M_PI/4, + 12, + { 100, 150, -1000 }, + M_PI, + M_PI/4, + 12); + EXPECT_TRUE(sCurveCalc.isOk() ); + + sCurveCalc.dump(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Test1AtEstimate) + +{ + RiaSCurveCalculator sCurveCalc({ 100, 100, 0 }, + 0, + M_PI/4, + 535.452, + { 100, 150, -1000 }, + M_PI, + M_PI/4, + 439.508); + EXPECT_TRUE(sCurveCalc.isOk() ); + + sCurveCalc.dump(); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Test2) +{ + RiaSCurveCalculator sCurveCalc({ 100, 100, 0 }, + 0, + M_PI/4, + 50, + { 100, 150, -1000 }, + M_PI, + M_PI/4, + 50); + + EXPECT_TRUE(sCurveCalc.isOk()); + + sCurveCalc.dump(); + +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Test3) +{ + RiaSCurveCalculator sCurveCalc({ 100, 100, 0 }, + 0, + 0.3, + 50, + { 100, 150, -1000 }, + 0, + 0.4, + 50); + + EXPECT_TRUE(sCurveCalc.isOk() ); + + sCurveCalc.dump(); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Test4) +{ + RiaSCurveCalculator sCurveCalc({ 0, 0, 0 }, + 0, + 45, + 115, + { 0, 50, -1000 }, + 0, + 0, + 115); + + EXPECT_TRUE(sCurveCalc.isOk() ); + + sCurveCalc.dump(); + +} + +double curveRadius = 115; +double angleEpsilon = 0.01; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Config1 ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, 0, curveRadius, + { 0,0,-1000 }, 0, 0, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK_INFINITE_RADIUS12, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Config1a ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, 0, curveRadius, + { 0,0,-1000 }, 0, angleEpsilon, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Config2 ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, 0, curveRadius, + { 0,0,-1000 }, 0, M_PI/2.0, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaSCurveCalculator, Config3 ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, 0, curveRadius, + { 0,0,-1000 }, 0, M_PI, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaSCurveCalculator, Config3a ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, 0, curveRadius, + { 0,0,-1000 }, 0, M_PI-angleEpsilon, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Config4 ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, M_PI/2.0, curveRadius, + { 0,0,-1000 }, 0, M_PI/2.0, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Config5 ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, M_PI/2.0, curveRadius, + { 0,0,-1000 }, M_PI, M_PI/2.0, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaSCurveCalculator, Config6 ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, M_PI, curveRadius, + { 0,0,-1000 }, 0, 0, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaSCurveCalculator, Config6a ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, M_PI, curveRadius, + { 0,0,-1000 }, 0, angleEpsilon, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaSCurveCalculator, Config6b ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, M_PI-angleEpsilon, curveRadius, + { 0,0,-1000 }, 0, 0.00, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaSCurveCalculator, Config7 ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, M_PI, curveRadius, + { 0,0,-1000 }, 0, M_PI/2.0, curveRadius+20); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaSCurveCalculator, Config8 ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, M_PI, curveRadius, + { 0,0,-1000 }, 0, M_PI, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaSCurveCalculator, Config8a ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, M_PI, curveRadius, + { 0,0,-1000 }, 0, M_PI-angleEpsilon, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaSCurveCalculator, Config8b ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, M_PI-angleEpsilon, curveRadius, + { 0,0,-1000 }, 0, M_PI, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, Config9 ) +{ + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, M_PI/2, curveRadius, + { 0,0,-1000 }, M_PI/2, M_PI/2, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, InfiniteStartRadius ) +{ + { + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, 0, curveRadius, + { 0,curveRadius,-1000 }, 0, M_PI/2, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK_INFINITE_RADIUS1, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); + } + + { + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, 0, 0, curveRadius, + { 0,curveRadius+0.01,-1000 }, 0, M_PI/2, curveRadius); + sCurveCalc.dump(); + EXPECT_EQ(RiaSCurveCalculator::OK, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::CONVERGED, sCurveCalc.solveStatus()); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Helper method to print the r1(q1, q2) r2(q1, q2) for plotting as 3D surface in Excel +//-------------------------------------------------------------------------------------------------- +void printQ1Q2R1R2Matrix(cvf::Vec3d p1, double azi1, double inc1, + cvf::Vec3d p2, double azi2, double inc2) +{ + + double q1Start = 0.0; + double q1End = 3000; + double step1 = 100; + double q2Start = 0.0; + double q2End = 3000; + double step2 = 100; + + std::cout << "R1" << std::endl; + std::cout << "q1\\q2" << " "; + + for (double q2 = q2Start; q2 < q2End; q2 += step2) + { + std::cout << q2 << " "; + } + std::cout << std::endl; + + for (double q1 = q1Start; q1 < q1End; q1 += step1) + { + std::cout << q1 << " "; + for (double q2 = q2Start; q2 < q2End; q2 += step2) + { + RiaSCurveCalculator sCurveCalc = RiaSCurveCalculator::fromTangentsAndLength(p1, azi1, inc1, q1, + p2, azi2, inc2, q2); + if ( sCurveCalc.isOk() ) + { + std::cout << sCurveCalc.firstRadius() << " " ; + } + else + { + std::cout << "NS" << " " ; + } + } + + std::cout << std::endl; + } + + std::cout << std::endl; + std::cout << "R2" << std::endl; + std::cout << "q1\\q2" << " "; + + for (double q2 = q2Start; q2 < q2End; q2 += step2) + { + std::cout << q2 << " "; + } + std::cout << std::endl; + + for (double q1 = q1Start; q1 < q1End; q1 += step1) + { + std::cout << q1 << " "; + for (double q2 = q2Start; q2 < q2End; q2 += step2) + { + RiaSCurveCalculator sCurveCalc = RiaSCurveCalculator::fromTangentsAndLength(p1, azi1, inc1, q1, + p2, azi2, inc2, q2); + if ( sCurveCalc.isOk() ) + { + std::cout << sCurveCalc.secondRadius() << " " ; + } + else + { + std::cout << "NS" << " " ; + } + } + + std::cout << std::endl; + } + +} + +//-------------------------------------------------------------------------------------------------- +/// Test used to print and plot the relations between q1, q2, r1 and r2 in excel as 3d surface +//-------------------------------------------------------------------------------------------------- +TEST(DISABLED_RiaSCurveCalculator, q_r_relation) +{ + std::cout << "Config 1" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, 0, + { 0,0,-1000 }, 0, 0); + + std::cout << "Config 1a" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, 0, + { 0,0,-1000 }, 0, angleEpsilon); + + std::cout << "Config 2" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, 0, + { 0,0,-1000 }, 0, M_PI/2.0); + + std::cout << "Config 3" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, 0, + { 0,0,-1000 }, 0, M_PI); + + std::cout << "Config 3a" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, 0, + { 0,0,-1000 }, 0, M_PI-angleEpsilon); + + std::cout << "Config 4" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, M_PI/2.0, + { 0,0,-1000 }, 0, M_PI/2.0); + + std::cout << "Config 5" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, M_PI/2.0, + { 0,0,-1000 }, M_PI, M_PI/2.0); + + std::cout << "Config 6" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, M_PI, + { 0,0,-1000 }, 0, 0); + + std::cout << "Config 6a" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, M_PI, + { 0,0,-1000 }, 0, angleEpsilon); + + std::cout << "Config 6b" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, M_PI-angleEpsilon, + { 0,0,-1000 }, 0, 0.00); + + std::cout << "Config 7" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, M_PI, + { 0,0,-1000 }, 0, M_PI/2.0); + + std::cout << "Config 8" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, M_PI, + { 0,0,-1000 }, 0, M_PI); + + std::cout << "Config 8a" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, M_PI, + { 0,0,-1000 }, 0, M_PI-angleEpsilon); + + std::cout << "Config 8b" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, M_PI-angleEpsilon, + { 0,0,-1000 }, 0, M_PI); + + std::cout << "Config 9" << std::endl; + + printQ1Q2R1R2Matrix( + { 0,0,0 }, 0, M_PI/2, + { 0,0,-1000 }, M_PI/2, M_PI/2); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaSCurveCalculator, ControlPointCurve) +{ + { + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, { 0, 0, -100 }, + { 0,500,-1000 }, { 0, 0, -500 }); + + EXPECT_EQ(RiaSCurveCalculator::FAILED_ARC_OVERLAP, sCurveCalc.curveStatus()); + EXPECT_EQ(RiaSCurveCalculator::NOT_SOLVED, sCurveCalc.solveStatus()); + //sCurveCalc.dump(); + } + + { + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, { 0, 0, -100 }, + { 0,100,-1000 }, { 0, 0, -900 }); + EXPECT_EQ(RiaSCurveCalculator::OK_INFINITE_RADIUS1, sCurveCalc.curveStatus()); + } + { + RiaSCurveCalculator sCurveCalc( + { 0,100,0 }, { 0, 0, -100 }, + { 0,0,-1000 }, { 0, 0, -900 }); + EXPECT_EQ(RiaSCurveCalculator::OK_INFINITE_RADIUS2, sCurveCalc.curveStatus()); + } + { + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, { 0, 0, -100}, + { 0,0,-1000 }, { 0, 0, -900 }); + EXPECT_EQ(RiaSCurveCalculator::OK_INFINITE_RADIUS12, sCurveCalc.curveStatus()); + } + + { + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, { 0, 0, -100}, + { 0,0, 0 }, { 0, 0, -900 }); + EXPECT_EQ(RiaSCurveCalculator::FAILED_ARC_OVERLAP, sCurveCalc.curveStatus()); + //sCurveCalc.dump(); + } + + { + RiaSCurveCalculator sCurveCalc( + { 0,0,0 }, { 0, 0, 0}, + { 0,0, -1000 }, { 0, 0, -900 }); + EXPECT_EQ(RiaSCurveCalculator::FAILED_INPUT_OVERLAP, sCurveCalc.curveStatus()); + //sCurveCalc.dump(); + } +} + +#include "RiaJCurveCalculator.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaJCurveCalculator, Basic) +{ + { + RiaJCurveCalculator calc({ 0,0,0 }, 0, M_PI/2, 100, { 0,100,-1000 }); + + EXPECT_TRUE(calc.curveStatus() == RiaJCurveCalculator::OK); + + cvf::Vec3d p11 = calc.firstArcEndpoint(); + EXPECT_NEAR(0, p11.x(), 1e-5); + EXPECT_NEAR(100, p11.y(), 1e-5); + EXPECT_NEAR(-100, p11.z(), 1e-5); + + cvf::Vec3d n = calc.firstNormal(); + EXPECT_NEAR(-1, n.x(), 1e-5); + EXPECT_NEAR(0, n.y(), 1e-5); + EXPECT_NEAR(0, n.z(), 1e-5); + + cvf::Vec3d c = calc.firstCenter(); + EXPECT_NEAR(0, c.x(), 1e-5); + EXPECT_NEAR(0, c.y(), 1e-5); + EXPECT_NEAR(-100, c.z(), 1e-5); + } + + { + RiaJCurveCalculator calc({ 0,0,0 }, 0, 0, 100, { 0, 0,-1000 }); + + EXPECT_TRUE(calc.curveStatus() == RiaJCurveCalculator::OK_STRAIGHT_LINE); + } + +} + +#include "RiaArcCurveCalculator.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(RiaArcCurveCalculator, Basic) +{ + { + RiaArcCurveCalculator calc({ 0,0,0 }, 0, M_PI/2, { 0,1000,-1000 }); + + EXPECT_TRUE(calc.curveStatus() == RiaArcCurveCalculator::OK); + EXPECT_NEAR(1000.0, calc.radius(), 1e-5); + EXPECT_NEAR(M_PI/2, calc.arcAngle(), 1e-5); + EXPECT_NEAR(M_PI/2*1000, calc.arcLength(), 1e-5); + + cvf::Vec3d center = calc.center(); + EXPECT_NEAR( 0, center.x(), 1e-5); + EXPECT_NEAR( 0, center.y(), 1e-5); + EXPECT_NEAR(-1000, center.z(), 1e-5); + + cvf::Vec3d n = calc.normal(); + EXPECT_NEAR(-1, n.x(), 1e-5); + EXPECT_NEAR( 0, n.y(), 1e-5); + EXPECT_NEAR( 0, n.z(), 1e-5); + + cvf::Vec3d te = calc.endTangent(); + EXPECT_NEAR( 0, te.x(), 1e-5); + EXPECT_NEAR( 0, te.y(), 1e-5); + EXPECT_NEAR(-1, te.z(), 1e-5); + } + + { + RiaArcCurveCalculator calc({ 0,0,0 }, 0, 0, { 0, 0,-1000 }); + + EXPECT_TRUE(calc.curveStatus() == RiaJCurveCalculator::OK_STRAIGHT_LINE); + + cvf::Vec3d te = calc.endTangent(); + EXPECT_NEAR(0, te.x(), 1e-5); + EXPECT_NEAR(0, te.y(), 1e-5); + EXPECT_NEAR(-1, te.z(), 1e-5); + } + +} \ No newline at end of file diff --git a/ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/3/2/dummy.txt b/ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/4/3/2/1/dummy.txt similarity index 100% rename from ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/3/2/dummy.txt rename to ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/4/3/2/1/dummy.txt diff --git a/ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/3/dummy.txt b/ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/4/3/2/dummy.txt similarity index 100% rename from ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/3/dummy.txt rename to ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/4/3/2/dummy.txt diff --git a/ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/4/3/dummy.txt b/ApplicationCode/UnitTests/TestData/RifCaseRealizationParametersReader/4/3/dummy.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ApplicationCode/UnitTests/cvfGeometryTools-Test.cpp b/ApplicationCode/UnitTests/cvfGeometryTools-Test.cpp index 428cf1816e..606f8cba8c 100644 --- a/ApplicationCode/UnitTests/cvfGeometryTools-Test.cpp +++ b/ApplicationCode/UnitTests/cvfGeometryTools-Test.cpp @@ -23,7 +23,6 @@ #include "cvfLibViewing.h" #include "cvfLibRender.h" #include "cvfLibGeometry.h" -#include "cafFixedArray.h" #include "cvfArrayWrapperToEdit.h" #include "cvfArrayWrapperConst.h" @@ -31,6 +30,8 @@ #include "cvfGeometryTools.h" #include "cvfBoundingBoxTree.h" +#include + using namespace cvf; #if 0 @@ -122,22 +123,15 @@ std::vector createVertices() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector getCubeFaces() +std::vector> getCubeFaces() { - std::vector cubeFaces; - - cvf::uint faces[4*4] = { - 0, 1, 2, 3, - 4, 5, 6, 7, - 5, 8, 9, 6, - 10, 11, 12, 13 - }; + std::vector> cubeFaces; cubeFaces.resize(4); - cubeFaces[0] = &faces[0]; - cubeFaces[1] = &faces[4]; - cubeFaces[2] = &faces[8]; - cubeFaces[3] = &faces[12]; + cubeFaces[0] = { 0, 1, 2, 3 }; + cubeFaces[1] = { 4, 5, 6, 7 }; + cubeFaces[2] = { 5, 8, 9, 6 }; + cubeFaces[3] = { 10, 11, 12, 13 }; return cubeFaces; } @@ -161,7 +155,7 @@ TEST(CellFaceIntersectionTst, Intersection1) std::vector additionalVertices; std::vector< std::vector > overlapPolygons; - std::vector faces = getCubeFaces(); + auto faces = getCubeFaces(); EdgeIntersectStorage edgeIntersectionStorage; edgeIntersectionStorage.setVertexCount(nodes.size()); diff --git a/ApplicationCode/UserInterface/CMakeLists_files.cmake b/ApplicationCode/UserInterface/CMakeLists_files.cmake index 29557d6499..8999464694 100644 --- a/ApplicationCode/UserInterface/CMakeLists_files.cmake +++ b/ApplicationCode/UserInterface/CMakeLists_files.cmake @@ -6,7 +6,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuDragDrop.h ${CMAKE_CURRENT_LIST_DIR}/RiuFemResultTextBuilder.h ${CMAKE_CURRENT_LIST_DIR}/RiuGeoQuestNavigation.h ${CMAKE_CURRENT_LIST_DIR}/RiuInterfaceToViewWindow.h -${CMAKE_CURRENT_LIST_DIR}/RiuLineSegmentQwtPlotCurve.h +${CMAKE_CURRENT_LIST_DIR}/RiuQwtSymbol.h +${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotCurve.h ${CMAKE_CURRENT_LIST_DIR}/RiuRimQwtPlotCurve.h ${CMAKE_CURRENT_LIST_DIR}/RiuPlotMainWindow.h ${CMAKE_CURRENT_LIST_DIR}/RiuMainWindow.h @@ -18,6 +19,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuProjectPropertyView.h ${CMAKE_CURRENT_LIST_DIR}/RiuPropertyViewTabWidget.h ${CMAKE_CURRENT_LIST_DIR}/RiuPvtPlotPanel.h ${CMAKE_CURRENT_LIST_DIR}/RiuPvtPlotUpdater.h +${CMAKE_CURRENT_LIST_DIR}/RiuQwtLinearScaleEngine.h ${CMAKE_CURRENT_LIST_DIR}/RiuQwtScalePicker.h ${CMAKE_CURRENT_LIST_DIR}/RiuQwtCurvePointTracker.h ${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWheelZoomer.h @@ -43,6 +45,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuTreeViewEventFilter.h ${CMAKE_CURRENT_LIST_DIR}/RiuViewer.h ${CMAKE_CURRENT_LIST_DIR}/RiuViewerToViewInterface.h ${CMAKE_CURRENT_LIST_DIR}/RiuViewerCommands.h +${CMAKE_CURRENT_LIST_DIR}/RiuPickItemInfo.h ${CMAKE_CURRENT_LIST_DIR}/RiuWellLogPlot.h ${CMAKE_CURRENT_LIST_DIR}/RiuWellLogTrack.h ${CMAKE_CURRENT_LIST_DIR}/RiuPlotAnnotationTool.h @@ -71,6 +74,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuMohrsCirclePlot.h ${CMAKE_CURRENT_LIST_DIR}/RiuPlotMainWindowTools.h ${CMAKE_CURRENT_LIST_DIR}/Riu3DMainWindowTools.h ${CMAKE_CURRENT_LIST_DIR}/RiuDockWidgetTools.h +${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotItemGroup.h +${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -80,7 +85,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuDragDrop.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuFemResultTextBuilder.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuGeoQuestNavigation.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuInterfaceToViewWindow.cpp -${CMAKE_CURRENT_LIST_DIR}/RiuLineSegmentQwtPlotCurve.cpp +${CMAKE_CURRENT_LIST_DIR}/RiuQwtSymbol.cpp +${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotCurve.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuRimQwtPlotCurve.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuPlotMainWindow.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuMainWindow.cpp @@ -92,6 +98,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuProjectPropertyView.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuPropertyViewTabWidget.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuPvtPlotPanel.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuPvtPlotUpdater.cpp +${CMAKE_CURRENT_LIST_DIR}/RiuQwtLinearScaleEngine.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuQwtScalePicker.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuQwtCurvePointTracker.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotWheelZoomer.cpp @@ -115,6 +122,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuToolTipMenu.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuTreeViewEventFilter.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuViewer.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuViewerCommands.cpp +${CMAKE_CURRENT_LIST_DIR}/RiuPickItemInfo.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuWellLogPlot.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuWellLogTrack.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuPlotAnnotationTool.cpp @@ -142,6 +150,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiuMohrsCirclePlot.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuPlotMainWindowTools.cpp ${CMAKE_CURRENT_LIST_DIR}/Riu3DMainWindowTools.cpp ${CMAKE_CURRENT_LIST_DIR}/RiuDockWidgetTools.cpp +${CMAKE_CURRENT_LIST_DIR}/RiuQwtPlotItemGroup.cpp +${CMAKE_CURRENT_LIST_DIR}/RiuWellPathComponentPlotItem.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/UserInterface/RiuCadNavigation.h b/ApplicationCode/UserInterface/RiuCadNavigation.h index ec16fe06d8..ae39dd1db9 100644 --- a/ApplicationCode/UserInterface/RiuCadNavigation.h +++ b/ApplicationCode/UserInterface/RiuCadNavigation.h @@ -25,7 +25,7 @@ class RiuCadNavigation : public caf::TrackBallBasedNavigation { public: RiuCadNavigation(); - virtual ~RiuCadNavigation(); + ~RiuCadNavigation() override; protected: - virtual bool handleInputEvent(QInputEvent* inputEvent); + bool handleInputEvent(QInputEvent* inputEvent) override; }; diff --git a/ApplicationCode/UserInterface/RiuCursors.cpp b/ApplicationCode/UserInterface/RiuCursors.cpp index 1996c17ccb..ea339eb817 100644 --- a/ApplicationCode/UserInterface/RiuCursors.cpp +++ b/ApplicationCode/UserInterface/RiuCursors.cpp @@ -72,7 +72,7 @@ QCursor RiuCursors::cursorFromFile(const QString& fileName, int hotspotX, int return QCursor(); } - QRgb maskClr = image.pixel(0, 0); + //QRgb maskClr = image.pixel(0, 0); //QImage imgMask = image.createMaskFromColor(maskClr, Qt::MaskInColor); QImage imgMask = image.createHeuristicMask(true); diff --git a/ApplicationCode/UserInterface/RiuCvfOverlayItemWidget.h b/ApplicationCode/UserInterface/RiuCvfOverlayItemWidget.h index 46f670b479..fe9541873f 100644 --- a/ApplicationCode/UserInterface/RiuCvfOverlayItemWidget.h +++ b/ApplicationCode/UserInterface/RiuCvfOverlayItemWidget.h @@ -36,7 +36,7 @@ class RiuCvfOverlayItemWidget : public QWidget Q_OBJECT public: explicit RiuCvfOverlayItemWidget(QWidget* parent = nullptr); - ~RiuCvfOverlayItemWidget(); + ~RiuCvfOverlayItemWidget() override; void updateFromOverlyItem( cvf::OverlayItem * item); diff --git a/ApplicationCode/UserInterface/RiuDragDrop.h b/ApplicationCode/UserInterface/RiuDragDrop.h index b497dc2b8d..9227789afd 100644 --- a/ApplicationCode/UserInterface/RiuDragDrop.h +++ b/ApplicationCode/UserInterface/RiuDragDrop.h @@ -43,17 +43,17 @@ class RiuDragDrop : public caf::PdmUiDragDropInterface { public: RiuDragDrop(); - virtual ~RiuDragDrop(); + ~RiuDragDrop() override; protected: - virtual Qt::DropActions supportedDropActions() const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); - virtual QMimeData* mimeData(const QModelIndexList &indexes) const; - virtual QStringList mimeTypes() const; + Qt::DropActions supportedDropActions() const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; + QMimeData* mimeData(const QModelIndexList &indexes) const override; + QStringList mimeTypes() const override; - virtual void onDragCanceled(); - virtual void onProposedDropActionUpdated(Qt::DropAction action); + void onDragCanceled() override; + void onProposedDropActionUpdated(Qt::DropAction action) override; private: void moveCasesToGridGroup(caf::PdmObjectGroup& objectGroup, RimIdenticalGridCaseGroup* gridCaseGroup); diff --git a/ApplicationCode/UserInterface/RiuEditPerforationCollectionWidget.cpp b/ApplicationCode/UserInterface/RiuEditPerforationCollectionWidget.cpp index 2e4ef5fdff..4c5498202c 100644 --- a/ApplicationCode/UserInterface/RiuEditPerforationCollectionWidget.cpp +++ b/ApplicationCode/UserInterface/RiuEditPerforationCollectionWidget.cpp @@ -54,7 +54,7 @@ RiuEditPerforationCollectionWidget::RiuEditPerforationCollectionWidget(QWidget* connect(m_pdmTableView->tableView(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint))); - m_pdmTableView->setListField(&(m_perforationCollection->m_perforations)); + m_pdmTableView->setChildArrayField(&(m_perforationCollection->m_perforations)); QHeaderView* verticalHeader = m_pdmTableView->tableView()->verticalHeader(); verticalHeader->setResizeMode(QHeaderView::Interactive); @@ -79,7 +79,7 @@ RiuEditPerforationCollectionWidget::RiuEditPerforationCollectionWidget(QWidget* //-------------------------------------------------------------------------------------------------- RiuEditPerforationCollectionWidget::~RiuEditPerforationCollectionWidget() { - m_pdmTableView->setListField(nullptr); + m_pdmTableView->setChildArrayField(nullptr); caf::SelectionManager::instance()->setActiveChildArrayFieldHandle(nullptr); } diff --git a/ApplicationCode/UserInterface/RiuEditPerforationCollectionWidget.h b/ApplicationCode/UserInterface/RiuEditPerforationCollectionWidget.h index 24aa05e04d..0e4d9a537f 100644 --- a/ApplicationCode/UserInterface/RiuEditPerforationCollectionWidget.h +++ b/ApplicationCode/UserInterface/RiuEditPerforationCollectionWidget.h @@ -36,7 +36,7 @@ class RiuEditPerforationCollectionWidget : public QDialog Q_OBJECT public: RiuEditPerforationCollectionWidget(QWidget* parent, RimPerforationCollection* perforationCollection); - ~RiuEditPerforationCollectionWidget(); + ~RiuEditPerforationCollectionWidget() override; private slots: void customMenuRequested(QPoint pos); diff --git a/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.cpp b/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.cpp index 273d6f655a..0ebd106e78 100644 --- a/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.cpp +++ b/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.cpp @@ -72,7 +72,7 @@ RiuExportMultipleSnapshotsWidget::RiuExportMultipleSnapshotsWidget(QWidget* pare connect(m_pdmTableView->tableView(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint))); - m_pdmTableView->setListField(&(project->multiSnapshotDefinitions())); + m_pdmTableView->setChildArrayField(&(project->multiSnapshotDefinitions())); QHeaderView* verticalHeader = m_pdmTableView->tableView()->verticalHeader(); verticalHeader->setResizeMode(QHeaderView::Interactive); @@ -126,7 +126,7 @@ RiuExportMultipleSnapshotsWidget::RiuExportMultipleSnapshotsWidget(QWidget* pare //-------------------------------------------------------------------------------------------------- RiuExportMultipleSnapshotsWidget::~RiuExportMultipleSnapshotsWidget() { - m_pdmTableView->setListField(nullptr); + m_pdmTableView->setChildArrayField(nullptr); caf::SelectionManager::instance()->setActiveChildArrayFieldHandle(nullptr); } diff --git a/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.h b/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.h index d963555dfa..c45446faec 100644 --- a/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.h +++ b/ApplicationCode/UserInterface/RiuExportMultipleSnapshotsWidget.h @@ -34,7 +34,7 @@ class RiuExportMultipleSnapshotsWidget : public QDialog Q_OBJECT public: RiuExportMultipleSnapshotsWidget(QWidget* parent, RimProject* project); - ~RiuExportMultipleSnapshotsWidget(); + ~RiuExportMultipleSnapshotsWidget() override; void addSnapshotItemFromActiveView(); void addEmptySnapshotItems(size_t itemCount); diff --git a/ApplicationCode/UserInterface/RiuFemResultTextBuilder.cpp b/ApplicationCode/UserInterface/RiuFemResultTextBuilder.cpp index d0fcd44f82..d56068d09e 100644 --- a/ApplicationCode/UserInterface/RiuFemResultTextBuilder.cpp +++ b/ApplicationCode/UserInterface/RiuFemResultTextBuilder.cpp @@ -56,16 +56,16 @@ RiuFemResultTextBuilder::RiuFemResultTextBuilder(RimGeoMechView* reservoirView, m_cellIndex = cellIndex; m_timeStepIndex = timeStepIndex; - m_intersectionPoint = cvf::Vec3d::UNDEFINED; + m_intersectionPointInDisplay = cvf::Vec3d::UNDEFINED; m_face = cvf::StructGridInterface::NO_FACE; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuFemResultTextBuilder::setIntersectionPoint(cvf::Vec3d intersectionPoint) +void RiuFemResultTextBuilder::setIntersectionPointInDisplay(cvf::Vec3d intersectionPointInDisplay) { - m_intersectionPoint = intersectionPoint; + m_intersectionPointInDisplay = intersectionPointInDisplay; } //-------------------------------------------------------------------------------------------------- @@ -141,7 +141,7 @@ QString RiuFemResultTextBuilder::geometrySelectionText(QString itemSeparator) size_t i = 0; size_t j = 0; size_t k = 0; - if (geomData->femParts()->part(m_gridIndex)->structGrid()->ijkFromCellIndex(m_cellIndex, &i, &j, &k)) + if (geomData->femParts()->part(m_gridIndex)->getOrCreateStructGrid()->ijkFromCellIndex(m_cellIndex, &i, &j, &k)) { // Adjust to 1-based Eclipse indexing i++; @@ -153,13 +153,13 @@ QString RiuFemResultTextBuilder::geometrySelectionText(QString itemSeparator) QString formattedText; if (m_2dIntersectionView) { - formattedText.sprintf("Horizontal length from well start: %.2f", m_intersectionPoint.x()); + formattedText.sprintf("Horizontal length from well start: %.2f", m_intersectionPointInDisplay.x()); text += formattedText + itemSeparator; - cvf::Mat4d t = m_2dIntersectionView->flatIntersectionPartMgr()->unflattenTransformMatrix(m_intersectionPoint); + cvf::Mat4d t = m_2dIntersectionView->flatIntersectionPartMgr()->unflattenTransformMatrix(m_intersectionPointInDisplay); if (!t.isZero()) { - cvf::Vec3d intPt = m_intersectionPoint.getTransformedPoint(t); + cvf::Vec3d intPt = m_intersectionPointInDisplay.getTransformedPoint(t); formattedText.sprintf("Intersection point : [E: %.2f, N: %.2f, Depth: %.2f]", intPt.x(), intPt.y(), -intPt.z()); text += formattedText; } @@ -167,7 +167,7 @@ QString RiuFemResultTextBuilder::geometrySelectionText(QString itemSeparator) else { cvf::ref transForm = m_reservoirView->displayCoordTransform(); - cvf::Vec3d domainCoord = transForm->translateToDomainCoord(m_intersectionPoint); + cvf::Vec3d domainCoord = transForm->translateToDomainCoord(m_intersectionPointInDisplay); formattedText.sprintf("Intersection point : [E: %.2f, N: %.2f, Depth: %.2f]", domainCoord.x(), domainCoord.y(), -domainCoord.z()); text += formattedText; @@ -224,7 +224,7 @@ QString RiuFemResultTextBuilder::formationDetails() { size_t i = 0; size_t j = 0; - geomData->femParts()->part(m_gridIndex)->structGrid()->ijkFromCellIndex(m_cellIndex, &i, &j, &k); + geomData->femParts()->part(m_gridIndex)->getOrCreateStructGrid()->ijkFromCellIndex(m_cellIndex, &i, &j, &k); } } } @@ -386,11 +386,12 @@ QString RiuFemResultTextBuilder::closestNodeResultText(RimGeoMechResultDefinitio RigFemPart* femPart = geomData->femParts()->part(m_gridIndex); RigFemResultPosEnum activeResultPosition = resultColors->resultPositionType(); + cvf::Vec3d intersectionPointInDomain = m_reservoirView->displayCoordTransform()->translateToDomainCoord(m_intersectionPointInDisplay); RigFemClosestResultIndexCalculator closestIndexCalc(femPart, activeResultPosition, m_cellIndex, m_face, - m_intersectionPoint); + intersectionPointInDomain); int resultIndex = closestIndexCalc.resultIndexToClosestResult(); int closestNodeId = closestIndexCalc.closestNodeId(); int closestElmNodResIdx = closestIndexCalc.closestElementNodeResIdx(); diff --git a/ApplicationCode/UserInterface/RiuFemResultTextBuilder.h b/ApplicationCode/UserInterface/RiuFemResultTextBuilder.h index 9754516c9d..6d1953b16e 100644 --- a/ApplicationCode/UserInterface/RiuFemResultTextBuilder.h +++ b/ApplicationCode/UserInterface/RiuFemResultTextBuilder.h @@ -45,7 +45,7 @@ class RiuFemResultTextBuilder public: RiuFemResultTextBuilder(RimGeoMechView* reservoirView, int gridIndex, int cellIndex, int timeStepIndex); void setFace(int face); - void setIntersectionPoint(cvf::Vec3d intersectionPoint); + void setIntersectionPointInDisplay(cvf::Vec3d intersectionPointInDisplay); void setIntersectionTriangle(const std::array& triangle); void set2dIntersectionView(Rim2dIntersectionView* intersectionView); @@ -75,5 +75,5 @@ class RiuFemResultTextBuilder bool m_isIntersectionTriangleSet; std::array m_intersectionTriangle; - cvf::Vec3d m_intersectionPoint; + cvf::Vec3d m_intersectionPointInDisplay; }; diff --git a/ApplicationCode/UserInterface/RiuFemTimeHistoryResultAccessor.cpp b/ApplicationCode/UserInterface/RiuFemTimeHistoryResultAccessor.cpp index a0db095e51..619847387a 100644 --- a/ApplicationCode/UserInterface/RiuFemTimeHistoryResultAccessor.cpp +++ b/ApplicationCode/UserInterface/RiuFemTimeHistoryResultAccessor.cpp @@ -37,13 +37,13 @@ RiuFemTimeHistoryResultAccessor::RiuFemTimeHistoryResultAccessor(RigGeoMechCaseD size_t gridIndex, int elementIndex, int face, - const cvf::Vec3d& intersectionPoint) + const cvf::Vec3d& intersectionPointInDomain) : m_geoMechCaseData(geomData), m_femResultAddress(femResultAddress), m_gridIndex(gridIndex), m_elementIndex(elementIndex), m_face(face), - m_intersectionPoint(intersectionPoint), + m_intersectionPointInDomain(intersectionPointInDomain), m_hasIntersectionTriangle(false) { computeTimeHistoryData(); @@ -57,14 +57,14 @@ RiuFemTimeHistoryResultAccessor::RiuFemTimeHistoryResultAccessor(RigGeoMechCaseD size_t gridIndex, int elementIndex, int face, - const cvf::Vec3d& intersectionPoint, + const cvf::Vec3d& intersectionPointInDomain, const std::array& intersectionTriangle) : m_geoMechCaseData(geomData), m_femResultAddress(femResultAddress), m_gridIndex(gridIndex), m_elementIndex(elementIndex), m_face(face), - m_intersectionPoint(intersectionPoint), + m_intersectionPointInDomain(intersectionPointInDomain), m_hasIntersectionTriangle(true), m_intersectionTriangle(intersectionTriangle) { @@ -87,14 +87,14 @@ QString RiuFemTimeHistoryResultAccessor::geometrySelectionText() const size_t i = 0; size_t j = 0; size_t k = 0; - if (m_geoMechCaseData->femParts()->part(m_gridIndex)->structGrid()->ijkFromCellIndex(m_elementIndex, &i, &j, &k)) + if (m_geoMechCaseData->femParts()->part(m_gridIndex)->getOrCreateStructGrid()->ijkFromCellIndex(m_elementIndex, &i, &j, &k)) { // Adjust to 1-based Eclipse indexing i++; j++; k++; - cvf::Vec3d domainCoord = m_intersectionPoint; + cvf::Vec3d domainCoord = m_intersectionPointInDomain; text += QString(", ijk[%1, %2, %3] ").arg(i).arg(j).arg(k); QString formattedText; @@ -126,7 +126,7 @@ void RiuFemTimeHistoryResultAccessor::computeTimeHistoryData() m_femResultAddress.resultPosType, m_elementIndex, m_face, - m_intersectionPoint ); + m_intersectionPointInDomain ); int scalarResultIndex = closestCalc.resultIndexToClosestResult(); m_closestNodeId = closestCalc.closestNodeId(); diff --git a/ApplicationCode/UserInterface/RiuFemTimeHistoryResultAccessor.h b/ApplicationCode/UserInterface/RiuFemTimeHistoryResultAccessor.h index 6df48f7d66..b3f601fe6a 100644 --- a/ApplicationCode/UserInterface/RiuFemTimeHistoryResultAccessor.h +++ b/ApplicationCode/UserInterface/RiuFemTimeHistoryResultAccessor.h @@ -36,14 +36,14 @@ class RiuFemTimeHistoryResultAccessor size_t gridIndex, int elementIndex, int face, - const cvf::Vec3d& intersectionPoint); + const cvf::Vec3d& intersectionPointInDomain); RiuFemTimeHistoryResultAccessor(RigGeoMechCaseData* geomData, RigFemResultAddress femResultAddress, size_t gridIndex, int elementIndex, int face, - const cvf::Vec3d& intersectionPoint, + const cvf::Vec3d& intersectionPointInDomain, const std::array& m_intersectionTriangle); QString geometrySelectionText() const; @@ -62,7 +62,7 @@ class RiuFemTimeHistoryResultAccessor int m_face; int m_closestNodeId; - cvf::Vec3d m_intersectionPoint; + cvf::Vec3d m_intersectionPointInDomain; bool m_hasIntersectionTriangle; std::array m_intersectionTriangle; diff --git a/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp index dfb3b62184..a39964cf53 100644 --- a/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp +++ b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.cpp @@ -22,7 +22,7 @@ #include "RimFlowCharacteristicsPlot.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuQwtPlotWheelZoomer.h" #include "RiuQwtPlotZoomer.h" #include "RiuResultQwtPlot.h" @@ -151,7 +151,7 @@ void RiuFlowCharacteristicsPlot::addCurveWithLargeSymbol(QwtPlot* plot, const QS curve->setSymbol(symbol); - // Add date and value twice to avoid a cross as symbol generated by RiuLineSegmentQwtPlotCurve + // Add date and value twice to avoid a cross as symbol generated by RiuQwtPlotCurve std::vector dateTimes; dateTimes.push_back(dateTime); @@ -167,9 +167,9 @@ void RiuFlowCharacteristicsPlot::addCurveWithLargeSymbol(QwtPlot* plot, const QS //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RiuLineSegmentQwtPlotCurve* RiuFlowCharacteristicsPlot::createEmptyCurve(QwtPlot* plot, const QString& curveName, const QColor& curveColor ) +RiuQwtPlotCurve* RiuFlowCharacteristicsPlot::createEmptyCurve(QwtPlot* plot, const QString& curveName, const QColor& curveColor ) { - RiuLineSegmentQwtPlotCurve* plotCurve = new RiuLineSegmentQwtPlotCurve(curveName); + RiuQwtPlotCurve* plotCurve = new RiuQwtPlotCurve(curveName); plotCurve->setTitle(curveName); plotCurve->setPen(QPen(curveColor)); @@ -184,7 +184,7 @@ void RiuFlowCharacteristicsPlot::addFlowCapStorageCapCurve(const QDateTime& date { CVF_ASSERT(!m_dateToColorMap.empty()); - RiuLineSegmentQwtPlotCurve* plotCurve = createEmptyCurve(m_flowCapVsStorageCapPlot, dateTime.toString(), m_dateToColorMap[dateTime]); + RiuQwtPlotCurve* plotCurve = createEmptyCurve(m_flowCapVsStorageCapPlot, dateTime.toString(), m_dateToColorMap[dateTime]); plotCurve->setSamplesFromXValuesAndYValues(xVals, yVals, false); m_flowCapVsStorageCapPlot->replot(); } @@ -196,7 +196,7 @@ void RiuFlowCharacteristicsPlot::addSweepEfficiencyCurve(const QDateTime& dateTi { CVF_ASSERT(!m_dateToColorMap.empty()); - RiuLineSegmentQwtPlotCurve* plotCurve = createEmptyCurve(m_sweepEffPlot, dateTime.toString(), m_dateToColorMap[dateTime]); + RiuQwtPlotCurve* plotCurve = createEmptyCurve(m_sweepEffPlot, dateTime.toString(), m_dateToColorMap[dateTime]); plotCurve->setSamplesFromXValuesAndYValues(xVals, yVals, false); m_sweepEffPlot->replot(); diff --git a/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h index eeaf4f902b..13d2b05bce 100644 --- a/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h +++ b/ApplicationCode/UserInterface/RiuFlowCharacteristicsPlot.h @@ -30,7 +30,7 @@ class RimFlowCharacteristicsPlot; class RiuNightchartsWidget; class RiuResultQwtPlot; -class RiuLineSegmentQwtPlotCurve; +class RiuQwtPlotCurve; class QLabel; @@ -48,7 +48,7 @@ class RiuFlowCharacteristicsPlot : public QFrame, public RiuInterfaceToViewWindo Q_OBJECT; public: RiuFlowCharacteristicsPlot(RimFlowCharacteristicsPlot* plotDefinition, QWidget* parent = nullptr); - virtual ~RiuFlowCharacteristicsPlot(); + ~RiuFlowCharacteristicsPlot() override; void setLorenzCurve(const QStringList& dateTimeStrings, const std::vector& dateTimes, const std::vector& timeHistoryValues); void addFlowCapStorageCapCurve(const QDateTime& dateTime, const std::vector& xVals, const std::vector& yVals); @@ -60,14 +60,14 @@ class RiuFlowCharacteristicsPlot : public QFrame, public RiuInterfaceToViewWindo void showLegend(bool show); RimFlowCharacteristicsPlot* ownerPlotDefinition(); - virtual RimViewWindow* ownerViewWindow() const override; + RimViewWindow* ownerViewWindow() const override; static void addWindowZoom(QwtPlot* plot); - static RiuLineSegmentQwtPlotCurve* createEmptyCurve(QwtPlot* plot, const QString& curveName, const QColor& curveColor); + static RiuQwtPlotCurve* createEmptyCurve(QwtPlot* plot, const QString& curveName, const QColor& curveColor); protected: - virtual QSize sizeHint() const override; - virtual QSize minimumSizeHint() const override; + QSize sizeHint() const override; + QSize minimumSizeHint() const override; private: void setDefaults(); diff --git a/ApplicationCode/UserInterface/RiuGeoQuestNavigation.h b/ApplicationCode/UserInterface/RiuGeoQuestNavigation.h index 2a2814bea3..964c7ef911 100644 --- a/ApplicationCode/UserInterface/RiuGeoQuestNavigation.h +++ b/ApplicationCode/UserInterface/RiuGeoQuestNavigation.h @@ -26,7 +26,7 @@ class RiuGeoQuestNavigation : public caf::TrackBallBasedNavigation { public: RiuGeoQuestNavigation(); - virtual ~RiuGeoQuestNavigation(); + ~RiuGeoQuestNavigation() override; protected: - virtual bool handleInputEvent(QInputEvent* inputEvent); + bool handleInputEvent(QInputEvent* inputEvent) override; }; diff --git a/ApplicationCode/UserInterface/RiuGridStatisticsHistogramWidget.h b/ApplicationCode/UserInterface/RiuGridStatisticsHistogramWidget.h index d6f08839fa..8b4eae7c85 100644 --- a/ApplicationCode/UserInterface/RiuGridStatisticsHistogramWidget.h +++ b/ApplicationCode/UserInterface/RiuGridStatisticsHistogramWidget.h @@ -37,7 +37,7 @@ class RiuGridStatisticsHistogramWidget : public QWidget void setMean(double mean) {m_mean = mean;} protected: - virtual void paintEvent(QPaintEvent* event); + void paintEvent(QPaintEvent* event) override; private: void draw(QPainter *painter,int x, int y, int width, int height ); diff --git a/ApplicationCode/UserInterface/RiuLineSegmentQwtPlotCurve.cpp b/ApplicationCode/UserInterface/RiuLineSegmentQwtPlotCurve.cpp deleted file mode 100644 index 9db96c0326..0000000000 --- a/ApplicationCode/UserInterface/RiuLineSegmentQwtPlotCurve.cpp +++ /dev/null @@ -1,243 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015- Statoil ASA -// Copyright (C) 2015- Ceetron Solutions AS -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RiuLineSegmentQwtPlotCurve.h" - -#include "qwt_symbol.h" -#include "RigCurveDataTools.h" -#include "qwt_date.h" -#include "qwt_point_mapper.h" -#include "qwt_painter.h" - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiuLineSegmentQwtPlotCurve::RiuLineSegmentQwtPlotCurve(const QString &title) - : QwtPlotCurve(title) -{ - this->setLegendAttribute(QwtPlotCurve::LegendShowLine, true); - this->setLegendAttribute(QwtPlotCurve::LegendShowSymbol, true); - this->setLegendAttribute(QwtPlotCurve::LegendShowBrush, true); - - this->setRenderHint(QwtPlotItem::RenderAntialiased, true); - - m_symbolSkipPixelDistance = 10.0f; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RiuLineSegmentQwtPlotCurve::~RiuLineSegmentQwtPlotCurve() -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuLineSegmentQwtPlotCurve::setSamplesFromXValuesAndYValues(const std::vector& xValues, const std::vector& yValues, bool keepOnlyPositiveValues) -{ - CVF_ASSERT(xValues.size() == yValues.size()); - - QPolygonF points; - std::vector< std::pair > filteredIntervals; - { - std::vector filteredYValues; - std::vector filteredXValues; - - { - auto intervalsOfValidValues = RigCurveDataTools::calculateIntervalsOfValidValues(yValues, keepOnlyPositiveValues); - - RigCurveDataTools::getValuesByIntervals(yValues, intervalsOfValidValues, &filteredYValues); - RigCurveDataTools::getValuesByIntervals(xValues, intervalsOfValidValues, &filteredXValues); - - filteredIntervals = RigCurveDataTools::computePolyLineStartStopIndices(intervalsOfValidValues); - } - - points.reserve(static_cast(filteredXValues.size())); - for ( size_t i = 0; i < filteredXValues.size(); i++ ) - { - points << QPointF(filteredXValues[i], filteredYValues[i]); - } - } - - this->setSamples(points); - this->setLineSegmentStartStopIndices(filteredIntervals); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuLineSegmentQwtPlotCurve::setSamplesFromDatesAndYValues(const std::vector& dateTimes, const std::vector& yValues, bool keepOnlyPositiveValues) -{ - setSamplesFromXValuesAndYValues(RiuLineSegmentQwtPlotCurve::fromQDateTime(dateTimes), yValues, keepOnlyPositiveValues); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuLineSegmentQwtPlotCurve::setSamplesFromTimeTAndYValues(const std::vector& dateTimes, const std::vector& yValues, bool keepOnlyPositiveValues) -{ - setSamplesFromXValuesAndYValues(RiuLineSegmentQwtPlotCurve::fromTime_t(dateTimes), yValues, keepOnlyPositiveValues); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuLineSegmentQwtPlotCurve::drawCurve(QPainter* p, int style, - const QwtScaleMap& xMap, const QwtScaleMap& yMap, - const QRectF& canvasRect, int from, int to) const -{ - size_t intervalCount = m_polyLineStartStopIndices.size(); - if (intervalCount > 0) - { - for (size_t intIdx = 0; intIdx < intervalCount; intIdx++) - { - if (m_polyLineStartStopIndices[intIdx].first == m_polyLineStartStopIndices[intIdx].second) - { - // Use a symbol to draw a single value, as a single value will not be visible - // when using QwtPlotCurve::drawCurve without symbols activated - - QwtSymbol symbol(QwtSymbol::XCross); - symbol.setSize(10, 10); - - QwtPlotCurve::drawSymbols(p, symbol, xMap, yMap, canvasRect, (int) m_polyLineStartStopIndices[intIdx].first, (int) m_polyLineStartStopIndices[intIdx].second); - } - else - { - QwtPlotCurve::drawCurve(p, style, xMap, yMap, canvasRect, (int) m_polyLineStartStopIndices[intIdx].first, (int) m_polyLineStartStopIndices[intIdx].second); - } - } - } - else - { - QwtPlotCurve::drawCurve(p, style, xMap, yMap, canvasRect, from, to); - } -}; - -//-------------------------------------------------------------------------------------------------- -/// Drawing symbols but skipping if they are to close to the previous one -//-------------------------------------------------------------------------------------------------- -void RiuLineSegmentQwtPlotCurve::drawSymbols(QPainter *painter, const QwtSymbol &symbol, - const QwtScaleMap &xMap, const QwtScaleMap &yMap, - const QRectF &canvasRect, int from, int to) const -{ - if (m_symbolSkipPixelDistance <= 0) - { - QwtPlotCurve::drawSymbols(painter, symbol, xMap, yMap, canvasRect, from, to); - return; - } - - QwtPointMapper mapper; - mapper.setFlag(QwtPointMapper::RoundPoints, - QwtPainter::roundingAlignment(painter)); - mapper.setFlag(QwtPointMapper::WeedOutPoints, - testPaintAttribute(QwtPlotCurve::FilterPoints)); - mapper.setBoundingRect(canvasRect); - - const QPolygonF points = mapper.toPointsF(xMap, yMap, - data(), from, to); - int pointCount = points.size(); - - QPolygonF filteredPoints; - QPointF lastDrawnSymbolPos; - - if (pointCount > 0) - { - filteredPoints.push_back(points[0]); - lastDrawnSymbolPos = points[0]; - } - - float sqSkipDist = m_symbolSkipPixelDistance*m_symbolSkipPixelDistance; - - for(int pIdx = 1; pIdx < pointCount -1 ; ++pIdx) - { - QPointF diff = points[pIdx] - lastDrawnSymbolPos; - float sqDistBetweenSymbols = diff.x()*diff.x() + diff.y()*diff.y(); - - if(sqDistBetweenSymbols > sqSkipDist) - { - filteredPoints.push_back(points[pIdx]); - lastDrawnSymbolPos = points[pIdx]; - } - } - - if(pointCount > 1) filteredPoints.push_back(points.back()); - - - if(filteredPoints.size() > 0) - symbol.drawSymbols(painter, filteredPoints); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuLineSegmentQwtPlotCurve::setLineSegmentStartStopIndices(const std::vector< std::pair >& lineSegmentStartStopIndices) -{ - m_polyLineStartStopIndices = lineSegmentStartStopIndices; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuLineSegmentQwtPlotCurve::setSymbolSkipPixelDistance(float distance) -{ - m_symbolSkipPixelDistance = distance >= 0.0f ? distance: 0.0f; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RiuLineSegmentQwtPlotCurve::fromQDateTime(const std::vector& dateTimes) -{ - std::vector doubleValues; - - if (!dateTimes.empty()) - { - doubleValues.reserve(dateTimes.size()); - - for (const auto& dt : dateTimes) - { - doubleValues.push_back(QwtDate::toDouble(dt)); - } - } - - return doubleValues; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RiuLineSegmentQwtPlotCurve::fromTime_t(const std::vector& timeSteps) -{ - std::vector doubleValues; - - if (!timeSteps.empty()) - { - doubleValues.reserve(timeSteps.size()); - for (const auto& time : timeSteps) - { - double milliSecSinceEpoch = time * 1000; // This is kind of hack, as the c++ standard does not state what time_t is. "Almost always" secs since epoch according to cppreference.com - - doubleValues.push_back(milliSecSinceEpoch); - } - } - - return doubleValues; -} diff --git a/ApplicationCode/UserInterface/RiuMainWindow.cpp b/ApplicationCode/UserInterface/RiuMainWindow.cpp index 5a9eb6ef90..bd0b04ce24 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMainWindow.cpp @@ -26,6 +26,7 @@ #include "RiaRegressionTest.h" #include "RiaRegressionTestRunner.h" +#include "RimContourMapView.h" #include "Rim2dIntersectionView.h" #include "Rim3dView.h" #include "RimCellEdgeColors.h" @@ -41,6 +42,9 @@ #include "RimIntersection.h" #include "RimProject.h" #include "RimSimWellInViewCollection.h" +#include "RimViewLinker.h" +#include "RimViewLinkerCollection.h" +#include "RimViewWindow.h" #include "RiuDockWidgetTools.h" #include "RiuDragDrop.h" @@ -61,6 +65,7 @@ #include "cafAnimationToolBar.h" #include "cafCmdExecCommandManager.h" #include "cafCmdFeatureManager.h" +#include "cafMemoryInspector.h" #include "cafPdmSettings.h" #include "cafPdmUiPropertyView.h" #include "cafPdmUiPropertyViewDialog.h" @@ -83,12 +88,16 @@ #include #include #include +#include #include #include +#include #include #include #include +#include + //================================================================================================== /// @@ -111,7 +120,8 @@ RiuMainWindow::RiuMainWindow() m_pvtPlotPanel(nullptr), m_mohrsCirclePlot(nullptr), m_windowMenu(nullptr), - m_blockSlotSubWindowActivated(false) + m_blockSlotSubWindowActivated(false), + m_holoLensToolBar(nullptr) { CVF_ASSERT(sm_mainWindowInstance == nullptr); @@ -139,6 +149,24 @@ RiuMainWindow::RiuMainWindow() // Enabling the line below will activate the undo stack // When enableUndoCommandSystem is set false, all commands are executed and deleted immediately //caf::CmdExecCommandManager::instance()->enableUndoCommandSystem(true); + + m_memoryCriticalWarning = new QLabel(""); + m_memoryUsedButton = new QToolButton(nullptr); + m_memoryTotalStatus = new QLabel(""); + + m_memoryUsedButton->setDefaultAction(caf::CmdFeatureManager::instance()->action("RicShowMemoryCleanupDialogFeature")); + + statusBar()->addPermanentWidget(m_memoryCriticalWarning); + statusBar()->addPermanentWidget(m_memoryUsedButton); + statusBar()->addPermanentWidget(m_memoryTotalStatus); + + + + updateMemoryUsage(); + + m_memoryRefreshTimer = new QTimer(this); + connect(m_memoryRefreshTimer, SIGNAL(timeout()), this, SLOT(updateMemoryUsage())); + m_memoryRefreshTimer->start(1000); } @@ -180,7 +208,7 @@ void RiuMainWindow::initializeGuiNewProjectLoaded() if (statusBar() && !RiaRegressionTestRunner::instance()->isRunningRegressionTests()) { - statusBar()->showMessage("Ready ..."); + statusBar()->showMessage("Ready ..."); } } @@ -391,6 +419,7 @@ void RiuMainWindow::createMenus() importMenu->addSeparator(); QMenu* importGeoMechMenu = importMenu->addMenu(QIcon(":/GeoMechCase48x48.png"), "Geo Mechanical Cases"); importGeoMechMenu->addAction(cmdFeatureMgr->action("RicImportGeoMechCaseFeature")); + importGeoMechMenu->addAction(cmdFeatureMgr->action("RicImportGeoMechCaseTimeStepFilterFeature")); importGeoMechMenu->addAction(cmdFeatureMgr->action("RicImportElementPropertyFeature")); #endif @@ -412,6 +441,7 @@ void RiuMainWindow::createMenus() exportMenu->addSeparator(); exportMenu->addAction(cmdFeatureMgr->action("RicSaveEclipseInputActiveVisibleCellsFeature")); exportMenu->addAction(cmdFeatureMgr->action("RicExportCompletionsForVisibleWellPathsFeature")); + exportMenu->addAction(cmdFeatureMgr->action("RicExportVisibleWellPathsFeature")); fileMenu->addSeparator(); fileMenu->addAction(cmdFeatureMgr->action("RicSaveProjectFeature")); @@ -437,6 +467,8 @@ void RiuMainWindow::createMenus() QMenu* editMenu = menuBar()->addMenu("&Edit"); editMenu->addAction(cmdFeatureMgr->action("RicSnapshotViewToClipboardFeature")); editMenu->addSeparator(); + editMenu->addAction(cmdFeatureMgr->action("RicShowMemoryCleanupDialogFeature")); + editMenu->addSeparator(); editMenu->addAction(cmdFeatureMgr->action("RicEditPreferencesFeature")); connect(editMenu, SIGNAL(aboutToShow()), SLOT(slotRefreshEditActions())); @@ -468,6 +500,10 @@ void RiuMainWindow::createMenus() testMenu->addAction(m_executePaintEventPerformanceTest); testMenu->addAction(cmdFeatureMgr->action("RicLaunchUnitTestsFeature")); testMenu->addAction(cmdFeatureMgr->action("RicRunCommandFileFeature")); + testMenu->addSeparator(); + + testMenu->addAction(cmdFeatureMgr->action("RicHoloLensExportToFolderFeature")); + testMenu->addAction(cmdFeatureMgr->action("RicHoloLensCreateDummyFiledBackedSessionFeature")); // Windows menu m_windowMenu = menuBar()->addMenu("&Windows"); @@ -553,6 +589,15 @@ void RiuMainWindow::createToolBars() dsToolBar->addAction(m_showWellCellsAction); } + { + m_holoLensToolBar = addToolBar(tr("HoloLens")); + m_holoLensToolBar->setObjectName(m_holoLensToolBar->windowTitle()); + + m_holoLensToolBar->addAction(cmdFeatureMgr->action("RicHoloLensCreateSessionFeature")); + m_holoLensToolBar->addAction(cmdFeatureMgr->action("RicHoloLensTerminateSessionFeature")); + m_holoLensToolBar->addAction(cmdFeatureMgr->action("RicHoloLensExportToSharingServerFeature")); + } + RiaApplication* app = RiaApplication::instance(); if (app->preferences()->showTestToolbar()) { @@ -566,7 +611,6 @@ void RiuMainWindow::createToolBars() // Create animation toolbar m_animationToolBar = new caf::AnimationToolBar("Animation", this); addToolBar(m_animationToolBar); - //connect(m_animationToolBar, SIGNAL(signalFrameRateChanged(double)), SLOT(slotFramerateChanged(double))); refreshAnimationActions(); refreshDrawStyleActions(); @@ -578,7 +622,7 @@ void RiuMainWindow::createToolBars() class RiuDockWidget : public QDockWidget { public: - explicit RiuDockWidget(const QString& title, QWidget* parent = 0, Qt::WindowFlags flags = 0) + explicit RiuDockWidget(const QString& title, QWidget* parent = nullptr, Qt::WindowFlags flags = nullptr) : QDockWidget(title, parent, flags) { } @@ -635,7 +679,9 @@ void RiuMainWindow::createDockPanels() QDockWidget* resultPlotDock = nullptr; QDockWidget* relPermPlotDock = nullptr; QDockWidget* pvtPlotDock = nullptr; +#ifdef USE_ODB_API QDockWidget* mohrsCirclePlotDock = nullptr; +#endif { QDockWidget* dockWidget = new RiuDockWidget("Property Editor", this); @@ -753,6 +799,14 @@ void RiuMainWindow::setResultInfo(const QString& info) const m_resultInfoPanel->setInfo(info); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::refreshViewActions() +{ + this->slotRefreshViewActions(); +} + //================================================================================================== // // Action slots @@ -777,6 +831,7 @@ void RiuMainWindow::slotRefreshFileActions() QStringList commandIdList; commandIdList << "RicExportCompletionsForVisibleWellPathsFeature"; + commandIdList << "RicExportVisibleWellPathsFeature"; cmdFeatureMgr->refreshStates(commandIdList); } @@ -796,7 +851,9 @@ void RiuMainWindow::slotRefreshEditActions() //-------------------------------------------------------------------------------------------------- void RiuMainWindow::slotRefreshViewActions() { - bool enabled = RiaApplication::instance()->activeGridView() != nullptr; + RimGridView* gridView = RiaApplication::instance()->activeGridView(); + RimContourMapView* view2d = dynamic_cast(gridView); + bool enabled = gridView != nullptr && view2d == nullptr; m_viewFromNorth->setEnabled(enabled); m_viewFromSouth->setEnabled(enabled); m_viewFromEast->setEnabled(enabled); @@ -936,6 +993,26 @@ QMdiSubWindow* RiuMainWindow::findMdiSubWindow(QWidget* viewer) return nullptr; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimViewWindow* RiuMainWindow::findViewWindowFromSubWindow(QMdiSubWindow* subWindow) +{ + std::vector allViewWindows; + RiaApplication::instance()->project()->descendantsIncludingThisOfType(allViewWindows); + + for (RimViewWindow* viewWindow : allViewWindows) + { + if (viewWindow->viewWidget() == subWindow->widget()) + { + return viewWindow; + } + } + return nullptr; +} + + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1248,22 +1325,6 @@ void RiuMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuMainWindow::slotUseShaders(bool enable) -{ - RiaApplication::instance()->setUseShaders(enable); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuMainWindow::slotShowPerformanceInfo(bool enable) -{ - RiaApplication::instance()->setShowPerformanceInfo(enable); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1277,17 +1338,6 @@ void RiuMainWindow::setActiveViewer(QWidget* viewer) m_blockSlotSubWindowActivated = false; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuMainWindow::slotFramerateChanged(double frameRate) -{ - if (RiaApplication::instance()->activeReservoirView() != nullptr) - { - RiaApplication::instance()->activeReservoirView()->maximumFrameRate.setValueWithFieldChanged(frameRate); - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1527,15 +1577,20 @@ void RiuMainWindow::slotToggleFaultLabelsAction(bool showLabels) //-------------------------------------------------------------------------------------------------- void RiuMainWindow::refreshDrawStyleActions() { + RimGridView* gridView = RiaApplication::instance()->activeGridView(); + RimContourMapView* view2d = dynamic_cast(gridView); + bool is2dMap = view2d != nullptr; + bool is3dGridView = gridView != nullptr && !is2dMap; + Rim3dView* view = RiaApplication::instance()->activeReservoirView(); - bool is3DView = view != nullptr; - bool isGridView = RiaApplication::instance()->activeGridView() != nullptr; + bool is3dView = view != nullptr && !is2dMap; + - m_drawStyleLinesAction->setEnabled(is3DView); - m_drawStyleLinesSolidAction->setEnabled(is3DView); - m_drawStyleSurfOnlyAction->setEnabled(is3DView); - m_drawStyleFaultLinesSolidAction->setEnabled(is3DView); - m_disableLightingAction->setEnabled(is3DView); + m_drawStyleLinesAction->setEnabled(is3dView); + m_drawStyleLinesSolidAction->setEnabled(is3dView); + m_drawStyleSurfOnlyAction->setEnabled(is3dView); + m_drawStyleFaultLinesSolidAction->setEnabled(is3dView); + m_disableLightingAction->setEnabled(is3dView); bool lightingDisabledInView = view ? view->isLightingDisabled() : false; @@ -1543,8 +1598,8 @@ void RiuMainWindow::refreshDrawStyleActions() m_disableLightingAction->setChecked(lightingDisabledInView); m_disableLightingAction->blockSignals(false); - m_drawStyleHideGridCellsAction->setEnabled(isGridView); - if (isGridView) + m_drawStyleHideGridCellsAction->setEnabled(is3dGridView); + if (is3dGridView) { m_drawStyleHideGridCellsAction->blockSignals(true); m_drawStyleHideGridCellsAction->setChecked(!view->isGridVisualizationMode()); @@ -1554,9 +1609,9 @@ void RiuMainWindow::refreshDrawStyleActions() RimEclipseView* eclView = dynamic_cast(view); bool hasEclipseView = eclView != nullptr; - m_showWellCellsAction->setEnabled(hasEclipseView); + m_showWellCellsAction->setEnabled(hasEclipseView && !is2dMap); - if (hasEclipseView) + if (hasEclipseView && !is2dMap) { m_showWellCellsAction->blockSignals(true); eclView->wellCollection()->updateStateForVisibilityCheckboxes(); @@ -1673,6 +1728,53 @@ void RiuMainWindow::updateUiFieldsFromActiveResult(caf::PdmObjectHandle* objectT } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::updateMemoryUsage() +{ + uint64_t currentUsage = caf::MemoryInspector::getApplicationPhysicalMemoryUsageMiB(); + uint64_t totalPhysicalMemory = caf::MemoryInspector::getTotalPhysicalMemoryMiB(); + uint64_t totalVirtualMemory = caf::MemoryInspector::getTotalVirtualMemoryMiB(); + uint64_t availVirtualMemory = caf::MemoryInspector::getAvailableVirtualMemoryMiB(); + + QColor okColor(0, 150, 0); + QColor warningColor(200, 0, 0); + QColor criticalColor(255, 100, 0); + + float currentUsageFraction = 0.0f; + float availVirtualFraction = 1.0f; + if (currentUsage > 0u && totalPhysicalMemory > 0u) + { + currentUsageFraction = std::min(1.0f, static_cast(currentUsage) / totalPhysicalMemory); + } + if (availVirtualMemory > 0u && totalVirtualMemory > 0u) + { + availVirtualFraction = static_cast(availVirtualMemory) / totalVirtualMemory; + } + + QColor usageColor((int)(okColor.red() * (1.0 - currentUsageFraction) + warningColor.red() * currentUsageFraction), + (int)(okColor.green() * (1.0 - currentUsageFraction) + warningColor.green() * currentUsageFraction), + (int)(okColor.blue() * (1.0 - currentUsageFraction) + warningColor.blue() * currentUsageFraction)); + + m_memoryCriticalWarning->setText(QString("")); + if (availVirtualFraction < caf::MemoryInspector::getRemainingMemoryCriticalThresholdFraction()) + { + m_memoryCriticalWarning->setText(QString("Available System Memory Critically Low!")); + m_memoryCriticalWarning->setStyleSheet(QString("QLabel {color: %1; padding: 0px 5px 0px 0px;}").arg(criticalColor.name())); + } + else + { + m_memoryCriticalWarning->setText(QString("")); + } + + m_memoryUsedButton->setText(QString("Memory Used: %1 MiB").arg(currentUsage)); + m_memoryTotalStatus->setText(QString("Total Physical Memory: %1 MiB").arg(totalPhysicalMemory)); + + m_memoryUsedButton->setStyleSheet(QString("QLabel {color: %1; padding: 0px 5px 0px 0px;}").arg(usageColor.name())); + m_memoryTotalStatus->setStyleSheet(QString("QLabel {padding: 0px 5px 0px 0px; }")); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1681,6 +1783,14 @@ void RiuMainWindow::showProcessMonitorDockPanel() showDockPanel(RiuDockWidgetTools::instance()->processMonitorName()); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuMainWindow::setDefaultToolbarVisibility() +{ + m_holoLensToolBar->hide(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1697,11 +1807,13 @@ void RiuMainWindow::slotScaleChanged(int scaleValue) //-------------------------------------------------------------------------------------------------- void RiuMainWindow::updateScaleValue() { - if (RiaApplication::instance()->activeReservoirView()) + Rim3dView* view = RiaApplication::instance()->activeReservoirView(); + bool isRegularReservoirView = view && dynamic_cast(view) == nullptr; + if (isRegularReservoirView) { m_scaleFactor->setEnabled(true); - int scaleValue = static_cast(RiaApplication::instance()->activeReservoirView()->scaleZ()); // Round down is probably ok. + int scaleValue = static_cast(view->scaleZ()); // Round down is probably ok. m_scaleFactor->blockSignals(true); m_scaleFactor->setValue(scaleValue); m_scaleFactor->blockSignals(false); @@ -1871,17 +1983,61 @@ RimMdiWindowGeometry RiuMainWindow::windowGeometryForViewer(QWidget* viewer) //-------------------------------------------------------------------------------------------------- void RiuMainWindow::tileWindows() { + QMdiArea::WindowOrder currentActivationOrder = m_mdiArea->activationOrder(); + + // Tile Windows so the one with the leftmost left edge gets sorted first. + std::list windowList; + for (QMdiSubWindow* subWindow : m_mdiArea->subWindowList(currentActivationOrder)) + { + windowList.push_back(subWindow); + } + + // Get the active view linker if there is one + RimProject * proj = RiaApplication::instance()->project(); + RimViewLinkerCollection* viewLinkerCollection = proj->viewLinkerCollection(); + RimViewLinker* viewLinker = nullptr; + if (viewLinkerCollection && viewLinkerCollection->isActive()) + { + viewLinker = viewLinkerCollection->viewLinker(); + } + + // Perform stable sort of list so we first sort by window position but retain activation order + // for windows with the same position. Needs to be sorted in decreasing order for the workaround below. + windowList.sort([this, viewLinker](QMdiSubWindow* lhs, QMdiSubWindow* rhs) + { + RimViewWindow* lhsViewWindow = findViewWindowFromSubWindow(lhs); + RimViewWindow* rhsViewWindow = findViewWindowFromSubWindow(rhs); + RimGridView* lhsGridView = dynamic_cast(lhsViewWindow); + RimGridView* rhsGridView = dynamic_cast(rhsViewWindow); + + if (viewLinker) + { + if (viewLinker->isFirstViewDependentOnSecondView(lhsGridView, rhsGridView)) + { + return true; + } + else if (viewLinker->isFirstViewDependentOnSecondView(rhsGridView, lhsGridView)) + { + return false; + } + } + return lhs->frameGeometry().topLeft().rx() > rhs->frameGeometry().topLeft().rx(); + }); + // Based on workaround described here // https://forum.qt.io/topic/50053/qmdiarea-tilesubwindows-always-places-widgets-in-activationhistoryorder-in-subwindowview-mode + // Force activation order so they end up in the order of the loop. + m_mdiArea->setActivationOrder(QMdiArea::ActivationHistoryOrder); QMdiSubWindow *a = m_mdiArea->activeSubWindow(); - QList list = m_mdiArea->subWindowList(m_mdiArea->activationOrder()); - for (int i = 0; i < list.count(); i++) + for (QMdiSubWindow* subWindow : windowList) { - m_mdiArea->setActiveSubWindow(list[i]); + m_mdiArea->setActiveSubWindow(subWindow); } m_mdiArea->tileSubWindows(); + // Set back the original activation order to avoid messing with the standard ordering + m_mdiArea->setActivationOrder(currentActivationOrder); m_mdiArea->setActiveSubWindow(a); } diff --git a/ApplicationCode/UserInterface/RiuMainWindow.h b/ApplicationCode/UserInterface/RiuMainWindow.h index f53ea53321..7d5b2fce2a 100644 --- a/ApplicationCode/UserInterface/RiuMainWindow.h +++ b/ApplicationCode/UserInterface/RiuMainWindow.h @@ -26,18 +26,22 @@ #include "cafPdmObjectHandle.h" #include -#include +#include #include +#include #include #include class QActionGroup; class QMdiSubWindow; +class QToolButton; class QSpinBox; +class QTimer; class QUndoView; class RimCase; +class RimViewWindow; class RiuMessagePanel; class RiuProcessMonitor; @@ -90,7 +94,8 @@ class RiuMainWindow : public RiuMainWindowBase void setResultInfo(const QString& info) const; - void refreshAnimationActions(); + void refreshViewActions(); + void refreshAnimationActions(); void updateScaleValue(); RiuProcessMonitor* processMonitor(); @@ -111,6 +116,7 @@ class RiuMainWindow : public RiuMainWindowBase void tileWindows(); bool isAnyMdiSubWindowVisible(); QMdiSubWindow* findMdiSubWindow(QWidget* viewer); + RimViewWindow* findViewWindowFromSubWindow(QMdiSubWindow* lhs); QList subWindowList(QMdiArea::WindowOrder order); RiuResultQwtPlot* resultPlot(); @@ -120,9 +126,10 @@ class RiuMainWindow : public RiuMainWindowBase RiuMessagePanel* messagePanel(); void showProcessMonitorDockPanel(); + void setDefaultToolbarVisibility(); protected: - virtual void closeEvent(QCloseEvent* event); + void closeEvent(QCloseEvent* event) override; private: void createActions(); @@ -180,13 +187,19 @@ class RiuMainWindow : public RiuMainWindowBase RiuPvtPlotPanel* m_pvtPlotPanel; QMenu* m_windowMenu; - + QLabel* m_memoryCriticalWarning; + QToolButton* m_memoryUsedButton; + QLabel* m_memoryTotalStatus; + QTimer* m_memoryRefreshTimer; // Menu and action slots private slots: friend class RiuMdiSubWindow; + // Memory update slot + void updateMemoryUsage(); + // File slots void slotRefreshFileActions(); @@ -204,17 +217,14 @@ private slots: void slotViewFromBelow(); void slotScaleChanged(int scaleValue); - void slotDrawStyleChanged(QAction* activatedAction); - void slotToggleHideGridCellsAction(bool); - void slotToggleFaultLabelsAction(bool); - void slotDisableLightingAction(bool); + void slotDrawStyleChanged(QAction* activatedAction); + void slotToggleHideGridCellsAction(bool); + void slotToggleFaultLabelsAction(bool); + void slotDisableLightingAction(bool); - void slotShowWellCellsAction(bool doAdd); + void slotShowWellCellsAction(bool doAdd); // Debug slots - void slotUseShaders(bool enable); - void slotShowPerformanceInfo(bool enable); - void slotSnapshotAllViewsToFile(); void slotCreateCommandObject(); @@ -237,10 +247,6 @@ private slots: void selectedObjectsChanged(); void customMenuRequested(const QPoint& pos); - - // Animation slots - void slotFramerateChanged(double frameRate); - // Pdm System : public: void setPdmRoot(caf::PdmObject* pdmRoot); @@ -265,6 +271,8 @@ private slots: QAction* m_drawStyleSurfOnlyAction; QAction* m_showWellCellsAction; + QToolBar* m_holoLensToolBar; + std::vector > additionalProjectViews; bool m_blockSlotSubWindowActivated; diff --git a/ApplicationCode/UserInterface/RiuMdiSubWindow.cpp b/ApplicationCode/UserInterface/RiuMdiSubWindow.cpp index fdc16117eb..29469b21a6 100644 --- a/ApplicationCode/UserInterface/RiuMdiSubWindow.cpp +++ b/ApplicationCode/UserInterface/RiuMdiSubWindow.cpp @@ -77,33 +77,33 @@ RimMdiWindowGeometry RiuMdiSubWindow::windowGeometryForWidget(QWidget* widget) { RimMdiWindowGeometry geo; - // Find topmost parent - - QWidget* nextParent = widget->parentWidget(); - QWidget* parent = nullptr; - while(nextParent) + if (widget) { - parent = nextParent; - nextParent = nextParent->parentWidget(); - } + // Find topmost parent - int mainWinID = 0; - if (parent) - { - if (parent == RiaApplication::instance()->mainPlotWindow()) + QWidget* nextParent = widget->parentWidget(); + QWidget* parent = nullptr; + while (nextParent) { - mainWinID = 1; + parent = nextParent; + nextParent = nextParent->parentWidget(); + } + + int mainWinID = 0; + if (parent) + { + if (parent == RiaApplication::instance()->mainPlotWindow()) + { + mainWinID = 1; + } } - } - if (widget) - { geo.mainWindowID = mainWinID; - geo.x = widget->pos().x(); - geo.y = widget->pos().y(); - geo.width = widget->size().width(); - geo.height = widget->size().height(); - geo.isMaximized = widget->isMaximized(); + geo.x = widget->pos().x(); + geo.y = widget->pos().y(); + geo.width = widget->size().width(); + geo.height = widget->size().height(); + geo.isMaximized = widget->isMaximized(); } return geo; diff --git a/ApplicationCode/UserInterface/RiuMdiSubWindow.h b/ApplicationCode/UserInterface/RiuMdiSubWindow.h index 2c21d535d8..5a2da2f8fa 100644 --- a/ApplicationCode/UserInterface/RiuMdiSubWindow.h +++ b/ApplicationCode/UserInterface/RiuMdiSubWindow.h @@ -27,11 +27,11 @@ class RiuMdiSubWindow : public QMdiSubWindow public: RiuMdiSubWindow(QWidget* parent = nullptr, Qt::WindowFlags flags = nullptr); - ~RiuMdiSubWindow(); + ~RiuMdiSubWindow() override; static RimMdiWindowGeometry windowGeometryForWidget(QWidget* widget); protected: - virtual void closeEvent(QCloseEvent* event); + void closeEvent(QCloseEvent* event) override; }; diff --git a/ApplicationCode/UserInterface/RiuMessagePanel.h b/ApplicationCode/UserInterface/RiuMessagePanel.h index 7cda43dff8..06213eb641 100644 --- a/ApplicationCode/UserInterface/RiuMessagePanel.h +++ b/ApplicationCode/UserInterface/RiuMessagePanel.h @@ -40,7 +40,7 @@ class RiuMessagePanel : public QWidget explicit RiuMessagePanel(QDockWidget* parent); void addMessage(RILogLevel messageLevel, const QString& msg); - virtual QSize sizeHint () const; + QSize sizeHint () const override; private slots: void slotShowContextMenu(const QPoint& pos); @@ -62,13 +62,13 @@ class RiuMessagePanelLogger : public RiaLogger public: explicit RiuMessagePanelLogger(RiuMessagePanel* messagePanel); - virtual int level() const override; - virtual void setLevel(int logLevel) override; + int level() const override; + 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; + 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: void writeToMessagePanel(RILogLevel messageLevel, const char* message); diff --git a/ApplicationCode/UserInterface/RiuMohrsCirclePlot.cpp b/ApplicationCode/UserInterface/RiuMohrsCirclePlot.cpp index d2908d7ef7..7eac3f6953 100644 --- a/ApplicationCode/UserInterface/RiuMohrsCirclePlot.cpp +++ b/ApplicationCode/UserInterface/RiuMohrsCirclePlot.cpp @@ -379,12 +379,16 @@ void RiuMohrsCirclePlot::queryData(RimGeoMechView* geoMechView, size_t gridIndex double frictionAngleDeg = geoMechView->geoMechCase()->frictionAngleDeg(); size_t i, j, k; - femPart->structGrid()->ijkFromCellIndex(elmIndex, &i, &j, &k); - - MohrsCirclesInfo mohrsCircle( - principals, gridIndex, elmIndex, i, j, k, geoMechView, calculateFOS(principals, frictionAngleDeg, cohesion), color); + bool validIndex = femPart->getOrCreateStructGrid()->ijkFromCellIndex(elmIndex, &i, &j, &k); + + CVF_ASSERT(validIndex); + if (validIndex) + { + MohrsCirclesInfo mohrsCircle( + principals, gridIndex, elmIndex, i, j, k, geoMechView, calculateFOS(principals, frictionAngleDeg, cohesion), color); - addMohrsCirclesInfo(mohrsCircle); + addMohrsCirclesInfo(mohrsCircle); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuMohrsCirclePlot.h b/ApplicationCode/UserInterface/RiuMohrsCirclePlot.h index 01f62c2b16..7e803421f4 100644 --- a/ApplicationCode/UserInterface/RiuMohrsCirclePlot.h +++ b/ApplicationCode/UserInterface/RiuMohrsCirclePlot.h @@ -45,7 +45,7 @@ class RiuMohrsCirclePlot : public QwtPlot public: RiuMohrsCirclePlot(QWidget* parent); - ~RiuMohrsCirclePlot(); + ~RiuMohrsCirclePlot() override; void appendSelection(const RiuSelectionItem* selectionItem); void clearPlot(); @@ -84,9 +84,9 @@ class RiuMohrsCirclePlot : public QwtPlot }; private: - virtual QSize sizeHint() const override; - virtual QSize minimumSizeHint() const override; - virtual void resizeEvent(QResizeEvent* e) override; + QSize sizeHint() const override; + QSize minimumSizeHint() const override; + void resizeEvent(QResizeEvent* e) override; void idealAxesEndPoints(double* xMin, double* xMax, double* yMax) const; diff --git a/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.cpp b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.cpp index 6611ceb0b7..d3467b6838 100644 --- a/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.cpp +++ b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.cpp @@ -38,7 +38,7 @@ class FileListModel: public QStringListModel { } - virtual Qt::ItemFlags flags (const QModelIndex& index) const + Qt::ItemFlags flags (const QModelIndex& index) const override { if (m_isItemsEditable) return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; @@ -46,7 +46,7 @@ class FileListModel: public QStringListModel return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } - virtual QVariant data ( const QModelIndex & index, int role ) const + QVariant data ( const QModelIndex & index, int role ) const override { if (role == Qt::DecorationRole) { @@ -68,11 +68,6 @@ class FileListModel: public QStringListModel } } - void setItemsEditable(bool isEditable) - { - m_isItemsEditable = isEditable; - } - private: bool m_isItemsEditable; }; @@ -230,9 +225,9 @@ void RiuMultiCaseImportDialog::appendEGRIDFilesRecursively(const QString& folder for (int i = 0; i < subFolders.size(); ++i) { - QString folderName = subFolders[i]; + QString subFolderName = subFolders[i]; - QString absoluteFolderName = baseDir.absoluteFilePath(folderName); + QString absoluteFolderName = baseDir.absoluteFilePath(subFolderName); appendEGRIDFilesRecursively(absoluteFolderName, gridFileNames); } } diff --git a/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.h b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.h index 7ad1275cc2..d26cf19716 100644 --- a/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.h +++ b/ApplicationCode/UserInterface/RiuMultiCaseImportDialog.h @@ -38,7 +38,7 @@ class RiuMultiCaseImportDialog: public QDialog public: explicit RiuMultiCaseImportDialog(QWidget *parent = nullptr); - virtual ~RiuMultiCaseImportDialog(); + ~RiuMultiCaseImportDialog() override; QStringList eclipseCaseFileNames() const; diff --git a/ApplicationCode/UserInterface/RiuNightchartsWidget.h b/ApplicationCode/UserInterface/RiuNightchartsWidget.h index 0a0ba6df5a..0ac9c66523 100644 --- a/ApplicationCode/UserInterface/RiuNightchartsWidget.h +++ b/ApplicationCode/UserInterface/RiuNightchartsWidget.h @@ -41,10 +41,10 @@ class RiuNightchartsWidget : public QWidget void clear(); - virtual QSize sizeHint() const override; + QSize sizeHint() const override; protected: - virtual void paintEvent(QPaintEvent* e); + void paintEvent(QPaintEvent* e) override; private: void updateSizePolicy(); diff --git a/ApplicationCode/UserInterface/RiuPickItemInfo.cpp b/ApplicationCode/UserInterface/RiuPickItemInfo.cpp new file mode 100644 index 0000000000..26339096af --- /dev/null +++ b/ApplicationCode/UserInterface/RiuPickItemInfo.cpp @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuPickItemInfo.h" + +#include "cvfHitItem.h" +#include "cvfPart.h" +#include "cvfDrawableGeo.h" +#include "cvfTransform.h" +#include "cvfHitItemCollection.h" + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuPickItemInfo RiuPickItemInfo::extractPickItemInfo(const cvf::HitItem* hitItem) +{ + RiuPickItemInfo pickInfo; + + pickInfo.m_pickedPart = hitItem->part(); + pickInfo.m_globalPickedPoint = hitItem->intersectionPoint(); + if ( pickInfo.m_pickedPart ) pickInfo.m_sourceInfo = pickInfo.m_pickedPart->sourceInfo(); + + const cvf::HitDetailDrawableGeo* detail = dynamic_cast(hitItem->detail()); + if ( detail ) pickInfo.m_faceIdx = detail->faceIndex(); + + pickInfo.m_localPickedPoint = pickInfo.m_globalPickedPoint; + const cvf::Transform* xf = pickInfo.m_pickedPart->transform(); + if ( xf ) + { + pickInfo.m_localPickedPoint.transformPoint(xf->worldTransform().getInverted()); + } + + return pickInfo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuPickItemInfo::convertToPickItemInfos( const cvf::HitItemCollection &hitItems) +{ + std::vector pickItemInfos; + pickItemInfos.reserve(hitItems.count()); + for ( size_t i = 0; i < hitItems.count(); i++ ) + { + pickItemInfos.emplace_back(RiuPickItemInfo(hitItems.item(i))); + } + return pickItemInfos; +} diff --git a/ApplicationCode/UserInterface/RiuPickItemInfo.h b/ApplicationCode/UserInterface/RiuPickItemInfo.h new file mode 100644 index 0000000000..f01073b49d --- /dev/null +++ b/ApplicationCode/UserInterface/RiuPickItemInfo.h @@ -0,0 +1,76 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfVector3.h" +#include + +namespace cvf +{ + class Part; + class Object; + class HitItem; + class HitItemCollection; +} + + +class RiuPickItemInfo +{ +public: + RiuPickItemInfo() + : m_distanceAlongRay(std::numeric_limits::infinity()) + , m_pickedPart(nullptr) + , m_globalPickedPoint (cvf::Vec3d::UNDEFINED) + , m_localPickedPoint (cvf::Vec3d::UNDEFINED) + , m_sourceInfo (nullptr) + , m_faceIdx (-1) + {} + + explicit RiuPickItemInfo(const cvf::HitItem* hitItem) + : m_pickedPart(nullptr) + , m_globalPickedPoint (cvf::Vec3d::UNDEFINED) + , m_localPickedPoint (cvf::Vec3d::UNDEFINED) + , m_sourceInfo (nullptr) + , m_faceIdx (-1) + { + *this = extractPickItemInfo(hitItem); + } + + const cvf::Part* pickedPart() const { return m_pickedPart;} + cvf::Vec3d globalPickedPoint() const { return m_globalPickedPoint;} + cvf::Vec3d localPickedPoint() const { return m_localPickedPoint;} + const cvf::Object* sourceInfo() const { return m_sourceInfo;} + cvf::uint faceIdx() const { return m_faceIdx;} + double distanceAlongRay() const { return m_distanceAlongRay;} + + static RiuPickItemInfo extractPickItemInfo(const cvf::HitItem* hitItem); + static std::vector convertToPickItemInfos(const cvf::HitItemCollection &hitItems); + +private: + double m_distanceAlongRay; + const cvf::Part* m_pickedPart; + cvf::Vec3d m_globalPickedPoint; + cvf::Vec3d m_localPickedPoint; + const cvf::Object* m_sourceInfo; + cvf::uint m_faceIdx; + +}; + + diff --git a/ApplicationCode/UserInterface/RiuPlotAnnotationTool.cpp b/ApplicationCode/UserInterface/RiuPlotAnnotationTool.cpp index 02c6c39cda..465e227167 100644 --- a/ApplicationCode/UserInterface/RiuPlotAnnotationTool.cpp +++ b/ApplicationCode/UserInterface/RiuPlotAnnotationTool.cpp @@ -34,7 +34,7 @@ RiuPlotAnnotationTool::~RiuPlotAnnotationTool() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuPlotAnnotationTool::attachFormationNames(QwtPlot* plot, const std::vector& names, const std::vector> yPositions) +void RiuPlotAnnotationTool::attachFormationNames(QwtPlot* plot, const std::vector& names, const std::vector> yPositions, bool showNames) { detachAllAnnotations(); @@ -47,10 +47,14 @@ void RiuPlotAnnotationTool::attachFormationNames(QwtPlot* plot, const std::vecto { QwtPlotMarker* line(new QwtPlotMarker()); - QString name = names[i]; - if (names[i].toLower().indexOf("top") == -1) + QString name; + if (showNames) { - name += " Top"; + name = names[i]; + if (names[i].toLower().indexOf("top") == -1) + { + name += " Top"; + } } RiuPlotAnnotationTool::horizontalDashedLine(line, name, yPositions[i].first); @@ -79,8 +83,6 @@ void RiuPlotAnnotationTool::attachWellPicks(QwtPlot* plot, const std::vector& names, const std::vector> yPositions); + void attachFormationNames(QwtPlot* plot, const std::vector& names, const std::vector> yPositions, bool showNames = true); void attachWellPicks(QwtPlot* plot, const std::vector& names, const std::vector yPositions); void detachAllAnnotations(); diff --git a/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp b/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp index c80bfe031c..a370883155 100644 --- a/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp @@ -27,6 +27,7 @@ #include "RimSummaryPlot.h" #include "RimViewWindow.h" #include "RimWellAllocationPlot.h" +#include "RimWellLogCurveCommonDataSource.h" #include "RimWellLogPlot.h" #include "RiuDragDrop.h" @@ -114,6 +115,7 @@ void RiuPlotMainWindow::cleanupGuiBeforeProjectClose() cleanUpTemporaryWidgets(); + m_wellLogPlotToolBarEditor->clear(); m_summaryPlotToolBarEditor->clear(); setWindowTitle("Plots - ResInsight"); @@ -317,6 +319,9 @@ void RiuPlotMainWindow::createToolBars() } } + m_wellLogPlotToolBarEditor = new caf::PdmUiToolBarEditor("Well Log Plot", this); + m_wellLogPlotToolBarEditor->hide(); + m_summaryPlotToolBarEditor = new caf::PdmUiToolBarEditor("Summary Plot", this); m_summaryPlotToolBarEditor->hide(); } @@ -422,6 +427,34 @@ QList RiuPlotMainWindow::subWindowList(QMdiArea::WindowOrder ord return m_mdiArea->subWindowList(order); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuPlotMainWindow::setWidthOfMdiWindow(QWidget* mdiWindowWidget, int newWidth) +{ + QMdiSubWindow* mdiWindow = findMdiSubWindow(mdiWindowWidget); + if (mdiWindow) + { + QSize subWindowSize = mdiWindow->size(); + + subWindowSize.setWidth(std::max(newWidth, 100)); + mdiWindow->resize(subWindowSize); + + if (mdiWindow->isMaximized()) + { + // Set window temporarily to normal state and back to maximized + // to redo layout so the whole window canvas is filled + // Tried to activate layout, did not work as expected + // Tested code: + // m_layout->activate(); + // mdiWindow->layout()->activate(); + + mdiWindow->showNormal(); + mdiWindow->showMaximized(); + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -432,6 +465,32 @@ void RiuPlotMainWindow::addToTemporaryWidgets(QWidget* widget) m_temporaryWidgets.push_back(widget); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuPlotMainWindow::updateWellLogPlotToolBar() +{ + RimWellLogPlot* wellLogPlot = dynamic_cast(m_activePlotViewWindow.p()); + if (wellLogPlot) + { + std::vector toolBarFields; + toolBarFields = wellLogPlot->commonDataSource()->fieldsToShowInToolbar(); + + m_wellLogPlotToolBarEditor->setFields(toolBarFields); + m_wellLogPlotToolBarEditor->updateUi(); + + m_wellLogPlotToolBarEditor->show(); + } + else + { + m_wellLogPlotToolBarEditor->clear(); + + m_wellLogPlotToolBarEditor->hide(); + } + + refreshToolbars(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -498,7 +557,9 @@ void RiuPlotMainWindow::addViewer(QWidget* viewer, const RimMdiWindowGeometry& w RiuWellLogPlot* wellLogPlot = dynamic_cast(subWin->widget()); if (wellLogPlot) { - subWindowSize = QSize(275, m_mdiArea->height()); + QSize preferredSize = wellLogPlot->preferredSize(); + subWindowSize = + QSize(preferredSize.width(), m_mdiArea->height()); } else { @@ -572,6 +633,7 @@ void RiuPlotMainWindow::slotSubWindowActivated(QMdiSubWindow* subWindow) m_activePlotViewWindow = viewWindow; } + updateWellLogPlotToolBar(); updateSummaryPlotToolBar(); } @@ -760,18 +822,35 @@ RimMdiWindowGeometry RiuPlotMainWindow::windowGeometryForViewer(QWidget* viewer) //-------------------------------------------------------------------------------------------------- void RiuPlotMainWindow::tileWindows() { + QMdiArea::WindowOrder currentActivationOrder = m_mdiArea->activationOrder(); + + std::list windowList; + for (QMdiSubWindow* subWindow : m_mdiArea->subWindowList(currentActivationOrder)) + { + windowList.push_back(subWindow); + } + + // Perform stable sort of list so we first sort by window position but retain activation order + // for windows with the same position. Needs to be sorted in decreasing order for workaround below. + windowList.sort([](const QMdiSubWindow* lhs, const QMdiSubWindow* rhs) + { + return lhs->frameGeometry().topLeft().rx() > rhs->frameGeometry().topLeft().rx(); + }); + // Based on workaround described here // https://forum.qt.io/topic/50053/qmdiarea-tilesubwindows-always-places-widgets-in-activationhistoryorder-in-subwindowview-mode QMdiSubWindow* a = m_mdiArea->activeSubWindow(); - - QList list = m_mdiArea->subWindowList(m_mdiArea->activationOrder()); - for (int i = 0; i < list.count(); i++) + // Force activation order so they end up in the order of the loop. + m_mdiArea->setActivationOrder(QMdiArea::ActivationHistoryOrder); + for (QMdiSubWindow* subWindow : windowList) { - m_mdiArea->setActiveSubWindow(list[i]); + m_mdiArea->setActiveSubWindow(subWindow); } m_mdiArea->tileSubWindows(); + // Set back the original activation order to avoid messing with the standard ordering + m_mdiArea->setActivationOrder(currentActivationOrder); m_mdiArea->setActiveSubWindow(a); } diff --git a/ApplicationCode/UserInterface/RiuPlotMainWindow.h b/ApplicationCode/UserInterface/RiuPlotMainWindow.h index 43aa9d4ada..e49d7d052b 100644 --- a/ApplicationCode/UserInterface/RiuPlotMainWindow.h +++ b/ApplicationCode/UserInterface/RiuPlotMainWindow.h @@ -77,8 +77,10 @@ class RiuPlotMainWindow : public RiuMainWindowBase QMdiSubWindow* findMdiSubWindow(QWidget* viewer); QList subWindowList(QMdiArea::WindowOrder order); + void setWidthOfMdiWindow(QWidget* mdiWindowWidget, int newWidth); void addToTemporaryWidgets(QWidget* widget); + void updateWellLogPlotToolBar(); void updateSummaryPlotToolBar(); protected: @@ -116,6 +118,7 @@ private slots: QMenu* m_windowMenu; + caf::PdmUiToolBarEditor* m_wellLogPlotToolBarEditor; caf::PdmUiToolBarEditor* m_summaryPlotToolBarEditor; std::unique_ptr m_dragDropInterface; diff --git a/ApplicationCode/UserInterface/RiuPlotMainWindowTools.cpp b/ApplicationCode/UserInterface/RiuPlotMainWindowTools.cpp index cd161b6315..ba6230a2c9 100644 --- a/ApplicationCode/UserInterface/RiuPlotMainWindowTools.cpp +++ b/ApplicationCode/UserInterface/RiuPlotMainWindowTools.cpp @@ -65,7 +65,11 @@ void RiuPlotMainWindowTools::refreshToolbars() { RiuPlotMainWindow* mpw = RiaApplication::instance()->mainPlotWindow(); - if (mpw) mpw->updateSummaryPlotToolBar(); + if (mpw) + { + mpw->updateSummaryPlotToolBar(); + mpw->updateWellLogPlotToolBar(); + } } diff --git a/ApplicationCode/UserInterface/RiuProcessMonitor.h b/ApplicationCode/UserInterface/RiuProcessMonitor.h index 25bb54317f..46fec6b862 100644 --- a/ApplicationCode/UserInterface/RiuProcessMonitor.h +++ b/ApplicationCode/UserInterface/RiuProcessMonitor.h @@ -47,7 +47,7 @@ class RiuProcessMonitor : public QWidget public: explicit RiuProcessMonitor(QDockWidget* pParent); - ~RiuProcessMonitor(); + ~RiuProcessMonitor() override; void startMonitorWorkProcess(caf::UiProcess* process); void stopMonitorWorkProcess(); diff --git a/ApplicationCode/UserInterface/RiuPropertyViewTabWidget.h b/ApplicationCode/UserInterface/RiuPropertyViewTabWidget.h index 2f184b872c..67080c207d 100644 --- a/ApplicationCode/UserInterface/RiuPropertyViewTabWidget.h +++ b/ApplicationCode/UserInterface/RiuPropertyViewTabWidget.h @@ -34,9 +34,9 @@ class RiuPropertyViewTabWidget : public QDialog { public: RiuPropertyViewTabWidget(QWidget* parent, caf::PdmObject* object, const QString& windowTitle, const QStringList& uiConfigNameForTabs); - ~RiuPropertyViewTabWidget(); + ~RiuPropertyViewTabWidget() override; - virtual QSize sizeHint() const override; + QSize sizeHint() const override; private: std::vector m_pageWidgets; diff --git a/ApplicationCode/UserInterface/RiuPvtPlotPanel.cpp b/ApplicationCode/UserInterface/RiuPvtPlotPanel.cpp index d9ca0f26f2..43bb927d4c 100644 --- a/ApplicationCode/UserInterface/RiuPvtPlotPanel.cpp +++ b/ApplicationCode/UserInterface/RiuPvtPlotPanel.cpp @@ -54,8 +54,8 @@ class PvtQwtPlot : public QwtPlot { public: PvtQwtPlot(QWidget* parent) : QwtPlot(parent) {} - virtual QSize sizeHint() const { return QSize(100, 100); } - virtual QSize minimumSizeHint() const { return QSize(0, 0); } + QSize sizeHint() const override { return QSize(100, 100); } + QSize minimumSizeHint() const override { return QSize(0, 0); } }; @@ -74,7 +74,7 @@ class RiuPvtQwtPicker : public QwtPicker setStateMachine(new QwtPickerTrackerMachine); } - virtual QwtText trackerText(const QPoint&) const + QwtText trackerText(const QPoint&) const override { QwtText text(m_trackerTextProvider->trackerText()); text.setRenderFlags(Qt::AlignLeft); diff --git a/ApplicationCode/UserInterface/RiuPvtPlotPanel.h b/ApplicationCode/UserInterface/RiuPvtPlotPanel.h index 88b09eb5e8..fee336c767 100644 --- a/ApplicationCode/UserInterface/RiuPvtPlotPanel.h +++ b/ApplicationCode/UserInterface/RiuPvtPlotPanel.h @@ -69,7 +69,7 @@ class RiuPvtPlotWidget : public QWidget, public RiuPvtTrackerTextProvider const QwtPlotCurve* closestCurveSample(const QPoint& cursorPosition, int* closestSampleIndex) const; size_t indexOfQwtCurve(const QwtPlotCurve* qwtCurve) const; void updateTrackerPlotMarkerAndLabelFromPicker(); - virtual QString trackerText() const override; + QString trackerText() const override; private slots: void slotPickerActivated(bool); @@ -119,7 +119,7 @@ class RiuPvtPlotPanel : public QWidget public: RiuPvtPlotPanel(QDockWidget* parent); - virtual ~RiuPvtPlotPanel(); + ~RiuPvtPlotPanel() override; void setPlotData(RiaEclipseUnitTools::UnitSystem unitSystem, const std::vector& fvfCurveArr, const std::vector& viscosityCurveArr, FvfDynProps fvfDynProps, ViscosityDynProps viscosityDynProps, CellValues cellValues, QString cellReferenceText); void clearPlot(); diff --git a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp index bb9c108bd4..d8a4922df8 100644 --- a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp +++ b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.cpp @@ -18,6 +18,8 @@ #include "RiuQwtCurvePointTracker.h" +#include "RiaQDateTimeTools.h" + #include "qwt_plot_marker.h" #include "qwt_symbol.h" @@ -176,7 +178,9 @@ QPointF RiuQwtCurvePointTracker::closestCurvePoint(const QPoint& cursorPosition, if ( dateScaleDraw ) { QDateTime date = dateScaleDraw->toDateTime(mainAxisSampleVal); - *mainAxisValueString = date.toString("hh:mm dd.MMMM.yyyy"); + + QString dateString = RiaQDateTimeTools::toStringUsingApplicationLocale(date, "hh:mm dd.MMMM.yyyy"); + *mainAxisValueString = dateString; } else if ( mainAxisScaleDraw ) { diff --git a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h index 80a4b467f8..ba3a2d26fc 100644 --- a/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h +++ b/ApplicationCode/UserInterface/RiuQwtCurvePointTracker.h @@ -34,14 +34,14 @@ class RiuQwtCurvePointTracker : public QwtPlotPicker { public: explicit RiuQwtCurvePointTracker(QwtPlot* plot, bool isMainAxisHorizontal, IPlotCurveInfoTextProvider* curveInfoTextProvider = nullptr); - ~RiuQwtCurvePointTracker(); + ~RiuQwtCurvePointTracker() override; protected: - virtual bool eventFilter(QObject *, QEvent *) override; + bool eventFilter(QObject *, QEvent *) override; void removeMarkerOnFocusLeave(); - virtual QwtText trackerText(const QPoint& pos) const override; + QwtText trackerText(const QPoint& pos) const override; QPointF closestCurvePoint(const QPoint& cursorPosition, QString* curveInfoText, QString* valueAxisValueString, diff --git a/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.cpp b/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.cpp new file mode 100644 index 0000000000..f87e7cc607 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.cpp @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + + +#include "RiuQwtLinearScaleEngine.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QwtScaleDiv RiuQwtLinearScaleEngine::divideScaleWithExplicitIntervals(double x1, double x2, double majorStepInterval, double minorStepInterval) +{ + QwtInterval interval(x1, x2); + QwtInterval roundedInterval = this->align(interval, majorStepInterval); + QList majorTicks = this->buildMajorTicks(roundedInterval, majorStepInterval); + QList minorTicks = this->buildMajorTicks(roundedInterval, minorStepInterval); + + return QwtScaleDiv(x1, x2, minorTicks, minorTicks, majorTicks); +} diff --git a/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.h b/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.h new file mode 100644 index 0000000000..ec821f19df --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtLinearScaleEngine.h @@ -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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "qwt_scale_engine.h" + +//================================================================================================== +// +// +// +//================================================================================================== +class RiuQwtLinearScaleEngine : public QwtLinearScaleEngine +{ +public: + QwtScaleDiv divideScaleWithExplicitIntervals(double x1, double x2, double majorStepInterval, double minorStepInterval); +}; diff --git a/ApplicationCode/UserInterface/RiuQwtPlotCurve.cpp b/ApplicationCode/UserInterface/RiuQwtPlotCurve.cpp new file mode 100644 index 0000000000..3b2fb9c8c1 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtPlotCurve.cpp @@ -0,0 +1,409 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Statoil ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuQwtPlotCurve.h" + +#include "RiaCurveDataTools.h" +#include "RiuQwtSymbol.h" + +#include "qwt_symbol.h" +#include "qwt_date.h" +#include "qwt_point_mapper.h" +#include "qwt_painter.h" +#include "qwt_plot_intervalcurve.h" +#include "qwt_scale_map.h" +#include "qwt_interval_symbol.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// Internal constants +//-------------------------------------------------------------------------------------------------- +#define DOUBLE_INF std::numeric_limits::infinity() + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuQwtPlotCurve::RiuQwtPlotCurve(const QString &title) + : QwtPlotCurve(title) +{ + this->setLegendAttribute(QwtPlotCurve::LegendShowLine, true); + this->setLegendAttribute(QwtPlotCurve::LegendShowSymbol, true); + this->setLegendAttribute(QwtPlotCurve::LegendShowBrush, true); + + this->setRenderHint(QwtPlotItem::RenderAntialiased, true); + + m_symbolSkipPixelDistance = 10.0f; + + m_errorBars = new QwtPlotIntervalCurve(); + m_errorBars->setStyle(QwtPlotIntervalCurve::CurveStyle::NoCurve); + m_errorBars->setSymbol(new QwtIntervalSymbol(QwtIntervalSymbol::Bar)); + m_errorBars->setItemAttribute(QwtPlotItem::Legend, false); + + m_showErrorBars = true; + m_attachedToPlot = nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuQwtPlotCurve::~RiuQwtPlotCurve() +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::setSamplesFromXValuesAndYValues(const std::vector& xValues, const std::vector& yValues, const std::vector& yErrorValues, bool keepOnlyPositiveValues) +{ + CVF_ASSERT(xValues.size() == yValues.size()); + CVF_ASSERT(yErrorValues.empty() || yErrorValues.size() == xValues.size()); + + bool showErrorBars = m_showErrorBars && !yErrorValues.empty(); + QPolygonF points; + QVector errorIntervals; + std::vector< std::pair > filteredIntervals; + { + std::vector filteredYValues; + std::vector filteredXValues; + std::vector filteredYErrorValues; + + { + auto intervalsOfValidValues = RiaCurveDataTools::calculateIntervalsOfValidValues(yValues, keepOnlyPositiveValues); + + RiaCurveDataTools::getValuesByIntervals(yValues, intervalsOfValidValues, &filteredYValues); + RiaCurveDataTools::getValuesByIntervals(xValues, intervalsOfValidValues, &filteredXValues); + + if(showErrorBars) RiaCurveDataTools::getValuesByIntervals(yErrorValues, intervalsOfValidValues, &filteredYErrorValues); + + filteredIntervals = RiaCurveDataTools::computePolyLineStartStopIndices(intervalsOfValidValues); + } + + points.reserve(static_cast(filteredXValues.size())); + errorIntervals.reserve(static_cast(filteredXValues.size())); + for ( size_t i = 0; i < filteredXValues.size(); i++ ) + { + points << QPointF(filteredXValues[i], filteredYValues[i]); + + if (showErrorBars && filteredYValues[i] != DOUBLE_INF && filteredYErrorValues[i] != DOUBLE_INF) + { + errorIntervals << QwtIntervalSample(filteredXValues[i], filteredYValues[i] - filteredYErrorValues[i], filteredYValues[i] + filteredYErrorValues[i]); + } + } + } + + this->setSamples(points); + this->setLineSegmentStartStopIndices(filteredIntervals); + + if(showErrorBars) m_errorBars->setSamples(errorIntervals); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::setSamplesFromXValuesAndYValues(const std::vector& xValues, const std::vector& yValues, bool keepOnlyPositiveValues) +{ + setSamplesFromXValuesAndYValues(xValues, yValues, std::vector(), keepOnlyPositiveValues); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::setSamplesFromDatesAndYValues(const std::vector& dateTimes, const std::vector& yValues, bool keepOnlyPositiveValues) +{ + setSamplesFromXValuesAndYValues(RiuQwtPlotCurve::fromQDateTime(dateTimes), yValues, std::vector(), keepOnlyPositiveValues); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::setSamplesFromTimeTAndYValues(const std::vector& dateTimes, const std::vector& yValues, bool keepOnlyPositiveValues) +{ + setSamplesFromXValuesAndYValues(RiuQwtPlotCurve::fromTime_t(dateTimes), yValues, std::vector(), keepOnlyPositiveValues); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::setSamplesFromTimeTAndYValues(const std::vector& dateTimes, const std::vector& yValues, const std::vector& yErrorValues, bool keepOnlyPositiveValues) +{ + setSamplesFromXValuesAndYValues(RiuQwtPlotCurve::fromTime_t(dateTimes), yValues, yErrorValues, keepOnlyPositiveValues); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::drawCurve(QPainter* p, int style, + const QwtScaleMap& xMap, const QwtScaleMap& yMap, + const QRectF& canvasRect, int from, int to) const +{ + size_t intervalCount = m_polyLineStartStopIndices.size(); + if (intervalCount > 0) + { + for (size_t intIdx = 0; intIdx < intervalCount; intIdx++) + { + if (m_polyLineStartStopIndices[intIdx].first == m_polyLineStartStopIndices[intIdx].second) + { + // Use a symbol to draw a single value, as a single value will not be visible + // when using QwtPlotCurve::drawCurve without symbols activated + + QwtSymbol symbol(QwtSymbol::XCross); + symbol.setSize(10, 10); + + QwtPlotCurve::drawSymbols(p, symbol, xMap, yMap, canvasRect, (int) m_polyLineStartStopIndices[intIdx].first, (int) m_polyLineStartStopIndices[intIdx].second); + } + else + { + QwtPlotCurve::drawCurve(p, style, xMap, yMap, canvasRect, (int) m_polyLineStartStopIndices[intIdx].first, (int) m_polyLineStartStopIndices[intIdx].second); + } + } + } + else + { + QwtPlotCurve::drawCurve(p, style, xMap, yMap, canvasRect, from, to); + } +}; + +//-------------------------------------------------------------------------------------------------- +/// Drawing symbols but skipping if they are to close to the previous one +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::drawSymbols(QPainter *painter, const QwtSymbol &symbol, + const QwtScaleMap &xMap, const QwtScaleMap &yMap, + const QRectF &canvasRect, int from, int to) const +{ + QwtPointMapper mapper; + bool filterSymbols = m_symbolSkipPixelDistance > 0; + + if (filterSymbols) + { + mapper.setFlag(QwtPointMapper::RoundPoints, + QwtPainter::roundingAlignment(painter)); + mapper.setFlag(QwtPointMapper::WeedOutPoints, + testPaintAttribute(QwtPlotCurve::FilterPoints)); + mapper.setBoundingRect(canvasRect); + } + + const QPolygonF points = mapper.toPointsF(xMap, yMap, data(), from, to); + int pointCount = points.size(); + QPolygonF pointsToDisplay; + + if (filterSymbols) + { + QPointF lastDrawnSymbolPos; + + if (pointCount > 0) + { + pointsToDisplay.push_back(points[0]); + lastDrawnSymbolPos = points[0]; + } + + float sqSkipDist = m_symbolSkipPixelDistance * m_symbolSkipPixelDistance; + + for (int pIdx = 1; pIdx < pointCount - 1; ++pIdx) + { + QPointF diff = points[pIdx] - lastDrawnSymbolPos; + float sqDistBetweenSymbols = diff.x()*diff.x() + diff.y()*diff.y(); + + if (sqDistBetweenSymbols > sqSkipDist) + { + pointsToDisplay.push_back(points[pIdx]); + lastDrawnSymbolPos = points[pIdx]; + } + } + + if (pointCount > 1) pointsToDisplay.push_back(points.back()); + } + else + { + pointsToDisplay = points; + } + + + if (pointsToDisplay.size() > 0) + { + symbol.drawSymbols(painter, pointsToDisplay); + + const RiuQwtSymbol* sym = dynamic_cast(&symbol); + + if (sym && !sym->label().isEmpty()) + { + for (auto& pt : pointsToDisplay) + { + sym->renderSymbolLabel(painter, pt); + } + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::setLineSegmentStartStopIndices(const std::vector< std::pair >& lineSegmentStartStopIndices) +{ + m_polyLineStartStopIndices = lineSegmentStartStopIndices; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::setSymbolSkipPixelDistance(float distance) +{ + m_symbolSkipPixelDistance = distance >= 0.0f ? distance: 0.0f; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::attach(QwtPlot *plot) +{ + QwtPlotItem::attach(plot); + if(m_showErrorBars) m_errorBars->attach(plot); + m_attachedToPlot = plot; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::detach() +{ + QwtPlotItem::detach(); + m_errorBars->detach(); + m_attachedToPlot = nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::clearErrorBars() +{ + m_errorBars->setSamples(nullptr); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::showErrorBars(bool show) +{ + m_showErrorBars = show; + if (m_showErrorBars && m_attachedToPlot) m_errorBars->attach(m_attachedToPlot); + else m_errorBars->detach(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::setErrorBarsColor(QColor color) +{ + QwtIntervalSymbol* newSymbol = new QwtIntervalSymbol(QwtIntervalSymbol::Bar); + newSymbol->setPen(QPen(color)); + m_errorBars->setSymbol(newSymbol); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotCurve::setAppearance(LineStyleEnum lineStyle, + CurveInterpolationEnum interpolationType, + int curveThickness, + const QColor& curveColor) +{ + QwtPlotCurve::CurveStyle curveStyle = QwtPlotCurve::NoCurve; + Qt::PenStyle penStyle = Qt::SolidLine; + + if (lineStyle != STYLE_NONE) + { + switch (interpolationType) + { + case INTERPOLATION_STEP_LEFT: + curveStyle = QwtPlotCurve::Steps; + setCurveAttribute(QwtPlotCurve::Inverted, false); + break; + case INTERPOLATION_POINT_TO_POINT: // Fall through + default: + curveStyle = QwtPlotCurve::Lines; + break; + } + + switch (lineStyle) + { + case STYLE_SOLID: + penStyle = Qt::SolidLine; + break; + case STYLE_DASH: + penStyle = Qt::DashLine; + break; + case STYLE_DOT: + penStyle = Qt::DotLine; + break; + case STYLE_DASH_DOT: + penStyle = Qt::DashDotLine; + break; + + default: + break; + } + } + QPen curvePen(curveColor); + curvePen.setWidth(curveThickness); + curvePen.setStyle(penStyle); + + setPen(curvePen); + setStyle(curveStyle); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuQwtPlotCurve::fromQDateTime(const std::vector& dateTimes) +{ + std::vector doubleValues; + + if (!dateTimes.empty()) + { + doubleValues.reserve(dateTimes.size()); + + for (const auto& dt : dateTimes) + { + doubleValues.push_back(QwtDate::toDouble(dt)); + } + } + + return doubleValues; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuQwtPlotCurve::fromTime_t(const std::vector& timeSteps) +{ + std::vector doubleValues; + + if (!timeSteps.empty()) + { + doubleValues.reserve(timeSteps.size()); + for (const auto& time : timeSteps) + { + double milliSecSinceEpoch = time * 1000; // This is kind of hack, as the c++ standard does not state what time_t is. "Almost always" secs since epoch according to cppreference.com + + doubleValues.push_back(milliSecSinceEpoch); + } + } + + return doubleValues; +} diff --git a/ApplicationCode/UserInterface/RiuLineSegmentQwtPlotCurve.h b/ApplicationCode/UserInterface/RiuQwtPlotCurve.h similarity index 64% rename from ApplicationCode/UserInterface/RiuLineSegmentQwtPlotCurve.h rename to ApplicationCode/UserInterface/RiuQwtPlotCurve.h index 31e220fcf9..6d483db3f2 100644 --- a/ApplicationCode/UserInterface/RiuLineSegmentQwtPlotCurve.h +++ b/ApplicationCode/UserInterface/RiuQwtPlotCurve.h @@ -19,7 +19,11 @@ #pragma once +#include "qwt_symbol.h" #include "qwt_plot_curve.h" +#include "qwt_plot_intervalcurve.h" + +class RiuErrorBarsQwtPlotCurve; //================================================================================================== // @@ -41,14 +45,35 @@ // Values 1.0|2.0|inf|inf|inf|1.0|2.0|1.0|inf|1.0|1.0|inf|1.0|inf // Vec index 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13 //================================================================================================== -class RiuLineSegmentQwtPlotCurve : public QwtPlotCurve +class RiuQwtPlotCurve : public QwtPlotCurve { public: - explicit RiuLineSegmentQwtPlotCurve(const QString &title = QString::null); - virtual ~RiuLineSegmentQwtPlotCurve(); + enum CurveInterpolationEnum + { + INTERPOLATION_POINT_TO_POINT, + INTERPOLATION_STEP_LEFT, + }; + + enum LineStyleEnum + { + STYLE_NONE, + STYLE_SOLID, + STYLE_DASH, + STYLE_DOT, + STYLE_DASH_DOT + }; + +public: + explicit RiuQwtPlotCurve(const QString &title = QString::null); + ~RiuQwtPlotCurve() override; + + void setSamplesFromXValuesAndYValues(const std::vector& xValues, + const std::vector& yValues, + bool keepOnlyPositiveValues); void setSamplesFromXValuesAndYValues(const std::vector& xValues, const std::vector& yValues, + const std::vector& yErrorValues, bool keepOnlyPositiveValues); void setSamplesFromDatesAndYValues(const std::vector& dateTimes, @@ -59,18 +84,34 @@ class RiuLineSegmentQwtPlotCurve : public QwtPlotCurve const std::vector& yValues, bool keepOnlyPositiveValues); + void setSamplesFromTimeTAndYValues(const std::vector& dateTimes, + const std::vector& yValues, + const std::vector& yErrorValues, + bool keepOnlyPositiveValues); + void setLineSegmentStartStopIndices(const std::vector< std::pair >& lineSegmentStartStopIndices); void setSymbolSkipPixelDistance(float distance); + void attach(QwtPlot *plot); + void detach(); + void clearErrorBars(); + void showErrorBars(bool show); + void setErrorBarsColor(QColor color); + + void setAppearance(LineStyleEnum lineStyle, + CurveInterpolationEnum interpolationType, + int curveThickness, + const QColor& curveColor); + protected: - virtual void drawCurve(QPainter* p, int style, + void drawCurve(QPainter* p, int style, const QwtScaleMap& xMap, const QwtScaleMap& yMap, const QRectF& canvasRect, - int from, int to) const; + int from, int to) const override; - virtual void drawSymbols(QPainter *p, const QwtSymbol &symbol, + void drawSymbols(QPainter *p, const QwtSymbol &symbol, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, @@ -83,4 +124,8 @@ class RiuLineSegmentQwtPlotCurve : public QwtPlotCurve private: std::vector< std::pair > m_polyLineStartStopIndices; float m_symbolSkipPixelDistance; + + bool m_showErrorBars; + QwtPlotIntervalCurve* m_errorBars; + QwtPlot* m_attachedToPlot; }; diff --git a/ApplicationCode/UserInterface/RiuQwtPlotItemGroup.cpp b/ApplicationCode/UserInterface/RiuQwtPlotItemGroup.cpp new file mode 100644 index 0000000000..6d9b4a2a1d --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtPlotItemGroup.cpp @@ -0,0 +1,110 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuQwtPlotItemGroup.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuQwtPlotItemGroup::RiuQwtPlotItemGroup() +{ + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuQwtPlotItemGroup::~RiuQwtPlotItemGroup() +{ + this->detach(); + for (QwtPlotItem* item : m_plotItems) + { + delete item; + } + for (QwtPlotItem* legendItem : m_legendItems) + { + delete legendItem; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotItemGroup::addPlotItem(QwtPlotItem* plotItem) +{ + m_plotItems.push_back(plotItem); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotItemGroup::addLegendItem(QwtPlotItem* legendItem) +{ + m_legendItems.push_back(legendItem); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtPlotItemGroup::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const +{ + for (const QwtPlotItem* item : m_plotItems) + { + item->draw(painter, xMap, yMap, canvasRect); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QRectF RiuQwtPlotItemGroup::boundingRect() const +{ + QRectF totalBoundingRect; + for (const QwtPlotItem* item : m_plotItems) + { + totalBoundingRect = totalBoundingRect.united(item->boundingRect()); + } + return totalBoundingRect; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QwtGraphic RiuQwtPlotItemGroup::legendIcon(int index, const QSizeF& size) const +{ + QwtGraphic graphic; + graphic.setDefaultSize(size); + + QPainter painter(&graphic); + painter.setRenderHint(QPainter::Antialiasing, + testRenderHint(QwtPlotItem::RenderAntialiased)); + + for (QwtPlotItem* legendItem : m_legendItems) + { + QwtGraphic subGraphic = legendItem->legendIcon(index, legendItem->legendIconSize()); + QRectF boundingRect = legendItem->boundingRect(); + QImage subImage = subGraphic.toImage(); + QRectF subRect(0.0, 0.0, legendItem->legendIconSize().width(), legendItem->legendIconSize().height()); + // Symbols may not have a bounding width/height. Force the width height to be the same as the icon + boundingRect.setWidth(subRect.width()); + boundingRect.setHeight(subRect.height()); + // Paint onto the existing icon + painter.drawImage(boundingRect, subImage, subRect); + } + return graphic; +} diff --git a/ApplicationCode/UserInterface/RiuQwtPlotItemGroup.h b/ApplicationCode/UserInterface/RiuQwtPlotItemGroup.h new file mode 100644 index 0000000000..38e27905ad --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtPlotItemGroup.h @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "qwt_plot_item.h" + +class QwtGraphic; +class QRectF; +class QPainter; + +//================================================================================================== +/// Class that can combine multiple Qwt plot items into one Qwt graphic with a combined legend. +/// +//================================================================================================== +class RiuQwtPlotItemGroup : public QwtPlotItem +{ +public: + RiuQwtPlotItemGroup(); + ~RiuQwtPlotItemGroup() override; + + void addPlotItem(QwtPlotItem* plotItem); + void addLegendItem(QwtPlotItem* legendItem); + + int rtti() const override { return 5000; } + void draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const override; + QRectF boundingRect() const override; + QwtGraphic legendIcon(int index, const QSizeF &size) const override; + +private: + std::vector m_plotItems; + std::vector m_legendItems; +}; + diff --git a/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h index a06f28b63a..7991d36b0f 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h +++ b/ApplicationCode/UserInterface/RiuQwtPlotWheelZoomer.h @@ -28,7 +28,7 @@ class RiuQwtPlotWheelZoomer : public QObject public: RiuQwtPlotWheelZoomer(QwtPlot* plot); - virtual bool eventFilter(QObject * watched, QEvent * event) override; + bool eventFilter(QObject * watched, QEvent * event) override; signals: void zoomUpdated(); diff --git a/ApplicationCode/UserInterface/RiuQwtPlotZoomer.h b/ApplicationCode/UserInterface/RiuQwtPlotZoomer.h index 1cdb0e9903..690adc976a 100644 --- a/ApplicationCode/UserInterface/RiuQwtPlotZoomer.h +++ b/ApplicationCode/UserInterface/RiuQwtPlotZoomer.h @@ -25,7 +25,7 @@ class RiuQwtPlotZoomer : public QwtPlotZoomer RiuQwtPlotZoomer(QWidget * canvas, bool doReplot=true) : QwtPlotZoomer(canvas, doReplot) {} protected: - virtual QSizeF minZoomSize() const override + QSizeF minZoomSize() const override { return QwtPlotZoomer::minZoomSize() / 10.0e6; } diff --git a/ApplicationCode/UserInterface/RiuQwtScalePicker.h b/ApplicationCode/UserInterface/RiuQwtScalePicker.h index 3f9955ff88..cecf5b17c8 100644 --- a/ApplicationCode/UserInterface/RiuQwtScalePicker.h +++ b/ApplicationCode/UserInterface/RiuQwtScalePicker.h @@ -14,7 +14,7 @@ class RiuQwtScalePicker : public QObject public: explicit RiuQwtScalePicker(QwtPlot *plot); - virtual bool eventFilter( QObject *, QEvent * ); + bool eventFilter( QObject *, QEvent * ) override; Q_SIGNALS: void clicked( int axis, double value ); diff --git a/ApplicationCode/UserInterface/RiuQwtSymbol.cpp b/ApplicationCode/UserInterface/RiuQwtSymbol.cpp new file mode 100644 index 0000000000..092f8df2eb --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtSymbol.cpp @@ -0,0 +1,181 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Equinor ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuQwtSymbol.h" + +#include + +//-------------------------------------------------------------------------------------------------- +/// Internal class to support labels on symbols +//-------------------------------------------------------------------------------------------------- +RiuQwtSymbol::RiuQwtSymbol(PointSymbolEnum riuStyle, const QString& label, LabelPosition labelPosition) + : QwtSymbol(QwtSymbol::NoSymbol), m_label(label), m_labelPosition(labelPosition) +{ + QwtSymbol::Style style = QwtSymbol::NoSymbol; + + switch (riuStyle) + { + case SYMBOL_ELLIPSE: + style = QwtSymbol::Ellipse; + break; + case SYMBOL_RECT: + style = QwtSymbol::Rect; + break; + case SYMBOL_DIAMOND: + style = QwtSymbol::Diamond; + break; + case SYMBOL_TRIANGLE: + style = QwtSymbol::Triangle; + break; + case SYMBOL_CROSS: + style = QwtSymbol::Cross; + break; + case SYMBOL_XCROSS: + style = QwtSymbol::XCross; + break; + case SYMBOL_DOWN_TRIANGLE: + style = QwtSymbol::DTriangle; + break; + case SYMBOL_LEFT_TRIANGLE: + style = QwtSymbol::Path; + { + QPainterPath path; + path.moveTo(0, 0); + path.lineTo(-10, 10); + path.lineTo(0, 20); + path.lineTo(0, 0); + setPath(path); + setPinPoint(QPointF(0, 0)); + } + break; + case SYMBOL_RIGHT_TRIANGLE: + style = QwtSymbol::Path; + { + QPainterPath path; + path.moveTo(0, 0); + path.lineTo(10, 10); + path.lineTo(0, 20); + path.lineTo(0, 0); + setPath(path); + setPinPoint(QPointF(0, 0)); + } + break; + case SYMBOL_LEFT_ANGLED_TRIANGLE: + style = QwtSymbol::Path; + { + QPainterPath path; + path.moveTo(0, 0); + path.lineTo(0, 10); + path.lineTo(-10, 10); + path.lineTo(0, 0); + setPath(path); + setPinPoint(QPointF(0, 10)); + } + break; + case SYMBOL_RIGHT_ANGLED_TRIANGLE: + style = QwtSymbol::Path; + { + QPainterPath path; + path.moveTo(0, 0); + path.lineTo(0, 10); + path.lineTo(10, 10); + path.lineTo(0, 0); + setPath(path); + setPinPoint(QPointF(0, 10)); + } + break; + default: + break; + } + setStyle(style); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtSymbol::renderSymbols(QPainter *painter, const QPointF *points, int numPoints) const +{ + QwtSymbol::renderSymbols(painter, points, numPoints); + + if (!m_label.isEmpty()) + { + for (int i = 0; i < numPoints; i++) + { + auto position = points[i]; + renderSymbolLabel(painter, position); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtSymbol::renderSymbolLabel(QPainter *painter, const QPointF& position) const +{ + QSize symbolSize = QwtSymbol::size(); + QRect symbolRect (position.x(), position.y(), symbolSize.width(), symbolSize.height()); + QRect labelRect = labelBoundingRect(symbolRect); + painter->drawText(labelRect.topLeft(), m_label); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQwtSymbol::setLabelPosition(LabelPosition labelPosition) +{ + m_labelPosition = labelPosition; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QRect RiuQwtSymbol::boundingRect() const +{ + QRect symbolRect = QwtSymbol::boundingRect(); + QRect labelRect = labelBoundingRect(symbolRect); + return symbolRect.united(labelRect); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QRect RiuQwtSymbol::labelBoundingRect(const QRect& symbolRect) const +{ + QPoint symbolPosition = symbolRect.topLeft(); + + int symbolWidth = symbolRect.width(); + + int labelWidth = QPainter().fontMetrics().width(m_label); + int labelHeight = QPainter().fontMetrics().height(); + + QPoint labelPosition; + if (m_labelPosition == LabelAboveSymbol) + { + labelPosition = QPoint(symbolPosition.x() - labelWidth / 2, symbolPosition.y() - 5); + } + else if (m_labelPosition == LabelLeftOfSymbol) + { + labelPosition = QPoint(symbolPosition.x() - labelWidth - symbolWidth, symbolPosition.y()); + } + else if (m_labelPosition == LabelRightOfSymbol) + { + labelPosition = QPoint(symbolPosition.x() + symbolWidth + 3, symbolPosition.y()); + } + return QRect(labelPosition.x(), labelPosition.y(), labelWidth, labelHeight); +} diff --git a/ApplicationCode/UserInterface/RiuQwtSymbol.h b/ApplicationCode/UserInterface/RiuQwtSymbol.h new file mode 100644 index 0000000000..d9e813a927 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuQwtSymbol.h @@ -0,0 +1,73 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2015- Equinor ASA +// Copyright (C) 2015- Ceetron Solutions AS +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "qwt_symbol.h" +#include + +//-------------------------------------------------------------------------------------------------- +/// This class overrides renderSymbols to draw symbols and labels. +/// The label is only visible in the legend, while it is clipped in the plot. +/// Therefore the method RiuQwtPlotCurve::drawSymbols also draw labels to have labels +/// in the plot as well. +//-------------------------------------------------------------------------------------------------- +class RiuQwtSymbol : public QwtSymbol +{ +public: + enum LabelPosition + { + LabelAboveSymbol, + LabelLeftOfSymbol, + LabelRightOfSymbol + }; + enum PointSymbolEnum + { + SYMBOL_NONE, + SYMBOL_ELLIPSE, + SYMBOL_RECT, + SYMBOL_DIAMOND, + SYMBOL_TRIANGLE, + SYMBOL_CROSS, + SYMBOL_XCROSS, + SYMBOL_DOWN_TRIANGLE, + SYMBOL_LEFT_TRIANGLE, + SYMBOL_RIGHT_TRIANGLE, + SYMBOL_LEFT_ANGLED_TRIANGLE, + SYMBOL_RIGHT_ANGLED_TRIANGLE + }; + + RiuQwtSymbol(PointSymbolEnum riuStyle, const QString& label, LabelPosition labelPosition = LabelAboveSymbol); + + void renderSymbols(QPainter *painter, const QPointF *points, int numPoints) const override; + void renderSymbolLabel(QPainter *painter, const QPointF& position) const; + QString label() const { return m_label; } + + void setLabelPosition(LabelPosition labelPosition); + QRect boundingRect() const override; + +private: + QRect labelBoundingRect(const QRect& symbolRect) const; + +private: + QString m_label; + LabelPosition m_labelPosition; +}; + + diff --git a/ApplicationCode/UserInterface/RiuRecentFileActionProvider.h b/ApplicationCode/UserInterface/RiuRecentFileActionProvider.h index 7bfe102d28..db1974b944 100644 --- a/ApplicationCode/UserInterface/RiuRecentFileActionProvider.h +++ b/ApplicationCode/UserInterface/RiuRecentFileActionProvider.h @@ -36,7 +36,7 @@ class RiuRecentFileActionProvider : public QObject public: explicit RiuRecentFileActionProvider(int maxActionCount = 9); - ~RiuRecentFileActionProvider(); + ~RiuRecentFileActionProvider() override; void addFileName(const QString& fileName); std::vector actions() const; diff --git a/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp b/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp index 48a35fb816..ed8c43f4d6 100644 --- a/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp +++ b/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.cpp @@ -19,10 +19,10 @@ #include "RiuRelativePermeabilityPlotPanel.h" #include "RiuRelativePermeabilityPlotUpdater.h" #include "RiuSummaryQwtPlot.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuTextDialog.h" -#include "RigCurveDataTools.h" +#include "RiaCurveDataTools.h" #include "RigFlowDiagSolverInterface.h" #include "cvfBase.h" @@ -37,6 +37,7 @@ #include "qwt_scale_engine.h" #include +#include #include #include #include @@ -59,8 +60,8 @@ class RelPermQwtPlot : public QwtPlot { public: RelPermQwtPlot(QWidget* parent) : QwtPlot(parent) {} - virtual QSize sizeHint() const { return QSize(100, 100); } - virtual QSize minimumSizeHint() const { return QSize(0, 0); } + QSize sizeHint() const override { return QSize(100, 100); } + QSize minimumSizeHint() const override { return QSize(0, 0); } }; @@ -99,23 +100,29 @@ RiuRelativePermeabilityPlotPanel::RiuRelativePermeabilityPlotPanel(QDockWidget* m_selectedCurvesButtonGroup->addButton(new QCheckBox("PCOG"), RigFlowDiagSolverInterface::RelPermCurve::PCOG); QGroupBox* groupBox = new QGroupBox("Curves"); - QVBoxLayout* groupBoxLayout = new QVBoxLayout; + QGridLayout* groupBoxLayout = new QGridLayout; groupBox->setLayout(groupBoxLayout); QList checkButtonList = m_selectedCurvesButtonGroup->buttons(); for (int i = 0; i < checkButtonList.size(); i++) { checkButtonList[i]->setChecked(true); - groupBoxLayout->addWidget(checkButtonList[i]); + groupBoxLayout->addWidget(checkButtonList[i], i / 2, i % 2); } - m_logarithmicScaleKrAxisCheckBox = new QCheckBox("Logarithmic Scale\nKr Axis"); + m_logarithmicScaleKrAxisCheckBox = new QCheckBox("Log Scale Kr Axis"); m_showUnscaledCheckBox = new QCheckBox("Show Unscaled"); + m_fixedXAxisCheckBox = new QCheckBox("Fixed [0, 1] X-axis"); + m_fixedLeftYAxisCheckBox = new QCheckBox("Fixed [0, 1] Kr-axis"); + m_fixedXAxisCheckBox->setChecked(true); + m_fixedLeftYAxisCheckBox->setChecked(true); QVBoxLayout* leftLayout = new QVBoxLayout; leftLayout->addWidget(groupBox); leftLayout->addWidget(m_logarithmicScaleKrAxisCheckBox); leftLayout->addWidget(m_showUnscaledCheckBox); + leftLayout->addWidget(m_fixedXAxisCheckBox); + leftLayout->addWidget(m_fixedLeftYAxisCheckBox); leftLayout->addStretch(1); QHBoxLayout* mainLayout = new QHBoxLayout(); @@ -128,6 +135,8 @@ RiuRelativePermeabilityPlotPanel::RiuRelativePermeabilityPlotPanel(QDockWidget* connect(m_selectedCurvesButtonGroup, SIGNAL(buttonClicked(int)), SLOT(slotButtonInButtonGroupClicked(int))); connect(m_logarithmicScaleKrAxisCheckBox, SIGNAL(stateChanged(int)), SLOT(slotSomeCheckBoxStateChanged(int))); connect(m_showUnscaledCheckBox, SIGNAL(stateChanged(int)), SLOT(slotSomeCheckBoxStateChanged(int))); + connect(m_fixedXAxisCheckBox, SIGNAL(stateChanged(int)), SLOT(slotSomeCheckBoxStateChanged(int))); + connect(m_fixedLeftYAxisCheckBox, SIGNAL(stateChanged(int)), SLOT(slotSomeCheckBoxStateChanged(int))); plotUiSelectedCurves(); } @@ -208,7 +217,7 @@ void RiuRelativePermeabilityPlotPanel::clearPlot() m_caseName.clear(); m_cellReferenceText.clear(); - plotCurvesInQwt(m_unitSystem, m_allCurvesArr, m_swat, m_sgas, m_cellReferenceText, false, m_qwtPlot, &m_myPlotMarkers); + plotCurvesInQwt(m_unitSystem, m_allCurvesArr, m_swat, m_sgas, m_cellReferenceText, false, true, true, m_qwtPlot, &m_myPlotMarkers); } //-------------------------------------------------------------------------------------------------- @@ -226,8 +235,10 @@ void RiuRelativePermeabilityPlotPanel::plotUiSelectedCurves() { std::vector selectedCurves = gatherUiSelectedCurves(); - const bool useLogScale = m_logarithmicScaleKrAxisCheckBox->isChecked() ? true : false; - plotCurvesInQwt(m_unitSystem, selectedCurves, m_swat, m_sgas, m_cellReferenceText, useLogScale, m_qwtPlot, &m_myPlotMarkers); + const bool useLogScale = m_logarithmicScaleKrAxisCheckBox->isChecked(); + const bool fixedXAxis = m_fixedXAxisCheckBox->isChecked(); + const bool fixedYAxis = m_fixedLeftYAxisCheckBox->isChecked(); + plotCurvesInQwt(m_unitSystem, selectedCurves, m_swat, m_sgas, m_cellReferenceText, useLogScale, fixedXAxis, fixedYAxis, m_qwtPlot, &m_myPlotMarkers); } //-------------------------------------------------------------------------------------------------- @@ -246,7 +257,7 @@ void RiuRelativePermeabilityPlotPanel::addTransparentCurve(QwtPlot* plot, const for (size_t i = 0; i < points.size(); i++) { - if (!RigCurveDataTools::isValidValue(points[i].y(), logScaleLeftAxis)) continue; + if (!RiaCurveDataTools::isValidValue(points[i].y(), logScaleLeftAxis)) continue; if (axes[i] == LEFT_YAXIS) { @@ -282,7 +293,9 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(RiaEclipseUnitTools::Unit double swat, double sgas, QString cellReferenceText, - bool logScaleLeftAxis, + bool logScaleLeftAxis, + bool fixedXAxis, + bool fixedLeftYAxis, QwtPlot* plot, std::vector* myPlotMarkers) { @@ -315,7 +328,7 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(RiaEclipseUnitTools::Unit } //QwtPlotCurve* qwtCurve = new QwtPlotCurve(curve.name.c_str()); - RiuLineSegmentQwtPlotCurve* qwtCurve = new RiuLineSegmentQwtPlotCurve(curve.name.c_str()); + RiuQwtPlotCurve* qwtCurve = new RiuQwtPlotCurve(curve.name.c_str()); CVF_ASSERT(curve.saturationVals.size() == curve.yVals.size()); //qwtCurve->setSamples(curve.xVals.data(), curve.yVals.data(), static_cast(curve.xVals.size())); @@ -403,7 +416,6 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(RiaEclipseUnitTools::Unit if (!dynamic_cast(plot->axisScaleEngine(QwtPlot::yLeft))) { plot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLogScaleEngine); - //plot->setAxisAutoScale(QwtPlot::yLeft, true); } } else @@ -411,10 +423,37 @@ void RiuRelativePermeabilityPlotPanel::plotCurvesInQwt(RiaEclipseUnitTools::Unit if (!dynamic_cast(plot->axisScaleEngine(QwtPlot::yLeft))) { plot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine); - //plot->setAxisAutoScale(QwtPlot::yLeft, true); } } + if (fixedXAxis) + { + plot->setAxisScale(QwtPlot::xBottom, 0.0, 1.0); + plot->setAxisAutoScale(QwtPlot::xBottom, false); + } + else + { + plot->setAxisAutoScale(QwtPlot::xBottom, true); + } + + if (fixedLeftYAxis) + { + if (logScaleLeftAxis) + { + plot->setAxisScale(QwtPlot::yLeft, 1.0e-6, 1.0); + } + else + { + plot->setAxisScale(QwtPlot::yLeft, 0.0, 1.0); + } + plot->setAxisAutoScale(QwtPlot::yLeft, false); + } + else + { + plot->setAxisAutoScale(QwtPlot::yLeft, true); + } + + QString titleStr = "Relative Permeability"; if (!cellReferenceText.isEmpty()) diff --git a/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.h b/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.h index faeb469935..d5a5d65b03 100644 --- a/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.h +++ b/ApplicationCode/UserInterface/RiuRelativePermeabilityPlotPanel.h @@ -44,7 +44,7 @@ class RiuRelativePermeabilityPlotPanel : public QWidget public: RiuRelativePermeabilityPlotPanel(QDockWidget* parent); - virtual ~RiuRelativePermeabilityPlotPanel(); + ~RiuRelativePermeabilityPlotPanel() override; void setPlotData(RiaEclipseUnitTools::UnitSystem unitSystem, const std::vector& relPermCurves, @@ -81,6 +81,8 @@ class RiuRelativePermeabilityPlotPanel : public QWidget double sgas, QString cellReferenceText, bool logScaleLeftAxis, + bool fixedXAxis, + bool fixedLeftYAxis, QwtPlot* plot, std::vector* myPlotMarkers); @@ -108,7 +110,7 @@ class RiuRelativePermeabilityPlotPanel : public QWidget std::vector gatherUiSelectedCurves() const; QString asciiDataForUiSelectedCurves() const; - virtual void contextMenuEvent(QContextMenuEvent* event) override; + void contextMenuEvent(QContextMenuEvent* event) override; private slots: void slotButtonInButtonGroupClicked(int); @@ -128,6 +130,8 @@ private slots: QButtonGroup* m_selectedCurvesButtonGroup; QCheckBox* m_showUnscaledCheckBox; QCheckBox* m_logarithmicScaleKrAxisCheckBox; + QCheckBox* m_fixedXAxisCheckBox; + QCheckBox* m_fixedLeftYAxisCheckBox; std::unique_ptr m_plotUpdater; }; diff --git a/ApplicationCode/UserInterface/RiuResultInfoPanel.h b/ApplicationCode/UserInterface/RiuResultInfoPanel.h index 96e964e31c..f067383d33 100644 --- a/ApplicationCode/UserInterface/RiuResultInfoPanel.h +++ b/ApplicationCode/UserInterface/RiuResultInfoPanel.h @@ -39,7 +39,7 @@ class RiuResultInfoPanel : public QWidget void setInfo(const QString& info); - virtual QSize sizeHint () const; + QSize sizeHint () const override; private: static void convertStringToHTML(QString* str); diff --git a/ApplicationCode/UserInterface/RiuResultQwtPlot.cpp b/ApplicationCode/UserInterface/RiuResultQwtPlot.cpp index bcb625f6d1..e844873ff4 100644 --- a/ApplicationCode/UserInterface/RiuResultQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuResultQwtPlot.cpp @@ -19,12 +19,13 @@ #include "RiuResultQwtPlot.h" -#include "RigCurveDataTools.h" +#include "RiaCurveDataTools.h" +#include "RiaQDateTimeTools.h" #include "RimContextCommandBuilder.h" #include "RimCase.h" -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "RiuSummaryQwtPlot.h" #include "RiuTextDialog.h" @@ -72,7 +73,7 @@ void RiuResultQwtPlot::addCurve(const RimCase* rimCase, const QString& curveName return; } - RiuLineSegmentQwtPlotCurve* plotCurve = new RiuLineSegmentQwtPlotCurve("Curve 1"); + RiuQwtPlotCurve* plotCurve = new RiuQwtPlotCurve("Curve 1"); plotCurve->setSamplesFromDatesAndYValues(dateTimes, timeHistoryValues, false); plotCurve->setTitle(curveName); @@ -214,7 +215,10 @@ QString RiuResultQwtPlot::asciiDataForUiSelectedCurves() const } } out += "\n"; - out += m_timeSteps.at(caseId)[i].toString("yyyy-MM-dd hh:mm:ss "); + + QString dateString = RiaQDateTimeTools::toStringUsingApplicationLocale(m_timeSteps.at(caseId)[i], "yyyy-MM-dd hh:mm:ss "); + + out += dateString; for (size_t j = 0; j < m_curveData.at(caseId).size(); j++) // curves { diff --git a/ApplicationCode/UserInterface/RiuResultQwtPlot.h b/ApplicationCode/UserInterface/RiuResultQwtPlot.h index 725a1c4a4d..85ec959cbe 100644 --- a/ApplicationCode/UserInterface/RiuResultQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuResultQwtPlot.h @@ -45,7 +45,7 @@ class RiuResultQwtPlot : public QwtPlot public: explicit RiuResultQwtPlot(QWidget* parent = nullptr); - virtual ~RiuResultQwtPlot(); + ~RiuResultQwtPlot() override; void addCurve(const RimCase* rimCase, const QString& curveName, @@ -61,9 +61,9 @@ class RiuResultQwtPlot : public QwtPlot void deleteAllCurves(); protected: - virtual QSize sizeHint() const override; - virtual QSize minimumSizeHint() const override; - virtual void contextMenuEvent(QContextMenuEvent *) override; + QSize sizeHint() const override; + QSize minimumSizeHint() const override; + void contextMenuEvent(QContextMenuEvent *) override; private: void setDefaults(); diff --git a/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp b/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp index d957952604..2017ed62b2 100644 --- a/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp +++ b/ApplicationCode/UserInterface/RiuResultTextBuilder.cpp @@ -57,7 +57,7 @@ RiuResultTextBuilder::RiuResultTextBuilder(RimEclipseView* reservoirView, size_t m_timeStepIndex = timeStepIndex; m_nncIndex = cvf::UNDEFINED_SIZE_T; - m_intersectionPoint = cvf::Vec3d::UNDEFINED; + m_intersectionPointInDisplay = cvf::Vec3d::UNDEFINED; m_face = cvf::StructGridInterface::NO_FACE; } @@ -95,7 +95,7 @@ RiuResultTextBuilder::RiuResultTextBuilder(RimEclipseView* reservoirView, size_t m_timeStepIndex = timeStepIndex; m_nncIndex = cvf::UNDEFINED_SIZE_T; - m_intersectionPoint = cvf::Vec3d::UNDEFINED; + m_intersectionPointInDisplay = cvf::Vec3d::UNDEFINED; m_face = cvf::StructGridInterface::NO_FACE; } @@ -110,9 +110,9 @@ void RiuResultTextBuilder::setNncIndex(size_t nncIndex) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuResultTextBuilder::setIntersectionPoint(cvf::Vec3d intersectionPoint) +void RiuResultTextBuilder::setIntersectionPointInDisplay(cvf::Vec3d intersectionPointInDisplay) { - m_intersectionPoint = intersectionPoint; + m_intersectionPointInDisplay = intersectionPointInDisplay; } //-------------------------------------------------------------------------------------------------- @@ -226,21 +226,21 @@ QString RiuResultTextBuilder::geometrySelectionText(QString itemSeparator) } } - if (m_intersectionPoint != cvf::Vec3d::UNDEFINED) + if (m_intersectionPointInDisplay != cvf::Vec3d::UNDEFINED) { cvf::ref transForm = m_reservoirView->displayCoordTransform(); - cvf::Vec3d domainCoord = transForm->translateToDomainCoord(m_intersectionPoint); + cvf::Vec3d domainCoord = transForm->translateToDomainCoord(m_intersectionPointInDisplay); QString formattedText; if (m_2dIntersectionView) { - formattedText.sprintf("Horizontal length from well start: %.2f", m_intersectionPoint.x()); + formattedText.sprintf("Horizontal length from well start: %.2f", m_intersectionPointInDisplay.x()); text += formattedText + itemSeparator; - cvf::Mat4d t = m_2dIntersectionView->flatIntersectionPartMgr()->unflattenTransformMatrix(m_intersectionPoint); + cvf::Mat4d t = m_2dIntersectionView->flatIntersectionPartMgr()->unflattenTransformMatrix(m_intersectionPointInDisplay); if (!t.isZero()) { - cvf::Vec3d intPt = m_intersectionPoint.getTransformedPoint(t); + cvf::Vec3d intPt = m_intersectionPointInDisplay.getTransformedPoint(t); formattedText.sprintf("Intersection point : [E: %.2f, N: %.2f, Depth: %.2f]", intPt.x(), intPt.y(), -intPt.z()); text += formattedText; } @@ -267,7 +267,6 @@ QString RiuResultTextBuilder::gridResultDetails() if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->eclipseCaseData()) { RigEclipseCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->eclipseCaseData(); - RigGridBase* grid = eclipseCaseData->grid(m_gridIndex); this->appendTextFromResultColors(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->cellResult(), &text); @@ -744,7 +743,6 @@ QString RiuResultTextBuilder::cellResultText(RimEclipseCellColors* resultColors) if (m_reservoirView->eclipseCase() && m_reservoirView->eclipseCase()->eclipseCaseData()) { RigEclipseCaseData* eclipseCaseData = m_reservoirView->eclipseCase()->eclipseCaseData(); - RigGridBase* grid = eclipseCaseData->grid(m_gridIndex); if (resultColors->isTernarySaturationSelected()) { diff --git a/ApplicationCode/UserInterface/RiuResultTextBuilder.h b/ApplicationCode/UserInterface/RiuResultTextBuilder.h index b7a7ec2467..03a54e0efe 100644 --- a/ApplicationCode/UserInterface/RiuResultTextBuilder.h +++ b/ApplicationCode/UserInterface/RiuResultTextBuilder.h @@ -46,7 +46,7 @@ class RiuResultTextBuilder void setFace(cvf::StructGridInterface::FaceType face); void setNncIndex(size_t nncIndex); - void setIntersectionPoint(cvf::Vec3d intersectionPoint); + void setIntersectionPointInDisplay(cvf::Vec3d intersectionPointInDisplay); void set2dIntersectionView(Rim2dIntersectionView* intersectionView); QString mainResultText(); @@ -83,5 +83,5 @@ class RiuResultTextBuilder size_t m_nncIndex; - cvf::Vec3d m_intersectionPoint; + cvf::Vec3d m_intersectionPointInDisplay; }; diff --git a/ApplicationCode/UserInterface/RiuRimQwtPlotCurve.cpp b/ApplicationCode/UserInterface/RiuRimQwtPlotCurve.cpp index 56914e98d7..78ed505893 100644 --- a/ApplicationCode/UserInterface/RiuRimQwtPlotCurve.cpp +++ b/ApplicationCode/UserInterface/RiuRimQwtPlotCurve.cpp @@ -23,7 +23,7 @@ /// //-------------------------------------------------------------------------------------------------- RiuRimQwtPlotCurve::RiuRimQwtPlotCurve(RimPlotCurve* ownerRimCurve, const QString &title /*= QString::null*/) - : RiuLineSegmentQwtPlotCurve(title) + : RiuQwtPlotCurve(title) , m_ownerRimCurve(ownerRimCurve) { diff --git a/ApplicationCode/UserInterface/RiuRimQwtPlotCurve.h b/ApplicationCode/UserInterface/RiuRimQwtPlotCurve.h index a8cebb632a..5234bcdbf9 100644 --- a/ApplicationCode/UserInterface/RiuRimQwtPlotCurve.h +++ b/ApplicationCode/UserInterface/RiuRimQwtPlotCurve.h @@ -17,13 +17,13 @@ ///////////////////////////////////////////////////////////////////////////////// #pragma once -#include "RiuLineSegmentQwtPlotCurve.h" +#include "RiuQwtPlotCurve.h" #include "cafPdmPointer.h" class RimPlotCurve; -class RiuRimQwtPlotCurve: public RiuLineSegmentQwtPlotCurve +class RiuRimQwtPlotCurve: public RiuQwtPlotCurve { public: explicit RiuRimQwtPlotCurve(RimPlotCurve* ownerRimCurve, const QString &title = QString::null); diff --git a/ApplicationCode/UserInterface/RiuRmsNavigation.h b/ApplicationCode/UserInterface/RiuRmsNavigation.h index 7274105dc7..427128f56e 100644 --- a/ApplicationCode/UserInterface/RiuRmsNavigation.h +++ b/ApplicationCode/UserInterface/RiuRmsNavigation.h @@ -26,7 +26,7 @@ class RiuRmsNavigation : public caf::TrackBallBasedNavigation { public: RiuRmsNavigation(); - virtual ~RiuRmsNavigation(); + ~RiuRmsNavigation() override; protected: - virtual bool handleInputEvent(QInputEvent* inputEvent); + bool handleInputEvent(QInputEvent* inputEvent) override; }; diff --git a/ApplicationCode/UserInterface/RiuSelectionChangedHandler.cpp b/ApplicationCode/UserInterface/RiuSelectionChangedHandler.cpp index 513c716578..69e86f26dd 100644 --- a/ApplicationCode/UserInterface/RiuSelectionChangedHandler.cpp +++ b/ApplicationCode/UserInterface/RiuSelectionChangedHandler.cpp @@ -52,6 +52,8 @@ #include +#include + #include @@ -160,7 +162,9 @@ void RiuSelectionChangedHandler::addCurveFromSelectionItem(const RiuEclipseSelec curveName += ", "; curveName += QString("Grid index %1").arg(eclipseSelectionItem->m_gridIndex); curveName += ", "; - curveName += RigTimeHistoryResultAccessor::geometrySelectionText(eclipseView->eclipseCase()->eclipseCaseData(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex); + curveName += RigTimeHistoryResultAccessor::geometrySelectionText(eclipseView->eclipseCase()->eclipseCaseData(), + eclipseSelectionItem->m_gridIndex, + eclipseSelectionItem->m_gridLocalCellIndex); std::vector timeHistoryValues = RigTimeHistoryResultAccessor::timeHistoryValues(eclipseView->eclipseCase()->eclipseCaseData(), eclipseView->cellResult(), eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex, timeStepDates.size()); @@ -185,6 +189,8 @@ void RiuSelectionChangedHandler::addCurveFromSelectionItem(const RiuGeoMechSelec { std::unique_ptr timeHistResultAccessor; + cvf::Vec3d intersectionPointInDomain = geoMechView->displayCoordTransform()->translateToDomainCoord(geomSelectionItem->m_localIntersectionPointInDisplay); + if ( geomSelectionItem->m_hasIntersectionTriangle ) { timeHistResultAccessor = std::unique_ptr( @@ -193,7 +199,7 @@ void RiuSelectionChangedHandler::addCurveFromSelectionItem(const RiuGeoMechSelec geomSelectionItem->m_gridIndex, static_cast(geomSelectionItem->m_cellIndex), geomSelectionItem->m_elementFace, - geomSelectionItem->m_localIntersectionPoint, + intersectionPointInDomain, geomSelectionItem->m_intersectionTriangle)); } else @@ -204,7 +210,7 @@ void RiuSelectionChangedHandler::addCurveFromSelectionItem(const RiuGeoMechSelec geomSelectionItem->m_gridIndex, static_cast(geomSelectionItem->m_cellIndex), geomSelectionItem->m_elementFace, - geomSelectionItem->m_localIntersectionPoint)); + intersectionPointInDomain)); } QString curveName; @@ -325,9 +331,18 @@ void RiuSelectionChangedHandler::updateResultInfo(const RiuSelectionItem* itemAd if (selItem->type() == RiuSelectionItem::INTERSECTION_SELECTION_OBJECT) { const Riu2dIntersectionSelectionItem* wrapperSelItem = dynamic_cast(selItem); - intersectionView = wrapperSelItem->view(); - if (wrapperSelItem && wrapperSelItem->eclipseSelectionItem()) selItem = wrapperSelItem->eclipseSelectionItem(); - else if (wrapperSelItem && wrapperSelItem->geoMechSelectionItem()) selItem = wrapperSelItem->geoMechSelectionItem(); + if (wrapperSelItem) + { + intersectionView = wrapperSelItem->view(); + if (wrapperSelItem->eclipseSelectionItem()) + { + selItem = wrapperSelItem->eclipseSelectionItem(); + } + else if (wrapperSelItem->geoMechSelectionItem()) + { + selItem = wrapperSelItem->geoMechSelectionItem(); + } + } } if (selItem->type() == RiuSelectionItem::ECLIPSE_SELECTION_OBJECT) @@ -339,7 +354,7 @@ void RiuSelectionChangedHandler::updateResultInfo(const RiuSelectionItem* itemAd RiuResultTextBuilder textBuilder(eclipseView, eclipseSelectionItem->m_gridIndex, eclipseSelectionItem->m_gridLocalCellIndex, eclipseView->currentTimeStep()); textBuilder.setFace(eclipseSelectionItem->m_face); textBuilder.setNncIndex(eclipseSelectionItem->m_nncIndex); - textBuilder.setIntersectionPoint(eclipseSelectionItem->m_localIntersectionPoint); + textBuilder.setIntersectionPointInDisplay(eclipseSelectionItem->m_localIntersectionPointInDisplay); textBuilder.set2dIntersectionView(intersectionView); resultInfo = textBuilder.mainResultText(); @@ -352,7 +367,7 @@ void RiuSelectionChangedHandler::updateResultInfo(const RiuSelectionItem* itemAd RimGeoMechView* geomView = geomSelectionItem->m_view.p(); RiuFemResultTextBuilder textBuilder(geomView, (int)geomSelectionItem->m_gridIndex, (int)geomSelectionItem->m_cellIndex, geomView->currentTimeStep()); - textBuilder.setIntersectionPoint(geomSelectionItem->m_localIntersectionPoint); + textBuilder.setIntersectionPointInDisplay(geomSelectionItem->m_localIntersectionPointInDisplay); textBuilder.setFace(geomSelectionItem->m_elementFace); textBuilder.set2dIntersectionView(intersectionView); if (geomSelectionItem->m_hasIntersectionTriangle) textBuilder.setIntersectionTriangle(geomSelectionItem->m_intersectionTriangle); diff --git a/ApplicationCode/UserInterface/RiuSelectionManager.cpp b/ApplicationCode/UserInterface/RiuSelectionManager.cpp index 87433a276e..39da507361 100644 --- a/ApplicationCode/UserInterface/RiuSelectionManager.cpp +++ b/ApplicationCode/UserInterface/RiuSelectionManager.cpp @@ -163,14 +163,14 @@ RiuEclipseSelectionItem::RiuEclipseSelectionItem(RimEclipseView* view, size_t nncIndex, cvf::Color3f color, cvf::StructGridInterface::FaceType face, - const cvf::Vec3d& localIntersectionPoint) + const cvf::Vec3d& localIntersectionPointInDisplay) : m_view(view), m_gridIndex(gridIndex), m_gridLocalCellIndex(cellIndex), m_nncIndex(nncIndex), m_color(color), m_face(face), - m_localIntersectionPoint(localIntersectionPoint) + m_localIntersectionPointInDisplay(localIntersectionPointInDisplay) { } @@ -182,14 +182,14 @@ RiuGeoMechSelectionItem::RiuGeoMechSelectionItem(RimGeoMechView* view, size_t cellIndex, cvf::Color3f color, int elementFace, - const cvf::Vec3d& localIntersectionPoint) + const cvf::Vec3d& localIntersectionPointInDisplay) : m_view(view) , m_gridIndex(gridIndex) , m_cellIndex(cellIndex) , m_color(color) , m_elementFace(elementFace) , m_hasIntersectionTriangle(false) - , m_localIntersectionPoint(localIntersectionPoint) + , m_localIntersectionPointInDisplay(localIntersectionPointInDisplay) { } @@ -201,7 +201,7 @@ RiuGeoMechSelectionItem::RiuGeoMechSelectionItem(RimGeoMechView* size_t cellIndex, cvf::Color3f color, int elementFace, - const cvf::Vec3d& localIntersectionPoint, + const cvf::Vec3d& localIntersectionPointInDisplay, const std::array& intersectionTriangle) : m_view(view) , m_gridIndex(gridIndex) @@ -210,7 +210,7 @@ RiuGeoMechSelectionItem::RiuGeoMechSelectionItem(RimGeoMechView* , m_elementFace(elementFace) , m_hasIntersectionTriangle(true) , m_intersectionTriangle(intersectionTriangle) - , m_localIntersectionPoint(localIntersectionPoint) + , m_localIntersectionPointInDisplay(localIntersectionPointInDisplay) { } diff --git a/ApplicationCode/UserInterface/RiuSelectionManager.h b/ApplicationCode/UserInterface/RiuSelectionManager.h index fa19b98b7c..b06af4fad8 100644 --- a/ApplicationCode/UserInterface/RiuSelectionManager.h +++ b/ApplicationCode/UserInterface/RiuSelectionManager.h @@ -137,11 +137,11 @@ class RiuEclipseSelectionItem : public RiuSelectionItem size_t nncIndex, cvf::Color3f color, cvf::StructGridInterface::FaceType face, - const cvf::Vec3d& localIntersectionPoint); + const cvf::Vec3d& localIntersectionPointInDisplay); - virtual ~RiuEclipseSelectionItem() {}; + ~RiuEclipseSelectionItem() override {}; - virtual RiuSelectionType type() const + RiuSelectionType type() const override { return ECLIPSE_SELECTION_OBJECT; } @@ -153,7 +153,7 @@ class RiuEclipseSelectionItem : public RiuSelectionItem size_t m_nncIndex; cvf::Color3f m_color; cvf::StructGridInterface::FaceType m_face; - cvf::Vec3d m_localIntersectionPoint; + cvf::Vec3d m_localIntersectionPointInDisplay; }; @@ -170,18 +170,18 @@ class RiuGeoMechSelectionItem : public RiuSelectionItem size_t cellIndex, cvf::Color3f color, int elementFace, - const cvf::Vec3d& localIntersectionPoint); + const cvf::Vec3d& localIntersectionPointInDisplay); explicit RiuGeoMechSelectionItem(RimGeoMechView* view, size_t gridIndex, size_t cellIndex, cvf::Color3f color, int elementFace, - const cvf::Vec3d& localIntersectionPoint, + const cvf::Vec3d& localIntersectionPointInDisplay, const std::array& intersectionTriangle ); - virtual ~RiuGeoMechSelectionItem() {}; + ~RiuGeoMechSelectionItem() override {}; - virtual RiuSelectionType type() const + RiuSelectionType type() const override { return GEOMECH_SELECTION_OBJECT; } @@ -194,7 +194,7 @@ class RiuGeoMechSelectionItem : public RiuSelectionItem int m_elementFace; bool m_hasIntersectionTriangle; std::array m_intersectionTriangle; - cvf::Vec3d m_localIntersectionPoint; + cvf::Vec3d m_localIntersectionPointInDisplay; }; @@ -208,9 +208,9 @@ class Riu2dIntersectionSelectionItem : public RiuSelectionItem public: explicit Riu2dIntersectionSelectionItem(Rim2dIntersectionView* view, RiuSelectionItem *selItem); - virtual ~Riu2dIntersectionSelectionItem(); + ~Riu2dIntersectionSelectionItem() override; - virtual RiuSelectionType type() const + RiuSelectionType type() const override { return INTERSECTION_SELECTION_OBJECT; } @@ -239,9 +239,9 @@ class RiuWellPathSelectionItem : public RiuSelectionItem const cvf::Vec3d& pipeCenterLineIntersectionInDomainCoords, double measuredDepth); - virtual ~RiuWellPathSelectionItem() {}; + ~RiuWellPathSelectionItem() override {}; - virtual RiuSelectionType type() const + RiuSelectionType type() const override { return WELLPATH_SELECTION_OBJECT; } @@ -265,9 +265,9 @@ class RiuSimWellSelectionItem : public RiuSelectionItem explicit RiuSimWellSelectionItem(RimSimWellInView* simwell, cvf::Vec3d domainCoord, size_t branchIndex); - virtual ~RiuSimWellSelectionItem() {}; + ~RiuSimWellSelectionItem() override {}; - virtual RiuSelectionType type() const + RiuSelectionType type() const override { return SIMWELL_SELECTION_OBJECT; } @@ -289,9 +289,9 @@ class RiuGeneralSelectionItem : public RiuSelectionItem public: RiuGeneralSelectionItem(caf::PdmObject* object); - virtual ~RiuGeneralSelectionItem() {}; + ~RiuGeneralSelectionItem() override {}; - virtual RiuSelectionType type() const + RiuSelectionType type() const override { return GENERAL_SELECTION_OBJECT; } diff --git a/ApplicationCode/UserInterface/RiuSimpleHistogramWidget.h b/ApplicationCode/UserInterface/RiuSimpleHistogramWidget.h index be82643d9f..19230f2e57 100644 --- a/ApplicationCode/UserInterface/RiuSimpleHistogramWidget.h +++ b/ApplicationCode/UserInterface/RiuSimpleHistogramWidget.h @@ -37,7 +37,7 @@ class RiuSimpleHistogramWidget : public QWidget void setMean(double mean) {m_mean = mean;} protected: - virtual void paintEvent(QPaintEvent* event); + void paintEvent(QPaintEvent* event) override; private: void draw(QPainter *painter,int x, int y, int width, int height ); diff --git a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp index abd0941df9..c5dde90a83 100644 --- a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.cpp @@ -19,7 +19,9 @@ #include "RiuSummaryCurveDefSelection.h" #include "RiaApplication.h" +#include "RiaStdStringTools.h" #include "RiaSummaryCurveDefinition.h" +#include "RiaCurveSetDefinition.h" #include "RifEclipseSummaryAddress.h" #include "RifSummaryReaderInterface.h" @@ -230,6 +232,9 @@ RiuSummaryCurveDefSelection::RiuSummaryCurveDefSelection() : m_identifierFieldsM m_multiSelectionMode = false; m_hideEnsembles = false; m_hideSummaryCases = false; + + m_prevCurveCount = 0; + m_prevCurveSetCount = 0; } //-------------------------------------------------------------------------------------------------- @@ -255,42 +260,42 @@ std::vector RiuSummaryCurveDefSelection::allCurveDefi { std::set curveDefinitions; - std::set selectedAddressesFromUi = buildAddressListFromSelections(); for (SummarySource* currSource : selectedSummarySources()) { - std::vector sourceCases; + std::vector sourceSources; RimSummaryCaseCollection* ensemble = dynamic_cast(currSource); + RimSummaryCase* sumCase = dynamic_cast(currSource); + + std::set addressesFromSource; + std::vector casesFromSource; // Build case list if (ensemble) { - auto sumCases = ensemble->allSummaryCases(); - sourceCases.insert(sourceCases.end(), sumCases.begin(), sumCases.end()); + auto addresses = ensemble->ensembleSummaryAddresses(); + addressesFromSource.insert(addresses.begin(), addresses.end()); + auto ensembleCases = ensemble->allSummaryCases(); + casesFromSource.insert(casesFromSource.end(), ensembleCases.begin(), ensembleCases.end()); } else { - RimSummaryCase* sourceCase = dynamic_cast(currSource); - if (sourceCase) + RifSummaryReaderInterface* reader = sumCase ? sumCase->summaryReader() : nullptr; + if (reader) { - sourceCases.push_back(sourceCase); + addressesFromSource.insert(reader->allResultAddresses().begin(), reader->allResultAddresses().end()); + casesFromSource.push_back(sumCase); } } - for (const auto& currCase : sourceCases) + for (auto caseFromSource : casesFromSource) { - if (currCase && currCase->summaryReader()) + for (const auto& addressFromSource : addressesFromSource) { - RifSummaryReaderInterface* reader = currCase->summaryReader(); - - const std::vector& readerAddresses = reader->allResultAddresses(); - for (const auto& readerAddress : readerAddresses) + if (selectedAddressesFromUi.count(addressFromSource) > 0) { - if (selectedAddressesFromUi.count(readerAddress) > 0) - { - curveDefinitions.insert(RiaSummaryCurveDefinition(currCase, readerAddress, ensemble)); - } + curveDefinitions.insert(RiaSummaryCurveDefinition(caseFromSource, addressFromSource, ensemble)); } } } @@ -302,6 +307,40 @@ std::vector RiuSummaryCurveDefSelection::allCurveDefi return curveDefVector; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiuSummaryCurveDefSelection::allCurveSetDefinitionsFromSelections() const +{ + std::vector curveSetDefVector; + std::set curveSetDefinitions; + std::set selectedAddressesFromUi = buildAddressListFromSelections(); + + for (SummarySource* currSource : selectedSummarySources()) + { + RimSummaryCaseCollection* ensemble = dynamic_cast(currSource); + if (!ensemble) continue; + + std::vector sourceSources; + std::set addressesFromSource; + + // Build case list + auto addresses = ensemble->ensembleSummaryAddresses(); + addressesFromSource.insert(addresses.begin(), addresses.end()); + + for (const auto& addressFromSource : addressesFromSource) + { + if (selectedAddressesFromUi.count(addressFromSource) > 0) + { + curveSetDefinitions.insert(RiaCurveSetDefinition(ensemble, addressFromSource)); + } + } + } + + std::copy(curveSetDefinitions.begin(), curveSetDefinitions.end(), std::back_inserter(curveSetDefVector)); + return curveSetDefVector; +} + //-------------------------------------------------------------------------------------------------- /// One CurveDefinition pr ensemble curve set //-------------------------------------------------------------------------------------------------- @@ -313,9 +352,10 @@ std::vector RiuSummaryCurveDefSelection::selection() { RimSummaryCaseCollection* ensemble = dynamic_cast(currSource); RimSummaryCase* sourceCase = dynamic_cast(currSource); + if (ensemble) { - std::set addressUnion = ensemble->calculateUnionOfSummaryAddresses(); + std::set addressUnion = ensemble->ensembleSummaryAddresses(); for ( const auto& addr : selectedAddressesFromUi) { if (addressUnion.count(addr)) @@ -328,10 +368,10 @@ std::vector RiuSummaryCurveDefSelection::selection() { if (!(sourceCase && sourceCase->summaryReader())) continue; - const std::vector& readerAddresses = sourceCase->summaryReader()->allResultAddresses(); - for ( const auto& addr : readerAddresses) + const std::set& readerAddresses = sourceCase->summaryReader()->allResultAddresses(); + for ( const auto& addr : selectedAddressesFromUi) { - if (selectedAddressesFromUi.count(addr)) + if (readerAddresses.count(addr)) { curveDefSelection.push_back(RiaSummaryCurveDefinition(sourceCase, addr, nullptr)); } @@ -377,21 +417,26 @@ void RiuSummaryCurveDefSelection::setFieldChangedHandler(const std::function& defaultCases) +void RiuSummaryCurveDefSelection::setDefaultSelection(const std::vector& defaultSources) { RimProject* proj = RiaApplication::instance()->project(); auto allSumCases = proj->allSummaryCases(); + auto allSumGroups = proj->summaryGroups(); + if (allSumCases.size() > 0) { - RifEclipseSummaryAddress defaultAddress = RifEclipseSummaryAddress::fieldVarAddress("FOPT"); + RifEclipseSummaryAddress defaultAddress = RifEclipseSummaryAddress(); - std::vector selectTheseCases = defaultCases; - if (selectTheseCases.empty()) selectTheseCases.push_back(allSumCases[0]); + std::vector selectTheseSources = defaultSources; + if (selectTheseSources.empty()) selectTheseSources.push_back(allSumCases[0]); std::vector curveDefs; - for(RimSummaryCase* c : selectTheseCases) + for(SummarySource* s : selectTheseSources) { - RiaSummaryCurveDefinition curveDef(c, defaultAddress); + RimSummaryCase* sumCase = dynamic_cast(s); + RimSummaryCaseCollection* ensemble = dynamic_cast(s); + + RiaSummaryCurveDefinition curveDef(sumCase, defaultAddress, ensemble); curveDefs.push_back(curveDef); } @@ -416,9 +461,12 @@ void RiuSummaryCurveDefSelection::setSelectedCurveDefinitions(const std::vector< if (summaryAddress.category() == RifEclipseSummaryAddress::SUMMARY_INVALID) { // If we have an invalid address, set the default address to Field - summaryAddress = RifEclipseSummaryAddress::fieldVarAddress(summaryAddress.quantityName()); + summaryAddress = RifEclipseSummaryAddress::fieldAddress(summaryAddress.quantityName()); } + // Ignore ensemble statistics curves + if (summaryAddress.category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) continue; + // Select summary category if not already selected auto& selectedCategories = m_selectedSummaryCategories(); @@ -428,11 +476,6 @@ void RiuSummaryCurveDefSelection::setSelectedCurveDefinitions(const std::vector< m_selectedSummaryCategories.v().push_back(summaryAddress.category()); } - if (curveDefinitions.size() == 1) - { - m_currentSummaryCategory = summaryAddress.category(); - } - // Select case if not already selected SummarySource* summSource = curveDef.isEnsembleCurve() ? static_cast(curveDef.ensemble()) : summaryCase; if (std::find(m_selectedSources.begin(), m_selectedSources.end(), summSource) == m_selectedSources.end()) @@ -476,7 +519,7 @@ std::set RiuSummaryCurveDefSelection::findPossibleSumm { RimSummaryCase* calcSumCase = calculatedSummaryCase(); - const std::vector allAddresses = calcSumCase->summaryReader()->allResultAddresses(); + const std::set allAddresses = calcSumCase->summaryReader()->allResultAddresses(); for (const auto& adr : allAddresses) { addressSet.insert(adr); @@ -491,9 +534,35 @@ std::set RiuSummaryCurveDefSelection::findPossibleSumm //-------------------------------------------------------------------------------------------------- void RiuSummaryCurveDefSelection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) { - if (m_toggleChangedHandler != nullptr) + if (changedField != &m_selectedSources && changedField != &m_selectedSummaryCategories && + changedField != &m_currentSummaryCategory) + { + RifEclipseSummaryAddress::SummaryVarCategory currentCategory = m_currentSummaryCategory(); + if (currentCategory != RifEclipseSummaryAddress::SUMMARY_INVALID) + { + // When a summary vector is selected, make sure the summary category for the summary vector is in the selection + // Note that we use the size of the variant to avoid this operation when an item in unchecked + + if (newValue.toList().size() > oldValue.toList().size()) + { + if (std::find(m_selectedSummaryCategories.v().begin(), m_selectedSummaryCategories.v().end(), currentCategory) == + m_selectedSummaryCategories.v().end()) + { + m_selectedSummaryCategories.v().push_back(currentCategory); + } + } + } + } + + size_t curveCount = allCurveDefinitionsFromSelection().size(); + size_t curveSetCount = allCurveSetDefinitionsFromSelections().size(); + + if (m_toggleChangedHandler != nullptr && (curveCount != m_prevCurveCount || curveSetCount != m_prevCurveSetCount)) { m_toggleChangedHandler(); + + m_prevCurveCount = curveCount; + m_prevCurveSetCount = curveSetCount; } } @@ -583,6 +652,8 @@ QList RiuSummaryCurveDefSelection::calculateValueOptions { for (size_t i = 0; i < caf::AppEnum::size(); ++i) { + if (caf::AppEnum::fromIndex(i) == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS) continue; + options.push_back(caf::PdmOptionItemInfo(caf::AppEnum::uiTextFromIndex(i), caf::AppEnum::fromIndex(i))); } @@ -607,6 +678,8 @@ QList RiuSummaryCurveDefSelection::calculateValueOptions { for (const auto& address : addrUnion[i]) { + if (address.isErrorResult()) continue; + auto name = address.uiText(identifierAndField->summaryIdentifier()); if (name.size() > 0) { @@ -624,7 +697,6 @@ QList RiuSummaryCurveDefSelection::calculateValueOptions itemNames[OBS_DATA].clear(); } - auto pdmField = identifierAndField->pdmField(); for(int i = 0; i < itemCount; i++) { // Create headers only for vector fields when observed data is selected @@ -653,13 +725,40 @@ QList RiuSummaryCurveDefSelection::calculateValueOptions } auto itemPostfix = (isVectorField && i == OBS_DATA) ? QString(OBSERVED_DATA_AVALUE_POSTFIX) : QString(""); - for (const auto& itemName : itemNames[i]) + + // Sort numeric identifiers by numeric val + std::vector itemNamesVector; + { + switch (identifierAndField->summaryIdentifier()) + { + case RifEclipseSummaryAddress::INPUT_REGION_NUMBER: + case RifEclipseSummaryAddress::INPUT_SEGMENT_NUMBER: + case RifEclipseSummaryAddress::INPUT_AQUIFER_NUMBER: + { + std::set values; + for (const std::string& itemName : itemNames[i]) + { + values.insert(RiaStdStringTools::toInt(itemName)); + } + for (int v : values) + { + itemNamesVector.push_back(std::to_string(v)); + } + break; + } + default: + itemNamesVector.insert(itemNamesVector.end(), itemNames[i].begin(), itemNames[i].end()); + break; + } + } + + for (const auto& itemName : itemNamesVector) { QString displayName; if (isVectorField) { - std::string longVectorName = RiuSummaryVectorDescriptionMap::instance()->fieldInfo(itemName); + std::string longVectorName = RiuSummaryVectorDescriptionMap::instance()->vectorLongName(itemName, true); displayName = QString::fromStdString(longVectorName); displayName += QString(" (%1)").arg(QString::fromStdString(itemName)); } @@ -839,7 +938,7 @@ void RiuSummaryCurveDefSelection::defineUiOrdering(QString uiConfigName, caf::Pd //-------------------------------------------------------------------------------------------------- std::set RiuSummaryCurveDefSelection::findPossibleSummaryAddressesFromSelectedCases(const SummaryIdentifierAndField *identifierAndField) { - std::vector cases; + std::vector sources; for (const auto& source : m_selectedSources()) { RimSummaryCase* sumCase = dynamic_cast(source.p()); @@ -847,15 +946,14 @@ std::set RiuSummaryCurveDefSelection::findPossibleSumm if (sumCase) { - if(!isObservedData(sumCase)) cases.push_back(sumCase); + if(!isObservedData(sumCase)) sources.push_back(sumCase); } else if (ensemble) { - const auto& ensembleCases = ensemble->allSummaryCases(); - cases.insert(cases.end(), ensembleCases.begin(), ensembleCases.end()); + sources.push_back(ensemble); } } - return findPossibleSummaryAddresses(cases, identifierAndField); + return findPossibleSummaryAddresses(sources, identifierAndField); } //-------------------------------------------------------------------------------------------------- @@ -863,7 +961,7 @@ std::set RiuSummaryCurveDefSelection::findPossibleSumm //-------------------------------------------------------------------------------------------------- std::set RiuSummaryCurveDefSelection::findPossibleSummaryAddressesFromSelectedObservedData(const SummaryIdentifierAndField *identifierAndField) { - std::vector obsData; + std::vector obsData; for (const auto& source : m_selectedSources()) { RimSummaryCase* sumCase = dynamic_cast(source.p()); @@ -879,7 +977,7 @@ std::set RiuSummaryCurveDefSelection::findPossibleSumm //-------------------------------------------------------------------------------------------------- /// Returns the summary addresses that match the selected item type and input selections made in GUI //-------------------------------------------------------------------------------------------------- -std::set RiuSummaryCurveDefSelection::findPossibleSummaryAddresses(const std::vector &selectedCases, +std::set RiuSummaryCurveDefSelection::findPossibleSummaryAddresses(const std::vector &selectedSources, const SummaryIdentifierAndField *identifierAndField) { std::set addrUnion; @@ -891,32 +989,39 @@ std::set RiuSummaryCurveDefSelection::findPossibleSumm return addrUnion; } - for (RimSummaryCase* currCase : selectedCases) + for (SummarySource* currSource : selectedSources) { - RifSummaryReaderInterface* reader = nullptr; - if (currCase) reader = currCase->summaryReader(); - if (reader) + std::set allAddresses; + + RimSummaryCase* currCase = dynamic_cast(currSource); + RimSummaryCaseCollection* currEnsemble = dynamic_cast(currSource); + + if (currCase) + { + RifSummaryReaderInterface* reader = currCase->summaryReader(); + if (reader) allAddresses = reader->allResultAddresses(); + } + else if (currEnsemble) { - const std::vector& allAddresses = reader->allResultAddresses(); - int addressCount = static_cast(allAddresses.size()); + allAddresses = currEnsemble->ensembleSummaryAddresses(); + } - bool applySelections = identifierAndField == nullptr || (!isVectorField && controllingIdentifierAndField != nullptr); - std::vector controllingFields; - if (applySelections) - { - // Build selections vector - controllingFields = buildControllingFieldList(identifierAndField); - } + bool applySelections = identifierAndField == nullptr || (!isVectorField && controllingIdentifierAndField != nullptr); + std::vector controllingFields; + if (applySelections) + { + // Build selections vector + controllingFields = buildControllingFieldList(identifierAndField); + } - for (int i = 0; i < addressCount; i++) + for(auto& address : allAddresses) + { + if (address.category() == m_currentSummaryCategory()) { - if (allAddresses[i].category() == m_currentSummaryCategory()) + bool addressSelected = applySelections ? isAddressCompatibleWithControllingFieldSelection(address, controllingFields) : true; + if (addressSelected) { - bool addressSelected = applySelections ? isAddressCompatibleWithControllingFieldSelection(allAddresses[i], controllingFields) : true; - if (addressSelected) - { - addrUnion.insert(allAddresses[i]); - } + addrUnion.insert(address); } } } @@ -963,7 +1068,7 @@ SummaryIdentifierAndField* RiuSummaryCurveDefSelection::lookupIdentifierAndField //-------------------------------------------------------------------------------------------------- /// Returns the Controlling pdm field info for the specified pdm field info. /// Controlling means the field controlling the dependent field -/// If the specified pdm field info is the topmost (i.e. index is 0), null pointer is returned +/// If the specified pdm field info is the topmost (i.e. index is 0), nullptr is returned //-------------------------------------------------------------------------------------------------- SummaryIdentifierAndField* RiuSummaryCurveDefSelection::lookupControllingField(const SummaryIdentifierAndField *dependentField) const { @@ -1016,7 +1121,8 @@ std::set RiuSummaryCurveDefSelection::buildAddressList std::set addressSet; for (const auto& category : m_selectedSummaryCategories()) { - if (category == RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_INVALID) continue; + if (m_identifierFieldsMap.at(category).size() == 0 || + category == RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_INVALID) continue; const auto& identifierAndFieldList = m_identifierFieldsMap.at(category); std::vector> selectionStack; diff --git a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.h b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.h index 0c88bdbbc7..6e65150d77 100644 --- a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.h +++ b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelection.h @@ -37,6 +37,7 @@ class RimSummaryCaseCollection; class RimSummaryCurveAutoName; class RimSummaryPlot; class RiaSummaryCurveDefinition; +class RiaCurveSetDefinition; class SummaryIdentifierAndField; @@ -53,10 +54,11 @@ class RiuSummaryCurveDefSelection : public caf::PdmObject public: RiuSummaryCurveDefSelection(); - virtual ~RiuSummaryCurveDefSelection(); + ~RiuSummaryCurveDefSelection() override; void setSelectedCurveDefinitions(const std::vector& curveDefinitions); std::vector allCurveDefinitionsFromSelection() const; + std::vector allCurveSetDefinitionsFromSelections() const; std::vector selection() const; void setMultiSelectionMode(bool multiSelectionMode); @@ -64,19 +66,19 @@ class RiuSummaryCurveDefSelection : public caf::PdmObject void hideSummaryCases(bool hide); void setFieldChangedHandler(const std::function& handlerFunc); - void setDefaultSelection(const std::vector& defaultCases); + void setDefaultSelection(const std::vector& defaultCases); private: - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, - const QVariant& newValue); - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly); - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, + const QVariant& newValue) override; + QList 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; - std::set findPossibleSummaryAddresses(const std::vector &selectedCases, + std::set findPossibleSummaryAddresses(const std::vector &selectedSources, const SummaryIdentifierAndField *identifierAndField); std::set findPossibleSummaryAddressesFromSelectedCases(const SummaryIdentifierAndField *identifierAndField); std::set findPossibleSummaryAddressesFromSelectedObservedData(const SummaryIdentifierAndField *identifierAndField); @@ -114,4 +116,7 @@ class RiuSummaryCurveDefSelection : public caf::PdmObject bool m_hideSummaryCases; std::function m_toggleChangedHandler; + + size_t m_prevCurveCount; + size_t m_prevCurveSetCount; }; diff --git a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionDialog.h b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionDialog.h index f8784337fc..1ee62f6472 100644 --- a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionDialog.h +++ b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionDialog.h @@ -37,7 +37,7 @@ class RiuSummaryCurveDefSelectionDialog : public QDialog { public: RiuSummaryCurveDefSelectionDialog(QWidget* parent); - ~RiuSummaryCurveDefSelectionDialog(); + ~RiuSummaryCurveDefSelectionDialog() override; void setCaseAndAddress(RimSummaryCase* summaryCase, const RifEclipseSummaryAddress& address); void setEnsembleAndAddress(RimSummaryCaseCollection* ensemble, const RifEclipseSummaryAddress& address); diff --git a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionEditor.cpp b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionEditor.cpp index 9e9099412a..b165e19bdf 100644 --- a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionEditor.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionEditor.cpp @@ -59,10 +59,12 @@ RiuSummaryCurveDefSelection* RiuSummaryCurveDefSelectionEditor::summaryAddressSe //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuSummaryCurveDefSelectionEditor::recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, const QString& uiConfigName) +void RiuSummaryCurveDefSelectionEditor::recursivelyConfigureAndUpdateTopLevelUiOrdering(const caf::PdmUiOrdering& topLevelUiOrdering, const QString& uiConfigName) { if (!m_firstRowLeftLayout || !m_firstRowRightLayout) return; + const std::vector& topLevelUiItems = topLevelUiOrdering.uiItems(); + for (size_t i = 0; i < topLevelUiItems.size(); ++i) { if (topLevelUiItems[i]->isUiHidden(uiConfigName)) continue; @@ -158,7 +160,7 @@ void RiuSummaryCurveDefSelectionEditor::configureAndUpdateFields(int widgetStart if (fieldEditor) { - fieldEditor->setField(field); + fieldEditor->setUiField(field); // Place the widget(s) into the correct parent and layout QWidget* fieldCombinedWidget = fieldEditor->combinedWidget(); @@ -214,7 +216,6 @@ QMinimizePanel* RiuSummaryCurveDefSelectionEditor::createGroupBoxWithContent(caf { QMinimizePanel* groupBox = findOrCreateGroupBox(this->widget(), group, uiConfigName); - const std::vector& groupChildren = group->uiItems(); - recursivelyConfigureAndUpdateUiItemsInGridLayoutColumn(groupChildren, groupBox->contentFrame(), uiConfigName); + recursivelyConfigureAndUpdateUiOrderingInGridLayoutColumn(*group, groupBox->contentFrame(), uiConfigName); return groupBox; } diff --git a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionEditor.h b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionEditor.h index 281fec6f37..2339eea6dd 100644 --- a/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionEditor.h +++ b/ApplicationCode/UserInterface/RiuSummaryCurveDefSelectionEditor.h @@ -18,7 +18,7 @@ #pragma once -#include "cafPdmUiWidgetBasedObjectEditor.h" +#include "cafPdmUiFormLayoutObjectEditor.h" #include #include @@ -43,19 +43,19 @@ namespace caf { /// /// //================================================================================================== -class RiuSummaryCurveDefSelectionEditor : public caf::PdmUiWidgetBasedObjectEditor +class RiuSummaryCurveDefSelectionEditor : public caf::PdmUiFormLayoutObjectEditor { public: RiuSummaryCurveDefSelectionEditor(); - ~RiuSummaryCurveDefSelectionEditor(); + ~RiuSummaryCurveDefSelectionEditor() override; RiuSummaryCurveDefSelection* summaryAddressSelection() const; private: - virtual void recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, - const QString& uiConfigName) override; + void recursivelyConfigureAndUpdateTopLevelUiOrdering(const caf::PdmUiOrdering& topLevelUiOrdering, + const QString& uiConfigName) override; - virtual QWidget* createWidget(QWidget* parent) override; + QWidget* createWidget(QWidget* parent) override; void configureAndUpdateFields(int widgetStartIndex, QBoxLayout* layout, diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp index f9f3ccb412..547f8936f3 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.cpp @@ -75,7 +75,7 @@ class EnsembleCurveInfoTextProvider : public IPlotCurveInfoTextProvider //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual QString curveInfoText(QwtPlotCurve* curve) override + QString curveInfoText(QwtPlotCurve* curve) override { RiuRimQwtPlotCurve* riuCurve = dynamic_cast(curve); RimSummaryCurve* sumCurve = nullptr; @@ -165,36 +165,6 @@ void RiuSummaryQwtPlot::currentVisibleWindow(QwtInterval* leftAxis, QwtInterval* *timeAxis = axisScaleDiv(xBottom).interval(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuSummaryQwtPlot::setZoomWindow(const QwtInterval& leftAxis, const QwtInterval& rightAxis, const QwtInterval& timeAxis) -{ - { - QRectF zoomWindow; - zoomWindow.setLeft(timeAxis.minValue()); - zoomWindow.setRight(timeAxis.maxValue()); - zoomWindow.setTop(leftAxis.maxValue()); - zoomWindow.setBottom(leftAxis.minValue()); - - m_zoomerLeft->blockSignals(true); - m_zoomerLeft->zoom(zoomWindow); - m_zoomerLeft->blockSignals(false); - } - - { - QRectF zoomWindow; - zoomWindow.setLeft(timeAxis.minValue()); - zoomWindow.setRight(timeAxis.maxValue()); - zoomWindow.setTop(rightAxis.maxValue()); - zoomWindow.setBottom(rightAxis.minValue()); - - // No need to block signal since there is no connected slot - m_zoomerRight->zoom(zoomWindow); - } - -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -399,8 +369,13 @@ void RiuSummaryQwtPlot::setCommonPlotBehaviour(QwtPlot* plot) plot->setAxisTitle(QwtPlot::yLeft, axisTitle); plot->setAxisTitle(QwtPlot::yRight, axisTitle); - // Enable mousetracking and event filter + // Set a focus policy to allow it taking key press events. + // This is not strictly necessary since this widget inherit QwtPlot + // which already has a focus policy. + // However, for completeness we still do it here. + plot->setFocusPolicy(Qt::WheelFocus); + // Enable mousetracking and event filter plot->canvas()->setMouseTracking(true); plot->canvas()->installEventFilter(plot); plot->plotLayout()->setAlignCanvasToScales(true); @@ -491,23 +466,26 @@ void RiuSummaryQwtPlot::selectClosestCurve(const QPoint& pos) } } - if(closestCurve && distMin < 20) + if (closestCurve && distMin < 20) { caf::PdmObject* selectedPlotObject = m_plotDefinition->findRimPlotObjectFromQwtCurve(closestCurve); - - RimProject* proj = nullptr; - selectedPlotObject->firstAncestorOrThisOfType(proj); - if(proj && selectedPlotObject) + if (selectedPlotObject) { - RiuPlotMainWindowTools::showPlotMainWindow(); - RiuPlotMainWindowTools::selectAsCurrentItem(selectedPlotObject); + RimProject* proj = nullptr; + selectedPlotObject->firstAncestorOrThisOfType(proj); + + if (proj) + { + RiuPlotMainWindowTools::showPlotMainWindow(); + RiuPlotMainWindowTools::selectAsCurrentItem(selectedPlotObject); + } } } } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void RiuSummaryQwtPlot::onZoomedSlot() { diff --git a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h index a166206284..c031338ce0 100644 --- a/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h +++ b/ApplicationCode/UserInterface/RiuSummaryQwtPlot.h @@ -49,10 +49,10 @@ class RiuSummaryQwtPlot : public QwtPlot, public RiuInterfaceToViewWindow Q_OBJECT; public: RiuSummaryQwtPlot(RimSummaryPlot* plotDefinition, QWidget* parent = nullptr); - virtual ~RiuSummaryQwtPlot(); + ~RiuSummaryQwtPlot() override; RimSummaryPlot* ownerPlotDefinition(); - virtual RimViewWindow* ownerViewWindow() const override; + RimViewWindow* ownerViewWindow() const override; void useDateBasedTimeAxis(); void useTimeBasedTimeAxis(); @@ -61,10 +61,6 @@ class RiuSummaryQwtPlot : public QwtPlot, public RiuInterfaceToViewWindow QwtInterval* rightAxis, QwtInterval* timeAxis) const; - void setZoomWindow(const QwtInterval& leftAxis, - const QwtInterval& rightAxis, - const QwtInterval& timeAxis); - void addOrUpdateEnsembleCurveSetLegend(RimEnsembleCurveSet * curveSetToShowLegendFor); void removeEnsembleCurveSetLegend(RimEnsembleCurveSet * curveSetToShowLegendFor); @@ -72,13 +68,13 @@ class RiuSummaryQwtPlot : public QwtPlot, public RiuInterfaceToViewWindow static void enableDateBasedBottomXAxis(QwtPlot* plot); protected: - virtual bool eventFilter(QObject* watched, QEvent* event) override; - virtual void keyPressEvent(QKeyEvent *) override; + bool eventFilter(QObject* watched, QEvent* event) override; + void keyPressEvent(QKeyEvent *) override; - virtual QSize sizeHint() const override; - virtual QSize minimumSizeHint() const override; - virtual void contextMenuEvent(QContextMenuEvent *) override; - virtual void updateLayout() override; + QSize sizeHint() const override; + QSize minimumSizeHint() const override; + void contextMenuEvent(QContextMenuEvent *) override; + void updateLayout() override; private: void setDefaults(); diff --git a/ApplicationCode/UserInterface/RiuSummaryVectorDescriptionMap.cpp b/ApplicationCode/UserInterface/RiuSummaryVectorDescriptionMap.cpp index 690f436773..edd2ed2f67 100644 --- a/ApplicationCode/UserInterface/RiuSummaryVectorDescriptionMap.cpp +++ b/ApplicationCode/UserInterface/RiuSummaryVectorDescriptionMap.cpp @@ -31,16 +31,18 @@ RiuSummaryVectorDescriptionMap* RiuSummaryVectorDescriptionMap::instance() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::string RiuSummaryVectorDescriptionMap::fieldInfo(const std::string &vectorName) +RiuSummaryVectorInfo RiuSummaryVectorDescriptionMap::vectorInfo(const std::string& vectorName) { - std::map::iterator it = m_summaryToDescMap.find(vectorName); - + std::map::iterator it = m_summaryToDescMap.find(vectorName); + if (it != m_summaryToDescMap.end()) { return it->second; } - else if (vectorName.size() > 1) + else if (vectorName.size() > 1 && vectorName[1] == 'U') { + // User defined vector name + std::string key = vectorName.substr(0, 2); it = m_summaryToDescMap.find(key); @@ -50,8 +52,33 @@ std::string RiuSummaryVectorDescriptionMap::fieldInfo(const std::string &vectorN return it->second; } } + else if (vectorName.size() > 5) + { + // Check for custom vector naming + + std::string baseName = vectorName.substr(0, 5); + while (baseName.back() == '_') baseName.pop_back(); + + it = m_summaryToDescMap.find(baseName); + + if (it != m_summaryToDescMap.end()) + { + return it->second; + } + } - return vectorName; + return RiuSummaryVectorInfo(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::string RiuSummaryVectorDescriptionMap::vectorLongName(const std::string& vectorName, + bool returnVectorNameIfNotFound) +{ + auto info = vectorInfo(vectorName); + return info.category != RifEclipseSummaryAddress::SUMMARY_INVALID || !returnVectorNameIfNotFound + ? info.longName : vectorName; } //-------------------------------------------------------------------------------------------------- @@ -67,1784 +94,1808 @@ RiuSummaryVectorDescriptionMap::RiuSummaryVectorDescriptionMap() //-------------------------------------------------------------------------------------------------- void RiuSummaryVectorDescriptionMap::populateFieldToInfoMap() { + using A = RifEclipseSummaryAddress; + m_summaryToDescMap = { - { "FOPR", "Oil Production Rate" }, - { "FOPRA", "Oil Production Rate above GOC" }, - { "FOPRB", "Oil Production Rate below GOC" }, - { "FOPTA", "Oil Production Total above GOC" }, - { "FOPTB", "Oil Production Total below GOC" }, - { "FOPR1", "Oil Production Rate above GOC" }, - { "FOPR2", "Oil Production Rate below GOC" }, - { "FOPT1", "Oil Production Total above GOC" }, - { "FOPT2", "Oil Production Total below GOC" }, - { "FOMR", "Oil Mass Rate" }, - { "FOMT", "Oil Mass Total" }, - { "FODN", "Oil Density at Surface Conditions" }, - { "FOPRH", "Oil Production Rate History" }, - { "FOPRT", "Oil Production Rate Target/Limit" }, - { "FOPRF", "Free Oil Production Rate" }, - { "FOPRS", "Solution Oil Production Rate" }, - { "FOPT", "Oil Production Total" }, - { "FOPTH", "Oil Production Total History" }, - { "FOPTF", "Free Oil Production Total" }, - { "FOPTS", "Solution Oil Production Total" }, - { "FOIR", "Oil Injection Rate" }, - { "FOIRH", "Oil Injection Rate History" }, - { "FOIRT", "Oil Injection Rate Target/Limit" }, - { "FOIT", "Oil Injection Total" }, - { "FOITH", "Oil Injection Total History" }, - { "FOPP", "Oil Potential Production rate" }, - { "FOPP2", "Oil Potential Production rate" }, - { "FOPI", "Oil Potential Injection rate" }, - { "FOPI2", "Oil Potential Injection rate" }, - { "FOVPR", "Oil Voidage Production Rate" }, - { "FOVPT", "Oil Voidage Production Total" }, - { "FOVIR", "Oil Voidage Injection Rate" }, - { "FOVIT", "Oil Voidage Injection Total" }, - { "FOnPR", "nth separator stage oil rate" }, - { "FOnPT", "nth separator stage oil total" }, - { "FEOR", "Export Oil Rate" }, - { "FEOT", "Export Oil Total" }, - { "FEOMF", "Export Oil Mole Fraction" }, - { "FWPR", "Water Production Rate" }, - { "FWMR", "Water Mass Rate" }, - { "FWMT", "Water Mass Total" }, - { "FWPRH", "Water Production Rate History" }, - { "FWPRT", "Water Production Rate Target/Limit" }, - { "FWPT", "Water Production Total" }, - { "FWPTH", "Water Production Total History" }, - { "FWIR", "Water Injection Rate" }, - { "FWIRH", "Water Injection Rate History" }, - { "FWIRT", "Water Injection Rate Target/Limit" }, - { "FWIT", "Water Injection Total" }, - { "FWITH", "Water Injection Total History" }, - { "FWPP", "Water Potential Production rate" }, - { "FWPP2", "Water Potential Production rate" }, - { "FWPI", "Water Potential Injection rate" }, - { "FWPI2", "Water Potential Injection rate" }, - { "FWVPR", "Water Voidage Production Rate" }, - { "FWVPT", "Water Voidage Production Total" }, - { "FWVIR", "Water Voidage Injection Rate" }, - { "FWVIT", "Water Voidage Injection Total" }, - { "FWPIR", "Ratio of produced water to injected water (percentage)" }, - { "FWMPR", "Water component molar production rate" }, - { "FWMPT", "Water component molar production total" }, - { "FWMIR", "Water component molar injection rate" }, - { "FWMIT", "Water component molar injection total" }, - { "FGPR", "Gas Production Rate" }, - { "FGPRA", "Gas Production Rate above" }, - { "FGPRB", "Gas Production Rate below" }, - { "FGPTA", "Gas Production Total above" }, - { "FGPTB", "Gas Production Total below" }, - { "FGPR1", "Gas Production Rate above GOC" }, - { "FGPR2", "Gas Production Rate below GOC" }, - { "FGPT1", "Gas Production Total above GOC" }, - { "FGPT2", "Gas Production Total below GOC" }, - { "FGMR", "Gas Mass Rate" }, - { "FGMT", "Gas Mass Total" }, - { "FGDN", "Gas Density at Surface Conditions" }, - { "FGPRH", "Gas Production Rate History" }, - { "FGPRT", "Gas Production Rate Target/Limit" }, - { "FGPRF", "Free Gas Production Rate" }, - { "FGPRS", "Solution Gas Production Rate" }, - { "FGPT", "Gas Production Total" }, - { "FGPTH", "Gas Production Total History" }, - { "FGPTF", "Free Gas Production Total" }, - { "FGPTS", "Solution Gas Production Total" }, - { "FGIR", "Gas Injection Rate" }, - { "FGIRH", "Gas Injection Rate History" }, - { "FGIRT", "Gas Injection Rate Target/Limit" }, - { "FGIT", "Gas Injection Total" }, - { "FGITH", "Gas Injection Total History" }, - { "FGPP", "Gas Potential Production rate" }, - { "FGPP2", "Gas Potential Production rate" }, - { "FGPPS", "Solution" }, - { "FGPPS2", "Solution" }, - { "FGPPF", "Free Gas Potential Production rate" }, - { "FGPPF2", "Free Gas Potential Production rate" }, - { "FGPI", "Gas Potential Injection rate" }, - { "FGPI2", "Gas Potential Injection rate" }, - { "FSGR", "Sales Gas Rate" }, - { "FGSR", "Sales Gas Rate" }, - { "FSGT", "Sales Gas Total" }, - { "FGST", "Sales Gas Total" }, - { "FSMF", "Sales Gas Mole Fraction" }, - { "FFGR", "Fuel Gas Rate, at and below this group" }, - { "FFGT", "Fuel Gas cumulative Total, at and below this group" }, - { "FFMF", "Fuel Gas Mole Fraction" }, - { "FGCR", "Gas Consumption Rate, at and below this group" }, - { "FGCT", "Gas Consumption Total, at and below this group" }, - { "FGIMR", "Gas Import Rate, at and below this group" }, - { "FGIMT", "Gas Import Total, at and below this group" }, - { "FGLIR", "Gas Lift Injection Rate" }, - { "FWGPR", "Wet Gas Production Rate" }, - { "FWGPT", "Wet Gas Production Total" }, - { "FWGPRH", "Wet Gas Production Rate History" }, - { "FWGIR", "Wet Gas Injection Rate" }, - { "FWGIT", "Wet Gas Injection Total" }, - { "FEGR", "Export Gas Rate" }, - { "FEGT", "Export Gas Total" }, - { "FEMF", "Export Gas Mole Fraction" }, - { "FEXGR", "Excess Gas Rate" }, - { "FEXGT", "Excess Gas Total" }, - { "FRGR", "Re-injection Gas Rate" }, - { "FRGT", "Re-injection Gas Total" }, - { "FGnPR", "nth separator stage gas rate" }, - { "FGnPT", "nth separator stage gas total" }, - { "FGVPR", "Gas Voidage Production Rate" }, - { "FGVPT", "Gas Voidage Production Total" }, - { "FGVIR", "Gas Voidage Injection Rate" }, - { "FGVIT", "Gas Voidage Injection Total" }, - { "FGQ", "Gas Quality" }, - { "FLPR", "Liquid Production Rate" }, - { "FLPRH", "Liquid Production Rate History" }, - { "FLPRT", "Liquid Production Rate Target/Limit" }, - { "FLPT", "Liquid Production Total" }, - { "FLPTH", "Liquid Production Total History" }, - { "FVPR", "Res Volume Production Rate" }, - { "FVPRT", "Res Volume Production Rate Target/Limit" }, - { "FVPT", "Res Volume Production Total" }, - { "FVIR", "Res Volume Injection Rate" }, - { "FVIRT", "Res Volume Injection Rate Target/Limit" }, - { "FVIT", "Res Volume Injection Total" }, - { "FWCT", "Water Cut" }, - { "FWCTH", "Water Cut History" }, - { "FGOR", "Gas-Oil Ratio" }, - { "FGORH", "Gas-Oil Ratio History" }, - { "FOGR", "Oil-Gas Ratio" }, - { "FOGRH", "Oil-Gas Ratio History" }, - { "FWGR", "Water-Gas Ratio" }, - { "FWGRH", "Water-Gas Ratio History" }, - { "FGLR", "Gas-Liquid Ratio" }, - { "FGLRH", "Gas-Liquid Ratio History" }, - { "FMCTP", "Mode of Control for group Production" }, - { "FMCTW", "Mode of Control for group Water Injection" }, - { "FMCTG", "Mode of Control for group Gas Injection" }, - { "FMWPT", "Total number of production wells" }, - { "FMWPR", "Number of production wells currently flowing" }, - { "FMWPA", "Number of abandoned production wells" }, - { "FMWPU", "Number of unused production wells" }, - { "FMWPG", "Number of producers on group control" }, - { "FMWPO", "Number of producers controlled by own oil rate limit" }, - { "FMWPS", "Number of producers on own surface rate limit control" }, - { "FMWPV", "Number of producers on own reservoir volume rate limit control" }, - { "FMWPP", "Number of producers on pressure control" }, - { "FMWPL", "Number of producers using artificial lift" }, - { "FMWIT", "Total number of injection wells" }, - { "FMWIN", "Number of injection wells currently flowing" }, - { "FMWIA", "Number of abandoned injection wells" }, - { "FMWIU", "Number of unused injection wells" }, - { "FMWIG", "Number of injectors on group control" }, - { "FMWIS", "Number of injectors on own surface rate limit control" }, - { "FMWIV", "Number of injectors on own reservoir volume rate limit control" }, - { "FMWIP", "Number of injectors on pressure control" }, - { "FMWDR", "Number of drilling events this timestep" }, - { "FMWDT", "Number of drilling events in total" }, - { "FMWWO", "Number of workover events this timestep" }, - { "FMWWT", "Number of workover events in total" }, - { "FEPR", "Energy Production Rate" }, - { "FEPT", "Energy Production Total" }, - { "FNLPR", "NGL Production Rate" }, - { "FNLPT", "NGL Production Total" }, - { "FNLPRH", "NGL Production Rate History" }, - { "FNLPTH", "NGL Production Total History" }, - { "FAMF", "Component aqueous mole fraction, from producing completions" }, - { "FXMF", "Liquid Mole Fraction" }, - { "FYMF", "Vapor Mole Fraction" }, - { "FXMFn", "Liquid Mole Fraction for nth separator stage" }, - { "FYMFn", "Vapor Mole Fraction for nth separator stage" }, - { "FZMF", "Total Mole Fraction" }, - { "FCMPR", "Hydrocarbon Component Molar Production Rates" }, - { "FCMPT", "Hydrocarbon Component" }, - { "FCMIR", "Hydrocarbon Component Molar Injection Rates" }, - { "FCMIT", "Hydrocarbon Component Molar Injection Totals" }, - { "FHMIR", "Hydrocarbon Molar Injection Rate" }, - { "FHMIT", "Hydrocarbon Molar Injection Total" }, - { "FHMPR", "Hydrocarbon Molar Production Rate" }, - { "FHMPT", "Hydrocarbon Molar Production Total" }, - { "FCHMR", "Hydrocarbon Component" }, - { "FCHMT", "Hydrocarbon Component" }, - { "FCWGPR", "Hydrocarbon Component Wet Gas Production Rate" }, - { "FCWGPT", "Hydrocarbon Component Wet Gas Production Total" }, - { "FCWGIR", "Hydrocarbon Component Wet Gas Injection Rate" }, - { "FCWGIT", "Hydrocarbon Component Wet Gas Injection Total" }, - { "FCGMR", "Hydrocarbon component" }, - { "FCGMT", "Hydrocarbon component" }, - { "FCOMR", "Hydrocarbon component" }, - { "FCOMT", "Hydrocarbon component" }, - { "FCNMR", "Hydrocarbon component molar rates in the NGL phase" }, - { "FCNWR", "Hydrocarbon component mass rates in the NGL phase" }, - { "FCGMRn", "Hydrocarbon component molar rates in the gas phase for nth separator stage" }, - { "FCGRn", "Hydrocarbon component molar rates in the gas phase for nth separator stage" }, - { "FCOMRn", "Hydrocarbon component" }, - { "FCORn", "Hydrocarbon component" }, - { "FMUF", "Make-up fraction" }, - { "FAMR", "Make-up gas rate" }, - { "FAMT", "Make-up gas total" }, - { "FGSPR", "Target sustainable rate for most recent sustainable capacity test for gas" }, - { "FGSRL", "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for gas" }, - { "FGSRU", "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for gas" }, - { "FGSSP", "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for gas" }, - { "FGSTP", "Test period for the most recent sustainable capacity test for gas" }, - { "FOSPR", "Target sustainable rate for most recent sustainable capacity test for oil" }, - { "FOSRL", "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for oil" }, - { "FOSRU", "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for oil" }, - { "FOSSP", "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for oil" }, - { "FOSTP", "Test period for the most recent sustainable capacity test for oil" }, - { "FWSPR", "Target sustainable rate for most recent sustainable capacity test for water" }, - { "FWSRL", "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for water" }, - { "FWSRU", "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for water" }, - { "FWSSP", "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for water" }, - { "FWSTP", "Test period for the most recent sustainable capacity test for water" }, - { "FGPRG", "Gas production rate" }, - { "FOPRG", "Oil production rate" }, - { "FNLPRG", "NGL production rate" }, - { "FXMFG", "Liquid mole fraction" }, - { "FYMFG", "Vapor mole fraction" }, - { "FCOMRG", "Hydrocarbon component" }, - { "FCGMRG", "Hydrocarbon component molar rates in the gas phase" }, - { "FCNMRG", "Hydrocarbon component molar rates in the NGL phase" }, - { "FPR", "Pressure average value" }, - { "FPRH", "Pressure average value" }, - { "FPRP", "Pressure average value" }, - { "FPRGZ", "P/Z" }, - { "FRS", "Gas-oil ratio" }, - { "FRV", "Oil-gas ratio" }, - { "FCHIP", "Component Hydrocarbon as Wet Gas" }, - { "FCMIP", "Component Hydrocarbon as Moles" }, - { "FPPC", "Initial Contact Corrected Potential" }, - { "FREAC", "Reaction rate. The reaction number is given as a component index" }, - { "FREAT", "Reaction total. The reaction number is given as a component index" }, - { "FRPV", "Pore Volume at Reservoir conditions" }, - { "FOPV", "Pore Volume containing Oil" }, - { "FWPV", "Pore Volume containing Water" }, - { "FGPV", "Pore Volume containing Gas" }, - { "FHPV", "Pore Volume containing Hydrocarbon" }, - { "FRTM", "Transmissibility Multiplier associated with rock compaction" }, - { "FOE", "(OIP(initial - OIP(now) / OIP(initial)" }, - { "FOEW", "Oil Production from Wells / OIP(initial)" }, - { "FOEIW", "(OIP(initial - OIP(now) / Initial Mobile Oil with respect to Water" }, - { "FOEWW", "Oil Production from Wells / Initial Mobile Oil with respect to Water" }, - { "FOEIG", "(OIP(initial - OIP(now) / Initial Mobile Oil with respect to Gas" }, - { "FOEWG", "Oil Production from Wells / Initial Mobile Oil with respect to Gas" }, - { "FORMR", "Total stock tank oil produced by rock compaction" }, - { "FORMW", "Total stock tank oil produced by water influx" }, - { "FORMG", "Total stock tank oil produced by gas influx" }, - { "FORME", "Total stock tank oil produced by oil expansion" }, - { "FORMS", "Total stock tank oil produced by solution gas" }, - { "FORMF", "Total stock tank oil produced by free gas influx" }, - { "FORMX", "Total stock tank oil produced by 'traced' water influx" }, - { "FORMY", "Total stock tank oil produced by other water influx" }, - { "FORFR", "Fraction of total oil produced by rock compaction" }, - { "FORFW", "Fraction of total oil produced by water influx" }, - { "FORFG", "Fraction of total oil produced by gas influx" }, - { "FORFE", "Fraction of total oil produced by oil expansion" }, - { "FORFS", "Fraction of total oil produced by solution gas" }, - { "FORFF", "Fraction of total oil produced by free gas influx" }, - { "FORFX", "Fraction of total oil produced by 'traced' water influx" }, - { "FORFY", "Fraction of total oil produced by other water influx" }, - { "FAQR", "Aquifer influx rate" }, - { "FAQT", "Cumulative aquifer influx" }, - { "FAQRG", "Aquifer influx rate" }, - { "FAQTG", "Cumulative aquifer influx" }, - { "FAQER", "Aquifer thermal energy influx rate" }, - { "FAQET", "Cumulative aquifer thermal energy influx" }, - { "FNQR", "Aquifer influx rate" }, - { "FNQT", "Cumulative aquifer influx" }, - { "FTPR", "Tracer Production Rate" }, - { "FTPT", "Tracer Production Total" }, - { "FTPC", "Tracer Production Concentration" }, - { "FTIR", "Tracer Injection Rate" }, - { "FTIT", "Tracer Injection Total" }, - { "FTIC", "Tracer Injection Concentration" }, - { "FTMR", "Traced mass Rate" }, - { "FTMT", "Traced mass Total" }, - { "FTQR", "Traced molar Rate" }, - { "FTCM", "Tracer Carrier molar Rate" }, - { "FTMF", "Traced molar fraction" }, - { "FTVL", "Traced liquid volume rate" }, - { "FTVV", "Traced vapor volume rate" }, - { "FTTL", "Traced liquid volume total" }, - { "FTTV", "Traced vapor volume total" }, - { "FTML", "Traced mass liquid rate" }, - { "FTMV", "Traced mass vapor rate" }, - { "FTLM", "Traced mass liquid total" }, - { "FTVM", "Traced mass vapor total" }, - { "FTIPT", "Tracer In Place" }, - { "FTIPF", "Tracer In Place" }, - { "FTIPS", "Tracer In Place" }, - { "FAPI", "Oil API" }, - { "FSPR", "Salt Production Rate" }, - { "FSPT", "Salt Production Total" }, - { "FSIR", "Salt Injection Rate" }, - { "FSIT", "Salt Injection Total" }, - { "FSPC", "Salt Production Concentration" }, - { "FSIC", "Salt Injection Concentration" }, - { "FSIP", "Salt In Place" }, - { "GTPRANI", "Anion Production Rate" }, - { "GTPTANI", "Anion Production Total" }, - { "GTIRANI", "Anion Injection Rate" }, - { "GTITANI", "Anion Injection Total" }, - { "GTPRCAT", "Cation Production Rate" }, - { "GTPTCAT", "Cation Production Total" }, - { "GTIRCAT", "Cation Injection Rate" }, - { "GTITCAT", "Cation Injection Total" }, - { "FTPCHEA", "Production Temperature" }, - { "FTICHEA", "Injection Temperature" }, - { "FTPRHEA", "Energy flows" }, - { "FTPTHEA", "Energy Production Total" }, - { "FTIRHEA", "Energy flows" }, - { "FTITHEA", "Energy Injection Total" }, - { "FTIPTHEA", "Difference in Energy in place between current and initial time" }, - { "FTPR", "Tracer Production Rate" }, - { "FTPT", "Tracer Production Total" }, - { "FTPC", "Tracer Production Concentration" }, - { "FTIR", "Tracer Injection Rate" }, - { "FTIT", "Tracer Injection Total" }, - { "FTIC", "Tracer Injection Concentration" }, - { "FTIPT", "Tracer In Place" }, - { "FTIPF", "Tracer In Place" }, - { "FTIPS", "Tracer In Place" }, - { "FTIP#", " Tracer In Place in phase # (1,2,3,...)" }, - { "FTADS", "Tracer Adsorption total" }, - { "FTDCY", "Decayed tracer" }, - { "FTIRF", "Tracer Injection Rate" }, - { "FTIRS", "Tracer Injection Rate" }, - { "FTPRF", "Tracer Production Rate" }, - { "FTPRS", "Tracer Production Rate" }, - { "FTITF", "Tracer Injection Total" }, - { "FTITS", "Tracer Injection Total" }, - { "FTPTF", "Tracer Production Total" }, - { "FTPTS", "Tracer Production Total" }, - { "FTICF", "Tracer Injection Concentration" }, - { "FTICS", "Tracer Injection Concentration" }, - { "FTPCF", "Tracer Production" }, - { "FTPCS", "Tracer Production" }, - { "FMPR", "Methane Production Rate" }, - { "FMPT", "Methane Production Total" }, - { "FMIR", "Methane Injection Rate" }, - { "FMIT", "Methane Injection Total" }, - { "FCGC", "Bulk Coal Gas Concentration" }, - { "FCSC", "Bulk Coal Solvent Concentration" }, - { "FTPRFOA", "Production Rate" }, - { "FTPTFOA", "Production Total" }, - { "FTIRFOA", "Injection Rate" }, - { "FTITFOA", "Injection Total" }, - { "FTIPTFOA", "In Solution" }, - { "FTADSFOA", "Adsorption total" }, - { "FTDCYFOA", "Decayed tracer" }, - { "FTMOBFOA", "Gas mobility factor" }, - { "FTPRFOA", "Production Rate" }, - { "FTPTFOA", "Production Total" }, - { "FTIRFOA", "Injection Rate" }, - { "FTITFOA", "Injection Total" }, - { "FTIPTFOA", "In Solution" }, - { "FTADSFOA", "Adsorption total" }, - { "FTDCYFOA", "Decayed tracer" }, - { "FTMOBFOA", "Gas mobility factor" }, - { "FSGR", "Sales Gas Rate" }, - { "FGSR", "Sales Gas Rate" }, - { "FSGT", "Sales Gas Total" }, - { "FGST", "Sales Gas Total" }, - { "FGDC", "Gas Delivery Capacity" }, - { "FGDCQ", "Field/Group Gas DCQ" }, - { "FGCR", "Gas consumption rate, at and below this group" }, - { "FGCT", "Gas consumption cumulative total, at and below this group" }, - { "FFGR", "Fuel Gas rate, at and below this group" }, - { "FFGT", "Fuel Gas cumulative total, at and below this group" }, - { "FGIMR", "Gas import rate, at and below this group" }, - { "FGIMT", "Gas import cumulative total, at and below this group" }, - { "FGLIR", "Gas Lift Injection Rate" }, - { "FGCV", "Gas Calorific Value" }, - { "FGQ", "Gas molar Quality" }, - { "FEPR", "Energy Production Rate" }, - { "FEPT", "Energy Production Total" }, - { "FESR", "Energy Sales Rate" }, - { "FEST", "Energy Sales Total" }, - { "FEDC", "Energy Delivery Capacity" }, - { "FEDCQ", "Energy DCQ" }, - { "FCPR", "Polymer Production Rate" }, - { "FCPC", "Polymer Production Concentration" }, - { "FCPT", "Polymer Production Total" }, - { "FCIR", "Polymer Injection Rate" }, - { "FCIC", "Polymer Injection Concentration" }, - { "FCIT", "Polymer Injection Total" }, - { "FCIP", "Polymer In Solution" }, - { "FCAD", "Polymer Adsorption total" }, - { "FSPR", "Salt Production Rate" }, - { "FSPT", "Salt Production Total" }, - { "FSIR", "Salt Injection Rate" }, - { "FSIT", "Salt Injection Total" }, - { "FSIP", "Salt In Place" }, - { "PSSPR", "Log of the pressure change per unit time" }, - { "PSSSO", "Log of the oil saturation change per unit time" }, - { "PSSSW", "Log of the water saturation change per unit time" }, - { "PSSSG", "Log of the gas saturation change per unit time" }, - { "PSSSC", "Log of the salt concentration change per unit time" }, - { "FNPR", "Solvent Production Rate" }, - { "FNPT", "Solvent Production Total" }, - { "FNIR", "Solvent Injection Rate" }, - { "FNIT", "Solvent Injection Total" }, - { "FNIP", "Solvent In Place" }, - { "FTPRSUR", "Production Rate" }, - { "FTPTSUR", "Production Total" }, - { "FTIRSUR", "Injection Rate" }, - { "FTITSUR", "Injection Total" }, - { "FTIPTSUR", "In Solution" }, - { "FTADSUR", "Adsorption total" }, - { "FTPRALK", "Production Rate" }, - { "FTPTALK", "Production Total" }, - { "FTIRALK", "Injection Rate" }, - { "FTITALK", "Injection Total" }, - { "FU", "User-defined field quantity" }, + { "FOPR", { A::SUMMARY_FIELD, "Oil Production Rate" } }, + { "FOPRA", { A::SUMMARY_FIELD, "Oil Production Rate above GOC" } }, + { "FOPRB", { A::SUMMARY_FIELD, "Oil Production Rate below GOC" } }, + { "FOPTA", { A::SUMMARY_FIELD, "Oil Production Total above GOC" } }, + { "FOPTB", { A::SUMMARY_FIELD, "Oil Production Total below GOC" } }, + { "FOPR1", { A::SUMMARY_FIELD, "Oil Production Rate above GOC" } }, + { "FOPR2", { A::SUMMARY_FIELD, "Oil Production Rate below GOC" } }, + { "FOPT1", { A::SUMMARY_FIELD, "Oil Production Total above GOC" } }, + { "FOPT2", { A::SUMMARY_FIELD, "Oil Production Total below GOC" } }, + { "FOMR", { A::SUMMARY_FIELD, "Oil Mass Rate" } }, + { "FOMT", { A::SUMMARY_FIELD, "Oil Mass Total" } }, + { "FODN", { A::SUMMARY_FIELD, "Oil Density at Surface Conditions" } }, + { "FOPRH", { A::SUMMARY_FIELD, "Oil Production Rate History" } }, + { "FOPRT", { A::SUMMARY_FIELD, "Oil Production Rate Target/Limit" } }, + { "FOPRF", { A::SUMMARY_FIELD, "Free Oil Production Rate" } }, + { "FOPRS", { A::SUMMARY_FIELD, "Solution Oil Production Rate" } }, + { "FOPT", { A::SUMMARY_FIELD, "Oil Production Total" } }, + { "FOPTH", { A::SUMMARY_FIELD, "Oil Production Total History" } }, + { "FOPTF", { A::SUMMARY_FIELD, "Free Oil Production Total" } }, + { "FOPTS", { A::SUMMARY_FIELD, "Solution Oil Production Total" } }, + { "FOIR", { A::SUMMARY_FIELD, "Oil Injection Rate" } }, + { "FOIRH", { A::SUMMARY_FIELD, "Oil Injection Rate History" } }, + { "FOIRT", { A::SUMMARY_FIELD, "Oil Injection Rate Target/Limit" } }, + { "FOIT", { A::SUMMARY_FIELD, "Oil Injection Total" } }, + { "FOITH", { A::SUMMARY_FIELD, "Oil Injection Total History" } }, + { "FOPP", { A::SUMMARY_FIELD, "Oil Potential Production rate" } }, + { "FOPP2", { A::SUMMARY_FIELD, "Oil Potential Production rate" } }, + { "FOPI", { A::SUMMARY_FIELD, "Oil Potential Injection rate" } }, + { "FOPI2", { A::SUMMARY_FIELD, "Oil Potential Injection rate" } }, + { "FOVPR", { A::SUMMARY_FIELD, "Oil Voidage Production Rate" } }, + { "FOVPT", { A::SUMMARY_FIELD, "Oil Voidage Production Total" } }, + { "FOVIR", { A::SUMMARY_FIELD, "Oil Voidage Injection Rate" } }, + { "FOVIT", { A::SUMMARY_FIELD, "Oil Voidage Injection Total" } }, + { "FOnPR", { A::SUMMARY_FIELD, "nth separator stage oil rate" } }, + { "FOnPT", { A::SUMMARY_FIELD, "nth separator stage oil total" } }, + { "FEOR", { A::SUMMARY_FIELD, "Export Oil Rate" } }, + { "FEOT", { A::SUMMARY_FIELD, "Export Oil Total" } }, + { "FEOMF", { A::SUMMARY_FIELD, "Export Oil Mole Fraction" } }, + { "FWPR", { A::SUMMARY_FIELD, "Water Production Rate" } }, + { "FWMR", { A::SUMMARY_FIELD, "Water Mass Rate" } }, + { "FWMT", { A::SUMMARY_FIELD, "Water Mass Total" } }, + { "FWPRH", { A::SUMMARY_FIELD, "Water Production Rate History" } }, + { "FWPRT", { A::SUMMARY_FIELD, "Water Production Rate Target/Limit" } }, + { "FWPT", { A::SUMMARY_FIELD, "Water Production Total" } }, + { "FWPTH", { A::SUMMARY_FIELD, "Water Production Total History" } }, + { "FWIR", { A::SUMMARY_FIELD, "Water Injection Rate" } }, + { "FWIRH", { A::SUMMARY_FIELD, "Water Injection Rate History" } }, + { "FWIRT", { A::SUMMARY_FIELD, "Water Injection Rate Target/Limit" } }, + { "FWIT", { A::SUMMARY_FIELD, "Water Injection Total" } }, + { "FWITH", { A::SUMMARY_FIELD, "Water Injection Total History" } }, + { "FWPP", { A::SUMMARY_FIELD, "Water Potential Production rate" } }, + { "FWPP2", { A::SUMMARY_FIELD, "Water Potential Production rate" } }, + { "FWPI", { A::SUMMARY_FIELD, "Water Potential Injection rate" } }, + { "FWPI2", { A::SUMMARY_FIELD, "Water Potential Injection rate" } }, + { "FWVPR", { A::SUMMARY_FIELD, "Water Voidage Production Rate" } }, + { "FWVPT", { A::SUMMARY_FIELD, "Water Voidage Production Total" } }, + { "FWVIR", { A::SUMMARY_FIELD, "Water Voidage Injection Rate" } }, + { "FWVIT", { A::SUMMARY_FIELD, "Water Voidage Injection Total" } }, + { "FWPIR", { A::SUMMARY_FIELD, "Ratio of produced water to injected water (percentage)" } }, + { "FWMPR", { A::SUMMARY_FIELD, "Water component molar production rate" } }, + { "FWMPT", { A::SUMMARY_FIELD, "Water component molar production total" } }, + { "FWMIR", { A::SUMMARY_FIELD, "Water component molar injection rate" } }, + { "FWMIT", { A::SUMMARY_FIELD, "Water component molar injection total" } }, + { "FGPR", { A::SUMMARY_FIELD, "Gas Production Rate" } }, + { "FGPRA", { A::SUMMARY_FIELD, "Gas Production Rate above" } }, + { "FGPRB", { A::SUMMARY_FIELD, "Gas Production Rate below" } }, + { "FGPTA", { A::SUMMARY_FIELD, "Gas Production Total above" } }, + { "FGPTB", { A::SUMMARY_FIELD, "Gas Production Total below" } }, + { "FGPR1", { A::SUMMARY_FIELD, "Gas Production Rate above GOC" } }, + { "FGPR2", { A::SUMMARY_FIELD, "Gas Production Rate below GOC" } }, + { "FGPT1", { A::SUMMARY_FIELD, "Gas Production Total above GOC" } }, + { "FGPT2", { A::SUMMARY_FIELD, "Gas Production Total below GOC" } }, + { "FGMR", { A::SUMMARY_FIELD, "Gas Mass Rate" } }, + { "FGMT", { A::SUMMARY_FIELD, "Gas Mass Total" } }, + { "FGDN", { A::SUMMARY_FIELD, "Gas Density at Surface Conditions" } }, + { "FGPRH", { A::SUMMARY_FIELD, "Gas Production Rate History" } }, + { "FGPRT", { A::SUMMARY_FIELD, "Gas Production Rate Target/Limit" } }, + { "FGPRF", { A::SUMMARY_FIELD, "Free Gas Production Rate" } }, + { "FGPRS", { A::SUMMARY_FIELD, "Solution Gas Production Rate" } }, + { "FGPT", { A::SUMMARY_FIELD, "Gas Production Total" } }, + { "FGPTH", { A::SUMMARY_FIELD, "Gas Production Total History" } }, + { "FGPTF", { A::SUMMARY_FIELD, "Free Gas Production Total" } }, + { "FGPTS", { A::SUMMARY_FIELD, "Solution Gas Production Total" } }, + { "FGIR", { A::SUMMARY_FIELD, "Gas Injection Rate" } }, + { "FGIRH", { A::SUMMARY_FIELD, "Gas Injection Rate History" } }, + { "FGIRT", { A::SUMMARY_FIELD, "Gas Injection Rate Target/Limit" } }, + { "FGIT", { A::SUMMARY_FIELD, "Gas Injection Total" } }, + { "FGITH", { A::SUMMARY_FIELD, "Gas Injection Total History" } }, + { "FGPP", { A::SUMMARY_FIELD, "Gas Potential Production rate" } }, + { "FGPP2", { A::SUMMARY_FIELD, "Gas Potential Production rate" } }, + { "FGPPS", { A::SUMMARY_FIELD, "Solution" } }, + { "FGPPS2", { A::SUMMARY_FIELD, "Solution" } }, + { "FGPPF", { A::SUMMARY_FIELD, "Free Gas Potential Production rate" } }, + { "FGPPF2", { A::SUMMARY_FIELD, "Free Gas Potential Production rate" } }, + { "FGPI", { A::SUMMARY_FIELD, "Gas Potential Injection rate" } }, + { "FGPI2", { A::SUMMARY_FIELD, "Gas Potential Injection rate" } }, + { "FSGR", { A::SUMMARY_FIELD, "Sales Gas Rate" } }, + { "FGSR", { A::SUMMARY_FIELD, "Sales Gas Rate" } }, + { "FSGT", { A::SUMMARY_FIELD, "Sales Gas Total" } }, + { "FGST", { A::SUMMARY_FIELD, "Sales Gas Total" } }, + { "FSMF", { A::SUMMARY_FIELD, "Sales Gas Mole Fraction" } }, + { "FFGR", { A::SUMMARY_FIELD, "Fuel Gas Rate, at and below this group" } }, + { "FFGT", { A::SUMMARY_FIELD, "Fuel Gas cumulative Total, at and below this group" } }, + { "FFMF", { A::SUMMARY_FIELD, "Fuel Gas Mole Fraction" } }, + { "FGCR", { A::SUMMARY_FIELD, "Gas Consumption Rate, at and below this group" } }, + { "FGCT", { A::SUMMARY_FIELD, "Gas Consumption Total, at and below this group" } }, + { "FGIMR", { A::SUMMARY_FIELD, "Gas Import Rate, at and below this group" } }, + { "FGIMT", { A::SUMMARY_FIELD, "Gas Import Total, at and below this group" } }, + { "FGLIR", { A::SUMMARY_FIELD, "Gas Lift Injection Rate" } }, + { "FWGPR", { A::SUMMARY_FIELD, "Wet Gas Production Rate" } }, + { "FWGPT", { A::SUMMARY_FIELD, "Wet Gas Production Total" } }, + { "FWGPRH", { A::SUMMARY_FIELD, "Wet Gas Production Rate History" } }, + { "FWGIR", { A::SUMMARY_FIELD, "Wet Gas Injection Rate" } }, + { "FWGIT", { A::SUMMARY_FIELD, "Wet Gas Injection Total" } }, + { "FEGR", { A::SUMMARY_FIELD, "Export Gas Rate" } }, + { "FEGT", { A::SUMMARY_FIELD, "Export Gas Total" } }, + { "FEMF", { A::SUMMARY_FIELD, "Export Gas Mole Fraction" } }, + { "FEXGR", { A::SUMMARY_FIELD, "Excess Gas Rate" } }, + { "FEXGT", { A::SUMMARY_FIELD, "Excess Gas Total" } }, + { "FRGR", { A::SUMMARY_FIELD, "Re-injection Gas Rate" } }, + { "FRGT", { A::SUMMARY_FIELD, "Re-injection Gas Total" } }, + { "FGnPR", { A::SUMMARY_FIELD, "nth separator stage gas rate" } }, + { "FGnPT", { A::SUMMARY_FIELD, "nth separator stage gas total" } }, + { "FGVPR", { A::SUMMARY_FIELD, "Gas Voidage Production Rate" } }, + { "FGVPT", { A::SUMMARY_FIELD, "Gas Voidage Production Total" } }, + { "FGVIR", { A::SUMMARY_FIELD, "Gas Voidage Injection Rate" } }, + { "FGVIT", { A::SUMMARY_FIELD, "Gas Voidage Injection Total" } }, + { "FGQ", { A::SUMMARY_FIELD, "Gas Quality" } }, + { "FLPR", { A::SUMMARY_FIELD, "Liquid Production Rate" } }, + { "FLPRH", { A::SUMMARY_FIELD, "Liquid Production Rate History" } }, + { "FLPRT", { A::SUMMARY_FIELD, "Liquid Production Rate Target/Limit" } }, + { "FLPT", { A::SUMMARY_FIELD, "Liquid Production Total" } }, + { "FLPTH", { A::SUMMARY_FIELD, "Liquid Production Total History" } }, + { "FVPR", { A::SUMMARY_FIELD, "Res Volume Production Rate" } }, + { "FVPRT", { A::SUMMARY_FIELD, "Res Volume Production Rate Target/Limit" } }, + { "FVPT", { A::SUMMARY_FIELD, "Res Volume Production Total" } }, + { "FVIR", { A::SUMMARY_FIELD, "Res Volume Injection Rate" } }, + { "FVIRT", { A::SUMMARY_FIELD, "Res Volume Injection Rate Target/Limit" } }, + { "FVIT", { A::SUMMARY_FIELD, "Res Volume Injection Total" } }, + { "FWCT", { A::SUMMARY_FIELD, "Water Cut" } }, + { "FWCTH", { A::SUMMARY_FIELD, "Water Cut History" } }, + { "FGOR", { A::SUMMARY_FIELD, "Gas-Oil Ratio" } }, + { "FGORH", { A::SUMMARY_FIELD, "Gas-Oil Ratio History" } }, + { "FOGR", { A::SUMMARY_FIELD, "Oil-Gas Ratio" } }, + { "FOGRH", { A::SUMMARY_FIELD, "Oil-Gas Ratio History" } }, + { "FWGR", { A::SUMMARY_FIELD, "Water-Gas Ratio" } }, + { "FWGRH", { A::SUMMARY_FIELD, "Water-Gas Ratio History" } }, + { "FGLR", { A::SUMMARY_FIELD, "Gas-Liquid Ratio" } }, + { "FGLRH", { A::SUMMARY_FIELD, "Gas-Liquid Ratio History" } }, + { "FMCTP", { A::SUMMARY_FIELD, "Mode of Control for group Production" } }, + { "FMCTW", { A::SUMMARY_FIELD, "Mode of Control for group Water Injection" } }, + { "FMCTG", { A::SUMMARY_FIELD, "Mode of Control for group Gas Injection" } }, + { "FMWPT", { A::SUMMARY_FIELD, "Total number of production wells" } }, + { "FMWPR", { A::SUMMARY_FIELD, "Number of production wells currently flowing" } }, + { "FMWPA", { A::SUMMARY_FIELD, "Number of abandoned production wells" } }, + { "FMWPU", { A::SUMMARY_FIELD, "Number of unused production wells" } }, + { "FMWPG", { A::SUMMARY_FIELD, "Number of producers on group control" } }, + { "FMWPO", { A::SUMMARY_FIELD, "Number of producers controlled by own oil rate limit" } }, + { "FMWPS", { A::SUMMARY_FIELD, "Number of producers on own surface rate limit control" } }, + { "FMWPV", { A::SUMMARY_FIELD, "Number of producers on own reservoir volume rate limit control" } }, + { "FMWPP", { A::SUMMARY_FIELD, "Number of producers on pressure control" } }, + { "FMWPL", { A::SUMMARY_FIELD, "Number of producers using artificial lift" } }, + { "FMWIT", { A::SUMMARY_FIELD, "Total number of injection wells" } }, + { "FMWIN", { A::SUMMARY_FIELD, "Number of injection wells currently flowing" } }, + { "FMWIA", { A::SUMMARY_FIELD, "Number of abandoned injection wells" } }, + { "FMWIU", { A::SUMMARY_FIELD, "Number of unused injection wells" } }, + { "FMWIG", { A::SUMMARY_FIELD, "Number of injectors on group control" } }, + { "FMWIS", { A::SUMMARY_FIELD, "Number of injectors on own surface rate limit control" } }, + { "FMWIV", { A::SUMMARY_FIELD, "Number of injectors on own reservoir volume rate limit control" } }, + { "FMWIP", { A::SUMMARY_FIELD, "Number of injectors on pressure control" } }, + { "FMWDR", { A::SUMMARY_FIELD, "Number of drilling events this timestep" } }, + { "FMWDT", { A::SUMMARY_FIELD, "Number of drilling events in total" } }, + { "FMWWO", { A::SUMMARY_FIELD, "Number of workover events this timestep" } }, + { "FMWWT", { A::SUMMARY_FIELD, "Number of workover events in total" } }, + { "FEPR", { A::SUMMARY_FIELD, "Energy Production Rate" } }, + { "FEPT", { A::SUMMARY_FIELD, "Energy Production Total" } }, + { "FNLPR", { A::SUMMARY_FIELD, "NGL Production Rate" } }, + { "FNLPT", { A::SUMMARY_FIELD, "NGL Production Total" } }, + { "FNLPRH", { A::SUMMARY_FIELD, "NGL Production Rate History" } }, + { "FNLPTH", { A::SUMMARY_FIELD, "NGL Production Total History" } }, + { "FAMF", { A::SUMMARY_FIELD, "Component aqueous mole fraction, from producing completions" } }, + { "FXMF", { A::SUMMARY_FIELD, "Liquid Mole Fraction" } }, + { "FYMF", { A::SUMMARY_FIELD, "Vapor Mole Fraction" } }, + { "FXMFn", { A::SUMMARY_FIELD, "Liquid Mole Fraction for nth separator stage" } }, + { "FYMFn", { A::SUMMARY_FIELD, "Vapor Mole Fraction for nth separator stage" } }, + { "FZMF", { A::SUMMARY_FIELD, "Total Mole Fraction" } }, + { "FCMPR", { A::SUMMARY_FIELD, "Hydrocarbon Component Molar Production Rates" } }, + { "FCMPT", { A::SUMMARY_FIELD, "Hydrocarbon Component" } }, + { "FCMIR", { A::SUMMARY_FIELD, "Hydrocarbon Component Molar Injection Rates" } }, + { "FCMIT", { A::SUMMARY_FIELD, "Hydrocarbon Component Molar Injection Totals" } }, + { "FHMIR", { A::SUMMARY_FIELD, "Hydrocarbon Molar Injection Rate" } }, + { "FHMIT", { A::SUMMARY_FIELD, "Hydrocarbon Molar Injection Total" } }, + { "FHMPR", { A::SUMMARY_FIELD, "Hydrocarbon Molar Production Rate" } }, + { "FHMPT", { A::SUMMARY_FIELD, "Hydrocarbon Molar Production Total" } }, + { "FCHMR", { A::SUMMARY_FIELD, "Hydrocarbon Component" } }, + { "FCHMT", { A::SUMMARY_FIELD, "Hydrocarbon Component" } }, + { "FCWGPR", { A::SUMMARY_FIELD, "Hydrocarbon Component Wet Gas Production Rate" } }, + { "FCWGPT", { A::SUMMARY_FIELD, "Hydrocarbon Component Wet Gas Production Total" } }, + { "FCWGIR", { A::SUMMARY_FIELD, "Hydrocarbon Component Wet Gas Injection Rate" } }, + { "FCWGIT", { A::SUMMARY_FIELD, "Hydrocarbon Component Wet Gas Injection Total" } }, + { "FCGMR", { A::SUMMARY_FIELD, "Hydrocarbon component" } }, + { "FCGMT", { A::SUMMARY_FIELD, "Hydrocarbon component" } }, + { "FCOMR", { A::SUMMARY_FIELD, "Hydrocarbon component" } }, + { "FCOMT", { A::SUMMARY_FIELD, "Hydrocarbon component" } }, + { "FCNMR", { A::SUMMARY_FIELD, "Hydrocarbon component molar rates in the NGL phase" } }, + { "FCNWR", { A::SUMMARY_FIELD, "Hydrocarbon component mass rates in the NGL phase" } }, + { "FCGMRn", { A::SUMMARY_FIELD, "Hydrocarbon component molar rates in the gas phase for nth separator stage" } }, + { "FCGRn", { A::SUMMARY_FIELD, "Hydrocarbon component molar rates in the gas phase for nth separator stage" } }, + { "FCOMRn", { A::SUMMARY_FIELD, "Hydrocarbon component" } }, + { "FCORn", { A::SUMMARY_FIELD, "Hydrocarbon component" } }, + { "FMUF", { A::SUMMARY_FIELD, "Make-up fraction" } }, + { "FAMR", { A::SUMMARY_FIELD, "Make-up gas rate" } }, + { "FAMT", { A::SUMMARY_FIELD, "Make-up gas total" } }, + { "FGSPR", { A::SUMMARY_FIELD, "Target sustainable rate for most recent sustainable capacity test for gas" } }, + { "FGSRL", { A::SUMMARY_FIELD, "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for gas" } }, + { "FGSRU", { A::SUMMARY_FIELD, "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for gas" } }, + { "FGSSP", { A::SUMMARY_FIELD, "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for gas" } }, + { "FGSTP", { A::SUMMARY_FIELD, "Test period for the most recent sustainable capacity test for gas" } }, + { "FOSPR", { A::SUMMARY_FIELD, "Target sustainable rate for most recent sustainable capacity test for oil" } }, + { "FOSRL", { A::SUMMARY_FIELD, "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for oil" } }, + { "FOSRU", { A::SUMMARY_FIELD, "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for oil" } }, + { "FOSSP", { A::SUMMARY_FIELD, "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for oil" } }, + { "FOSTP", { A::SUMMARY_FIELD, "Test period for the most recent sustainable capacity test for oil" } }, + { "FWSPR", { A::SUMMARY_FIELD, "Target sustainable rate for most recent sustainable capacity test for water" } }, + { "FWSRL", { A::SUMMARY_FIELD, "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for water" } }, + { "FWSRU", { A::SUMMARY_FIELD, "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for water" } }, + { "FWSSP", { A::SUMMARY_FIELD, "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for water" } }, + { "FWSTP", { A::SUMMARY_FIELD, "Test period for the most recent sustainable capacity test for water" } }, + { "FGPRG", { A::SUMMARY_FIELD, "Gas production rate" } }, + { "FOPRG", { A::SUMMARY_FIELD, "Oil production rate" } }, + { "FNLPRG", { A::SUMMARY_FIELD, "NGL production rate" } }, + { "FXMFG", { A::SUMMARY_FIELD, "Liquid mole fraction" } }, + { "FYMFG", { A::SUMMARY_FIELD, "Vapor mole fraction" } }, + { "FCOMRG", { A::SUMMARY_FIELD, "Hydrocarbon component" } }, + { "FCGMRG", { A::SUMMARY_FIELD, "Hydrocarbon component molar rates in the gas phase" } }, + { "FCNMRG", { A::SUMMARY_FIELD, "Hydrocarbon component molar rates in the NGL phase" } }, + { "FPR", { A::SUMMARY_FIELD, "Pressure average value" } }, + { "FPRH", { A::SUMMARY_FIELD, "Pressure average value" } }, + { "FPRP", { A::SUMMARY_FIELD, "Pressure average value" } }, + { "FPRGZ", { A::SUMMARY_FIELD, "P/Z" } }, + { "FRS", { A::SUMMARY_FIELD, "Gas-oil ratio" } }, + { "FRV", { A::SUMMARY_FIELD, "Oil-gas ratio" } }, + { "FCHIP", { A::SUMMARY_FIELD, "Component Hydrocarbon as Wet Gas" } }, + { "FCMIP", { A::SUMMARY_FIELD, "Component Hydrocarbon as Moles" } }, + { "FPPC", { A::SUMMARY_FIELD, "Initial Contact Corrected Potential" } }, + { "FREAC", { A::SUMMARY_FIELD, "Reaction rate. The reaction number is given as a component index" } }, + { "FREAT", { A::SUMMARY_FIELD, "Reaction total. The reaction number is given as a component index" } }, + { "FRPV", { A::SUMMARY_FIELD, "Pore Volume at Reservoir conditions" } }, + { "FOPV", { A::SUMMARY_FIELD, "Pore Volume containing Oil" } }, + { "FWPV", { A::SUMMARY_FIELD, "Pore Volume containing Water" } }, + { "FGPV", { A::SUMMARY_FIELD, "Pore Volume containing Gas" } }, + { "FHPV", { A::SUMMARY_FIELD, "Pore Volume containing Hydrocarbon" } }, + { "FRTM", { A::SUMMARY_FIELD, "Transmissibility Multiplier associated with rock compaction" } }, + { "FOE", { A::SUMMARY_FIELD, "(OIP(initial - OIP(now) / OIP(initial)" } }, + { "FOEW", { A::SUMMARY_FIELD, "Oil Production from Wells / OIP(initial)" } }, + { "FOEIW", { A::SUMMARY_FIELD, "(OIP(initial - OIP(now) / Initial Mobile Oil with respect to Water" } }, + { "FOEWW", { A::SUMMARY_FIELD, "Oil Production from Wells / Initial Mobile Oil with respect to Water" } }, + { "FOEIG", { A::SUMMARY_FIELD, "(OIP(initial - OIP(now) / Initial Mobile Oil with respect to Gas" } }, + { "FOEWG", { A::SUMMARY_FIELD, "Oil Production from Wells / Initial Mobile Oil with respect to Gas" } }, + { "FORMR", { A::SUMMARY_FIELD, "Total stock tank oil produced by rock compaction" } }, + { "FORMW", { A::SUMMARY_FIELD, "Total stock tank oil produced by water influx" } }, + { "FORMG", { A::SUMMARY_FIELD, "Total stock tank oil produced by gas influx" } }, + { "FORME", { A::SUMMARY_FIELD, "Total stock tank oil produced by oil expansion" } }, + { "FORMS", { A::SUMMARY_FIELD, "Total stock tank oil produced by solution gas" } }, + { "FORMF", { A::SUMMARY_FIELD, "Total stock tank oil produced by free gas influx" } }, + { "FORMX", { A::SUMMARY_FIELD, "Total stock tank oil produced by 'traced' water influx" } }, + { "FORMY", { A::SUMMARY_FIELD, "Total stock tank oil produced by other water influx" } }, + { "FORFR", { A::SUMMARY_FIELD, "Fraction of total oil produced by rock compaction" } }, + { "FORFW", { A::SUMMARY_FIELD, "Fraction of total oil produced by water influx" } }, + { "FORFG", { A::SUMMARY_FIELD, "Fraction of total oil produced by gas influx" } }, + { "FORFE", { A::SUMMARY_FIELD, "Fraction of total oil produced by oil expansion" } }, + { "FORFS", { A::SUMMARY_FIELD, "Fraction of total oil produced by solution gas" } }, + { "FORFF", { A::SUMMARY_FIELD, "Fraction of total oil produced by free gas influx" } }, + { "FORFX", { A::SUMMARY_FIELD, "Fraction of total oil produced by 'traced' water influx" } }, + { "FORFY", { A::SUMMARY_FIELD, "Fraction of total oil produced by other water influx" } }, + { "FAQR", { A::SUMMARY_FIELD, "Aquifer influx rate" } }, + { "FAQT", { A::SUMMARY_FIELD, "Cumulative aquifer influx" } }, + { "FAQRG", { A::SUMMARY_FIELD, "Aquifer influx rate" } }, + { "FAQTG", { A::SUMMARY_FIELD, "Cumulative aquifer influx" } }, + { "FAQER", { A::SUMMARY_FIELD, "Aquifer thermal energy influx rate" } }, + { "FAQET", { A::SUMMARY_FIELD, "Cumulative aquifer thermal energy influx" } }, + { "FNQR", { A::SUMMARY_FIELD, "Aquifer influx rate" } }, + { "FNQT", { A::SUMMARY_FIELD, "Cumulative aquifer influx" } }, + { "FTPR", { A::SUMMARY_FIELD, "Tracer Production Rate" } }, + { "FTPT", { A::SUMMARY_FIELD, "Tracer Production Total" } }, + { "FTPC", { A::SUMMARY_FIELD, "Tracer Production Concentration" } }, + { "FTIR", { A::SUMMARY_FIELD, "Tracer Injection Rate" } }, + { "FTIT", { A::SUMMARY_FIELD, "Tracer Injection Total" } }, + { "FTIC", { A::SUMMARY_FIELD, "Tracer Injection Concentration" } }, + { "FTMR", { A::SUMMARY_FIELD, "Traced mass Rate" } }, + { "FTMT", { A::SUMMARY_FIELD, "Traced mass Total" } }, + { "FTQR", { A::SUMMARY_FIELD, "Traced molar Rate" } }, + { "FTCM", { A::SUMMARY_FIELD, "Tracer Carrier molar Rate" } }, + { "FTMF", { A::SUMMARY_FIELD, "Traced molar fraction" } }, + { "FTVL", { A::SUMMARY_FIELD, "Traced liquid volume rate" } }, + { "FTVV", { A::SUMMARY_FIELD, "Traced vapor volume rate" } }, + { "FTTL", { A::SUMMARY_FIELD, "Traced liquid volume total" } }, + { "FTTV", { A::SUMMARY_FIELD, "Traced vapor volume total" } }, + { "FTML", { A::SUMMARY_FIELD, "Traced mass liquid rate" } }, + { "FTMV", { A::SUMMARY_FIELD, "Traced mass vapor rate" } }, + { "FTLM", { A::SUMMARY_FIELD, "Traced mass liquid total" } }, + { "FTVM", { A::SUMMARY_FIELD, "Traced mass vapor total" } }, + { "FTIPT", { A::SUMMARY_FIELD, "Tracer In Place" } }, + { "FTIPF", { A::SUMMARY_FIELD, "Tracer In Place" } }, + { "FTIPS", { A::SUMMARY_FIELD, "Tracer In Place" } }, + { "FAPI", { A::SUMMARY_FIELD, "Oil API" } }, + { "FSPR", { A::SUMMARY_FIELD, "Salt Production Rate" } }, + { "FSPT", { A::SUMMARY_FIELD, "Salt Production Total" } }, + { "FSIR", { A::SUMMARY_FIELD, "Salt Injection Rate" } }, + { "FSIT", { A::SUMMARY_FIELD, "Salt Injection Total" } }, + { "FSPC", { A::SUMMARY_FIELD, "Salt Production Concentration" } }, + { "FSIC", { A::SUMMARY_FIELD, "Salt Injection Concentration" } }, + { "FSIP", { A::SUMMARY_FIELD, "Salt In Place" } }, + { "GTPRANI", { A::SUMMARY_FIELD, "Anion Production Rate" } }, + { "GTPTANI", { A::SUMMARY_FIELD, "Anion Production Total" } }, + { "GTIRANI", { A::SUMMARY_FIELD, "Anion Injection Rate" } }, + { "GTITANI", { A::SUMMARY_FIELD, "Anion Injection Total" } }, + { "GTPRCAT", { A::SUMMARY_FIELD, "Cation Production Rate" } }, + { "GTPTCAT", { A::SUMMARY_FIELD, "Cation Production Total" } }, + { "GTIRCAT", { A::SUMMARY_FIELD, "Cation Injection Rate" } }, + { "GTITCAT", { A::SUMMARY_FIELD, "Cation Injection Total" } }, + { "FTPCHEA", { A::SUMMARY_FIELD, "Production Temperature" } }, + { "FTICHEA", { A::SUMMARY_FIELD, "Injection Temperature" } }, + { "FTPRHEA", { A::SUMMARY_FIELD, "Energy flows" } }, + { "FTPTHEA", { A::SUMMARY_FIELD, "Energy Production Total" } }, + { "FTIRHEA", { A::SUMMARY_FIELD, "Energy flows" } }, + { "FTITHEA", { A::SUMMARY_FIELD, "Energy Injection Total" } }, + { "FTIPTHEA", { A::SUMMARY_FIELD, "Difference in Energy in place between current and initial time" } }, + { "FTPR", { A::SUMMARY_FIELD, "Tracer Production Rate" } }, + { "FTPT", { A::SUMMARY_FIELD, "Tracer Production Total" } }, + { "FTPC", { A::SUMMARY_FIELD, "Tracer Production Concentration" } }, + { "FTIR", { A::SUMMARY_FIELD, "Tracer Injection Rate" } }, + { "FTIT", { A::SUMMARY_FIELD, "Tracer Injection Total" } }, + { "FTIC", { A::SUMMARY_FIELD, "Tracer Injection Concentration" } }, + { "FTIPT", { A::SUMMARY_FIELD, "Tracer In Place" } }, + { "FTIPF", { A::SUMMARY_FIELD, "Tracer In Place" } }, + { "FTIPS", { A::SUMMARY_FIELD, "Tracer In Place" } }, + { "FTIP#", { A::SUMMARY_FIELD, " Tracer In Place in phase # (1,2,3,...)" } }, + { "FTADS", { A::SUMMARY_FIELD, "Tracer Adsorption total" } }, + { "FTDCY", { A::SUMMARY_FIELD, "Decayed tracer" } }, + { "FTIRF", { A::SUMMARY_FIELD, "Tracer Injection Rate" } }, + { "FTIRS", { A::SUMMARY_FIELD, "Tracer Injection Rate" } }, + { "FTPRF", { A::SUMMARY_FIELD, "Tracer Production Rate" } }, + { "FTPRS", { A::SUMMARY_FIELD, "Tracer Production Rate" } }, + { "FTITF", { A::SUMMARY_FIELD, "Tracer Injection Total" } }, + { "FTITS", { A::SUMMARY_FIELD, "Tracer Injection Total" } }, + { "FTPTF", { A::SUMMARY_FIELD, "Tracer Production Total" } }, + { "FTPTS", { A::SUMMARY_FIELD, "Tracer Production Total" } }, + { "FTICF", { A::SUMMARY_FIELD, "Tracer Injection Concentration" } }, + { "FTICS", { A::SUMMARY_FIELD, "Tracer Injection Concentration" } }, + { "FTPCF", { A::SUMMARY_FIELD, "Tracer Production" } }, + { "FTPCS", { A::SUMMARY_FIELD, "Tracer Production" } }, + { "FMPR", { A::SUMMARY_FIELD, "Methane Production Rate" } }, + { "FMPT", { A::SUMMARY_FIELD, "Methane Production Total" } }, + { "FMIR", { A::SUMMARY_FIELD, "Methane Injection Rate" } }, + { "FMIT", { A::SUMMARY_FIELD, "Methane Injection Total" } }, + { "FCGC", { A::SUMMARY_FIELD, "Bulk Coal Gas Concentration" } }, + { "FCSC", { A::SUMMARY_FIELD, "Bulk Coal Solvent Concentration" } }, + { "FTPRFOA", { A::SUMMARY_FIELD, "Production Rate" } }, + { "FTPTFOA", { A::SUMMARY_FIELD, "Production Total" } }, + { "FTIRFOA", { A::SUMMARY_FIELD, "Injection Rate" } }, + { "FTITFOA", { A::SUMMARY_FIELD, "Injection Total" } }, + { "FTIPTFOA", { A::SUMMARY_FIELD, "In Solution" } }, + { "FTADSFOA", { A::SUMMARY_FIELD, "Adsorption total" } }, + { "FTDCYFOA", { A::SUMMARY_FIELD, "Decayed tracer" } }, + { "FTMOBFOA", { A::SUMMARY_FIELD, "Gas mobility factor" } }, + { "FTPRFOA", { A::SUMMARY_FIELD, "Production Rate" } }, + { "FTPTFOA", { A::SUMMARY_FIELD, "Production Total" } }, + { "FTIRFOA", { A::SUMMARY_FIELD, "Injection Rate" } }, + { "FTITFOA", { A::SUMMARY_FIELD, "Injection Total" } }, + { "FTIPTFOA", { A::SUMMARY_FIELD, "In Solution" } }, + { "FTADSFOA", { A::SUMMARY_FIELD, "Adsorption total" } }, + { "FTDCYFOA", { A::SUMMARY_FIELD, "Decayed tracer" } }, + { "FTMOBFOA", { A::SUMMARY_FIELD, "Gas mobility factor" } }, + { "FSGR", { A::SUMMARY_FIELD, "Sales Gas Rate" } }, + { "FGSR", { A::SUMMARY_FIELD, "Sales Gas Rate" } }, + { "FSGT", { A::SUMMARY_FIELD, "Sales Gas Total" } }, + { "FGST", { A::SUMMARY_FIELD, "Sales Gas Total" } }, + { "FGDC", { A::SUMMARY_FIELD, "Gas Delivery Capacity" } }, + { "FGDCQ", { A::SUMMARY_FIELD, "Field/Group Gas DCQ" } }, + { "FGCR", { A::SUMMARY_FIELD, "Gas consumption rate, at and below this group" } }, + { "FGCT", { A::SUMMARY_FIELD, "Gas consumption cumulative total, at and below this group" } }, + { "FFGR", { A::SUMMARY_FIELD, "Fuel Gas rate, at and below this group" } }, + { "FFGT", { A::SUMMARY_FIELD, "Fuel Gas cumulative total, at and below this group" } }, + { "FGIMR", { A::SUMMARY_FIELD, "Gas import rate, at and below this group" } }, + { "FGIMT", { A::SUMMARY_FIELD, "Gas import cumulative total, at and below this group" } }, + { "FGLIR", { A::SUMMARY_FIELD, "Gas Lift Injection Rate" } }, + { "FGCV", { A::SUMMARY_FIELD, "Gas Calorific Value" } }, + { "FGQ", { A::SUMMARY_FIELD, "Gas molar Quality" } }, + { "FEPR", { A::SUMMARY_FIELD, "Energy Production Rate" } }, + { "FEPT", { A::SUMMARY_FIELD, "Energy Production Total" } }, + { "FESR", { A::SUMMARY_FIELD, "Energy Sales Rate" } }, + { "FEST", { A::SUMMARY_FIELD, "Energy Sales Total" } }, + { "FEDC", { A::SUMMARY_FIELD, "Energy Delivery Capacity" } }, + { "FEDCQ", { A::SUMMARY_FIELD, "Energy DCQ" } }, + { "FCPR", { A::SUMMARY_FIELD, "Polymer Production Rate" } }, + { "FCPC", { A::SUMMARY_FIELD, "Polymer Production Concentration" } }, + { "FCPT", { A::SUMMARY_FIELD, "Polymer Production Total" } }, + { "FCIR", { A::SUMMARY_FIELD, "Polymer Injection Rate" } }, + { "FCIC", { A::SUMMARY_FIELD, "Polymer Injection Concentration" } }, + { "FCIT", { A::SUMMARY_FIELD, "Polymer Injection Total" } }, + { "FCIP", { A::SUMMARY_FIELD, "Polymer In Solution" } }, + { "FCAD", { A::SUMMARY_FIELD, "Polymer Adsorption total" } }, + { "FSPR", { A::SUMMARY_FIELD, "Salt Production Rate" } }, + { "FSPT", { A::SUMMARY_FIELD, "Salt Production Total" } }, + { "FSIR", { A::SUMMARY_FIELD, "Salt Injection Rate" } }, + { "FSIT", { A::SUMMARY_FIELD, "Salt Injection Total" } }, + { "FSIP", { A::SUMMARY_FIELD, "Salt In Place" } }, + { "PSSPR", { A::SUMMARY_FIELD, "Log of the pressure change per unit time" } }, + { "PSSSO", { A::SUMMARY_FIELD, "Log of the oil saturation change per unit time" } }, + { "PSSSW", { A::SUMMARY_FIELD, "Log of the water saturation change per unit time" } }, + { "PSSSG", { A::SUMMARY_FIELD, "Log of the gas saturation change per unit time" } }, + { "PSSSC", { A::SUMMARY_FIELD, "Log of the salt concentration change per unit time" } }, + { "FNPR", { A::SUMMARY_FIELD, "Solvent Production Rate" } }, + { "FNPT", { A::SUMMARY_FIELD, "Solvent Production Total" } }, + { "FNIR", { A::SUMMARY_FIELD, "Solvent Injection Rate" } }, + { "FNIT", { A::SUMMARY_FIELD, "Solvent Injection Total" } }, + { "FNIP", { A::SUMMARY_FIELD, "Solvent In Place" } }, + { "FTPRSUR", { A::SUMMARY_FIELD, "Production Rate" } }, + { "FTPTSUR", { A::SUMMARY_FIELD, "Production Total" } }, + { "FTIRSUR", { A::SUMMARY_FIELD, "Injection Rate" } }, + { "FTITSUR", { A::SUMMARY_FIELD, "Injection Total" } }, + { "FTIPTSUR", { A::SUMMARY_FIELD, "In Solution" } }, + { "FTADSUR", { A::SUMMARY_FIELD, "Adsorption total" } }, + { "FTPRALK", { A::SUMMARY_FIELD, "Production Rate" } }, + { "FTPTALK", { A::SUMMARY_FIELD, "Production Total" } }, + { "FTIRALK", { A::SUMMARY_FIELD, "Injection Rate" } }, + { "FTITALK", { A::SUMMARY_FIELD, "Injection Total" } }, + { "FU", { A::SUMMARY_FIELD, "User-defined field quantity" } }, + + { "GOPR", { A::SUMMARY_WELL_GROUP, "Oil Production Rate" } }, + { "GOPRA", { A::SUMMARY_WELL_GROUP, "Oil Production Rate above GOC" } }, + { "GOPRB", { A::SUMMARY_WELL_GROUP, "Oil Production Rate below GOC" } }, + { "GOPTA", { A::SUMMARY_WELL_GROUP, "Oil Production Total above GOC" } }, + { "GOPTB", { A::SUMMARY_WELL_GROUP, "Oil Production Total below GOC" } }, + { "GOPR1", { A::SUMMARY_WELL_GROUP, "Oil Production Rate above GOC" } }, + { "GOPR2", { A::SUMMARY_WELL_GROUP, "Oil Production Rate below GOC" } }, + { "GOPT1", { A::SUMMARY_WELL_GROUP, "Oil Production Total above GOC" } }, + { "GOPT2", { A::SUMMARY_WELL_GROUP, "Oil Production Total below GOC" } }, + { "GOMR", { A::SUMMARY_WELL_GROUP, "Oil Mass Rate" } }, + { "GOMT", { A::SUMMARY_WELL_GROUP, "Oil Mass Total" } }, + { "GODN", { A::SUMMARY_WELL_GROUP, "Oil Density at Surface Conditions" } }, + { "GOPRH", { A::SUMMARY_WELL_GROUP, "Oil Production Rate History" } }, + { "GOPRT", { A::SUMMARY_WELL_GROUP, "Oil Production Rate Target/Limit" } }, + { "GOPRL", { A::SUMMARY_WELL_GROUP, "Oil Production Rate Target/Limit" } }, + { "GOPRF", { A::SUMMARY_WELL_GROUP, "Free Oil Production Rate" } }, + { "GOPRS", { A::SUMMARY_WELL_GROUP, "Solution Oil Production Rate" } }, + { "GOPT", { A::SUMMARY_WELL_GROUP, "Oil Production Total" } }, + { "GOPTH", { A::SUMMARY_WELL_GROUP, "Oil Production Total History" } }, + { "GOPTF", { A::SUMMARY_WELL_GROUP, "Free Oil Production Total" } }, + { "GOPTS", { A::SUMMARY_WELL_GROUP, "Solution Oil Production Total" } }, + { "GOIR", { A::SUMMARY_WELL_GROUP, "Oil Injection Rate" } }, + { "GOIRH", { A::SUMMARY_WELL_GROUP, "Oil Injection Rate History" } }, + { "GOIRT", { A::SUMMARY_WELL_GROUP, "Oil Injection Rate Target/Limit" } }, + { "GOIRL", { A::SUMMARY_WELL_GROUP, "Oil Injection Rate Target/Limit" } }, + { "GOIT", { A::SUMMARY_WELL_GROUP, "Oil Injection Total" } }, + { "GOITH", { A::SUMMARY_WELL_GROUP, "Oil Injection Total History" } }, + { "GOPP", { A::SUMMARY_WELL_GROUP, "Oil Potential Production rate" } }, + { "GOPP2", { A::SUMMARY_WELL_GROUP, "Oil Potential Production rate" } }, + { "GOPI", { A::SUMMARY_WELL_GROUP, "Oil Potential Injection rate" } }, + { "GOPI2", { A::SUMMARY_WELL_GROUP, "Oil Potential Injection rate" } }, + { "GOPGR", { A::SUMMARY_WELL_GROUP, "Oil Production Guide Rate" } }, + { "GOIGR", { A::SUMMARY_WELL_GROUP, "Oil Injection Guide Rate" } }, + { "GOVPR", { A::SUMMARY_WELL_GROUP, "Oil Voidage Production Rate" } }, + { "GOVPT", { A::SUMMARY_WELL_GROUP, "Oil Voidage Production Total" } }, + { "GOVIR", { A::SUMMARY_WELL_GROUP, "Oil Voidage Injection Rate" } }, + { "GOVIT", { A::SUMMARY_WELL_GROUP, "Oil Voidage Injection Total" } }, + { "GOnPR", { A::SUMMARY_WELL_GROUP, "nth separator stage oil rate" } }, + { "GOnPT", { A::SUMMARY_WELL_GROUP, "nth separator stage oil total" } }, + { "GEOR", { A::SUMMARY_WELL_GROUP, "Export Oil Rate" } }, + { "GEOT", { A::SUMMARY_WELL_GROUP, "Export Oil Total" } }, + { "GEOMF", { A::SUMMARY_WELL_GROUP, "Export Oil Mole Fraction" } }, + { "GWPR", { A::SUMMARY_WELL_GROUP, "Water Production Rate" } }, + { "GWMR", { A::SUMMARY_WELL_GROUP, "Water Mass Rate" } }, + { "GWMT", { A::SUMMARY_WELL_GROUP, "Water Mass Total" } }, + { "GWPRH", { A::SUMMARY_WELL_GROUP, "Water Production Rate History" } }, + { "GWPRT", { A::SUMMARY_WELL_GROUP, "Water Production Rate Target/Limit" } }, + { "GWPRL", { A::SUMMARY_WELL_GROUP, "Water Production Rate Target/Limit" } }, + { "GWPT", { A::SUMMARY_WELL_GROUP, "Water Production Total" } }, + { "GWPTH", { A::SUMMARY_WELL_GROUP, "Water Production Total History" } }, + { "GWIR", { A::SUMMARY_WELL_GROUP, "Water Injection Rate" } }, + { "GWIRH", { A::SUMMARY_WELL_GROUP, "Water Injection Rate History" } }, + { "GWIRT", { A::SUMMARY_WELL_GROUP, "Water Injection Rate Target/Limit" } }, + { "GWIRL", { A::SUMMARY_WELL_GROUP, "Water Injection Rate Target/Limit" } }, + { "GWIT", { A::SUMMARY_WELL_GROUP, "Water Injection Total" } }, + { "GWITH", { A::SUMMARY_WELL_GROUP, "Water Injection Total History" } }, + { "GWPP", { A::SUMMARY_WELL_GROUP, "Water Potential Production rate" } }, + { "GWPP2", { A::SUMMARY_WELL_GROUP, "Water Potential Production rate" } }, + { "GWPI", { A::SUMMARY_WELL_GROUP, "Water Potential Injection rate" } }, + { "GWPI2", { A::SUMMARY_WELL_GROUP, "Water Potential Injection rate" } }, + { "GWPGR", { A::SUMMARY_WELL_GROUP, "Water Production Guide Rate" } }, + { "GWIGR", { A::SUMMARY_WELL_GROUP, "Water Injection Guide Rate" } }, + { "GWVPR", { A::SUMMARY_WELL_GROUP, "Water Voidage Production Rate" } }, + { "GWVPT", { A::SUMMARY_WELL_GROUP, "Water Voidage Production Total" } }, + { "GWVIR", { A::SUMMARY_WELL_GROUP, "Water Voidage Injection Rate" } }, + { "GWVIT", { A::SUMMARY_WELL_GROUP, "Water Voidage Injection Total" } }, + { "GWPIR", { A::SUMMARY_WELL_GROUP, "Ratio of produced water to injected water (percentage)" } }, + { "GWMPR", { A::SUMMARY_WELL_GROUP, "Water component molar production rate" } }, + { "GWMPT", { A::SUMMARY_WELL_GROUP, "Water component molar production total" } }, + { "GWMIR", { A::SUMMARY_WELL_GROUP, "Water component molar injection rate" } }, + { "GWMIT", { A::SUMMARY_WELL_GROUP, "Water component molar injection total" } }, + { "GGPR", { A::SUMMARY_WELL_GROUP, "Gas Production Rate" } }, + { "GGPRA", { A::SUMMARY_WELL_GROUP, "Gas Production Rate above" } }, + { "GGPRB", { A::SUMMARY_WELL_GROUP, "Gas Production Rate below" } }, + { "GGPTA", { A::SUMMARY_WELL_GROUP, "Gas Production Total above" } }, + { "GGPTB", { A::SUMMARY_WELL_GROUP, "Gas Production Total below" } }, + { "GGPR1", { A::SUMMARY_WELL_GROUP, "Gas Production Rate above GOC" } }, + { "GGPR2", { A::SUMMARY_WELL_GROUP, "Gas Production Rate below GOC" } }, + { "GGPT1", { A::SUMMARY_WELL_GROUP, "Gas Production Total above GOC" } }, + { "GGPT2", { A::SUMMARY_WELL_GROUP, "Gas Production Total below GOC" } }, + { "GGMR", { A::SUMMARY_WELL_GROUP, "Gas Mass Rate" } }, + { "GGMT", { A::SUMMARY_WELL_GROUP, "Gas Mass Total" } }, + { "GGDN", { A::SUMMARY_WELL_GROUP, "Gas Density at Surface Conditions" } }, + { "GGPRH", { A::SUMMARY_WELL_GROUP, "Gas Production Rate History" } }, + { "GGPRT", { A::SUMMARY_WELL_GROUP, "Gas Production Rate Target/Limit" } }, + { "GGPRL", { A::SUMMARY_WELL_GROUP, "Gas Production Rate Target/Limit" } }, + { "GGPRF", { A::SUMMARY_WELL_GROUP, "Free Gas Production Rate" } }, + { "GGPRS", { A::SUMMARY_WELL_GROUP, "Solution Gas Production Rate" } }, + { "GGPT", { A::SUMMARY_WELL_GROUP, "Gas Production Total" } }, + { "GGPTH", { A::SUMMARY_WELL_GROUP, "Gas Production Total History" } }, + { "GGPTF", { A::SUMMARY_WELL_GROUP, "Free Gas Production Total" } }, + { "GGPTS", { A::SUMMARY_WELL_GROUP, "Solution Gas Production Total" } }, + { "GGIR", { A::SUMMARY_WELL_GROUP, "Gas Injection Rate" } }, + { "GGIRH", { A::SUMMARY_WELL_GROUP, "Gas Injection Rate History" } }, + { "GGIRT", { A::SUMMARY_WELL_GROUP, "Gas Injection Rate Target/Limit" } }, + { "GGIRL", { A::SUMMARY_WELL_GROUP, "Gas Injection Rate Target/Limit" } }, + { "GGIT", { A::SUMMARY_WELL_GROUP, "Gas Injection Total" } }, + { "GGITH", { A::SUMMARY_WELL_GROUP, "Gas Injection Total History" } }, + { "GGPP", { A::SUMMARY_WELL_GROUP, "Gas Potential Production rate" } }, + { "GGPP2", { A::SUMMARY_WELL_GROUP, "Gas Potential Production rate" } }, + { "GGPPS", { A::SUMMARY_WELL_GROUP, "Solution" } }, + { "GGPPS2", { A::SUMMARY_WELL_GROUP, "Solution" } }, + { "GGPPF", { A::SUMMARY_WELL_GROUP, "Free Gas Potential Production rate" } }, + { "GGPPF2", { A::SUMMARY_WELL_GROUP, "Free Gas Potential Production rate" } }, + { "GGPI", { A::SUMMARY_WELL_GROUP, "Gas Potential Injection rate" } }, + { "GGPI2", { A::SUMMARY_WELL_GROUP, "Gas Potential Injection rate" } }, + { "GGPGR", { A::SUMMARY_WELL_GROUP, "Gas Production Guide Rate" } }, + { "GGIGR", { A::SUMMARY_WELL_GROUP, "Gas Injection Guide Rate" } }, + { "GSGR", { A::SUMMARY_WELL_GROUP, "Sales Gas Rate" } }, + { "GGSR", { A::SUMMARY_WELL_GROUP, "Sales Gas Rate" } }, + { "GSGT", { A::SUMMARY_WELL_GROUP, "Sales Gas Total" } }, + { "GGST", { A::SUMMARY_WELL_GROUP, "Sales Gas Total" } }, + { "GSMF", { A::SUMMARY_WELL_GROUP, "Sales Gas Mole Fraction" } }, + { "GFGR", { A::SUMMARY_WELL_GROUP, "Fuel Gas Rate, at and below this group" } }, + { "GFGT", { A::SUMMARY_WELL_GROUP, "Fuel Gas cumulative Total, at and below this group" } }, + { "GFMF", { A::SUMMARY_WELL_GROUP, "Fuel Gas Mole Fraction" } }, + { "GGCR", { A::SUMMARY_WELL_GROUP, "Gas Consumption Rate, at and below this group" } }, + { "GGCT", { A::SUMMARY_WELL_GROUP, "Gas Consumption Total, at and below this group" } }, + { "GGIMR", { A::SUMMARY_WELL_GROUP, "Gas Import Rate, at and below this group" } }, + { "GGIMT", { A::SUMMARY_WELL_GROUP, "Gas Import Total, at and below this group" } }, + { "GGLIR", { A::SUMMARY_WELL_GROUP, "Gas Lift Injection Rate" } }, + { "GWGPR", { A::SUMMARY_WELL_GROUP, "Wet Gas Production Rate" } }, + { "GWGPT", { A::SUMMARY_WELL_GROUP, "Wet Gas Production Total" } }, + { "GWGPRH", { A::SUMMARY_WELL_GROUP, "Wet Gas Production Rate History" } }, + { "GWGIR", { A::SUMMARY_WELL_GROUP, "Wet Gas Injection Rate" } }, + { "GWGIT", { A::SUMMARY_WELL_GROUP, "Wet Gas Injection Total" } }, + { "GEGR", { A::SUMMARY_WELL_GROUP, "Export Gas Rate" } }, + { "GEGT", { A::SUMMARY_WELL_GROUP, "Export Gas Total" } }, + { "GEMF", { A::SUMMARY_WELL_GROUP, "Export Gas Mole Fraction" } }, + { "GEXGR", { A::SUMMARY_WELL_GROUP, "Excess Gas Rate" } }, + { "GEXGT", { A::SUMMARY_WELL_GROUP, "Excess Gas Total" } }, + { "GRGR", { A::SUMMARY_WELL_GROUP, "Re-injection Gas Rate" } }, + { "GRGT", { A::SUMMARY_WELL_GROUP, "Re-injection Gas Total" } }, + { "GGnPR", { A::SUMMARY_WELL_GROUP, "nth separator stage gas rate" } }, + { "GGnPT", { A::SUMMARY_WELL_GROUP, "nth separator stage gas total" } }, + { "GGVPR", { A::SUMMARY_WELL_GROUP, "Gas Voidage Production Rate" } }, + { "GGVPT", { A::SUMMARY_WELL_GROUP, "Gas Voidage Production Total" } }, + { "GGVIR", { A::SUMMARY_WELL_GROUP, "Gas Voidage Injection Rate" } }, + { "GGVIT", { A::SUMMARY_WELL_GROUP, "Gas Voidage Injection Total" } }, + { "GGQ", { A::SUMMARY_WELL_GROUP, "Gas Quality" } }, + { "GLPR", { A::SUMMARY_WELL_GROUP, "Liquid Production Rate" } }, + { "GLPRH", { A::SUMMARY_WELL_GROUP, "Liquid Production Rate History" } }, + { "GLPRT", { A::SUMMARY_WELL_GROUP, "Liquid Production Rate Target/Limit" } }, + { "GLPRL", { A::SUMMARY_WELL_GROUP, "Liquid Production Rate Target/Limit" } }, + { "GLPT", { A::SUMMARY_WELL_GROUP, "Liquid Production Total" } }, + { "GLPTH", { A::SUMMARY_WELL_GROUP, "Liquid Production Total History" } }, + { "GVPR", { A::SUMMARY_WELL_GROUP, "Res Volume Production Rate" } }, + { "GVPRT", { A::SUMMARY_WELL_GROUP, "Res Volume Production Rate Target/Limit" } }, + { "GVPRL", { A::SUMMARY_WELL_GROUP, "Res Volume Production Rate Target/Limit" } }, + { "GVPT", { A::SUMMARY_WELL_GROUP, "Res Volume Production Total" } }, + { "GVPGR", { A::SUMMARY_WELL_GROUP, "Res Volume Production Guide Rate" } }, + { "GVIR", { A::SUMMARY_WELL_GROUP, "Res Volume Injection Rate" } }, + { "GVIRT", { A::SUMMARY_WELL_GROUP, "Res Volume Injection Rate Target/Limit" } }, + { "GVIRL", { A::SUMMARY_WELL_GROUP, "Res Volume Injection Rate Target/Limit" } }, + { "GVIT", { A::SUMMARY_WELL_GROUP, "Res Volume Injection Total" } }, + { "GWCT", { A::SUMMARY_WELL_GROUP, "Water Cut" } }, + { "GWCTH", { A::SUMMARY_WELL_GROUP, "Water Cut History" } }, + { "GGOR", { A::SUMMARY_WELL_GROUP, "Gas-Oil Ratio" } }, + { "GGORH", { A::SUMMARY_WELL_GROUP, "Gas-Oil Ratio History" } }, + { "GOGR", { A::SUMMARY_WELL_GROUP, "Oil-Gas Ratio" } }, + { "GOGRH", { A::SUMMARY_WELL_GROUP, "Oil-Gas Ratio History" } }, + { "GWGR", { A::SUMMARY_WELL_GROUP, "Water-Gas Ratio" } }, + { "GWGRH", { A::SUMMARY_WELL_GROUP, "Water-Gas Ratio History" } }, + { "GGLR", { A::SUMMARY_WELL_GROUP, "Gas-Liquid Ratio" } }, + { "GGLRH", { A::SUMMARY_WELL_GROUP, "Gas-Liquid Ratio History" } }, + { "GMCTP", { A::SUMMARY_WELL_GROUP, "Mode of Control for group Production" } }, + { "GMCTW", { A::SUMMARY_WELL_GROUP, "Mode of Control for group Water Injection" } }, + { "GMCTG", { A::SUMMARY_WELL_GROUP, "Mode of Control for group Gas Injection" } }, + { "GMWPT", { A::SUMMARY_WELL_GROUP, "Total number of production wells" } }, + { "GMWPR", { A::SUMMARY_WELL_GROUP, "Number of production wells currently flowing" } }, + { "GMWPA", { A::SUMMARY_WELL_GROUP, "Number of abandoned production wells" } }, + { "GMWPU", { A::SUMMARY_WELL_GROUP, "Number of unused production wells" } }, + { "GMWPG", { A::SUMMARY_WELL_GROUP, "Number of producers on group control" } }, + { "GMWPO", { A::SUMMARY_WELL_GROUP, "Number of producers controlled by own oil rate limit" } }, + { "GMWPS", { A::SUMMARY_WELL_GROUP, "Number of producers on own surface rate limit control" } }, + { "GMWPV", { A::SUMMARY_WELL_GROUP, "Number of producers on own reservoir volume rate limit control" } }, + { "GMWPP", { A::SUMMARY_WELL_GROUP, "Number of producers on pressure control" } }, + { "GMWPL", { A::SUMMARY_WELL_GROUP, "Number of producers using artificial lift" } }, + { "GMWIT", { A::SUMMARY_WELL_GROUP, "Total number of injection wells" } }, + { "GMWIN", { A::SUMMARY_WELL_GROUP, "Number of injection wells currently flowing" } }, + { "GMWIA", { A::SUMMARY_WELL_GROUP, "Number of abandoned injection wells" } }, + { "GMWIU", { A::SUMMARY_WELL_GROUP, "Number of unused injection wells" } }, + { "GMWIG", { A::SUMMARY_WELL_GROUP, "Number of injectors on group control" } }, + { "GMWIS", { A::SUMMARY_WELL_GROUP, "Number of injectors on own surface rate limit control" } }, + { "GMWIV", { A::SUMMARY_WELL_GROUP, "Number of injectors on own reservoir volume rate limit control" } }, + { "GMWIP", { A::SUMMARY_WELL_GROUP, "Number of injectors on pressure control" } }, + { "GMWDR", { A::SUMMARY_WELL_GROUP, "Number of drilling events this timestep" } }, + { "GMWDT", { A::SUMMARY_WELL_GROUP, "Number of drilling events in total" } }, + { "GMWWO", { A::SUMMARY_WELL_GROUP, "Number of workover events this timestep" } }, + { "GMWWT", { A::SUMMARY_WELL_GROUP, "Number of workover events in total" } }, + { "GEPR", { A::SUMMARY_WELL_GROUP, "Energy Production Rate" } }, + { "GEPT", { A::SUMMARY_WELL_GROUP, "Energy Production Total" } }, + { "GEFF", { A::SUMMARY_WELL_GROUP, "Efficiency Factor" } }, + { "GNLPR", { A::SUMMARY_WELL_GROUP, "NGL Production Rate" } }, + { "GNLPT", { A::SUMMARY_WELL_GROUP, "NGL Production Total" } }, + { "GNLPRH", { A::SUMMARY_WELL_GROUP, "NGL Production Rate History" } }, + { "GNLPTH", { A::SUMMARY_WELL_GROUP, "NGL Production Total History" } }, + { "GAMF", { A::SUMMARY_WELL_GROUP, "Component aqueous mole fraction, from producing completions" } }, + { "GXMF", { A::SUMMARY_WELL_GROUP, "Liquid Mole Fraction" } }, + { "GYMF", { A::SUMMARY_WELL_GROUP, "Vapor Mole Fraction" } }, + { "GXMFn", { A::SUMMARY_WELL_GROUP, "Liquid Mole Fraction for nth separator stage" } }, + { "GYMFn", { A::SUMMARY_WELL_GROUP, "Vapor Mole Fraction for nth separator stage" } }, + { "GZMF", { A::SUMMARY_WELL_GROUP, "Total Mole Fraction" } }, + { "GCMPR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Component Molar Production Rates" } }, + { "GCMPT", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Component" } }, + { "GCMIR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Component Molar Injection Rates" } }, + { "GCMIT", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Component Molar Injection Totals" } }, + { "GHMIR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Molar Injection Rate" } }, + { "GHMIT", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Molar Injection Total" } }, + { "GHMPR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Molar Production Rate" } }, + { "GHMPT", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Molar Production Total" } }, + { "GCHMR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Component" } }, + { "GCHMT", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Component" } }, + { "GCWGPR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Component Wet Gas Production Rate" } }, + { "GCWGPT", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Component Wet Gas Production Total" } }, + { "GCWGIR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Component Wet Gas Injection Rate" } }, + { "GCWGIT", { A::SUMMARY_WELL_GROUP, "Hydrocarbon Component Wet Gas Injection Total" } }, + { "GCGMR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component" } }, + { "GCGMT", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component" } }, + { "GCOMR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component" } }, + { "GCOMT", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component" } }, + { "GCNMR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component molar rates in the NGL phase" } }, + { "GCNWR", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component mass rates in the NGL phase" } }, + { "GCGMRn", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component molar rates in the gas phase for nth separator stage" } }, + { "GCGRn", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component molar rates in the gas phase for nth separator stage" } }, + { "GCOMRn", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component" } }, + { "GCORn", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component" } }, + { "GMUF", { A::SUMMARY_WELL_GROUP, "Make-up fraction" } }, + { "GAMR", { A::SUMMARY_WELL_GROUP, "Make-up gas rate" } }, + { "GAMT", { A::SUMMARY_WELL_GROUP, "Make-up gas total" } }, + { "GGSPR", { A::SUMMARY_WELL_GROUP, "Target sustainable rate for most recent sustainable capacity test for gas" } }, + { "GGSRL", { A::SUMMARY_WELL_GROUP, "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for gas" } }, + { "GGSRU", { A::SUMMARY_WELL_GROUP, "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for gas" } }, + { "GGSSP", { A::SUMMARY_WELL_GROUP, "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for gas" } }, + { "GGSTP", { A::SUMMARY_WELL_GROUP, "Test period for the most recent sustainable capacity test for gas" } }, + { "GOSPR", { A::SUMMARY_WELL_GROUP, "Target sustainable rate for most recent sustainable capacity test for oil" } }, + { "GOSRL", { A::SUMMARY_WELL_GROUP, "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for oil" } }, + { "GOSRU", { A::SUMMARY_WELL_GROUP, "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for oil" } }, + { "GOSSP", { A::SUMMARY_WELL_GROUP, "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for oil" } }, + { "GOSTP", { A::SUMMARY_WELL_GROUP, "Test period for the most recent sustainable capacity test for oil" } }, + { "GWSPR", { A::SUMMARY_WELL_GROUP, "Target sustainable rate for most recent sustainable capacity test for water" } }, + { "GWSRL", { A::SUMMARY_WELL_GROUP, "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for water" } }, + { "GWSRU", { A::SUMMARY_WELL_GROUP, "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for water" } }, + { "GWSSP", { A::SUMMARY_WELL_GROUP, "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for water" } }, + { "GWSTP", { A::SUMMARY_WELL_GROUP, "Test period for the most recent sustainable capacity test for water" } }, + { "GGPRG", { A::SUMMARY_WELL_GROUP, "Gas production rate" } }, + { "GOPRG", { A::SUMMARY_WELL_GROUP, "Oil production rate" } }, + { "GNLPRG", { A::SUMMARY_WELL_GROUP, "NGL production rate" } }, + { "GXMFG", { A::SUMMARY_WELL_GROUP, "Liquid mole fraction" } }, + { "GYMFG", { A::SUMMARY_WELL_GROUP, "Vapor mole fraction" } }, + { "GCOMRG", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component" } }, + { "GCGMRG", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component molar rates in the gas phase" } }, + { "GCNMRG", { A::SUMMARY_WELL_GROUP, "Hydrocarbon component molar rates in the NGL phase" } }, + { "GTPR", { A::SUMMARY_WELL_GROUP, "Tracer Production Rate" } }, + { "GTPT", { A::SUMMARY_WELL_GROUP, "Tracer Production Total" } }, + { "GTPC", { A::SUMMARY_WELL_GROUP, "Tracer Production Concentration" } }, + { "GTIR", { A::SUMMARY_WELL_GROUP, "Tracer Injection Rate" } }, + { "GTIT", { A::SUMMARY_WELL_GROUP, "Tracer Injection Total" } }, + { "GTIC", { A::SUMMARY_WELL_GROUP, "Tracer Injection Concentration" } }, + { "GTMR", { A::SUMMARY_WELL_GROUP, "Traced mass Rate" } }, + { "GTMT", { A::SUMMARY_WELL_GROUP, "Traced mass Total" } }, + { "GTQR", { A::SUMMARY_WELL_GROUP, "Traced molar Rate" } }, + { "GTCM", { A::SUMMARY_WELL_GROUP, "Tracer Carrier molar Rate" } }, + { "GTMF", { A::SUMMARY_WELL_GROUP, "Traced molar fraction" } }, + { "GTVL", { A::SUMMARY_WELL_GROUP, "Traced liquid volume rate" } }, + { "GTVV", { A::SUMMARY_WELL_GROUP, "Traced vapor volume rate" } }, + { "GTTL", { A::SUMMARY_WELL_GROUP, "Traced liquid volume total" } }, + { "GTTV", { A::SUMMARY_WELL_GROUP, "Traced vapor volume total" } }, + { "GTML", { A::SUMMARY_WELL_GROUP, "Traced mass liquid rate" } }, + { "GTMV", { A::SUMMARY_WELL_GROUP, "Traced mass vapor rate" } }, + { "GTLM", { A::SUMMARY_WELL_GROUP, "Traced mass liquid total" } }, + { "GTVM", { A::SUMMARY_WELL_GROUP, "Traced mass vapor total" } }, + { "GAPI", { A::SUMMARY_WELL_GROUP, "Oil API" } }, + { "GSPR", { A::SUMMARY_WELL_GROUP, "Salt Production Rate" } }, + { "GSPT", { A::SUMMARY_WELL_GROUP, "Salt Production Total" } }, + { "GSIR", { A::SUMMARY_WELL_GROUP, "Salt Injection Rate" } }, + { "GSIT", { A::SUMMARY_WELL_GROUP, "Salt Injection Total" } }, + { "GSPC", { A::SUMMARY_WELL_GROUP, "Salt Production Concentration" } }, + { "GSIC", { A::SUMMARY_WELL_GROUP, "Salt Injection Concentration" } }, + { "WTPRANI", { A::SUMMARY_WELL_GROUP, "Anion Production Rate" } }, + { "WTPTANI", { A::SUMMARY_WELL_GROUP, "Anion Production Total" } }, + { "WTIRANI", { A::SUMMARY_WELL_GROUP, "Anion Injection Rate" } }, + { "WTITANI", { A::SUMMARY_WELL_GROUP, "Anion Injection Total" } }, + { "WTPRCAT", { A::SUMMARY_WELL_GROUP, "Cation Production Rate" } }, + { "WTPTCAT", { A::SUMMARY_WELL_GROUP, "Cation Production Total" } }, + { "WTIRCAT", { A::SUMMARY_WELL_GROUP, "Cation Injection Rate" } }, + { "WTITCAT", { A::SUMMARY_WELL_GROUP, "Cation Injection Total" } }, + { "GTPCHEA", { A::SUMMARY_WELL_GROUP, "Production Temperature" } }, + { "GTICHEA", { A::SUMMARY_WELL_GROUP, "Injection Temperature" } }, + { "GTPRHEA", { A::SUMMARY_WELL_GROUP, "Energy flows" } }, + { "GTPTHEA", { A::SUMMARY_WELL_GROUP, "Energy Production Total" } }, + { "GTIRHEA", { A::SUMMARY_WELL_GROUP, "Energy flows" } }, + { "GTITHEA", { A::SUMMARY_WELL_GROUP, "Energy Injection Total" } }, + { "GTPR", { A::SUMMARY_WELL_GROUP, "Tracer Production Rate" } }, + { "GTPT", { A::SUMMARY_WELL_GROUP, "Tracer Production Total" } }, + { "GTPC", { A::SUMMARY_WELL_GROUP, "Tracer Production Concentration" } }, + { "GTIR", { A::SUMMARY_WELL_GROUP, "Tracer Injection Rate" } }, + { "GTIT", { A::SUMMARY_WELL_GROUP, "Tracer Injection Total" } }, + { "GTIC", { A::SUMMARY_WELL_GROUP, "Tracer Injection Concentration" } }, + { "GTIRF", { A::SUMMARY_WELL_GROUP, "Tracer Injection Rate" } }, + { "GTIRS", { A::SUMMARY_WELL_GROUP, "Tracer Injection Rate" } }, + { "GTPRF", { A::SUMMARY_WELL_GROUP, "Tracer Production Rate" } }, + { "GTPRS", { A::SUMMARY_WELL_GROUP, "Tracer Production Rate" } }, + { "GTITF", { A::SUMMARY_WELL_GROUP, "Tracer Injection Total" } }, + { "GTITS", { A::SUMMARY_WELL_GROUP, "Tracer Injection Total" } }, + { "GTPTF", { A::SUMMARY_WELL_GROUP, "Tracer Production Total" } }, + { "GTPTS", { A::SUMMARY_WELL_GROUP, "Tracer Production Total" } }, + { "GTICF", { A::SUMMARY_WELL_GROUP, "Tracer Injection Concentration" } }, + { "GTICS", { A::SUMMARY_WELL_GROUP, "Tracer Injection Concentration" } }, + { "GTPCF", { A::SUMMARY_WELL_GROUP, "Tracer Production" } }, + { "GTPCS", { A::SUMMARY_WELL_GROUP, "Tracer Production" } }, + { "GMPR", { A::SUMMARY_WELL_GROUP, "Methane Production Rate" } }, + { "GMPT", { A::SUMMARY_WELL_GROUP, "Methane Production Total" } }, + { "GMIR", { A::SUMMARY_WELL_GROUP, "Methane Injection Rate" } }, + { "GMIT", { A::SUMMARY_WELL_GROUP, "Methane Injection Total" } }, + { "GTPRFOA", { A::SUMMARY_WELL_GROUP, "Production Rate" } }, + { "GTPTFOA", { A::SUMMARY_WELL_GROUP, "Production Total" } }, + { "GTIRFOA", { A::SUMMARY_WELL_GROUP, "Injection Rate" } }, + { "GTITFOA", { A::SUMMARY_WELL_GROUP, "Injection Total" } }, + { "GSGR", { A::SUMMARY_WELL_GROUP, "Sales Gas Rate" } }, + { "GGSR", { A::SUMMARY_WELL_GROUP, "Sales Gas Rate" } }, + { "GSGT", { A::SUMMARY_WELL_GROUP, "Sales Gas Total" } }, + { "GGST", { A::SUMMARY_WELL_GROUP, "Sales Gas Total" } }, + { "GGDC", { A::SUMMARY_WELL_GROUP, "Gas Delivery Capacity" } }, + { "GGDCQ", { A::SUMMARY_WELL_GROUP, "Field/Group Gas DCQ" } }, + { "GMCPL", { A::SUMMARY_WELL_GROUP, "Group Multi-level Compressor Level" } }, + { "GPR", { A::SUMMARY_WELL_GROUP, "Group nodal Pressure in network" } }, + { "GPRDC", { A::SUMMARY_WELL_GROUP, "Group Pressure at Delivery Capacity" } }, + { "GGCR", { A::SUMMARY_WELL_GROUP, "Gas consumption rate, at and below this group" } }, + { "GGCT", { A::SUMMARY_WELL_GROUP, "Gas consumption cumulative total, at and below this group" } }, + { "GFGR", { A::SUMMARY_WELL_GROUP, "Fuel Gas rate, at and below this group" } }, + { "GFGT", { A::SUMMARY_WELL_GROUP, "Fuel Gas cumulative total, at and below this group" } }, + { "GGIMR", { A::SUMMARY_WELL_GROUP, "Gas import rate, at and below this group" } }, + { "GGIMT", { A::SUMMARY_WELL_GROUP, "Gas import cumulative total, at and below this group" } }, + { "GPRFP", { A::SUMMARY_WELL_GROUP, "Group or node Pressure in network from end of First Pass" } }, + { "GGPRNBFP", { A::SUMMARY_WELL_GROUP, "Gas flow rate along Group’s or node’s outlet branch in network, from end of First Pass" } }, + { "GGLIR", { A::SUMMARY_WELL_GROUP, "Gas Lift Injection Rate" } }, + { "GGCV", { A::SUMMARY_WELL_GROUP, "Gas Calorific Value" } }, + { "GGQ", { A::SUMMARY_WELL_GROUP, "Gas molar Quality" } }, + { "GEPR", { A::SUMMARY_WELL_GROUP, "Energy Production Rate" } }, + { "GEPT", { A::SUMMARY_WELL_GROUP, "Energy Production Total" } }, + { "GESR", { A::SUMMARY_WELL_GROUP, "Energy Sales Rate" } }, + { "GEST", { A::SUMMARY_WELL_GROUP, "Energy Sales Total" } }, + { "GEDC", { A::SUMMARY_WELL_GROUP, "Energy Delivery Capacity" } }, + { "GEDCQ", { A::SUMMARY_WELL_GROUP, "Energy DCQ" } }, + { "GPR", { A::SUMMARY_WELL_GROUP, "Group or node Pressure in the production network" } }, + { "GPRG", { A::SUMMARY_WELL_GROUP, "Group or node Pressure in the gas injection network" } }, + { "GPRW", { A::SUMMARY_WELL_GROUP, "Group or node Pressure in the water injection network" } }, + { "GPRB", { A::SUMMARY_WELL_GROUP, "Pressure drop along the group’s or node’s outlet branch in the production network" } }, + { "GPRBG", { A::SUMMARY_WELL_GROUP, "Pressure drop along the group’s or node’s inlet branch in the gas injection network" } }, + { "GPRBW", { A::SUMMARY_WELL_GROUP, "Pressure drop along the group’s or node’s inlet branch in the water injection network" } }, + { "GALQ", { A::SUMMARY_WELL_GROUP, "ALQ in the group’s or node’s outlet branch in the production network" } }, + { "GOPRNB", { A::SUMMARY_WELL_GROUP, "Oil flow rate along the group’s or node’s outlet branch in the production network" } }, + { "GWPRNB", { A::SUMMARY_WELL_GROUP, "Water flow rate along the group’s or node’s outlet branch in the production network" } }, + { "GGPRNB", { A::SUMMARY_WELL_GROUP, "Gas flow rate along the group’s or node’s outlet branch in the production network" } }, + { "GLPRNB", { A::SUMMARY_WELL_GROUP, "Liquid flow rate along the group’s or node’s outlet branch in the production network" } }, + { "GWIRNB", { A::SUMMARY_WELL_GROUP, "Water flow rate along the group’s or node’s inlet branch in the water injection network" } }, + { "GGIRNB", { A::SUMMARY_WELL_GROUP, "Gas flow rate along the group’s or node’s inlet branch in the gas injection network" } }, + { "GOMNR", { A::SUMMARY_WELL_GROUP, "Group or node minimum oil rate as specified with GNETDP in the production network" } }, + { "GGMNR", { A::SUMMARY_WELL_GROUP, "Group or node minimum gas rate as specified with GNETDP in the production network" } }, + { "GWMNR", { A::SUMMARY_WELL_GROUP, "Group or node minimum water rate as specified with GNETDP in the production network" } }, + { "GLMNR", { A::SUMMARY_WELL_GROUP, "Group or node minimum liquid rate as specified with GNETDP in the production network" } }, + { "GOMXR", { A::SUMMARY_WELL_GROUP, "Group or node maximum oil rate as specified with GNETDP in the production network" } }, + { "GGMXR", { A::SUMMARY_WELL_GROUP, "Group or node maximum gas rate as specified with GNETDP in the production network" } }, + { "GWMXR", { A::SUMMARY_WELL_GROUP, "Group or node maximum water rate as specified with GNETDP in the production network" } }, + { "GLMXR", { A::SUMMARY_WELL_GROUP, "Group or node maximum liquid rate as specified with GNETDP in the production network" } }, + { "GMNP", { A::SUMMARY_WELL_GROUP, "Group or node minimum pressure as specified with GNETDP in the production network" } }, + { "GMXP", { A::SUMMARY_WELL_GROUP, "Group or node maximum pressure as specified with GNETDP in the production network" } }, + { "GPRINC", { A::SUMMARY_WELL_GROUP, "Group or node pressure increment as specified with GNETDP in the production network" } }, + { "GPRDEC", { A::SUMMARY_WELL_GROUP, "Group or node pressure decrement as specified with GNETDP in the production network" } }, + { "GCPR", { A::SUMMARY_WELL_GROUP, "Polymer Production Rate" } }, + { "GCPC", { A::SUMMARY_WELL_GROUP, "Polymer Production Concentration" } }, + { "GCPT", { A::SUMMARY_WELL_GROUP, "Polymer Production Total" } }, + { "GCIR", { A::SUMMARY_WELL_GROUP, "Polymer Injection Rate" } }, + { "GCIC", { A::SUMMARY_WELL_GROUP, "Polymer Injection Concentration" } }, + { "GCIT", { A::SUMMARY_WELL_GROUP, "Polymer Injection Total" } }, + { "GSPR", { A::SUMMARY_WELL_GROUP, "Salt Production Rate" } }, + { "GSPT", { A::SUMMARY_WELL_GROUP, "Salt Production Total" } }, + { "GSIR", { A::SUMMARY_WELL_GROUP, "Salt Injection Rate" } }, + { "GSIT", { A::SUMMARY_WELL_GROUP, "Salt Injection Total" } }, + { "GOPRL", { A::SUMMARY_WELL_GROUP, "Group Oil Production Rate Target" } }, + { "GOIRL", { A::SUMMARY_WELL_GROUP, "Group Oil Injection Rate Target" } }, + { "GWPRL", { A::SUMMARY_WELL_GROUP, "Group Water Production Rate Target" } }, + { "GWIRL", { A::SUMMARY_WELL_GROUP, "Group Water Injection Rate Target" } }, + { "GGPRL", { A::SUMMARY_WELL_GROUP, "Group Gas Production Rate Target" } }, + { "GGIRL", { A::SUMMARY_WELL_GROUP, "Group Gas Injection Rate Target" } }, + { "GLPRL", { A::SUMMARY_WELL_GROUP, "Group Liquid Production Rate Target" } }, + { "GVPRL", { A::SUMMARY_WELL_GROUP, "Group reservoir Volume Production Rate Target" } }, + { "GVIRL", { A::SUMMARY_WELL_GROUP, "Group reservoir Volume Injection Rate Target" } }, + { "GNPR", { A::SUMMARY_WELL_GROUP, "Solvent Production Rate" } }, + { "GNPT", { A::SUMMARY_WELL_GROUP, "Solvent Production Total" } }, + { "GNIR", { A::SUMMARY_WELL_GROUP, "Solvent Injection Rate" } }, + { "GNIT", { A::SUMMARY_WELL_GROUP, "Solvent Injection Total" } }, + { "GTPRSUR", { A::SUMMARY_WELL_GROUP, "Production Rate" } }, + { "GTPTSUR", { A::SUMMARY_WELL_GROUP, "Production Total" } }, + { "GTIRSUR", { A::SUMMARY_WELL_GROUP, "Injection Rate" } }, + { "GTITSUR", { A::SUMMARY_WELL_GROUP, "Injection Total" } }, + { "GTPRALK", { A::SUMMARY_WELL_GROUP, "Production Rate" } }, + { "GTPTALK", { A::SUMMARY_WELL_GROUP, "Production Total" } }, + { "GTIRALK", { A::SUMMARY_WELL_GROUP, "Injection Rate" } }, + { "GTITALK", { A::SUMMARY_WELL_GROUP, "Injection Total" } }, + { "GU", { A::SUMMARY_WELL_GROUP, "User-defined group quantity" } }, + + { "WOPR", { A::SUMMARY_WELL, "Oil Production Rate" } }, + { "WOPRA", { A::SUMMARY_WELL, "Oil Production Rate above GOC" } }, + { "WOPRB", { A::SUMMARY_WELL, "Oil Production Rate below GOC" } }, + { "WOPTA", { A::SUMMARY_WELL, "Oil Production Total above GOC" } }, + { "WOPTB", { A::SUMMARY_WELL, "Oil Production Total below GOC" } }, + { "WOPR1", { A::SUMMARY_WELL, "Oil Production Rate above GOC" } }, + { "WOPR2", { A::SUMMARY_WELL, "Oil Production Rate below GOC" } }, + { "WOPT1", { A::SUMMARY_WELL, "Oil Production Total above GOC" } }, + { "WOPT2", { A::SUMMARY_WELL, "Oil Production Total below GOC" } }, + { "WOMR", { A::SUMMARY_WELL, "Oil Mass Rate" } }, + { "WOMT", { A::SUMMARY_WELL, "Oil Mass Total" } }, + { "WODN", { A::SUMMARY_WELL, "Oil Density at Surface Conditions" } }, + { "WOPRH", { A::SUMMARY_WELL, "Oil Production Rate History" } }, + { "WOPRT", { A::SUMMARY_WELL, "Oil Production Rate Target/Limit" } }, + { "WOPRF", { A::SUMMARY_WELL, "Free Oil Production Rate" } }, + { "WOPRS", { A::SUMMARY_WELL, "Solution Oil Production Rate" } }, + { "WOPT", { A::SUMMARY_WELL, "Oil Production Total" } }, + { "WOPTH", { A::SUMMARY_WELL, "Oil Production Total History" } }, + { "WOPTF", { A::SUMMARY_WELL, "Free Oil Production Total" } }, + { "WOPTS", { A::SUMMARY_WELL, "Solution Oil Production Total" } }, + { "WOIR", { A::SUMMARY_WELL, "Oil Injection Rate" } }, + { "WOIRH", { A::SUMMARY_WELL, "Oil Injection Rate History" } }, + { "WOIRT", { A::SUMMARY_WELL, "Oil Injection Rate Target/Limit" } }, + { "WOIT", { A::SUMMARY_WELL, "Oil Injection Total" } }, + { "WOITH", { A::SUMMARY_WELL, "Oil Injection Total History" } }, + { "WOPP", { A::SUMMARY_WELL, "Oil Potential Production rate" } }, + { "WOPP2", { A::SUMMARY_WELL, "Oil Potential Production rate" } }, + { "WOPI", { A::SUMMARY_WELL, "Oil Potential Injection rate" } }, + { "WOPI2", { A::SUMMARY_WELL, "Oil Potential Injection rate" } }, + { "WOPGR", { A::SUMMARY_WELL, "Oil Production Guide Rate" } }, + { "WOIGR", { A::SUMMARY_WELL, "Oil Injection Guide Rate" } }, + { "WOVPR", { A::SUMMARY_WELL, "Oil Voidage Production Rate" } }, + { "WOVPT", { A::SUMMARY_WELL, "Oil Voidage Production Total" } }, + { "WOVIR", { A::SUMMARY_WELL, "Oil Voidage Injection Rate" } }, + { "WOVIT", { A::SUMMARY_WELL, "Oil Voidage Injection Total" } }, + { "WOnPR", { A::SUMMARY_WELL, "nth separator stage oil rate" } }, + { "WOnPT", { A::SUMMARY_WELL, "nth separator stage oil total" } }, + { "WWPR", { A::SUMMARY_WELL, "Water Production Rate" } }, + { "WWMR", { A::SUMMARY_WELL, "Water Mass Rate" } }, + { "WWMT", { A::SUMMARY_WELL, "Water Mass Total" } }, + { "WWPRH", { A::SUMMARY_WELL, "Water Production Rate History" } }, + { "WWPRT", { A::SUMMARY_WELL, "Water Production Rate Target/Limit" } }, + { "WWPT", { A::SUMMARY_WELL, "Water Production Total" } }, + { "WWPTH", { A::SUMMARY_WELL, "Water Production Total History" } }, + { "WWIR", { A::SUMMARY_WELL, "Water Injection Rate" } }, + { "WWIRH", { A::SUMMARY_WELL, "Water Injection Rate History" } }, + { "WWIRT", { A::SUMMARY_WELL, "Water Injection Rate Target/Limit" } }, + { "WWIT", { A::SUMMARY_WELL, "Water Injection Total" } }, + { "WWITH", { A::SUMMARY_WELL, "Water Injection Total History" } }, + { "WWPP", { A::SUMMARY_WELL, "Water Potential Production rate" } }, + { "WWPP2", { A::SUMMARY_WELL, "Water Potential Production rate" } }, + { "WWPI", { A::SUMMARY_WELL, "Water Potential Injection rate" } }, + { "WWIP", { A::SUMMARY_WELL, "Water Potential Injection rate" } }, + { "WWPI2", { A::SUMMARY_WELL, "Water Potential Injection rate" } }, + { "WWIP2", { A::SUMMARY_WELL, "Water Potential Injection rate" } }, + { "WWPGR", { A::SUMMARY_WELL, "Water Production Guide Rate" } }, + { "WWIGR", { A::SUMMARY_WELL, "Water Injection Guide Rate" } }, + { "WWVPR", { A::SUMMARY_WELL, "Water Voidage Production Rate" } }, + { "WWVPT", { A::SUMMARY_WELL, "Water Voidage Production Total" } }, + { "WWVIR", { A::SUMMARY_WELL, "Water Voidage Injection Rate" } }, + { "WWVIT", { A::SUMMARY_WELL, "Water Voidage Injection Total" } }, + { "WWPIR", { A::SUMMARY_WELL, "Ratio of produced water to injected water (percentage)" } }, + { "WWMPR", { A::SUMMARY_WELL, "Water component molar production rate" } }, + { "WWMPT", { A::SUMMARY_WELL, "Water component molar production total" } }, + { "WWMIR", { A::SUMMARY_WELL, "Water component molar injection rate" } }, + { "WWMIT", { A::SUMMARY_WELL, "Water component molar injection total" } }, + { "WGPR", { A::SUMMARY_WELL, "Gas Production Rate" } }, + { "WGPRA", { A::SUMMARY_WELL, "Gas Production Rate above" } }, + { "WGPRB", { A::SUMMARY_WELL, "Gas Production Rate below" } }, + { "WGPTA", { A::SUMMARY_WELL, "Gas Production Total above" } }, + { "WGPTB", { A::SUMMARY_WELL, "Gas Production Total below" } }, + { "WGPR1", { A::SUMMARY_WELL, "Gas Production Rate above GOC" } }, + { "WGPR2", { A::SUMMARY_WELL, "Gas Production Rate below GOC" } }, + { "WGPT1", { A::SUMMARY_WELL, "Gas Production Total above GOC" } }, + { "WGPT2", { A::SUMMARY_WELL, "Gas Production Total below GOC" } }, + { "WGMR", { A::SUMMARY_WELL, "Gas Mass Rate" } }, + { "WGMT", { A::SUMMARY_WELL, "Gas Mass Total" } }, + { "WGDN", { A::SUMMARY_WELL, "Gas Density at Surface Conditions" } }, + { "WGPRH", { A::SUMMARY_WELL, "Gas Production Rate History" } }, + { "WGPRT", { A::SUMMARY_WELL, "Gas Production Rate Target/Limit" } }, + { "WGPRF", { A::SUMMARY_WELL, "Free Gas Production Rate" } }, + { "WGPRS", { A::SUMMARY_WELL, "Solution Gas Production Rate" } }, + { "WGPT", { A::SUMMARY_WELL, "Gas Production Total" } }, + { "WGPTH", { A::SUMMARY_WELL, "Gas Production Total History" } }, + { "WGPTF", { A::SUMMARY_WELL, "Free Gas Production Total" } }, + { "WGPTS", { A::SUMMARY_WELL, "Solution Gas Production Total" } }, + { "WGIR", { A::SUMMARY_WELL, "Gas Injection Rate" } }, + { "WGIRH", { A::SUMMARY_WELL, "Gas Injection Rate History" } }, + { "WGIRT", { A::SUMMARY_WELL, "Gas Injection Rate Target/Limit" } }, + { "WGIT", { A::SUMMARY_WELL, "Gas Injection Total" } }, + { "WGITH", { A::SUMMARY_WELL, "Gas Injection Total History" } }, + { "WGPP", { A::SUMMARY_WELL, "Gas Potential Production rate" } }, + { "WGPP2", { A::SUMMARY_WELL, "Gas Potential Production rate" } }, + { "WGPPS", { A::SUMMARY_WELL, "Solution" } }, + { "WGPPS2", { A::SUMMARY_WELL, "Solution" } }, + { "WGPPF", { A::SUMMARY_WELL, "Free Gas Potential Production rate" } }, + { "WGPPF2", { A::SUMMARY_WELL, "Free Gas Potential Production rate" } }, + { "WGPI", { A::SUMMARY_WELL, "Gas Potential Injection rate" } }, + { "WGIP", { A::SUMMARY_WELL, "Gas Potential Injection rate" } }, + { "WGPI2", { A::SUMMARY_WELL, "Gas Potential Injection rate" } }, + { "WGIP2", { A::SUMMARY_WELL, "Gas Potential Injection rate" } }, + { "WGPGR", { A::SUMMARY_WELL, "Gas Production Guide Rate" } }, + { "WGIGR", { A::SUMMARY_WELL, "Gas Injection Guide Rate" } }, + { "WGLIR", { A::SUMMARY_WELL, "Gas Lift Injection Rate" } }, + { "WWGPR", { A::SUMMARY_WELL, "Wet Gas Production Rate" } }, + { "WWGPT", { A::SUMMARY_WELL, "Wet Gas Production Total" } }, + { "WWGPRH", { A::SUMMARY_WELL, "Wet Gas Production Rate History" } }, + { "WWGIR", { A::SUMMARY_WELL, "Wet Gas Injection Rate" } }, + { "WWGIT", { A::SUMMARY_WELL, "Wet Gas Injection Total" } }, + { "WGnPR", { A::SUMMARY_WELL, "nth separator stage gas rate" } }, + { "WGnPT", { A::SUMMARY_WELL, "nth separator stage gas total" } }, + { "WGVPR", { A::SUMMARY_WELL, "Gas Voidage Production Rate" } }, + { "WGVPT", { A::SUMMARY_WELL, "Gas Voidage Production Total" } }, + { "WGVIR", { A::SUMMARY_WELL, "Gas Voidage Injection Rate" } }, + { "WGVIT", { A::SUMMARY_WELL, "Gas Voidage Injection Total" } }, + { "WGQ", { A::SUMMARY_WELL, "Gas Quality" } }, + { "WLPR", { A::SUMMARY_WELL, "Liquid Production Rate" } }, + { "WLPRH", { A::SUMMARY_WELL, "Liquid Production Rate History" } }, + { "WLPRT", { A::SUMMARY_WELL, "Liquid Production Rate Target/Limit" } }, + { "WLPT", { A::SUMMARY_WELL, "Liquid Production Total" } }, + { "WLPTH", { A::SUMMARY_WELL, "Liquid Production Total History" } }, + { "WVPR", { A::SUMMARY_WELL, "Res Volume Production Rate" } }, + { "WVPRT", { A::SUMMARY_WELL, "Res Volume Production Rate Target/Limit" } }, + { "WVPT", { A::SUMMARY_WELL, "Res Volume Production Total" } }, + { "WVPGR", { A::SUMMARY_WELL, "Res Volume Production Guide Rate" } }, + { "WVIR", { A::SUMMARY_WELL, "Res Volume Injection Rate" } }, + { "WVIRT", { A::SUMMARY_WELL, "Res Volume Injection Rate Target/Limit" } }, + { "WVIT", { A::SUMMARY_WELL, "Res Volume Injection Total" } }, + { "WWCT", { A::SUMMARY_WELL, "Water Cut" } }, + { "WWCTH", { A::SUMMARY_WELL, "Water Cut History" } }, + { "WGOR", { A::SUMMARY_WELL, "Gas-Oil Ratio" } }, + { "WGORH", { A::SUMMARY_WELL, "Gas-Oil Ratio History" } }, + { "WOGR", { A::SUMMARY_WELL, "Oil-Gas Ratio" } }, + { "WOGRH", { A::SUMMARY_WELL, "Oil-Gas Ratio History" } }, + { "WWGR", { A::SUMMARY_WELL, "Water-Gas Ratio" } }, + { "WWGRH", { A::SUMMARY_WELL, "Water-Gas Ratio History" } }, + { "WGLR", { A::SUMMARY_WELL, "Gas-Liquid Ratio" } }, + { "WGLRH", { A::SUMMARY_WELL, "Gas-Liquid Ratio History" } }, + { "WBGLR", { A::SUMMARY_WELL, "Bottom hole Gas-Liquid Ratio" } }, + { "WBHP", { A::SUMMARY_WELL, "Bottom Hole Pressure" } }, + { "WBHPH", { A::SUMMARY_WELL, "Bottom Hole Pressure History," } }, + { "WBHPT", { A::SUMMARY_WELL, "Bottom Hole Pressure Target/Limit" } }, + { "WTHP", { A::SUMMARY_WELL, "Tubing Head Pressure" } }, + { "WTHPH", { A::SUMMARY_WELL, "Tubing Head Pressure History," } }, + { "WPI", { A::SUMMARY_WELL, "Productivity Index of well’s preferred phase" } }, + { "WPIO", { A::SUMMARY_WELL, "Oil phase PI" } }, + { "WPIG", { A::SUMMARY_WELL, "Gas phase PI" } }, + { "WPIW", { A::SUMMARY_WELL, "Water phase PI" } }, + { "WPIL", { A::SUMMARY_WELL, "Liquid phase PI" } }, + { "WBP", { A::SUMMARY_WELL, "One-point Pressure Average" } }, + { "WBP4", { A::SUMMARY_WELL, "Four-point Pressure Average" } }, + { "WBP5", { A::SUMMARY_WELL, "Five-point Pressure Average" } }, + { "WBP9", { A::SUMMARY_WELL, "Nine-point Pressure Average" } }, + { "WPI1", { A::SUMMARY_WELL, "Productivity Index based on the value of WBP" } }, + { "WPI4", { A::SUMMARY_WELL, "Productivity Index based on the value of WBP4" } }, + { "WPI5", { A::SUMMARY_WELL, "Productivity Index based on the value of WBP5" } }, + { "WPI9", { A::SUMMARY_WELL, "Productivity Index based on the value of WBP9" } }, + { "WHD", { A::SUMMARY_WELL, "Hydraulic head in well based on the reference depth given in HYDRHEAD and the well’s reference depth" } }, + { "WHDF", { A::SUMMARY_WELL, "Hydraulic head in well based on the reference depth given in HYDRHEAD and the well’s reference depth calculated at freshwater conditions" } }, + { "WSTAT", { A::SUMMARY_WELL, "Well State Indicator" } }, + { "WMCTL", { A::SUMMARY_WELL, "Mode of Control" } }, + { "WMCON", { A::SUMMARY_WELL, "The number of connections capable of flowing in the well" } }, + { "WEPR", { A::SUMMARY_WELL, "Energy Production Rate" } }, + { "WEPT", { A::SUMMARY_WELL, "Energy Production Total" } }, + { "WEFF", { A::SUMMARY_WELL, "Efficiency Factor" } }, + { "WEFFG", { A::SUMMARY_WELL, "Product of efficiency factors of the well and all its superior groups" } }, + { "WALQ", { A::SUMMARY_WELL, "Well Artificial Lift Quantity" } }, + { "WMVFP", { A::SUMMARY_WELL, "VFP table number used by the well" } }, + { "WNLPR", { A::SUMMARY_WELL, "NGL Production Rate" } }, + { "WNLPT", { A::SUMMARY_WELL, "NGL Production Total" } }, + { "WNLPRH", { A::SUMMARY_WELL, "NGL Production Rate History" } }, + { "WNLPTH", { A::SUMMARY_WELL, "NGL Production Total History" } }, + { "WNLPRT", { A::SUMMARY_WELL, "NGL Production Rate Target" } }, + { "WAMF", { A::SUMMARY_WELL, "Component aqueous mole fraction, from producing completions" } }, + { "WXMF", { A::SUMMARY_WELL, "Liquid Mole Fraction" } }, + { "WYMF", { A::SUMMARY_WELL, "Vapor Mole Fraction" } }, + { "WXMFn", { A::SUMMARY_WELL, "Liquid Mole Fraction for nth separator stage" } }, + { "WYMFn", { A::SUMMARY_WELL, "Vapor Mole Fraction for nth separator stage" } }, + { "WZMF", { A::SUMMARY_WELL, "Total Mole Fraction" } }, + { "WCMPR", { A::SUMMARY_WELL, "Hydrocarbon Component Molar Production Rates" } }, + { "WCMPT", { A::SUMMARY_WELL, "Hydrocarbon Component" } }, + { "WCMIR", { A::SUMMARY_WELL, "Hydrocarbon Component Molar Injection Rates" } }, + { "WCMIT", { A::SUMMARY_WELL, "Hydrocarbon Component Molar Injection Totals" } }, + { "WCGIR", { A::SUMMARY_WELL, "Hydrocarbon Component Gas Injection Rate" } }, + { "WCGPR", { A::SUMMARY_WELL, "Hydrocarbon Component Gas Production Rate" } }, + { "WCOPR", { A::SUMMARY_WELL, "Hydrocarbon Component Oil Production Rate" } }, + { "WHMIR", { A::SUMMARY_WELL, "Hydrocarbon Molar Injection Rate" } }, + { "WHMIT", { A::SUMMARY_WELL, "Hydrocarbon Molar Injection Total" } }, + { "WHMPR", { A::SUMMARY_WELL, "Hydrocarbon Molar Production Rate" } }, + { "WHMPT", { A::SUMMARY_WELL, "Hydrocarbon Molar Production Total" } }, + { "WCHMR", { A::SUMMARY_WELL, "Hydrocarbon Component" } }, + { "WCHMT", { A::SUMMARY_WELL, "Hydrocarbon Component" } }, + { "WCWGPR", { A::SUMMARY_WELL, "Hydrocarbon Component Wet Gas Production Rate" } }, + { "WCWGPT", { A::SUMMARY_WELL, "Hydrocarbon Component Wet Gas Production Total" } }, + { "WCWGIR", { A::SUMMARY_WELL, "Hydrocarbon Component Wet Gas Injection Rate" } }, + { "WCWGIT", { A::SUMMARY_WELL, "Hydrocarbon Component Wet Gas Injection Total" } }, + { "WCGMR", { A::SUMMARY_WELL, "Hydrocarbon component" } }, + { "WCGMT", { A::SUMMARY_WELL, "Hydrocarbon component" } }, + { "WCOMR", { A::SUMMARY_WELL, "Hydrocarbon component" } }, + { "WCOMT", { A::SUMMARY_WELL, "Hydrocarbon component" } }, + { "WCNMR", { A::SUMMARY_WELL, "Hydrocarbon component molar rates in the NGL phase" } }, + { "WCNWR", { A::SUMMARY_WELL, "Hydrocarbon component mass rates in the NGL phase" } }, + { "WCGMRn", { A::SUMMARY_WELL, "Hydrocarbon component molar rates in the gas phase for nth separator stage" } }, + { "WCGRn", { A::SUMMARY_WELL, "Hydrocarbon component molar rates in the gas phase for nth separator stage" } }, + { "WCOMRn", { A::SUMMARY_WELL, "Hydrocarbon component" } }, + { "WCORn", { A::SUMMARY_WELL, "Hydrocarbon component" } }, + { "WMUF", { A::SUMMARY_WELL, "Make-up fraction" } }, + { "WTHT", { A::SUMMARY_WELL, "Tubing Head Temperature" } }, + { "WMMW", { A::SUMMARY_WELL, "Mean molecular weight of wellstream" } }, + { "WPWE0", { A::SUMMARY_WELL, "Well drilled indicator" } }, + { "WPWE1", { A::SUMMARY_WELL, "Connections opened indicator" } }, + { "WPWE2", { A::SUMMARY_WELL, "Connections closed indicator" } }, + { "WPWE3", { A::SUMMARY_WELL, "Connections closed to bottom indicator" } }, + { "WPWE4", { A::SUMMARY_WELL, "Well stopped indicator" } }, + { "WPWE5", { A::SUMMARY_WELL, "Injector to producer indicator" } }, + { "WPWE6", { A::SUMMARY_WELL, "Producer to injector indicator" } }, + { "WPWE7", { A::SUMMARY_WELL, "Well shut indicator" } }, + { "WPWEM", { A::SUMMARY_WELL, "WELEVNT output mnemonic" } }, + { "WDRPR", { A::SUMMARY_WELL, "Well drilling priority" } }, + { "WBHWCn", { A::SUMMARY_WELL, "Derivative of well BHP with respect to parameter n" } }, + { "WGFWCn", { A::SUMMARY_WELL, "Derivative of well gas flow rate with respect to parameter n" } }, + { "WOFWCn", { A::SUMMARY_WELL, "Derivative of well oil flow rate with respect to parameter n" } }, + { "WWFWCn", { A::SUMMARY_WELL, "Derivative of water flow rate with respect to parameter n" } }, + { "WTPR", { A::SUMMARY_WELL, "Tracer Production Rate" } }, + { "WTPT", { A::SUMMARY_WELL, "Tracer Production Total" } }, + { "WTPC", { A::SUMMARY_WELL, "Tracer Production Concentration" } }, + { "WTIR", { A::SUMMARY_WELL, "Tracer Injection Rate" } }, + { "WTIT", { A::SUMMARY_WELL, "Tracer Injection Total" } }, + { "WTIC", { A::SUMMARY_WELL, "Tracer Injection Concentration" } }, + { "WTMR", { A::SUMMARY_WELL, "Traced mass Rate" } }, + { "WTMT", { A::SUMMARY_WELL, "Traced mass Total" } }, + { "WTQR", { A::SUMMARY_WELL, "Traced molar Rate" } }, + { "WTCM", { A::SUMMARY_WELL, "Tracer Carrier molar Rate" } }, + { "WTMF", { A::SUMMARY_WELL, "Traced molar fraction" } }, + { "WTVL", { A::SUMMARY_WELL, "Traced liquid volume rate" } }, + { "WTVV", { A::SUMMARY_WELL, "Traced vapor volume rate" } }, + { "WTTL", { A::SUMMARY_WELL, "Traced liquid volume total" } }, + { "WTTV", { A::SUMMARY_WELL, "Traced vapor volume total" } }, + { "WTML", { A::SUMMARY_WELL, "Traced mass liquid rate" } }, + { "WTMV", { A::SUMMARY_WELL, "Traced mass vapor rate" } }, + { "WTLM", { A::SUMMARY_WELL, "Traced mass liquid total" } }, + { "WTVM", { A::SUMMARY_WELL, "Traced mass vapor total" } }, + { "WAPI", { A::SUMMARY_WELL, "Oil API" } }, + { "WSPR", { A::SUMMARY_WELL, "Salt Production Rate" } }, + { "WSPT", { A::SUMMARY_WELL, "Salt Production Total" } }, + { "WSIR", { A::SUMMARY_WELL, "Salt Injection Rate" } }, + { "WSIT", { A::SUMMARY_WELL, "Salt Injection Total" } }, + { "WSPC", { A::SUMMARY_WELL, "Salt Production Concentration" } }, + { "WSIC", { A::SUMMARY_WELL, "Salt Injection Concentration" } }, + { "WTPCHEA", { A::SUMMARY_WELL, "Production Temperature" } }, + { "WTICHEA", { A::SUMMARY_WELL, "Injection Temperature" } }, + { "WTPRHEA", { A::SUMMARY_WELL, "Energy flows" } }, + { "WTPTHEA", { A::SUMMARY_WELL, "Energy Production Total" } }, + { "WTIRHEA", { A::SUMMARY_WELL, "Energy flows" } }, + { "WTITHEA", { A::SUMMARY_WELL, "Energy Injection Total" } }, + { "WTPR", { A::SUMMARY_WELL, "Tracer Production Rate" } }, + { "WTPT", { A::SUMMARY_WELL, "Tracer Production Total" } }, + { "WTPC", { A::SUMMARY_WELL, "Tracer Production Concentration" } }, + { "WTIR", { A::SUMMARY_WELL, "Tracer Injection Rate" } }, + { "WTIT", { A::SUMMARY_WELL, "Tracer Injection Total" } }, + { "WTIC", { A::SUMMARY_WELL, "Tracer Injection Concentration" } }, + { "WTIRF", { A::SUMMARY_WELL, "Tracer Injection Rate" } }, + { "WTIRS", { A::SUMMARY_WELL, "Tracer Injection Rate" } }, + { "WTPRF", { A::SUMMARY_WELL, "Tracer Production Rate" } }, + { "WTPRS", { A::SUMMARY_WELL, "Tracer Production Rate" } }, + { "WTITF", { A::SUMMARY_WELL, "Tracer Injection Total" } }, + { "WTITS", { A::SUMMARY_WELL, "Tracer Injection Total" } }, + { "WTPTF", { A::SUMMARY_WELL, "Tracer Production Total" } }, + { "WTPTS", { A::SUMMARY_WELL, "Tracer Production Total" } }, + { "WTICF", { A::SUMMARY_WELL, "Tracer Injection Concentration" } }, + { "WTICS", { A::SUMMARY_WELL, "Tracer Injection Concentration" } }, + { "WTPCF", { A::SUMMARY_WELL, "Tracer Production" } }, + { "WTPCS", { A::SUMMARY_WELL, "Tracer Production" } }, + { "WMPR", { A::SUMMARY_WELL, "Methane Production Rate" } }, + { "WMPT", { A::SUMMARY_WELL, "Methane Production Total" } }, + { "WMIR", { A::SUMMARY_WELL, "Methane Injection Rate" } }, + { "WMIT", { A::SUMMARY_WELL, "Methane Injection Total" } }, + { "WTPRFOA", { A::SUMMARY_WELL, "Production Rate" } }, + { "WTPTFOA", { A::SUMMARY_WELL, "Production Total" } }, + { "WTIRFOA", { A::SUMMARY_WELL, "Injection Rate" } }, + { "WTITFOA", { A::SUMMARY_WELL, "Injection Total" } }, + { "WGDC", { A::SUMMARY_WELL, "Gas Delivery Capacity" } }, + { "NGOPAS", { A::SUMMARY_WELL, "Number of iterations to converge DCQ in first pass" } }, + { "WGPRFP", { A::SUMMARY_WELL, "Well Gas Production Rate from end of First Pass" } }, + { "WTHPFP", { A::SUMMARY_WELL, "Well Tubing Head Pressure from end of First Pass" } }, + { "WBHPFP", { A::SUMMARY_WELL, "Well Bottom Hole Pressure from end of First Pass" } }, + { "WGLIR", { A::SUMMARY_WELL, "Gas Lift Injection Rate" } }, + { "WOGLR", { A::SUMMARY_WELL, "Well Oil Gas Lift Ratio" } }, + { "WGCV", { A::SUMMARY_WELL, "Gas Calorific Value" } }, + { "WGQ", { A::SUMMARY_WELL, "Gas molar Quality" } }, + { "WEPR", { A::SUMMARY_WELL, "Energy Production Rate" } }, + { "WEPT", { A::SUMMARY_WELL, "Energy Production Total" } }, + { "WEDC", { A::SUMMARY_WELL, "Energy Delivery Capacity" } }, + { "WCPR", { A::SUMMARY_WELL, "Polymer Production Rate" } }, + { "WCPC", { A::SUMMARY_WELL, "Polymer Production Concentration" } }, + { "WCPT", { A::SUMMARY_WELL, "Polymer Production Total" } }, + { "WCIR", { A::SUMMARY_WELL, "Polymer Injection Rate" } }, + { "WCIC", { A::SUMMARY_WELL, "Polymer Injection Concentration" } }, + { "WCIT", { A::SUMMARY_WELL, "Polymer Injection Total" } }, + { "WSPR", { A::SUMMARY_WELL, "Salt Production Rate" } }, + { "WSPT", { A::SUMMARY_WELL, "Salt Production Total" } }, + { "WSIR", { A::SUMMARY_WELL, "Salt Injection Rate" } }, + { "WSIT", { A::SUMMARY_WELL, "Salt Injection Total" } }, + { "WNPR", { A::SUMMARY_WELL, "Solvent Production Rate" } }, + { "WNPT", { A::SUMMARY_WELL, "Solvent Production Total" } }, + { "WNIR", { A::SUMMARY_WELL, "Solvent Injection Rate" } }, + { "WNIT", { A::SUMMARY_WELL, "Solvent Injection Total" } }, + { "WTPRSUR", { A::SUMMARY_WELL, "Production Rate" } }, + { "WTPTSUR", { A::SUMMARY_WELL, "Production Total" } }, + { "WTIRSUR", { A::SUMMARY_WELL, "Injection Rate" } }, + { "WTITSUR", { A::SUMMARY_WELL, "Injection Total" } }, + { "WTPRALK", { A::SUMMARY_WELL, "Production Rate" } }, + { "WTPTALK", { A::SUMMARY_WELL, "Production Total" } }, + { "WTIRALK", { A::SUMMARY_WELL, "Injection Rate" } }, + { "WTITALK", { A::SUMMARY_WELL, "Injection Total" } }, + { "WU", { A::SUMMARY_WELL, "User-defined well quantity" } }, - { "GOPR", "Oil Production Rate" }, - { "GOPRA", "Oil Production Rate above GOC" }, - { "GOPRB", "Oil Production Rate below GOC" }, - { "GOPTA", "Oil Production Total above GOC" }, - { "GOPTB", "Oil Production Total below GOC" }, - { "GOPR1", "Oil Production Rate above GOC" }, - { "GOPR2", "Oil Production Rate below GOC" }, - { "GOPT1", "Oil Production Total above GOC" }, - { "GOPT2", "Oil Production Total below GOC" }, - { "GOMR", "Oil Mass Rate" }, - { "GOMT", "Oil Mass Total" }, - { "GODN", "Oil Density at Surface Conditions" }, - { "GOPRH", "Oil Production Rate History" }, - { "GOPRT", "Oil Production Rate Target/Limit" }, - { "GOPRL", "Oil Production Rate Target/Limit" }, - { "GOPRF", "Free Oil Production Rate" }, - { "GOPRS", "Solution Oil Production Rate" }, - { "GOPT", "Oil Production Total" }, - { "GOPTH", "Oil Production Total History" }, - { "GOPTF", "Free Oil Production Total" }, - { "GOPTS", "Solution Oil Production Total" }, - { "GOIR", "Oil Injection Rate" }, - { "GOIRH", "Oil Injection Rate History" }, - { "GOIRT", "Oil Injection Rate Target/Limit" }, - { "GOIRL", "Oil Injection Rate Target/Limit" }, - { "GOIT", "Oil Injection Total" }, - { "GOITH", "Oil Injection Total History" }, - { "GOPP", "Oil Potential Production rate" }, - { "GOPP2", "Oil Potential Production rate" }, - { "GOPI", "Oil Potential Injection rate" }, - { "GOPI2", "Oil Potential Injection rate" }, - { "GOPGR", "Oil Production Guide Rate" }, - { "GOIGR", "Oil Injection Guide Rate" }, - { "GOVPR", "Oil Voidage Production Rate" }, - { "GOVPT", "Oil Voidage Production Total" }, - { "GOVIR", "Oil Voidage Injection Rate" }, - { "GOVIT", "Oil Voidage Injection Total" }, - { "GOnPR", "nth separator stage oil rate" }, - { "GOnPT", "nth separator stage oil total" }, - { "GEOR", "Export Oil Rate" }, - { "GEOT", "Export Oil Total" }, - { "GEOMF", "Export Oil Mole Fraction" }, - { "GWPR", "Water Production Rate" }, - { "GWMR", "Water Mass Rate" }, - { "GWMT", "Water Mass Total" }, - { "GWPRH", "Water Production Rate History" }, - { "GWPRT", "Water Production Rate Target/Limit" }, - { "GWPRL", "Water Production Rate Target/Limit" }, - { "GWPT", "Water Production Total" }, - { "GWPTH", "Water Production Total History" }, - { "GWIR", "Water Injection Rate" }, - { "GWIRH", "Water Injection Rate History" }, - { "GWIRT", "Water Injection Rate Target/Limit" }, - { "GWIRL", "Water Injection Rate Target/Limit" }, - { "GWIT", "Water Injection Total" }, - { "GWITH", "Water Injection Total History" }, - { "GWPP", "Water Potential Production rate" }, - { "GWPP2", "Water Potential Production rate" }, - { "GWPI", "Water Potential Injection rate" }, - { "GWPI2", "Water Potential Injection rate" }, - { "GWPGR", "Water Production Guide Rate" }, - { "GWIGR", "Water Injection Guide Rate" }, - { "GWVPR", "Water Voidage Production Rate" }, - { "GWVPT", "Water Voidage Production Total" }, - { "GWVIR", "Water Voidage Injection Rate" }, - { "GWVIT", "Water Voidage Injection Total" }, - { "GWPIR", "Ratio of produced water to injected water (percentage)" }, - { "GWMPR", "Water component molar production rate" }, - { "GWMPT", "Water component molar production total" }, - { "GWMIR", "Water component molar injection rate" }, - { "GWMIT", "Water component molar injection total" }, - { "GGPR", "Gas Production Rate" }, - { "GGPRA", "Gas Production Rate above" }, - { "GGPRB", "Gas Production Rate below" }, - { "GGPTA", "Gas Production Total above" }, - { "GGPTB", "Gas Production Total below" }, - { "GGPR1", "Gas Production Rate above GOC" }, - { "GGPR2", "Gas Production Rate below GOC" }, - { "GGPT1", "Gas Production Total above GOC" }, - { "GGPT2", "Gas Production Total below GOC" }, - { "GGMR", "Gas Mass Rate" }, - { "GGMT", "Gas Mass Total" }, - { "GGDN", "Gas Density at Surface Conditions" }, - { "GGPRH", "Gas Production Rate History" }, - { "GGPRT", "Gas Production Rate Target/Limit" }, - { "GGPRL", "Gas Production Rate Target/Limit" }, - { "GGPRF", "Free Gas Production Rate" }, - { "GGPRS", "Solution Gas Production Rate" }, - { "GGPT", "Gas Production Total" }, - { "GGPTH", "Gas Production Total History" }, - { "GGPTF", "Free Gas Production Total" }, - { "GGPTS", "Solution Gas Production Total" }, - { "GGIR", "Gas Injection Rate" }, - { "GGIRH", "Gas Injection Rate History" }, - { "GGIRT", "Gas Injection Rate Target/Limit" }, - { "GGIRL", "Gas Injection Rate Target/Limit" }, - { "GGIT", "Gas Injection Total" }, - { "GGITH", "Gas Injection Total History" }, - { "GGPP", "Gas Potential Production rate" }, - { "GGPP2", "Gas Potential Production rate" }, - { "GGPPS", "Solution" }, - { "GGPPS2", "Solution" }, - { "GGPPF", "Free Gas Potential Production rate" }, - { "GGPPF2", "Free Gas Potential Production rate" }, - { "GGPI", "Gas Potential Injection rate" }, - { "GGPI2", "Gas Potential Injection rate" }, - { "GGPGR", "Gas Production Guide Rate" }, - { "GGIGR", "Gas Injection Guide Rate" }, - { "GSGR", "Sales Gas Rate" }, - { "GGSR", "Sales Gas Rate" }, - { "GSGT", "Sales Gas Total" }, - { "GGST", "Sales Gas Total" }, - { "GSMF", "Sales Gas Mole Fraction" }, - { "GFGR", "Fuel Gas Rate, at and below this group" }, - { "GFGT", "Fuel Gas cumulative Total, at and below this group" }, - { "GFMF", "Fuel Gas Mole Fraction" }, - { "GGCR", "Gas Consumption Rate, at and below this group" }, - { "GGCT", "Gas Consumption Total, at and below this group" }, - { "GGIMR", "Gas Import Rate, at and below this group" }, - { "GGIMT", "Gas Import Total, at and below this group" }, - { "GGLIR", "Gas Lift Injection Rate" }, - { "GWGPR", "Wet Gas Production Rate" }, - { "GWGPT", "Wet Gas Production Total" }, - { "GWGPRH", "Wet Gas Production Rate History" }, - { "GWGIR", "Wet Gas Injection Rate" }, - { "GWGIT", "Wet Gas Injection Total" }, - { "GEGR", "Export Gas Rate" }, - { "GEGT", "Export Gas Total" }, - { "GEMF", "Export Gas Mole Fraction" }, - { "GEXGR", "Excess Gas Rate" }, - { "GEXGT", "Excess Gas Total" }, - { "GRGR", "Re-injection Gas Rate" }, - { "GRGT", "Re-injection Gas Total" }, - { "GGnPR", "nth separator stage gas rate" }, - { "GGnPT", "nth separator stage gas total" }, - { "GGVPR", "Gas Voidage Production Rate" }, - { "GGVPT", "Gas Voidage Production Total" }, - { "GGVIR", "Gas Voidage Injection Rate" }, - { "GGVIT", "Gas Voidage Injection Total" }, - { "GGQ", "Gas Quality" }, - { "GLPR", "Liquid Production Rate" }, - { "GLPRH", "Liquid Production Rate History" }, - { "GLPRT", "Liquid Production Rate Target/Limit" }, - { "GLPRL", "Liquid Production Rate Target/Limit" }, - { "GLPT", "Liquid Production Total" }, - { "GLPTH", "Liquid Production Total History" }, - { "GVPR", "Res Volume Production Rate" }, - { "GVPRT", "Res Volume Production Rate Target/Limit" }, - { "GVPRL", "Res Volume Production Rate Target/Limit" }, - { "GVPT", "Res Volume Production Total" }, - { "GVPGR", "Res Volume Production Guide Rate" }, - { "GVIR", "Res Volume Injection Rate" }, - { "GVIRT", "Res Volume Injection Rate Target/Limit" }, - { "GVIRL", "Res Volume Injection Rate Target/Limit" }, - { "GVIT", "Res Volume Injection Total" }, - { "GWCT", "Water Cut" }, - { "GWCTH", "Water Cut History" }, - { "GGOR", "Gas-Oil Ratio" }, - { "GGORH", "Gas-Oil Ratio History" }, - { "GOGR", "Oil-Gas Ratio" }, - { "GOGRH", "Oil-Gas Ratio History" }, - { "GWGR", "Water-Gas Ratio" }, - { "GWGRH", "Water-Gas Ratio History" }, - { "GGLR", "Gas-Liquid Ratio" }, - { "GGLRH", "Gas-Liquid Ratio History" }, - { "GMCTP", "Mode of Control for group Production" }, - { "GMCTW", "Mode of Control for group Water Injection" }, - { "GMCTG", "Mode of Control for group Gas Injection" }, - { "GMWPT", "Total number of production wells" }, - { "GMWPR", "Number of production wells currently flowing" }, - { "GMWPA", "Number of abandoned production wells" }, - { "GMWPU", "Number of unused production wells" }, - { "GMWPG", "Number of producers on group control" }, - { "GMWPO", "Number of producers controlled by own oil rate limit" }, - { "GMWPS", "Number of producers on own surface rate limit control" }, - { "GMWPV", "Number of producers on own reservoir volume rate limit control" }, - { "GMWPP", "Number of producers on pressure control" }, - { "GMWPL", "Number of producers using artificial lift" }, - { "GMWIT", "Total number of injection wells" }, - { "GMWIN", "Number of injection wells currently flowing" }, - { "GMWIA", "Number of abandoned injection wells" }, - { "GMWIU", "Number of unused injection wells" }, - { "GMWIG", "Number of injectors on group control" }, - { "GMWIS", "Number of injectors on own surface rate limit control" }, - { "GMWIV", "Number of injectors on own reservoir volume rate limit control" }, - { "GMWIP", "Number of injectors on pressure control" }, - { "GMWDR", "Number of drilling events this timestep" }, - { "GMWDT", "Number of drilling events in total" }, - { "GMWWO", "Number of workover events this timestep" }, - { "GMWWT", "Number of workover events in total" }, - { "GEPR", "Energy Production Rate" }, - { "GEPT", "Energy Production Total" }, - { "GEFF", "Efficiency Factor" }, - { "GNLPR", "NGL Production Rate" }, - { "GNLPT", "NGL Production Total" }, - { "GNLPRH", "NGL Production Rate History" }, - { "GNLPTH", "NGL Production Total History" }, - { "GAMF", "Component aqueous mole fraction, from producing completions" }, - { "GXMF", "Liquid Mole Fraction" }, - { "GYMF", "Vapor Mole Fraction" }, - { "GXMFn", "Liquid Mole Fraction for nth separator stage" }, - { "GYMFn", "Vapor Mole Fraction for nth separator stage" }, - { "GZMF", "Total Mole Fraction" }, - { "GCMPR", "Hydrocarbon Component Molar Production Rates" }, - { "GCMPT", "Hydrocarbon Component" }, - { "GCMIR", "Hydrocarbon Component Molar Injection Rates" }, - { "GCMIT", "Hydrocarbon Component Molar Injection Totals" }, - { "GHMIR", "Hydrocarbon Molar Injection Rate" }, - { "GHMIT", "Hydrocarbon Molar Injection Total" }, - { "GHMPR", "Hydrocarbon Molar Production Rate" }, - { "GHMPT", "Hydrocarbon Molar Production Total" }, - { "GCHMR", "Hydrocarbon Component" }, - { "GCHMT", "Hydrocarbon Component" }, - { "GCWGPR", "Hydrocarbon Component Wet Gas Production Rate" }, - { "GCWGPT", "Hydrocarbon Component Wet Gas Production Total" }, - { "GCWGIR", "Hydrocarbon Component Wet Gas Injection Rate" }, - { "GCWGIT", "Hydrocarbon Component Wet Gas Injection Total" }, - { "GCGMR", "Hydrocarbon component" }, - { "GCGMT", "Hydrocarbon component" }, - { "GCOMR", "Hydrocarbon component" }, - { "GCOMT", "Hydrocarbon component" }, - { "GCNMR", "Hydrocarbon component molar rates in the NGL phase" }, - { "GCNWR", "Hydrocarbon component mass rates in the NGL phase" }, - { "GCGMRn", "Hydrocarbon component molar rates in the gas phase for nth separator stage" }, - { "GCGRn", "Hydrocarbon component molar rates in the gas phase for nth separator stage" }, - { "GCOMRn", "Hydrocarbon component" }, - { "GCORn", "Hydrocarbon component" }, - { "GMUF", "Make-up fraction" }, - { "GAMR", "Make-up gas rate" }, - { "GAMT", "Make-up gas total" }, - { "GGSPR", "Target sustainable rate for most recent sustainable capacity test for gas" }, - { "GGSRL", "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for gas" }, - { "GGSRU", "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for gas" }, - { "GGSSP", "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for gas" }, - { "GGSTP", "Test period for the most recent sustainable capacity test for gas" }, - { "GOSPR", "Target sustainable rate for most recent sustainable capacity test for oil" }, - { "GOSRL", "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for oil" }, - { "GOSRU", "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for oil" }, - { "GOSSP", "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for oil" }, - { "GOSTP", "Test period for the most recent sustainable capacity test for oil" }, - { "GWSPR", "Target sustainable rate for most recent sustainable capacity test for water" }, - { "GWSRL", "Maximum tested rate sustained for the test period during the most recent sustainable capacity test for water" }, - { "GWSRU", "Minimum tested rate not sustained for the test period during the most recent sustainable capacity test for water" }, - { "GWSSP", "Period for which target sustainable rate could be maintained for the most recent sustainable capacity test for water" }, - { "GWSTP", "Test period for the most recent sustainable capacity test for water" }, - { "GGPRG", "Gas production rate" }, - { "GOPRG", "Oil production rate" }, - { "GNLPRG", "NGL production rate" }, - { "GXMFG", "Liquid mole fraction" }, - { "GYMFG", "Vapor mole fraction" }, - { "GCOMRG", "Hydrocarbon component" }, - { "GCGMRG", "Hydrocarbon component molar rates in the gas phase" }, - { "GCNMRG", "Hydrocarbon component molar rates in the NGL phase" }, - { "GTPR", "Tracer Production Rate" }, - { "GTPT", "Tracer Production Total" }, - { "GTPC", "Tracer Production Concentration" }, - { "GTIR", "Tracer Injection Rate" }, - { "GTIT", "Tracer Injection Total" }, - { "GTIC", "Tracer Injection Concentration" }, - { "GTMR", "Traced mass Rate" }, - { "GTMT", "Traced mass Total" }, - { "GTQR", "Traced molar Rate" }, - { "GTCM", "Tracer Carrier molar Rate" }, - { "GTMF", "Traced molar fraction" }, - { "GTVL", "Traced liquid volume rate" }, - { "GTVV", "Traced vapor volume rate" }, - { "GTTL", "Traced liquid volume total" }, - { "GTTV", "Traced vapor volume total" }, - { "GTML", "Traced mass liquid rate" }, - { "GTMV", "Traced mass vapor rate" }, - { "GTLM", "Traced mass liquid total" }, - { "GTVM", "Traced mass vapor total" }, - { "GAPI", "Oil API" }, - { "GSPR", "Salt Production Rate" }, - { "GSPT", "Salt Production Total" }, - { "GSIR", "Salt Injection Rate" }, - { "GSIT", "Salt Injection Total" }, - { "GSPC", "Salt Production Concentration" }, - { "GSIC", "Salt Injection Concentration" }, - { "WTPRANI", "Anion Production Rate" }, - { "WTPTANI", "Anion Production Total" }, - { "WTIRANI", "Anion Injection Rate" }, - { "WTITANI", "Anion Injection Total" }, - { "WTPRCAT", "Cation Production Rate" }, - { "WTPTCAT", "Cation Production Total" }, - { "WTIRCAT", "Cation Injection Rate" }, - { "WTITCAT", "Cation Injection Total" }, - { "GTPCHEA", "Production Temperature" }, - { "GTICHEA", "Injection Temperature" }, - { "GTPRHEA", "Energy flows" }, - { "GTPTHEA", "Energy Production Total" }, - { "GTIRHEA", "Energy flows" }, - { "GTITHEA", "Energy Injection Total" }, - { "GTPR", "Tracer Production Rate" }, - { "GTPT", "Tracer Production Total" }, - { "GTPC", "Tracer Production Concentration" }, - { "GTIR", "Tracer Injection Rate" }, - { "GTIT", "Tracer Injection Total" }, - { "GTIC", "Tracer Injection Concentration" }, - { "GTIRF", "Tracer Injection Rate" }, - { "GTIRS", "Tracer Injection Rate" }, - { "GTPRF", "Tracer Production Rate" }, - { "GTPRS", "Tracer Production Rate" }, - { "GTITF", "Tracer Injection Total" }, - { "GTITS", "Tracer Injection Total" }, - { "GTPTF", "Tracer Production Total" }, - { "GTPTS", "Tracer Production Total" }, - { "GTICF", "Tracer Injection Concentration" }, - { "GTICS", "Tracer Injection Concentration" }, - { "GTPCF", "Tracer Production" }, - { "GTPCS", "Tracer Production" }, - { "GMPR", "Methane Production Rate" }, - { "GMPT", "Methane Production Total" }, - { "GMIR", "Methane Injection Rate" }, - { "GMIT", "Methane Injection Total" }, - { "GTPRFOA", "Production Rate" }, - { "GTPTFOA", "Production Total" }, - { "GTIRFOA", "Injection Rate" }, - { "GTITFOA", "Injection Total" }, - { "GSGR", "Sales Gas Rate" }, - { "GGSR", "Sales Gas Rate" }, - { "GSGT", "Sales Gas Total" }, - { "GGST", "Sales Gas Total" }, - { "GGDC", "Gas Delivery Capacity" }, - { "GGDCQ", "Field/Group Gas DCQ" }, - { "GMCPL", "Group Multi-level Compressor Level" }, - { "GPR", "Group nodal Pressure in network" }, - { "GPRDC", "Group Pressure at Delivery Capacity" }, - { "GGCR", "Gas consumption rate, at and below this group" }, - { "GGCT", "Gas consumption cumulative total, at and below this group" }, - { "GFGR", "Fuel Gas rate, at and below this group" }, - { "GFGT", "Fuel Gas cumulative total, at and below this group" }, - { "GGIMR", "Gas import rate, at and below this group" }, - { "GGIMT", "Gas import cumulative total, at and below this group" }, - { "GPRFP", "Group or node Pressure in network from end of First Pass" }, - { "GGPRNBFP", "Gas flow rate along Group’s or node’s outlet branch in network, from end of First Pass" }, - { "GGLIR", "Gas Lift Injection Rate" }, - { "GGCV", "Gas Calorific Value" }, - { "GGQ", "Gas molar Quality" }, - { "GEPR", "Energy Production Rate" }, - { "GEPT", "Energy Production Total" }, - { "GESR", "Energy Sales Rate" }, - { "GEST", "Energy Sales Total" }, - { "GEDC", "Energy Delivery Capacity" }, - { "GEDCQ", "Energy DCQ" }, - { "GPR", "Group or node Pressure in the production network" }, - { "GPRG", "Group or node Pressure in the gas injection network" }, - { "GPRW", "Group or node Pressure in the water injection network" }, - { "GPRB", "Pressure drop along the group’s or node’s outlet branch in the production network" }, - { "GPRBG", "Pressure drop along the group’s or node’s inlet branch in the gas injection network" }, - { "GPRBW", "Pressure drop along the group’s or node’s inlet branch in the water injection network" }, - { "GALQ", "ALQ in the group’s or node’s outlet branch in the production network" }, - { "GOPRNB", "Oil flow rate along the group’s or node’s outlet branch in the production network" }, - { "GWPRNB", "Water flow rate along the group’s or node’s outlet branch in the production network" }, - { "GGPRNB", "Gas flow rate along the group’s or node’s outlet branch in the production network" }, - { "GLPRNB", "Liquid flow rate along the group’s or node’s outlet branch in the production network" }, - { "GWIRNB", "Water flow rate along the group’s or node’s inlet branch in the water injection network" }, - { "GGIRNB", "Gas flow rate along the group’s or node’s inlet branch in the gas injection network" }, - { "GOMNR", "Group or node minimum oil rate as specified with GNETDP in the production network" }, - { "GGMNR", "Group or node minimum gas rate as specified with GNETDP in the production network" }, - { "GWMNR", "Group or node minimum water rate as specified with GNETDP in the production network" }, - { "GLMNR", "Group or node minimum liquid rate as specified with GNETDP in the production network" }, - { "GOMXR", "Group or node maximum oil rate as specified with GNETDP in the production network" }, - { "GGMXR", "Group or node maximum gas rate as specified with GNETDP in the production network" }, - { "GWMXR", "Group or node maximum water rate as specified with GNETDP in the production network" }, - { "GLMXR", "Group or node maximum liquid rate as specified with GNETDP in the production network" }, - { "GMNP", "Group or node minimum pressure as specified with GNETDP in the production network" }, - { "GMXP", "Group or node maximum pressure as specified with GNETDP in the production network" }, - { "GPRINC", "Group or node pressure increment as specified with GNETDP in the production network" }, - { "GPRDEC", "Group or node pressure decrement as specified with GNETDP in the production network" }, - { "GCPR", "Polymer Production Rate" }, - { "GCPC", "Polymer Production Concentration" }, - { "GCPT", "Polymer Production Total" }, - { "GCIR", "Polymer Injection Rate" }, - { "GCIC", "Polymer Injection Concentration" }, - { "GCIT", "Polymer Injection Total" }, - { "GSPR", "Salt Production Rate" }, - { "GSPT", "Salt Production Total" }, - { "GSIR", "Salt Injection Rate" }, - { "GSIT", "Salt Injection Total" }, - { "GOPRL", "Group Oil Production Rate Target" }, - { "GOIRL", "Group Oil Injection Rate Target" }, - { "GWPRL", "Group Water Production Rate Target" }, - { "GWIRL", "Group Water Injection Rate Target" }, - { "GGPRL", "Group Gas Production Rate Target" }, - { "GGIRL", "Group Gas Injection Rate Target" }, - { "GLPRL", "Group Liquid Production Rate Target" }, - { "GVPRL", "Group reservoir Volume Production Rate Target" }, - { "GVIRL", "Group reservoir Volume Injection Rate Target" }, - { "GNPR", "Solvent Production Rate" }, - { "GNPT", "Solvent Production Total" }, - { "GNIR", "Solvent Injection Rate" }, - { "GNIT", "Solvent Injection Total" }, - { "GTPRSUR", "Production Rate" }, - { "GTPTSUR", "Production Total" }, - { "GTIRSUR", "Injection Rate" }, - { "GTITSUR", "Injection Total" }, - { "GTPRALK", "Production Rate" }, - { "GTPTALK", "Production Total" }, - { "GTIRALK", "Injection Rate" }, - { "GTITALK", "Injection Total" }, - { "GU", "User-defined group quantity" }, + // Future CONNECTION vectors + { "COFR", { A::SUMMARY_WELL_COMPLETION, "Oil Flow Rate" } }, + { "COFRF", { A::SUMMARY_WELL_COMPLETION, "Free Oil Flow Rate" } }, + { "COFRS", { A::SUMMARY_WELL_COMPLETION, "Solution oil flow rate" } }, + { "COFRU", { A::SUMMARY_WELL_COMPLETION, "Sum of connection oil flow rates upstream of, and including, this connection" } }, + { "COPR", { A::SUMMARY_WELL_COMPLETION, "Oil Production Rate" } }, + { "COPT", { A::SUMMARY_WELL_COMPLETION, "Oil Production Total" } }, + { "COPTF", { A::SUMMARY_WELL_COMPLETION, "Free Oil Production Total" } }, + { "COPTS", { A::SUMMARY_WELL_COMPLETION, "Solution Oil Production Total" } }, + { "COIT", { A::SUMMARY_WELL_COMPLETION, "Oil Injection Total" } }, + { "COPP", { A::SUMMARY_WELL_COMPLETION, "Oil Potential Production rate" } }, + { "COPI", { A::SUMMARY_WELL_COMPLETION, "Oil Potential Injection rate" } }, + { "CWFR", { A::SUMMARY_WELL_COMPLETION, "Water Flow Rate" } }, + { "CWFRU", { A::SUMMARY_WELL_COMPLETION, "Sum of connection water flow rates upstream of, and including, this connection" } }, + { "CWPR", { A::SUMMARY_WELL_COMPLETION, "Water Production Rate" } }, + { "CWPT", { A::SUMMARY_WELL_COMPLETION, "Water Production Total" } }, + { "CWIR", { A::SUMMARY_WELL_COMPLETION, "Water Injection Rate" } }, + { "CWIT", { A::SUMMARY_WELL_COMPLETION, "Water Injection Total" } }, + { "CWPP", { A::SUMMARY_WELL_COMPLETION, "Water Potential Production rate" } }, + { "CWPI", { A::SUMMARY_WELL_COMPLETION, "Water Potential Injection rate" } }, + { "CGFR", { A::SUMMARY_WELL_COMPLETION, "Gas Flow Rate" } }, + { "CGFRF", { A::SUMMARY_WELL_COMPLETION, "Free Gas Flow Rate" } }, + { "CGFRS", { A::SUMMARY_WELL_COMPLETION, "Solution Gas Flow Rate" } }, + { "CGFRU", { A::SUMMARY_WELL_COMPLETION, "Sum of connection gas flow rates upstream of, and including, this connection" } }, + { "CGPR", { A::SUMMARY_WELL_COMPLETION, "Gas Production Rate " } }, + { "CGPT", { A::SUMMARY_WELL_COMPLETION, "Gas Production Total" } }, + { "CGPTF", { A::SUMMARY_WELL_COMPLETION, "Free Gas Production Total" } }, + { "CGPTS", { A::SUMMARY_WELL_COMPLETION, "Solution Gas Production Total" } }, + { "CGIR", { A::SUMMARY_WELL_COMPLETION, "Gas Injection Rate" } }, + { "CGIT", { A::SUMMARY_WELL_COMPLETION, "Gas Injection Total" } }, + { "CGPP", { A::SUMMARY_WELL_COMPLETION, "Gas Potential Production rate" } }, + { "CGPI", { A::SUMMARY_WELL_COMPLETION, "Gas Potential Injection rate" } }, + { "CGQ", { A::SUMMARY_WELL_COMPLETION, "Gas Quality" } }, + { "CLFR", { A::SUMMARY_WELL_COMPLETION, "Liquid Flow Rate" } }, + { "CLPT", { A::SUMMARY_WELL_COMPLETION, "Liquid Production Total" } }, + { "CVFR", { A::SUMMARY_WELL_COMPLETION, "Reservoir" } }, + { "CVPR", { A::SUMMARY_WELL_COMPLETION, "Res Volume Production Rate" } }, + { "CVPT", { A::SUMMARY_WELL_COMPLETION, "Res Volume Production Total" } }, + { "CVIR", { A::SUMMARY_WELL_COMPLETION, "Res Volume Injection Rate" } }, + { "CVIT", { A::SUMMARY_WELL_COMPLETION, "Res Volume Injection Total" } }, + { "CWCT", { A::SUMMARY_WELL_COMPLETION, "Water Cut" } }, + { "CGOR", { A::SUMMARY_WELL_COMPLETION, "Gas-Oil Ratio" } }, + { "COGR", { A::SUMMARY_WELL_COMPLETION, "Oil-Gas Ratio" } }, + { "CWGR", { A::SUMMARY_WELL_COMPLETION, "Water-Gas Ratio" } }, + { "CGLR", { A::SUMMARY_WELL_COMPLETION, "Gas-Liquid Ratio" } }, + { "CPR", { A::SUMMARY_WELL_COMPLETION, "Connection Pressure" } }, + { "CPI", { A::SUMMARY_WELL_COMPLETION, "Productivity Index of well’s preferred phase" } }, + { "CTFAC", { A::SUMMARY_WELL_COMPLETION, "Connection Transmissibility Factor" } }, + { "CDBF", { A::SUMMARY_WELL_COMPLETION, "Blocking factor for generalized pseudo-pressure method" } }, + { "CGPPTN", { A::SUMMARY_WELL_COMPLETION, "Generalized pseudo-pressure table update counter" } }, + { "CGPPTS", { A::SUMMARY_WELL_COMPLETION, "Generalized pseudo-pressure table update status" } }, + { "CDSM", { A::SUMMARY_WELL_COMPLETION, "Current mass of scale deposited" } }, + { "CDSML", { A::SUMMARY_WELL_COMPLETION, "Current mass of scale deposited per unit perforation length" } }, + { "CDSF", { A::SUMMARY_WELL_COMPLETION, "PI multiplicative factor due to scale damage" } }, + { "CAMF", { A::SUMMARY_WELL_COMPLETION, "Component aqueous mole fraction, from producing completions" } }, + { "CZMF", { A::SUMMARY_WELL_COMPLETION, "Total Mole Fraction" } }, + { "CKFR", { A::SUMMARY_WELL_COMPLETION, "Hydrocarbon Component" } }, + { "CKFT", { A::SUMMARY_WELL_COMPLETION, "Hydrocarbon Component" } }, + { "CDFAC", { A::SUMMARY_WELL_COMPLETION, "D-factor for flow dependent skin factor" } }, + { "CTFR", { A::SUMMARY_WELL_COMPLETION, "Tracer Flow Rate" } }, + { "CTPR", { A::SUMMARY_WELL_COMPLETION, "Tracer Production Rate" } }, + { "CTPT", { A::SUMMARY_WELL_COMPLETION, "Tracer Production Total" } }, + { "CTPC", { A::SUMMARY_WELL_COMPLETION, "Tracer Production Concentration" } }, + { "CTIR", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Rate" } }, + { "CTIT", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Total" } }, + { "CTIC", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Concentration" } }, + { "CAPI", { A::SUMMARY_WELL_COMPLETION, "Oil API" } }, + { "CSFR", { A::SUMMARY_WELL_COMPLETION, "Salt Flow Rate" } }, + { "CSPR", { A::SUMMARY_WELL_COMPLETION, "Salt Production Rate" } }, + { "CSPT", { A::SUMMARY_WELL_COMPLETION, "Salt Production Total" } }, + { "CSIR", { A::SUMMARY_WELL_COMPLETION, "Salt Injection Rate" } }, + { "CSIT", { A::SUMMARY_WELL_COMPLETION, "Salt Injection Total" } }, + { "CSPC", { A::SUMMARY_WELL_COMPLETION, "Salt Production Concentration" } }, + { "CSIC", { A::SUMMARY_WELL_COMPLETION, "Salt Injection Concentration" } }, + { "CTFRANI", { A::SUMMARY_WELL_COMPLETION, "Anion Flow Rate" } }, + { "CTPTANI", { A::SUMMARY_WELL_COMPLETION, "Anion Production Total" } }, + { "CTITANI", { A::SUMMARY_WELL_COMPLETION, "Anion Injection Total" } }, + { "CTFRCAT", { A::SUMMARY_WELL_COMPLETION, "Cation Flow Rate" } }, + { "CTPTCAT", { A::SUMMARY_WELL_COMPLETION, "Cation Production Total" } }, + { "CTITCAT", { A::SUMMARY_WELL_COMPLETION, "Cation Injection Total" } }, + { "CTFR", { A::SUMMARY_WELL_COMPLETION, "Tracer Flow Rate" } }, + { "CTPR", { A::SUMMARY_WELL_COMPLETION, "Tracer Production Rate" } }, + { "CTPT", { A::SUMMARY_WELL_COMPLETION, "Tracer Production Total" } }, + { "CTPC", { A::SUMMARY_WELL_COMPLETION, "Tracer Production Concentration" } }, + { "CTIR", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Rate" } }, + { "CTIT", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Total" } }, + { "CTIC", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Concentration" } }, + { "CTIRF", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Rate" } }, + { "CTIRS", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Rate" } }, + { "CTPRF", { A::SUMMARY_WELL_COMPLETION, "Tracer Production Rate" } }, + { "CTPRS", { A::SUMMARY_WELL_COMPLETION, "Tracer Production Rate" } }, + { "CTITF", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Total" } }, + { "CTITS", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Total" } }, + { "CTPTF", { A::SUMMARY_WELL_COMPLETION, "Tracer Production Total" } }, + { "CTPTS", { A::SUMMARY_WELL_COMPLETION, "Tracer Production Total" } }, + { "CTICF", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Concentration" } }, + { "CTICS", { A::SUMMARY_WELL_COMPLETION, "Tracer Injection Concentration" } }, + { "CTPCF", { A::SUMMARY_WELL_COMPLETION, "Tracer Production" } }, + { "CTPCS", { A::SUMMARY_WELL_COMPLETION, "Tracer Production" } }, + { "CTFRFOA", { A::SUMMARY_WELL_COMPLETION, "Flow Rate" } }, + { "CTPTFOA", { A::SUMMARY_WELL_COMPLETION, "Production Total" } }, + { "CTITFOA", { A::SUMMARY_WELL_COMPLETION, "Injection Total" } }, + { "CRREXCH", { A::SUMMARY_WELL_COMPLETION, "Exchange flux at current time" } }, + { "CRRPROT", { A::SUMMARY_WELL_COMPLETION, "Connection cumulative water production" } }, + { "CRRINJT", { A::SUMMARY_WELL_COMPLETION, "Connection cumulative water injection" } }, + { "CCFR", { A::SUMMARY_WELL_COMPLETION, "Polymer Flow Rate" } }, + { "CCPR", { A::SUMMARY_WELL_COMPLETION, "Polymer Production Rate" } }, + { "CCPC", { A::SUMMARY_WELL_COMPLETION, "Polymer Production Concentration" } }, + { "CCPT", { A::SUMMARY_WELL_COMPLETION, "Polymer Production Total" } }, + { "CCIR", { A::SUMMARY_WELL_COMPLETION, "Polymer Injection Rate" } }, + { "CCIC", { A::SUMMARY_WELL_COMPLETION, "Polymer Injection Concentration" } }, + { "CCIT", { A::SUMMARY_WELL_COMPLETION, "Polymer Injection Total" } }, + { "CSFR", { A::SUMMARY_WELL_COMPLETION, "Salt Flow Rate" } }, + { "CSPR", { A::SUMMARY_WELL_COMPLETION, "Salt Production Rate" } }, + { "CSPT", { A::SUMMARY_WELL_COMPLETION, "Salt Production Total" } }, + { "CSIR", { A::SUMMARY_WELL_COMPLETION, "Salt Injection Rate" } }, + { "CSIT", { A::SUMMARY_WELL_COMPLETION, "Salt Injection Total" } }, + { "CNFR", { A::SUMMARY_WELL_COMPLETION, "Solvent Flow Rate" } }, + { "CNPT", { A::SUMMARY_WELL_COMPLETION, "Solvent Production Total" } }, + { "CNIT", { A::SUMMARY_WELL_COMPLETION, "Solvent Injection Total" } }, + { "CTFRSUR", { A::SUMMARY_WELL_COMPLETION, "Flow Rate" } }, + { "CTPTSUR", { A::SUMMARY_WELL_COMPLETION, "Production Total" } }, + { "CTITSUR", { A::SUMMARY_WELL_COMPLETION, "Injection Total" } }, + { "CTFRALK", { A::SUMMARY_WELL_COMPLETION, "Flow Rate" } }, + { "CTPTALK", { A::SUMMARY_WELL_COMPLETION, "Production Total" } }, + { "CTITALK", { A::SUMMARY_WELL_COMPLETION, "Injection Total" } }, + { "COFRU", { A::SUMMARY_WELL_COMPLETION, "Sum of connection oil flow rates upstream of, and including, this connection" } }, + { "CWFRU", { A::SUMMARY_WELL_COMPLETION, "Sum of connection water flow rates upstream of, and including, this connection" } }, + { "CGFRU", { A::SUMMARY_WELL_COMPLETION, "Sum of connection gas flow rates upstream of, and including, this connection" } }, + { "LCOFRU", { A::SUMMARY_WELL_COMPLETION, "As COFRU but for local grids" } }, + { "LCWFRU", { A::SUMMARY_WELL_COMPLETION, "As CWFRU but for local grids" } }, + { "LCGFRU", { A::SUMMARY_WELL_COMPLETION, "As CGFRU but for local grids" } }, + { "CU", { A::SUMMARY_WELL_COMPLETION, "User-defined connection quantity" } }, - { "WOPR", "Oil Production Rate" }, - { "WOPRA", "Oil Production Rate above GOC" }, - { "WOPRB", "Oil Production Rate below GOC" }, - { "WOPTA", "Oil Production Total above GOC" }, - { "WOPTB", "Oil Production Total below GOC" }, - { "WOPR1", "Oil Production Rate above GOC" }, - { "WOPR2", "Oil Production Rate below GOC" }, - { "WOPT1", "Oil Production Total above GOC" }, - { "WOPT2", "Oil Production Total below GOC" }, - { "WOMR", "Oil Mass Rate" }, - { "WOMT", "Oil Mass Total" }, - { "WODN", "Oil Density at Surface Conditions" }, - { "WOPRH", "Oil Production Rate History" }, - { "WOPRT", "Oil Production Rate Target/Limit" }, - { "WOPRF", "Free Oil Production Rate" }, - { "WOPRS", "Solution Oil Production Rate" }, - { "WOPT", "Oil Production Total" }, - { "WOPTH", "Oil Production Total History" }, - { "WOPTF", "Free Oil Production Total" }, - { "WOPTS", "Solution Oil Production Total" }, - { "WOIR", "Oil Injection Rate" }, - { "WOIRH", "Oil Injection Rate History" }, - { "WOIRT", "Oil Injection Rate Target/Limit" }, - { "WOIT", "Oil Injection Total" }, - { "WOITH", "Oil Injection Total History" }, - { "WOPP", "Oil Potential Production rate" }, - { "WOPP2", "Oil Potential Production rate" }, - { "WOPI", "Oil Potential Injection rate" }, - { "WOPI2", "Oil Potential Injection rate" }, - { "WOPGR", "Oil Production Guide Rate" }, - { "WOIGR", "Oil Injection Guide Rate" }, - { "WOVPR", "Oil Voidage Production Rate" }, - { "WOVPT", "Oil Voidage Production Total" }, - { "WOVIR", "Oil Voidage Injection Rate" }, - { "WOVIT", "Oil Voidage Injection Total" }, - { "WOnPR", "nth separator stage oil rate" }, - { "WOnPT", "nth separator stage oil total" }, - { "WWPR", "Water Production Rate" }, - { "WWMR", "Water Mass Rate" }, - { "WWMT", "Water Mass Total" }, - { "WWPRH", "Water Production Rate History" }, - { "WWPRT", "Water Production Rate Target/Limit" }, - { "WWPT", "Water Production Total" }, - { "WWPTH", "Water Production Total History" }, - { "WWIR", "Water Injection Rate" }, - { "WWIRH", "Water Injection Rate History" }, - { "WWIRT", "Water Injection Rate Target/Limit" }, - { "WWIT", "Water Injection Total" }, - { "WWITH", "Water Injection Total History" }, - { "WWPP", "Water Potential Production rate" }, - { "WWPP2", "Water Potential Production rate" }, - { "WWPI", "Water Potential Injection rate" }, - { "WWIP", "Water Potential Injection rate" }, - { "WWPI2", "Water Potential Injection rate" }, - { "WWIP2", "Water Potential Injection rate" }, - { "WWPGR", "Water Production Guide Rate" }, - { "WWIGR", "Water Injection Guide Rate" }, - { "WWVPR", "Water Voidage Production Rate" }, - { "WWVPT", "Water Voidage Production Total" }, - { "WWVIR", "Water Voidage Injection Rate" }, - { "WWVIT", "Water Voidage Injection Total" }, - { "WWPIR", "Ratio of produced water to injected water (percentage)" }, - { "WWMPR", "Water component molar production rate" }, - { "WWMPT", "Water component molar production total" }, - { "WWMIR", "Water component molar injection rate" }, - { "WWMIT", "Water component molar injection total" }, - { "WGPR", "Gas Production Rate" }, - { "WGPRA", "Gas Production Rate above" }, - { "WGPRB", "Gas Production Rate below" }, - { "WGPTA", "Gas Production Total above" }, - { "WGPTB", "Gas Production Total below" }, - { "WGPR1", "Gas Production Rate above GOC" }, - { "WGPR2", "Gas Production Rate below GOC" }, - { "WGPT1", "Gas Production Total above GOC" }, - { "WGPT2", "Gas Production Total below GOC" }, - { "WGMR", "Gas Mass Rate" }, - { "WGMT", "Gas Mass Total" }, - { "WGDN", "Gas Density at Surface Conditions" }, - { "WGPRH", "Gas Production Rate History" }, - { "WGPRT", "Gas Production Rate Target/Limit" }, - { "WGPRF", "Free Gas Production Rate" }, - { "WGPRS", "Solution Gas Production Rate" }, - { "WGPT", "Gas Production Total" }, - { "WGPTH", "Gas Production Total History" }, - { "WGPTF", "Free Gas Production Total" }, - { "WGPTS", "Solution Gas Production Total" }, - { "WGIR", "Gas Injection Rate" }, - { "WGIRH", "Gas Injection Rate History" }, - { "WGIRT", "Gas Injection Rate Target/Limit" }, - { "WGIT", "Gas Injection Total" }, - { "WGITH", "Gas Injection Total History" }, - { "WGPP", "Gas Potential Production rate" }, - { "WGPP2", "Gas Potential Production rate" }, - { "WGPPS", "Solution" }, - { "WGPPS2", "Solution" }, - { "WGPPF", "Free Gas Potential Production rate" }, - { "WGPPF2", "Free Gas Potential Production rate" }, - { "WGPI", "Gas Potential Injection rate" }, - { "WGIP", "Gas Potential Injection rate" }, - { "WGPI2", "Gas Potential Injection rate" }, - { "WGIP2", "Gas Potential Injection rate" }, - { "WGPGR", "Gas Production Guide Rate" }, - { "WGIGR", "Gas Injection Guide Rate" }, - { "WGLIR", "Gas Lift Injection Rate" }, - { "WWGPR", "Wet Gas Production Rate" }, - { "WWGPT", "Wet Gas Production Total" }, - { "WWGPRH", "Wet Gas Production Rate History" }, - { "WWGIR", "Wet Gas Injection Rate" }, - { "WWGIT", "Wet Gas Injection Total" }, - { "WGnPR", "nth separator stage gas rate" }, - { "WGnPT", "nth separator stage gas total" }, - { "WGVPR", "Gas Voidage Production Rate" }, - { "WGVPT", "Gas Voidage Production Total" }, - { "WGVIR", "Gas Voidage Injection Rate" }, - { "WGVIT", "Gas Voidage Injection Total" }, - { "WGQ", "Gas Quality" }, - { "WLPR", "Liquid Production Rate" }, - { "WLPRH", "Liquid Production Rate History" }, - { "WLPRT", "Liquid Production Rate Target/Limit" }, - { "WLPT", "Liquid Production Total" }, - { "WLPTH", "Liquid Production Total History" }, - { "WVPR", "Res Volume Production Rate" }, - { "WVPRT", "Res Volume Production Rate Target/Limit" }, - { "WVPT", "Res Volume Production Total" }, - { "WVPGR", "Res Volume Production Guide Rate" }, - { "WVIR", "Res Volume Injection Rate" }, - { "WVIRT", "Res Volume Injection Rate Target/Limit" }, - { "WVIT", "Res Volume Injection Total" }, - { "WWCT", "Water Cut" }, - { "WWCTH", "Water Cut History" }, - { "WGOR", "Gas-Oil Ratio" }, - { "WGORH", "Gas-Oil Ratio History" }, - { "WOGR", "Oil-Gas Ratio" }, - { "WOGRH", "Oil-Gas Ratio History" }, - { "WWGR", "Water-Gas Ratio" }, - { "WWGRH", "Water-Gas Ratio History" }, - { "WGLR", "Gas-Liquid Ratio" }, - { "WGLRH", "Gas-Liquid Ratio History" }, - { "WBGLR", "Bottom hole Gas-Liquid Ratio" }, - { "WBHP", "Bottom Hole Pressure" }, - { "WBHPH", "Bottom Hole Pressure History," }, - { "WBHPT", "Bottom Hole Pressure Target/Limit" }, - { "WTHP", "Tubing Head Pressure" }, - { "WTHPH", "Tubing Head Pressure History," }, - { "WPI", "Productivity Index of well’s preferred phase" }, - { "WPIO", "Oil phase PI" }, - { "WPIG", "Gas phase PI" }, - { "WPIW", "Water phase PI" }, - { "WPIL", "Liquid phase PI" }, - { "WBP", "One-point Pressure Average" }, - { "WBP4", "Four-point Pressure Average" }, - { "WBP5", "Five-point Pressure Average" }, - { "WBP9", "Nine-point Pressure Average" }, - { "WPI1", "Productivity Index based on the value of WBP" }, - { "WPI4", "Productivity Index based on the value of WBP4" }, - { "WPI5", "Productivity Index based on the value of WBP5" }, - { "WPI9", "Productivity Index based on the value of WBP9" }, - { "WHD", "Hydraulic head in well based on the reference depth given in HYDRHEAD and the well’s reference depth" }, - { "WHDF", "Hydraulic head in well based on the reference depth given in HYDRHEAD and the well’s reference depth calculated at freshwater conditions" }, - { "WSTAT", "Well State Indicator" }, - { "WMCTL", "Mode of Control" }, - { "WMCON", "The number of connections capable of flowing in the well" }, - { "WEPR", "Energy Production Rate" }, - { "WEPT", "Energy Production Total" }, - { "WEFF", "Efficiency Factor" }, - { "WEFFG", "Product of efficiency factors of the well and all its superior groups" }, - { "WALQ", "Well Artificial Lift Quantity" }, - { "WMVFP", "VFP table number used by the well" }, - { "WNLPR", "NGL Production Rate" }, - { "WNLPT", "NGL Production Total" }, - { "WNLPRH", "NGL Production Rate History" }, - { "WNLPTH", "NGL Production Total History" }, - { "WNLPRT", "NGL Production Rate Target" }, - { "WAMF", "Component aqueous mole fraction, from producing completions" }, - { "WXMF", "Liquid Mole Fraction" }, - { "WYMF", "Vapor Mole Fraction" }, - { "WXMFn", "Liquid Mole Fraction for nth separator stage" }, - { "WYMFn", "Vapor Mole Fraction for nth separator stage" }, - { "WZMF", "Total Mole Fraction" }, - { "WCMPR", "Hydrocarbon Component Molar Production Rates" }, - { "WCMPT", "Hydrocarbon Component" }, - { "WCMIR", "Hydrocarbon Component Molar Injection Rates" }, - { "WCMIT", "Hydrocarbon Component Molar Injection Totals" }, - { "WCGIR", "Hydrocarbon Component Gas Injection Rate" }, - { "WCGPR", "Hydrocarbon Component Gas Production Rate" }, - { "WCOPR", "Hydrocarbon Component Oil Production Rate" }, - { "WHMIR", "Hydrocarbon Molar Injection Rate" }, - { "WHMIT", "Hydrocarbon Molar Injection Total" }, - { "WHMPR", "Hydrocarbon Molar Production Rate" }, - { "WHMPT", "Hydrocarbon Molar Production Total" }, - { "WCHMR", "Hydrocarbon Component" }, - { "WCHMT", "Hydrocarbon Component" }, - { "WCWGPR", "Hydrocarbon Component Wet Gas Production Rate" }, - { "WCWGPT", "Hydrocarbon Component Wet Gas Production Total" }, - { "WCWGIR", "Hydrocarbon Component Wet Gas Injection Rate" }, - { "WCWGIT", "Hydrocarbon Component Wet Gas Injection Total" }, - { "WCGMR", "Hydrocarbon component" }, - { "WCGMT", "Hydrocarbon component" }, - { "WCOMR", "Hydrocarbon component" }, - { "WCOMT", "Hydrocarbon component" }, - { "WCNMR", "Hydrocarbon component molar rates in the NGL phase" }, - { "WCNWR", "Hydrocarbon component mass rates in the NGL phase" }, - { "WCGMRn", "Hydrocarbon component molar rates in the gas phase for nth separator stage" }, - { "WCGRn", "Hydrocarbon component molar rates in the gas phase for nth separator stage" }, - { "WCOMRn", "Hydrocarbon component" }, - { "WCORn", "Hydrocarbon component" }, - { "WMUF", "Make-up fraction" }, - { "WTHT", "Tubing Head Temperature" }, - { "WMMW", "Mean molecular weight of wellstream" }, - { "WPWE0", "Well drilled indicator" }, - { "WPWE1", "Connections opened indicator" }, - { "WPWE2", "Connections closed indicator" }, - { "WPWE3", "Connections closed to bottom indicator" }, - { "WPWE4", "Well stopped indicator" }, - { "WPWE5", "Injector to producer indicator" }, - { "WPWE6", "Producer to injector indicator" }, - { "WPWE7", "Well shut indicator" }, - { "WPWEM", "WELEVNT output mnemonic" }, - { "WDRPR", "Well drilling priority" }, - { "WBHWCn", "Derivative of well BHP with respect to parameter n" }, - { "WGFWCn", "Derivative of well gas flow rate with respect to parameter n" }, - { "WOFWCn", "Derivative of well oil flow rate with respect to parameter n" }, - { "WWFWCn", "Derivative of water flow rate with respect to parameter n" }, - { "WTPR", "Tracer Production Rate" }, - { "WTPT", "Tracer Production Total" }, - { "WTPC", "Tracer Production Concentration" }, - { "WTIR", "Tracer Injection Rate" }, - { "WTIT", "Tracer Injection Total" }, - { "WTIC", "Tracer Injection Concentration" }, - { "WTMR", "Traced mass Rate" }, - { "WTMT", "Traced mass Total" }, - { "WTQR", "Traced molar Rate" }, - { "WTCM", "Tracer Carrier molar Rate" }, - { "WTMF", "Traced molar fraction" }, - { "WTVL", "Traced liquid volume rate" }, - { "WTVV", "Traced vapor volume rate" }, - { "WTTL", "Traced liquid volume total" }, - { "WTTV", "Traced vapor volume total" }, - { "WTML", "Traced mass liquid rate" }, - { "WTMV", "Traced mass vapor rate" }, - { "WTLM", "Traced mass liquid total" }, - { "WTVM", "Traced mass vapor total" }, - { "WAPI", "Oil API" }, - { "WSPR", "Salt Production Rate" }, - { "WSPT", "Salt Production Total" }, - { "WSIR", "Salt Injection Rate" }, - { "WSIT", "Salt Injection Total" }, - { "WSPC", "Salt Production Concentration" }, - { "WSIC", "Salt Injection Concentration" }, - { "WTPCHEA", "Production Temperature" }, - { "WTICHEA", "Injection Temperature" }, - { "WTPRHEA", "Energy flows" }, - { "WTPTHEA", "Energy Production Total" }, - { "WTIRHEA", "Energy flows" }, - { "WTITHEA", "Energy Injection Total" }, - { "WTPR", "Tracer Production Rate" }, - { "WTPT", "Tracer Production Total" }, - { "WTPC", "Tracer Production Concentration" }, - { "WTIR", "Tracer Injection Rate" }, - { "WTIT", "Tracer Injection Total" }, - { "WTIC", "Tracer Injection Concentration" }, - { "WTIRF", "Tracer Injection Rate" }, - { "WTIRS", "Tracer Injection Rate" }, - { "WTPRF", "Tracer Production Rate" }, - { "WTPRS", "Tracer Production Rate" }, - { "WTITF", "Tracer Injection Total" }, - { "WTITS", "Tracer Injection Total" }, - { "WTPTF", "Tracer Production Total" }, - { "WTPTS", "Tracer Production Total" }, - { "WTICF", "Tracer Injection Concentration" }, - { "WTICS", "Tracer Injection Concentration" }, - { "WTPCF", "Tracer Production" }, - { "WTPCS", "Tracer Production" }, - { "WMPR", "Methane Production Rate" }, - { "WMPT", "Methane Production Total" }, - { "WMIR", "Methane Injection Rate" }, - { "WMIT", "Methane Injection Total" }, - { "WTPRFOA", "Production Rate" }, - { "WTPTFOA", "Production Total" }, - { "WTIRFOA", "Injection Rate" }, - { "WTITFOA", "Injection Total" }, - { "WGDC", "Gas Delivery Capacity" }, - { "NGOPAS", "Number of iterations to converge DCQ in first pass" }, - { "WGPRFP", "Well Gas Production Rate from end of First Pass" }, - { "WTHPFP", "Well Tubing Head Pressure from end of First Pass" }, - { "WBHPFP", "Well Bottom Hole Pressure from end of First Pass" }, - { "WGLIR", "Gas Lift Injection Rate" }, - { "WOGLR", "Well Oil Gas Lift Ratio" }, - { "WGCV", "Gas Calorific Value" }, - { "WGQ", "Gas molar Quality" }, - { "WEPR", "Energy Production Rate" }, - { "WEPT", "Energy Production Total" }, - { "WEDC", "Energy Delivery Capacity" }, - { "WCPR", "Polymer Production Rate" }, - { "WCPC", "Polymer Production Concentration" }, - { "WCPT", "Polymer Production Total" }, - { "WCIR", "Polymer Injection Rate" }, - { "WCIC", "Polymer Injection Concentration" }, - { "WCIT", "Polymer Injection Total" }, - { "WSPR", "Salt Production Rate" }, - { "WSPT", "Salt Production Total" }, - { "WSIR", "Salt Injection Rate" }, - { "WSIT", "Salt Injection Total" }, - { "WNPR", "Solvent Production Rate" }, - { "WNPT", "Solvent Production Total" }, - { "WNIR", "Solvent Injection Rate" }, - { "WNIT", "Solvent Injection Total" }, - { "WTPRSUR", "Production Rate" }, - { "WTPTSUR", "Production Total" }, - { "WTIRSUR", "Injection Rate" }, - { "WTITSUR", "Injection Total" }, - { "WTPRALK", "Production Rate" }, - { "WTPTALK", "Production Total" }, - { "WTIRALK", "Injection Rate" }, - { "WTITALK", "Injection Total" }, - { "WU", "User-defined well quantity" }, + { "COFRL", { A::SUMMARY_WELL_COMPLETION, "Oil Flow Rate" } }, + { "WOFRL", { A::SUMMARY_WELL_COMPLETION, "Oil Flow Rate" } }, + { "COPRL", { A::SUMMARY_WELL_COMPLETION, "Oil Flow Rate" } }, + { "WOPRL", { A::SUMMARY_WELL_COMPLETION, "Oil Flow Rate" } }, + { "COPTL", { A::SUMMARY_WELL_COMPLETION, "Oil Production Total" } }, + { "WOPTL", { A::SUMMARY_WELL_COMPLETION, "Oil Production Total" } }, + { "COITL", { A::SUMMARY_WELL_COMPLETION, "Oil Injection Total" } }, + { "WOITL", { A::SUMMARY_WELL_COMPLETION, "Oil Injection Total" } }, + { "CWFRL", { A::SUMMARY_WELL_COMPLETION, "Water Flow Rate" } }, + { "WWFRL", { A::SUMMARY_WELL_COMPLETION, "Water Flow Rate" } }, + { "CWPRL", { A::SUMMARY_WELL_COMPLETION, "Water Flow Rate" } }, + { "WWPRL", { A::SUMMARY_WELL_COMPLETION, "Water Flow Rate" } }, + { "CWPTL", { A::SUMMARY_WELL_COMPLETION, "Water Production Total" } }, + { "WWPTL", { A::SUMMARY_WELL_COMPLETION, "Water Production Total" } }, + { "CWIRL", { A::SUMMARY_WELL_COMPLETION, "Water Injection Rate" } }, + { "WWIRL", { A::SUMMARY_WELL_COMPLETION, "Water Injection Rate" } }, + { "CWITL", { A::SUMMARY_WELL_COMPLETION, "Water Injection Total" } }, + { "WWITL", { A::SUMMARY_WELL_COMPLETION, "Water Injection Total" } }, + { "CGFRL", { A::SUMMARY_WELL_COMPLETION, "Gas Flow Rate" } }, + { "WGFRL", { A::SUMMARY_WELL_COMPLETION, "Gas Flow Rate" } }, + { "CGPRL", { A::SUMMARY_WELL_COMPLETION, "Gas Flow Rate" } }, + { "WGPRL", { A::SUMMARY_WELL_COMPLETION, "Gas Flow Rate" } }, + { "CGPTL", { A::SUMMARY_WELL_COMPLETION, "Gas Production Total" } }, + { "WGPTL", { A::SUMMARY_WELL_COMPLETION, "Gas Production Total" } }, + { "CGIRL", { A::SUMMARY_WELL_COMPLETION, "Gas Injection Rate" } }, + { "WGIRL", { A::SUMMARY_WELL_COMPLETION, "Gas Injection Rate" } }, + { "CGITL", { A::SUMMARY_WELL_COMPLETION, "Gas Injection Total" } }, + { "WGITL", { A::SUMMARY_WELL_COMPLETION, "Gas Injection Total" } }, + { "CLFRL", { A::SUMMARY_WELL_COMPLETION, "Liquid Flow Rate" } }, + { "WLFRL", { A::SUMMARY_WELL_COMPLETION, "Liquid Flow Rate" } }, + { "CLPTL", { A::SUMMARY_WELL_COMPLETION, "Liquid Production Total" } }, + { "WLPTL", { A::SUMMARY_WELL_COMPLETION, "Liquid Production Total" } }, + { "CVFRL", { A::SUMMARY_WELL_COMPLETION, "Reservoir" } }, + { "WVFRL", { A::SUMMARY_WELL_COMPLETION, "Res Volume Flow Rate" } }, + { "CVPRL", { A::SUMMARY_WELL_COMPLETION, "Res Volume Production Flow Rate" } }, + { "WVPRL", { A::SUMMARY_WELL_COMPLETION, "Res Volume Production Flow Rate" } }, + { "CVIRL", { A::SUMMARY_WELL_COMPLETION, "Res Volume Injection Flow Rate" } }, + { "WVIRL", { A::SUMMARY_WELL_COMPLETION, "Res Volume Injection Flow Rate" } }, + { "CVPTL", { A::SUMMARY_WELL_COMPLETION, "Res Volume Production Total" } }, + { "WVPTL", { A::SUMMARY_WELL_COMPLETION, "Res Volume Production Total" } }, + { "CVITL", { A::SUMMARY_WELL_COMPLETION, "Res Volume Injection Total" } }, + { "WVITL", { A::SUMMARY_WELL_COMPLETION, "Res Volume Injection Total" } }, + { "CWCTL", { A::SUMMARY_WELL_COMPLETION, "Water Cut" } }, + { "WWCTL", { A::SUMMARY_WELL_COMPLETION, "Water Cut" } }, + { "CGORL", { A::SUMMARY_WELL_COMPLETION, "Gas-Oil Ratio" } }, + { "WGORL", { A::SUMMARY_WELL_COMPLETION, "Gas-Oil Ratio" } }, + { "COGRL", { A::SUMMARY_WELL_COMPLETION, "Oil-Gas Ratio" } }, + { "WOGRL", { A::SUMMARY_WELL_COMPLETION, "Oil-Gas Ratio" } }, + { "CWGRL", { A::SUMMARY_WELL_COMPLETION, "Water-Gas Ratio" } }, + { "WWGRL", { A::SUMMARY_WELL_COMPLETION, "Water-Gas Ratio" } }, + { "CGLRL", { A::SUMMARY_WELL_COMPLETION, "Gas-Liquid Ratio" } }, + { "WGLRL", { A::SUMMARY_WELL_COMPLETION, "Gas-Liquid Ratio" } }, + { "CPRL", { A::SUMMARY_WELL_COMPLETION, "Average Connection Pressure in completion" } }, + { "CKFRL", { A::SUMMARY_WELL_COMPLETION, "Hydrocarbon Component" } }, + { "CKFTL", { A::SUMMARY_WELL_COMPLETION, "Hydrocarbon Component" } }, - { "COFR", "Oil Flow Rate" }, - { "COFRF", "Free Oil Flow Rate" }, - { "COFRS", "Solution oil flow rate" }, - { "COFRU", "Sum of connection oil flow rates upstream of, and including, this connection" }, - { "COPR", "Oil Production Rate" }, - { "COPT", "Oil Production Total" }, - { "COPTF", "Free Oil Production Total" }, - { "COPTS", "Solution Oil Production Total" }, - { "COIT", "Oil Injection Total" }, - { "COPP", "Oil Potential Production rate" }, - { "COPI", "Oil Potential Injection rate" }, - { "CWFR", "Water Flow Rate" }, - { "CWFRU", "Sum of connection water flow rates upstream of, and including, this connection" }, - { "CWPR", "Water Production Rate" }, - { "CWPT", "Water Production Total" }, - { "CWIR", "Water Injection Rate" }, - { "CWIT", "Water Injection Total" }, - { "CWPP", "Water Potential Production rate" }, - { "CWPI", "Water Potential Injection rate" }, - { "CGFR", "Gas Flow Rate" }, - { "CGFRF", "Free Gas Flow Rate" }, - { "CGFRS", "Solution Gas Flow Rate" }, - { "CGFRU", "Sum of connection gas flow rates upstream of, and including, this connection" }, - { "CGPR", "Gas Production Rate " }, - { "CGPT", "Gas Production Total" }, - { "CGPTF", "Free Gas Production Total" }, - { "CGPTS", "Solution Gas Production Total" }, - { "CGIR", "Gas Injection Rate" }, - { "CGIT", "Gas Injection Total" }, - { "CGPP", "Gas Potential Production rate" }, - { "CGPI", "Gas Potential Injection rate" }, - { "CGQ", "Gas Quality" }, - { "CLFR", "Liquid Flow Rate" }, - { "CLPT", "Liquid Production Total" }, - { "CVFR", "Reservoir" }, - { "CVPR", "Res Volume Production Rate" }, - { "CVPT", "Res Volume Production Total" }, - { "CVIR", "Res Volume Injection Rate" }, - { "CVIT", "Res Volume Injection Total" }, - { "CWCT", "Water Cut" }, - { "CGOR", "Gas-Oil Ratio" }, - { "COGR", "Oil-Gas Ratio" }, - { "CWGR", "Water-Gas Ratio" }, - { "CGLR", "Gas-Liquid Ratio" }, - { "CPR", "Connection Pressure" }, - { "CPI", "Productivity Index of well’s preferred phase" }, - { "CTFAC", "Connection Transmissibility Factor" }, - { "CDBF", "Blocking factor for generalized pseudo-pressure method" }, - { "CGPPTN", "Generalized pseudo-pressure table update counter" }, - { "CGPPTS", "Generalized pseudo-pressure table update status" }, - { "CDSM", "Current mass of scale deposited" }, - { "CDSML", "Current mass of scale deposited per unit perforation length" }, - { "CDSF", "PI multiplicative factor due to scale damage" }, - { "CAMF", "Component aqueous mole fraction, from producing completions" }, - { "CZMF", "Total Mole Fraction" }, - { "CKFR", "Hydrocarbon Component" }, - { "CKFT", "Hydrocarbon Component" }, - { "CDFAC", "D-factor for flow dependent skin factor" }, - { "CTFR", "Tracer Flow Rate" }, - { "CTPR", "Tracer Production Rate" }, - { "CTPT", "Tracer Production Total" }, - { "CTPC", "Tracer Production Concentration" }, - { "CTIR", "Tracer Injection Rate" }, - { "CTIT", "Tracer Injection Total" }, - { "CTIC", "Tracer Injection Concentration" }, - { "CAPI", "Oil API" }, - { "CSFR", "Salt Flow Rate" }, - { "CSPR", "Salt Production Rate" }, - { "CSPT", "Salt Production Total" }, - { "CSIR", "Salt Injection Rate" }, - { "CSIT", "Salt Injection Total" }, - { "CSPC", "Salt Production Concentration" }, - { "CSIC", "Salt Injection Concentration" }, - { "CTFRANI", "Anion Flow Rate" }, - { "CTPTANI", "Anion Production Total" }, - { "CTITANI", "Anion Injection Total" }, - { "CTFRCAT", "Cation Flow Rate" }, - { "CTPTCAT", "Cation Production Total" }, - { "CTITCAT", "Cation Injection Total" }, - { "CTFR", "Tracer Flow Rate" }, - { "CTPR", "Tracer Production Rate" }, - { "CTPT", "Tracer Production Total" }, - { "CTPC", "Tracer Production Concentration" }, - { "CTIR", "Tracer Injection Rate" }, - { "CTIT", "Tracer Injection Total" }, - { "CTIC", "Tracer Injection Concentration" }, - { "CTIRF", "Tracer Injection Rate" }, - { "CTIRS", "Tracer Injection Rate" }, - { "CTPRF", "Tracer Production Rate" }, - { "CTPRS", "Tracer Production Rate" }, - { "CTITF", "Tracer Injection Total" }, - { "CTITS", "Tracer Injection Total" }, - { "CTPTF", "Tracer Production Total" }, - { "CTPTS", "Tracer Production Total" }, - { "CTICF", "Tracer Injection Concentration" }, - { "CTICS", "Tracer Injection Concentration" }, - { "CTPCF", "Tracer Production" }, - { "CTPCS", "Tracer Production" }, - { "CTFRFOA", "Flow Rate" }, - { "CTPTFOA", "Production Total" }, - { "CTITFOA", "Injection Total" }, - { "CRREXCH", "Exchange flux at current time" }, - { "CRRPROT", "Connection cumulative water production" }, - { "CRRINJT", "Connection cumulative water injection" }, - { "CCFR", "Polymer Flow Rate" }, - { "CCPR", "Polymer Production Rate" }, - { "CCPC", "Polymer Production Concentration" }, - { "CCPT", "Polymer Production Total" }, - { "CCIR", "Polymer Injection Rate" }, - { "CCIC", "Polymer Injection Concentration" }, - { "CCIT", "Polymer Injection Total" }, - { "CSFR", "Salt Flow Rate" }, - { "CSPR", "Salt Production Rate" }, - { "CSPT", "Salt Production Total" }, - { "CSIR", "Salt Injection Rate" }, - { "CSIT", "Salt Injection Total" }, - { "CNFR", "Solvent Flow Rate" }, - { "CNPT", "Solvent Production Total" }, - { "CNIT", "Solvent Injection Total" }, - { "CTFRSUR", "Flow Rate" }, - { "CTPTSUR", "Production Total" }, - { "CTITSUR", "Injection Total" }, - { "CTFRALK", "Flow Rate" }, - { "CTPTALK", "Production Total" }, - { "CTITALK", "Injection Total" }, - { "COFRU", "Sum of connection oil flow rates upstream of, and including, this connection" }, - { "CWFRU", "Sum of connection water flow rates upstream of, and including, this connection" }, - { "CGFRU", "Sum of connection gas flow rates upstream of, and including, this connection" }, - { "LCOFRU", "As COFRU but for local grids" }, - { "LCWFRU", "As CWFRU but for local grids" }, - { "LCGFRU", "As CGFRU but for local grids" }, - { "CU", "User-defined connection quantity" }, + { "RPR", { A::SUMMARY_REGION, "Pressure average value" } }, + { "RPRH", { A::SUMMARY_REGION, "Pressure average value" } }, + { "RPRP", { A::SUMMARY_REGION, "Pressure average value" } }, + { "RPRGZ", { A::SUMMARY_REGION, "P/Z" } }, + { "RRS", { A::SUMMARY_REGION, "Gas-oil ratio" } }, + { "RRV", { A::SUMMARY_REGION, "Oil-gas ratio" } }, + { "RPPC", { A::SUMMARY_REGION, "Initial Contact Corrected Potential" } }, + { "RRPV", { A::SUMMARY_REGION, "Pore Volume at Reservoir conditions" } }, + { "ROPV", { A::SUMMARY_REGION, "Pore Volume containing Oil" } }, + { "RWPV", { A::SUMMARY_REGION, "Pore Volume containing Water" } }, + { "RGPV", { A::SUMMARY_REGION, "Pore Volume containing Gas" } }, + { "RHPV", { A::SUMMARY_REGION, "Pore Volume containing Hydrocarbon" } }, + { "RRTM", { A::SUMMARY_REGION, "Transmissibility Multiplier associated with rock compaction" } }, + { "ROE", { A::SUMMARY_REGION, "(OIP(initial - OIP(now) / OIP(initial)" } }, + { "ROEW", { A::SUMMARY_REGION, "Oil Production from Wells / OIP(initial)" } }, + { "ROEIW", { A::SUMMARY_REGION, "(OIP(initial - OIP(now) / Initial Mobile Oil with respect to Water" } }, + { "ROEWW", { A::SUMMARY_REGION, "Oil Production from Wells / Initial Mobile Oil with respect to Water" } }, + { "ROEIG", { A::SUMMARY_REGION, "(OIP(initial - OIP(now) / Initial Mobile Oil with respect to Gas" } }, + { "ROEWG", { A::SUMMARY_REGION, "Oil Production from Wells / Initial Mobile Oil with respect to Gas" } }, + { "RORMR", { A::SUMMARY_REGION, "Total stock tank oil produced by rock compaction" } }, + { "RORMW", { A::SUMMARY_REGION, "Total stock tank oil produced by water influx" } }, + { "RORMG", { A::SUMMARY_REGION, "Total stock tank oil produced by gas influx" } }, + { "RORME", { A::SUMMARY_REGION, "Total stock tank oil produced by oil expansion" } }, + { "RORMS", { A::SUMMARY_REGION, "Total stock tank oil produced by solution gas" } }, + { "RORMF", { A::SUMMARY_REGION, "Total stock tank oil produced by free gas influx" } }, + { "RORMX", { A::SUMMARY_REGION, "Total stock tank oil produced by 'traced' water influx" } }, + { "RORMY", { A::SUMMARY_REGION, "Total stock tank oil produced by other water influx" } }, + { "RORFR", { A::SUMMARY_REGION, "Fraction of total oil produced by rock compaction" } }, + { "RORFW", { A::SUMMARY_REGION, "Fraction of total oil produced by water influx" } }, + { "RORFG", { A::SUMMARY_REGION, "Fraction of total oil produced by gas influx" } }, + { "RORFE", { A::SUMMARY_REGION, "Fraction of total oil produced by oil expansion" } }, + { "RORFS", { A::SUMMARY_REGION, "Fraction of total oil produced by solution gas" } }, + { "RORFF", { A::SUMMARY_REGION, "Fraction of total oil produced by free gas influx" } }, + { "RORFX", { A::SUMMARY_REGION, "Fraction of total oil produced by 'traced' water influx" } }, + { "RORFY", { A::SUMMARY_REGION, "Fraction of total oil produced by other water influx" } }, + { "RTIPT", { A::SUMMARY_REGION, "Tracer In Place" } }, + { "RTIPF", { A::SUMMARY_REGION, "Tracer In Place" } }, + { "RTIPS", { A::SUMMARY_REGION, "Tracer In Place" } }, + { "RAPI", { A::SUMMARY_REGION, "Oil API" } }, + { "RSIP", { A::SUMMARY_REGION, "Salt In Place" } }, + { "RTIPTHEA", { A::SUMMARY_REGION, "Difference in Energy in place between current and initial time" } }, + { "RTIPT", { A::SUMMARY_REGION, "Tracer In Place" } }, + { "RTIPF", { A::SUMMARY_REGION, "Tracer In Place" } }, + { "RTIPS", { A::SUMMARY_REGION, "Tracer In Place" } }, + { "RTIP#", { A::SUMMARY_REGION, "Tracer In Place in phase # (1,2,3,...)" } }, + { "RTADS", { A::SUMMARY_REGION, "Tracer Adsorption total" } }, + { "RTDCY", { A::SUMMARY_REGION, "Decayed tracer" } }, + { "RCGC", { A::SUMMARY_REGION, "Bulk Coal Gas Concentration" } }, + { "RCSC", { A::SUMMARY_REGION, "Bulk Coal Solvent Concentration" } }, + { "RTIPTFOA", { A::SUMMARY_REGION, "In Solution" } }, + { "RTADSFOA", { A::SUMMARY_REGION, "Adsorption total" } }, + { "RTDCYFOA", { A::SUMMARY_REGION, "Decayed tracer" } }, + { "RTMOBFOA", { A::SUMMARY_REGION, "Gas mobility factor" } }, + { "RCIP", { A::SUMMARY_REGION, "Polymer In Solution" } }, + { "RCAD", { A::SUMMARY_REGION, "Polymer Adsorption total" } }, + { "RSIP", { A::SUMMARY_REGION, "Salt In Place" } }, + { "RNIP", { A::SUMMARY_REGION, "Solvent In Place" } }, + { "RTIPTSUR", { A::SUMMARY_REGION, "In Solution" } }, + { "RTADSUR", { A::SUMMARY_REGION, "Adsorption total" } }, + { "RU", { A::SUMMARY_REGION, "User-defined region quantity" } }, - { "COFRL", "Oil Flow Rate" }, - { "WOFRL", "Oil Flow Rate" }, - { "COPRL", "Oil Flow Rate" }, - { "WOPRL", "Oil Flow Rate" }, - { "COPTL", "Oil Production Total" }, - { "WOPTL", "Oil Production Total" }, - { "COITL", "Oil Injection Total" }, - { "WOITL", "Oil Injection Total" }, - { "CWFRL", "Water Flow Rate" }, - { "WWFRL", "Water Flow Rate" }, - { "CWPRL", "Water Flow Rate" }, - { "WWPRL", "Water Flow Rate" }, - { "CWPTL", "Water Production Total" }, - { "WWPTL", "Water Production Total" }, - { "CWIRL", "Water Injection Rate" }, - { "WWIRL", "Water Injection Rate" }, - { "CWITL", "Water Injection Total" }, - { "WWITL", "Water Injection Total" }, - { "CGFRL", "Gas Flow Rate" }, - { "WGFRL", "Gas Flow Rate" }, - { "CGPRL", "Gas Flow Rate" }, - { "WGPRL", "Gas Flow Rate" }, - { "CGPTL", "Gas Production Total" }, - { "WGPTL", "Gas Production Total" }, - { "CGIRL", "Gas Injection Rate" }, - { "WGIRL", "Gas Injection Rate" }, - { "CGITL", "Gas Injection Total" }, - { "WGITL", "Gas Injection Total" }, - { "CLFRL", "Liquid Flow Rate" }, - { "WLFRL", "Liquid Flow Rate" }, - { "CLPTL", "Liquid Production Total" }, - { "WLPTL", "Liquid Production Total" }, - { "CVFRL", "Reservoir" }, - { "WVFRL", "Res Volume Flow Rate" }, - { "CVPRL", "Res Volume Production Flow Rate" }, - { "WVPRL", "Res Volume Production Flow Rate" }, - { "CVIRL", "Res Volume Injection Flow Rate" }, - { "WVIRL", "Res Volume Injection Flow Rate" }, - { "CVPTL", "Res Volume Production Total" }, - { "WVPTL", "Res Volume Production Total" }, - { "CVITL", "Res Volume Injection Total" }, - { "WVITL", "Res Volume Injection Total" }, - { "CWCTL", "Water Cut" }, - { "WWCTL", "Water Cut" }, - { "CGORL", "Gas-Oil Ratio" }, - { "WGORL", "Gas-Oil Ratio" }, - { "COGRL", "Oil-Gas Ratio" }, - { "WOGRL", "Oil-Gas Ratio" }, - { "CWGRL", "Water-Gas Ratio" }, - { "WWGRL", "Water-Gas Ratio" }, - { "CGLRL", "Gas-Liquid Ratio" }, - { "WGLRL", "Gas-Liquid Ratio" }, - { "CPRL", "Average Connection Pressure in completion" }, - { "CKFRL", "Hydrocarbon Component" }, - { "CKFTL", "Hydrocarbon Component" }, + { "ROFR", { A::SUMMARY_REGION_2_REGION, "Inter-region oil flow rate" } }, + { "ROFR+", { A::SUMMARY_REGION_2_REGION, "Inter-region oil flow rate" } }, + { "ROFR-", { A::SUMMARY_REGION_2_REGION, "Inter-region oil flow rate" } }, + { "ROFT", { A::SUMMARY_REGION_2_REGION, "Inter-region oil flow total" } }, + { "ROFT+", { A::SUMMARY_REGION_2_REGION, "Inter-region oil flow total" } }, + { "ROFT-", { A::SUMMARY_REGION_2_REGION, "Inter-region oil flow total" } }, + { "ROFTL", { A::SUMMARY_REGION_2_REGION, "Inter-region oil flow total" } }, + { "ROFTG", { A::SUMMARY_REGION_2_REGION, "Inter-region oil flow total" } }, + { "RGFR", { A::SUMMARY_REGION_2_REGION, "Inter-region gas flow rate" } }, + { "RGFR+", { A::SUMMARY_REGION_2_REGION, "Inter-region gas flow rate" } }, + { "RGFR-", { A::SUMMARY_REGION_2_REGION, "Inter-region gas flow rate" } }, + { "RGFT", { A::SUMMARY_REGION_2_REGION, "Inter-region gas flow total)" } }, + { "RGFT+", { A::SUMMARY_REGION_2_REGION, "Inter-region gas flow total" } }, + { "RGFT-", { A::SUMMARY_REGION_2_REGION, "Inter-region gas flow total" } }, + { "RGFTL", { A::SUMMARY_REGION_2_REGION, "Inter-region gas flow total" } }, + { "RGFTG", { A::SUMMARY_REGION_2_REGION, "Inter-region gas flow total" } }, + { "RWFR", { A::SUMMARY_REGION_2_REGION, "Inter-region water flow rate" } }, + { "RWFR+", { A::SUMMARY_REGION_2_REGION, "Inter-region water flow rate" } }, + { "RWFR-", { A::SUMMARY_REGION_2_REGION, "Inter-region water flow rate" } }, + { "RWFT", { A::SUMMARY_REGION_2_REGION, "Inter-region water flow total" } }, + { "RTFTF", { A::SUMMARY_REGION_2_REGION, "Tracer inter-region Flow Total" } }, + { "RTFTS", { A::SUMMARY_REGION_2_REGION, "Tracer inter-region Flow Total" } }, + { "RTFTT", { A::SUMMARY_REGION_2_REGION, "Tracer inter-region Flow Total" } }, + { "RSFT", { A::SUMMARY_REGION_2_REGION, "Salt inter-region Flow Total" } }, + { "RTFTT", { A::SUMMARY_REGION_2_REGION, "Tracer inter-region Flow" } }, + { "RTFTF", { A::SUMMARY_REGION_2_REGION, "Tracer inter-region Flow" } }, + { "RTFTS", { A::SUMMARY_REGION_2_REGION, "Tracer inter-region Flow" } }, + { "RTFT#", { A::SUMMARY_REGION_2_REGION, "Tracer inter-region Flow in phase # (1,2,3,...)" } }, + { "RTFTTFOA", { A::SUMMARY_REGION_2_REGION, "Inter-region Flow Total" } }, + { "RCFT", { A::SUMMARY_REGION_2_REGION, "Polymer inter-region Flow Total" } }, + { "RSFT", { A::SUMMARY_REGION_2_REGION, "Salt inter-region Flow Total" } }, + { "RNFT", { A::SUMMARY_REGION_2_REGION, "Solvent inter-region Flow" } }, + { "RTFTTSUR", { A::SUMMARY_REGION_2_REGION, "Inter-region Flow Total" } }, - { "ROFR", "Inter-region oil flow rate" }, - { "ROFR+", "Inter-region oil flow rate" }, - { "ROFR-", "Inter-region oil flow rate" }, - { "ROFT", "Inter-region oil flow total" }, - { "ROFT+", "Inter-region oil flow total" }, - { "ROFT-", "Inter-region oil flow total" }, - { "ROFTL", "Inter-region oil flow total" }, - { "ROFTG", "Inter-region oil flow total" }, - { "RGFR", "Inter-region gas flow rate" }, - { "RGFR+", "Inter-region gas flow rate" }, - { "RGFR-", "Inter-region gas flow rate" }, - { "RGFT", "Inter-region gas flow total)" }, - { "RGFT+", "Inter-region gas flow total" }, - { "RGFT-", "Inter-region gas flow total" }, - { "RGFTL", "Inter-region gas flow total" }, - { "RGFTG", "Inter-region gas flow total" }, - { "RWFR", "Inter-region water flow rate" }, - { "RWFR+", "Inter-region water flow rate" }, - { "RWFR-", "Inter-region water flow rate" }, - { "RWFT", "Inter-region water flow total" }, - { "RPR", "Pressure average value" }, - { "RPRH", "Pressure average value" }, - { "RPRP", "Pressure average value" }, - { "RPRGZ", "P/Z" }, - { "RRS", "Gas-oil ratio" }, - { "RRV", "Oil-gas ratio" }, - { "RPPC", "Initial Contact Corrected Potential" }, - { "RRPV", "Pore Volume at Reservoir conditions" }, - { "ROPV", "Pore Volume containing Oil" }, - { "RWPV", "Pore Volume containing Water" }, - { "RGPV", "Pore Volume containing Gas" }, - { "RHPV", "Pore Volume containing Hydrocarbon" }, - { "RRTM", "Transmissibility Multiplier associated with rock compaction" }, - { "ROE", "(OIP(initial - OIP(now) / OIP(initial)" }, - { "ROEW", "Oil Production from Wells / OIP(initial)" }, - { "ROEIW", "(OIP(initial - OIP(now) / Initial Mobile Oil with respect to Water" }, - { "ROEWW", "Oil Production from Wells / Initial Mobile Oil with respect to Water" }, - { "ROEIG", "(OIP(initial - OIP(now) / Initial Mobile Oil with respect to Gas" }, - { "ROEWG", "Oil Production from Wells / Initial Mobile Oil with respect to Gas" }, - { "RORMR", "Total stock tank oil produced by rock compaction" }, - { "RORMW", "Total stock tank oil produced by water influx" }, - { "RORMG", "Total stock tank oil produced by gas influx" }, - { "RORME", "Total stock tank oil produced by oil expansion" }, - { "RORMS", "Total stock tank oil produced by solution gas" }, - { "RORMF", "Total stock tank oil produced by free gas influx" }, - { "RORMX", "Total stock tank oil produced by 'traced' water influx" }, - { "RORMY", "Total stock tank oil produced by other water influx" }, - { "RORFR", "Fraction of total oil produced by rock compaction" }, - { "RORFW", "Fraction of total oil produced by water influx" }, - { "RORFG", "Fraction of total oil produced by gas influx" }, - { "RORFE", "Fraction of total oil produced by oil expansion" }, - { "RORFS", "Fraction of total oil produced by solution gas" }, - { "RORFF", "Fraction of total oil produced by free gas influx" }, - { "RORFX", "Fraction of total oil produced by 'traced' water influx" }, - { "RORFY", "Fraction of total oil produced by other water influx" }, - { "RTIPT", "Tracer In Place" }, - { "RTIPF", "Tracer In Place" }, - { "RTIPS", "Tracer In Place" }, - { "RTFTF", "Tracer inter-region Flow Total" }, - { "RTFTS", "Tracer inter-region Flow Total" }, - { "RTFTT", "Tracer inter-region Flow Total" }, - { "RAPI", "Oil API" }, - { "RSIP", "Salt In Place" }, - { "RSFT", "Salt inter-region Flow Total" }, - { "RTIPTHEA", "Difference in Energy in place between current and initial time" }, - { "RTIPT", "Tracer In Place" }, - { "RTIPF", "Tracer In Place" }, - { "RTIPS", "Tracer In Place" }, - { "RTIP#", "Tracer In Place in phase # (1,2,3,...)" }, - { "RTFTT", "Tracer inter-region Flow" }, - { "RTFTF", "Tracer inter-region Flow" }, - { "RTFTS", "Tracer inter-region Flow" }, - { "RTFT#", "Tracer inter-region Flow in phase # (1,2,3,...)" }, - { "RTADS", "Tracer Adsorption total" }, - { "RTDCY", "Decayed tracer" }, - { "RCGC", "Bulk Coal Gas Concentration" }, - { "RCSC", "Bulk Coal Solvent Concentration" }, - { "RTIPTFOA", "In Solution" }, - { "RTFTTFOA", "Inter-region Flow Total" }, - { "RTADSFOA", "Adsorption total" }, - { "RTDCYFOA", "Decayed tracer" }, - { "RTMOBFOA", "Gas mobility factor" }, - { "RCIP", "Polymer In Solution" }, - { "RCFT", "Polymer inter-region Flow Total" }, - { "RCAD", "Polymer Adsorption total" }, - { "RSIP", "Salt In Place" }, - { "RSFT", "Salt inter-region Flow Total" }, - { "RNIP", "Solvent In Place" }, - { "RNFT", "Solvent inter-region Flow" }, - { "RTIPTSUR", "In Solution" }, - { "RTFTTSUR", "Inter-region Flow Total" }, - { "RTADSUR", "Adsorption total" }, - { "RU", "User-defined region quantity" }, + { "BPR", { A::SUMMARY_BLOCK, "Oil phase Pressure" } }, + { "BPRESSUR", { A::SUMMARY_BLOCK, "Oil phase Pressure" } }, + { "BWPR", { A::SUMMARY_BLOCK, "Water phase Pressure" } }, + { "BGPR", { A::SUMMARY_BLOCK, "Gas phase Pressure" } }, + { "BRS", { A::SUMMARY_BLOCK, "Gas-oil ratio" } }, + { "BRV", { A::SUMMARY_BLOCK, "Oil-gas ratio" } }, + { "BPBUB", { A::SUMMARY_BLOCK, "Bubble point pressure" } }, + { "BPDEW", { A::SUMMARY_BLOCK, "Dew point pressure" } }, + { "BRSSAT", { A::SUMMARY_BLOCK, "Saturated gas-oil ratio" } }, + { "BRVSAT", { A::SUMMARY_BLOCK, "Saturated oil-gas ratio" } }, + { "BSTATE", { A::SUMMARY_BLOCK, "Gas-oil state indicator" } }, + { "BPPC", { A::SUMMARY_BLOCK, "Initial Contact Corrected Potential" } }, + { "BOKR", { A::SUMMARY_BLOCK, "Oil relative permeability" } }, + { "BWKR", { A::SUMMARY_BLOCK, "Water relative permeability" } }, + { "BGKR", { A::SUMMARY_BLOCK, "Gas relative permeability" } }, + { "BKRO", { A::SUMMARY_BLOCK, "Oil relative permeability" } }, + { "BKROG", { A::SUMMARY_BLOCK, "Two-phase oil relative permeability to gas" } }, + { "BKROW", { A::SUMMARY_BLOCK, "Two-phase oil relative permeability to water" } }, + { "BKRG", { A::SUMMARY_BLOCK, "Gas relative permeability" } }, + { "BKRGO", { A::SUMMARY_BLOCK, "Two-phase gas relative permeability to oil " } }, + { "BKRGW", { A::SUMMARY_BLOCK, "Two-phase gas relative permeability to water" } }, + { "BKRW", { A::SUMMARY_BLOCK, "Water relative permeability" } }, + { "BKRWG", { A::SUMMARY_BLOCK, "Two-phase water relative permeability to gas" } }, + { "BKRWO", { A::SUMMARY_BLOCK, "Two-phase water relative permeability to oil" } }, + { "BRK", { A::SUMMARY_BLOCK, "Water relative permeability reduction factor due to polymer" } }, + { "BEWKR", { A::SUMMARY_BLOCK, "Water effective relative permeability due to polymer" } }, + { "BWPC", { A::SUMMARY_BLOCK, "Water-Oil capillary pressure" } }, + { "BGPC", { A::SUMMARY_BLOCK, "Gas-Oil capillary pressure" } }, + { "BPCO", { A::SUMMARY_BLOCK, "Oil Capillary Pressures" } }, + { "BPCG", { A::SUMMARY_BLOCK, "Gas Capillary Pressures" } }, + { "BPCW", { A::SUMMARY_BLOCK, "Water Capillary Pressures" } }, + { "BGTRP", { A::SUMMARY_BLOCK, "Trapped gas saturation" } }, + { "BGTPD", { A::SUMMARY_BLOCK, "Dynamic trapped gas saturation" } }, + { "BGSHY", { A::SUMMARY_BLOCK, "Departure saturation from drainage to imbibition for gas capillary pressure hysteresis" } }, + { "BGSTRP", { A::SUMMARY_BLOCK, "Trapped gas critical saturation for gas capillary pressure hysteresis" } }, + { "BWSHY", { A::SUMMARY_BLOCK, "Departure saturation from drainage to imbibition for water capillary pressure hysteresis" } }, + { "BWSMA", { A::SUMMARY_BLOCK, "Maximum wetting saturation for water capillary pressure hysteresis" } }, + { "BMLSC", { A::SUMMARY_BLOCK, "Hydrocarbon molar density" } }, + { "BMLST", { A::SUMMARY_BLOCK, "Total hydrocarbon molar density" } }, + { "BMWAT", { A::SUMMARY_BLOCK, "Water molar density" } }, + { "BROMLS", { A::SUMMARY_BLOCK, "Residual oil moles/ reservoir volume" } }, + { "BJV", { A::SUMMARY_BLOCK, "In" } }, + { "BVMF", { A::SUMMARY_BLOCK, "Vapor mole fraction" } }, + { "BPSAT", { A::SUMMARY_BLOCK, "Saturation Pressures" } }, + { "BAMF", { A::SUMMARY_BLOCK, "Component aqueous mole fraction" } }, + { "BXMF", { A::SUMMARY_BLOCK, "Liquid hydrocarbon component mole fraction" } }, + { "BYMF", { A::SUMMARY_BLOCK, "Vapor hydrocarbon component mole fraction / vapor steam" } }, + { "BSMF", { A::SUMMARY_BLOCK, "CO2STORE with SOLID option only Solid hydrocarbon component mole fraction" } }, + { "BSTEN", { A::SUMMARY_BLOCK, "Surface Tension" } }, + { "BFMISC", { A::SUMMARY_BLOCK, "Miscibility Factor" } }, + { "BREAC", { A::SUMMARY_BLOCK, "Reaction rate. The reaction number is given as a component index" } }, + { "BHD", { A::SUMMARY_BLOCK, "Hydraulic head" } }, + { "BHDF", { A::SUMMARY_BLOCK, "Hydraulic head at fresh water conditions" } }, + { "BPR_X", { A::SUMMARY_BLOCK, "Pressure interpolated at a defined coordinate" } }, + { "BHD_X", { A::SUMMARY_BLOCK, "Hydraulic head interpolated at a defined coordinate" } }, + { "BHDF_X", { A::SUMMARY_BLOCK, "Hydraulic head at fresh water conditions interpolated at a defined coordinate" } }, + { "BSCN_X", { A::SUMMARY_BLOCK, "Brine concentration interpolated at a defined coordinate" } }, + { "BCTRA_X", { A::SUMMARY_BLOCK, "Tracer concentration interpolated at a defined coordinate" } }, + { "LBPR_X", { A::SUMMARY_BLOCK, "Pressure interpolated at a defined coordinate within a local grid" } }, + { "LBHD_X", { A::SUMMARY_BLOCK, "Hydraulic head interpolated at a defined coordinate within a local grid" } }, + { "LBHDF_X", { A::SUMMARY_BLOCK, "Hydraulic head at freshwater conditions interpolated at a defined coordinate within a local grid" } }, + { "LBSCN_X", { A::SUMMARY_BLOCK, "Brine concentration interpolated at a defined coordinate within a local grid" } }, + { "LBCTRA_X", { A::SUMMARY_BLOCK, "Tracer concentration interpolated at a defined coordinate within a local grid" } }, + { "BOKRX", { A::SUMMARY_BLOCK, "Oil relative permeability in the X direction" } }, + { "BOKRX", { A::SUMMARY_BLOCK, "- Oil relative permeability in the -X direction" } }, + { "BOKRY", { A::SUMMARY_BLOCK, "Oil relative permeability in the Y direction" } }, + { "BOKRY", { A::SUMMARY_BLOCK, "- Oil relative permeability in the -Y direction" } }, + { "BOKRZ", { A::SUMMARY_BLOCK, "Oil relative permeability in the Z direction" } }, + { "BOKRZ", { A::SUMMARY_BLOCK, "- Oil relative permeability in the -Z direction" } }, + { "BWKRX", { A::SUMMARY_BLOCK, "Water relative permeability in the X direction" } }, + { "BWKRX", { A::SUMMARY_BLOCK, "- Water relative permeability in the -X direction" } }, + { "BWKRY", { A::SUMMARY_BLOCK, "Water relative permeability in the Y direction" } }, + { "BWKRY", { A::SUMMARY_BLOCK, "- Water relative permeability in the -Y direction" } }, + { "BWKRZ", { A::SUMMARY_BLOCK, "Water relative permeability in the Z direction" } }, + { "BWKRZ", { A::SUMMARY_BLOCK, "- Water relative permeability in the -Z direction" } }, + { "BGKRX", { A::SUMMARY_BLOCK, "Gas relative permeability in the X direction" } }, + { "BGKRX", { A::SUMMARY_BLOCK, "- Gas relative permeability in the -X direction" } }, + { "BGKRY", { A::SUMMARY_BLOCK, "Gas relative permeability in the Y direction" } }, + { "BGKRY", { A::SUMMARY_BLOCK, "- Gas relative permeability in the -Y direction" } }, + { "BGKRZ", { A::SUMMARY_BLOCK, "Gas relative permeability in the Z direction" } }, + { "BGKRZ", { A::SUMMARY_BLOCK, "- Gas relative permeability in the -Z direction" } }, + { "BOKRI", { A::SUMMARY_BLOCK, "Oil relative permeability in the I direction" } }, + { "BOKRI", { A::SUMMARY_BLOCK, "- Oil relative permeability in the -I direction" } }, + { "BOKRJ", { A::SUMMARY_BLOCK, "Oil relative permeability in the J direction" } }, + { "BOKRJ", { A::SUMMARY_BLOCK, "- Oil relative permeability in the -J direction" } }, + { "BOKRK", { A::SUMMARY_BLOCK, "Oil relative permeability in the K direction" } }, + { "BOKRK", { A::SUMMARY_BLOCK, "- Oil relative permeability in the -K direction" } }, + { "BWKRI", { A::SUMMARY_BLOCK, "Water relative permeability in the I direction" } }, + { "BWKRI", { A::SUMMARY_BLOCK, "- Water relative permeability in the -I direction" } }, + { "BWKRJ", { A::SUMMARY_BLOCK, "Water relative permeability in the J direction" } }, + { "BWKRJ", { A::SUMMARY_BLOCK, "- Water relative permeability in the -J direction" } }, + { "BWKRK", { A::SUMMARY_BLOCK, "Water relative permeability in the K direction" } }, + { "BWKRK", { A::SUMMARY_BLOCK, "- Water relative permeability in the -K direction" } }, + { "BGKRI", { A::SUMMARY_BLOCK, "Gas relative permeability in the I direction" } }, + { "BGKRI", { A::SUMMARY_BLOCK, "- Gas relative permeability in the -I direction" } }, + { "BGKRJ", { A::SUMMARY_BLOCK, "Gas relative permeability in the J direction" } }, + { "BGKRJ", { A::SUMMARY_BLOCK, "- Gas relative permeability in the -J direction" } }, + { "BGKRK", { A::SUMMARY_BLOCK, "Gas relative permeability in the K direction" } }, + { "BGKRK", { A::SUMMARY_BLOCK, "- Gas relative permeability in the -K direction" } }, + { "BOKRR", { A::SUMMARY_BLOCK, "Oil relative permeability in the R" } }, + { "BOKRR", { A::SUMMARY_BLOCK, "- Oil relative permeability in the -R" } }, + { "BOKRT", { A::SUMMARY_BLOCK, "Oil relative permeability in the T" } }, + { "BOKRT", { A::SUMMARY_BLOCK, "- Oil relative permeability in the -T" } }, + { "BWKRR", { A::SUMMARY_BLOCK, "Water relative permeability in the R" } }, + { "BWKRR", { A::SUMMARY_BLOCK, "- Water relative permeability in the -R" } }, + { "BWKRT", { A::SUMMARY_BLOCK, "Water relative permeability in the T" } }, + { "BWKRT", { A::SUMMARY_BLOCK, "- Water relative permeability in the -T" } }, + { "BGKRR", { A::SUMMARY_BLOCK, "Gas relative permeability in the R" } }, + { "BGKRR", { A::SUMMARY_BLOCK, "- Gas relative permeability in the -R" } }, + { "BGKRT", { A::SUMMARY_BLOCK, "Gas relative permeability in the T" } }, + { "BGKRT", { A::SUMMARY_BLOCK, "- Gas relative permeability in the -T" } }, + { "BRPV", { A::SUMMARY_BLOCK, "Pore Volume at Reservoir conditions" } }, + { "BPORV", { A::SUMMARY_BLOCK, "Cell Pore Volumes at Reference conditions" } }, + { "BOPV", { A::SUMMARY_BLOCK, "Pore Volume containing Oil" } }, + { "BWPV", { A::SUMMARY_BLOCK, "Pore Volume containing Water" } }, + { "BGPV", { A::SUMMARY_BLOCK, "Pore Volume containing Gas" } }, + { "BHPV", { A::SUMMARY_BLOCK, "Pore Volume containing Hydrocarbon" } }, + { "BRTM", { A::SUMMARY_BLOCK, "Transmissibility Multiplier associated with rock compaction" } }, + { "BPERMMOD", { A::SUMMARY_BLOCK, "Transmissibility Multiplier associated with rock compaction" } }, + { "BPERMMDX", { A::SUMMARY_BLOCK, "Directional Transmissibility Multipliers in the X direction, associated with rock compaction" } }, + { "BPERMMDY", { A::SUMMARY_BLOCK, "Directional Transmissibility Multipliers in the Y direction, associated with rock compaction" } }, + { "BPERMMDZ", { A::SUMMARY_BLOCK, "Directional Transmissibility Multipliers in the Z direction, associated with rock compaction" } }, + { "BPORVMOD", { A::SUMMARY_BLOCK, "Pore Volume Multiplier associated with rock compaction" } }, + { "BSIGMMOD", { A::SUMMARY_BLOCK, "Dual Porosity Sigma Multiplier associated with rock compaction" } }, + { "BTCNF", { A::SUMMARY_BLOCK, "Tracer Concentration" } }, + { "BTCNS", { A::SUMMARY_BLOCK, "Tracer Concentration" } }, + { "BTCN", { A::SUMMARY_BLOCK, "Tracer Concentration" } }, + { "BTIPT", { A::SUMMARY_BLOCK, "Tracer In Place" } }, + { "BTIPF", { A::SUMMARY_BLOCK, "Tracer In Place" } }, + { "BTIPS", { A::SUMMARY_BLOCK, "Tracer In Place" } }, + { "BAPI", { A::SUMMARY_BLOCK, "Oil API" } }, + { "BSCN", { A::SUMMARY_BLOCK, "Salt Cell Concentration" } }, + { "BSIP", { A::SUMMARY_BLOCK, "Salt In Place" } }, + { "BEWV_SAL", { A::SUMMARY_BLOCK, "Effective water viscosity due to salt concentration" } }, + { "BTCNFANI", { A::SUMMARY_BLOCK, "Anion Flowing Concentration" } }, + { "BTCNFCAT", { A::SUMMARY_BLOCK, "Cation Flowing Concentration" } }, + { "BTRADCAT", { A::SUMMARY_BLOCK, "Cation Rock Associated Concentration" } }, + { "BTSADCAT", { A::SUMMARY_BLOCK, "Cation Surfactant Associated Concentration" } }, + { "BESALSUR", { A::SUMMARY_BLOCK, "Effective Salinity with respect to Surfactant" } }, + { "BESALPLY", { A::SUMMARY_BLOCK, "Effective Salinity with respect to Polymer" } }, + { "BTCNFHEA", { A::SUMMARY_BLOCK, "Block Temperature" } }, + { "BTIPTHEA", { A::SUMMARY_BLOCK, "Difference in Energy in place between current and initial time" } }, + { "BTCNF", { A::SUMMARY_BLOCK, "Tracer Concentration" } }, + { "BTCNS", { A::SUMMARY_BLOCK, "Tracer Concentration" } }, + { "BTCN#", { A::SUMMARY_BLOCK, "Tracer concentration in phase # (1,2,3,...)" } }, + { "BTIPT", { A::SUMMARY_BLOCK, "Tracer In Place" } }, + { "BTIPF", { A::SUMMARY_BLOCK, "Tracer In Place" } }, + { "BTIPS", { A::SUMMARY_BLOCK, "Tracer In Place" } }, + { "BTIP#", { A::SUMMARY_BLOCK, "Tracer In Place in phase # (1,2,3,...)" } }, + { "BTADS", { A::SUMMARY_BLOCK, "Tracer Adsorption" } }, + { "BTDCY", { A::SUMMARY_BLOCK, "Decayed tracer" } }, + { "BCGC", { A::SUMMARY_BLOCK, "Bulk Coal Gas Concentration" } }, + { "BCSC", { A::SUMMARY_BLOCK, "Bulk Coal Solvent Concentration" } }, + { "BTCNFFOA", { A::SUMMARY_BLOCK, "Concentration" } }, + { "BFOAM", { A::SUMMARY_BLOCK, "Surfactant concentration" } }, + { "BTCNMFOA", { A::SUMMARY_BLOCK, "Capillary number" } }, + { "BFOAMCNM", { A::SUMMARY_BLOCK, "Capillary number" } }, + { "BTIPTFOA", { A::SUMMARY_BLOCK, "In Solution" } }, + { "BTADSFOA", { A::SUMMARY_BLOCK, "Adsorption" } }, + { "BTDCYFOA", { A::SUMMARY_BLOCK, "Decayed tracer" } }, + { "BTMOBFOA", { A::SUMMARY_BLOCK, "Gas mobility factor" } }, + { "BFOAMMOB", { A::SUMMARY_BLOCK, "Gas mobility factor" } }, + { "BTHLFFOA", { A::SUMMARY_BLOCK, "Decay Half life" } }, + { "BGI", { A::SUMMARY_BLOCK, "Block Gi value" } }, + { "BCCN", { A::SUMMARY_BLOCK, "Polymer Concentration" } }, + { "BCIP", { A::SUMMARY_BLOCK, "Polymer In Solution" } }, + { "BEPVIS", { A::SUMMARY_BLOCK, "Effective polymer solution viscosity" } }, + { "BVPOLY", { A::SUMMARY_BLOCK, "Effective polymer solution viscosity" } }, + { "BEMVIS", { A::SUMMARY_BLOCK, "Effective mixture" } }, + { "BEWV_POL", { A::SUMMARY_BLOCK, "Effective water viscosity" } }, + { "BCAD", { A::SUMMARY_BLOCK, "Polymer Adsorption concentration" } }, + { "BCDCS", { A::SUMMARY_BLOCK, "Polymer thermal degradation - total mass degraded in previous timestep" } }, + { "BCDCR", { A::SUMMARY_BLOCK, "Polymer thermal degradation - total degradation rate" } }, + { "BCDCP", { A::SUMMARY_BLOCK, "Polymer thermal degradation solution degradation rate" } }, + { "BCDCA", { A::SUMMARY_BLOCK, "Polymer thermal degradation adsorbed degradation rate" } }, + { "BCABnnn", { A::SUMMARY_BLOCK, "Adsorbed polymer by highest temperature band at which RRF was calculated" } }, + { "BSCN", { A::SUMMARY_BLOCK, "Salt Cell Concentration" } }, + { "BSIP", { A::SUMMARY_BLOCK, "Salt In Place" } }, + { "BFLOW0I", { A::SUMMARY_BLOCK, "Inter-block water flow rate in the positive I direction multiplied by the corresponding shear multiplier" } }, + { "BFLOW0J", { A::SUMMARY_BLOCK, "Inter-block water flow rate in the positive J direction multiplied by the corresponding shear multiplier" } }, + { "BFLOW0K", { A::SUMMARY_BLOCK, "Inter-block water flow rate in the positive K direction multiplied by the corresponding shear multiplier" } }, + { "BVELW0I", { A::SUMMARY_BLOCK, "Water velocity in the positive I direction multiplied by the corresponding shear multiplier" } }, + { "BVELW0J", { A::SUMMARY_BLOCK, "Water velocity in the positive J direction multiplied by the corresponding shear multiplier" } }, + { "BVELW0K", { A::SUMMARY_BLOCK, "Water velocity in the positive K direction multiplied by the corresponding shear multiplier" } }, + { "BPSHLZI", { A::SUMMARY_BLOCK, "Viscosity multiplier due to sheared water flow in the positive I direction" } }, + { "BPSHLZJ", { A::SUMMARY_BLOCK, "Viscosity multiplier due to sheared water flow in the positive J direction" } }, + { "BPSHLZK", { A::SUMMARY_BLOCK, "Viscosity multiplier due to sheared water flow in the positive K direction" } }, + { "BSRTW0I", { A::SUMMARY_BLOCK, "Water shear rate in the positive I direction prior to shear effects" } }, + { "BSRTW0J", { A::SUMMARY_BLOCK, "Water shear rate in the positive J direction prior to shear effects" } }, + { "BSRTW0K", { A::SUMMARY_BLOCK, "Water shear rate in the positive K direction prior to shear effects" } }, + { "BSRTWI", { A::SUMMARY_BLOCK, "Water shear rate in the positive I direction following shear effects" } }, + { "BSRTWJ", { A::SUMMARY_BLOCK, "Water shear rate in the positive J direction following shear effects" } }, + { "BSRTWK", { A::SUMMARY_BLOCK, "Water shear rate in the positive K direction following shear effects" } }, + { "BSHWVISI", { A::SUMMARY_BLOCK, "Shear viscosity of the water/polymer solution due to shear thinning/thickening in the positive I direction" } }, + { "BSHWVISJ", { A::SUMMARY_BLOCK, "Shear viscosity of the water/polymer solution due to shear thinning/thickening in the positive J direction" } }, + { "BSHWVISK", { A::SUMMARY_BLOCK, "Shear viscosity of the water/polymer solution due to shear thinning/thickening in the positive K direction" } }, + { "BNSAT", { A::SUMMARY_BLOCK, "Solvent SATuration" } }, + { "BNIP", { A::SUMMARY_BLOCK, "Solvent In Place" } }, + { "BNKR", { A::SUMMARY_BLOCK, "Solvent relative permeability" } }, + { "BTCNFSUR", { A::SUMMARY_BLOCK, "Concentration" } }, + { "BSURF", { A::SUMMARY_BLOCK, "Concentration in solution" } }, + { "BTIPTSUR", { A::SUMMARY_BLOCK, "In Solution" } }, + { "BTADSUR", { A::SUMMARY_BLOCK, "Adsorption" } }, + { "BTCASUR", { A::SUMMARY_BLOCK, "Log" } }, + { "BSURFCNM", { A::SUMMARY_BLOCK, "Log" } }, + { "BTSTSUR", { A::SUMMARY_BLOCK, "Surface tension" } }, + { "BSURFST", { A::SUMMARY_BLOCK, "Surface tension" } }, + { "BEWV_SUR", { A::SUMMARY_BLOCK, "Effective water viscosity due to surfactant concentration" } }, + { "BESVIS", { A::SUMMARY_BLOCK, "Effective water viscosity due to surfactant concentration" } }, + { "BTCNFALK", { A::SUMMARY_BLOCK, "Concentration" } }, + { "BTADSALK", { A::SUMMARY_BLOCK, "Adsorption" } }, + { "BTSTMALK", { A::SUMMARY_BLOCK, "Surface tension multiplier" } }, + { "BTSADALK", { A::SUMMARY_BLOCK, "Surfactant adsorption multiplier" } }, + { "BTPADALK", { A::SUMMARY_BLOCK, "Polymer adsorption multiplier" } }, + { "BKRGOE", { A::SUMMARY_BLOCK, "Equivalent relative permeability to gas for gas-oil system" } }, + { "BKRGWE", { A::SUMMARY_BLOCK, "Equivalent relative permeability to gas for gas-water system" } }, + { "BKRWGE", { A::SUMMARY_BLOCK, "Equivalent relative permeability to water for water-gas system" } }, + { "BKROWT", { A::SUMMARY_BLOCK, "Opposite saturation direction turning point relative permeability to oil for oil-water system" } }, + { "BKRWOT", { A::SUMMARY_BLOCK, "Opposite saturation direction turning point relative permeability to water for water-oil system" } }, + { "BKROGT", { A::SUMMARY_BLOCK, "Opposite saturation direction turning point relative permeability to oil for oil-gas system" } }, + { "BKRGOT", { A::SUMMARY_BLOCK, "Opposite saturation direction turning point relative permeability to gas for gas-oil system" } }, + { "BKRGWT", { A::SUMMARY_BLOCK, "Opposite saturation direction turning point relative permeability to gas for gas-water system" } }, + { "BKRWGT", { A::SUMMARY_BLOCK, "Opposite saturation direction turning point relative permeability to water for water-gas system" } }, + { "BIFTOW", { A::SUMMARY_BLOCK, "Oil-water interfacial tension" } }, + { "BIFTWO", { A::SUMMARY_BLOCK, "Water-oil interfacial tension" } }, + { "BIFTOG", { A::SUMMARY_BLOCK, "Oil-gas interfacial tension" } }, + { "BIFTGO", { A::SUMMARY_BLOCK, "Gas-oil interfacial tension" } }, + { "BIFTGW", { A::SUMMARY_BLOCK, "Gas-water interfacial tension" } }, + { "BIFTWG", { A::SUMMARY_BLOCK, "Water-gas interfacial tension" } }, + { "BPCOWR", { A::SUMMARY_BLOCK, "Representative oil-water capillary pressure" } }, + { "BPCWOR", { A::SUMMARY_BLOCK, "Representative water-oil capillary pressure" } }, + { "BPCOGR", { A::SUMMARY_BLOCK, "Representative oil-gas capillary pressure" } }, + { "BPCGOR", { A::SUMMARY_BLOCK, "Representative gas-oil capillary pressure" } }, + { "BPCGWR", { A::SUMMARY_BLOCK, "Representative gas-water capillary pressure" } }, + { "BPCWGR", { A::SUMMARY_BLOCK, "Representative water-gas capillary pressure" } }, - { "BPR", "Oil phase Pressure" }, - { "BPRESSUR", "Oil phase Pressure" }, - { "BWPR", "Water phase Pressure" }, - { "BGPR", "Gas phase Pressure" }, - { "BRS", "Gas-oil ratio" }, - { "BRV", "Oil-gas ratio" }, - { "BPBUB", "Bubble point pressure" }, - { "BPDEW", "Dew point pressure" }, - { "BRSSAT", "Saturated gas-oil ratio" }, - { "BRVSAT", "Saturated oil-gas ratio" }, - { "BSTATE", "Gas-oil state indicator" }, - { "BPPC", "Initial Contact Corrected Potential" }, - { "BOKR", "Oil relative permeability" }, - { "BWKR", "Water relative permeability" }, - { "BGKR", "Gas relative permeability" }, - { "BKRO", "Oil relative permeability" }, - { "BKROG", "Two-phase oil relative permeability to gas" }, - { "BKROW", "Two-phase oil relative permeability to water" }, - { "BKRG", "Gas relative permeability" }, - { "BKRGO", "Two-phase gas relative permeability to oil " }, - { "BKRGW", "Two-phase gas relative permeability to water" }, - { "BKRW", "Water relative permeability" }, - { "BKRWG", "Two-phase water relative permeability to gas" }, - { "BKRWO", "Two-phase water relative permeability to oil" }, - { "BRK", "Water relative permeability reduction factor due to polymer" }, - { "BEWKR", "Water effective relative permeability due to polymer" }, - { "BWPC", "Water-Oil capillary pressure" }, - { "BGPC", "Gas-Oil capillary pressure" }, - { "BPCO", "Oil Capillary Pressures" }, - { "BPCG", "Gas Capillary Pressures" }, - { "BPCW", "Water Capillary Pressures" }, - { "BGTRP", "Trapped gas saturation" }, - { "BGTPD", "Dynamic trapped gas saturation" }, - { "BGSHY", "Departure saturation from drainage to imbibition for gas capillary pressure hysteresis" }, - { "BGSTRP", "Trapped gas critical saturation for gas capillary pressure hysteresis" }, - { "BWSHY", "Departure saturation from drainage to imbibition for water capillary pressure hysteresis" }, - { "BWSMA", "Maximum wetting saturation for water capillary pressure hysteresis" }, - { "BMLSC", "Hydrocarbon molar density" }, - { "BMLST", "Total hydrocarbon molar density" }, - { "BMWAT", "Water molar density" }, - { "BROMLS", "Residual oil moles/ reservoir volume" }, - { "BJV", "In" }, - { "BVMF", "Vapor mole fraction" }, - { "BPSAT", "Saturation Pressures" }, - { "BAMF", "Component aqueous mole fraction" }, - { "BXMF", "Liquid hydrocarbon component mole fraction" }, - { "BYMF", "Vapor hydrocarbon component mole fraction / vapor steam" }, - { "BSMF", "CO2STORE with SOLID option only Solid hydrocarbon component mole fraction" }, - { "BSTEN", "Surface Tension" }, - { "BFMISC", "Miscibility Factor" }, - { "BREAC", "Reaction rate. The reaction number is given as a component index" }, - { "BHD", "Hydraulic head" }, - { "BHDF", "Hydraulic head at fresh water conditions" }, - { "BPR_X", "Pressure interpolated at a defined coordinate" }, - { "BHD_X", "Hydraulic head interpolated at a defined coordinate" }, - { "BHDF_X", "Hydraulic head at fresh water conditions interpolated at a defined coordinate" }, - { "BSCN_X", "Brine concentration interpolated at a defined coordinate" }, - { "BCTRA_X", "Tracer concentration interpolated at a defined coordinate" }, - { "LBPR_X", "Pressure interpolated at a defined coordinate within a local grid" }, - { "LBHD_X", "Hydraulic head interpolated at a defined coordinate within a local grid" }, - { "LBHDF_X", "Hydraulic head at freshwater conditions interpolated at a defined coordinate within a local grid" }, - { "LBSCN_X", "Brine concentration interpolated at a defined coordinate within a local grid" }, - { "LBCTRA_X", "Tracer concentration interpolated at a defined coordinate within a local grid" }, - { "BOKRX", "Oil relative permeability in the X direction" }, - { "BOKRX", "- Oil relative permeability in the -X direction" }, - { "BOKRY", "Oil relative permeability in the Y direction" }, - { "BOKRY", "- Oil relative permeability in the -Y direction" }, - { "BOKRZ", "Oil relative permeability in the Z direction" }, - { "BOKRZ", "- Oil relative permeability in the -Z direction" }, - { "BWKRX", "Water relative permeability in the X direction" }, - { "BWKRX", "- Water relative permeability in the -X direction" }, - { "BWKRY", "Water relative permeability in the Y direction" }, - { "BWKRY", "- Water relative permeability in the -Y direction" }, - { "BWKRZ", "Water relative permeability in the Z direction" }, - { "BWKRZ", "- Water relative permeability in the -Z direction" }, - { "BGKRX", "Gas relative permeability in the X direction" }, - { "BGKRX", "- Gas relative permeability in the -X direction" }, - { "BGKRY", "Gas relative permeability in the Y direction" }, - { "BGKRY", "- Gas relative permeability in the -Y direction" }, - { "BGKRZ", "Gas relative permeability in the Z direction" }, - { "BGKRZ", "- Gas relative permeability in the -Z direction" }, - { "BOKRI", "Oil relative permeability in the I direction" }, - { "BOKRI", "- Oil relative permeability in the -I direction" }, - { "BOKRJ", "Oil relative permeability in the J direction" }, - { "BOKRJ", "- Oil relative permeability in the -J direction" }, - { "BOKRK", "Oil relative permeability in the K direction" }, - { "BOKRK", "- Oil relative permeability in the -K direction" }, - { "BWKRI", "Water relative permeability in the I direction" }, - { "BWKRI", "- Water relative permeability in the -I direction" }, - { "BWKRJ", "Water relative permeability in the J direction" }, - { "BWKRJ", "- Water relative permeability in the -J direction" }, - { "BWKRK", "Water relative permeability in the K direction" }, - { "BWKRK", "- Water relative permeability in the -K direction" }, - { "BGKRI", "Gas relative permeability in the I direction" }, - { "BGKRI", "- Gas relative permeability in the -I direction" }, - { "BGKRJ", "Gas relative permeability in the J direction" }, - { "BGKRJ", "- Gas relative permeability in the -J direction" }, - { "BGKRK", "Gas relative permeability in the K direction" }, - { "BGKRK", "- Gas relative permeability in the -K direction" }, - { "BOKRR", "Oil relative permeability in the R" }, - { "BOKRR", "- Oil relative permeability in the -R" }, - { "BOKRT", "Oil relative permeability in the T" }, - { "BOKRT", "- Oil relative permeability in the -T" }, - { "BWKRR", "Water relative permeability in the R" }, - { "BWKRR", "- Water relative permeability in the -R" }, - { "BWKRT", "Water relative permeability in the T" }, - { "BWKRT", "- Water relative permeability in the -T" }, - { "BGKRR", "Gas relative permeability in the R" }, - { "BGKRR", "- Gas relative permeability in the -R" }, - { "BGKRT", "Gas relative permeability in the T" }, - { "BGKRT", "- Gas relative permeability in the -T" }, - { "BRPV", "Pore Volume at Reservoir conditions" }, - { "BPORV", "Cell Pore Volumes at Reference conditions" }, - { "BOPV", "Pore Volume containing Oil" }, - { "BWPV", "Pore Volume containing Water" }, - { "BGPV", "Pore Volume containing Gas" }, - { "BHPV", "Pore Volume containing Hydrocarbon" }, - { "BRTM", "Transmissibility Multiplier associated with rock compaction" }, - { "BPERMMOD", "Transmissibility Multiplier associated with rock compaction" }, - { "BPERMMDX", "Directional Transmissibility Multipliers in the X direction, associated with rock compaction" }, - { "BPERMMDY", "Directional Transmissibility Multipliers in the Y direction, associated with rock compaction" }, - { "BPERMMDZ", "Directional Transmissibility Multipliers in the Z direction, associated with rock compaction" }, - { "BPORVMOD", "Pore Volume Multiplier associated with rock compaction" }, - { "BSIGMMOD", "Dual Porosity Sigma Multiplier associated with rock compaction" }, - { "BTCNF", "Tracer Concentration" }, - { "BTCNS", "Tracer Concentration" }, - { "BTCN", "Tracer Concentration" }, - { "BTIPT", "Tracer In Place" }, - { "BTIPF", "Tracer In Place" }, - { "BTIPS", "Tracer In Place" }, - { "BAPI", "Oil API" }, - { "BSCN", "Salt Cell Concentration" }, - { "BSIP", "Salt In Place" }, - { "BEWV_SAL", "Effective water viscosity due to salt concentration" }, - { "BTCNFANI", "Anion Flowing Concentration" }, - { "BTCNFCAT", "Cation Flowing Concentration" }, - { "BTRADCAT", "Cation Rock Associated Concentration" }, - { "BTSADCAT", "Cation Surfactant Associated Concentration" }, - { "BESALSUR", "Effective Salinity with respect to Surfactant" }, - { "BESALPLY", "Effective Salinity with respect to Polymer" }, - { "BTCNFHEA", "Block Temperature" }, - { "BTIPTHEA", "Difference in Energy in place between current and initial time" }, - { "BTCNF", "Tracer Concentration" }, - { "BTCNS", "Tracer Concentration" }, - { "BTCN#", "Tracer concentration in phase # (1,2,3,...)" }, - { "BTIPT", "Tracer In Place" }, - { "BTIPF", "Tracer In Place" }, - { "BTIPS", "Tracer In Place" }, - { "BTIP#", "Tracer In Place in phase # (1,2,3,...)" }, - { "BTADS", "Tracer Adsorption" }, - { "BTDCY", "Decayed tracer" }, - { "BCGC", "Bulk Coal Gas Concentration" }, - { "BCSC", "Bulk Coal Solvent Concentration" }, - { "BTCNFFOA", "Concentration" }, - { "BFOAM", "Surfactant concentration" }, - { "BTCNMFOA", "Capillary number" }, - { "BFOAMCNM", "Capillary number" }, - { "BTIPTFOA", "In Solution" }, - { "BTADSFOA", "Adsorption" }, - { "BTDCYFOA", "Decayed tracer" }, - { "BTMOBFOA", "Gas mobility factor" }, - { "BFOAMMOB", "Gas mobility factor" }, - { "BTHLFFOA", "Decay Half life" }, - { "BGI", "Block Gi value" }, - { "BCCN", "Polymer Concentration" }, - { "BCIP", "Polymer In Solution" }, - { "BEPVIS", "Effective polymer solution viscosity" }, - { "BVPOLY", "Effective polymer solution viscosity" }, - { "BEMVIS", "Effective mixture" }, - { "BEWV_POL", "Effective water viscosity" }, - { "BCAD", "Polymer Adsorption concentration" }, - { "BCDCS", "Polymer thermal degradation - total mass degraded in previous timestep" }, - { "BCDCR", "Polymer thermal degradation - total degradation rate" }, - { "BCDCP", "Polymer thermal degradation solution degradation rate" }, - { "BCDCA", "Polymer thermal degradation adsorbed degradation rate" }, - { "BCABnnn", "Adsorbed polymer by highest temperature band at which RRF was calculated" }, - { "BSCN", "Salt Cell Concentration" }, - { "BSIP", "Salt In Place" }, - { "BFLOW0I", "Inter-block water flow rate in the positive I direction multiplied by the corresponding shear multiplier" }, - { "BFLOW0J", "Inter-block water flow rate in the positive J direction multiplied by the corresponding shear multiplier" }, - { "BFLOW0K", "Inter-block water flow rate in the positive K direction multiplied by the corresponding shear multiplier" }, - { "BVELW0I", "Water velocity in the positive I direction multiplied by the corresponding shear multiplier" }, - { "BVELW0J", "Water velocity in the positive J direction multiplied by the corresponding shear multiplier" }, - { "BVELW0K", "Water velocity in the positive K direction multiplied by the corresponding shear multiplier" }, - { "BPSHLZI", "Viscosity multiplier due to sheared water flow in the positive I direction" }, - { "BPSHLZJ", "Viscosity multiplier due to sheared water flow in the positive J direction" }, - { "BPSHLZK", "Viscosity multiplier due to sheared water flow in the positive K direction" }, - { "BSRTW0I", "Water shear rate in the positive I direction prior to shear effects" }, - { "BSRTW0J", "Water shear rate in the positive J direction prior to shear effects" }, - { "BSRTW0K", "Water shear rate in the positive K direction prior to shear effects" }, - { "BSRTWI", "Water shear rate in the positive I direction following shear effects" }, - { "BSRTWJ", "Water shear rate in the positive J direction following shear effects" }, - { "BSRTWK", "Water shear rate in the positive K direction following shear effects" }, - { "BSHWVISI", "Shear viscosity of the water/polymer solution due to shear thinning/thickening in the positive I direction" }, - { "BSHWVISJ", "Shear viscosity of the water/polymer solution due to shear thinning/thickening in the positive J direction" }, - { "BSHWVISK", "Shear viscosity of the water/polymer solution due to shear thinning/thickening in the positive K direction" }, - { "BNSAT", "Solvent SATuration" }, - { "BNIP", "Solvent In Place" }, - { "BNKR", "Solvent relative permeability" }, - { "BTCNFSUR", "Concentration" }, - { "BSURF", "Concentration in solution" }, - { "BTIPTSUR", "In Solution" }, - { "BTADSUR", "Adsorption" }, - { "BTCASUR", "Log" }, - { "BSURFCNM", "Log" }, - { "BTSTSUR", "Surface tension" }, - { "BSURFST", "Surface tension" }, - { "BEWV_SUR", "Effective water viscosity due to surfactant concentration" }, - { "BESVIS", "Effective water viscosity due to surfactant concentration" }, - { "BTCNFALK", "Concentration" }, - { "BTADSALK", "Adsorption" }, - { "BTSTMALK", "Surface tension multiplier" }, - { "BTSADALK", "Surfactant adsorption multiplier" }, - { "BTPADALK", "Polymer adsorption multiplier" }, - { "BKRGOE", "Equivalent relative permeability to gas for gas-oil system" }, - { "BKRGWE", "Equivalent relative permeability to gas for gas-water system" }, - { "BKRWGE", "Equivalent relative permeability to water for water-gas system" }, - { "BKROWT", "Opposite saturation direction turning point relative permeability to oil for oil-water system" }, - { "BKRWOT", "Opposite saturation direction turning point relative permeability to water for water-oil system" }, - { "BKROGT", "Opposite saturation direction turning point relative permeability to oil for oil-gas system" }, - { "BKRGOT", "Opposite saturation direction turning point relative permeability to gas for gas-oil system" }, - { "BKRGWT", "Opposite saturation direction turning point relative permeability to gas for gas-water system" }, - { "BKRWGT", "Opposite saturation direction turning point relative permeability to water for water-gas system" }, - { "BIFTOW", "Oil-water interfacial tension" }, - { "BIFTWO", "Water-oil interfacial tension" }, - { "BIFTOG", "Oil-gas interfacial tension" }, - { "BIFTGO", "Gas-oil interfacial tension" }, - { "BIFTGW", "Gas-water interfacial tension" }, - { "BIFTWG", "Water-gas interfacial tension" }, - { "BPCOWR", "Representative oil-water capillary pressure" }, - { "BPCWOR", "Representative water-oil capillary pressure" }, - { "BPCOGR", "Representative oil-gas capillary pressure" }, - { "BPCGOR", "Representative gas-oil capillary pressure" }, - { "BPCGWR", "Representative gas-water capillary pressure" }, - { "BPCWGR", "Representative water-gas capillary pressure" }, + { "SOFR", { A::SUMMARY_WELL_SEGMENT, "Segment Oil Flow Rate" } }, + { "SOFRF", { A::SUMMARY_WELL_SEGMENT, "Segment Free Oil Flow Rate" } }, + { "SOFRS", { A::SUMMARY_WELL_SEGMENT, "Segment Solution Oil Flow Rate" } }, + { "SWFR", { A::SUMMARY_WELL_SEGMENT, "Segment Water Flow Rate" } }, + { "SGFR", { A::SUMMARY_WELL_SEGMENT, "Segment Gas Flow Rate" } }, + { "SGFRF", { A::SUMMARY_WELL_SEGMENT, "Segment Free Gas Flow Rate" } }, + { "SGFRS", { A::SUMMARY_WELL_SEGMENT, "Segment Solution Gas Flow Rate" } }, + { "SKFR", { A::SUMMARY_WELL_SEGMENT, "Segment Component Flow Rate" } }, + { "SCWGFR", { A::SUMMARY_WELL_SEGMENT, "Segment Component Flow Rate as Wet Gas" } }, + { "SHFR", { A::SUMMARY_WELL_SEGMENT, "Segment Enthalpy Flow Rate" } }, + { "SWCT", { A::SUMMARY_WELL_SEGMENT, "Segment Water Cut" } }, + { "SGOR", { A::SUMMARY_WELL_SEGMENT, "Segment Gas Oil Ratio" } }, + { "SOGR", { A::SUMMARY_WELL_SEGMENT, "Segment Oil Gas Ratio" } }, + { "SWGR", { A::SUMMARY_WELL_SEGMENT, "Segment Water Gas Ratio" } }, + { "SPR", { A::SUMMARY_WELL_SEGMENT, "Segment Pressure" } }, + { "SPRD", { A::SUMMARY_WELL_SEGMENT, "Segment Pressure Drop" } }, + { "SPRDF", { A::SUMMARY_WELL_SEGMENT, "Segment Pressure Drop component due to Friction" } }, + { "SPRDH", { A::SUMMARY_WELL_SEGMENT, "Segment Pressure Drop component due to Hydrostatic head" } }, + { "SPRDA", { A::SUMMARY_WELL_SEGMENT, "Segment Pressure drop due to Acceleration head" } }, + { "SPRDM", { A::SUMMARY_WELL_SEGMENT, "Segment frictional Pressure Drop Multiplier" } }, + { "SPPOW", { A::SUMMARY_WELL_SEGMENT, "Working power of a pull through pump" } }, + { "SOFV", { A::SUMMARY_WELL_SEGMENT, "Segment Oil Flow Velocity" } }, + { "SWFV", { A::SUMMARY_WELL_SEGMENT, "Segment Water Flow Velocity" } }, + { "SGFV", { A::SUMMARY_WELL_SEGMENT, "Segment Gas Flow Velocity" } }, + { "SOHF", { A::SUMMARY_WELL_SEGMENT, "Segment Oil Holdup Fraction" } }, + { "SWHF", { A::SUMMARY_WELL_SEGMENT, "Segment Water Holdup Fraction" } }, + { "SGHF", { A::SUMMARY_WELL_SEGMENT, "Segment Gas Holdup Fraction" } }, + { "SDENM", { A::SUMMARY_WELL_SEGMENT, "Segment fluid mixture density" } }, + { "SOVIS", { A::SUMMARY_WELL_SEGMENT, "Segment oil viscosity" } }, + { "SWVIS", { A::SUMMARY_WELL_SEGMENT, "Segment water viscosity" } }, + { "SGVIS", { A::SUMMARY_WELL_SEGMENT, "Segment gas viscosity" } }, + { "SEMVIS", { A::SUMMARY_WELL_SEGMENT, "Segment effective mixture viscosity" } }, + { "SGLPP", { A::SUMMARY_WELL_SEGMENT, "Segment Gas-Liquid Profile Parameter, C0" } }, + { "SGLVD", { A::SUMMARY_WELL_SEGMENT, "Segment Gas-Liquid Drift Velocity, Vd" } }, + { "SOWPP", { A::SUMMARY_WELL_SEGMENT, "Segment Oil-Water Profile Parameter, C0" } }, + { "SOWVD", { A::SUMMARY_WELL_SEGMENT, "Segment Oil-Water Drift Velocity, Vd" } }, + { "SOIMR", { A::SUMMARY_WELL_SEGMENT, "Segment Oil Import Rate" } }, + { "SGIMR", { A::SUMMARY_WELL_SEGMENT, "Segment Gas Import Rate" } }, + { "SWIMR", { A::SUMMARY_WELL_SEGMENT, "Segment Water Import Rate" } }, + { "SHIMR", { A::SUMMARY_WELL_SEGMENT, "Segment Enthalpy Import Rate" } }, + { "SORMR", { A::SUMMARY_WELL_SEGMENT, "Segment Oil Removal Rate" } }, + { "SGRMR", { A::SUMMARY_WELL_SEGMENT, "Segment Gas Removal Rate" } }, + { "SWRMR", { A::SUMMARY_WELL_SEGMENT, "Segment Water Removal Rate" } }, + { "SHRMR", { A::SUMMARY_WELL_SEGMENT, "Segment Enthalpy Removal Rate" } }, + { "SOIMT", { A::SUMMARY_WELL_SEGMENT, "Segment Oil Import Total" } }, + { "SGIMT", { A::SUMMARY_WELL_SEGMENT, "Segment Gas Import Total" } }, + { "SWIMT", { A::SUMMARY_WELL_SEGMENT, "Segment Water Import Total" } }, + { "SHIMT", { A::SUMMARY_WELL_SEGMENT, "Segment Enthalpy Import Total" } }, + { "SORMT", { A::SUMMARY_WELL_SEGMENT, "Segment Oil Removal Total" } }, + { "SGRMT", { A::SUMMARY_WELL_SEGMENT, "Segment Gas Removal Total" } }, + { "SWRMT", { A::SUMMARY_WELL_SEGMENT, "Segment Water Removal Total" } }, + { "SHRMT", { A::SUMMARY_WELL_SEGMENT, "Segment Enthalpy Removal Total" } }, + { "SAPI", { A::SUMMARY_WELL_SEGMENT, "Segment API value" } }, + { "SCFR", { A::SUMMARY_WELL_SEGMENT, "Segment polymer flow rate" } }, + { "SCCN", { A::SUMMARY_WELL_SEGMENT, "Segment polymer concentration" } }, + { "SSFR", { A::SUMMARY_WELL_SEGMENT, "Segment brine flow rate" } }, + { "SSCN", { A::SUMMARY_WELL_SEGMENT, "Segment brine concentration" } }, + { "STFR", { A::SUMMARY_WELL_SEGMENT, "Segment tracer flow rate" } }, + { "STFC", { A::SUMMARY_WELL_SEGMENT, "Segment tracer concentration" } }, + { "SFD", { A::SUMMARY_WELL_SEGMENT, "Segment diameter for Karst Conduit Calcite Dissolution" } }, + { "SPSAT", { A::SUMMARY_WELL_SEGMENT, "Segment Psat" } }, + { "STEM", { A::SUMMARY_WELL_SEGMENT, "Segment Temperature" } }, + { "SENE", { A::SUMMARY_WELL_SEGMENT, "Segment Energy Density" } }, + { "SSQU", { A::SUMMARY_WELL_SEGMENT, "Segment Steam Quality" } }, + { "SCVPR", { A::SUMMARY_WELL_SEGMENT, "Segment Calorific Value Production Rate" } }, + { "SGQ", { A::SUMMARY_WELL_SEGMENT, "Segment Gas Quality" } }, + { "SCSA", { A::SUMMARY_WELL_SEGMENT, "Segment Cross Sectional Area" } }, + { "SSTR", { A::SUMMARY_WELL_SEGMENT, "Strength of ICD on segment" } }, + { "SFOPN", { A::SUMMARY_WELL_SEGMENT, "Setting of segment" } }, + { "SALQ", { A::SUMMARY_WELL_SEGMENT, "Artificial lift quantity for segment" } }, + { "SRRQR", { A::SUMMARY_WELL_SEGMENT, "Reach flow at current time" } }, + { "SRRQT", { A::SUMMARY_WELL_SEGMENT, "Reach cumulative flow" } }, + { "SRBQR", { A::SUMMARY_WELL_SEGMENT, "Branch flow at current time" } }, + { "SRBQT", { A::SUMMARY_WELL_SEGMENT, "Branch cumulative flow" } }, + { "SRTQR", { A::SUMMARY_WELL_SEGMENT, "River total flow at current time" } }, + { "SRTQT", { A::SUMMARY_WELL_SEGMENT, "River total cumulative flow" } }, + { "SRRFLOW", { A::SUMMARY_WELL_SEGMENT, "Reach flux through cross-sectional area at current time" } }, + { "SRRAREA", { A::SUMMARY_WELL_SEGMENT, "Reach area at current time" } }, + { "SRRDEPTH", { A::SUMMARY_WELL_SEGMENT, "Reach depth at current time" } }, + { "SRREXCH", { A::SUMMARY_WELL_SEGMENT, "Exchange flux at current time" } }, + { "SRRFRODE", { A::SUMMARY_WELL_SEGMENT, "Reach Froude number at current time" } }, + { "SRRHEAD", { A::SUMMARY_WELL_SEGMENT, "Reach hydraulic head at current time" } }, + { "SRTFR", { A::SUMMARY_WELL_SEGMENT, "Reach tracer flow rate" } }, + { "SRTFC", { A::SUMMARY_WELL_SEGMENT, "Reach tracer concentration" } }, + { "SRSFR", { A::SUMMARY_WELL_SEGMENT, "Reach brine flow rate through connections" } }, + { "SRSFC", { A::SUMMARY_WELL_SEGMENT, "Reach brine concentration" } }, + { "SU", { A::SUMMARY_WELL_SEGMENT, "User-defined segment quantity" } }, - { "SOFR", "Segment Oil Flow Rate" }, - { "SOFRF", "Segment Free Oil Flow Rate" }, - { "SOFRS", "Segment Solution Oil Flow Rate" }, - { "SWFR", "Segment Water Flow Rate" }, - { "SGFR", "Segment Gas Flow Rate" }, - { "SGFRF", "Segment Free Gas Flow Rate" }, - { "SGFRS", "Segment Solution Gas Flow Rate" }, - { "SKFR", "Segment Component Flow Rate" }, - { "SCWGFR", "Segment Component Flow Rate as Wet Gas" }, - { "SHFR", "Segment Enthalpy Flow Rate" }, - { "SWCT", "Segment Water Cut" }, - { "SGOR", "Segment Gas Oil Ratio" }, - { "SOGR", "Segment Oil Gas Ratio" }, - { "SWGR", "Segment Water Gas Ratio" }, - { "SPR", "Segment Pressure" }, - { "SPRD", "Segment Pressure Drop" }, - { "SPRDF", "Segment Pressure Drop component due to Friction" }, - { "SPRDH", "Segment Pressure Drop component due to Hydrostatic head" }, - { "SPRDA", "Segment Pressure drop due to Acceleration head" }, - { "SPRDM", "Segment frictional Pressure Drop Multiplier" }, - { "SPPOW", "Working power of a pull through pump" }, - { "SOFV", "Segment Oil Flow Velocity" }, - { "SWFV", "Segment Water Flow Velocity" }, - { "SGFV", "Segment Gas Flow Velocity" }, - { "SOHF", "Segment Oil Holdup Fraction" }, - { "SWHF", "Segment Water Holdup Fraction" }, - { "SGHF", "Segment Gas Holdup Fraction" }, - { "SDENM", "Segment fluid mixture density" }, - { "SOVIS", "Segment oil viscosity" }, - { "SWVIS", "Segment water viscosity" }, - { "SGVIS", "Segment gas viscosity" }, - { "SEMVIS", "Segment effective mixture viscosity" }, - { "SGLPP", "Segment Gas-Liquid Profile Parameter, C0" }, - { "SGLVD", "Segment Gas-Liquid Drift Velocity, Vd" }, - { "SOWPP", "Segment Oil-Water Profile Parameter, C0" }, - { "SOWVD", "Segment Oil-Water Drift Velocity, Vd" }, - { "SOIMR", "Segment Oil Import Rate" }, - { "SGIMR", "Segment Gas Import Rate" }, - { "SWIMR", "Segment Water Import Rate" }, - { "SHIMR", "Segment Enthalpy Import Rate" }, - { "SORMR", "Segment Oil Removal Rate" }, - { "SGRMR", "Segment Gas Removal Rate" }, - { "SWRMR", "Segment Water Removal Rate" }, - { "SHRMR", "Segment Enthalpy Removal Rate" }, - { "SOIMT", "Segment Oil Import Total" }, - { "SGIMT", "Segment Gas Import Total" }, - { "SWIMT", "Segment Water Import Total" }, - { "SHIMT", "Segment Enthalpy Import Total" }, - { "SORMT", "Segment Oil Removal Total" }, - { "SGRMT", "Segment Gas Removal Total" }, - { "SWRMT", "Segment Water Removal Total" }, - { "SHRMT", "Segment Enthalpy Removal Total" }, - { "SAPI", "Segment API value" }, - { "SCFR", "Segment polymer flow rate" }, - { "SCCN", "Segment polymer concentration" }, - { "SSFR", "Segment brine flow rate" }, - { "SSCN", "Segment brine concentration" }, - { "STFR", "Segment tracer flow rate" }, - { "STFC", "Segment tracer concentration" }, - { "SFD", "Segment diameter for Karst Conduit Calcite Dissolution" }, - { "SPSAT", "Segment Psat" }, - { "STEM", "Segment Temperature" }, - { "SENE", "Segment Energy Density" }, - { "SSQU", "Segment Steam Quality" }, - { "SCVPR", "Segment Calorific Value Production Rate" }, - { "SGQ", "Segment Gas Quality" }, - { "SCSA", "Segment Cross Sectional Area" }, - { "SSTR", "Strength of ICD on segment" }, - { "SFOPN", "Setting of segment" }, - { "SALQ", "Artificial lift quantity for segment" }, - { "SRRQR", "Reach flow at current time" }, - { "SRRQT", "Reach cumulative flow" }, - { "SRBQR", "Branch flow at current time" }, - { "SRBQT", "Branch cumulative flow" }, - { "SRTQR", "River total flow at current time" }, - { "SRTQT", "River total cumulative flow" }, - { "SRRFLOW", "Reach flux through cross-sectional area at current time" }, - { "SRRAREA", "Reach area at current time" }, - { "SRRDEPTH", "Reach depth at current time" }, - { "SRREXCH", "Exchange flux at current time" }, - { "SRRFRODE", "Reach Froude number at current time" }, - { "SRRHEAD", "Reach hydraulic head at current time" }, - { "SRTFR", "Reach tracer flow rate" }, - { "SRTFC", "Reach tracer concentration" }, - { "SRSFR", "Reach brine flow rate through connections" }, - { "SRSFC", "Reach brine concentration" }, - { "SU", "User-defined segment quantity" }, + { "AAQR", { A::SUMMARY_AQUIFER, "Aquifer influx rate" } }, + { "ALQR", { A::SUMMARY_AQUIFER, "Aquifer influx rate" } }, + { "AAQT", { A::SUMMARY_AQUIFER, "Cumulative aquifer influx" } }, + { "ALQT", { A::SUMMARY_AQUIFER, "Cumulative aquifer influx" } }, + { "AAQRG", { A::SUMMARY_AQUIFER, "Aquifer influx rate" } }, + { "ALQRG", { A::SUMMARY_AQUIFER, "Aquifer influx rate" } }, + { "AAQTG", { A::SUMMARY_AQUIFER, "Cumulative aquifer influx" } }, + { "ALQTG", { A::SUMMARY_AQUIFER, "Cumulative aquifer influx" } }, + { "AACMR", { A::SUMMARY_AQUIFER, "Aquifer component molar influx rate" } }, + { "AACMT", { A::SUMMARY_AQUIFER, "Aquifer component molar influx totals" } }, + { "AAQP", { A::SUMMARY_AQUIFER, "Aquifer pressure" } }, + { "AAQER", { A::SUMMARY_AQUIFER, "Aquifer thermal energy influx rate" } }, + { "AAQET", { A::SUMMARY_AQUIFER, "Cumulative aquifer thermal energy influx" } }, + { "AAQTEMP", { A::SUMMARY_AQUIFER, "Aquifer temperature" } }, + { "AAQENTH", { A::SUMMARY_AQUIFER, "Aquifer molar enthalpy" } }, + { "AAQTD", { A::SUMMARY_AQUIFER, "Aquifer dimensionless time" } }, + { "AAQPD", { A::SUMMARY_AQUIFER, "Aquifer dimensionless pressure" } }, + { "ANQR", { A::SUMMARY_AQUIFER, "Aquifer influx rate" } }, + { "ANQT", { A::SUMMARY_AQUIFER, "Cumulative aquifer influx" } }, + { "ANQP", { A::SUMMARY_AQUIFER, "Aquifer pressure" } }, - { "AAQR", "Aquifer influx rate" }, - { "ALQR", "Aquifer influx rate" }, - { "AAQT", "Cumulative aquifer influx" }, - { "ALQT", "Cumulative aquifer influx" }, - { "AAQRG", "Aquifer influx rate" }, - { "ALQRG", "Aquifer influx rate" }, - { "AAQTG", "Cumulative aquifer influx" }, - { "ALQTG", "Cumulative aquifer influx" }, - { "AACMR", "Aquifer component molar influx rate" }, - { "AACMT", "Aquifer component molar influx totals" }, - { "AAQP", "Aquifer pressure" }, - { "AAQER", "Aquifer thermal energy influx rate" }, - { "AAQET", "Cumulative aquifer thermal energy influx" }, - { "AAQTEMP", "Aquifer temperature" }, - { "AAQENTH", "Aquifer molar enthalpy" }, - { "AAQTD", "Aquifer dimensionless time" }, - { "AAQPD", "Aquifer dimensionless pressure" }, - { "ANQR", "Aquifer influx rate" }, - { "ANQT", "Cumulative aquifer influx" }, - { "ANQP", "Aquifer pressure" } + { "CPU", { A::SUMMARY_MISC, "CPU" } }, + { "DATE", { A::SUMMARY_MISC, "Date" } }, + { "DAY", { A::SUMMARY_MISC, "Day" } }, + { "ELAPSED", { A::SUMMARY_MISC, "Elapsed time in seconds" } }, + { "MLINEARS", { A::SUMMARY_MISC, "Number linear iterations for each timestep" } }, + { "MONTH", { A::SUMMARY_MISC, "Month" } }, + { "MSUMLINS", { A::SUMMARY_MISC, "Total number of linear iterations since the start of the run" } }, + { "MSUMNEWT", { A::SUMMARY_MISC, "Total number of Newton iterations since the start of the run" } }, + { "NEWTON", { A::SUMMARY_MISC, "Number of Newton iterations used for each timestep" } }, + { "STEPTYPE", { A::SUMMARY_MISC, "Step type" } }, + { "TCPU", { A::SUMMARY_MISC, "TCPU" } }, + { "TCPUDAY", { A::SUMMARY_MISC, "TCPUDAY" } }, + { "TCPUTS", { A::SUMMARY_MISC, "TCPUTS" } }, + { "TELAPLIN", { A::SUMMARY_MISC, "TELAPLIN" } }, + { "TIME", { A::SUMMARY_MISC, "Time" } }, + { "TIMESTEP", { A::SUMMARY_MISC, "Time step" } }, + { "TIMESTRY", { A::SUMMARY_MISC, "TIMESTRY" } }, + { "YEAR", { A::SUMMARY_MISC, "Year" } }, + { "YEARS", { A::SUMMARY_MISC, "Years" } } }; } diff --git a/ApplicationCode/UserInterface/RiuSummaryVectorDescriptionMap.h b/ApplicationCode/UserInterface/RiuSummaryVectorDescriptionMap.h index 1eac78fe8e..6ebc683129 100644 --- a/ApplicationCode/UserInterface/RiuSummaryVectorDescriptionMap.h +++ b/ApplicationCode/UserInterface/RiuSummaryVectorDescriptionMap.h @@ -18,10 +18,23 @@ #pragma once +#include "RifEclipseSummaryAddress.h" + #include #include +class RiuSummaryVectorInfo +{ +public: + RiuSummaryVectorInfo() : category(RifEclipseSummaryAddress::SUMMARY_INVALID) {} + RiuSummaryVectorInfo(RifEclipseSummaryAddress::SummaryVarCategory category, const std::string& longName) + : category(category), longName(longName) {} + + RifEclipseSummaryAddress::SummaryVarCategory category; + std::string longName; +}; + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -30,12 +43,14 @@ class RiuSummaryVectorDescriptionMap public: static RiuSummaryVectorDescriptionMap* instance(); - std::string fieldInfo(const std::string& field); + RiuSummaryVectorInfo vectorInfo(const std::string& vectorName); + std::string vectorLongName(const std::string& vectorName, + bool returnVectorNameIfNotFound = false); private: RiuSummaryVectorDescriptionMap(); void populateFieldToInfoMap(); private: - std::map m_summaryToDescMap; + std::map m_summaryToDescMap; }; diff --git a/ApplicationCode/UserInterface/RiuTextDialog.cpp b/ApplicationCode/UserInterface/RiuTextDialog.cpp index 2fb4be3e13..f7a87f7582 100644 --- a/ApplicationCode/UserInterface/RiuTextDialog.cpp +++ b/ApplicationCode/UserInterface/RiuTextDialog.cpp @@ -4,6 +4,7 @@ // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by +// it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // @@ -19,13 +20,19 @@ #include "RiuTextDialog.h" #include "RiuTools.h" +#include "RiaApplication.h" +#include "RiaQDateTimeTools.h" + +#include "SummaryPlotCommands/RicAsciiExportSummaryPlotFeature.h" + #include #include #include #include #include +#include - +#include //-------------------------------------------------------------------------------------------------- /// @@ -88,6 +95,30 @@ void RiuQPlainTextEdit::slotSelectAll() this->selectAll(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuQPlainTextEdit::slotExportToFile() +{ + // Get dialog + RiuShowTabbedPlotDataDialog* dialog = nullptr; + auto curr = parent(); + while (dialog == nullptr) + { + if (!curr) break; + dialog = dynamic_cast(curr); + if (dialog) break; + curr = curr->parent(); + } + + if(dialog) + { + QString defaultDir = RicAsciiExportSummaryPlotFeature::defaultExportDir(); + auto fileName = RicAsciiExportSummaryPlotFeature::getFileNameFromUserDialog(dialog->description(), defaultDir); + RicAsciiExportSummaryPlotFeature::exportTextToFile(fileName, this->toPlainText()); + } +} + //-------------------------------------------------------------------------------------------------- /// /// @@ -156,3 +187,157 @@ void RiuTextDialog::contextMenuEvent(QContextMenuEvent* event) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuShowTabbedPlotDataDialog::RiuShowTabbedPlotDataDialog(QWidget* parent /*= nullptr*/) + : QDialog(parent, RiuTools::defaultDialogFlags()) +{ + m_tabWidget = new QTabWidget(this); + + connect(m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(slotTabChanged(int))); + + for(auto timePeriod : RiaQDateTimeTools::dateTimePeriods()) + { + if(timePeriod == DateTimePeriod::DECADE) continue; + + QString tabTitle = + timePeriod == DateTimePeriod::NONE ? "No Resampling" : + QString("Plot Data, %1").arg(RiaQDateTimeTools::dateTimePeriodName(timePeriod)); + + RiuQPlainTextEdit* textEdit = new RiuQPlainTextEdit(); + textEdit->setReadOnly(true); + textEdit->setLineWrapMode(QPlainTextEdit::NoWrap); + + QFont font("Courier", 8); + textEdit->setFont(font); + textEdit->setContextMenuPolicy(Qt::NoContextMenu); + + auto fontWidth = QFontMetrics(font).width("m"); + textEdit->setTabStopWidth(fontWidth * 4); + + m_tabWidget->addTab(textEdit, tabTitle); + } + + QVBoxLayout* layout = new QVBoxLayout(); + layout->addWidget(m_tabWidget); + setLayout(layout); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuShowTabbedPlotDataDialog::setDescription(const QString& description) +{ + m_description = description; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuShowTabbedPlotDataDialog::description() const +{ + if (m_description.isEmpty()) return "Plot Data"; + return m_description; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuShowTabbedPlotDataDialog::setTextProvider(std::function textProvider) +{ + m_textProvider = textProvider; + + updateText(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuQPlainTextEdit * RiuShowTabbedPlotDataDialog::currentTextEdit() const +{ + return dynamic_cast(m_tabWidget->currentWidget()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +DateTimePeriod RiuShowTabbedPlotDataDialog::indexToPeriod(int index) +{ + auto currTabTitle = m_tabWidget->tabText(index); + if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_DAY_NAME)) return DateTimePeriod::DAY; + if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_WEEK_NAME)) return DateTimePeriod::WEEK; + if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_MONTH_NAME)) return DateTimePeriod::MONTH; + if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_QUARTER_NAME)) return DateTimePeriod::QUARTER; + if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_HALFYEAR_NAME)) return DateTimePeriod::HALFYEAR; + if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_YEAR_NAME)) return DateTimePeriod::YEAR; + if (currTabTitle.contains(RiaQDateTimeTools::TIMESPAN_DECADE_NAME)) return DateTimePeriod::DECADE; + return DateTimePeriod::NONE; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuShowTabbedPlotDataDialog::updateText() +{ + auto textEdit = currentTextEdit(); + auto currIndex = m_tabWidget->currentIndex(); + if (textEdit && textEdit->toPlainText().isEmpty() && m_textProvider) + { + textEdit->setPlainText(m_textProvider(indexToPeriod(currIndex))); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuShowTabbedPlotDataDialog::slotTabChanged(int index) +{ + updateText(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuShowTabbedPlotDataDialog::contextMenuEvent(QContextMenuEvent* event) +{ + QMenu menu; + RiuQPlainTextEdit* textEdit = dynamic_cast(m_tabWidget->currentWidget()); + + { + + QAction* actionToSetup = new QAction(this); + + actionToSetup->setText("Copy"); + actionToSetup->setIcon(QIcon(":/Copy.png")); + actionToSetup->setShortcuts(QKeySequence::Copy); + + connect(actionToSetup, SIGNAL(triggered()), textEdit, SLOT(slotCopyContentToClipboard())); + + menu.addAction(actionToSetup); + } + + { + QAction* actionToSetup = new QAction(this); + + actionToSetup->setText("Select All"); + actionToSetup->setShortcuts(QKeySequence::SelectAll); + + connect(actionToSetup, SIGNAL(triggered()), textEdit, SLOT(slotSelectAll())); + + menu.addAction(actionToSetup); + } + + { + QAction* actionToSetup = new QAction(this); + + actionToSetup->setText("Export to File..."); + //actionToSetup->setShortcuts(QKeySequence::); + + connect(actionToSetup, SIGNAL(triggered()), textEdit, SLOT(slotExportToFile())); + + menu.addAction(actionToSetup); + } + + menu.exec(event->globalPos()); +} diff --git a/ApplicationCode/UserInterface/RiuTextDialog.h b/ApplicationCode/UserInterface/RiuTextDialog.h index 7dffaa74e4..f666ef066d 100644 --- a/ApplicationCode/UserInterface/RiuTextDialog.h +++ b/ApplicationCode/UserInterface/RiuTextDialog.h @@ -18,10 +18,20 @@ #pragma once +#include "RiaQDateTimeTools.h" + #include #include +#include + +class QTabWidget; +class RimSummaryPlot; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- class RiuQPlainTextEdit : public QPlainTextEdit { Q_OBJECT @@ -29,12 +39,12 @@ class RiuQPlainTextEdit : public QPlainTextEdit explicit RiuQPlainTextEdit(QWidget *parent = nullptr) : QPlainTextEdit(parent) {} protected: - virtual void keyPressEvent(QKeyEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; private slots: void slotCopyContentToClipboard(); void slotSelectAll(); - + void slotExportToFile(); }; @@ -53,8 +63,37 @@ class RiuTextDialog : public QDialog private: RiuQPlainTextEdit* m_textEdit; protected: - virtual void contextMenuEvent(QContextMenuEvent *) override; + void contextMenuEvent(QContextMenuEvent *) override; }; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RiuShowTabbedPlotDataDialog : public QDialog +{ + Q_OBJECT + +public: + explicit RiuShowTabbedPlotDataDialog(QWidget* parent = nullptr); + + void setDescription(const QString& description); + QString description() const; + void setTextProvider(std::function textProvider); + +private: + RiuQPlainTextEdit * currentTextEdit() const; + DateTimePeriod indexToPeriod(int index); + void updateText(); + + QTabWidget* m_tabWidget; + QString m_description; + std::function m_textProvider; + +private slots: + void slotTabChanged(int index); + +protected: + void contextMenuEvent(QContextMenuEvent *) override; +}; diff --git a/ApplicationCode/UserInterface/RiuTofAccumulatedPhaseFractionsPlot.h b/ApplicationCode/UserInterface/RiuTofAccumulatedPhaseFractionsPlot.h index ac43f8167b..552c215e36 100644 --- a/ApplicationCode/UserInterface/RiuTofAccumulatedPhaseFractionsPlot.h +++ b/ApplicationCode/UserInterface/RiuTofAccumulatedPhaseFractionsPlot.h @@ -44,10 +44,10 @@ class RiuTofAccumulatedPhaseFractionsPlot : public QwtPlot, public RiuInterfaceT public: RiuTofAccumulatedPhaseFractionsPlot(RimTofAccumulatedPhaseFractionsPlot* plotDefinition, QWidget* parent = nullptr); - virtual ~RiuTofAccumulatedPhaseFractionsPlot(); + ~RiuTofAccumulatedPhaseFractionsPlot() override; RimTofAccumulatedPhaseFractionsPlot* ownerPlotDefinition(); - virtual RimViewWindow* ownerViewWindow() const override; + RimViewWindow* ownerViewWindow() const override; void setSamples(std::vector xSamples, std::vector watValues, @@ -56,8 +56,8 @@ class RiuTofAccumulatedPhaseFractionsPlot : public QwtPlot, public RiuInterfaceT int maxTofYears); protected: - virtual QSize sizeHint() const override; - virtual int heightForWidth(int w) const override; + QSize sizeHint() const override; + int heightForWidth(int w) const override; private: void setDefaults(); diff --git a/ApplicationCode/UserInterface/RiuToolTipMenu.h b/ApplicationCode/UserInterface/RiuToolTipMenu.h index d67ee41b7b..9ead364549 100644 --- a/ApplicationCode/UserInterface/RiuToolTipMenu.h +++ b/ApplicationCode/UserInterface/RiuToolTipMenu.h @@ -28,5 +28,5 @@ class RiuToolTipMenu : public QMenu public: explicit RiuToolTipMenu(QWidget * parent); - bool event(QEvent* e); + bool event(QEvent* e) override; }; diff --git a/ApplicationCode/UserInterface/RiuTreeViewEventFilter.h b/ApplicationCode/UserInterface/RiuTreeViewEventFilter.h index 37b950cf65..04e2980f17 100644 --- a/ApplicationCode/UserInterface/RiuTreeViewEventFilter.h +++ b/ApplicationCode/UserInterface/RiuTreeViewEventFilter.h @@ -32,5 +32,5 @@ class RiuTreeViewEventFilter : public QObject explicit RiuTreeViewEventFilter(QObject* parent); protected: - bool eventFilter(QObject *obj, QEvent *event); + bool eventFilter(QObject *obj, QEvent *event) override; }; \ No newline at end of file diff --git a/ApplicationCode/UserInterface/RiuViewer.cpp b/ApplicationCode/UserInterface/RiuViewer.cpp index 3e7ff17476..8df36b5af0 100644 --- a/ApplicationCode/UserInterface/RiuViewer.cpp +++ b/ApplicationCode/UserInterface/RiuViewer.cpp @@ -53,6 +53,7 @@ #include "cvfFont.h" #include "cvfOpenGLResourceManager.h" #include "cvfOverlayAxisCross.h" +#include "cvfPartRenderHintCollection.h" #include "cvfRenderQueueSorter.h" #include "cvfRenderSequence.h" #include "cvfRendering.h" @@ -65,6 +66,8 @@ #include "WindowEdgeAxesOverlayItem/RivWindowEdgeAxesOverlayItem.h" #include +#include "WellPathCommands/PointTangentManipulator/RicPointTangentManipulator.h" + using cvf::ManipulatorTrackball; @@ -184,6 +187,7 @@ RiuViewer::RiuViewer(const QGLFormat& format, QWidget* parent) m_windowEdgeAxisOverlay = new RivWindowEdgeAxesOverlayItem(standardFont); m_showWindowEdgeAxes = false; + m_selectionVisualizerManager = new caf::PdmUiSelectionVisualizer3d(this); } //-------------------------------------------------------------------------------------------------- @@ -506,21 +510,6 @@ void RiuViewer::mousePressEvent(QMouseEvent* event) m_lastMousePressPosition = event->pos(); } - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -cvf::Collection RiuViewer::allOverlayItems() -{ - cvf::Collection allOverLays; - for (size_t oIdx = 0; oIdx < m_mainRendering->overlayItemCount(); ++oIdx) - { - allOverLays.push_back(m_mainRendering->overlayItem(oIdx)); - } - return allOverLays; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -616,9 +605,9 @@ void RiuViewer::updateLegendLayout() yPos = border + edgeAxisBorderHeight; // Set same width to all legends in the column - for (caf::TitledOverlayFrame* legend : columnLegends ) + for (caf::TitledOverlayFrame* columnLegend : columnLegends ) { - legend->setRenderSize(cvf::Vec2ui(maxColumnWidht, legend->renderSize().y())); + columnLegend->setRenderSize(cvf::Vec2ui(maxColumnWidht, columnLegend->renderSize().y())); } maxColumnWidht = 0; columnLegends.clear(); @@ -830,20 +819,41 @@ void RiuViewer::updateGridBoxData(double scaleZ, m_gridBoxGenerator->setGridBoxDomainCoordBoundingBox(domainCoordBoundingBox); m_gridBoxGenerator->createGridBoxParts(); + + m_selectionVisualizerManager->updateVisibleEditors(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RiuViewer::showEdgeTickMarks(bool enable) +void RiuViewer::showEdgeTickMarksXY(bool enable, bool showAxisLines) { m_mainRendering->removeOverlayItem(m_windowEdgeAxisOverlay.p()); if (enable) { + m_windowEdgeAxisOverlay->setDomainAxes(RivWindowEdgeAxesOverlayItem::XY_AXES); + m_windowEdgeAxisOverlay->setIsSwitchingYAxisSign(false); + m_windowEdgeAxisOverlay->setShowAxisLines(showAxisLines); m_mainRendering->addOverlayItem(m_windowEdgeAxisOverlay.p()); } + m_showWindowEdgeAxes = enable; +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewer::showEdgeTickMarksXZ(bool enable, bool showAxisLines) +{ + m_mainRendering->removeOverlayItem(m_windowEdgeAxisOverlay.p()); + + if (enable) + { + m_windowEdgeAxisOverlay->setDomainAxes(RivWindowEdgeAxesOverlayItem::XZ_AXES); + m_windowEdgeAxisOverlay->setIsSwitchingYAxisSign(true); + m_windowEdgeAxisOverlay->setShowAxisLines(showAxisLines); + m_mainRendering->addOverlayItem(m_windowEdgeAxisOverlay.p()); + } m_showWindowEdgeAxes = enable; } @@ -896,26 +906,48 @@ cvf::OverlayItem* RiuViewer::pickFixedPositionedLegend(int winPosX, int winPosY) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuViewer::updateParallelProjectionSettings(RiuViewer* sourceViewer) +void RiuViewer::setCursorPosition(const cvf::Vec3d& domainCoord) { - if (!sourceViewer || sourceViewer->m_navigationPolicy.isNull()) return; + if (m_cursorPositionDomainCoords != domainCoord) + { + m_cursorPositionDomainCoords = domainCoord; - cvf::Vec3d poi = sourceViewer->m_navigationPolicy->pointOfInterest(); - this->updateParallelProjectionHeightFromMoveZoom(poi); - this->updateParallelProjectionCameraPosFromPointOfInterestMove(poi); + update(); + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuViewer::setCursorPosition(const cvf::Vec3d& domainCoord) +std::vector> RiuViewer::visibleParts() { - if (m_cursorPositionDomainCoords != domainCoord) + std::vector> partsMatchingEnableMask; + + if (m_mainRendering.notNull()) { - m_cursorPositionDomainCoords = domainCoord; + auto enableMask = m_mainRendering->enableMask(); + cvf::Scene* scene = currentScene(); - update(); + for (cvf::uint i = 0; i < scene->modelCount(); i++) + { + cvf::Model* model = scene->model(i); + if (enableMask & model->partEnableMask()) + { + cvf::Collection partCollection; + model->allParts(&partCollection); + + for (const auto& p : partCollection) + { + if (enableMask & p->enableMask()) + { + partsMatchingEnableMask.push_back(p); + } + } + } + } } + + return partsMatchingEnableMask; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/UserInterface/RiuViewer.h b/ApplicationCode/UserInterface/RiuViewer.h index c2b8eda882..a7820a60ae 100644 --- a/ApplicationCode/UserInterface/RiuViewer.h +++ b/ApplicationCode/UserInterface/RiuViewer.h @@ -45,6 +45,7 @@ class QProgressBar; namespace caf { class TitledOverlayFrame; + class PdmUiSelectionVisualizer3d; } namespace cvf @@ -68,7 +69,7 @@ class RiuViewer : public caf::Viewer, public RiuInterfaceToViewWindow public: RiuViewer(const QGLFormat& format, QWidget* parent); - ~RiuViewer(); + ~RiuViewer() override; void setDefaultView(); cvf::Vec3d pointOfInterest(); @@ -89,7 +90,8 @@ class RiuViewer : public caf::Viewer, public RiuInterfaceToViewWindow const cvf::Vec3d& displayModelOffset, const cvf::Color3f& backgroundColor, const cvf::BoundingBox& domainCoordBoundingBox); - void showEdgeTickMarks(bool enable); + void showEdgeTickMarksXY(bool enable, bool showAxisLines = false); + void showEdgeTickMarksXZ(bool enable, bool showAxisLines = false); void updateAnnotationItems(); @@ -101,7 +103,7 @@ class RiuViewer : public caf::Viewer, public RiuInterfaceToViewWindow void enableNavigationRotation(bool disable); void updateNavigationPolicy(); - virtual void navigationPolicyUpdate(); // Override of caf::Viewer::navigationPolicyUpdate() + void navigationPolicyUpdate() override; void setCurrentFrame(int frameIndex); @@ -112,19 +114,19 @@ class RiuViewer : public caf::Viewer, public RiuInterfaceToViewWindow cvf::OverlayItem* pickFixedPositionedLegend(int winPosX, int winPosY); - void updateParallelProjectionSettings(RiuViewer* sourceViewer); - void setCursorPosition(const cvf::Vec3d& domainCoord); + std::vector> visibleParts(); + public slots: - virtual void slotSetCurrentFrame(int frameIndex); - virtual void slotEndAnimation(); + void slotSetCurrentFrame(int frameIndex) override; + void slotEndAnimation() override; protected: - virtual void optimizeClippingPlanes(); - virtual void resizeGL(int width, int height); - virtual void mouseMoveEvent(QMouseEvent* e) override; - virtual void leaveEvent(QEvent *) override; + void optimizeClippingPlanes() override; + void resizeGL(int width, int height) override; + void mouseMoveEvent(QMouseEvent* e) override; + void leaveEvent(QEvent *) override; private: void updateLegendLayout(); @@ -135,10 +137,10 @@ public slots: void updateAxisCrossTextColor(); - void paintOverlayItems(QPainter* painter); + void paintOverlayItems(QPainter* painter) override; - void mouseReleaseEvent(QMouseEvent* event); - void mousePressEvent(QMouseEvent* event); + void mouseReleaseEvent(QMouseEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; private: QLabel* m_infoLabel; @@ -157,8 +159,6 @@ public slots: cvf::ref m_axisCross; bool m_showAxisCross; cvf::Collection m_visibleLegends; - cvf::Collection allOverlayItems(); - caf::PdmInterfacePointer m_rimView; QPoint m_lastMousePressPosition; @@ -169,6 +169,8 @@ public slots: cvf::ref m_windowEdgeAxisOverlay; bool m_showWindowEdgeAxes; + caf::PdmUiSelectionVisualizer3d* m_selectionVisualizerManager; + cvf::Vec3d m_cursorPositionDomainCoords; bool m_isNavigationRotationEnabled; }; diff --git a/ApplicationCode/UserInterface/RiuViewerCommands.cpp b/ApplicationCode/UserInterface/RiuViewerCommands.cpp index 3ff7f6bd8b..2b7b00893f 100644 --- a/ApplicationCode/UserInterface/RiuViewerCommands.cpp +++ b/ApplicationCode/UserInterface/RiuViewerCommands.cpp @@ -25,10 +25,11 @@ #include "RicEclipsePropertyFilterNewExec.h" #include "RicGeoMechPropertyFilterNewExec.h" -#include "RicViewerEventInterface.h" -#include "WellLogCommands/Ric3dWellLogCurveViewerEventHandler.h" -#include "WellPathCommands/RicIntersectionViewerEventHandler.h" -#include "WellPathCommands/RicWellPathViewerEventHandler.h" +#include "RicPickEventHandler.h" +#include "RicContourMapPickEventHandler.h" +#include "WellLogCommands/Ric3dWellLogCurvePickEventHandler.h" +#include "WellPathCommands/RicIntersectionPickEventHandler.h" +#include "WellPathCommands/RicWellPathPickEventHandler.h" #include "RigEclipseCaseData.h" #include "RigFault.h" @@ -65,6 +66,7 @@ #include "RiuResultTextBuilder.h" #include "RiuSelectionManager.h" #include "RiuViewer.h" +#include "RiuPickItemInfo.h" #include "RivFemPartGeometryGenerator.h" #include "RivFemPickSourceInfo.h" @@ -106,6 +108,9 @@ // RiaViewerCommands // //================================================================================================== +RicPickEventHandler* RiuViewerCommands::sm_overridingPickHandler = nullptr; + +std::vector RiuViewerCommands::sm_defaultPickEventHandlers; //-------------------------------------------------------------------------------------------------- /// @@ -118,16 +123,12 @@ RiuViewerCommands::RiuViewerCommands(RiuViewer* ownerViewer) , m_currentPickPositionInDomainCoords(cvf::Vec3d::UNDEFINED) , m_viewer(ownerViewer) { + if ( sm_defaultPickEventHandlers.empty() ) { - m_viewerEventHandlers.push_back(dynamic_cast(RicIntersectionViewerEventHandler::instance())); - } - - { - m_viewerEventHandlers.push_back(dynamic_cast(Ric3dWellLogCurveViewerEventHandler::instance())); - } - - { - m_viewerEventHandlers.push_back(dynamic_cast(RicWellPathViewerEventHandler::instance())); + addDefaultPickEventHandler(RicIntersectionPickEventHandler::instance()); + addDefaultPickEventHandler(Ric3dWellLogCurvePickEventHandler::instance()); + addDefaultPickEventHandler(RicWellPathPickEventHandler::instance()); + addDefaultPickEventHandler(RicContourMapPickEventHandler::instance()); } } @@ -147,55 +148,58 @@ void RiuViewerCommands::setOwnerView(Rim3dView * owner) m_reservoirView = owner; } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuViewerCommands::displayContextMenu(QMouseEvent* event) { - m_currentGridIdx = cvf::UNDEFINED_SIZE_T; - m_currentCellIndex = cvf::UNDEFINED_SIZE_T; - - int winPosX = event->x(); - int winPosY = event->y(); + // Do the ray pick, and extract the infos - QMenu menu; - caf::CmdFeatureMenuBuilder menuBuilder; + std::vector pickItemInfos; + { + cvf::HitItemCollection hitItems; + if (m_viewer->rayPick( event->x(), event->y(), &hitItems)) + { + pickItemInfos = RiuPickItemInfo::convertToPickItemInfos(hitItems); + } + } - uint firstPartTriangleIndex = cvf::UNDEFINED_UINT; - cvf::Vec3d localIntersectionPoint(cvf::Vec3d::ZERO); - cvf::Vec3d globalIntersectionPoint(cvf::Vec3d::ZERO); + // Find the following data const cvf::Part* firstHitPart = nullptr; - + uint firstPartTriangleIndex = cvf::UNDEFINED_UINT; m_currentPickPositionInDomainCoords = cvf::Vec3d::UNDEFINED; - // Check type of view - RimGridView* gridView = dynamic_cast(m_reservoirView.p()); - Rim2dIntersectionView* int2dView = dynamic_cast(m_reservoirView.p()); - - cvf::HitItemCollection hitItems; - if (m_viewer->rayPick(winPosX, winPosY, &hitItems)) + if (pickItemInfos.size()) { - std::vector> partAndTriangleIndexPairs; - extractIntersectionData(hitItems, &localIntersectionPoint, &globalIntersectionPoint, - &partAndTriangleIndexPairs, nullptr, nullptr); + cvf::Vec3d globalIntersectionPoint(cvf::Vec3d::ZERO); - for (const auto& partTringleIndex : partAndTriangleIndexPairs) + if ( pickItemInfos.size() ) { - if (!firstHitPart) + globalIntersectionPoint = pickItemInfos[0].globalPickedPoint(); + } + + for (const auto& pickItem : pickItemInfos) + { + const RivObjectSourceInfo* objectSourceInfo = dynamic_cast(pickItem.sourceInfo()); + if ( objectSourceInfo && dynamic_cast(objectSourceInfo->object()) ) { - auto part = partTringleIndex.first; - const RivObjectSourceInfo* objectSourceInfo = dynamic_cast(part->sourceInfo()); - if (objectSourceInfo && dynamic_cast(objectSourceInfo->object())) - { - // Skip picking on perforation interval, display well path context menu - continue; - } + // Skip picking on perforation interval, display well path context menu + continue; + } - firstHitPart = part; - firstPartTriangleIndex = partTringleIndex.second; - break; + const RivSourceInfo* rivSourceInfo = dynamic_cast(pickItem.sourceInfo()); + if ( rivSourceInfo && rivSourceInfo->hasNNCIndices()) + { + // Skip picking on nnc-s + continue; } + + firstHitPart = pickItem.pickedPart(); + firstPartTriangleIndex = pickItem.faceIdx(); + globalIntersectionPoint = pickItem.globalPickedPoint(); + break; } cvf::Vec3d displayModelOffset = cvf::Vec3d::ZERO; @@ -205,9 +209,20 @@ void RiuViewerCommands::displayContextMenu(QMouseEvent* event) cvf::ref transForm = m_reservoirView.p()->displayCoordTransform(); m_currentPickPositionInDomainCoords = transForm->transformToDomainCoord(globalIntersectionPoint); } - } + // Build menue + + QMenu menu; + caf::CmdFeatureMenuBuilder menuBuilder; + m_currentGridIdx = cvf::UNDEFINED_SIZE_T; + m_currentCellIndex = cvf::UNDEFINED_SIZE_T; + + // Check type of view + + RimGridView* gridView = dynamic_cast(m_reservoirView.p()); + Rim2dIntersectionView* int2dView = dynamic_cast(m_reservoirView.p()); + if (firstHitPart && firstPartTriangleIndex != cvf::UNDEFINED_UINT) { const RivSourceInfo* rivSourceInfo = dynamic_cast(firstHitPart->sourceInfo()); @@ -378,6 +393,7 @@ void RiuViewerCommands::displayContextMenu(QMouseEvent* event) menuBuilder.addSeparator(); menuBuilder << "RicShowWellAllocationPlotFeature"; + menuBuilder << "RicNewWellBoreStabilityPlotFeature"; menuBuilder.subMenuEnd(); @@ -391,9 +407,9 @@ void RiuViewerCommands::displayContextMenu(QMouseEvent* event) menuBuilder.subMenuEnd(); menuBuilder.addSeparator(); - + menuBuilder << "RicNewWellPathAttributeFeature"; menuBuilder.subMenuStart("Completions", QIcon(":/FishBoneGroup16x16.png")); - + menuBuilder << "RicNewWellPathFractureAtPosFeature"; menuBuilder << "RicNewFishbonesSubsAtMeasuredDepthFeature"; menuBuilder << "RicNewPerforationIntervalAtMeasuredDepthFeature"; @@ -489,11 +505,50 @@ void RiuViewerCommands::displayContextMenu(QMouseEvent* event) //-------------------------------------------------------------------------------------------------- void RiuViewerCommands::handlePickAction(int winPosX, int winPosY, Qt::KeyboardModifiers keyboardModifiers) { + // Overlay item picking + if (handleOverlayItemPicking(winPosX, winPosY)) { return; } + // Do the ray intersection with the scene + + std::vector pickItemInfos; + { + cvf::HitItemCollection hitItems; + if ( m_viewer->rayPick(winPosX, winPosY, &hitItems) ) + { + if ( hitItems.count() ) + { + pickItemInfos = RiuPickItemInfo::convertToPickItemInfos(hitItems); + } + } + } + + // Make pickEventHandlers do their stuff + + if ( pickItemInfos.size() ) + { + Ric3DPickEvent viewerEventObject(pickItemInfos, + m_reservoirView); + + if (sm_overridingPickHandler && sm_overridingPickHandler->handlePickEvent(viewerEventObject)) + { + return; + } + + for ( size_t i = 0; i < sm_defaultPickEventHandlers.size(); i++ ) + { + if ( sm_defaultPickEventHandlers[i]->handlePickEvent(viewerEventObject) ) + { + return; + } + } + } + + // Old pick handling. Todo: Encapsulate in pickEventHandlers + size_t gridIndex = cvf::UNDEFINED_SIZE_T; size_t cellIndex = cvf::UNDEFINED_SIZE_T; size_t nncIndex = cvf::UNDEFINED_SIZE_T; @@ -513,25 +568,37 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY, Qt::KeyboardM const cvf::Part* firstNncHitPart = nullptr; uint nncPartTriangleIndex = cvf::UNDEFINED_UINT; - cvf::HitItemCollection hitItems; - if (m_viewer->rayPick(winPosX, winPosY, &hitItems)) + if ( pickItemInfos.size() ) { - std::vector> partAndTriangleIndexPairs; - extractIntersectionData(hitItems, &localIntersectionPoint, &globalIntersectionPoint, &partAndTriangleIndexPairs, &firstNncHitPart, &nncPartTriangleIndex); + size_t indexToFirstNoneNncItem = cvf::UNDEFINED_SIZE_T;; + size_t indexToNncItemNearFirstItem = cvf::UNDEFINED_SIZE_T;; + + findFirstItems(pickItemInfos, &indexToFirstNoneNncItem, &indexToNncItemNearFirstItem); + + if ( indexToFirstNoneNncItem != cvf::UNDEFINED_SIZE_T ) + { + localIntersectionPoint = pickItemInfos[indexToFirstNoneNncItem].localPickedPoint(); + globalIntersectionPoint = pickItemInfos[indexToFirstNoneNncItem].globalPickedPoint(); + firstHitPart = pickItemInfos[indexToFirstNoneNncItem].pickedPart(); + firstPartTriangleIndex = pickItemInfos[indexToFirstNoneNncItem].faceIdx(); + } + + if ( indexToNncItemNearFirstItem != cvf::UNDEFINED_SIZE_T ) + { + firstNncHitPart = pickItemInfos[indexToNncItemNearFirstItem].pickedPart(); + nncPartTriangleIndex = pickItemInfos[indexToNncItemNearFirstItem].faceIdx(); + } + } - if (!partAndTriangleIndexPairs.empty()) + if (firstNncHitPart && firstNncHitPart->sourceInfo()) + { + const RivSourceInfo* rivSourceInfo = dynamic_cast(firstNncHitPart->sourceInfo()); + if (rivSourceInfo) { - RicViewerEventObject viewerEventObject(globalIntersectionPoint, partAndTriangleIndexPairs, m_reservoirView); - for (size_t i = 0; i < m_viewerEventHandlers.size(); i++) + if (nncPartTriangleIndex < rivSourceInfo->m_NNCIndices->size()) { - if (m_viewerEventHandlers[i]->handleEvent(viewerEventObject)) - { - return; - } + nncIndex = rivSourceInfo->m_NNCIndices->get(nncPartTriangleIndex); } - - firstHitPart = partAndTriangleIndexPairs.front().first; - firstPartTriangleIndex = partAndTriangleIndexPairs.front().second; } } @@ -664,8 +731,7 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY, Qt::KeyboardM const auto& multipleCompletions = connectionFactors->multipleCompletionsPerEclipseCell(wellConnectionSourceInfo->wellPath(), timeStep); - RigCompletionDataGridCell completionGridCell(globalCellIndex, eclipseCase->eclipseCaseData()->mainGrid()); - auto completionDataIt = multipleCompletions.find(completionGridCell); + auto completionDataIt = multipleCompletions.find(globalCellIndex); if (completionDataIt != multipleCompletions.end()) { completionsForOneCell = completionDataIt->second; @@ -751,22 +817,9 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY, Qt::KeyboardM } } - RiuMainWindow::instance()->selectAsCurrentItem(simWellConnectionSourceInfo->simWellInView(), allowActiveViewChange); } } - - if (firstNncHitPart && firstNncHitPart->sourceInfo()) - { - const RivSourceInfo* rivSourceInfo = dynamic_cast(firstNncHitPart->sourceInfo()); - if (rivSourceInfo) - { - if (nncPartTriangleIndex < rivSourceInfo->m_NNCIndices->size()) - { - nncIndex = rivSourceInfo->m_NNCIndices->get(nncPartTriangleIndex); - } - } - } } if (cellIndex == cvf::UNDEFINED_SIZE_T) @@ -831,6 +884,28 @@ void RiuViewerCommands::handlePickAction(int winPosX, int winPosY, Qt::KeyboardM } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewerCommands::setPickEventHandler(RicPickEventHandler* pickEventHandler) +{ + if (sm_overridingPickHandler) sm_overridingPickHandler->notifyUnregistered(); + + sm_overridingPickHandler = pickEventHandler; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewerCommands::removePickEventHandlerIfActive(RicPickEventHandler* pickEventHandler) +{ + if (sm_overridingPickHandler == pickEventHandler) + { + sm_overridingPickHandler = nullptr; + if (pickEventHandler) pickEventHandler->notifyUnregistered(); + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -839,6 +914,33 @@ cvf::Vec3d RiuViewerCommands::lastPickPositionInDomainCoords() const return m_currentPickPositionInDomainCoords; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewerCommands::addDefaultPickEventHandler(RicDefaultPickEventHandler* pickEventHandler) +{ + removeDefaultPickEventHandler(pickEventHandler); + if (pickEventHandler) + { + sm_defaultPickEventHandlers.push_back(pickEventHandler); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuViewerCommands::removeDefaultPickEventHandler(RicDefaultPickEventHandler* pickEventHandler) +{ + for ( auto it = sm_defaultPickEventHandlers.begin(); it != sm_defaultPickEventHandlers.end(); ++it ) + { + if ( *it == pickEventHandler ) + { + sm_defaultPickEventHandlers.erase(it); + break; + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -890,16 +992,17 @@ void RiuViewerCommands::findCellAndGridIndex(const RivIntersectionBoxSourceInfo* } } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuViewerCommands::extractIntersectionData(const cvf::HitItemCollection& hitItems, - cvf::Vec3d* localIntersectionPoint, - cvf::Vec3d*globalIntersectionPoint, - std::vector>* partAndTriangleIndexPairs, - const cvf::Part** nncPart, uint* nncPartFaceHit) +void RiuViewerCommands::findFirstItems(const std::vector & pickItemInfos, + size_t* indexToFirstNoneNncItem, + size_t* indexToNncItemNearFirsItem) { - CVF_ASSERT(hitItems.count() > 0); + CVF_ASSERT(pickItemInfos.size() > 0); + CVF_ASSERT(indexToFirstNoneNncItem); + CVF_ASSERT(indexToNncItemNearFirsItem); double pickDepthThresholdSquared = 0.05 *0.05; { @@ -913,121 +1016,53 @@ void RiuViewerCommands::extractIntersectionData(const cvf::HitItemCollection& hi } } - size_t firstNonNncPartIndex = cvf::UNDEFINED_SIZE_T; - cvf::Vec3d firstItemIntersectionPoint = hitItems.item(0)->intersectionPoint(); + size_t firstNonNncHitIndex = cvf::UNDEFINED_SIZE_T; + size_t nncNearFirstItemIndex = cvf::UNDEFINED_SIZE_T; + cvf::Vec3d firstOrFirstNonNncIntersectionPoint = pickItemInfos[0].globalPickedPoint(); - // Check if we have a close hit item with NNC data + // Find first nnc part, and store as a separate thing if the nnc is first or close behind the first hit item. + // Find index to first ordinary (non-nnc) part - for (size_t i = 0; i < hitItems.count(); i++) + for (size_t i = 0; i < pickItemInfos.size(); i++) { - const cvf::HitItem* hitItemCandidate = hitItems.item(i); - cvf::Vec3d diff = firstItemIntersectionPoint - hitItemCandidate->intersectionPoint(); - - const cvf::Part* pickedPartCandidate = hitItemCandidate->part(); - bool isNncpart = false; - - if (pickedPartCandidate && pickedPartCandidate->sourceInfo()) - { - const RivSourceInfo* rivSourceInfo = dynamic_cast(pickedPartCandidate->sourceInfo()); - if (rivSourceInfo && rivSourceInfo->hasNNCIndices()) - { - - // Hit items are ordered by distance from eye - if (diff.lengthSquared() < pickDepthThresholdSquared) - { - if (nncPart) - { - *nncPart = pickedPartCandidate; - } - - const cvf::HitDetailDrawableGeo* detail = dynamic_cast(hitItemCandidate->detail()); - if (detail && nncPartFaceHit) - { - *nncPartFaceHit = detail->faceIndex(); - } - - isNncpart = true; - } - } - } + // If hit item is nnc and is close to first (none-nnc) hit, store nncpart and face id - if (!isNncpart && firstNonNncPartIndex == cvf::UNDEFINED_SIZE_T) - { - firstItemIntersectionPoint = hitItemCandidate->intersectionPoint(); - firstNonNncPartIndex = i; - } - - if (firstNonNncPartIndex != cvf::UNDEFINED_SIZE_T && nncPart && *nncPart) - { - break; - } - } + bool canFindRelvantNNC = true; - if (firstNonNncPartIndex != cvf::UNDEFINED_SIZE_T) - { + const RivSourceInfo* rivSourceInfo = dynamic_cast(pickItemInfos[i].sourceInfo()); + if ( rivSourceInfo && rivSourceInfo->hasNNCIndices() ) { - const cvf::HitItem* firstNonNncHitItem = hitItems.item(firstNonNncPartIndex); - const cvf::Part* pickedPart = firstNonNncHitItem->part(); - CVF_ASSERT(pickedPart); - - const cvf::Transform* xf = pickedPart->transform(); - const cvf::Vec3d& globalPickedPoint = firstNonNncHitItem->intersectionPoint(); - - if (globalIntersectionPoint) + if ( nncNearFirstItemIndex == cvf::UNDEFINED_SIZE_T && canFindRelvantNNC) { - *globalIntersectionPoint = globalPickedPoint; - } + cvf::Vec3d distFirstNonNNCToCandidate = firstOrFirstNonNncIntersectionPoint - pickItemInfos[i].globalPickedPoint(); - if (localIntersectionPoint) - { - if (xf) + // This candidate is an NNC hit + if ( distFirstNonNNCToCandidate.lengthSquared() < pickDepthThresholdSquared ) { - *localIntersectionPoint = globalPickedPoint.getTransformedPoint(xf->worldTransform().getInverted()); + nncNearFirstItemIndex = i; } else { - *localIntersectionPoint = globalPickedPoint; + canFindRelvantNNC = false; } } } - - for (size_t i = firstNonNncPartIndex; i < hitItems.count(); i++) + else { - const cvf::HitItem* hitItem = hitItems.item(i); - const cvf::Part* pickedPart = hitItem->part(); - - cvf::uint faceIndex = cvf::UNDEFINED_UINT; - const cvf::HitDetailDrawableGeo* detail = dynamic_cast(hitItem->detail()); - if (detail) + if ( firstNonNncHitIndex == cvf::UNDEFINED_SIZE_T ) { - faceIndex = detail->faceIndex(); + firstNonNncHitIndex = i; } - - partAndTriangleIndexPairs->push_back(std::make_pair(pickedPart, faceIndex)); } - } - else - { - if (localIntersectionPoint && nncPart && *nncPart) - { - const cvf::Vec3d& globalPickedPoint = firstItemIntersectionPoint; - - if (globalIntersectionPoint) - { - *globalIntersectionPoint = globalPickedPoint; - } - const cvf::Transform* xf = (*nncPart)->transform(); - if (xf) - { - *localIntersectionPoint = globalPickedPoint.getTransformedPoint(xf->worldTransform().getInverted()); - } - else - { - *localIntersectionPoint = globalPickedPoint; - } + if (firstNonNncHitIndex != cvf::UNDEFINED_SIZE_T && (nncNearFirstItemIndex != cvf::UNDEFINED_SIZE_T || !canFindRelvantNNC) ) + { + break; // Found what can be found } } + + (*indexToFirstNoneNncItem) = firstNonNncHitIndex; + (*indexToNncItemNearFirsItem) = nncNearFirstItemIndex; } //-------------------------------------------------------------------------------------------------- @@ -1045,7 +1080,7 @@ void RiuViewerCommands::ijkFromCellIndex(size_t gridIdx, size_t cellIndex, size if (geomView && geomView->geoMechCase()) { - geomView->femParts()->part(gridIdx)->structGrid()->ijkFromCellIndex(cellIndex, i, j, k); + geomView->femParts()->part(gridIdx)->getOrCreateStructGrid()->ijkFromCellIndex(cellIndex, i, j, k); } } diff --git a/ApplicationCode/UserInterface/RiuViewerCommands.h b/ApplicationCode/UserInterface/RiuViewerCommands.h index ae867ac110..7ee7e0f410 100644 --- a/ApplicationCode/UserInterface/RiuViewerCommands.h +++ b/ApplicationCode/UserInterface/RiuViewerCommands.h @@ -25,7 +25,8 @@ #include #include -class RicViewerEventInterface; +class RicDefaultPickEventHandler; +class RicPickEventHandler; class RimEclipseView; class RimGeoMechView; class RimIntersection; @@ -33,6 +34,7 @@ class Rim3dView; class RiuViewer; class RivIntersectionBoxSourceInfo; class RivIntersectionSourceInfo; +class RiuPickItemInfo; class QMouseEvent; @@ -51,23 +53,32 @@ class RiuViewerCommands: public QObject public: explicit RiuViewerCommands(RiuViewer* ownerViewer); - ~RiuViewerCommands(); + ~RiuViewerCommands() override; void setOwnerView(Rim3dView * owner); void displayContextMenu(QMouseEvent* event); void handlePickAction(int winPosX, int winPosY, Qt::KeyboardModifiers keyboardModifiers); - cvf::Vec3d lastPickPositionInDomainCoords() const; + static void setPickEventHandler(RicPickEventHandler* pickEventHandler); + static void removePickEventHandlerIfActive(RicPickEventHandler* pickEventHandler); + + cvf::Vec3d lastPickPositionInDomainCoords() const; private: void findCellAndGridIndex(const RivIntersectionSourceInfo* crossSectionSourceInfo, cvf::uint firstPartTriangleIndex, size_t* cellIndex, size_t* gridIndex); void findCellAndGridIndex(const RivIntersectionBoxSourceInfo* intersectionBoxSourceInfo, cvf::uint firstPartTriangleIndex, size_t* cellIndex, size_t* gridIndex); void ijkFromCellIndex(size_t gridIdx, size_t cellIndex, size_t* i, size_t* j, size_t* k); - void extractIntersectionData(const cvf::HitItemCollection& hitItems, cvf::Vec3d* localIntersectionPoint, cvf::Vec3d* globalIntersectionPoint, std::vector>* partAndTriangleIndexPairs, const cvf::Part** nncPart, uint* nncPartFaceHit); + + void findFirstItems(const std::vector & pickItemInfos, + size_t* indexToFirstNoneNncItem, + size_t* indexToNncItemNearFirsItem); bool handleOverlayItemPicking(int winPosX, int winPosY); + static void addDefaultPickEventHandler(RicDefaultPickEventHandler* pickEventHandler); + static void removeDefaultPickEventHandler(RicDefaultPickEventHandler* pickEventHandler); + private: size_t m_currentGridIdx; size_t m_currentCellIndex; @@ -75,5 +86,7 @@ class RiuViewerCommands: public QObject cvf::Vec3d m_currentPickPositionInDomainCoords; caf::PdmPointer m_reservoirView; QPointer m_viewer; - std::vector m_viewerEventHandlers; + + static RicPickEventHandler* sm_overridingPickHandler; + static std::vector sm_defaultPickEventHandlers; }; diff --git a/ApplicationCode/UserInterface/RiuWellAllocationPlot.cpp b/ApplicationCode/UserInterface/RiuWellAllocationPlot.cpp index ecd47ffad5..0b13abacdb 100644 --- a/ApplicationCode/UserInterface/RiuWellAllocationPlot.cpp +++ b/ApplicationCode/UserInterface/RiuWellAllocationPlot.cpp @@ -94,7 +94,7 @@ RiuWellAllocationPlot::RiuWellAllocationPlot(RimWellAllocationPlot* plotDefiniti rightColumnLayout->addWidget(m_plotDefinition->tofAccumulatedPhaseFractionsPlot()->createViewWidget(this), Qt::AlignTop); rightColumnLayout->addStretch(); - QWidget* wellFlowWidget = m_plotDefinition->accumulatedWellFlowPlot()->createViewWidget(this); + QWidget* wellFlowWidget = m_plotDefinition->accumulatedWellFlowPlot()->createPlotWidget(); plotWidgetsLayout->addWidget(wellFlowWidget); } diff --git a/ApplicationCode/UserInterface/RiuWellAllocationPlot.h b/ApplicationCode/UserInterface/RiuWellAllocationPlot.h index 52494bb749..eb4af0d0b6 100644 --- a/ApplicationCode/UserInterface/RiuWellAllocationPlot.h +++ b/ApplicationCode/UserInterface/RiuWellAllocationPlot.h @@ -46,10 +46,10 @@ class RiuWellAllocationPlot : public QFrame, public RiuInterfaceToViewWindow Q_OBJECT; public: RiuWellAllocationPlot(RimWellAllocationPlot* plotDefinition, QWidget* parent = nullptr); - virtual ~RiuWellAllocationPlot(); + ~RiuWellAllocationPlot() override; RimWellAllocationPlot* ownerPlotDefinition(); - virtual RimViewWindow* ownerViewWindow() const override; + RimViewWindow* ownerViewWindow() const override; void showTitle(const QString& title); void hideTitle(); @@ -59,10 +59,10 @@ class RiuWellAllocationPlot : public QFrame, public RiuInterfaceToViewWindow protected: - virtual QSize sizeHint() const override; - virtual QSize minimumSizeHint() const override; + QSize sizeHint() const override; + QSize minimumSizeHint() const override; - virtual void contextMenuEvent(QContextMenuEvent *) override; + void contextMenuEvent(QContextMenuEvent *) override; private: void setDefaults(); diff --git a/ApplicationCode/UserInterface/RiuWellLogPlot.cpp b/ApplicationCode/UserInterface/RiuWellLogPlot.cpp index 42c039695d..00dc18b030 100644 --- a/ApplicationCode/UserInterface/RiuWellLogPlot.cpp +++ b/ApplicationCode/UserInterface/RiuWellLogPlot.cpp @@ -19,11 +19,14 @@ #include "RiuWellLogPlot.h" +#include "RiaApplication.h" + #include "RimContextCommandBuilder.h" #include "RimWellLogPlot.h" #include "RimWellLogTrack.h" #include "RiuMainWindow.h" +#include "RiuPlotMainWindow.h" #include "RiuWellLogTrack.h" #include "cafSelectionManager.h" @@ -32,13 +35,14 @@ #include "cvfAssert.h" #include "qwt_legend.h" +#include "qwt_plot_layout.h" #include #include #include +#include #include #include -#include #include @@ -57,12 +61,19 @@ RiuWellLogPlot::RiuWellLogPlot(RimWellLogPlot* plotDefinition, QWidget* parent) setAutoFillBackground(true); + m_plotTitle = new QLabel("PLOT TITLE HERE", this); + QFont font = m_plotTitle->font(); + font.setPointSize(14); + font.setBold(true); + m_plotTitle->setFont(font); + m_plotTitle->hide(); m_scrollBar = new QScrollBar(this); m_scrollBar->setOrientation(Qt::Vertical); m_scrollBar->setVisible(true); this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + setFocusPolicy(Qt::StrongFocus); connect(m_scrollBar, SIGNAL(valueChanged(int)), this, SLOT(slotSetMinDepth(int))); } @@ -97,14 +108,23 @@ void RiuWellLogPlot::insertTrackPlot(RiuWellLogTrack* trackPlot, size_t index) m_trackPlots.insert(static_cast(index), trackPlot); QwtLegend* legend = new QwtLegend(this); - legend->setMaxColumns(1); + int legendColumns = 1; + if (m_plotDefinition->areTrackLegendsHorizontal()) + { + legendColumns = 0; // unlimited + } + legend->setMaxColumns(legendColumns); + + legend->horizontalScrollBar()->setVisible(false); + legend->verticalScrollBar()->setVisible(false); + legend->connect(trackPlot, SIGNAL(legendDataChanged(const QVariant &, const QList< QwtLegendData > &)), SLOT(updateLegend(const QVariant &, const QList< QwtLegendData > &))); legend->contentsWidget()->layout()->setAlignment(Qt::AlignBottom | Qt::AlignHCenter); m_legends.insert(static_cast(index), legend); - - this->connect(trackPlot, SIGNAL(legendDataChanged(const QVariant &, const QList< QwtLegendData > &)), SLOT(scheduleUpdateChildrenLayout())); - if (!m_plotDefinition->isTrackLegendsVisible()) + this->connect(trackPlot, SIGNAL(legendDataChanged(const QVariant &, const QList< QwtLegendData > &)), SLOT(scheduleUpdateChildrenLayout())); + + if (!m_plotDefinition->areTrackLegendsVisible()) { legend->hide(); } @@ -119,8 +139,6 @@ void RiuWellLogPlot::insertTrackPlot(RiuWellLogTrack* trackPlot, size_t index) { trackPlot->hide(); } - - modifyWidthOfContainingMdiWindow(trackPlot->width()); } //-------------------------------------------------------------------------------------------------- @@ -130,8 +148,6 @@ void RiuWellLogPlot::removeTrackPlot(RiuWellLogTrack* trackPlot) { if (!trackPlot) return; - int windowWidthChange = - trackPlot->width(); - int trackIdx = m_trackPlots.indexOf(trackPlot); CVF_ASSERT(trackIdx >= 0); @@ -141,50 +157,6 @@ void RiuWellLogPlot::removeTrackPlot(RiuWellLogTrack* trackPlot) QwtLegend* legend = m_legends[trackIdx]; m_legends.removeAt(trackIdx); delete legend; - - modifyWidthOfContainingMdiWindow(windowWidthChange); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuWellLogPlot::modifyWidthOfContainingMdiWindow(int widthChange) -{ - QMdiSubWindow* mdiWindow = RiuMainWindow::instance()->findMdiSubWindow(this); - if (mdiWindow) - { - if (m_trackPlots.size() == 0 && widthChange <= 0) return; // Last track removed. Leave be - - QSize subWindowSize = mdiWindow->size(); - int newWidth = 0; - - if (m_trackPlots.size() == 1 && widthChange > 0) // First track added - { - newWidth = widthChange; - } - else - { - newWidth = subWindowSize.width() + widthChange; - } - - if (newWidth < 0) newWidth = 100; - - subWindowSize.setWidth(newWidth); - mdiWindow->resize(subWindowSize); - - if (mdiWindow->isMaximized()) - { - // Set window temporarily to normal state and back to maximized - // to redo layout so the whole window canvas is filled - // Tried to activate layout, did not work as expected - // Tested code: - // m_layout->activate(); - // mdiWindow->layout()->activate(); - - mdiWindow->showNormal(); - mdiWindow->showMaximized(); - } - } } //-------------------------------------------------------------------------------------------------- @@ -201,12 +173,36 @@ void RiuWellLogPlot::setDepthZoomAndReplot(double minDepth, double maxDepth) updateScrollBar(minDepth, maxDepth); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::setPlotTitle(const QString& plotTitle) +{ + m_plotTitle->setText(plotTitle); + this->updateChildrenLayout(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QSize RiuWellLogPlot::sizeHint() const +QSize RiuWellLogPlot::preferredSize() const { - return QSize(1,1); + int titleWidth = 0; + int titleHeight = 0; + if (m_plotTitle && m_plotTitle->isVisible()) + { + titleWidth = m_plotTitle->width(); + titleHeight = m_plotTitle->height() + 10; + } + + int sumTrackWidth = 0; + int maxTrackHeight = 0; + for (QPointer track : m_trackPlots) + { + sumTrackWidth += track->width(); + maxTrackHeight = std::max(maxTrackHeight, track->height()); + } + return QSize(std::max(titleWidth, sumTrackWidth), titleHeight + maxTrackHeight); } //-------------------------------------------------------------------------------------------------- @@ -230,6 +226,22 @@ void RiuWellLogPlot::contextMenuEvent(QContextMenuEvent* event) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize RiuWellLogPlot::sizeHint() const +{ + return QSize(1, 1); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::keyPressEvent(QKeyEvent* keyEvent) +{ + m_plotDefinition->handleKeyPressEvent(keyEvent); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -296,77 +308,202 @@ void RiuWellLogPlot::resizeEvent(QResizeEvent *event) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RiuWellLogPlot::placeChildWidgets(int height, int width) +std::map RiuWellLogPlot::calculateTrackWidthsToMatchFrame(int frameWidth) const { int trackCount = m_trackPlots.size(); - CVF_ASSERT(m_legends.size() == trackCount); - + int visibleTrackCount = 0; + int firstTrackAxisOffset = 0; // Account for first track having the y-axis labels and markers for (int tIdx = 0; tIdx < trackCount; ++tIdx) { - if (m_trackPlots[tIdx]->isVisible()) ++visibleTrackCount; + if (m_trackPlots[tIdx]->isVisible()) + { + if (visibleTrackCount == 0) + { + firstTrackAxisOffset = static_cast(m_trackPlots[tIdx]->plotLayout()->canvasRect().left()); + } + else if (visibleTrackCount == 1) + { + // The others axes also have markers, and so we need to subtract for this to get the shift due to labels and title + int otherTrackAxisOffset = static_cast(m_trackPlots[tIdx]->plotLayout()->canvasRect().left()); + firstTrackAxisOffset -= otherTrackAxisOffset; + } + ++visibleTrackCount; + } } int scrollBarWidth = 0; if (m_scrollBar->isVisible()) scrollBarWidth = m_scrollBar->sizeHint().width(); + + std::map trackWidths; + + if (visibleTrackCount) + { + int totalTrackWidth = (frameWidth - firstTrackAxisOffset - scrollBarWidth); + int trackWidthExtra = (frameWidth - firstTrackAxisOffset - scrollBarWidth) % visibleTrackCount; + + int totalWidthWeights = 0; + for (int tIdx = 0; tIdx < trackCount; ++tIdx) + { + if (m_trackPlots[tIdx]->isVisible()) + { + totalWidthWeights += m_trackPlots[tIdx]->widthScaleFactor(); + } + } + + bool firstVisible = true; + for (int tIdx = 0; tIdx < trackCount; ++tIdx) + { + if (m_trackPlots[tIdx]->isVisible()) + { + int realTrackWidth = (totalTrackWidth * m_trackPlots[tIdx]->widthScaleFactor()) / totalWidthWeights; + + if (firstVisible) + { + realTrackWidth += firstTrackAxisOffset; + firstVisible = false; + } + + if (trackWidthExtra > 0) + { + realTrackWidth += 1; + --trackWidthExtra; + } + + trackWidths[tIdx] = realTrackWidth; + } + } + } + + return trackWidths; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::placeChildWidgets(int frameHeight, int frameWidth) +{ + CVF_ASSERT(m_legends.size() == m_trackPlots.size()); + + positionTitle(frameWidth); + + const int trackPadding = 2; + + std::map trackWidths = calculateTrackWidthsToMatchFrame(frameWidth); + size_t visibleTrackCount = trackWidths.size(); int maxLegendHeight = 0; - if (m_plotDefinition && m_plotDefinition->isTrackLegendsVisible()) + if (m_plotDefinition && m_plotDefinition->areTrackLegendsVisible()) { - for ( int tIdx = 0; tIdx < trackCount; ++tIdx ) + for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx ) { if ( m_trackPlots[tIdx]->isVisible() ) { - int legendHeight = m_legends[tIdx]->sizeHint().height(); + int legendHeight = m_legends[tIdx]->heightForWidth(trackWidths[tIdx] - 2 * trackPadding); if ( legendHeight > maxLegendHeight ) maxLegendHeight = legendHeight; } } } - int trackHeight = height - maxLegendHeight; + int titleHeight = 0; + if (m_plotTitle && m_plotTitle->isVisible()) + { + titleHeight = m_plotTitle->height() + 10; + } + + int trackHeight = frameHeight - maxLegendHeight - titleHeight; int trackX = 0; if (visibleTrackCount) { - int trackWidth = (width - scrollBarWidth)/visibleTrackCount; - int trackWidthExtra = (width-scrollBarWidth)%visibleTrackCount; + + int maxCanvasOffset = 0; + for (int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx) + { + if (m_trackPlots[tIdx]->isVisible()) + { + // Hack to align QWT plots. See below. + QRectF canvasRect = m_trackPlots[tIdx]->plotLayout()->canvasRect(); + maxCanvasOffset = std::max(maxCanvasOffset, static_cast(canvasRect.top())); + } + } - for (int tIdx = 0; tIdx < trackCount; ++tIdx) + + for (int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx) { if (m_trackPlots[tIdx]->isVisible()) { - int realTrackWidth = trackWidth; - if (trackWidthExtra > 0) + int adjustedVerticalPosition = titleHeight + maxLegendHeight + 10; + int adjustedTrackHeight = trackHeight; { - realTrackWidth += 1; - --trackWidthExtra; + // Hack to align QWT plots which doesn't have an x-axis with the other tracks. + // Since they are missing the axis, QWT will shift them upwards. + // So we shift the plot downwards and resize to match the others. + // TODO: Look into subclassing QwtPlotLayout instead. + QRectF canvasRect = m_trackPlots[tIdx]->plotLayout()->canvasRect(); + int myCanvasOffset = static_cast(canvasRect.top()); + int myMargins = m_trackPlots[tIdx]->plotLayout()->canvasMargin(QwtPlot::xTop); + int canvasShift = std::max(0, maxCanvasOffset - myCanvasOffset); + adjustedVerticalPosition += canvasShift - myMargins; + adjustedTrackHeight -= canvasShift; } - int realLegendWidth = std::max(realTrackWidth, m_legends[tIdx]->sizeHint().width()); - m_legends[tIdx]->setGeometry(trackX, 0, realLegendWidth, maxLegendHeight); - m_trackPlots[tIdx]->setGeometry(trackX, maxLegendHeight, realTrackWidth, trackHeight); + + int realTrackWidth = trackWidths[tIdx]; + m_legends[tIdx]->setGeometry(trackX + trackPadding, titleHeight, realTrackWidth - 2 * trackPadding, maxLegendHeight); + m_trackPlots[tIdx]->setGeometry(trackX + trackPadding, adjustedVerticalPosition, realTrackWidth - 2 * trackPadding, adjustedTrackHeight); trackX += realTrackWidth; } } } - if (m_scrollBar->isVisible()) m_scrollBar->setGeometry(trackX, maxLegendHeight, scrollBarWidth, trackHeight); + if (m_scrollBar->isVisible()) + { + m_scrollBar->setGeometry(trackX, titleHeight + maxLegendHeight, m_scrollBar->sizeHint().width(), trackHeight); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::positionTitle(int frameWidth) +{ + if (m_plotDefinition && m_plotDefinition->isPlotTitleVisible()) + { + int textWidth = m_plotTitle->sizeHint().width(); + m_plotTitle->setGeometry(frameWidth/2 - textWidth/2, 0, textWidth, m_plotTitle->sizeHint().height()); + m_plotTitle->show(); + } + else + { + m_plotTitle->hide(); + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RiuWellLogPlot::updateChildrenLayout() -{ +{ int trackCount = m_trackPlots.size(); + int numTracksAlreadyShown = 0; for (int tIdx = 0; tIdx < trackCount; ++tIdx) { if (m_trackPlots[tIdx]->isVisible()) { - m_legends[tIdx]->show(); + int legendColumns = 1; + if (m_plotDefinition->areTrackLegendsHorizontal()) + { + legendColumns = 0; // unlimited + } + m_legends[tIdx]->setMaxColumns(legendColumns); + m_legends[tIdx]->show(); + + m_trackPlots[tIdx]->enableDepthAxisLabelsAndTitle(numTracksAlreadyShown == 0); + numTracksAlreadyShown++; } else { diff --git a/ApplicationCode/UserInterface/RiuWellLogPlot.h b/ApplicationCode/UserInterface/RiuWellLogPlot.h index 768bba563f..188fcf86be 100644 --- a/ApplicationCode/UserInterface/RiuWellLogPlot.h +++ b/ApplicationCode/UserInterface/RiuWellLogPlot.h @@ -19,20 +19,22 @@ #pragma once +#include "RiuInterfaceToViewWindow.h" + #include "cafPdmPointer.h" #include #include #include -#include "RiuInterfaceToViewWindow.h" +#include class RimWellLogPlot; class RiuWellLogTrack; -class QHBoxLayout; -class QScrollBar; class QFocusEvent; +class QLabel; +class QScrollBar; class QwtLegend; //================================================================================================== @@ -46,42 +48,47 @@ class RiuWellLogPlot : public QWidget, public RiuInterfaceToViewWindow public: RiuWellLogPlot(RimWellLogPlot* plotDefinition, QWidget* parent = nullptr); - virtual ~RiuWellLogPlot(); + ~RiuWellLogPlot() override; RimWellLogPlot* ownerPlotDefinition(); - virtual RimViewWindow* ownerViewWindow() const override; + RimViewWindow* ownerViewWindow() const override; void addTrackPlot(RiuWellLogTrack* trackPlot); void insertTrackPlot(RiuWellLogTrack* trackPlot, size_t index); void removeTrackPlot(RiuWellLogTrack* trackPlot); void setDepthZoomAndReplot(double minDepth, double maxDepth); - - public slots: + void setPlotTitle(const QString& plotTitle); + virtual QSize preferredSize() const; +public slots: void updateChildrenLayout(); protected: - virtual void resizeEvent(QResizeEvent *event); - virtual void showEvent(QShowEvent *); - virtual void changeEvent(QEvent *); - virtual QSize sizeHint() const override; - virtual void contextMenuEvent(QContextMenuEvent *) override; + void resizeEvent(QResizeEvent *event) override; + void showEvent(QShowEvent *) override; + void changeEvent(QEvent *) override; + void contextMenuEvent(QContextMenuEvent *) override; + QSize sizeHint() const override; + + + void keyPressEvent(QKeyEvent* keyEvent) override; private: void updateScrollBar(double minDepth, double maxDepth); - void modifyWidthOfContainingMdiWindow(int widthChange); - void placeChildWidgets(int height, int width); + std::map calculateTrackWidthsToMatchFrame(int frameWidth) const; + void placeChildWidgets(int frameHeight, int frameWidth); + void positionTitle(int frameWidth); private slots: void slotSetMinDepth(int value); void scheduleUpdateChildrenLayout(); private: - QHBoxLayout* m_layout; - QScrollBar* m_scrollBar; - QList > m_legends; + QLabel* m_plotTitle; + QScrollBar* m_scrollBar; + QList > m_legends; QList > m_trackPlots; - caf::PdmPointer m_plotDefinition; - QTimer* m_scheduleUpdateChildrenLayoutTimer; + caf::PdmPointer m_plotDefinition; + QTimer* m_scheduleUpdateChildrenLayoutTimer; }; diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp index 8bf7946637..bb459de35d 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp @@ -1,4 +1,4 @@ -///////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2015- Statoil ASA // Copyright (C) 2015- Ceetron Solutions AS @@ -28,6 +28,8 @@ #include "RiuPlotMainWindowTools.h" #include "RiuQwtCurvePointTracker.h" +#include "RiuQwtLinearScaleEngine.h" + #include "qwt_legend.h" #include "qwt_plot_curve.h" #include "qwt_plot_grid.h" @@ -35,7 +37,6 @@ #include "qwt_plot_marker.h" #include "qwt_plot_picker.h" #include "qwt_scale_draw.h" -#include "qwt_scale_engine.h" #include "qwt_symbol.h" #include "qwt_text.h" @@ -89,7 +90,7 @@ void RiuWellLogTrack::setDefaults() axisScaleEngine(QwtPlot::xTop)->setAttribute(QwtScaleEngine::Floating, true); axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating, true); setAxisScale(QwtPlot::yLeft, 1000, 0); - setAxisScale(QwtPlot::xTop, -10, 100); + setXRange(0, 100); } @@ -105,10 +106,9 @@ void RiuWellLogTrack::setDepthZoom(double minDepth, double maxDepth) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RiuWellLogTrack::setXRange(double min, double max) +void RiuWellLogTrack::setXRange(double min, double max, QwtPlot::Axis axis) { - setAxisScale(QwtPlot::xTop, min, max); - setAxisScale(QwtPlot::xBottom, min, max); + setAxisScale(axis, min, max); } //-------------------------------------------------------------------------------------------------- @@ -117,8 +117,11 @@ void RiuWellLogTrack::setXRange(double min, double max) void RiuWellLogTrack::setDepthTitle(const QString& title) { QwtText axisTitleY = axisTitle(QwtPlot::yLeft); - axisTitleY.setText(title); - setAxisTitle(QwtPlot::yLeft, axisTitleY); + if (title != axisTitleY.text()) + { + axisTitleY.setText(title); + setAxisTitle(QwtPlot::yLeft, axisTitleY); + } } //-------------------------------------------------------------------------------------------------- @@ -128,7 +131,10 @@ void RiuWellLogTrack::setXTitle(const QString& title) { QwtText axisTitleX = axisTitle(QwtPlot::xTop); axisTitleX.setText(title); - setAxisTitle(QwtPlot::xTop, axisTitleX); + if (title != axisTitleX.text()) + { + setAxisTitle(QwtPlot::xTop, axisTitleX); + } } //-------------------------------------------------------------------------------------------------- @@ -261,3 +267,111 @@ bool RiuWellLogTrack::isRimTrackVisible() return false; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrack::enableDepthAxisLabelsAndTitle(bool enable) +{ + this->axisScaleDraw(QwtPlot::yLeft)->enableComponent(QwtAbstractScaleDraw::Ticks, enable); + this->axisScaleDraw(QwtPlot::yLeft)->enableComponent(QwtAbstractScaleDraw::Labels, enable); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RiuWellLogTrack::widthScaleFactor() const +{ + if (m_plotTrackDefinition) + { + return m_plotTrackDefinition->widthScaleFactor(); + } + return 1; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrack::enableXGridLines(bool majorGridLines, bool minorGridLines) +{ + QwtPlotItemList plotItems = this->itemList(QwtPlotItem::Rtti_PlotGrid); + for (QwtPlotItem* plotItem : plotItems) + { + QwtPlotGrid* grid = static_cast(plotItem); + grid->setXAxis(QwtPlot::xTop); + grid->enableX(majorGridLines); + grid->enableXMin(minorGridLines); + grid->setMajorPen(Qt::lightGray, 1.0, Qt::SolidLine); + grid->setMinorPen(Qt::lightGray, 1.0, Qt::DashLine); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrack::enableDepthGridLines(bool majorGridLines, bool minorGridLines) +{ + QwtPlotItemList plotItems = this->itemList(QwtPlotItem::Rtti_PlotGrid); + for (QwtPlotItem* plotItem : plotItems) + { + QwtPlotGrid* grid = static_cast(plotItem); + grid->setYAxis(QwtPlot::yLeft); + grid->enableY(majorGridLines); + grid->enableYMin(minorGridLines); + grid->setMajorPen(Qt::lightGray, 1.0, Qt::SolidLine); + grid->setMinorPen(Qt::lightGray, 1.0, Qt::DashLine); + } + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrack::setMajorAndMinorTickIntervals(double majorTickInterval, double minorTickInterval) +{ + RiuQwtLinearScaleEngine* scaleEngine = dynamic_cast(this->axisScaleEngine(QwtPlot::xTop)); + if (scaleEngine) + { + QwtInterval currentRange = this->axisInterval(QwtPlot::xTop); + QwtScaleDiv scaleDiv = scaleEngine->divideScaleWithExplicitIntervals(currentRange.minValue(), currentRange.maxValue(), majorTickInterval, minorTickInterval); + + this->setAxisScaleDiv(QwtPlot::xTop, scaleDiv); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogTrack::setAutoTickIntervalCounts(int maxMajorTickIntervalCount, int maxMinorTickIntervalCount) +{ + this->setAxisMaxMajor(QwtPlot::xTop, maxMajorTickIntervalCount); + this->setAxisMaxMinor(QwtPlot::xTop, maxMinorTickIntervalCount); + // Reapply axis limits to force Qwt to use the tick settings. + QwtInterval currentRange = this->axisInterval(QwtPlot::xTop); + this->setXRange(currentRange.minValue(), currentRange.maxValue()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RiuWellLogTrack::getCurrentMajorTickInterval() const +{ + QwtScaleDiv scaleDiv = this->axisScaleDiv(QwtPlot::xTop); + QList majorTicks = scaleDiv.ticks(QwtScaleDiv::MajorTick); + if (majorTicks.size() < 2) return 0.0; + + return majorTicks.at(1) - majorTicks.at(0); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double RiuWellLogTrack::getCurrentMinorTickInterval() const +{ + QwtScaleDiv scaleDiv = this->axisScaleDiv(QwtPlot::xTop); + QList minorTicks = scaleDiv.ticks(QwtScaleDiv::MinorTick); + if (minorTicks.size() < 2) return 0.0; + + return minorTicks.at(1) - minorTicks.at(0); + +} + diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.h b/ApplicationCode/UserInterface/RiuWellLogTrack.h index 9be479e3d5..26f07a5235 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.h +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.h @@ -43,20 +43,27 @@ class RiuWellLogTrack : public QwtPlot public: RiuWellLogTrack(RimWellLogTrack* plotTrackDefinition, QWidget* parent = nullptr); - virtual ~RiuWellLogTrack(); + ~RiuWellLogTrack() override; void setDepthZoom(double minDepth, double maxDepth); void setDepthTitle(const QString& title); void setXTitle(const QString& title); - void setXRange(double min, double max); + void setXRange(double min, double max, QwtPlot::Axis axis = QwtPlot::xTop); bool isRimTrackVisible(); - + void enableDepthAxisLabelsAndTitle(bool enable); + int widthScaleFactor() const; + void enableXGridLines(bool majorGridLines, bool minorGridLines); + void enableDepthGridLines(bool majorGridLines, bool minorGridLines); + void setMajorAndMinorTickIntervals(double majorTickInterval, double minorTickInterval); + void setAutoTickIntervalCounts(int maxMajorTickIntervalCount, int maxMinorTickIntervalCount); + double getCurrentMajorTickInterval() const; + double getCurrentMinorTickInterval() const; protected: - virtual bool eventFilter(QObject* watched, QEvent* event); - virtual QSize sizeHint() const; - virtual QSize minimumSizeHint() const; + bool eventFilter(QObject* watched, QEvent* event) override; + QSize sizeHint() const override; + QSize minimumSizeHint() const override; private: void setDefaults(); diff --git a/ApplicationCode/UserInterface/RiuWellPathComponentPlotItem.cpp b/ApplicationCode/UserInterface/RiuWellPathComponentPlotItem.cpp new file mode 100644 index 0000000000..9318879725 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuWellPathComponentPlotItem.cpp @@ -0,0 +1,521 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RiuWellPathComponentPlotItem.h" + +#include "RiaColorTables.h" +#include "RiaColorTools.h" + +#include "RimFishbonesMultipleSubs.h" +#include "RimFracture.h" +#include "RimFractureTemplate.h" +#include "RimPerforationInterval.h" +#include "RimWellLogPlot.h" +#include "RimWellLogTrack.h" +#include "RimWellPathAttribute.h" +#include "RimWellPathAttributeCollection.h" +#include "RimWellPath.h" +#include "RimWellPathValve.h" + +#include "RigWellPath.h" + +#include "qwt_plot.h" +#include "qwt_plot_marker.h" +#include "qwt_plot_shapeitem.h" + +#include +#include + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellPathComponentPlotItem::RiuWellPathComponentPlotItem(const RimWellPath* wellPath) + : m_wellPath(wellPath) + , m_componentType(RiaDefines::WELL_PATH) + , m_columnOffset(0.0) + , m_depthType(RimWellLogPlot::MEASURED_DEPTH) + , m_showLabel(false) +{ + CVF_ASSERT(wellPath); + double wellStart = wellPath->wellPathGeometry()->measureDepths().front(); + double wellEnd = wellPath->wellPathGeometry()->measureDepths().back(); + m_startMD = wellStart; + m_endMD = wellEnd; + m_label = wellPath->name(); + m_legendTitle = "Well Tube"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellPathComponentPlotItem::RiuWellPathComponentPlotItem(const RimWellPath* wellPath, const RimWellPathComponentInterface* component) + : m_wellPath(wellPath) + , m_columnOffset(0.0) + , m_depthType(RimWellLogPlot::MEASURED_DEPTH) + , m_showLabel(false) +{ + CVF_ASSERT(wellPath && component); + + m_componentType = component->componentType(); + m_label = component->componentLabel(); + m_legendTitle = component->componentTypeLabel(); + m_startMD = component->startMD(); + m_endMD = component->endMD(); + + calculateColumnOffsets(component); + const RimWellPathValve* valve = dynamic_cast(component); + if (valve) + { + m_subMDs = valve->valveLocations(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellPathComponentPlotItem::~RiuWellPathComponentPlotItem() +{ + detachFromQwt(); + + if (m_parentQwtPlot) + { + m_parentQwtPlot->replot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuWellPathComponentPlotItem::label() const +{ + return m_label; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::loadDataAndUpdate(bool updateParentPlot) +{ + onLoadDataAndUpdate(updateParentPlot); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiaDefines::WellPathComponentType RiuWellPathComponentPlotItem::componentType() const +{ + return m_componentType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::calculateColumnOffsets(const RimWellPathComponentInterface* component) +{ + std::set uniqueCasingDiameters; + + std::vector attributeCollection; + m_wellPath->descendantsIncludingThisOfType(attributeCollection); + for (const RimWellPathAttribute* otherAttribute : attributeCollection.front()->attributes()) + { + if (otherAttribute->componentType() == RiaDefines::CASING) + { + uniqueCasingDiameters.insert(otherAttribute->diameterInInches()); + } + } + + if (!uniqueCasingDiameters.empty()) + { + m_maxColumnOffset = (uniqueCasingDiameters.size() - 1) * 0.25; + + const RimWellPathAttribute* myAttribute = dynamic_cast(component); + if (myAttribute && myAttribute->componentType() == RiaDefines::CASING) + { + int nNarrowerCasings = std::count_if(uniqueCasingDiameters.begin(), uniqueCasingDiameters.end(), [myAttribute](double otherCasingDiameter) + { + return otherCasingDiameter < myAttribute->diameterInInches(); + }); + + m_columnOffset = nNarrowerCasings * 0.25; + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::onLoadDataAndUpdate(bool updateParentPlot) +{ + double startDepth, endDepth; + std::tie(startDepth, endDepth) = depthsOfDepthType(); + double midDepth = 0.5 * (startDepth + endDepth); + + double casingTrackEnd = 0.75 + m_maxColumnOffset; + + if (m_componentType == RiaDefines::WELL_PATH) + { + addColumnFeature(-0.25, 0.25, startDepth, endDepth, componentColor()); + } + else if (m_componentType == RiaDefines::CASING) + { + double posMin = 0.5 + m_columnOffset; + double posMax = 0.75 + m_columnOffset; + addColumnFeature(-posMax, -posMin, startDepth, endDepth, componentColor()); + addColumnFeature(posMin, posMax, startDepth, endDepth, componentColor()); + addMarker(-posMax, endDepth,12, RiuQwtSymbol::SYMBOL_LEFT_ANGLED_TRIANGLE, componentColor()); + addMarker(posMax, endDepth, 12, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor()); + addMarker(casingTrackEnd, endDepth, 12, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor(0.0), label()); + + } + else if (m_componentType == RiaDefines::LINER) + { + addColumnFeature(-0.5, -0.25, startDepth, endDepth, componentColor()); + addColumnFeature(0.25, 0.5, startDepth, endDepth, componentColor()); + addMarker(casingTrackEnd, endDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor(0.0), label()); + } + else if (m_componentType == RiaDefines::PERFORATION_INTERVAL) + { + addColumnFeature(-casingTrackEnd, -0.25, startDepth, endDepth, componentColor(), Qt::Dense6Pattern); + addColumnFeature(0.25, casingTrackEnd, startDepth, endDepth, componentColor(), Qt::Dense6Pattern); + // Empirically a spacing of around 30 in depth between symbols looks good in the most relevant zoom levels. + const double markerSpacing = 30; + const int markerSize = 6; + double markerDepth = startDepth; + while (markerDepth < endDepth - 5) + { + addMarker(-casingTrackEnd, markerDepth, markerSize, RiuQwtSymbol::SYMBOL_LEFT_TRIANGLE, componentColor()); + addMarker(casingTrackEnd, markerDepth, markerSize, RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE, componentColor()); + + markerDepth += markerSpacing; + } + addMarker(casingTrackEnd, midDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE, componentColor(0.0), label()); + + QwtPlotItem* legendItem1 = createMarker(16.0, 0.0, 6, RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE, componentColor()); + legendItem1->setLegendIconSize(QSize(4, 8)); + QwtPlotItem* legendItem2 = createMarker(16.0, 8.0, 6, RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE, componentColor()); + legendItem2->setLegendIconSize(QSize(4, 8)); + m_combinedComponentGroup.addLegendItem(legendItem1); + m_combinedComponentGroup.addLegendItem(legendItem2); + } + else if (m_componentType == RiaDefines::FISHBONES) + { + addColumnFeature(-casingTrackEnd, -0.25, startDepth, endDepth, componentColor(), Qt::BDiagPattern); + addColumnFeature(0.25, casingTrackEnd, startDepth, endDepth, componentColor(), Qt::FDiagPattern); + addMarker(casingTrackEnd, midDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor(0.0), label()); + } + else if (m_componentType == RiaDefines::FRACTURE) + { + addColumnFeature(-casingTrackEnd, -0.25, startDepth, endDepth, componentColor(), Qt::SolidPattern); + addColumnFeature(0.25, casingTrackEnd, startDepth, endDepth, componentColor(), Qt::SolidPattern); + addMarker(casingTrackEnd, startDepth, 10, RiuQwtSymbol::SYMBOL_NONE, componentColor(), "", Qt::AlignTop | Qt::AlignRight, Qt::Horizontal, true); + addMarker(casingTrackEnd, endDepth, 10, RiuQwtSymbol::SYMBOL_NONE, componentColor(), "", Qt::AlignTop | Qt::AlignRight, Qt::Horizontal, true); + addMarker(casingTrackEnd, startDepth, 1, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor(0.0f), label(), Qt::AlignTop | Qt::AlignRight); + } + else if (m_componentType == RiaDefines::ICD) + { + for (double md : m_subMDs) + { + addMarker(0.0, md, 16, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor(), "", Qt::AlignCenter, Qt::Horizontal, false, true); + } + m_combinedComponentGroup.addLegendItem(createMarker(0.0, 0.0, 12.0, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor())); + } + else if (m_componentType == RiaDefines::ICV) + { + for (double md : m_subMDs) + { + addMarker(0.0, md, 16, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor(), "", Qt::AlignCenter, Qt::Horizontal, false, true); + } + m_combinedComponentGroup.addLegendItem(createMarker(0.0, 0.0, 12.0, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor())); + } + else if (m_componentType == RiaDefines::AICD) + { + for (double md : m_subMDs) + { + addMarker(0.0, md, 16, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor(), "", Qt::AlignCenter, Qt::Horizontal, false, true); + } + m_combinedComponentGroup.addLegendItem(createMarker(0.0, 0.0, 12.0, RiuQwtSymbol::SYMBOL_ELLIPSE, componentColor())); + } + else if (m_componentType == RiaDefines::PACKER) + { + addColumnFeature(-casingTrackEnd, -0.25, startDepth, endDepth, componentColor(), Qt::DiagCrossPattern); + addColumnFeature(0.25, casingTrackEnd, startDepth, endDepth, componentColor(), Qt::DiagCrossPattern); + addMarker(casingTrackEnd, midDepth, 10, RiuQwtSymbol::SYMBOL_RIGHT_ANGLED_TRIANGLE, componentColor(0.0), label()); + } + m_combinedComponentGroup.setTitle(legendTitle()); + m_combinedComponentGroup.setLegendIconSize(QSize(20, 16)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair RiuWellPathComponentPlotItem::depthsOfDepthType() const +{ + double startDepth = m_startMD; + double endDepth = m_endMD; + + if (m_depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH) + { + cvf::Vec3d startPoint = m_wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(m_startMD); + cvf::Vec3d endPoint = m_wellPath->wellPathGeometry()->interpolatedPointAlongWellPath(m_endMD); + startDepth = -startPoint.z(); + endDepth = -endPoint.z(); + } + return std::make_pair(startDepth, endDepth); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::addMarker(double posX, + double depth, + int size, + RiuQwtSymbol::PointSymbolEnum symbolType, + cvf::Color4f baseColor, + QString label /*= QString("")*/, + Qt::Alignment labelAlignment /*= Qt::AlignTop*/, + Qt::Orientation labelOrientation /*= Qt::Vertical*/, + bool drawLine /*= false*/, + bool contrastTextColor /*= true*/) +{ + QwtPlotItem* marker = createMarker(posX, depth, size, symbolType, baseColor, label, labelAlignment, labelOrientation, drawLine, contrastTextColor); + m_combinedComponentGroup.addPlotItem(marker); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QwtPlotItem* RiuWellPathComponentPlotItem::createMarker(double posX, double depth, int size, RiuQwtSymbol::PointSymbolEnum symbolType, cvf::Color4f baseColor, QString label /*= QString("")*/, Qt::Alignment labelAlignment /*= Qt::AlignTop*/, Qt::Orientation labelOrientation /*= Qt::Vertical*/, bool drawLine /*= false*/, bool contrastTextColor /*= true*/) +{ + QColor bgColor = RiaColorTools::toQColor(baseColor); + QColor textColor = RiaColorTools::toQColor(baseColor.toColor3f(), 1.0); + if (contrastTextColor) + { + textColor = RiaColorTools::toQColor(RiaColorTools::constrastColor(baseColor.toColor3f())); + } + QwtPlotMarker* marker = new QwtPlotMarker(label); + RiuQwtSymbol* symbol = new RiuQwtSymbol(symbolType, "", RiuQwtSymbol::LabelRightOfSymbol); + symbol->setSize(size); + symbol->setColor(bgColor); + marker->setSymbol(symbol); + marker->setSpacing(6); + marker->setXValue(posX); + marker->setYValue(depth); + + if (m_showLabel) + { + QwtText labelText(label); + labelText.setColor(textColor); + QFont font; + font.setPointSize(8); + labelText.setFont(font); + marker->setLabel(labelText); + marker->setLabelAlignment(labelAlignment); + marker->setLabelOrientation(labelOrientation); + } + + if (drawLine) + { + marker->setLineStyle(QwtPlotMarker::HLine); + marker->setLinePen(bgColor, 2.0, Qt::SolidLine); + } + return marker; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::addColumnFeature(double startX, + double endX, + double startDepth, + double endDepth, + cvf::Color4f baseColor, + Qt::BrushStyle brushStyle /*= Qt::SolidPattern*/) +{ + if (brushStyle != Qt::SolidPattern) + { + // If we're doing a special pattern, draw the background in white first over the existing pattern + cvf::Color4f semiTransparentWhite(cvf::Color3f(cvf::Color3::WHITE), 0.9f); + QwtPlotItem* backgroundShape = createColumnShape(startX, endX, startDepth, endDepth, semiTransparentWhite, Qt::SolidPattern); + m_combinedComponentGroup.addPlotItem(backgroundShape); + + QwtPlotItem* patternShape = createColumnShape(startX, endX, startDepth, endDepth, baseColor, brushStyle); + m_combinedComponentGroup.addPlotItem(patternShape); + if (endX >= 0.0) + { + QwtPlotItem* legendBGShape = createColumnShape(0.0, 16.0, 0.0, 16.0, semiTransparentWhite, Qt::SolidPattern); + m_combinedComponentGroup.addLegendItem(legendBGShape); + + QwtPlotItem* legendShape = createColumnShape(0.0, 16.0, 0.0, 16.0, baseColor, brushStyle); + m_combinedComponentGroup.addLegendItem(legendShape); + } + } + else + { + QwtPlotItem* backgroundShape = createColumnShape(startX, endX, startDepth, endDepth, baseColor, Qt::SolidPattern); + m_combinedComponentGroup.addPlotItem(backgroundShape); + + if (endX >= 0.0) + { + QwtPlotItem* legendShape = createColumnShape(0.0, 16.0, 0.0, 16.0, baseColor, Qt::SolidPattern); + m_combinedComponentGroup.addLegendItem(legendShape); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QwtPlotItem* RiuWellPathComponentPlotItem::createColumnShape(double startX, + double endX, + double startDepth, + double endDepth, + cvf::Color4f baseColor, + Qt::BrushStyle brushStyle) +{ + QwtPlotShapeItem* columnShape = new QwtPlotShapeItem(label()); + QPolygonF polygon; + QColor color = RiaColorTools::toQColor(baseColor); + + polygon.push_back(QPointF(startX, startDepth)); + polygon.push_back(QPointF(endX, startDepth)); + polygon.push_back(QPointF(endX, endDepth)); + polygon.push_back(QPointF(startX, endDepth)); + polygon.push_back(QPointF(startX, startDepth)); + columnShape->setPolygon(polygon); + columnShape->setXAxis(QwtPlot::xBottom); + columnShape->setBrush(QBrush(color, brushStyle)); + columnShape->setLegendMode(QwtPlotShapeItem::LegendShape); + columnShape->setLegendIconSize(QSize(16, 16)); + return columnShape; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +cvf::Color4f RiuWellPathComponentPlotItem::componentColor(float alpha /*= 1.0*/) const +{ + return cvf::Color4f(RiaColorTables::wellPathComponentColors()[m_componentType], alpha); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuWellPathComponentPlotItem::xValueRange(double* minimumValue, double* maximumValue) const +{ + CVF_ASSERT(minimumValue && maximumValue); + *maximumValue = 1.0; + *minimumValue = -1.0; + return true; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RiuWellPathComponentPlotItem::yValueRange(double* minimumValue, double* maximumValue) const +{ + CVF_ASSERT(minimumValue && maximumValue); + + if (minimumValue && maximumValue) + { + std::tie(*minimumValue, *maximumValue) = depthsOfDepthType(); + return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::setShowLabel(bool showLabel) +{ + m_showLabel = showLabel; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::setDepthType(RimWellLogPlot::DepthTypeEnum depthType) +{ + m_depthType = depthType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::setContributeToLegend(bool contributeToLegend) +{ + m_combinedComponentGroup.setItemAttribute(QwtPlotItem::Legend, contributeToLegend); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::setParentQwtPlotAndReplot(QwtPlot* plot) +{ + setParentQwtPlotNoReplot(plot); + if (m_parentQwtPlot) + { + m_parentQwtPlot->replot(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::setParentQwtPlotNoReplot(QwtPlot* plot) +{ + m_parentQwtPlot = plot; + attachToQwt(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::attachToQwt() +{ + if (m_parentQwtPlot) + { + m_combinedComponentGroup.attach(m_parentQwtPlot); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::detachFromQwt() +{ + m_combinedComponentGroup.detach(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellPathComponentPlotItem::reattachToQwt() +{ + detachFromQwt(); + attachToQwt(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiuWellPathComponentPlotItem::legendTitle() const +{ + return m_legendTitle; +} diff --git a/ApplicationCode/UserInterface/RiuWellPathComponentPlotItem.h b/ApplicationCode/UserInterface/RiuWellPathComponentPlotItem.h new file mode 100644 index 0000000000..28ad00ea96 --- /dev/null +++ b/ApplicationCode/UserInterface/RiuWellPathComponentPlotItem.h @@ -0,0 +1,140 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RiaDefines.h" +#include "RiuQwtPlotItemGroup.h" + +#include "RimPlotCurve.h" +#include "RimWellLogPlot.h" +#include "RimWellPathAttribute.h" +#include "RimWellPathComponentInterface.h" + +#include "cafPdmBase.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +#include "cvfColor4.h" +#include "cvfObject.h" + +#include +#include + +class RigWellLogCurveData; +class RimWellPath; +class QwtPlotItem; + + + +//================================================================================================== +/// +/// +//================================================================================================== +class RiuWellPathComponentPlotItem +{ + +public: + RiuWellPathComponentPlotItem(const RimWellPath* wellPath); + + RiuWellPathComponentPlotItem(const RimWellPath* wellPath, + const RimWellPathComponentInterface* completion); + + ~RiuWellPathComponentPlotItem(); + + QString label() const; + QString legendTitle() const; + + void loadDataAndUpdate(bool updateParentPlot); + + RiaDefines::WellPathComponentType componentType() const; + + bool xValueRange(double* minimumValue, double* maximumValue) const; + bool yValueRange(double* minimumValue, double* maximumValue) const; + + void setShowLabel(bool showLabel); + void setDepthType(RimWellLogPlot::DepthTypeEnum depthType); + void setContributeToLegend(bool contributeToLegend); + + void setParentQwtPlotAndReplot(QwtPlot* plot); + void setParentQwtPlotNoReplot(QwtPlot* plot); + void attachToQwt(); + void detachFromQwt(); + void reattachToQwt(); + +private: + void calculateColumnOffsets(const RimWellPathComponentInterface* component); + + void onLoadDataAndUpdate(bool updateParentPlot); + + std::pair depthsOfDepthType() const; + + void addMarker(double posX, + double depth, + int size, + RiuQwtSymbol::PointSymbolEnum symbolType, + cvf::Color4f baseColor, + QString label = QString(""), + Qt::Alignment labelAlignment = Qt::AlignVCenter | Qt::AlignRight, + Qt::Orientation labelOrientation = Qt::Horizontal, + bool drawLine = false, + bool contrastTextColor = false); + QwtPlotItem* createMarker(double posX, + double depth, + int size, + RiuQwtSymbol::PointSymbolEnum symbolType, + cvf::Color4f baseColor, + QString label = QString(""), + Qt::Alignment labelAlignment = Qt::AlignVCenter | Qt::AlignRight, + Qt::Orientation labelOrientation = Qt::Horizontal, + bool drawLine = false, + bool contrastTextColor = false); + void addColumnFeature(double startX, + double endX, + double startDepth, + double endDepth, + cvf::Color4f baseColor, + Qt::BrushStyle brushStyle = Qt::SolidPattern); + + QwtPlotItem* createColumnShape(double startX, + double endX, + double startDepth, + double endDepth, + cvf::Color4f baseColor, + Qt::BrushStyle brushStyle = Qt::SolidPattern); + + cvf::Color4f componentColor(float alpha = 1.0) const; + +private: + const RimWellPath* m_wellPath; + + RiaDefines::WellPathComponentType m_componentType; + double m_startMD; + double m_endMD; + std::vector m_subMDs; + QString m_label; + QString m_legendTitle; + double m_columnOffset; + double m_maxColumnOffset; + + RimWellLogPlot::DepthTypeEnum m_depthType; + QPointer m_parentQwtPlot; + RiuQwtPlotItemGroup m_combinedComponentGroup; + + bool m_showLabel; +}; diff --git a/ApplicationCode/UserInterface/RiuWellPltPlot.cpp b/ApplicationCode/UserInterface/RiuWellPltPlot.cpp index defdd24b08..c02ee9da41 100644 --- a/ApplicationCode/UserInterface/RiuWellPltPlot.cpp +++ b/ApplicationCode/UserInterface/RiuWellPltPlot.cpp @@ -77,7 +77,7 @@ RiuWellPltPlot::RiuWellPltPlot(RimWellPltPlot* plotDefinition, QWidget* parent) mainLayout->addLayout(plotWidgetsLayout); plotWidgetsLayout->addLayout(rightColumnLayout); - QWidget* wellFlowWidget = m_plotDefinition->wellLogPlot()->createViewWidget(this); + QWidget* wellFlowWidget = m_plotDefinition->wellLogPlot()->createPlotWidget(); plotWidgetsLayout->addWidget(wellFlowWidget); } diff --git a/ApplicationCode/UserInterface/RiuWellPltPlot.h b/ApplicationCode/UserInterface/RiuWellPltPlot.h index e571e1bf0b..84846b4d02 100644 --- a/ApplicationCode/UserInterface/RiuWellPltPlot.h +++ b/ApplicationCode/UserInterface/RiuWellPltPlot.h @@ -46,19 +46,19 @@ class RiuWellPltPlot : public QFrame, public RiuInterfaceToViewWindow Q_OBJECT; public: RiuWellPltPlot(RimWellPltPlot* plotDefinition, QWidget* parent = nullptr); - virtual ~RiuWellPltPlot(); + ~RiuWellPltPlot() override; RimWellPltPlot* ownerPlotDefinition(); - virtual RimViewWindow* ownerViewWindow() const override; + RimViewWindow* ownerViewWindow() const override; void showTitle(const QString& title); void hideTitle(); protected: - virtual QSize sizeHint() const override; - virtual QSize minimumSizeHint() const override; + QSize sizeHint() const override; + QSize minimumSizeHint() const override; - virtual void contextMenuEvent(QContextMenuEvent *) override; + void contextMenuEvent(QContextMenuEvent *) override; private: void setDefaults(); diff --git a/ApplicationCode/UserInterface/RiuWellRftPlot.cpp b/ApplicationCode/UserInterface/RiuWellRftPlot.cpp index c2a9d7c4e3..ab25e0dda0 100644 --- a/ApplicationCode/UserInterface/RiuWellRftPlot.cpp +++ b/ApplicationCode/UserInterface/RiuWellRftPlot.cpp @@ -77,7 +77,7 @@ RiuWellRftPlot::RiuWellRftPlot(RimWellRftPlot* plotDefinition, QWidget* parent) mainLayout->addLayout(plotWidgetsLayout); plotWidgetsLayout->addLayout(rightColumnLayout); - QWidget* wellFlowWidget = m_plotDefinition->wellLogPlot()->createViewWidget(this); + QWidget* wellFlowWidget = m_plotDefinition->wellLogPlot()->createPlotWidget(); plotWidgetsLayout->addWidget(wellFlowWidget); } diff --git a/ApplicationCode/UserInterface/RiuWellRftPlot.h b/ApplicationCode/UserInterface/RiuWellRftPlot.h index cf60df95f5..40ccc207ff 100644 --- a/ApplicationCode/UserInterface/RiuWellRftPlot.h +++ b/ApplicationCode/UserInterface/RiuWellRftPlot.h @@ -46,19 +46,19 @@ class RiuWellRftPlot : public QFrame, public RiuInterfaceToViewWindow Q_OBJECT; public: RiuWellRftPlot(RimWellRftPlot* plotDefinition, QWidget* parent = nullptr); - virtual ~RiuWellRftPlot(); + ~RiuWellRftPlot() override; RimWellRftPlot* ownerPlotDefinition(); - virtual RimViewWindow* ownerViewWindow() const override; + RimViewWindow* ownerViewWindow() const override; void showTitle(const QString& title); void hideTitle(); protected: - virtual QSize sizeHint() const override; - virtual QSize minimumSizeHint() const override; + QSize sizeHint() const override; + QSize minimumSizeHint() const override; - virtual void contextMenuEvent(QContextMenuEvent *) override; + void contextMenuEvent(QContextMenuEvent *) override; private: void setDefaults(); diff --git a/ApplicationCode/UserInterface/RiuWidgetDragger.h b/ApplicationCode/UserInterface/RiuWidgetDragger.h index ea68299cd9..9b51f3f5a0 100644 --- a/ApplicationCode/UserInterface/RiuWidgetDragger.h +++ b/ApplicationCode/UserInterface/RiuWidgetDragger.h @@ -30,7 +30,7 @@ class RiuWidgetDragger : public QObject public: RiuWidgetDragger(QWidget* widgetToMove); - virtual bool eventFilter(QObject * watched, QEvent * event) override; + bool eventFilter(QObject * watched, QEvent * event) override; private: QPointer m_widgetToMove; diff --git a/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.cpp b/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.cpp index 9e5e7c66f0..859018bb81 100644 --- a/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.cpp +++ b/ApplicationCode/WellPathImportSsihub/RiuWellImportWizard.cpp @@ -28,13 +28,14 @@ #include "cafPdmObject.h" #include "cafPdmObjectGroup.h" #include "cafPdmUiListView.h" -#include "cafPdmUiListViewEditor.h" #include "cafPdmUiPropertyView.h" #include "cafPdmUiTreeView.h" #include "cafPdmUiTreeViewEditor.h" #include "cafUtils.h" #include +#include +#include #include #include @@ -316,7 +317,19 @@ void RiuWellImportWizard::setUrl(const QString& httpAddress) //-------------------------------------------------------------------------------------------------- void RiuWellImportWizard::startRequest(QUrl url) { - m_reply = m_networkAccessManager.get(QNetworkRequest(url)); + auto request = QNetworkRequest(url); + +#ifndef QT_NO_OPENSSL + bool supportsSsl = QSslSocket::supportsSsl(); + if (supportsSsl) + { + QSslConfiguration config = QSslConfiguration::defaultConfiguration(); + config.setProtocol(QSsl::TlsV1); + request.setSslConfiguration(config); + } +#endif + + m_reply = m_networkAccessManager.get(request); connect(m_reply, SIGNAL(finished()), this, SLOT(httpFinished())); connect(m_reply, SIGNAL(readyRead()), diff --git a/CMakeLists.txt b/CMakeLists.txt index 85d449a798..044eef0717 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") add_definitions(-DCVF_OSX) elseif(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /std:c++14") endif() if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -292,7 +292,6 @@ list(APPEND THIRD_PARTY_LIBRARIES clipper ) - ################################################################################ # Thirdparty libraries are put in ThirdParty solution folder ################################################################################ diff --git a/Fwk/AppFwk/CommonCode/CMakeLists.txt b/Fwk/AppFwk/CommonCode/CMakeLists.txt index 52e5193f4d..7c1e353946 100644 --- a/Fwk/AppFwk/CommonCode/CMakeLists.txt +++ b/Fwk/AppFwk/CommonCode/CMakeLists.txt @@ -35,6 +35,8 @@ add_library( ${PROJECT_NAME} cvfCellRange.h cafColorTable.cpp cafColorTable.h + cafContourLines.cpp + cafContourLines.h cvfStructGridGeometryGenerator.cpp cvfStructGridGeometryGenerator.h @@ -62,4 +64,8 @@ target_link_libraries ( ${PROJECT_NAME} ${QT_LIBRARIES} ) +if (MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/W4 /wd4100 /wd4127") +endif() + source_group("" FILES ${PROJECT_FILES}) diff --git a/Fwk/AppFwk/CommonCode/cafContourLines.cpp b/Fwk/AppFwk/CommonCode/cafContourLines.cpp new file mode 100644 index 0000000000..9721166e30 --- /dev/null +++ b/Fwk/AppFwk/CommonCode/cafContourLines.cpp @@ -0,0 +1,264 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Equinor ASA +// Copyright (C) 2018- Ceetron Solutions AS +// +// Adapted from work by Paul D. Bourke named "conrec" +// +// http://paulbourke.net/papers/conrec/. +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "cafContourLines.h" +#include + +const int caf::ContourLines::s_castab[3][3][3] = +{ + { {0,0,8},{0,2,5},{7,6,9} }, + { {0,3,4},{1,3,1},{4,3,0} }, + { {9,6,7},{5,2,0},{8,0,0} } +}; + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void caf::ContourLines::create(const std::vector& dataXY, const std::vector& xCoords, const std::vector& yCoords, const std::vector& contourLevels, std::vector>* polygons) +{ + CVF_ASSERT(!contourLevels.empty()); + int nContourLevels = static_cast(contourLevels.size()); + std::vector sh(5, 0); + std::vector h(5, 0.0), xh(5, 0.0), yh(5, 0.0); + + int nx = static_cast(xCoords.size()); + int ny = static_cast(yCoords.size()); + + CVF_ASSERT(static_cast(dataXY.size()) == nx * ny); + + polygons->resize(nContourLevels); + + int im[4] = { 0,1,1,0 }, jm[4] = { 0,0,1,1 }; + + for (int j = (ny - 2); j >= 0; j--) + { + for (int i = 0; i < nx - 1; i++) + { + double temp1, temp2; + temp1 = std::min(saneValue(gridIndex1d(i, j, nx), dataXY, contourLevels), + saneValue(gridIndex1d(i, j + 1, nx), dataXY, contourLevels)); + temp2 = std::min(saneValue(gridIndex1d(i + 1, j, nx), dataXY, contourLevels), + saneValue(gridIndex1d(i + 1, j + 1, nx), dataXY, contourLevels)); + double dmin = std::min(temp1, temp2); + temp1 = std::max(saneValue(gridIndex1d(i, j, nx), dataXY, contourLevels), + saneValue(gridIndex1d(i, j + 1, nx), dataXY, contourLevels)); + temp2 = std::max(saneValue(gridIndex1d(i + 1, j, nx), dataXY, contourLevels), + saneValue(gridIndex1d(i + 1, j + 1, nx), dataXY, contourLevels)); + double dmax = std::max(temp1, temp2); + if (dmax < contourLevels[0] || dmin > contourLevels[nContourLevels - 1]) + continue; + + for (int k = 0; k < nContourLevels; k++) + { + if (contourLevels[k] < dmin || contourLevels[k] > dmax) + continue; + for (int m = 4; m >= 0; m--) + { + if (m > 0) + { + double value = saneValue(gridIndex1d(i + im[m - 1], j + jm[m - 1], nx), dataXY, contourLevels); + if (value == invalidValue(contourLevels)) + { + h[m] = invalidValue(contourLevels); + } + else + { + h[m] = value - contourLevels[k]; + } + xh[m] = xCoords[i + im[m - 1]]; + yh[m] = yCoords[j + jm[m - 1]]; + } + else + { + h[0] = 0.25 * (h[1] + h[2] + h[3] + h[4]); + xh[0] = 0.5 * (xCoords[i] + xCoords[i + 1]); + yh[0] = 0.5 * (yCoords[j] + yCoords[j + 1]); + } + if (h[m] > 0.0) + sh[m] = 1; + else if (h[m] < 0.0) + sh[m] = -1; + else + sh[m] = 0; + } + + /* + Note: at this stage the relative heights of the corners and the + centre are in the h array, and the corresponding coordinates are + in the xh and yh arrays. The centre of the box is indexed by 0 + and the 4 corners by 1 to 4 as shown below. + Each triangle is then indexed by the parameter m, and the 3 + vertices of each triangle are indexed by parameters m1,m2,and m3. + It is assumed that the centre of the box is always vertex 2 + though this isimportant only when all 3 vertices lie exactly on + the same contour level, in which case only the side of the box + is drawn. + vertex 4 +-------------------+ vertex 3 + | \ / | + | \ m-3 / | + | \ / | + | \ / | + | m=2 X m=2 | the centre is vertex 0 + | / \ | + | / \ | + | / m=1 \ | + | / \ | + vertex 1 +-------------------+ vertex 2 + */ + /* Scan each triangle in the box */ + for (int m = 1; m <= 4; m++) { + int m1 = m; + int m2 = 0; + int m3 = (m != 4) ? m + 1 : 1; + + double x1 = 0.0, x2 = 0.0, y1 = 0.0, y2 = 0.0; + int case_value = s_castab[sh[m1] + 1][sh[m2] + 1][sh[m3] + 1]; + if (case_value == 0) + continue; + + switch (case_value) { + case 1: /* Line between vertices 1 and 2 */ + x1 = xh[m1]; + y1 = yh[m1]; + x2 = xh[m2]; + y2 = yh[m2]; + break; + case 2: /* Line between vertices 2 and 3 */ + x1 = xh[m2]; + y1 = yh[m2]; + x2 = xh[m3]; + y2 = yh[m3]; + break; + case 3: /* Line between vertices 3 and 1 */ + x1 = xh[m3]; + y1 = yh[m3]; + x2 = xh[m1]; + y2 = yh[m1]; + break; + case 4: /* Line between vertex 1 and side 2-3 */ + x1 = xh[m1]; + y1 = yh[m1]; + x2 = xsect(m2, m3, h, xh, yh); + y2 = ysect(m2, m3, h, xh, yh); + break; + case 5: /* Line between vertex 2 and side 3-1 */ + x1 = xh[m2]; + y1 = yh[m2]; + x2 = xsect(m3, m1, h, xh, yh); + y2 = ysect(m3, m1, h, xh, yh); + break; + case 6: /* Line between vertex 3 and side 1-2 */ + x1 = xh[m3]; + y1 = yh[m3]; + x2 = xsect(m1, m2, h, xh, yh); + y2 = ysect(m1, m2, h, xh, yh); + break; + case 7: /* Line between sides 1-2 and 2-3 */ + x1 = xsect(m1, m2, h, xh, yh); + y1 = ysect(m1, m2, h, xh, yh); + x2 = xsect(m2, m3, h, xh, yh); + y2 = ysect(m2, m3, h, xh, yh); + break; + case 8: /* Line between sides 2-3 and 3-1 */ + x1 = xsect(m2, m3, h, xh, yh); + y1 = ysect(m2, m3, h, xh, yh); + x2 = xsect(m3, m1, h, xh, yh); + y2 = ysect(m3, m1, h, xh, yh); + break; + case 9: /* Line between sides 3-1 and 1-2 */ + x1 = xsect(m3, m1, h, xh, yh); + y1 = ysect(m3, m1, h, xh, yh); + x2 = xsect(m1, m2, h, xh, yh); + y2 = ysect(m1, m2, h, xh, yh); + break; + default: + break; + } + + /* Finally draw the line */ + polygons->at(k).push_back(cvf::Vec2d(x1, y1)); + polygons->at(k).push_back(cvf::Vec2d(x2, y2)); + } /* m */ + } /* k - contour */ + } /* i */ + } /* j */ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double caf::ContourLines::contourRange(const std::vector& contourLevels) +{ + CVF_ASSERT(!contourLevels.empty()); + return std::max(1.0e-6, contourLevels.back() - contourLevels.front()); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double caf::ContourLines::invalidValue(const std::vector& contourLevels) +{ + return contourLevels.front() - 1000.0*contourRange(contourLevels); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double caf::ContourLines::saneValue(int index, const std::vector& dataXY, const std::vector& contourLevels) +{ + CVF_ASSERT(index >= 0 && index < static_cast(dataXY.size())); + + // Place all invalid values below the bottom contour level. + if (dataXY[index] == -std::numeric_limits::infinity() || + dataXY[index] == std::numeric_limits::infinity()) + { + return invalidValue(contourLevels); + } + return dataXY[index]; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double caf::ContourLines::xsect(int p1, int p2, const std::vector& h, const std::vector& xh, const std::vector& yh) +{ + return (h[p2] * xh[p1] - h[p1] * xh[p2]) / (h[p2] - h[p1]); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +double caf::ContourLines::ysect(int p1, int p2, const std::vector& h, const std::vector& xh, const std::vector& yh) +{ + return (h[p2] * yh[p1] - h[p1] * yh[p2]) / (h[p2] - h[p1]); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int caf::ContourLines::gridIndex1d(int i, int j, int nx) +{ + return j * nx + i; +} diff --git a/Fwk/AppFwk/CommonCode/cafContourLines.h b/Fwk/AppFwk/CommonCode/cafContourLines.h new file mode 100644 index 0000000000..62ef94be6e --- /dev/null +++ b/Fwk/AppFwk/CommonCode/cafContourLines.h @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2018- Equinor ASA +// Copyright (C) 2018- Ceetron Solutions AS +// +// Adapted from work by Paul D. Bourke named "conrec" +// +// http://paulbourke.net/papers/conrec/. +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cvfBase.h" +#include "cvfVector2.h" +#include + +namespace caf +{ +class ContourLines +{ +public: + static void create(const std::vector& dataXY, + const std::vector& xPositions, + const std::vector& yPositions, + const std::vector& contourLevels, + std::vector>* polygons); +private: + static double contourRange(const std::vector& contourLevels); + static double invalidValue(const std::vector& contourLevels); + static double saneValue(int index, const std::vector& dataXY, const std::vector& contourLevels); + static double xsect(int p1, int p2, const std::vector& h, const std::vector& xh, const std::vector& yh); + static double ysect(int p1, int p2, const std::vector& h, const std::vector& xh, const std::vector& yh); + static int gridIndex1d(int i, int j, int nx); +private: + static const int s_castab[3][3][3]; +}; +} \ No newline at end of file diff --git a/Fwk/AppFwk/CommonCode/cafUtils.cpp b/Fwk/AppFwk/CommonCode/cafUtils.cpp index 4922396a6c..e531f34338 100644 --- a/Fwk/AppFwk/CommonCode/cafUtils.cpp +++ b/Fwk/AppFwk/CommonCode/cafUtils.cpp @@ -143,6 +143,7 @@ QString Utils::makeValidFileBasename(const QString& fileBasenameCandidate) cleanBasename.replace("|", "_"); cleanBasename.replace("?", "_"); cleanBasename.replace("*", "_"); + cleanBasename.replace("\n", "_"); cleanBasename.replace(QRegExp("_+"), "_"); @@ -280,4 +281,39 @@ bool Utils::isStringMatch(const QString& filterString, const QString& value) return searcher.exactMatch(value); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool Utils::removeDirectoryAndFilesRecursively(const QString& dirName) +{ + bool result = true; + QDir dir(dirName); + + if (dir.exists()) + { + QFileInfoList fileInfoList = + dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst); + for (const auto& fileInfo : fileInfoList) + { + if (fileInfo.isDir()) + { + result = removeDirectoryAndFilesRecursively(fileInfo.absoluteFilePath()); + } + else + { + result = QFile::remove(fileInfo.absoluteFilePath()); + } + + if (!result) + { + return result; + } + } + + result = QDir().rmdir(dirName); + } + + return result; +} + } // namespace caf diff --git a/Fwk/AppFwk/CommonCode/cafUtils.h b/Fwk/AppFwk/CommonCode/cafUtils.h index 9cdbcc1c4f..5bef77dfee 100644 --- a/Fwk/AppFwk/CommonCode/cafUtils.h +++ b/Fwk/AppFwk/CommonCode/cafUtils.h @@ -69,6 +69,7 @@ class Utils static bool isFolderWritable(const QString& folderName); static bool isStringMatch(const QString& filterString, const QString& value); + static bool removeDirectoryAndFilesRecursively(const QString& dirName); }; } diff --git a/Fwk/AppFwk/CommonCode/cvfStructGrid.cpp b/Fwk/AppFwk/CommonCode/cvfStructGrid.cpp index 7e82ed2c93..c24531ed2c 100644 --- a/Fwk/AppFwk/CommonCode/cvfStructGrid.cpp +++ b/Fwk/AppFwk/CommonCode/cvfStructGrid.cpp @@ -249,9 +249,9 @@ void StructGridInterface::characteristicCellSizes(double* iSize, double* jSize, ubyte faceConnNegK[4]; cellFaceVertexIndices(StructGridInterface::NEG_K, faceConnNegK); - double iSize = 0.0; - double jSize = 0.0; - double kSize = 0.0; + double iLengthAccumulated = 0.0; + double jLengthAccumulated = 0.0; + double kLengthAccumulated = 0.0; cvf::Vec3d cornerVerts[8]; size_t cellCount = 0; @@ -270,20 +270,20 @@ void StructGridInterface::characteristicCellSizes(double* iSize, double* jSize, size_t cellIndex = cellIndexFromIJK(i, j, k); cellCornerVertices(cellIndex, cornerVerts); - iSize += (cornerVerts[faceConnPosI[0]] - cornerVerts[faceConnNegI[0]]).lengthSquared(); - iSize += (cornerVerts[faceConnPosI[1]] - cornerVerts[faceConnNegI[3]]).lengthSquared(); - iSize += (cornerVerts[faceConnPosI[2]] - cornerVerts[faceConnNegI[2]]).lengthSquared(); - iSize += (cornerVerts[faceConnPosI[3]] - cornerVerts[faceConnNegI[1]]).lengthSquared(); + iLengthAccumulated += (cornerVerts[faceConnPosI[0]] - cornerVerts[faceConnNegI[0]]).lengthSquared(); + iLengthAccumulated += (cornerVerts[faceConnPosI[1]] - cornerVerts[faceConnNegI[3]]).lengthSquared(); + iLengthAccumulated += (cornerVerts[faceConnPosI[2]] - cornerVerts[faceConnNegI[2]]).lengthSquared(); + iLengthAccumulated += (cornerVerts[faceConnPosI[3]] - cornerVerts[faceConnNegI[1]]).lengthSquared(); - jSize += (cornerVerts[faceConnPosJ[0]] - cornerVerts[faceConnNegJ[0]]).lengthSquared(); - jSize += (cornerVerts[faceConnPosJ[1]] - cornerVerts[faceConnNegJ[3]]).lengthSquared(); - jSize += (cornerVerts[faceConnPosJ[2]] - cornerVerts[faceConnNegJ[2]]).lengthSquared(); - jSize += (cornerVerts[faceConnPosJ[3]] - cornerVerts[faceConnNegJ[1]]).lengthSquared(); + jLengthAccumulated += (cornerVerts[faceConnPosJ[0]] - cornerVerts[faceConnNegJ[0]]).lengthSquared(); + jLengthAccumulated += (cornerVerts[faceConnPosJ[1]] - cornerVerts[faceConnNegJ[3]]).lengthSquared(); + jLengthAccumulated += (cornerVerts[faceConnPosJ[2]] - cornerVerts[faceConnNegJ[2]]).lengthSquared(); + jLengthAccumulated += (cornerVerts[faceConnPosJ[3]] - cornerVerts[faceConnNegJ[1]]).lengthSquared(); - kSize += (cornerVerts[faceConnPosK[0]] - cornerVerts[faceConnNegK[0]]).lengthSquared(); - kSize += (cornerVerts[faceConnPosK[1]] - cornerVerts[faceConnNegK[3]]).lengthSquared(); - kSize += (cornerVerts[faceConnPosK[2]] - cornerVerts[faceConnNegK[2]]).lengthSquared(); - kSize += (cornerVerts[faceConnPosK[3]] - cornerVerts[faceConnNegK[1]]).lengthSquared(); + kLengthAccumulated += (cornerVerts[faceConnPosK[0]] - cornerVerts[faceConnNegK[0]]).lengthSquared(); + kLengthAccumulated += (cornerVerts[faceConnPosK[1]] - cornerVerts[faceConnNegK[3]]).lengthSquared(); + kLengthAccumulated += (cornerVerts[faceConnPosK[2]] - cornerVerts[faceConnNegK[2]]).lengthSquared(); + kLengthAccumulated += (cornerVerts[faceConnPosK[3]] - cornerVerts[faceConnNegK[1]]).lengthSquared(); cellCount++; } @@ -295,9 +295,9 @@ void StructGridInterface::characteristicCellSizes(double* iSize, double* jSize, if (divisor > 0.0) { - m_characteristicCellSizeI = cvf::Math::sqrt(iSize / divisor); - m_characteristicCellSizeJ = cvf::Math::sqrt(jSize / divisor); - m_characteristicCellSizeK = cvf::Math::sqrt(kSize / divisor); + m_characteristicCellSizeI = cvf::Math::sqrt(iLengthAccumulated / divisor); + m_characteristicCellSizeJ = cvf::Math::sqrt(jLengthAccumulated / divisor); + m_characteristicCellSizeK = cvf::Math::sqrt(kLengthAccumulated / divisor); } } diff --git a/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp b/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp index 5f8e01e014..55f7a799c6 100644 --- a/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp +++ b/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.cpp @@ -77,6 +77,14 @@ void CellRangeFilter::addCellIncludeRange(size_t minI, size_t minJ, size_t minK, m_includeRanges.push_back(CellRange(minI, minJ, minK, maxI, maxJ, maxK, applyToSubGridAreas)); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CellRangeFilter::addCellInclude(size_t i, size_t j, size_t k, bool applyToSubGridAreas) +{ + m_includeRanges.push_back(CellRange(i, j, k, i + 1, j + 1, k + 1, applyToSubGridAreas)); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -88,9 +96,9 @@ void CellRangeFilter::addCellExcludeRange(size_t minI, size_t minJ, size_t minK, //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void CellRangeFilter::addCellInclude(size_t i, size_t j, size_t k, bool applyToSubGridAreas) +void CellRangeFilter::addCellExclude(size_t i, size_t j, size_t k, bool applyToSubGridAreas) { - m_includeRanges.push_back(CellRange(i, j, k, i, j, k, applyToSubGridAreas)); + m_excludeRanges.push_back(CellRange(i, j, k, i + 1, j + 1, k + 1, applyToSubGridAreas)); } //-------------------------------------------------------------------------------------------------- @@ -164,8 +172,9 @@ bool CellRangeFilter::hasIncludeRanges() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -StructGridGeometryGenerator::StructGridGeometryGenerator(const StructGridInterface* grid) -: m_grid(grid) +StructGridGeometryGenerator::StructGridGeometryGenerator(const StructGridInterface* grid, bool useOpenMP) +: m_grid(grid), + m_useOpenMP(useOpenMP) { CVF_ASSERT(grid); m_quadMapper = new StructGridQuadToCellFaceMapper; @@ -365,7 +374,7 @@ void StructGridGeometryGenerator::computeArrays() cvf::Vec3d offset = m_grid->displayModelOffset(); -#pragma omp parallel for schedule(dynamic) +#pragma omp parallel for schedule(dynamic) if (m_useOpenMP) for (int k = 0; k < static_cast(m_grid->cellCountK()); k++) { size_t j; @@ -404,7 +413,7 @@ void StructGridGeometryGenerator::computeArrays() m_grid->cellFaceVertexIndices(face, faceConn); // Critical section to avoid two threads accessing the arrays at the same time. - #pragma omp critical + #pragma omp critical(critical_section_StructGridGeometryGenerator_computeArrays) { int n; for (n = 0; n < 4; n++) diff --git a/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.h b/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.h index 29b532828b..2308348b76 100644 --- a/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.h +++ b/Fwk/AppFwk/CommonCode/cvfStructGridGeometryGenerator.h @@ -60,6 +60,7 @@ class CellRangeFilter void addCellInclude(size_t i, size_t j, size_t k, bool applyToSubGridAreas); void addCellExcludeRange(size_t minI, size_t minJ, size_t minK, size_t maxI, size_t maxJ, size_t maxK, bool applyToSubGridAreas); + void addCellExclude(size_t i, size_t j, size_t k, bool applyToSubGridAreas); bool isCellVisible(size_t i, size_t j, size_t k, bool isInSubGridArea) const; bool isCellExcluded(size_t i, size_t j, size_t k, bool isInSubGridArea) const; @@ -163,7 +164,7 @@ class StuctGridTriangleToCellFaceMapper : public Object class StructGridGeometryGenerator : public Object { public: - explicit StructGridGeometryGenerator(const StructGridInterface* grid); + explicit StructGridGeometryGenerator(const StructGridInterface* grid, bool useOpenMP); ~StructGridGeometryGenerator(); // Setup methods @@ -208,6 +209,11 @@ class StructGridGeometryGenerator : public Object // Mappings ref m_quadMapper; ref m_triangleMapper; + + // Multiple treads can be used when building geometry data structures. + // This causes visual artifacts due to transparency algorithm, and a stable visual image + // can be produced if OpenMP is disabled. Currently used by regression test comparing images + bool m_useOpenMP; }; } diff --git a/Fwk/AppFwk/cafAnimControl/CMakeLists.txt b/Fwk/AppFwk/cafAnimControl/CMakeLists.txt index 4a4b41bffe..5e016e8180 100644 --- a/Fwk/AppFwk/cafAnimControl/CMakeLists.txt +++ b/Fwk/AppFwk/cafAnimControl/CMakeLists.txt @@ -47,4 +47,8 @@ target_include_directories(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR} ) +if (MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/W4 /wd4127") +endif() + source_group("" FILES ${PROJECT_FILES}) diff --git a/Fwk/AppFwk/cafCommand/CMakeLists.txt b/Fwk/AppFwk/cafCommand/CMakeLists.txt index 4ebb3c9fed..d4e2656877 100644 --- a/Fwk/AppFwk/cafCommand/CMakeLists.txt +++ b/Fwk/AppFwk/cafCommand/CMakeLists.txt @@ -70,4 +70,8 @@ target_link_libraries ( ${PROJECT_NAME} cafProjectDataModel ) +if (MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/W4 /wd4100 /wd4127") +endif() + source_group("" FILES ${PROJECT_FILES}) diff --git a/Fwk/AppFwk/cafCommand/cafCmdExecCommandManager.cpp b/Fwk/AppFwk/cafCommand/cafCmdExecCommandManager.cpp index 2c7ae60011..445c5e0a38 100644 --- a/Fwk/AppFwk/cafCommand/cafCmdExecCommandManager.cpp +++ b/Fwk/AppFwk/cafCommand/cafCmdExecCommandManager.cpp @@ -57,7 +57,7 @@ class UndoRedoWrapper : public QUndoCommand setText(m_executeCommand->name()); } - ~UndoRedoWrapper() + ~UndoRedoWrapper() override { delete m_executeCommand; } @@ -65,7 +65,7 @@ class UndoRedoWrapper : public QUndoCommand //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void undo() + void undo() override { m_executeCommand->undo(); } @@ -73,7 +73,7 @@ class UndoRedoWrapper : public QUndoCommand //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void redo() + void redo() override { m_executeCommand->redo(); } diff --git a/Fwk/AppFwk/cafCommand/cafCmdFeature.h b/Fwk/AppFwk/cafCommand/cafCmdFeature.h index db4c8856af..d1b905f575 100644 --- a/Fwk/AppFwk/cafCommand/cafCmdFeature.h +++ b/Fwk/AppFwk/cafCommand/cafCmdFeature.h @@ -74,7 +74,7 @@ class CmdFeature : public QObject Q_OBJECT public: CmdFeature(); - virtual ~CmdFeature(); + ~CmdFeature() override; QAction* action(); QAction* actionWithCustomText(const QString& customText); diff --git a/Fwk/AppFwk/cafCommand/cafCmdFeatureManager.h b/Fwk/AppFwk/cafCommand/cafCmdFeatureManager.h index 5053985847..db3bb6a605 100644 --- a/Fwk/AppFwk/cafCommand/cafCmdFeatureManager.h +++ b/Fwk/AppFwk/cafCommand/cafCmdFeatureManager.h @@ -60,7 +60,7 @@ class CmdFeatureManager : public QObject public: static CmdFeatureManager* instance(); - virtual ~CmdFeatureManager(); + ~CmdFeatureManager() override; QAction* action(const QString& commandId); QAction* action(const QString& commandId, const QString& customActionText); diff --git a/Fwk/AppFwk/cafCommand/cafCmdFieldChangeExec.h b/Fwk/AppFwk/cafCommand/cafCmdFieldChangeExec.h index 5606809b7e..ac2797d56b 100644 --- a/Fwk/AppFwk/cafCommand/cafCmdFieldChangeExec.h +++ b/Fwk/AppFwk/cafCommand/cafCmdFieldChangeExec.h @@ -77,14 +77,14 @@ class CmdFieldChangeExec : public CmdExecuteCommand { public: explicit CmdFieldChangeExec(NotificationCenter* notificationCenter); - virtual ~CmdFieldChangeExec(); + ~CmdFieldChangeExec() override; CmdFieldChangeExecData* commandData(); - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: void readFieldValueFromValidXmlDocument(QXmlStreamReader& xmlStream, PdmXmlFieldHandle* xmlFieldHandle); diff --git a/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.cpp b/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.cpp index c7f6636047..fab5475222 100644 --- a/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.cpp +++ b/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.cpp @@ -37,25 +37,14 @@ #include "cafCmdSelectionChangeExec.h" #include "cafPdmReferenceHelper.h" +#include "cafSelectionManager.h" namespace caf { - - template<> - void AppEnum::setUp() - { - addItem(SelectionManager::APPLICATION_GLOBAL, "APPLICATION_GLOBAL", "APPLICATION_GLOBAL"); - addItem(SelectionManager::CURRENT, "CURRENT", "CURRENT"); - addItem(SelectionManager::UNDEFINED, "UNDEFINED", "UNDEFINED"); - setDefault(SelectionManager::UNDEFINED); - } - CAF_PDM_SOURCE_INIT(CmdSelectionChangeExecData, "CmdSelectionChangeExecData"); - - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -69,7 +58,7 @@ QString CmdSelectionChangeExec::name() //-------------------------------------------------------------------------------------------------- void CmdSelectionChangeExec::redo() { - SelectionManager::instance()->setSelectionFromReferences(m_commandData->m_newSelection.v(), m_commandData->m_selectionRole.v()); + SelectionManager::instance()->setSelectionAtLevelFromReferences(m_commandData->m_newSelection.v(), m_commandData->m_selectionLevel.v()); } //-------------------------------------------------------------------------------------------------- @@ -77,7 +66,7 @@ void CmdSelectionChangeExec::redo() //-------------------------------------------------------------------------------------------------- void CmdSelectionChangeExec::undo() { - SelectionManager::instance()->setSelectionFromReferences(m_commandData->m_previousSelection.v(), m_commandData->m_selectionRole.v()); + SelectionManager::instance()->setSelectionAtLevelFromReferences(m_commandData->m_previousSelection.v(), m_commandData->m_selectionLevel.v()); } //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.h b/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.h index aada19f097..3f9676743f 100644 --- a/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.h +++ b/Fwk/AppFwk/cafCommand/cafCmdSelectionChangeExec.h @@ -40,7 +40,6 @@ #include "cafPdmField.h" #include "cafPdmObject.h" -#include "cafSelectionManager.h" #include "cafAppEnum.h" @@ -61,12 +60,12 @@ class CmdSelectionChangeExecData : public PdmObject { CAF_PDM_InitObject("CmdSelectionChangeExecData uiName", "", "CmdSelectionChangeExecData tooltip", "CmdSelectionChangeExecData whatsthis"); - CAF_PDM_InitFieldNoDefault(&m_selectionRole, "selectionRole", "selectionRole", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_selectionLevel, "selectionLevel", "selectionLevel", "", "", ""); CAF_PDM_InitField(&m_previousSelection, "previousSelection", std::vector(), "previousSelection", "", "", ""); CAF_PDM_InitField(&m_newSelection, "newSelection", std::vector(), "newSelection", "", "", ""); } - PdmField< AppEnum > m_selectionRole; + PdmField< int > m_selectionLevel; PdmField< std::vector > m_previousSelection; PdmField< std::vector > m_newSelection; }; @@ -79,13 +78,13 @@ class CmdSelectionChangeExec : public CmdExecuteCommand { public: explicit CmdSelectionChangeExec(NotificationCenter* notificationCenter); - virtual ~CmdSelectionChangeExec();; + ~CmdSelectionChangeExec() override;; CmdSelectionChangeExecData* commandData(); - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: CmdSelectionChangeExecData* m_commandData; diff --git a/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.cpp b/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.cpp index e3a78c5c62..f8ccf61a14 100644 --- a/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.cpp +++ b/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.cpp @@ -40,6 +40,8 @@ #include "cafCmdExecCommandManager.h" #include "cafCmdSelectionChangeExec.h" +#include "cafSelectionManager.h" + namespace caf { @@ -47,9 +49,9 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void CmdSelectionHelper::executeSelectionCommand(const std::vector& selection, SelectionManager::SelectionRole role) +void CmdSelectionHelper::executeSelectionCommand(const std::vector& selection, int selectionLevel) { - CmdSelectionChangeExec* selectionChangeExec = createSelectionCommand(selection, role); + CmdSelectionChangeExec* selectionChangeExec = createSelectionCommand(selection, selectionLevel); CmdExecCommandManager::instance()->processExecuteCommand(selectionChangeExec); } @@ -57,11 +59,12 @@ void CmdSelectionHelper::executeSelectionCommand(const std::vector& selection, SelectionManager::SelectionRole role) +CmdSelectionChangeExec* CmdSelectionHelper::createSelectionCommand(const std::vector& selection, int selectionLevel) { CmdSelectionChangeExec* selectionChangeExec = new CmdSelectionChangeExec(SelectionManager::instance()->notificationCenter()); - selectionChangeExec->commandData()->m_selectionRole.v() = role; - SelectionManager::instance()->selectionAsReferences(selectionChangeExec->commandData()->m_previousSelection.v(), role); + selectionChangeExec->commandData()->m_selectionLevel.v() = selectionLevel; + + SelectionManager::instance()->selectionAsReferences(selectionChangeExec->commandData()->m_previousSelection.v(), selectionLevel); for (size_t i = 0; i < selection.size(); i++) { diff --git a/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.h b/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.h index bb933ba9fa..1a9e919866 100644 --- a/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.h +++ b/Fwk/AppFwk/cafCommand/cafCmdSelectionHelper.h @@ -37,20 +37,18 @@ #pragma once -#include "cafSelectionManager.h" - #include - namespace caf { class CmdSelectionChangeExec; +class PdmObjectHandle; class CmdSelectionHelper { public: - static void executeSelectionCommand(const std::vector& selection, SelectionManager::SelectionRole role); - static CmdSelectionChangeExec* createSelectionCommand(const std::vector& selection, SelectionManager::SelectionRole role); + static void executeSelectionCommand(const std::vector& selection, int selectionLevel); + static CmdSelectionChangeExec* createSelectionCommand(const std::vector& selection, int selectionLevel); }; diff --git a/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.cpp b/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.cpp index cfc18684fd..574c5a8954 100644 --- a/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.cpp +++ b/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.cpp @@ -66,43 +66,9 @@ CmdUiCommandSystemImpl::CmdUiCommandSystemImpl() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void CmdUiCommandSystemImpl::fieldChangedCommand(PdmFieldHandle* editorField, const QVariant& newUiValue) +void CmdUiCommandSystemImpl::fieldChangedCommand( const std::vector& fieldsToUpdate, const QVariant& newUiValue) { - std::vector fieldsToUpdate; - fieldsToUpdate.push_back(editorField); - - // For current selection, find all fields with same keyword - { - std::vector items; - SelectionManager::instance()->selectedItems(items, SelectionManager::CURRENT); - - for (size_t i = 0; i < items.size(); i++) - { - PdmObjectHandle* objectHandle = dynamic_cast(items[i]); - if (objectHandle) - { - // An object is selected, find field with same keyword as the current field being edited - PdmFieldHandle* fieldHandle = objectHandle->findField(editorField->keyword()); - if (fieldHandle && fieldHandle != editorField) - { - fieldsToUpdate.push_back(fieldHandle); - } - } - else - { - // A field is selected, check if keywords are identical - PdmUiFieldHandle* uiFieldHandle = dynamic_cast(items[i]); - if (uiFieldHandle) - { - PdmFieldHandle* field = uiFieldHandle->fieldHandle(); - if (field && field != editorField && field->keyword() == editorField->keyword()) - { - fieldsToUpdate.push_back(field); - } - } - } - } - } + if ( fieldsToUpdate.empty() ) return; std::vector commands; @@ -136,7 +102,7 @@ void CmdUiCommandSystemImpl::fieldChangedCommand(PdmFieldHandle* editorField, co } } - caf::PdmUiObjectHandle* uiOwnerObjectHandle = uiObj(editorField->ownerObject()); + caf::PdmUiObjectHandle* uiOwnerObjectHandle = uiObj(fieldsToUpdate[0]->ownerObject()); if (uiOwnerObjectHandle && !uiOwnerObjectHandle->useUndoRedoForFieldChanged()) { // Temporarily disable undo framework as requested by the PdmUiObjectHandle diff --git a/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.h b/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.h index 40fb1c787d..5fe57e6625 100644 --- a/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.h +++ b/Fwk/AppFwk/cafCommand/cafCmdUiCommandSystemImpl.h @@ -38,7 +38,7 @@ #pragma once #include "cafInternalPdmUiCommandSystemInterface.h" - +#include namespace caf { @@ -50,8 +50,8 @@ class CmdUiCommandSystemImpl : public PdmUiCommandSystemInterface public: CmdUiCommandSystemImpl(); - virtual void fieldChangedCommand(PdmFieldHandle* field, const QVariant& newUiValue); - virtual void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu); + void fieldChangedCommand(const std::vector& fieldsToUpdate, const QVariant& newUiValue) override; + void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu) override; bool isUndoEnabled(); void enableUndoFeature(bool enable); diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExec.h b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExec.h index 3ee60f49b0..ffeb7f942a 100644 --- a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExec.h +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemExec.h @@ -52,13 +52,13 @@ class CmdAddItemExec : public CmdExecuteCommand { public: explicit CmdAddItemExec(NotificationCenter* notificationCenter); - virtual ~CmdAddItemExec();; + ~CmdAddItemExec() override;; CmdAddItemExecData* commandData(); - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: CmdAddItemExecData* m_commandData; diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemFeature.h b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemFeature.h index 576f291288..28036fd5b0 100644 --- a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemFeature.h +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdAddItemFeature.h @@ -53,9 +53,9 @@ class CmdAddItemFeature : public CmdFeature protected: CmdExecuteCommand* createExecuteCommand(); - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExec.h b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExec.h index 083aa43a00..b39896cda7 100644 --- a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExec.h +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemExec.h @@ -52,14 +52,14 @@ class CmdDeleteItemExec : public CmdExecuteCommand { public: explicit CmdDeleteItemExec(NotificationCenter* notificationCenter); - virtual ~CmdDeleteItemExec() {}; + ~CmdDeleteItemExec() override {}; CmdDeleteItemExecData* commandData(); - virtual QString name(); - virtual void redo(); - virtual void undo(); + QString name() override; + void redo() override; + void undo() override; private: CmdDeleteItemExecData* m_commandData; diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.cpp b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.cpp index 09ae65ca65..1901fd9e7d 100644 --- a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.cpp +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.cpp @@ -58,7 +58,7 @@ namespace caf CmdExecuteCommand* CmdDeleteItemFeature::createExecuteCommand() { std::vector items; - SelectionManager::instance()->selectedItems(items, SelectionManager::CURRENT); + SelectionManager::instance()->selectedItems(items, SelectionManager::FIRST_LEVEL); caf::PdmChildArrayFieldHandle* childArrayFieldHandle = caf::SelectionManager::instance()->activeChildArrayFieldHandle(); if (!childArrayFieldHandle) return nullptr; @@ -106,7 +106,7 @@ CmdExecuteCommand* CmdDeleteItemFeature::createExecuteCommand() //-------------------------------------------------------------------------------------------------- bool CmdDeleteItemFeature::isCommandEnabled() { - caf::PdmObject* currentPdmObject = dynamic_cast(caf::SelectionManager::instance()->selectedItem(caf::SelectionManager::CURRENT)); + caf::PdmObject* currentPdmObject = dynamic_cast(caf::SelectionManager::instance()->selectedItem(caf::SelectionManager::FIRST_LEVEL)); if (!currentPdmObject) return false; caf::PdmChildArrayFieldHandle* childArrayFieldHandle = caf::SelectionManager::instance()->activeChildArrayFieldHandle(); diff --git a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.h b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.h index d98288614c..425df6e30d 100644 --- a/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.h +++ b/Fwk/AppFwk/cafCommand/defaultfeatures/cafCmdDeleteItemFeature.h @@ -52,9 +52,9 @@ class CmdDeleteItemFeature : public CmdFeature CmdExecuteCommand* createExecuteCommand(); // Overrides - virtual bool isCommandEnabled(); - virtual void onActionTriggered( bool isChecked ); - virtual void setupActionLook( QAction* actionToSetup ); + bool isCommandEnabled() override; + void onActionTriggered( bool isChecked ) override; + void setupActionLook( QAction* actionToSetup ) override; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt index aab257286e..107983a970 100644 --- a/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt +++ b/Fwk/AppFwk/cafProjectDataModel/CMakeLists.txt @@ -8,7 +8,6 @@ include (${QT_USE_FILE}) set( PROJECT_FILES cafFactory.h - cafFixedArray.h cafOmpMutex.h cafPdmDocument.cpp cafPdmDocument.h @@ -32,4 +31,8 @@ target_include_directories(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR} ) +if (MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/W4 /wd4100 /wd4127") +endif() + source_group("" FILES ${PROJECT_FILES}) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafFactory.h b/Fwk/AppFwk/cafProjectDataModel/cafFactory.h index 94a87f979f..2b291a5b3f 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafFactory.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafFactory.h @@ -58,8 +58,13 @@ #define CAF_UNIQUE_COMPILE_UNIT_VAR_NAME(foo) CAF_FACTORY_CONCATENATE_STRINGS(foo, __LINE__) +/// Macros to simplify registering entries in a factory +/// There are two, to make it possible to use two registrations in one macro + #define CAF_FACTORY_REGISTER(BaseType, TypeToCreate, KeyType, key) \ static bool CAF_UNIQUE_COMPILE_UNIT_VAR_NAME(my##TypeToCreate) = caf::Factory::instance()->registerCreator(key) +#define CAF_FACTORY_REGISTER2(BaseType, TypeToCreate, KeyType, key) \ +static bool CAF_UNIQUE_COMPILE_UNIT_VAR_NAME(my2##TypeToCreate) = caf::Factory::instance()->registerCreator(key) namespace caf { diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/CMakeLists.txt index 40e8db36b0..cd5797cb83 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/CMakeLists.txt +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/CMakeLists.txt @@ -45,6 +45,10 @@ set( PROJECT_FILES cafTristate.h cafFilePath.cpp cafFilePath.h + cafAsyncObjectDeleter.h + cafAsyncObjectDeleter.inl + cafAsyncWorkerManager.h + cafAsyncWorkerManager.cpp ) add_library( ${PROJECT_NAME} @@ -56,4 +60,8 @@ target_include_directories(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR} ) +if (MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/W4 /wd4100 /wd4127") +endif() + source_group("" FILES ${PROJECT_FILES}) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncObjectDeleter.h similarity index 55% rename from Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h rename to Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncObjectDeleter.h index 86ab9af79d..daa7e8ca18 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafFixedArray.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncObjectDeleter.h @@ -34,43 +34,21 @@ // //################################################################################################## - #pragma once -#include "cafAssert.h" - - namespace caf { - -//================================================================================================== -/// A fixed array class. Used to create small fixed size index arrays typically -//================================================================================================== - -template < typename T, size_t size > -class FixedArray -{ - T m_array[size]; -public: - - const T* data() const { return m_array; } - T* data() { return m_array; } - - FixedArray& operator=(const T* ptr) { for (size_t i = 0; i < size ; ++i) m_array[i] = ptr[i]; return *this;} - - template T& operator[](const IndexType& index) { CAF_ASSERT(static_cast(index) < size); return m_array[index]; } - template const T& operator[](const IndexType& index) const { CAF_ASSERT(static_cast(index) < size); return m_array[index]; } -}; - -typedef FixedArray IntArray3; -typedef FixedArray IntArray6; -typedef FixedArray IntArray4; -typedef FixedArray IntArray8; -typedef FixedArray UintArray4; -typedef FixedArray UintArray8; -typedef FixedArray SizeTArray3; -typedef FixedArray SizeTArray4; -typedef FixedArray SizeTArray6; -typedef FixedArray SizeTArray8; - + template + class AsyncPdmObjectVectorDeleter + { + public: + AsyncPdmObjectVectorDeleter(std::vector& pointerVector); + AsyncPdmObjectVectorDeleter(std::vector>& pdmPointerVector); + ~AsyncPdmObjectVectorDeleter(); + void start(); + private: + std::vector m_pointersToDelete; + }; } + +#include "cafAsyncObjectDeleter.inl" diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncObjectDeleter.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncObjectDeleter.inl new file mode 100644 index 0000000000..fef1b4d0f2 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncObjectDeleter.inl @@ -0,0 +1,74 @@ +#include + +#include "cafAsyncWorkerManager.h" +#include "cafPdmObjectHandle.h" + +namespace caf +{ + //-------------------------------------------------------------------------------------------------- + /// Constructor that takes ownership of the data in the provided vector + //-------------------------------------------------------------------------------------------------- + template + AsyncPdmObjectVectorDeleter::AsyncPdmObjectVectorDeleter(std::vector& pointerVector) + { + m_pointersToDelete.reserve(pointerVector.size()); + for (PdmObjectType* rawPointer : pointerVector) + { + if (rawPointer) + { + PdmObjectHandle* objectHandle = static_cast(rawPointer); + objectHandle->prepareForDelete(); + m_pointersToDelete.push_back(objectHandle); + } + } + pointerVector.clear(); + } + + //-------------------------------------------------------------------------------------------------- + /// Constructor that takes ownership of the data in the provided vector + //-------------------------------------------------------------------------------------------------- + template + AsyncPdmObjectVectorDeleter::AsyncPdmObjectVectorDeleter(std::vector>& pdmPointerVector) + { + m_pointersToDelete.reserve(pdmPointerVector.size()); + for (PdmPointer& pdmPointer : pdmPointerVector) + { + if (pdmPointer.notNull()) + { + PdmObjectHandle* objectHandle = pdmPointer.rawPtr(); + objectHandle->prepareForDelete(); + m_pointersToDelete.push_back(objectHandle); + } + } + pdmPointerVector.clear(); + } + + //-------------------------------------------------------------------------------------------------- + /// Destructor will launch the asynchronous deletion if start() hasn't already been run. + //-------------------------------------------------------------------------------------------------- + template + AsyncPdmObjectVectorDeleter::~AsyncPdmObjectVectorDeleter() + { + if (!m_pointersToDelete.empty()) + { + start(); + } + } + + //-------------------------------------------------------------------------------------------------- + /// Perform deletion of the pointers in a separate thread. + //-------------------------------------------------------------------------------------------------- + template + void AsyncPdmObjectVectorDeleter::start() + { + std::thread thread([](std::vector&& pointerVector) + { + for (PdmObjectHandle* pointerToDelete : pointerVector) + { + delete pointerToDelete; + } + }, std::move(m_pointersToDelete)); + AsyncWorkerManager::instance().takeThreadOwnership(thread, false); + } + +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncWorkerManager.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncWorkerManager.cpp new file mode 100644 index 0000000000..940629cc98 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncWorkerManager.cpp @@ -0,0 +1,81 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafAsyncWorkerManager.h" + +//-------------------------------------------------------------------------------------------------- +/// Create a static thread manager that is cleared when the program ends. +//-------------------------------------------------------------------------------------------------- +caf::AsyncWorkerManager& caf::AsyncWorkerManager::instance() +{ + static AsyncWorkerManager manager; + return manager; +} + +//-------------------------------------------------------------------------------------------------- +/// Destructor waiting for threads to join. +//-------------------------------------------------------------------------------------------------- +caf::AsyncWorkerManager::~AsyncWorkerManager() +{ + for (ThreadAndJoinAtExitPair& workerThreadAndJoinFlag : m_threads) + { + if (workerThreadAndJoinFlag.second && workerThreadAndJoinFlag.first.joinable()) + { + workerThreadAndJoinFlag.first.join(); + } + else + { + workerThreadAndJoinFlag.first.detach(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// Takes over ownership of the thread and the caller no longer has access to it. +/// A flag can be provided to force the Worker manager to join the threads on exit. +/// Set this to true if it is important that the thread finishes before the program exits. +//-------------------------------------------------------------------------------------------------- +void caf::AsyncWorkerManager::takeThreadOwnership(std::thread& thread, bool joinAtExit) +{ + m_threads.push_back(std::make_pair(std::move(thread), joinAtExit)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::AsyncWorkerManager::AsyncWorkerManager() +{ +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncWorkerManager.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncWorkerManager.h new file mode 100644 index 0000000000..f8c33ff141 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafAsyncWorkerManager.h @@ -0,0 +1,56 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2011-2013 Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include +#include +#include + +namespace caf +{ + class AsyncWorkerManager + { + public: + static AsyncWorkerManager& instance(); + ~AsyncWorkerManager(); + void takeThreadOwnership(std::thread& thread, bool joinAtExit); + private: + typedef std::pair ThreadAndJoinAtExitPair; + AsyncWorkerManager(); + std::vector m_threads; + }; +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.h index c3546cecd8..67b89af2aa 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.h @@ -21,7 +21,7 @@ class PdmChildArrayFieldHandle : public PdmPtrArrayFieldHandle { public: PdmChildArrayFieldHandle() {} - virtual ~PdmChildArrayFieldHandle() {} + ~PdmChildArrayFieldHandle() override {} virtual void deleteAllChildObjects() = 0; @@ -51,19 +51,21 @@ class PdmChildArrayField : public PdmChildArrayFieldHandle typedef DataType* DataTypePtr; public: PdmChildArrayField() { } - virtual ~PdmChildArrayField(); + ~PdmChildArrayField() override; PdmChildArrayField& operator() () { return *this; } const PdmChildArrayField& operator() () const { return *this; } // Reimplementation of PdmPointersFieldHandle methods - virtual size_t size() const { return m_pointers.size(); } - virtual bool empty() const { return m_pointers.empty(); } - virtual void clear(); - virtual void deleteAllChildObjects(); - virtual void insertAt(int indexAfter, PdmObjectHandle* obj); - virtual PdmObjectHandle* at(size_t index); + size_t size() const override { return m_pointers.size(); } + bool empty() const override { return m_pointers.empty(); } + void clear() override; + void deleteAllChildObjects() override; + void insertAt(int indexAfter, PdmObjectHandle* obj) override; + PdmObjectHandle* at(size_t index) override; + + virtual void deleteAllChildObjectsAsync(); // std::vector-like access @@ -75,7 +77,7 @@ class PdmChildArrayField : public PdmChildArrayFieldHandle void insert(size_t indexAfter, const std::vector >& objects); size_t count(const DataType* pointer) const; - void erase(size_t index); + void erase(size_t index) override; size_t index(const DataType* pointer) const; typename std::vector< PdmPointer >::iterator begin() { return m_pointers.begin(); }; @@ -88,8 +90,8 @@ class PdmChildArrayField : public PdmChildArrayFieldHandle // Child objects std::vector childObjects() const; - virtual void childObjects(std::vector* objects); - virtual void removeChildObject(PdmObjectHandle* object); + void childObjects(std::vector* objects) override; + void removeChildObject(PdmObjectHandle* object) override; private: //To be disabled PDM_DISABLE_COPY_AND_ASSIGN(PdmChildArrayField); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.inl index 019111b2e5..faf473dcad 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.inl +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmChildArrayField.inl @@ -1,3 +1,4 @@ +#include "cafAsyncObjectDeleter.h" #include "cafClassTypeName.h" #include "cafPdmObjectHandle.h" @@ -138,6 +139,20 @@ void PdmChildArrayField::deleteAllChildObjects() m_pointers.clear(); } +//-------------------------------------------------------------------------------------------------- +/// Transfers ownership of the objects pointed to a separate thread. +/// Then clears the container and lets the thread delete the objects. +//-------------------------------------------------------------------------------------------------- +template +void PdmChildArrayField::deleteAllChildObjectsAsync() +{ + CAF_ASSERT(isInitializedByInitFieldMacro()); + + AsyncPdmObjectVectorDeleter pointerDeleter(m_pointers); + CAF_ASSERT(m_pointers.empty()); // Object storage for m_pointers should be empty immediately. +} + + //-------------------------------------------------------------------------------------------------- /// Removes the pointer at index from the container. Does not delete the object pointed to. /// Todo: This implementation can't be necessary in the new regime. Should be to just remove diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmCoreBasicTest.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmCoreBasicTest.cpp index b4e51874dc..24f7e815d9 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmCoreBasicTest.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmCore_UnitTests/cafPdmCoreBasicTest.cpp @@ -14,13 +14,11 @@ #include - -class DemoPdmObject: public caf::PdmObjectHandle +class DemoPdmObject : public caf::PdmObjectHandle { public: - - DemoPdmObject() - { + DemoPdmObject() + { this->addField(&m_proxyDoubleField, "m_proxyDoubleField"); m_proxyDoubleField.registerSetMethod(this, &DemoPdmObject::setDoubleMember); m_proxyDoubleField.registerGetMethod(this, &DemoPdmObject::doubleMember); @@ -34,105 +32,111 @@ class DemoPdmObject: public caf::PdmObjectHandle m_proxyStringField.registerGetMethod(this, &DemoPdmObject::stringMember); this->addField(&m_memberDoubleField, "m_memberDoubleField"); - this->addField(&m_memberIntField, "m_memberIntField"); + this->addField(&m_memberIntField, "m_memberIntField"); this->addField(&m_memberStringField, "m_memberStringField"); - - - // Default values + // Default values m_doubleMember = 2.1; - m_intMember = 7; + m_intMember = 7; m_stringMember = "abba"; m_memberDoubleField = 0.0; - m_memberIntField = 0; + m_memberIntField = 0; m_memberStringField = ""; - } - ~DemoPdmObject() - { - } + ~DemoPdmObject() {} // Fields caf::PdmProxyValueField m_proxyDoubleField; caf::PdmProxyValueField m_proxyIntField; caf::PdmProxyValueField m_proxyStringField; - caf::PdmDataValueField m_memberDoubleField; - caf::PdmDataValueField m_memberIntField; - caf::PdmDataValueField m_memberStringField; - + caf::PdmDataValueField m_memberDoubleField; + caf::PdmDataValueField m_memberIntField; + caf::PdmDataValueField m_memberStringField; // Internal class members accessed by proxy fields - double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } - void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } - - int intMember() const { return m_intMember; } - void setIntMember(const int& val) { m_intMember = val; } + double doubleMember() const + { + std::cout << "doubleMember" << std::endl; + return m_doubleMember; + } + void setDoubleMember(const double& d) + { + m_doubleMember = d; + std::cout << "setDoubleMember" << std::endl; + } - QString stringMember() const { return m_stringMember; } - void setStringMember(const QString& val) { m_stringMember = val; } + int intMember() const + { + return m_intMember; + } + void setIntMember(const int& val) + { + m_intMember = val; + } + + QString stringMember() const + { + return m_stringMember; + } + void setStringMember(const QString& val) + { + m_stringMember = val; + } -private: +private: double m_doubleMember; int m_intMember; QString m_stringMember; }; - class InheritedDemoObj : public DemoPdmObject { public: - InheritedDemoObj() { this->addField(&m_texts, "Texts"); this->addField(&m_childArrayField, "DemoPdmObjectects"); this->addField(&m_ptrField, "m_ptrField"); - + this->addField(&m_singleFilePath, "m_singleFilePath"); this->addField(&m_multipleFilePath, "m_multipleFilePath"); - } - caf::PdmDataValueField m_texts; + caf::PdmDataValueField m_texts; caf::PdmChildArrayField m_childArrayField; caf::PdmPtrField m_ptrField; - caf::PdmDataValueField m_singleFilePath; - caf::PdmDataValueField> m_multipleFilePath; + caf::PdmDataValueField m_singleFilePath; + caf::PdmDataValueField> m_multipleFilePath; }; - TEST(BaseTest, Delete) { - DemoPdmObject* s2 = new DemoPdmObject; - delete s2; + DemoPdmObject* s2 = new DemoPdmObject; + delete s2; } - //-------------------------------------------------------------------------------------------------- /// TestPdmDataValueField //-------------------------------------------------------------------------------------------------- TEST(BaseTest, TestPdmDataValueField) { - DemoPdmObject* a = new DemoPdmObject; - + DemoPdmObject* a = new DemoPdmObject; - ASSERT_DOUBLE_EQ(0.0, a->m_memberDoubleField.value()); - a->m_memberDoubleField.setValue(1.2); - ASSERT_DOUBLE_EQ(1.2, a->m_memberDoubleField.value()); - - ASSERT_EQ(0, a->m_memberIntField.value()); - a->m_memberIntField.setValue(11); - ASSERT_EQ(11, a->m_memberIntField.value()); - - ASSERT_TRUE(a->m_memberStringField.value().isEmpty()); - a->m_memberStringField.setValue("123"); - ASSERT_TRUE(a->m_memberStringField.value() == "123"); + ASSERT_DOUBLE_EQ(0.0, a->m_memberDoubleField.value()); + a->m_memberDoubleField.setValue(1.2); + ASSERT_DOUBLE_EQ(1.2, a->m_memberDoubleField.value()); + ASSERT_EQ(0, a->m_memberIntField.value()); + a->m_memberIntField.setValue(11); + ASSERT_EQ(11, a->m_memberIntField.value()); + ASSERT_TRUE(a->m_memberStringField.value().isEmpty()); + a->m_memberStringField.setValue("123"); + ASSERT_TRUE(a->m_memberStringField.value() == "123"); } //-------------------------------------------------------------------------------------------------- @@ -153,65 +157,62 @@ TEST(BaseTest, TestPdmProxyValueField) ASSERT_TRUE(a->m_proxyStringField.value() == "abba"); a->m_proxyStringField.setValue("123"); ASSERT_TRUE(a->m_proxyStringField.value() == "123"); - } //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- TEST(BaseTest, TestPdmValueFieldInterface) { - DemoPdmObject* a = new DemoPdmObject; - - { - caf::PdmValueField* valField = dynamic_cast(a->findField("m_proxyDoubleField")); - QVariant newVal = 3.4; - valField->setFromQVariant(newVal); - QVariant var = valField->toQVariant(); - ASSERT_TRUE(newVal == var); - } - - { - caf::PdmValueField* valField = dynamic_cast(a->findField("m_proxyIntField")); - QVariant newVal = 3; - valField->setFromQVariant(newVal); - QVariant var = valField->toQVariant(); - ASSERT_TRUE(newVal == var); - } - - { - caf::PdmValueField* valField = dynamic_cast(a->findField("m_proxyStringField")); - QVariant newVal = "test"; - valField->setFromQVariant(newVal); - QVariant var = valField->toQVariant(); - ASSERT_TRUE(newVal == var); - } - - { - caf::PdmValueField* valField = dynamic_cast(a->findField("m_memberDoubleField")); - QVariant newVal = 3.4; - valField->setFromQVariant(newVal); - QVariant var = valField->toQVariant(); - ASSERT_TRUE(newVal == var); - } - - { - caf::PdmValueField* valField = dynamic_cast(a->findField("m_memberIntField")); - QVariant newVal = 3; - valField->setFromQVariant(newVal); - QVariant var = valField->toQVariant(); - ASSERT_TRUE(newVal == var); - } - - { - caf::PdmValueField* valField = dynamic_cast(a->findField("m_memberStringField")); - QVariant newVal = "test"; - valField->setFromQVariant(newVal); - QVariant var = valField->toQVariant(); - ASSERT_TRUE(newVal == var); - } + DemoPdmObject* a = new DemoPdmObject; -} + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_proxyDoubleField")); + QVariant newVal = 3.4; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_proxyIntField")); + QVariant newVal = 3; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_proxyStringField")); + QVariant newVal = "test"; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_memberDoubleField")); + QVariant newVal = 3.4; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_memberIntField")); + QVariant newVal = 3; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } + + { + caf::PdmValueField* valField = dynamic_cast(a->findField("m_memberStringField")); + QVariant newVal = "test"; + valField->setFromQVariant(newVal); + QVariant var = valField->toQVariant(); + ASSERT_TRUE(newVal == var); + } +} //-------------------------------------------------------------------------------------------------- /// Test of PdmDataValueField operations @@ -221,19 +222,20 @@ TEST(BaseTest, NormalPdmField) class A : public caf::PdmObjectHandle { public: - explicit A(const std::vector& testValue) : field2(testValue), field3(field2) + explicit A(const std::vector& testValue) + : field2(testValue) + , field3(field2) { this->addField(&field1, "field1"); this->addField(&field2, "field2"); this->addField(&field3, "field3"); } - caf::PdmDataValueField > field1; - caf::PdmDataValueField > field2; - caf::PdmDataValueField > field3; + caf::PdmDataValueField> field1; + caf::PdmDataValueField> field2; + caf::PdmDataValueField> field3; }; - std::vector testValue; testValue.push_back(1.1); testValue.push_back(1.2); @@ -351,14 +353,12 @@ TEST(BaseTest, PdmChildArrayField) EXPECT_TRUE(s3 == NULL); } - TEST(BaseTest, PdmChildArrayParentField) { // Test of instanciating a class with forward declare of object used in PdmChildArrayField and PdmChildField Parent* parentObj = new Parent; delete parentObj; - } #include "Child.h" @@ -371,7 +371,7 @@ TEST(BaseTest, PdmPointersFieldInsertVector) Child* s2 = new Child; Child* s3 = new Child; - std::vector > typedObjects; + std::vector> typedObjects; typedObjects.push_back(s1); typedObjects.push_back(s2); typedObjects.push_back(s3); @@ -389,30 +389,29 @@ TEST(BaseTest, PdmPointersFieldInsertVector) //-------------------------------------------------------------------------------------------------- TEST(BaseTest, PdmChildArrayFieldHandle) { - // virtual size_t size() const = 0; // virtual bool empty() const = 0; // virtual void clear() = 0; // virtual PdmObject* createAppendObject(int indexAfter) = 0; // virtual void erase(size_t index) = 0; // virtual void deleteAllChildObjects() = 0; - // + // // virtual PdmObject* at(size_t index) = 0; - // + // // bool hasSameFieldCountForAllObjects(); - DemoPdmObject* s0 = new DemoPdmObject; + DemoPdmObject* s0 = new DemoPdmObject; s0->m_memberDoubleField = 1000; - DemoPdmObject* s1 = new DemoPdmObject; + DemoPdmObject* s1 = new DemoPdmObject; s1->m_memberDoubleField = 1000; - DemoPdmObject* s2 = new DemoPdmObject; + DemoPdmObject* s2 = new DemoPdmObject; s2->m_memberDoubleField = 2000; - DemoPdmObject* s3 = new DemoPdmObject; + DemoPdmObject* s3 = new DemoPdmObject; s3->m_memberDoubleField = 3000; - InheritedDemoObj* ihd1 = new InheritedDemoObj; + InheritedDemoObj* ihd1 = new InheritedDemoObj; caf::PdmChildArrayFieldHandle* listField = &(ihd1->m_childArrayField); EXPECT_EQ(0, listField->size()); @@ -441,7 +440,6 @@ TEST(BaseTest, PdmChildArrayFieldHandle) EXPECT_EQ(0, listField->size()); EXPECT_TRUE(listField->hasSameFieldCountForAllObjects()); EXPECT_TRUE(listField->empty()); - } //-------------------------------------------------------------------------------------------------- /// Test of PdmChildField @@ -453,8 +451,8 @@ TEST(BaseTest, PdmChildField) { public: explicit A(Child* a) - : field2(a), - b(0) + : field2(a) + , b(0) { this->addField(&field2, "field2"); } @@ -465,7 +463,7 @@ TEST(BaseTest, PdmChildField) } caf::PdmChildField field2; - int b; + int b; }; { @@ -480,7 +478,7 @@ TEST(BaseTest, PdmChildField) EXPECT_EQ(static_cast(nullptr), a.field2); } { - A a(NULL); + A a(NULL); Child* c2 = new Child; // Assign a.field2 = c2; @@ -490,7 +488,6 @@ TEST(BaseTest, PdmChildField) EXPECT_EQ(c2, a.field2.value()); EXPECT_TRUE(c2 == a.field2); - std::vector objects; a.field2.childObjects(&objects); EXPECT_EQ((size_t)1, objects.size()); @@ -498,7 +495,6 @@ TEST(BaseTest, PdmChildField) } } - TEST(BaseTest, PdmPtrField) { InheritedDemoObj* ihd1 = new InheritedDemoObj; @@ -508,18 +504,18 @@ TEST(BaseTest, PdmPtrField) EXPECT_EQ(static_cast(nullptr), ihd1->m_ptrField); // Assignment - ihd1->m_ptrField = ihd1; + ihd1->m_ptrField = ihd1; InheritedDemoObj* accessedIhd = ihd1->m_ptrField; EXPECT_EQ(ihd1, accessedIhd); ihd1->m_ptrField = caf::PdmPointer(ihd2); - accessedIhd = ihd1->m_ptrField; + accessedIhd = ihd1->m_ptrField; EXPECT_EQ(ihd2, accessedIhd); // Access accessedIhd = ihd1->m_ptrField; // Conversion EXPECT_EQ(ihd2, accessedIhd); - accessedIhd = ihd1->m_ptrField.value(); + accessedIhd = ihd1->m_ptrField.value(); EXPECT_EQ(ihd2, accessedIhd); caf::PdmPointer accessedPdmPtr; @@ -532,43 +528,52 @@ TEST(BaseTest, PdmPtrField) // Operator == EXPECT_TRUE(ihd1->m_ptrField == ihd2); EXPECT_FALSE(ihd1->m_ptrField == ihd1); - + EXPECT_TRUE(ihd1->m_ptrField == caf::PdmPointer(ihd2)); // Generic access - std::vector objects; - ihd1->m_ptrField.ptrReferencedObjects(&objects); - EXPECT_EQ(1, objects.size()); - EXPECT_EQ(ihd2, objects[0]); + { + std::vector objects; + ihd1->m_ptrField.ptrReferencedObjects(&objects); + EXPECT_EQ(1, objects.size()); + EXPECT_EQ(ihd2, objects[0]); + } // Operator -> ihd1->m_ptrField->m_texts = "Hei PtrField"; - EXPECT_TRUE(ihd1->m_ptrField->m_texts == "Hei PtrField"); + EXPECT_TRUE(ihd1->m_ptrField->m_texts == "Hei PtrField"); - // Refrencing system - std::vector ptrFields; - ihd2->referringPtrFields(ptrFields); - EXPECT_EQ(1, ptrFields.size()); - EXPECT_EQ(&(ihd1->m_ptrField), ptrFields[0]); + // Referencing system + { + std::vector ptrFields; + ihd2->referringPtrFields(ptrFields); + EXPECT_EQ(1, ptrFields.size()); + EXPECT_EQ(&(ihd1->m_ptrField), ptrFields[0]); + } - objects.clear(); - ihd2->objectsWithReferringPtrFields(objects); - EXPECT_EQ(1, objects.size()); - EXPECT_EQ(ihd1, objects[0]); + { + std::vector objects; + ihd2->objectsWithReferringPtrFields(objects); + EXPECT_EQ(1, objects.size()); + EXPECT_EQ(ihd1, objects[0]); + } + { + std::vector reffingDemoObjects; + ihd2->objectsWithReferringPtrFieldsOfType(reffingDemoObjects); + EXPECT_EQ(1, reffingDemoObjects.size()); + } delete ihd1; delete ihd2; - } - //-------------------------------------------------------------------------------------------------- /// Tests the features of PdmPointer //-------------------------------------------------------------------------------------------------- TEST(BaseTest, PdmPointer) { - InheritedDemoObj * d = new InheritedDemoObj; + InheritedDemoObj* d = new InheritedDemoObj; { caf::PdmPointer p; @@ -594,12 +599,10 @@ TEST(BaseTest, PdmPointer) caf::PdmPointer p3(new DemoPdmObject()); delete p3; - } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- TEST(BaseTest, PdmFilePath) { @@ -615,7 +618,7 @@ TEST(BaseTest, PdmFilePath) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- TEST(BaseTest, MultiplePdmFilePath) { @@ -625,7 +628,7 @@ TEST(BaseTest, MultiplePdmFilePath) d->m_multipleFilePath.v().push_back(newVal); d->m_multipleFilePath.v().push_back(newVal); - QVariant var = d->m_multipleFilePath.toQVariant(); + QVariant var = d->m_multipleFilePath.toQVariant(); QStringList str = var.toStringList(); EXPECT_EQ(2, str.size()); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h index 4529e4aed5..9a45fb4898 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmDataValueField.h @@ -94,7 +94,7 @@ class PdmDataValueField : public PdmValueField const DataType& v() const { return m_fieldValue; } bool operator== (const DataType& fieldValue) const { return m_fieldValue == fieldValue; } - + bool operator!= (const DataType& fieldValue) const { return m_fieldValue != fieldValue; } protected: DataType m_fieldValue; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.cpp index ea72d25d38..b184061ef2 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.cpp @@ -14,18 +14,7 @@ namespace caf //-------------------------------------------------------------------------------------------------- PdmObjectHandle::~PdmObjectHandle() { - for (size_t i = 0; i < m_capabilities.size(); ++i) - { - if (m_capabilities[i].second) delete m_capabilities[i].first; - } - - // Set all guarded pointers pointing to this to NULL - - std::set::iterator it; - for (it = m_pointersReferencingMe.begin(); it != m_pointersReferencingMe.end() ; ++it) - { - (**it) = nullptr; - } + this->prepareForDelete(); } //-------------------------------------------------------------------------------------------------- @@ -102,6 +91,30 @@ void PdmObjectHandle::objectsWithReferringPtrFields(std::vector::iterator it; + for (it = m_pointersReferencingMe.begin(); it != m_pointersReferencingMe.end(); ++it) + { + (**it) = nullptr; + } + + m_capabilities.clear(); + m_referencingPtrFields.clear(); + m_pointersReferencingMe.clear(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h index e877c83003..87d5e1a7d8 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmObjectHandle.h @@ -53,6 +53,12 @@ class PdmObjectHandle void referringPtrFields(std::vector& fieldsReferringToMe) const; /// Convenience method to get the objects pointing to this field void objectsWithReferringPtrFields(std::vector& objects) const; + /// Convenience method to get the objects of specified type pointing to this field + template + void objectsWithReferringPtrFieldsOfType(std::vector& objectsOfType) const; + + // Detach object from all referring fields + void prepareForDelete(); // Object capabilities void addCapability(PdmObjectCapability* capability, bool takeOwnership) { m_capabilities.push_back(std::make_pair(capability, takeOwnership)); } @@ -124,10 +130,10 @@ void PdmObjectHandle::firstAncestorOrThisOfType(T*& ancestor) const // Check if this matches the type - const T* objectOfType = dynamic_cast(this); - if (objectOfType) + const T* objectOfTypeConst = dynamic_cast(this); + if (objectOfTypeConst) { - ancestor = const_cast(objectOfType); + ancestor = const_cast(objectOfTypeConst); return; } @@ -199,5 +205,24 @@ void PdmObjectHandle::descendantsIncludingThisOfType(std::vector& descendant } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void PdmObjectHandle::objectsWithReferringPtrFieldsOfType(std::vector& objectsOfType) const +{ + std::vector objectsReferencingThis; + this->objectsWithReferringPtrFields(objectsReferencingThis); + + for (auto object : objectsReferencingThis) + { + if (dynamic_cast(object)) + { + objectsOfType.push_back(dynamic_cast(object)); + } + } +} + + } // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPointer.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPointer.h index b9caaf2d58..ffdf1a403c 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPointer.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPointer.h @@ -78,7 +78,7 @@ class PdmPointer { PdmObjectHandle* m_object; public : - inline PdmPointer () : m_object(NULL) { } + inline PdmPointer () : m_object(nullptr) { } inline PdmPointer ( T * p ) : m_object(p) { PdmPointerImpl::addReference(&m_object); } inline PdmPointer ( const PdmPointer & p ) : m_object ( p.m_object ) { PdmPointerImpl::addReference(&m_object); } @@ -92,13 +92,15 @@ public : T* operator->() const { return static_cast(const_cast(m_object)); } PdmPointer & operator= ( const PdmPointer& p ) { if (this != &p) PdmPointerImpl::removeReference(&m_object); m_object = p.m_object; PdmPointerImpl::addReference(&m_object); return *this; } PdmPointer & operator= ( T* p ) { if (m_object != p) PdmPointerImpl::removeReference(&m_object); m_object = p; PdmPointerImpl::addReference(&m_object); return *this; } - + template + bool operator==(const PdmPointer& rhs) const { return m_object == rhs.rawPtr(); } // Private methods used by PdmField and PdmPointersField. Do not use unless you mean it ! PdmObjectHandle* rawPtr() const { return m_object; } void setRawPtr( PdmObjectHandle* p) { if (m_object != p) PdmPointerImpl::removeReference(&m_object); m_object = p; PdmPointerImpl::addReference(&m_object); } }; - - } // End of namespace caf +#include +Q_DECLARE_METATYPE(caf::PdmPointer); + diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrArrayFieldHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrArrayFieldHandle.h index 574d0d61bc..6226e6c42d 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrArrayFieldHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrArrayFieldHandle.h @@ -14,7 +14,7 @@ class PdmPtrArrayFieldHandle : public PdmFieldHandle { public: PdmPtrArrayFieldHandle() {} - virtual ~PdmPtrArrayFieldHandle() {} + ~PdmPtrArrayFieldHandle() override {} virtual size_t size() const = 0; virtual bool empty() const = 0; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h index 11e800eb4a..5ac6e0c879 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h @@ -3,7 +3,7 @@ #include "cafAssert.h" #include "cafPdmPointer.h" -#include "cafPdmFieldHandle.h" +#include "cafPdmValueField.h" namespace caf { @@ -21,7 +21,7 @@ template< typename T> class PdmFieldXmlCap; //================================================================================================== template -class PdmPtrField : public PdmFieldHandle +class PdmPtrField : public PdmValueField { public: PdmPtrField() @@ -31,7 +31,7 @@ class PdmPtrField : public PdmFieldHandle }; template -class PdmPtrField : public PdmFieldHandle +class PdmPtrField : public PdmValueField { typedef DataType* DataTypePtr; public: @@ -51,6 +51,11 @@ class PdmPtrField : public PdmFieldHandle DataType* value() const { return m_fieldValue; } void setValue(const DataTypePtr& fieldValue); + // QVariant access + virtual QVariant toQVariant() const override; + virtual void setFromQVariant(const QVariant& variant) override; + virtual bool isReadOnly() const override { return false; } + // Access operators /*Conversion*/ operator DataType* () const { return m_fieldValue; } @@ -80,6 +85,3 @@ class PdmPtrField : public PdmFieldHandle } // End of namespace caf #include "cafPdmPtrField.inl" - -#include -Q_DECLARE_METATYPE(caf::PdmPointer); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl index d02373d73c..0aaaa36149 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl @@ -1,6 +1,29 @@ +#include + namespace caf { +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +QVariant caf::PdmPtrField::toQVariant() const +{ + caf::PdmObjectHandle* objectHandle = m_fieldValue.rawPtr(); + caf::PdmPointer ptrHandle(objectHandle); + return QVariant::fromValue(ptrHandle); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +void caf::PdmPtrField::setFromQVariant(const QVariant& variant) +{ + caf::PdmPointer variantHandle = variant.value>(); + m_fieldValue.setRawPtr(variantHandle.rawPtr()); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp index ca3169abf8..a228299144 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp @@ -60,7 +60,7 @@ PdmDocument::PdmDocument() void PdmDocument::readFile() { QFile xmlFile(fileName); - if (!xmlFile.open(QIODevice::ReadOnly )) + if (!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) return; readFile(&xmlFile); @@ -101,7 +101,7 @@ void PdmDocument::readFile(QIODevice* xmlFile) bool PdmDocument::writeFile() { QFile xmlFile(fileName); - if (!xmlFile.open(QIODevice::WriteOnly )) + if (!xmlFile.open(QIODevice::WriteOnly | QIODevice::Text)) return false; writeFile(&xmlFile); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h index 4883a159c6..2914a7ecfc 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmObject.h @@ -140,7 +140,7 @@ class PdmObject : public PdmObjectHandle, public PdmXmlObjectHandle, public PdmU { public: PdmObject() : PdmObjectHandle(), PdmXmlObjectHandle(this, false), PdmUiObjectHandle(this, false) {} - virtual ~PdmObject() {} + ~PdmObject() override {} /// Adds field to the internal data structure and sets the file keyword and Ui information /// Consider this method private. Please use the CAF_PDM_InitField() macro instead diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectGroup.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectGroup.h index 067e797f28..e596efdb00 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectGroup.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmObjectGroup.h @@ -18,7 +18,7 @@ class PdmObjectGroup : public PdmObject CAF_PDM_HEADER_INIT; public: PdmObjectGroup(); - ~PdmObjectGroup(); + ~PdmObjectGroup() override; std::vector objects; @@ -73,7 +73,7 @@ class PdmObjectCollection : public PdmObject CAF_PDM_HEADER_INIT; public: PdmObjectCollection(); - ~PdmObjectCollection(); + ~PdmObjectCollection() override; caf::PdmChildArrayField objects; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt index 45aa9428f7..5d5ccd9094 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt @@ -10,6 +10,15 @@ include_directories ( .. ) +# These headers need to go through Qt's MOC compiler +set( QOBJECT_HEADERS + cafPdmUiFieldEditorHandle.h +) + +if ( NOT CMAKE_AUTOMOC ) + qt4_wrap_cpp( MOC_FILES_CPP ${QOBJECT_HEADERS} ) +endif() + set( PROJECT_FILES cafInternalPdmFieldTypeSpecializations.h @@ -44,11 +53,14 @@ set( PROJECT_FILES cafSelectionManager.cpp cafSelectionManager.h + cafSelectionChangedReceiver.h + cafSelectionChangedReceiver.cpp cafSelectionManagerTools.h ) add_library( ${PROJECT_NAME} ${PROJECT_FILES} + ${MOC_FILES_CPP} ) target_link_libraries ( ${PROJECT_NAME} @@ -60,4 +72,8 @@ target_include_directories(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR} ) +if (MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/W4 /wd4100 /wd4127") +endif() + source_group("" FILES ${PROJECT_FILES}) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiCommandSystemInterface.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiCommandSystemInterface.h index 07f247fef7..89ebc8b453 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiCommandSystemInterface.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiCommandSystemInterface.h @@ -36,6 +36,8 @@ #pragma once +#include + class QVariant; class QMenu; class QString; @@ -50,7 +52,7 @@ class PdmUiFieldHandle; class PdmUiCommandSystemInterface { public: - virtual void fieldChangedCommand(PdmFieldHandle* field, const QVariant& newUiValue) = 0; + virtual void fieldChangedCommand( const std::vector& fieldsToUpdate, const QVariant& newUiValue) = 0; virtual void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu) = 0; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.h index 7ae9b45686..9b00a03882 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.h @@ -15,14 +15,14 @@ class PdmFieldUiCap : public PdmUiFieldHandle // Gui generalized interface public: - virtual QVariant uiValue() const; - virtual void setValueFromUiEditor(const QVariant& uiValue); - virtual QList valueOptions(bool* useOptionsOnly); + QVariant uiValue() const override; + void setValueFromUiEditor(const QVariant& uiValue) override; + QList valueOptions(bool* useOptionsOnly) const override; - virtual QVariant toUiBasedQVariant() const; + QVariant toUiBasedQVariant() const override; private: - QList m_optionEntryCache; + mutable QList m_optionEntryCache; private: FieldType* m_field; @@ -42,11 +42,11 @@ class PdmFieldUiCap< PdmChildField > : public PdmUiFieldHandle // Gui generalized interface public: - virtual QVariant uiValue() const { return QVariant();} - virtual void setValueFromUiEditor(const QVariant& uiValue) { } - virtual QList valueOptions(bool* useOptionsOnly) { return QList(); } + QVariant uiValue() const override { return QVariant();} + void setValueFromUiEditor(const QVariant& uiValue) override { } + QList valueOptions(bool* useOptionsOnly) const override { return QList(); } - virtual QVariant toUiBasedQVariant() const { return QVariant(); } + QVariant toUiBasedQVariant() const override { return QVariant(); } }; // @@ -61,11 +61,11 @@ class PdmFieldUiCap< PdmChildArrayField > : public PdmUiFieldHandle // Gui generalized interface public: - virtual QVariant uiValue() const { return QVariant(); } - virtual void setValueFromUiEditor(const QVariant& uiValue) { } - virtual QList valueOptions(bool* useOptionsOnly) { return QList(); } + QVariant uiValue() const override { return QVariant(); } + void setValueFromUiEditor(const QVariant& uiValue) override { } + QList valueOptions(bool* useOptionsOnly) const override { return QList(); } - virtual QVariant toUiBasedQVariant() const { return QVariant(); } + QVariant toUiBasedQVariant() const override { return QVariant(); } }; template diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.inl index 14b16ac725..34b98ff1db 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.inl +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafInternalPdmUiFieldCapability.inl @@ -169,7 +169,7 @@ QVariant caf::PdmFieldUiCap::uiValue() const //-------------------------------------------------------------------------------------------------- template -QList caf::PdmFieldUiCap::valueOptions(bool* useOptionsOnly) +QList caf::PdmFieldUiCap::valueOptions(bool* useOptionsOnly) const { m_optionEntryCache.clear(); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiCommandSystemProxy.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiCommandSystemProxy.cpp index 810ad8a96d..a60aa18910 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiCommandSystemProxy.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiCommandSystemProxy.cpp @@ -42,8 +42,10 @@ #include "cafPdmObjectHandle.h" #include "cafPdmUiFieldHandle.h" #include "cafPdmUiObjectHandle.h" +#include "cafSelectionManager.h" #include +#include namespace caf { @@ -83,13 +85,62 @@ void PdmUiCommandSystemProxy::setUiValueToField(PdmUiFieldHandle* uiFieldHandle, { if (uiFieldHandle) { + // Handle editing multiple objects when several objects are selected + PdmFieldHandle* editorField = uiFieldHandle->fieldHandle(); + const std::type_info& fieldOwnerTypeId = typeid( *editorField->ownerObject()); + + std::vector fieldsToUpdate; + fieldsToUpdate.push_back(editorField); + + // For level 1 selection, find all fields with same keyword + // Todo: Should traverse the ui ordering and find all fields with same keyword and same ownerobject type. + // Until we do, fields embedded into the property panel from a different object will not work with multiselection edit + // For now we only makes sure we have same ownerobject type + { + std::vector items; + + int selectionLevel = 1; // = 0; + SelectionManager::instance()->selectedItems(items, selectionLevel); + + for (size_t i = 0; i < items.size(); i++) + { + PdmObjectHandle* objectHandle = dynamic_cast(items[i]); + if (objectHandle && typeid( *objectHandle) == fieldOwnerTypeId) + { + // An object is selected, find field with same keyword as the current field being edited + PdmFieldHandle* fieldHandle = objectHandle->findField(editorField->keyword()); + if (fieldHandle && fieldHandle != editorField) + { + fieldsToUpdate.push_back(fieldHandle); + } + } + else + { + // Todo Remove when dust has settled. Selection manager is not supposed to select single fields + // A field is selected, check if keywords are identical + PdmUiFieldHandle* itemFieldHandle = dynamic_cast(items[i]); + if (itemFieldHandle) + { + PdmFieldHandle* field = itemFieldHandle->fieldHandle(); + if (field && field != editorField && field->keyword() == editorField->keyword()) + { + fieldsToUpdate.push_back(field); + } + } + } + } + } + if (m_commandInterface) { - m_commandInterface->fieldChangedCommand(uiFieldHandle->fieldHandle(), newUiValue); + m_commandInterface->fieldChangedCommand(fieldsToUpdate, newUiValue); } else { - uiFieldHandle->setValueFromUiEditor(newUiValue); + for (auto fieldHandle : fieldsToUpdate) + { + fieldHandle->uiCapability()->setValueFromUiEditor(newUiValue); + } } } } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.cpp index 74009476b4..cc3153de1e 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.cpp @@ -43,7 +43,9 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiEditorHandle::PdmUiEditorHandle() : m_pdmItem(nullptr) +PdmUiEditorHandle::PdmUiEditorHandle() + : m_pdmItem(nullptr) + , m_isConfiguringUi(false) { } @@ -56,6 +58,29 @@ PdmUiEditorHandle::~PdmUiEditorHandle() if (m_pdmItem) m_pdmItem->removeFieldEditor(this); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiEditorHandle::updateUi(const QString& uiConfigName) +{ + CAF_ASSERT(!m_isConfiguringUi); + m_isConfiguringUi = true; + m_currentConfigName = uiConfigName; + this->configureAndUpdateUi(uiConfigName); + m_isConfiguringUi = false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiEditorHandle::updateUi() +{ + CAF_ASSERT(!m_isConfiguringUi); + m_isConfiguringUi = true; + this->configureAndUpdateUi(m_currentConfigName); + m_isConfiguringUi = false; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.h index a5c4e23f99..f3641e40d5 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiEditorHandle.h @@ -50,29 +50,20 @@ class PdmUiItem; /// Abstract class to handle editors. Inherits QObject to be able to use signals and slots //================================================================================================== -class PdmUiEditorHandle: public QObject +class PdmUiEditorHandle : public QObject { public: PdmUiEditorHandle(); - virtual ~PdmUiEditorHandle(); + ~PdmUiEditorHandle() override; public: + void updateUi(const QString& uiConfigName);; + void updateUi();; + +protected: + // Interface to override: /// Virtual method to be overridden. Needs to set up the supplied widget /// with all signals etc to make it communicate with this object - - void updateUi(const QString& uiConfigName) - { - m_currentConfigName = uiConfigName; - this->configureAndUpdateUi(uiConfigName); - }; - - void updateUi() - { - this->configureAndUpdateUi(m_currentConfigName); - }; - -protected: // Interface to override: - /// Supposed to update all parts of the widgets, both visibility, sensitivity, decorations and field data virtual void configureAndUpdateUi(const QString& uiConfigName) = 0; @@ -86,6 +77,8 @@ class PdmUiEditorHandle: public QObject friend PdmUiItem::~PdmUiItem(); PdmUiItem* m_pdmItem; QString m_currentConfigName; + + bool m_isConfiguringUi; }; @@ -99,12 +92,12 @@ class PdmUiProxyEditorHandle: public PdmUiEditorHandle { public: explicit PdmUiProxyEditorHandle(PdmUiEditorHandle* mainEditorHandle) : PdmUiEditorHandle() { m_mainEditorHandle = mainEditorHandle; } - virtual ~PdmUiProxyEditorHandle() {}; + ~PdmUiProxyEditorHandle() override {}; protected: // Interface to override: /// Supposed to update all parts of the widgets, both visibility, sensitivity, decorations and field data - virtual void configureAndUpdateUi(const QString& uiConfigName) + void configureAndUpdateUi(const QString& uiConfigName) override { if (m_mainEditorHandle) { diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp index 003814a2d5..6aae177baf 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.cpp @@ -37,10 +37,14 @@ #include "cafPdmUiFieldEditorHandle.h" -#include "cafPdmUiFieldHandle.h" +#include "cafPdmObjectHandle.h" #include "cafPdmUiCommandSystemProxy.h" +#include "cafPdmUiFieldHandle.h" +#include "cafPdmUiObjectHandle.h" +#include #include +#include #include namespace caf @@ -70,15 +74,27 @@ PdmUiFieldEditorHandle::~PdmUiFieldEditorHandle() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiFieldEditorHandle::setField(PdmUiFieldHandle * field) +void PdmUiFieldEditorHandle::setUiField(PdmUiFieldHandle * field) { this->bindToPdmItem(field); + + if (m_editorWidget) + { + if (field && field->isCustomContextMenuEnabled()) + { + m_editorWidget->setContextMenuPolicy(Qt::CustomContextMenu); + } + else + { + m_editorWidget->setContextMenuPolicy(Qt::DefaultContextMenu); + } + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiFieldHandle* PdmUiFieldEditorHandle::field() +PdmUiFieldHandle* PdmUiFieldEditorHandle::uiField() { return dynamic_cast(pdmItem()); } @@ -91,6 +107,19 @@ void PdmUiFieldEditorHandle::createWidgets(QWidget * parent) if (m_combinedWidget.isNull()) m_combinedWidget = createCombinedWidget(parent); if (m_editorWidget.isNull()) m_editorWidget = createEditorWidget(parent); if (m_labelWidget.isNull()) m_labelWidget = createLabelWidget(parent); + + if (m_editorWidget) + { + connect(m_editorWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(customMenuRequested(QPoint))); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QMargins PdmUiFieldEditorHandle::labelContentMargins() const +{ + return calculateLabelContentMargins(); } //-------------------------------------------------------------------------------------------------- @@ -98,7 +127,7 @@ void PdmUiFieldEditorHandle::createWidgets(QWidget * parent) //-------------------------------------------------------------------------------------------------- void PdmUiFieldEditorHandle::setValueToField(const QVariant& newUiValue) { - PdmUiCommandSystemProxy::instance()->setUiValueToField(field(), newUiValue); + PdmUiCommandSystemProxy::instance()->setUiValueToField(uiField(), newUiValue); } //-------------------------------------------------------------------------------------------------- @@ -127,5 +156,56 @@ void PdmUiFieldEditorHandle::updateLabelFromField(QLabel* label, const QString& } } -} //End of namespace caf +//------------------------------------------------------------------------------------------------------------ +/// Re-implement this virtual method if a custom PdmUiField is misaligned with its label. +/// See cafPdmUiLineEditor for an example. +//------------------------------------------------------------------------------------------------------------ +QMargins PdmUiFieldEditorHandle::calculateLabelContentMargins() const +{ + return m_labelWidget->contentsMargins(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiFieldEditorHandle::customMenuRequested(QPoint pos) +{ + PdmObjectHandle* objectHandle = nullptr; + if (uiField() && uiField()->fieldHandle()) + { + objectHandle = uiField()->fieldHandle()->ownerObject(); + } + + if (!objectHandle) + { + return; + } + + auto widget = editorWidget(); + if (widget) + { + QPoint globalPos; + + auto abstractScrollAreaWidget = dynamic_cast(widget); + + if (abstractScrollAreaWidget) + { + // Qt doc: QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the viewport(). + globalPos = abstractScrollAreaWidget->viewport()->mapToGlobal(pos); + } + else + { + globalPos = widget->mapToGlobal(pos); + } + + QMenu menu; + objectHandle->uiCapability()->defineCustomContextMenu(uiField()->fieldHandle(), &menu, widget); + + if (!menu.actions().empty()) + { + menu.exec(globalPos); + } + } +} +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h index e18b411dc7..b2c220f794 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldEditorHandle.h @@ -33,8 +33,6 @@ // for more details. // //################################################################################################## - - #pragma once #include "cafFactory.h" @@ -49,20 +47,6 @@ class QLabel; - -// Taken from gtest.h -// -// Due to C++ preprocessor weirdness, we need double indirection to -// concatenate two tokens when one of them is __LINE__. Writing -// -// foo ## __LINE__ -// -// will result in the token foo__LINE__, instead of foo followed by -// the current line number. For more details, see -// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 -#define PDM_FIELD_EDITOR_STRING_CONCATENATE(foo, bar) PDM_FIELD_EDITOR_STRING_CONCATENATE_IMPL_(foo, bar) -#define PDM_FIELD_EDITOR_STRING_CONCATENATE_IMPL_(foo, bar) foo ## bar - namespace caf { @@ -70,23 +54,26 @@ namespace caf /// Macros helping in development of PDM UI editors //================================================================================================== -/// CAF_PDM_UI_EDITOR_HEADER_INIT assists the factory used when creating editors +/// CAF_PDM_UI_FIELD_EDITOR_HEADER_INIT assists the factory used when creating editors /// Place this in the header file inside the class definition of your PdmUiEditor #define CAF_PDM_UI_FIELD_EDITOR_HEADER_INIT \ public: \ static QString uiEditorTypeName() - /// CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT implements editorTypeName() and registers the field editor in the field editor factory - /// Place this in the cpp file, preferably above the constructor +/// CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT implements editorTypeName() and registers the field editor in the field editor factory +/// Place this in the cpp file, preferably above the constructor #define CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(EditorClassName) \ QString EditorClassName::uiEditorTypeName() { return #EditorClassName; } \ - static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(my##EditorClassName, __LINE__) = caf::Factory::instance()->registerCreator(EditorClassName::uiEditorTypeName()) + CAF_FACTORY_REGISTER(caf::PdmUiFieldEditorHandle, EditorClassName, QString, EditorClassName::uiEditorTypeName()) + +/// CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR registers what default editor to use with a field of a certain type +/// Place this in the cpp file, preferably above the constructor #define CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(EditorClassName, TypeName) \ - static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(myField##EditorClassName, __LINE__) = caf::Factory::instance()->registerCreator(qStringTypeName(caf::PdmField)); \ - static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(myProxyField##EditorClassName, __LINE__) = caf::Factory::instance()->registerCreator(qStringTypeName(caf::PdmProxyValueField)) + CAF_FACTORY_REGISTER(caf::PdmUiFieldEditorHandle, EditorClassName, QString, qStringTypeName(caf::PdmField)); \ + CAF_FACTORY_REGISTER2(caf::PdmUiFieldEditorHandle, EditorClassName, QString, qStringTypeName(caf::PdmProxyValueField) ) class PdmUiGroup; class PdmUiFieldHandle; @@ -97,18 +84,20 @@ class PdmUiFieldHandle; class PdmUiFieldEditorHandle : public PdmUiEditorHandle { + Q_OBJECT public: PdmUiFieldEditorHandle(); - ~PdmUiFieldEditorHandle(); + ~PdmUiFieldEditorHandle() override; - PdmUiFieldHandle* field(); - void setField(PdmUiFieldHandle * field); + PdmUiFieldHandle* uiField(); + void setUiField(PdmUiFieldHandle* uiFieldHandle); void createWidgets(QWidget * parent); QWidget* combinedWidget() { return m_combinedWidget; } QWidget* editorWidget() { return m_editorWidget; } QWidget* labelWidget() { return m_labelWidget; } + QMargins labelContentMargins() const; protected: // Virtual interface to override /// Implement one of these, or both editor and label. The widgets will be used in the parent layout according to @@ -121,6 +110,10 @@ class PdmUiFieldEditorHandle : public PdmUiEditorHandle void setValueToField(const QVariant& value); void updateLabelFromField(QLabel* label, const QString& uiConfigName = "") const; + virtual QMargins calculateLabelContentMargins() const; + +private slots: + void customMenuRequested(QPoint pos); private: QPointer m_combinedWidget; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.cpp index 1f6686a5dd..0cb0e16e0b 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.cpp @@ -7,23 +7,52 @@ namespace caf { +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiFieldHandle::PdmUiFieldHandle(PdmFieldHandle* owner, bool giveOwnership) + : m_isAutoAddingOptionFromValue(true) +{ + m_owner = owner; + owner->addCapability(this, giveOwnership); +} +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiFieldHandle::~PdmUiFieldHandle() {} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -PdmUiFieldHandle::PdmUiFieldHandle(PdmFieldHandle* owner, bool giveOwnership): - m_isAutoAddingOptionFromValue(true) +caf::PdmFieldHandle* PdmUiFieldHandle::fieldHandle() { - m_owner = owner; - owner->addCapability(this, giveOwnership); + return m_owner; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QVariant PdmUiFieldHandle::uiValue() const +{ + return QVariant(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList PdmUiFieldHandle::valueOptions(bool* useOptionsOnly) const +{ + return QList(); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void PdmUiFieldHandle::notifyFieldChanged(const QVariant& oldFieldValue, const QVariant& newFieldValue) { + // Todo : Should use a virtual version of isElementEqual. The variant != operation will not work on user types + if (oldFieldValue != newFieldValue) { PdmFieldHandle* fieldHandle = this->fieldHandle(); @@ -43,6 +72,27 @@ void PdmUiFieldHandle::notifyFieldChanged(const QVariant& oldFieldValue, const Q } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiFieldHandle::isAutoAddingOptionFromValue() const +{ + return m_isAutoAddingOptionFromValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiFieldHandle::setAutoAddingOptionFromValue(bool isAddingValue) +{ + m_isAutoAddingOptionFromValue = isAddingValue; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiFieldHandle::setValueFromUiEditor(const QVariant& uiValue) {} + //-------------------------------------------------------------------------------------------------- /// Implementation of uiCapability() defined in cafPdmFieldHandle.h //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.h index 242ce3ef51..1d05b955bb 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiFieldHandle.h @@ -1,43 +1,40 @@ #pragma once -#include "cafPdmUiItem.h" #include "cafPdmFieldCapability.h" #include "cafPdmUiFieldHandleInterface.h" +#include "cafPdmUiItem.h" namespace caf { - class PdmFieldHandle; class PdmUiFieldHandle : public PdmUiItem, public PdmFieldCapability, public PdmUiFieldHandleInterface { public: PdmUiFieldHandle(PdmFieldHandle* owner, bool giveOwnership); - virtual ~PdmUiFieldHandle() { } + ~PdmUiFieldHandle() override; - PdmFieldHandle* fieldHandle() { return m_owner; } + PdmFieldHandle* fieldHandle(); // Generalized access methods for User interface // The QVariant encapsulates the real value, or an index into the valueOptions - virtual QVariant uiValue() const { return QVariant(); } - virtual QList - valueOptions(bool* useOptionsOnly) { return QList(); } + virtual QVariant uiValue() const; + virtual QList valueOptions(bool* useOptionsOnly) const; - virtual void notifyFieldChanged(const QVariant& oldUiBasedQVariant, const QVariant& newUiBasedQVariant); + void notifyFieldChanged(const QVariant& oldUiBasedQVariant, const QVariant& newUiBasedQVariant) override; - bool isAutoAddingOptionFromValue() const { return m_isAutoAddingOptionFromValue; } - void setAutoAddingOptionFromValue(bool isAddingValue) { m_isAutoAddingOptionFromValue = isAddingValue;} + bool isAutoAddingOptionFromValue() const; + void setAutoAddingOptionFromValue(bool isAddingValue); private: friend class PdmUiCommandSystemProxy; friend class CmdFieldChangeExec; - virtual void setValueFromUiEditor(const QVariant& uiValue) { } + virtual void setValueFromUiEditor(const QVariant& uiValue); private: - PdmFieldHandle* m_owner; - bool m_isAutoAddingOptionFromValue; + PdmFieldHandle* m_owner; + bool m_isAutoAddingOptionFromValue; }; - } // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiGroup.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiGroup.cpp index de3741dea8..3d5aa18a9c 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiGroup.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiGroup.cpp @@ -48,6 +48,7 @@ PdmUiGroup::PdmUiGroup() m_isCollapsedByDefault = false; m_hasForcedExpandedState = false; m_forcedCollapseState = false; + m_enableFrame = true; } //-------------------------------------------------------------------------------------------------- @@ -75,7 +76,7 @@ QString PdmUiGroup::keyword() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool PdmUiGroup::isUiGroup() +bool PdmUiGroup::isUiGroup() const { return true; } @@ -97,6 +98,14 @@ void PdmUiGroup::setCollapsed(bool doCollapse) m_forcedCollapseState = doCollapse; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiGroup::setEnableFrame(bool enableFrame) +{ + m_enableFrame = enableFrame; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -121,5 +130,13 @@ bool PdmUiGroup::forcedExpandedState() const return !m_forcedCollapseState; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiGroup::enableFrame() const +{ + return m_enableFrame; +} + } //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiGroup.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiGroup.h index b30e0fb34c..4d3fd1cffb 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiGroup.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiGroup.h @@ -54,24 +54,27 @@ class PdmUiGroup : public PdmUiItem, public PdmUiOrdering void setKeyword(const QString& keyword); QString keyword() const; - virtual bool isUiGroup(); + bool isUiGroup() const override; /// Set this group to be collapsed by default. When the user expands the group, the default no longer has any effect. - void setCollapsedByDefault(bool doCollapse); + void setCollapsedByDefault(bool doCollapse); /// Forcifully set the collapsed state of the group, overriding the previous user actions and the default - void setCollapsed(bool doCollapse); + void setCollapsed(bool doCollapse); + void setEnableFrame(bool enableFrame); // Pdm internal methods - bool isExpandedByDefault() const; - bool hasForcedExpandedState() const; - bool forcedExpandedState() const; + bool isExpandedByDefault() const; + bool hasForcedExpandedState() const; + bool forcedExpandedState() const; + bool enableFrame() const; private: - bool m_isCollapsedByDefault; - bool m_hasForcedExpandedState; - bool m_forcedCollapseState; - - QString m_keyword; + bool m_isCollapsedByDefault; + bool m_hasForcedExpandedState; + bool m_forcedCollapseState; + bool m_enableFrame; + + QString m_keyword; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.cpp index dfe441507d..7b2a30549a 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.cpp @@ -34,44 +34,48 @@ // //################################################################################################## - #include "cafPdmUiItem.h" -#include "cafPdmUiEditorHandle.h" #include "cafPdmPtrField.h" +#include "cafPdmUiEditorHandle.h" #include "cafPdmUiObjectEditorHandle.h" namespace caf { - //-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -PdmOptionItemInfo::PdmOptionItemInfo(const QString& anOptionUiText, const QVariant& aValue, bool isReadOnly /* = false */, QIcon anIcon /* = QIcon()*/) - : m_optionUiText(anOptionUiText), - m_value(aValue), - m_isReadOnly(isReadOnly), - m_icon(anIcon), - m_level(0) +/// +//-------------------------------------------------------------------------------------------------- +PdmOptionItemInfo::PdmOptionItemInfo(const QString& anOptionUiText, + const QVariant& aValue, + bool isReadOnly /* = false */, + QIcon anIcon /* = QIcon()*/) + : m_optionUiText(anOptionUiText) + , m_value(aValue) + , m_isReadOnly(isReadOnly) + , m_icon(anIcon) + , m_level(0) { } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -PdmOptionItemInfo::PdmOptionItemInfo(const QString& anOptionUiText, caf::PdmObjectHandle* obj, bool isReadOnly /*= false*/, QIcon anIcon /*= QIcon()*/) - : m_optionUiText(anOptionUiText), - m_isReadOnly(isReadOnly), - m_icon(anIcon), - m_level(0) +PdmOptionItemInfo::PdmOptionItemInfo(const QString& anOptionUiText, + caf::PdmObjectHandle* obj, + bool isReadOnly /*= false*/, + QIcon anIcon /*= QIcon()*/) + : m_optionUiText(anOptionUiText) + , m_isReadOnly(isReadOnly) + , m_icon(anIcon) + , m_level(0) { m_value = QVariant::fromValue(caf::PdmPointer(obj)); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -PdmOptionItemInfo PdmOptionItemInfo::createHeader(const QString& anOptionUiText, bool isReadOnly /*= false*/, QIcon anIcon /*= QIcon()*/) +PdmOptionItemInfo + PdmOptionItemInfo::createHeader(const QString& anOptionUiText, bool isReadOnly /*= false*/, QIcon anIcon /*= QIcon()*/) { PdmOptionItemInfo header(anOptionUiText, QVariant(), isReadOnly, anIcon); @@ -79,7 +83,7 @@ PdmOptionItemInfo PdmOptionItemInfo::createHeader(const QString& anOptionUiText, } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void PdmOptionItemInfo::setLevel(int level) { @@ -87,7 +91,7 @@ void PdmOptionItemInfo::setLevel(int level) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const QString PdmOptionItemInfo::optionUiText() const { @@ -95,7 +99,7 @@ const QString PdmOptionItemInfo::optionUiText() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const QVariant PdmOptionItemInfo::value() const { @@ -103,7 +107,7 @@ const QVariant PdmOptionItemInfo::value() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool PdmOptionItemInfo::isReadOnly() const { @@ -111,7 +115,7 @@ bool PdmOptionItemInfo::isReadOnly() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool PdmOptionItemInfo::isHeading() const { @@ -119,7 +123,7 @@ bool PdmOptionItemInfo::isHeading() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const QIcon PdmOptionItemInfo::icon() const { @@ -127,7 +131,7 @@ const QIcon PdmOptionItemInfo::icon() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- int PdmOptionItemInfo::level() const { @@ -135,13 +139,13 @@ int PdmOptionItemInfo::level() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- QStringList PdmOptionItemInfo::extractUiTexts(const QList& optionList) { QStringList texts; - - for (auto option : optionList) + + for (const auto& option : optionList) { texts.push_back(option.optionUiText()); } @@ -149,7 +153,6 @@ QStringList PdmOptionItemInfo::extractUiTexts(const QList& op return texts; } - //================================================================================================== /// PdmUiItem //================================================================================================== @@ -157,9 +160,9 @@ QStringList PdmOptionItemInfo::extractUiTexts(const QList& op bool PdmUiItem::sm_showExtraDebugText = false; //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const QString PdmUiItem::uiName(QString uiConfigName) const +const QString PdmUiItem::uiName(const QString& uiConfigName) const { const PdmUiItemInfo* conInfo = configInfo(uiConfigName); const PdmUiItemInfo* defInfo = defaultInfo(); @@ -169,13 +172,21 @@ const QString PdmUiItem::uiName(QString uiConfigName) const if (defInfo && !(defInfo->m_uiName.isNull())) return defInfo->m_uiName; if (sttInfo && !(sttInfo->m_uiName.isNull())) return sttInfo->m_uiName; - return QString(""); + return QString(""); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const QIcon PdmUiItem::uiIcon(QString uiConfigName) const +void PdmUiItem::setUiName(const QString& uiName, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_uiName = uiName; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QIcon PdmUiItem::uiIcon(const QString& uiConfigName) const { const PdmUiItemInfo* conInfo = configInfo(uiConfigName); const PdmUiItemInfo* defInfo = defaultInfo(); @@ -185,13 +196,45 @@ const QIcon PdmUiItem::uiIcon(QString uiConfigName) const if (defInfo && !(defInfo->m_icon.isNull())) return defInfo->m_icon; if (sttInfo && !(sttInfo->m_icon.isNull())) return sttInfo->m_icon; - return QIcon(); + return QIcon(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::setUiIcon(const QIcon& uiIcon, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_icon = uiIcon; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const QColor PdmUiItem::uiContentTextColor(const QString& uiConfigName) const +{ + const PdmUiItemInfo* conInfo = configInfo(uiConfigName); + const PdmUiItemInfo* defInfo = defaultInfo(); + const PdmUiItemInfo* sttInfo = m_staticItemInfo; + + if (conInfo && (conInfo->m_contentTextColor.isValid())) return conInfo->m_contentTextColor; + if (defInfo && (defInfo->m_contentTextColor.isValid())) return defInfo->m_contentTextColor; + if (sttInfo && (sttInfo->m_contentTextColor.isValid())) return sttInfo->m_contentTextColor; + + return QColor(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::setUiContentTextColor(const QColor& color, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_contentTextColor = color; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const QString PdmUiItem::uiToolTip(QString uiConfigName) const +const QString PdmUiItem::uiToolTip(const QString& uiConfigName) const { const PdmUiItemInfo* conInfo = configInfo(uiConfigName); const PdmUiItemInfo* defInfo = defaultInfo(); @@ -226,13 +269,21 @@ const QString PdmUiItem::uiToolTip(QString uiConfigName) const } } - return text; + return text; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::setUiToolTip(const QString& uiToolTip, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_toolTip = uiToolTip; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -const QString PdmUiItem::uiWhatsThis(QString uiConfigName) const +const QString PdmUiItem::uiWhatsThis(const QString& uiConfigName) const { const PdmUiItemInfo* conInfo = configInfo(uiConfigName); const PdmUiItemInfo* defInfo = defaultInfo(); @@ -242,13 +293,21 @@ const QString PdmUiItem::uiWhatsThis(QString uiConfigName) const if (defInfo && !(defInfo->m_whatsThis.isNull())) return defInfo->m_whatsThis; if (sttInfo && !(sttInfo->m_whatsThis.isNull())) return sttInfo->m_whatsThis; - return QString(""); + return QString(""); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -bool PdmUiItem::isUiHidden(QString uiConfigName) const +void PdmUiItem::setUiWhatsThis(const QString& uiWhatsThis, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_whatsThis = uiWhatsThis; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiItem::isUiHidden(const QString& uiConfigName) const { const PdmUiItemInfo* conInfo = configInfo(uiConfigName); const PdmUiItemInfo* defInfo = defaultInfo(); @@ -262,9 +321,17 @@ bool PdmUiItem::isUiHidden(QString uiConfigName) const } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::setUiHidden(bool isHidden, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_isHidden = isHidden; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- -bool PdmUiItem::isUiTreeHidden(QString uiConfigName) const +bool PdmUiItem::isUiTreeHidden(const QString& uiConfigName) const { // TODO: Must be separated from uiHidden when childField object embedding is implemented @@ -272,9 +339,17 @@ bool PdmUiItem::isUiTreeHidden(QString uiConfigName) const } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::setUiTreeHidden(bool isHidden, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_isHidden = isHidden; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- -bool PdmUiItem::isUiTreeChildrenHidden(QString uiConfigName) const +bool PdmUiItem::isUiTreeChildrenHidden(const QString& uiConfigName) const { const PdmUiItemInfo* conInfo = configInfo(uiConfigName); const PdmUiItemInfo* defInfo = defaultInfo(); @@ -288,9 +363,17 @@ bool PdmUiItem::isUiTreeChildrenHidden(QString uiConfigName) const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -bool PdmUiItem::isUiReadOnly(QString uiConfigName /*= ""*/) const +void PdmUiItem::setUiTreeChildrenHidden(bool isTreeChildrenHidden, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_isTreeChildrenHidden = isTreeChildrenHidden; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiItem::isUiReadOnly(const QString& uiConfigName /*= ""*/) const { const PdmUiItemInfo* conInfo = configInfo(uiConfigName); const PdmUiItemInfo* defInfo = defaultInfo(); @@ -304,7 +387,15 @@ bool PdmUiItem::isUiReadOnly(QString uiConfigName /*= ""*/) const } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::setUiReadOnly(bool isReadOnly, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_isReadOnly = isReadOnly; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- QString PdmUiItem::uiEditorTypeName(const QString& uiConfigName) const { @@ -320,9 +411,25 @@ QString PdmUiItem::uiEditorTypeName(const QString& uiConfigName) const } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::setUiEditorTypeName(const QString& editorTypeName, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_editorTypeName = editorTypeName; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- -PdmUiItemInfo::LabelPosType PdmUiItem::uiLabelPosition(QString uiConfigName) const +bool PdmUiItem::isUiGroup() const +{ + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiItemInfo::LabelPosType PdmUiItem::uiLabelPosition(const QString& uiConfigName) const { const PdmUiItemInfo* conInfo = configInfo(uiConfigName); const PdmUiItemInfo* defInfo = defaultInfo(); @@ -336,10 +443,42 @@ PdmUiItemInfo::LabelPosType PdmUiItem::uiLabelPosition(QString uiConfigName) con } //-------------------------------------------------------------------------------------------------- -/// +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::setUiLabelPosition(PdmUiItemInfo::LabelPosType alignment, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_labelAlignment = alignment; +} + +//-------------------------------------------------------------------------------------------------- +/// //-------------------------------------------------------------------------------------------------- +bool PdmUiItem::isCustomContextMenuEnabled(const QString& uiConfigName /*= ""*/) const +{ + const PdmUiItemInfo* conInfo = configInfo(uiConfigName); + const PdmUiItemInfo* defInfo = defaultInfo(); + const PdmUiItemInfo* sttInfo = m_staticItemInfo; -const PdmUiItemInfo* PdmUiItem::configInfo(QString uiConfigName) const + if (conInfo && (conInfo->m_isCustomContextMenuEnabled != -1)) return conInfo->m_isCustomContextMenuEnabled; + if (defInfo && (defInfo->m_isCustomContextMenuEnabled != -1)) return defInfo->m_isCustomContextMenuEnabled; + if (sttInfo && (sttInfo->m_isCustomContextMenuEnabled != -1)) return sttInfo->m_isCustomContextMenuEnabled; + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::setCustomContextMenuEnabled(bool enableCustomContextMenu, const QString& uiConfigName /*= ""*/) +{ + m_configItemInfos[uiConfigName].m_isCustomContextMenuEnabled = enableCustomContextMenu; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- + +const PdmUiItemInfo* PdmUiItem::configInfo(const QString& uiConfigName) const { if (uiConfigName == "" || uiConfigName.isNull()) return nullptr; @@ -352,7 +491,7 @@ const PdmUiItemInfo* PdmUiItem::configInfo(QString uiConfigName) const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- const PdmUiItemInfo* PdmUiItem::defaultInfo() const @@ -366,9 +505,9 @@ const PdmUiItemInfo* PdmUiItem::defaultInfo() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void PdmUiItem::updateConnectedEditors() +void PdmUiItem::updateConnectedEditors() const { std::set::iterator it; for (it = m_editors.begin(); it != m_editors.end(); ++it) @@ -378,9 +517,9 @@ void PdmUiItem::updateConnectedEditors() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void PdmUiItem::updateAllRequiredEditors() +void PdmUiItem::updateAllRequiredEditors() const { updateConnectedEditors(); @@ -388,7 +527,7 @@ void PdmUiItem::updateAllRequiredEditors() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- PdmUiItem::~PdmUiItem() { @@ -400,20 +539,34 @@ PdmUiItem::~PdmUiItem() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void PdmUiItem::updateUiIconFromState(bool isActive, QString uiConfigName) +PdmUiItem::PdmUiItem() + : m_staticItemInfo(nullptr) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::updateUiIconFromState(bool isActive, const QString& uiConfigName) { static const QString iconStorageConfigNamePostfix = "_Internally_StoredNormalIcon"; - const PdmUiItemInfo* conInfo = configInfo(uiConfigName + iconStorageConfigNamePostfix); - QIcon normalIcon; + const PdmUiItemInfo* conInfo = configInfo(uiConfigName + iconStorageConfigNamePostfix); + QIcon normalIcon; - if (conInfo) normalIcon = conInfo->m_icon; - else normalIcon = this->uiIcon(uiConfigName); + if (conInfo) + { + normalIcon = conInfo->m_icon; + } + else + { + normalIcon = this->uiIcon(uiConfigName); + } this->setUiIcon(normalIcon, uiConfigName + iconStorageConfigNamePostfix); - if ( isActive ) + if (isActive) { this->setUiIcon(normalIcon, uiConfigName); m_configItemInfos.erase(uiConfigName + iconStorageConfigNamePostfix); @@ -427,7 +580,7 @@ void PdmUiItem::updateUiIconFromState(bool isActive, QString uiConfigName) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- std::vector PdmUiItem::connectedEditors() const { @@ -441,7 +594,7 @@ std::vector PdmUiItem::connectedEditors() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- bool PdmUiItem::showExtraDebugText() { @@ -449,12 +602,35 @@ bool PdmUiItem::showExtraDebugText() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void PdmUiItem::enableExtraDebugText(bool enable) { sm_showExtraDebugText = enable; } -} //End of namespace caf +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::setUiItemInfo(PdmUiItemInfo* itemInfo) +{ + m_staticItemInfo = itemInfo; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::removeFieldEditor(PdmUiEditorHandle* fieldView) +{ + m_editors.erase(fieldView); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiItem::addFieldEditor(PdmUiEditorHandle* fieldView) +{ + m_editors.insert(fieldView); +} +} // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.h index 5df67078ac..9b67ecfd25 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiItem.h @@ -56,12 +56,12 @@ class PdmUiItemInfo { public: PdmUiItemInfo() - : m_editorTypeName(""), m_isHidden(-1), m_isTreeChildrenHidden(-1), m_isReadOnly(-1), m_labelAlignment(LEFT) + : m_editorTypeName(""), m_isHidden(-1), m_isTreeChildrenHidden(-1), m_isReadOnly(-1), m_labelAlignment(LEFT), m_isCustomContextMenuEnabled(-1) {} PdmUiItemInfo(const QString& uiName, QIcon icon = QIcon(), QString toolTip = "", QString whatsThis = "", QString extraDebugText = "") : m_uiName(uiName), m_icon(icon), m_toolTip(toolTip), m_whatsThis(whatsThis), m_extraDebugText(extraDebugText), - m_editorTypeName(""), m_isHidden(false), m_isTreeChildrenHidden(false), m_isReadOnly(false), m_labelAlignment(LEFT) + m_editorTypeName(""), m_isHidden(false), m_isTreeChildrenHidden(false), m_isReadOnly(false), m_labelAlignment(LEFT), m_isCustomContextMenuEnabled(false) { } enum LabelPosType { LEFT, TOP, HIDDEN }; @@ -69,7 +69,8 @@ class PdmUiItemInfo private: friend class PdmUiItem; QString m_uiName; - QIcon m_icon; + QIcon m_icon; + QColor m_contentTextColor; ///< Color of a fields value text. Invalid by default. An Invalid color is not used. QString m_toolTip; QString m_whatsThis; QString m_extraDebugText; @@ -78,6 +79,7 @@ class PdmUiItemInfo int m_isTreeChildrenHidden; ///< Children of UiItem should be hidden. -1 means not set int m_isReadOnly; ///< UiItem should be insensitive, or read only. -1 means not set. LabelPosType m_labelAlignment; + int m_isCustomContextMenuEnabled; }; //================================================================================================== @@ -191,52 +193,58 @@ bool PdmOptionItemInfo::findValues(const QList& optionList, Q class PdmUiItem { public: - PdmUiItem() : m_staticItemInfo(nullptr) { } + PdmUiItem(); virtual ~PdmUiItem(); PdmUiItem(const PdmUiItem&) = delete; PdmUiItem& operator=(const PdmUiItem&) = delete; - const QString uiName(QString uiConfigName = "") const; - void setUiName(const QString& uiName, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_uiName = uiName; } + const QString uiName(const QString& uiConfigName = "") const; + void setUiName(const QString& uiName, const QString& uiConfigName = ""); - const QIcon uiIcon(QString uiConfigName = "") const; - void setUiIcon(const QIcon& uiIcon, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_icon = uiIcon; } + const QIcon uiIcon(const QString& uiConfigName = "") const; + void setUiIcon(const QIcon& uiIcon, const QString& uiConfigName = ""); - const QString uiToolTip(QString uiConfigName = "") const; - void setUiToolTip(const QString& uiToolTip, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_toolTip = uiToolTip; } + const QColor uiContentTextColor(const QString& uiConfigName = "") const; + void setUiContentTextColor(const QColor& uiIcon, const QString& uiConfigName = ""); - const QString uiWhatsThis(QString uiConfigName = "") const; - void setUiWhatsThis(const QString& uiWhatsThis, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_whatsThis = uiWhatsThis; } + const QString uiToolTip(const QString& uiConfigName = "") const; + void setUiToolTip(const QString& uiToolTip, const QString& uiConfigName = ""); - bool isUiHidden(QString uiConfigName = "") const; - void setUiHidden(bool isHidden, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_isHidden = isHidden; } + const QString uiWhatsThis(const QString& uiConfigName = "") const; + void setUiWhatsThis(const QString& uiWhatsThis, const QString& uiConfigName = ""); - bool isUiTreeHidden(QString uiConfigName = "") const; - void setUiTreeHidden(bool isHidden, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_isHidden = isHidden; } + bool isUiHidden(const QString& uiConfigName = "") const; + void setUiHidden(bool isHidden, const QString& uiConfigName = ""); - bool isUiTreeChildrenHidden(QString uiConfigName = "") const; - void setUiTreeChildrenHidden(bool isTreeChildrenHidden, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_isTreeChildrenHidden = isTreeChildrenHidden; } + bool isUiTreeHidden(const QString& uiConfigName = "") const; + void setUiTreeHidden(bool isHidden, const QString& uiConfigName = ""); - bool isUiReadOnly(QString uiConfigName = "") const; - void setUiReadOnly(bool isReadOnly, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_isReadOnly = isReadOnly; } + bool isUiTreeChildrenHidden(const QString& uiConfigName = "") const; + void setUiTreeChildrenHidden(bool isTreeChildrenHidden, const QString& uiConfigName = ""); + + bool isUiReadOnly(const QString& uiConfigName = "") const; + void setUiReadOnly(bool isReadOnly, const QString& uiConfigName = ""); PdmUiItemInfo::LabelPosType - uiLabelPosition(QString uiConfigName = "") const; - void setUiLabelPosition(PdmUiItemInfo::LabelPosType alignment, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_labelAlignment = alignment; } + uiLabelPosition(const QString& uiConfigName = "") const; + void setUiLabelPosition(PdmUiItemInfo::LabelPosType alignment, const QString& uiConfigName = ""); + + bool isCustomContextMenuEnabled(const QString& uiConfigName = "") const; + void setCustomContextMenuEnabled(bool enableCustomContextMenu, const QString& uiConfigName = ""); QString uiEditorTypeName(const QString& uiConfigName) const; - void setUiEditorTypeName(const QString& editorTypeName, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_editorTypeName = editorTypeName; } + void setUiEditorTypeName(const QString& editorTypeName, const QString& uiConfigName = ""); - virtual bool isUiGroup() { return false; } + virtual bool isUiGroup() const; /// Intended to be called when fields in an object has been changed - void updateConnectedEditors(); + void updateConnectedEditors() const; /// Intended to be called when an object has been created or deleted - void updateAllRequiredEditors(); + void updateAllRequiredEditors() const; - void updateUiIconFromState(bool isActive, QString uiConfigName = ""); + void updateUiIconFromState(bool isActive, const QString& uiConfigName = ""); std::vector connectedEditors() const; @@ -251,17 +259,17 @@ class PdmUiItem /// Consider as PRIVATE to the PdmSystem //================================================================================================== - void setUiItemInfo(PdmUiItemInfo* itemInfo) { m_staticItemInfo = itemInfo; } + void setUiItemInfo(PdmUiItemInfo* itemInfo); - void removeFieldEditor(PdmUiEditorHandle* fieldView) { m_editors.erase(fieldView); } - void addFieldEditor(PdmUiEditorHandle* fieldView) { m_editors.insert(fieldView); } + void removeFieldEditor(PdmUiEditorHandle* fieldView); + void addFieldEditor(PdmUiEditorHandle* fieldView); protected: std::set m_editors; private: const PdmUiItemInfo* defaultInfo() const; - const PdmUiItemInfo* configInfo(QString uiConfigName) const; + const PdmUiItemInfo* configInfo(const QString& uiConfigName) const; PdmUiItemInfo* m_staticItemInfo; std::map< QString, PdmUiItemInfo > m_configItemInfos; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectEditorHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectEditorHandle.h index d09acd52de..e6a481219f 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectEditorHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectEditorHandle.h @@ -59,7 +59,7 @@ class PdmUiObjectEditorHandle : public PdmUiEditorHandle { public: PdmUiObjectEditorHandle(); - virtual ~PdmUiObjectEditorHandle(); + ~PdmUiObjectEditorHandle() override; QWidget* getOrCreateWidget(QWidget* parent); QWidget* widget() const; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.cpp index 38fea693ff..a8a8173e6c 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.cpp @@ -23,7 +23,7 @@ PdmUiObjectHandle::PdmUiObjectHandle(PdmObjectHandle* owner, bool giveOwnership) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiObjectHandle* uiObj(PdmObjectHandle* obj) +PdmUiObjectHandle* uiObj(const PdmObjectHandle* obj) { if (!obj) return nullptr; PdmUiObjectHandle* uiObject = obj->capability(); @@ -35,7 +35,7 @@ PdmUiObjectHandle* uiObj(PdmObjectHandle* obj) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiObjectHandle::uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) +void PdmUiObjectHandle::uiOrdering(const QString& uiConfigName, PdmUiOrdering& uiOrdering) { // Restore state for includeRemainingFields, as this flag // can be changed in defineUiOrdering() @@ -66,7 +66,7 @@ void PdmUiObjectHandle::uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrderi //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiObjectHandle::editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute) +void PdmUiObjectHandle::editorAttribute(const PdmFieldHandle* field, const QString& uiConfigName, PdmUiEditorAttribute * attribute) { this->defineEditorAttribute(field, uiConfigName, attribute); } @@ -74,7 +74,7 @@ void PdmUiObjectHandle::editorAttribute(const PdmFieldHandle* field, QString uiC //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiObjectHandle::objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute) +void PdmUiObjectHandle::objectEditorAttribute(const QString& uiConfigName, PdmUiEditorAttribute* attribute) { this->defineObjectEditorAttribute(uiConfigName, attribute); } @@ -88,7 +88,7 @@ void PdmUiObjectHandle::objectEditorAttribute(QString uiConfigName, PdmUiEditorA /// /// The caller is responsible to delete the returned PdmUiTreeOrdering //-------------------------------------------------------------------------------------------------- -PdmUiTreeOrdering* PdmUiObjectHandle::uiTreeOrdering(QString uiConfigName /*= ""*/) +PdmUiTreeOrdering* PdmUiObjectHandle::uiTreeOrdering(const QString& uiConfigName /*= ""*/) const { CAF_ASSERT(this); // This method actually is possible to call on a NULL ptr without getting a crash, so we assert instead. @@ -168,7 +168,7 @@ void PdmUiObjectHandle::addDefaultUiTreeChildren(PdmUiTreeOrdering* uiTreeOrderi /// Builds the sPdmUiTree for all the children of @param root recursively, and stores the result /// in root //-------------------------------------------------------------------------------------------------- -void PdmUiObjectHandle::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */) +void PdmUiObjectHandle::expandUiTree(PdmUiTreeOrdering* root, const QString& uiConfigName /*= "" */) { #if 1 if (!root || !root->isValid()) return; @@ -180,7 +180,7 @@ void PdmUiObjectHandle::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigNa PdmUiTreeOrdering* child = root->child(cIdx); if (child->isValid() && !child->ignoreSubTree()) { - expandUiTree(child); + expandUiTree(child, uiConfigName); } } } @@ -207,7 +207,7 @@ void PdmUiObjectHandle::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigNa uiObj(root->object())->addDefaultUiTreeChildren(root); if (root->childCount()) { - expandUiTree(root); + expandUiTree(root, uiConfigName); } } } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h index 7bfe542b3a..7818894f66 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiObjectHandle.h @@ -3,6 +3,7 @@ #include "cafPdmUiItem.h" #include "cafPdmObjectCapability.h" +class QMenu; namespace caf { @@ -14,31 +15,32 @@ class PdmUiOrdering; class PdmFieldHandle; class PdmUiEditorAttribute; + class PdmUiObjectHandle : public PdmUiItem, public PdmObjectCapability { public: PdmUiObjectHandle(PdmObjectHandle* owner, bool giveOwnership); - virtual ~PdmUiObjectHandle() { } + ~PdmUiObjectHandle() override { } PdmObjectHandle* objectHandle() { return m_owner; } const PdmObjectHandle* objectHandle() const { return m_owner; } /// Method to be called from the Ui classes creating Auto Gui to get the group information /// supplied by the \sa defineUiOrdering method that can be reimplemented - void uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) ; + void uiOrdering(const QString& uiConfigName, PdmUiOrdering& uiOrdering); /// Method to be called by Ui displaying a tree representation of the object hierarchy /// Caller must delete the returned object. - PdmUiTreeOrdering* uiTreeOrdering(QString uiConfigName = ""); + PdmUiTreeOrdering* uiTreeOrdering(const QString& uiConfigName = "") const; /// Helper function to expand a pre-defined tree start - static void expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName = ""); + static void expandUiTree(PdmUiTreeOrdering* root, const QString& uiConfigName = ""); /// For a specific field, return editor specific parameters used to customize the editor behavior. - void editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute* attribute); + void editorAttribute(const PdmFieldHandle* field, const QString& uiConfigName, PdmUiEditorAttribute* attribute); /// Return object editor specific parameters used to customize the editor behavior. - void objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute); + void objectEditorAttribute(const QString& uiConfigName, PdmUiEditorAttribute* attribute); /// Field used to control if field change of and object should be covered by undo/redo framework virtual bool useUndoRedoForFieldChanged() { return true; } @@ -64,6 +66,7 @@ class PdmUiObjectHandle : public PdmUiItem, public PdmObjectCapability /// All field editor widgets are supposed to be created when this function is called virtual void onEditorWidgetsCreated() {} + protected: /// Override to customize the order and grouping of the Gui. /// Fill up the uiOrdering object with groups and field references to create the gui structure @@ -84,6 +87,15 @@ class PdmUiObjectHandle : public PdmUiItem, public PdmObjectCapability // if user uses them on wrong type of objects bool isInheritedFromPdmUiObject() { return true; } + /// Override used to append actions to a context menu + /// To use this method, enable custom context menu by + /// m_myField.uiCapability()->setUseCustomContextMenu(true); + friend class PdmUiFieldEditorHandle; + virtual void defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, + QMenu* menu, + QWidget* fieldEditorWidget) + {} + private: /// Helper method for the TreeItem generation stuff void addDefaultUiTreeChildren(PdmUiTreeOrdering* uiTreeOrdering); @@ -92,7 +104,7 @@ class PdmUiObjectHandle : public PdmUiItem, public PdmObjectCapability }; -PdmUiObjectHandle* uiObj(PdmObjectHandle* obj); +PdmUiObjectHandle* uiObj(const PdmObjectHandle* obj); } // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.cpp index 6483f6f068..2a0490b87c 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.cpp @@ -53,20 +53,20 @@ PdmUiOrdering::~PdmUiOrdering() for (size_t i = 0; i < m_createdGroups.size(); ++i) { delete m_createdGroups[i]; - m_createdGroups[i] = NULL; + m_createdGroups[i] = nullptr; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiGroup* PdmUiOrdering::addNewGroup(const QString& displayName) +PdmUiGroup* PdmUiOrdering::addNewGroup(const QString& displayName, LayoutOptions layout) { PdmUiGroup* group = new PdmUiGroup; group->setUiName(displayName); m_createdGroups.push_back(group); - m_ordering.push_back(group); + m_ordering.push_back(std::make_pair(group, layout)); return group; } @@ -74,55 +74,202 @@ PdmUiGroup* PdmUiOrdering::addNewGroup(const QString& displayName) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmUiGroup* PdmUiOrdering::addNewGroupWithKeyword(const QString& displayName, const QString& keyword) +caf::PdmUiGroup* PdmUiOrdering::addNewGroupWithKeyword(const QString& displayName, const QString& keyword, LayoutOptions layout) { - PdmUiGroup* group = addNewGroup(displayName); + PdmUiGroup* group = addNewGroup(displayName, layout); group->setKeyword(keyword); return group; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiOrdering::insertBeforeGroup(const QString& groupId, const PdmFieldHandle* field, LayoutOptions layout) +{ + PositionFound pos = findGroupPosition(groupId); + if (pos.parent) + { + pos.parent->insert(pos.indexInParent, field, layout); + return true; + } + else + { + return false; + } +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiOrdering::insertBeforeItem(const PdmUiItem* item, const PdmFieldHandle* field, LayoutOptions layout) +{ + PositionFound pos = findItemPosition(item); + if (pos.parent) + { + pos.parent->insert(pos.indexInParent, field, layout); + return true; + } + else + { + return false; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmUiGroup* PdmUiOrdering::createGroupBeforeGroup(const QString& groupId, const QString& displayName, LayoutOptions layout) +{ + return createGroupWithIdBeforeGroup(groupId, displayName, "", layout); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmUiGroup* PdmUiOrdering::createGroupBeforeItem(const PdmUiItem* item, const QString& displayName, LayoutOptions layout) +{ + return createGroupWithIdBeforeItem(item, displayName, "", layout); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmUiGroup* PdmUiOrdering::createGroupWithIdBeforeGroup(const QString& groupId, const QString& displayName, const QString& newGroupId, LayoutOptions layout) +{ + PositionFound pos = findGroupPosition(groupId); + if (pos.parent) + { + return pos.parent->insertNewGroupWithKeyword(pos.indexInParent, displayName, newGroupId, layout); + } + + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmUiGroup* PdmUiOrdering::createGroupWithIdBeforeItem(const PdmUiItem* item, const QString& displayName, const QString& newGroupId, LayoutOptions layout) +{ + PositionFound pos = findItemPosition(item); + if (pos.parent) + { + return pos.parent->insertNewGroupWithKeyword(pos.indexInParent, displayName, newGroupId, layout); + } + + return nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmUiGroup* PdmUiOrdering::findGroup(const QString& groupId) const +{ + return findGroupPosition(groupId).group(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmUiGroup* PdmUiOrdering::insertNewGroupWithKeyword(size_t index, + const QString& displayName, + const QString& groupKeyword, + LayoutOptions layout) +{ + PdmUiGroup* group = new PdmUiGroup; + group->setUiName(displayName); + + m_createdGroups.push_back(group); + + m_ordering.insert(m_ordering.begin() + index, std::make_pair(group, layout)); + + group->setKeyword(groupKeyword); + + return group; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool PdmUiOrdering::contains(const PdmUiItem* item) const +{ + return this->findItemPosition(item).parent != nullptr; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmUiOrdering::PositionFound PdmUiOrdering::findItemPosition(const PdmUiItem* item) const { for (size_t i = 0; i < m_ordering.size(); ++i) { - if (m_ordering[i] == item) return true; - if (m_ordering[i] && m_ordering[i]->isUiGroup()) + if (m_ordering[i].first == item) return { const_cast(this), i}; + if (m_ordering[i].first && m_ordering[i].first->isUiGroup()) { - if (static_cast(m_ordering[i])->contains(item)) return true; + PositionFound result = static_cast(m_ordering[i].first)->findItemPosition(item); + if (result.parent ) return result; } } - return false; + return {nullptr, size_t(-1)}; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiOrdering::add(const PdmFieldHandle* field) +caf::PdmUiOrdering::PositionFound PdmUiOrdering::findGroupPosition(const QString& groupKeyword) const +{ + for (size_t i = 0; i < m_ordering.size(); ++i) + { + if (m_ordering[i].first && m_ordering[i].first->isUiGroup()) + { + if (static_cast(m_ordering[i].first)->keyword() == groupKeyword) return { const_cast(this), i}; + PositionFound result = static_cast(m_ordering[i].first)->findGroupPosition(groupKeyword); + if (result.parent ) return result; + } + } + return {nullptr, size_t(-1)}; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiOrdering::add(const PdmFieldHandle* field, LayoutOptions layout) { PdmUiFieldHandle* uiItem = const_cast(field)->uiCapability(); CAF_ASSERT(uiItem); CAF_ASSERT(!this->contains(uiItem)); - m_ordering.push_back(uiItem); + m_ordering.push_back(std::make_pair(uiItem, layout)); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiOrdering::add(const PdmObjectHandle* obj) +void PdmUiOrdering::add(const PdmObjectHandle* obj, LayoutOptions layout) { PdmUiObjectHandle* uiItem = uiObj(const_cast(obj)); CAF_ASSERT(uiItem); CAF_ASSERT(!this->contains(uiItem)); + m_ordering.push_back(std::make_pair(uiItem, layout)); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiOrdering::insert(size_t index, const PdmFieldHandle* field, LayoutOptions layout) +{ + PdmUiFieldHandle* uiItem = const_cast(field)->uiCapability(); + CAF_ASSERT(uiItem); + CAF_ASSERT(!this->contains(uiItem)); - m_ordering.push_back(uiItem); + m_ordering.insert(m_ordering.begin() + index, std::make_pair(uiItem, layout)); } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -142,10 +289,89 @@ void PdmUiOrdering::skipRemainingFields(bool doSkip /*= true*/) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const std::vector& PdmUiOrdering::uiItems() const +const std::vector PdmUiOrdering::uiItems() const +{ + std::vector justUiItems; + justUiItems.reserve(m_ordering.size()); + for (const FieldAndLayout& itemAndLayout : m_ordering) + { + justUiItems.push_back(itemAndLayout.first); + } + return justUiItems; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +const std::vector& PdmUiOrdering::uiItemsWithLayout() const { return m_ordering; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int PdmUiOrdering::nrOfColumns() const +{ + int maxColumns = 0; + int currentRowColumns = 0; + for (const FieldAndLayout& itemAndLayout : m_ordering) + { + int currentColumnSpan = itemAndLayout.second.totalColumnSpan; + if (currentColumnSpan == LayoutOptions::MAX_COLUMN_SPAN) + { + int minimumFieldColumnSpan = 1; + int minimumLabelColumnSpan = 0; + if (itemAndLayout.first->uiLabelPosition() == PdmUiItemInfo::LEFT) + { + minimumLabelColumnSpan = 1; + } + currentColumnSpan = minimumLabelColumnSpan + minimumFieldColumnSpan; + } + + if (itemAndLayout.second.newRow) + { + currentRowColumns = currentColumnSpan; + } + else + { + currentRowColumns += currentColumnSpan; + } + maxColumns = std::max(maxColumns, currentRowColumns); + } + return maxColumns; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmUiItem* PdmUiOrdering::PositionFound::item() +{ + if ( parent ) + { + return parent->uiItems()[indexInParent]; + } + else + { + return nullptr; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmUiGroup* PdmUiOrdering::PositionFound::group() +{ + PdmUiItem* g = item(); + if ( g && g->isUiGroup() ) + { + return static_cast(g); + } + else + { + return nullptr; + } +} + } //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.h index 3e737bf553..9dce113c9a 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiOrdering.h @@ -55,28 +55,68 @@ class PdmObjectHandle; class PdmUiOrdering { public: + struct LayoutOptions + { + static const int MAX_COLUMN_SPAN = -1; + LayoutOptions(bool newRow = true, int totalColumnSpan = MAX_COLUMN_SPAN, int leftLabelColumnSpan = MAX_COLUMN_SPAN) + : newRow(newRow), totalColumnSpan(totalColumnSpan), leftLabelColumnSpan(leftLabelColumnSpan) + {} + + bool newRow; + int totalColumnSpan; + int leftLabelColumnSpan; + }; + typedef std::pair FieldAndLayout; + PdmUiOrdering(): m_skipRemainingFields(false) { }; virtual ~PdmUiOrdering(); PdmUiOrdering(const PdmUiOrdering&) = delete; PdmUiOrdering& operator=(const PdmUiOrdering&) = delete; - PdmUiGroup* addNewGroup(const QString& displayName); - PdmUiGroup* addNewGroupWithKeyword(const QString& displayName, const QString& keyword); + void add(const PdmFieldHandle* field, LayoutOptions layout = LayoutOptions()); + void add(const PdmObjectHandle* obj, LayoutOptions layout = LayoutOptions()); + bool insertBeforeGroup(const QString& groupId, const PdmFieldHandle* fieldToInsert, LayoutOptions layout = LayoutOptions()); + bool insertBeforeItem(const PdmUiItem* item, const PdmFieldHandle* fieldToInsert, LayoutOptions layout = LayoutOptions()); + + PdmUiGroup* addNewGroup(const QString& displayName, LayoutOptions layout = LayoutOptions()); + PdmUiGroup* createGroupBeforeGroup(const QString& groupId, const QString& displayName, LayoutOptions layout = LayoutOptions()); + PdmUiGroup* createGroupBeforeItem(const PdmUiItem* item, const QString& displayName, LayoutOptions layout = LayoutOptions()); - void add(const PdmFieldHandle* field); - void add(const PdmObjectHandle* obj); + PdmUiGroup* addNewGroupWithKeyword(const QString& displayName, const QString& groupKeyword, LayoutOptions layout = LayoutOptions()); + PdmUiGroup* createGroupWithIdBeforeGroup(const QString& groupId, const QString& displayName, const QString& newGroupId, LayoutOptions layout = LayoutOptions()); + PdmUiGroup* createGroupWithIdBeforeItem(const PdmUiItem* item, const QString& displayName, const QString& newGroupId, LayoutOptions layout = LayoutOptions()); + + PdmUiGroup* findGroup(const QString& groupId) const; void skipRemainingFields(bool doSkip = true); // Pdm internal methods - const std::vector& uiItems() const; - bool contains(const PdmUiItem* item) const; - bool isIncludingRemainingFields() const; + const std::vector uiItems() const; + const std::vector& uiItemsWithLayout() const; + int nrOfColumns() const; + bool contains(const PdmUiItem* item) const; + bool isIncludingRemainingFields() const; + +protected: + + struct PositionFound + { + PdmUiOrdering* parent; + size_t indexInParent; + PdmUiItem* item(); + PdmUiGroup* group(); + }; + + PositionFound findGroupPosition(const QString& groupKeyword) const; + PositionFound findItemPosition(const PdmUiItem* item) const; private: - std::vector m_ordering; ///< The order of groups and fields + void insert(size_t index, const PdmFieldHandle* field, LayoutOptions layout = LayoutOptions()); + PdmUiGroup* insertNewGroupWithKeyword(size_t index, const QString& displayName, const QString& groupKeyword, LayoutOptions layout = LayoutOptions()); + + std::vector m_ordering; ///< The order of groups and fields std::vector m_createdGroups; ///< Owned PdmUiGroups, for memory management only bool m_skipRemainingFields; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiTreeOrdering.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiTreeOrdering.h index 6528a97af4..2bd94cf717 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiTreeOrdering.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafPdmUiTreeOrdering.h @@ -110,7 +110,7 @@ class PdmUiTreeOrdering bool containsObject(const PdmObjectHandle* object); void appendChild( PdmUiTreeOrdering* child); - friend class PdmUiTreeViewModel; + friend class PdmUiTreeViewQModel; PdmUiEditorHandle* editor(); void setEditor(PdmUiEditorHandle* editor); void insertChild( int position, PdmUiTreeOrdering* child); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.cpp new file mode 100644 index 0000000000..fa65b0effa --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.cpp @@ -0,0 +1,59 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafSelectionChangedReceiver.h" +#include "cafSelectionManager.h" + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::SelectionChangedReceiver::SelectionChangedReceiver() +{ + SelectionManager::instance()->registerSelectionChangedReceiver(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::SelectionChangedReceiver::~SelectionChangedReceiver() +{ + SelectionManager::instance()->unregisterSelectionChangedReceiver(this); +} + +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.h new file mode 100644 index 0000000000..296c14a67e --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.h @@ -0,0 +1,54 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#pragma once + +#include + +namespace caf +{ +class SelectionChangedReceiver +{ +public: + SelectionChangedReceiver(); + virtual ~SelectionChangedReceiver(); + +protected: + friend class SelectionManager; + /// Called whenever caf::SelectionManager's selection changes + virtual void onSelectionManagerSelectionChanged( const std::set& changedSelectionLevels ) = 0; +}; + +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp index 42c8195fad..8d513543bf 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp @@ -37,7 +37,6 @@ #include "cafSelectionManager.h" -#include "cafNotificationCenter.h" #include "cafPdmReferenceHelper.h" #include "cafPdmUiFieldHandle.h" #include "cafPdmUiObjectHandle.h" @@ -57,12 +56,24 @@ SelectionManager* SelectionManager::instance() return singleton; } +//-------------------------------------------------------------------------------------------------- +/// Obsolete. Do not use this method. +//-------------------------------------------------------------------------------------------------- +caf::NotificationCenter* SelectionManager::notificationCenter() +{ + return nullptr; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void SelectionManager::selectedItems(std::vector& items, int role /*= SelectionManager::APPLICATION_GLOBAL*/) +void SelectionManager::selectedItems(std::vector& items, int selectionLevel /*= 0*/) { - std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; + const auto& levelSelectionPairIt = m_selectionPrLevel.find(selectionLevel); + + if (levelSelectionPairIt == m_selectionPrLevel.end()) return ; + + std::vector< std::pair, PdmUiItem*> >& selection = levelSelectionPairIt->second; for (size_t i = 0; i < selection.size(); i++) { @@ -76,40 +87,140 @@ void SelectionManager::selectedItems(std::vector& items, int role /* //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void SelectionManager::setSelectedItems(const std::vector& items, int role /*= SelectionManager::APPLICATION_GLOBAL*/) +void SelectionManager::setSelectedItems(const std::vector& items) { - std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; + std::map , PdmUiItem*> > > newCompleteSelectionMap; + + std::vector< std::pair, PdmUiItem*> > & newSelection = newCompleteSelectionMap[0]; - selection.clear(); + extractInternalSelectionItems(items, &newSelection); - for (size_t i = 0; i < items.size(); i++) + std::set changedLevels = findChangedLevels(newCompleteSelectionMap); + + if ( !changedLevels.empty() ) + { + m_selectionPrLevel = newCompleteSelectionMap; + notifySelectionChanged(changedLevels); + } +} + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::extractInternalSelectionItems(const std::vector &items, + std::vector, PdmUiItem *>> *newSelection) +{ + for ( size_t i = 0; i < items.size(); i++ ) { PdmUiFieldHandle* fieldHandle = dynamic_cast(items[i]); - if (fieldHandle) + if ( fieldHandle ) { PdmObjectHandle* obj = fieldHandle->fieldHandle()->ownerObject(); - selection.push_back(std::make_pair(obj, fieldHandle)); + newSelection->push_back(std::make_pair(obj, fieldHandle)); } else { PdmUiObjectHandle* obj = dynamic_cast(items[i]); - if (obj) + if ( obj ) { - selection.push_back(std::make_pair(obj->objectHandle(), obj)); + newSelection->push_back(std::make_pair(obj->objectHandle(), obj)); } } } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::setSelectedItemsAtLevel(const std::vector& items, int selectionLevel) +{ + std::vector< std::pair, PdmUiItem*> >& selection = m_selectionPrLevel[selectionLevel]; + std::vector< std::pair, PdmUiItem*> > newSelection; + + extractInternalSelectionItems(items, &newSelection); + + if (newSelection != selection) + { + selection = newSelection; + notifySelectionChanged({selectionLevel}); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void SelectionManager::setSelection(const std::vector< SelectionItem > completeSelection) +{ + std::map , PdmUiItem*> > > newCompleteSelectionMap; + std::map > newSelectionPrLevel; + + for (const SelectionItem& item: completeSelection) + { + newSelectionPrLevel[item.selectionLevel].push_back(item.item); + } + + for (auto& levelItemsPair: newSelectionPrLevel) + { + std::vector< std::pair, PdmUiItem*> > & newSelectionLevel = newCompleteSelectionMap[levelItemsPair.first]; + extractInternalSelectionItems(levelItemsPair.second, &newSelectionLevel); + } + + std::set changedLevels = findChangedLevels(newCompleteSelectionMap); + + if ( !changedLevels.empty()) + { + m_selectionPrLevel = newCompleteSelectionMap; + notifySelectionChanged(changedLevels); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::set SelectionManager::findChangedLevels(const std::map, PdmUiItem *>>> & newCompleteSelectionMap ) const +{ + std::set changedLevels; + + // Compare the existing levels with the corresponding levels in the new selection + + for ( auto& levelSelectionPair : m_selectionPrLevel ) + { + auto it = newCompleteSelectionMap.find(levelSelectionPair.first); + if ( it != newCompleteSelectionMap.end() ) + { + if ( levelSelectionPair.second != it->second ) changedLevels.insert(levelSelectionPair.first); + } + else + { + if ( !levelSelectionPair.second.empty() ) changedLevels.insert(levelSelectionPair.first); + } + } - notifySelectionChanged(); + // Add each of the levels in the new selection that are not present in the existing selection + for ( auto& levelSelectionPair : newCompleteSelectionMap ) + { + auto it = m_selectionPrLevel.find(levelSelectionPair.first); + if ( it == m_selectionPrLevel.end() ) + { + changedLevels.insert(levelSelectionPair.first); + } + } + + return changedLevels; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiItem* SelectionManager::selectedItem(int role /*= SelectionManager::APPLICATION_GLOBAL*/) +PdmUiItem* SelectionManager::selectedItem(int selectionLevel /*= 0*/) { - std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; + const auto& levelSelectionPairIt = m_selectionPrLevel.find(selectionLevel); + if (levelSelectionPairIt == m_selectionPrLevel.end()) return nullptr; + + std::vector< std::pair, PdmUiItem*> >& selection = levelSelectionPairIt->second; if (selection.size() == 1) { @@ -125,32 +236,43 @@ PdmUiItem* SelectionManager::selectedItem(int role /*= SelectionManager::APPLICA //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void SelectionManager::setSelectedItem(PdmUiItem* item, int role /*= SelectionManager::APPLICATION_GLOBAL*/) +void SelectionManager::setSelectedItem(PdmUiItem* item) { std::vector singleSelection; singleSelection.push_back(item); - setSelectedItems(singleSelection, role); + setSelectedItems(singleSelection); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -SelectionManager::SelectionManager() +void SelectionManager::setSelectedItemAtLevel(PdmUiItem* item, int selectionLevel) { - m_selectionForRole.resize(UNDEFINED); + std::vector singleSelection; + singleSelection.push_back(item); + + setSelectedItemsAtLevel(singleSelection, selectionLevel); +} - m_notificationCenter = nullptr; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +SelectionManager::SelectionManager() +{ m_activeChildArrayFieldHandle = nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void SelectionManager::selectionAsReferences(std::vector& referenceList, int role) const +void SelectionManager::selectionAsReferences(std::vector& referenceList, int selectionLevel /*= 0*/) const { -// const std::vector& selection = m_selectionForRole[role]; - const std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; + const auto& levelSelectionPairIt = m_selectionPrLevel.find(selectionLevel); + + if (levelSelectionPairIt == m_selectionPrLevel.end()) return; + + const std::vector< std::pair, PdmUiItem*> >& selection = levelSelectionPairIt->second; for (size_t i = 0; i < selection.size(); i++) { @@ -170,7 +292,7 @@ void SelectionManager::selectionAsReferences(std::vector& referenceList //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void SelectionManager::setSelectionFromReferences(const std::vector& referenceList, int role) +void SelectionManager::setSelectionAtLevelFromReferences(const std::vector& referenceList, int selectionLevel /*= 0*/) { std::vector uiItems; @@ -189,58 +311,87 @@ void SelectionManager::setSelectionFromReferences(const std::vector& re } } - setSelectedItems(uiItems, role); + setSelectedItemsAtLevel(uiItems, selectionLevel); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void SelectionManager::clearAll() +bool SelectionManager::isSelected(PdmUiItem* item, int selectionLevel) const { - for (size_t i = 0; i < m_selectionForRole.size(); i++) + auto levelIter = m_selectionPrLevel.find(selectionLevel); + + if (levelIter == m_selectionPrLevel.end()) return false; + + const std::vector< std::pair, PdmUiItem*> >& selection = levelIter->second; + + auto iter = selection.begin(); + while ( iter != selection.end() ) { - m_selectionForRole[i].clear(); + if ( iter->second == item ) + { + return true; + } + else + { + ++iter; + } } - notifySelectionChanged(); + return false; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void SelectionManager::clear(int role) +void SelectionManager::clearAll() { - m_selectionForRole[role].clear(); + std::set changedSelectionLevels; - notifySelectionChanged(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void SelectionManager::notifySelectionChanged() -{ - if (m_notificationCenter) + for ( auto & levelSelectionPair : m_selectionPrLevel) { - m_notificationCenter->notifyObserversOfSelectionChange(); + if ( !levelSelectionPair.second.empty()) + { + levelSelectionPair.second.clear(); + changedSelectionLevels.insert(levelSelectionPair.first); + } + } + + m_selectionPrLevel.clear(); + + if ( changedSelectionLevels.size() ) + { + notifySelectionChanged(changedSelectionLevels); } } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void SelectionManager::setNotificationCenter(NotificationCenter* notificationCenter) +void SelectionManager::clear(int selectionLevel) { - m_notificationCenter = notificationCenter; + const auto& levelSelectionPairIt = m_selectionPrLevel.find(selectionLevel); + + if (levelSelectionPairIt == m_selectionPrLevel.end()) return; + + if ( !levelSelectionPairIt->second.empty() ) + { + m_selectionPrLevel[selectionLevel].clear(); + + notifySelectionChanged({selectionLevel}); + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -NotificationCenter* SelectionManager::notificationCenter() +void SelectionManager::notifySelectionChanged( const std::set& changedSelectionLevels ) { - return m_notificationCenter; + for (auto receiver: m_selectionReceivers) + { + receiver->onSelectionManagerSelectionChanged(changedSelectionLevels); + } } //-------------------------------------------------------------------------------------------------- @@ -248,11 +399,11 @@ NotificationCenter* SelectionManager::notificationCenter() //-------------------------------------------------------------------------------------------------- void SelectionManager::removeObjectFromAllSelections(PdmObjectHandle* pdmObject) { - bool doNotifySelectionChanged = false; + std::set changedSelectionLevels; - for (size_t role = 0; role < m_selectionForRole.size(); role++) + for ( auto & levelSelectionPair : m_selectionPrLevel) { - std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; + std::vector< std::pair, PdmUiItem*> >& selection = levelSelectionPair.second; std::vector< std::pair, PdmUiItem*> >::iterator iter = selection.begin(); while (iter != selection.end()) @@ -264,7 +415,7 @@ void SelectionManager::removeObjectFromAllSelections(PdmObjectHandle* pdmObject) { iter = selection.erase(iter); - doNotifySelectionChanged = true; + changedSelectionLevels.insert(levelSelectionPair.first); } else { @@ -278,10 +429,7 @@ void SelectionManager::removeObjectFromAllSelections(PdmObjectHandle* pdmObject) } } - if (doNotifySelectionChanged) - { - notifySelectionChanged(); - } + notifySelectionChanged(changedSelectionLevels); } void SelectionManager::setPdmRootObject(PdmObjectHandle* root) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h index ca090c019e..4668b3c627 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h @@ -33,18 +33,17 @@ // for more details. // //################################################################################################## - - #pragma once -#include "cafPdmPointer.h" +#include "cafSelectionChangedReceiver.h" +#include "cafPdmObjectHandle.h" +#include "cafPdmPointer.h" #include "cafPdmField.h" -#include - #include - +#include +#include namespace caf { @@ -59,55 +58,58 @@ class PdmChildArrayFieldHandle; class SelectionManager { public: - enum SelectionRole - { - APPLICATION_GLOBAL, - CURRENT, - UNDEFINED + enum SelectionLevel + { + UNDEFINED = -1, + BASE_LEVEL = 0, + FIRST_LEVEL = 1, + SECOND_LEVEL = 2 }; public: - static SelectionManager* instance(); + static SelectionManager* instance(); - void setNotificationCenter(NotificationCenter* notificationCenter); - NotificationCenter* notificationCenter(); - - void setActiveChildArrayFieldHandle(PdmChildArrayFieldHandle* childArray); - PdmChildArrayFieldHandle* activeChildArrayFieldHandle(); + PdmUiItem* selectedItem(int selectionLevel = 0); + void selectedItems(std::vector& items, int selectionLevel = 0); + + void setSelectedItem(PdmUiItem* item); + void setSelectedItemAtLevel(PdmUiItem* item, int selectionLevel); + + void setSelectedItems(const std::vector& items); + void setSelectedItemsAtLevel(const std::vector& items, int selectionLevel = 0); - void setPdmRootObject(PdmObjectHandle* root); - PdmObjectHandle* pdmRootObject() { return m_rootObject; } + struct SelectionItem { PdmUiItem* item; int selectionLevel; }; + void setSelection(const std::vector< SelectionItem > completeSelection); - PdmUiItem* selectedItem(int role = SelectionManager::APPLICATION_GLOBAL); - void setSelectedItem(PdmUiItem* item, int role = SelectionManager::APPLICATION_GLOBAL); - void selectedItems(std::vector& items, int role = SelectionManager::APPLICATION_GLOBAL); - void setSelectedItems(const std::vector& items, int role = SelectionManager::APPLICATION_GLOBAL); + void selectionAsReferences(std::vector& referenceList, int selectionLevel = 0) const; + void setSelectionAtLevelFromReferences(const std::vector& referenceList, int selectionLevel); - void selectionAsReferences(std::vector& referenceList, int role = SelectionManager::APPLICATION_GLOBAL) const; - void setSelectionFromReferences(const std::vector& referenceList, int role = SelectionManager::APPLICATION_GLOBAL); + bool isSelected(PdmUiItem* item, int selectionLevel) const; - void clearAll(); - void clear(int role); - void removeObjectFromAllSelections(PdmObjectHandle* pdmObject); + void clearAll(); + void clear(int selectionLevel); + void removeObjectFromAllSelections(PdmObjectHandle* pdmObject); template - void objectsByType(std::vector* typedObjects, int role = SelectionManager::APPLICATION_GLOBAL) + void objectsByType(std::vector* typedObjects, int selectionLevel = 0) { std::vector items; - this->selectedItems(items, role); + this->selectedItems(items, selectionLevel); for (size_t i = 0; i < items.size(); i++) { T* obj = dynamic_cast(items[i]); if (obj) typedObjects->push_back(obj); } } + + /// Returns the selected objects of the requested type if _all_ the selected objects are of the requested type template - void objectsByTypeStrict(std::vector* typedObjects, int role = SelectionManager::APPLICATION_GLOBAL) + void objectsByTypeStrict(std::vector* typedObjects, int selectionLevel = 0) { std::vector items; - this->selectedItems(items, role); + this->selectedItems(items, selectionLevel); for (size_t i = 0; i < items.size(); i++) { T* obj = dynamic_cast(items[i]); @@ -120,16 +122,62 @@ class SelectionManager } } + template + T* selectedItemOfType(int selectionLevel = 0) + { + std::vector typedObjects; + this->objectsByType(&typedObjects, selectionLevel); + if (!typedObjects.empty()) + { + return typedObjects.front(); + } + return nullptr; + } + + template + T* selectedItemAncestorOfType(int selectionLevel = 0) + { + PdmUiItem* item = this->selectedItem(selectionLevel); + PdmObjectHandle* selectedObject = dynamic_cast(item); + if (selectedObject) + { + T* ancestor = nullptr; + selectedObject->firstAncestorOrThisOfType(ancestor); + return ancestor; + } + return nullptr; + } + + // OBSOLETE ! Remove when time to refactor the command system + NotificationCenter* notificationCenter(); + + void setActiveChildArrayFieldHandle(PdmChildArrayFieldHandle* childArray); + PdmChildArrayFieldHandle* activeChildArrayFieldHandle(); + + void setPdmRootObject(PdmObjectHandle* root); + PdmObjectHandle* pdmRootObject() { return m_rootObject; } + // End OBSOLETE + private: SelectionManager(); - void notifySelectionChanged(); + + static void extractInternalSelectionItems(const std::vector &items, + std::vector, PdmUiItem *>> *internalSelectionItems); + + void notifySelectionChanged( const std::set& changedSelectionLevels ); + std::set findChangedLevels(const std::map, PdmUiItem *>>> &newCompleteSelectionMap) const; + + friend class SelectionChangedReceiver; + void registerSelectionChangedReceiver ( SelectionChangedReceiver* receiver) { m_selectionReceivers.insert(receiver);} + void unregisterSelectionChangedReceiver( SelectionChangedReceiver* receiver) { m_selectionReceivers.erase(receiver);} private: - std::vector < std::vector< std::pair, PdmUiItem*> > > m_selectionForRole; + std::map , PdmUiItem*> > > m_selectionPrLevel; - NotificationCenter* m_notificationCenter; PdmChildArrayFieldHandle* m_activeChildArrayFieldHandle; PdmPointer m_rootObject; + + std::set< SelectionChangedReceiver*> m_selectionReceivers; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafUiTreeItem.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafUiTreeItem.h index b1bc82c029..d16a456c5f 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafUiTreeItem.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafUiTreeItem.h @@ -76,6 +76,18 @@ class UiTreeItem return m_childItems.value(row); } + bool hasGrandChildren() const + { + for (auto child : m_childItems) + { + if (child->childCount() != 0) + { + return true; + } + } + return false; + } + int childCount() const { return m_childItems.count(); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/CMakeLists.txt index 01fa1d3fa6..95b987c4b7 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/CMakeLists.txt +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/CMakeLists.txt @@ -53,4 +53,8 @@ target_include_directories(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR} ) +if (MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/W4 /wd4100 /wd4127") +endif() + source_group("" FILES ${PROJECT_FILES}) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h index b904463a0a..27582b60fd 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h @@ -14,8 +14,8 @@ class PdmFieldXmlCap : public PdmXmlFieldHandle // Xml Serializing public: - virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); - virtual void writeFieldData(QXmlStreamWriter& xmlStream) const; + void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) override; + void writeFieldData(QXmlStreamWriter& xmlStream) const override; private: FieldType* m_field; }; @@ -38,9 +38,9 @@ class PdmFieldXmlCap< PdmPtrField > : public PdmXmlFieldHandle // Xml Serializing public: - virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); - virtual void writeFieldData(QXmlStreamWriter& xmlStream) const; - virtual void resolveReferences(); + void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) override; + void writeFieldData(QXmlStreamWriter& xmlStream) const override; + void resolveReferences() override; private: FieldType* m_field; @@ -67,9 +67,9 @@ class PdmFieldXmlCap< PdmPtrArrayField >: public PdmXmlFieldHandle // Xml Serializing public: - virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); - virtual void writeFieldData(QXmlStreamWriter& xmlStream) const; - virtual void resolveReferences(); + void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) override; + void writeFieldData(QXmlStreamWriter& xmlStream) const override; + void resolveReferences() override; private: FieldType* m_field; @@ -91,8 +91,8 @@ class PdmFieldXmlCap< PdmChildField > : public PdmXmlFieldHandle // Xml Serializing public: - virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); - virtual void writeFieldData(QXmlStreamWriter& xmlStream) const; + void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) override; + void writeFieldData(QXmlStreamWriter& xmlStream) const override; private: FieldType* m_field; }; @@ -109,8 +109,8 @@ class PdmFieldXmlCap< PdmChildArrayField > : public PdmXmlFieldHandle // Xml Serializing public: - virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); - virtual void writeFieldData(QXmlStreamWriter& xmlStream) const; + void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) override; + void writeFieldData(QXmlStreamWriter& xmlStream) const override; private: FieldType* m_field; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h index 03ab3f9b33..b94509d321 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmDefaultObjectFactory.h @@ -62,7 +62,7 @@ class PdmDefaultObjectFactory : public PdmObjectFactory public: static PdmDefaultObjectFactory * instance(); - virtual PdmObjectHandle* create(const QString& classNameKeyword); + PdmObjectHandle* create(const QString& classNameKeyword) override; template< typename PdmObjectBaseDerivative > bool registerCreator() @@ -89,7 +89,7 @@ class PdmDefaultObjectFactory : public PdmObjectFactory private: PdmDefaultObjectFactory() {} - ~PdmDefaultObjectFactory() { /* Could clean up, but ... */ } + ~PdmDefaultObjectFactory() override { /* Could clean up, but ... */ } // Internal helper classes @@ -105,7 +105,7 @@ class PdmDefaultObjectFactory : public PdmObjectFactory class PdmObjectCreator : public PdmObjectCreatorBase { public: - virtual PdmObjectHandle * create() { return new PdmObjectBaseDerivative(); } + PdmObjectHandle * create() override { return new PdmObjectBaseDerivative(); } }; // Map to store factory diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h index 631ce73765..91ca4b9d9b 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h @@ -23,7 +23,7 @@ class PdmXmlFieldHandle : public PdmFieldCapability { public: PdmXmlFieldHandle(PdmFieldHandle* owner , bool giveOwnership); - virtual ~PdmXmlFieldHandle() { } + ~PdmXmlFieldHandle() override { } PdmFieldHandle* fieldHandle() { return m_owner; } const PdmFieldHandle* fieldHandle() const { return m_owner; } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp index 52e6ae55de..fc0847a032 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp @@ -185,6 +185,29 @@ PdmObjectHandle* PdmXmlObjectHandle::copyByXmlSerialization(PdmObjectFactory* ob return objectCopy; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmObjectHandle* PdmXmlObjectHandle::copyAndCastByXmlSerialization(const QString& destinationClassKeyword, const QString& sourceClassKeyword, PdmObjectFactory* objectFactory) +{ + this->setupBeforeSaveRecursively(); + + QString xmlString = this->writeObjectToXmlString(); + + PdmObjectHandle* upgradedObject = objectFactory->create(destinationClassKeyword); + QXmlStreamReader inputStream(xmlString); + + QXmlStreamReader::TokenType tt; + tt = inputStream.readNext(); // Start of document + tt = inputStream.readNext(); + QString classKeyword = inputStream.name().toString(); + CAF_ASSERT(classKeyword == sourceClassKeyword); + + xmlObj(upgradedObject)->readFields(inputStream, objectFactory); + + return upgradedObject; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h index 5616308e67..8daba8e57d 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h @@ -27,7 +27,7 @@ class PdmXmlObjectHandle : public PdmObjectCapability public: PdmXmlObjectHandle(PdmObjectHandle* owner, bool giveOwnership); - virtual ~PdmXmlObjectHandle() { } + ~PdmXmlObjectHandle() override { } /// The classKeyword method is overridden in subclasses by the CAF_PDM_XML_HEADER_INIT macro virtual QString classKeyword() const = 0; @@ -37,6 +37,9 @@ class PdmXmlObjectHandle : public PdmObjectCapability QString writeObjectToXmlString() const; static PdmObjectHandle* readUnknownObjectFromXmlString(const QString& xmlString, PdmObjectFactory* objectFactory); PdmObjectHandle* copyByXmlSerialization(PdmObjectFactory* objectFactory); + PdmObjectHandle* copyAndCastByXmlSerialization(const QString& destinationClassKeyword, + const QString& sourceClassKeyword, + PdmObjectFactory* objectFactory); // Main XML serialization methods that is used internally by the document serialization system // Not supposed to be used directly. diff --git a/Fwk/AppFwk/cafTensor/cafTensor3.h b/Fwk/AppFwk/cafTensor/cafTensor3.h index c943821cb8..5e475a63b1 100644 --- a/Fwk/AppFwk/cafTensor/cafTensor3.h +++ b/Fwk/AppFwk/cafTensor/cafTensor3.h @@ -29,9 +29,13 @@ class Tensor3 { S m_tensor[6]; // SXX, SYY, SZZ, SXY, SYZ, SZX public: - Tensor3() {} + Tensor3(); Tensor3(S sxx, S syy, S szz, S sxy, S syz, S szx); Tensor3(const Tensor3& other); + template + explicit Tensor3(const Tensor3& other); + + static Tensor3 invalid(); inline Tensor3& operator=(const Tensor3& rhs); inline Tensor3 operator+(const Tensor3& rhs) const; @@ -55,6 +59,7 @@ class Tensor3 }; typedef Tensor3 Ten3f; +typedef Tensor3 Ten3d; } diff --git a/Fwk/AppFwk/cafTensor/cafTensor3.inl b/Fwk/AppFwk/cafTensor/cafTensor3.inl index 8a55e55e40..2bfe705b08 100644 --- a/Fwk/AppFwk/cafTensor/cafTensor3.inl +++ b/Fwk/AppFwk/cafTensor/cafTensor3.inl @@ -27,6 +27,19 @@ namespace caf { +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template< typename S> +caf::Tensor3::Tensor3() +{ + m_tensor[0] = (S) 0.0; + m_tensor[1] = (S) 0.0; + m_tensor[2] = (S) 0.0; + m_tensor[3] = (S) 0.0; + m_tensor[4] = (S) 0.0; + m_tensor[5] = (S) 0.0; +} //---------------------------------------------------------------------------------------------------- /// Copy constructor @@ -37,6 +50,21 @@ inline Tensor3::Tensor3(const Tensor3& other) cvf::System::memcpy(m_tensor, sizeof(m_tensor), other.m_tensor, sizeof(other.m_tensor)); } +//---------------------------------------------------------------------------------------------------- +/// Explicit Cast constructor +//---------------------------------------------------------------------------------------------------- +template +template +Tensor3::Tensor3(const Tensor3& other) +{ + m_tensor[SXX] = other[Tensor3::SXX]; + m_tensor[SYY] = other[Tensor3::SYY]; + m_tensor[SZZ] = other[Tensor3::SZZ]; + m_tensor[SXY] = other[Tensor3::SXY]; + m_tensor[SYZ] = other[Tensor3::SYZ]; + m_tensor[SZX] = other[Tensor3::SZX]; +} + //---------------------------------------------------------------------------------------------------- /// Constructor with explicit initialization of all tensor elements. /// @@ -52,6 +80,17 @@ Tensor3::Tensor3(S sxx, S syy, S szz, S sxy, S syz, S szx) m_tensor[5] = szx; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +template +Tensor3 caf::Tensor3::invalid() +{ + return caf::Tensor3(std::numeric_limits::infinity(), std::numeric_limits::infinity(), + std::numeric_limits::infinity(), std::numeric_limits::infinity(), + std::numeric_limits::infinity(), std::numeric_limits::infinity()); +} + //---------------------------------------------------------------------------------------------------- /// Assignment operator //---------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.cpp b/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.cpp index 9085e7bbe7..089d8445eb 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.cpp +++ b/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.cpp @@ -151,28 +151,29 @@ QWidget* CustomObjectEditor::createWidget(QWidget* parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void CustomObjectEditor::recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, const QString& uiConfigName) +void CustomObjectEditor::recursivelyConfigureAndUpdateTopLevelUiOrdering(const PdmUiOrdering& topLevelUiOrdering, const QString& uiConfigName) { resetCellId(); QWidget* previousTabOrderWidget = nullptr; + const std::vector& topLevelUiItems = topLevelUiOrdering.uiItemsWithLayout(); + for (size_t i = 0; i < topLevelUiItems.size(); ++i) { - if (topLevelUiItems[i]->isUiHidden(uiConfigName)) continue; + if (topLevelUiItems[i].first->isUiHidden(uiConfigName)) continue; - if (topLevelUiItems[i]->isUiGroup()) + if (topLevelUiItems[i].first->isUiGroup()) { - PdmUiGroup* group = static_cast(topLevelUiItems[i]); + PdmUiGroup* group = static_cast(topLevelUiItems[i].first); QMinimizePanel* groupBox = findOrCreateGroupBox(this->widget(), group, uiConfigName); /// Insert the group box at the correct position of the parent layout int nextCellId = getNextAvailableCellId(); std::pair rowCol = rowAndColumn(nextCellId); m_layout->addWidget(groupBox, rowCol.first, rowCol.second, 1, 1); - - const std::vector& groupChildren = group->uiItems(); - recursivelyConfigureAndUpdateUiItemsInGridLayoutColumn(groupChildren, groupBox->contentFrame(), uiConfigName); + + recursivelyConfigureAndUpdateUiOrderingInGridLayoutColumn(*group, groupBox->contentFrame(), uiConfigName); } // NB! Only groups at top level are handled, fields at top level are not added to layout diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.h b/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.h index cb5e88593c..4c9bb600f1 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.h +++ b/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.h @@ -36,7 +36,7 @@ #pragma once -#include "cafPdmUiWidgetBasedObjectEditor.h" +#include "cafPdmUiFormLayoutObjectEditor.h" #include @@ -61,12 +61,12 @@ class PdmUiGroup; /// User defined external widgets can be inserted into grid layout cells, and these cells /// are excluded for automatic layout //================================================================================================== -class CustomObjectEditor : public PdmUiWidgetBasedObjectEditor +class CustomObjectEditor : public PdmUiFormLayoutObjectEditor { Q_OBJECT public: CustomObjectEditor(); - ~CustomObjectEditor(); + ~CustomObjectEditor() override; void defineGridLayout(int rowCount, int columnCount); @@ -77,9 +77,9 @@ class CustomObjectEditor : public PdmUiWidgetBasedObjectEditor void addBlankCell(int row, int column); private: - virtual QWidget* createWidget(QWidget* parent) override; - virtual void recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, - const QString& uiConfigName) override; + QWidget* createWidget(QWidget* parent) override; + void recursivelyConfigureAndUpdateTopLevelUiOrdering(const PdmUiOrdering& topLevelUiOrdering, + const QString& uiConfigName) override; bool isAreaAvailable(int row, int column, int rowSpan, int columnSpan) const; bool isCellIdAvailable(int cellId) const; diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp index b7ef99938a..4b51082a51 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp +++ b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp @@ -27,11 +27,13 @@ #include "cafPdmReferenceHelper.h" #include "cafPdmUiComboBoxEditor.h" #include "cafPdmUiFilePathEditor.h" +#include "cafPdmUiOrdering.h" #include "cafPdmUiItem.h" #include "cafPdmUiListEditor.h" #include "cafPdmUiPropertyView.h" #include "cafPdmUiPushButtonEditor.h" #include "cafPdmUiTableView.h" +#include "cafPdmUiTableViewEditor.h" #include "cafPdmUiTextEditor.h" #include "cafPdmUiTreeSelectionEditor.h" #include "cafPdmUiTreeView.h" @@ -74,6 +76,8 @@ class SmallDemoPdmObject: public caf::PdmObject CAF_PDM_InitField(&m_toggleField, "Toggle", false, "Add Items To Multi Select", "", "Toggle Field tooltip", " Toggle Field whatsthis"); CAF_PDM_InitField(&m_doubleField, "BigNumber", 0.0, "Big Number", "", "Enter a big number here", "This is a place you can enter a big real value if you want" ); + m_doubleField.uiCapability()->setCustomContextMenuEnabled(true); + CAF_PDM_InitField(&m_intField, "IntNumber", 0, "Small Number", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); CAF_PDM_InitField(&m_textField, "TextField", QString(""), "Text", "", "Text tooltip", "This is a place you can enter a small integer value if you want"); @@ -103,6 +107,7 @@ class SmallDemoPdmObject: public caf::PdmObject caf::PdmField m_doubleField; caf::PdmField m_intField; caf::PdmField m_textField; + caf::PdmProxyValueField m_proxyDoubleField; caf::PdmField m_fileName; caf::PdmField> m_fileNameList; @@ -111,12 +116,12 @@ class SmallDemoPdmObject: public caf::PdmObject caf::PdmField m_toggleField; - virtual caf::PdmFieldHandle* objectToggleField() + caf::PdmFieldHandle* objectToggleField() override { return &m_toggleField; } - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override { if (changedField == &m_toggleField) { @@ -131,7 +136,7 @@ class SmallDemoPdmObject: public caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override { QList options; @@ -192,6 +197,18 @@ class SmallDemoPdmObject: public caf::PdmObject } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, + QMenu* menu, + QWidget* fieldEditorWidget) override + { + menu->addAction("test"); + menu->addAction("other test <<>>"); + } + private: double m_doubleMember; @@ -199,11 +216,10 @@ class SmallDemoPdmObject: public caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override { uiOrdering.add(&m_doubleField); uiOrdering.add(&m_intField); - QString dynamicGroupName = QString("Dynamic Group Text (%1)").arg(m_intField); caf::PdmUiGroup* group = uiOrdering.addNewGroupWithKeyword(dynamicGroupName, "MyTest"); @@ -215,6 +231,151 @@ class SmallDemoPdmObject: public caf::PdmObject CAF_PDM_SOURCE_INIT(SmallDemoPdmObject, "SmallDemoPdmObject"); +class SmallGridDemoPdmObject : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; +public: + + SmallGridDemoPdmObject() + { + CAF_PDM_InitObject("Small Grid Demo Object", "", "This object is a demo of the CAF framework", "This object is a demo of the CAF framework"); + + CAF_PDM_InitField(&m_intFieldStandard, "Standard", 0, "Standard", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldUseFullSpace, "FullSpace", 0, "Use Full Space For Both", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldUseFullSpaceLabel, "FullSpaceLabel", 0, "Total 3, Label MAX", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldUseFullSpaceField, "FullSpaceField", 0, "Total MAX, Label 1", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldWideLabel,"WideLabel", 0, "Wide Label", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldWideField,"WideField", 0, "Wide Field", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldLeft, "LeftField", 0, "Left Field", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldRight, "RightField", 0, "Right Field With More Text", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldWideBoth, "WideBoth", 0, "Wide Both", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + + CAF_PDM_InitField(&m_intFieldWideBoth2, "WideBoth2", 0, "Wide Both", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldLeft2, "LeftFieldInGrp", 0, "Left Field", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldCenter, "CenterFieldInGrp", 0, "Center Field", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldRight2, "RightFieldInGrp", 0, "Right Field", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldLabelTop, "FieldLabelTop", 0, "Field Label Top", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + m_intFieldLabelTop.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + CAF_PDM_InitField(&m_stringFieldLabelHidden, "FieldLabelHidden", QString("Hidden Label Field"), "Field Label Hidden", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + m_stringFieldLabelHidden.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + CAF_PDM_InitField(&m_intFieldWideBothAuto, "WideBothAuto", 0, "Wide ", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldLeftAuto, "LeftFieldInGrpAuto", 0, "Left Field", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldCenterAuto, "CenterFieldInGrpAuto", 0, "Center Field", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldRightAuto, "RightFieldInGrpAuto", 0, "Right Field", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldLabelTopAuto, "FieldLabelTopAuto", 0, "Field Label Top", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + m_intFieldLabelTopAuto.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::TOP); + CAF_PDM_InitField(&m_stringFieldLabelHiddenAuto, "FieldLabelHiddenAuto", QString("Hidden Label Field"), "Field Label Hidden", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + m_stringFieldLabelHiddenAuto.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); + + CAF_PDM_InitField(&m_intFieldLeftOfGroup, "FieldLeftOfGrp", 0, "Left of group", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldRightOfGroup, "FieldRightOfGrp", 0, "Right of group wide label", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + + CAF_PDM_InitField(&m_intFieldInsideGroup1, "FieldInGrp1", 0, "Inside Group", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldInsideGroup2, "FieldInGrp2", 0, "Inside Group", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldInsideGroup3, "FieldInGrp3", 0, "Inside Group", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldInsideGroup4, "FieldInGrp4", 0, "Inside Group", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldInsideGroup5, "FieldInGrp5", 0, "Inside Group", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + CAF_PDM_InitField(&m_intFieldInsideGroup6, "FieldInGrp6", 0, "Inside Group", "", "Enter some small number here", "This is a place you can enter a small integer value if you want"); + + } + + // Outside group + caf::PdmField m_intFieldStandard; + caf::PdmField m_intFieldUseFullSpace; + caf::PdmField m_intFieldUseFullSpaceLabel; + caf::PdmField m_intFieldUseFullSpaceField; + caf::PdmField m_intFieldWideLabel; + caf::PdmField m_intFieldWideField; + caf::PdmField m_intFieldWideBoth; + caf::PdmField m_intFieldLeft; + caf::PdmField m_intFieldRight; + + // First group + caf::PdmField m_intFieldWideBoth2; + caf::PdmField m_intFieldLeft2; + caf::PdmField m_intFieldCenter; + caf::PdmField m_intFieldRight2; + caf::PdmField m_intFieldLabelTop; + caf::PdmField m_stringFieldLabelHidden; + + // Auto group + caf::PdmField m_intFieldWideBothAuto; + caf::PdmField m_intFieldLeftAuto; + caf::PdmField m_intFieldCenterAuto; + caf::PdmField m_intFieldRightAuto; + caf::PdmField m_intFieldLabelTopAuto; + caf::PdmField m_stringFieldLabelHiddenAuto; + + // Combination with groups + caf::PdmField m_intFieldLeftOfGroup; + caf::PdmField m_intFieldRightOfGroup; + caf::PdmField m_intFieldInsideGroup1; + caf::PdmField m_intFieldInsideGroup2; + + // Side-by-side groups + caf::PdmField m_intFieldInsideGroup3; + caf::PdmField m_intFieldInsideGroup4; + caf::PdmField m_intFieldInsideGroup5; + caf::PdmField m_intFieldInsideGroup6; + +protected: + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override + { + uiOrdering.add(&m_intFieldStandard); + uiOrdering.add(&m_intFieldUseFullSpace, caf::PdmUiOrdering::LayoutOptions(true, caf::PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN, caf::PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN)); + uiOrdering.add(&m_intFieldUseFullSpaceLabel, caf::PdmUiOrdering::LayoutOptions(true, 3, caf::PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN)); + uiOrdering.add(&m_intFieldUseFullSpaceField, caf::PdmUiOrdering::LayoutOptions(true, caf::PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN, 1)); + uiOrdering.add(&m_intFieldWideLabel, caf::PdmUiOrdering::LayoutOptions(true, 4, 3)); + uiOrdering.add(&m_intFieldWideField, caf::PdmUiOrdering::LayoutOptions(true, 4, 1)); + uiOrdering.add(&m_intFieldLeft, caf::PdmUiOrdering::LayoutOptions(true)); + uiOrdering.add(&m_intFieldRight, caf::PdmUiOrdering::LayoutOptions(false)); + uiOrdering.add(&m_intFieldWideBoth, caf::PdmUiOrdering::LayoutOptions(true, 4, 2)); + + QString dynamicGroupName = QString("Dynamic Group Text (%1)").arg(m_intFieldStandard); + + caf::PdmUiGroup* group = uiOrdering.addNewGroup("Wide Group", { true, 4 }); + group->add(&m_intFieldWideBoth2, caf::PdmUiOrdering::LayoutOptions(true, 6, 3)); + group->add(&m_intFieldLeft2, caf::PdmUiOrdering::LayoutOptions(true)); + group->add(&m_intFieldCenter, caf::PdmUiOrdering::LayoutOptions(false)); + group->add(&m_intFieldRight2, caf::PdmUiOrdering::LayoutOptions(false)); + group->add(&m_intFieldLabelTop, caf::PdmUiOrdering::LayoutOptions(true, 6)); + group->add(&m_stringFieldLabelHidden, caf::PdmUiOrdering::LayoutOptions(true, 6)); + + caf::PdmUiGroup* autoGroup = uiOrdering.addNewGroup("Automatic Full Width Group", caf::PdmUiOrdering::LayoutOptions(true)); + autoGroup->add(&m_intFieldWideBothAuto, caf::PdmUiOrdering::LayoutOptions(true)); + autoGroup->add(&m_intFieldLeftAuto, caf::PdmUiOrdering::LayoutOptions(true)); + autoGroup->add(&m_intFieldCenterAuto, false); + autoGroup->add(&m_intFieldRightAuto, caf::PdmUiOrdering::LayoutOptions(false)); + autoGroup->add(&m_intFieldLabelTopAuto, true); + autoGroup->add(&m_stringFieldLabelHiddenAuto, true); + + + uiOrdering.add(&m_intFieldLeftOfGroup); + caf::PdmUiGroup* group2 = uiOrdering.addNewGroup("Right Group", caf::PdmUiOrdering::LayoutOptions(false, 2, 0)); + group2->setEnableFrame(false); + group2->add(&m_intFieldInsideGroup1); + + caf::PdmUiGroup* group3 = uiOrdering.addNewGroup("Narrow L", caf::PdmUiOrdering::LayoutOptions(true, 1)); + group3->add(&m_intFieldInsideGroup2); + uiOrdering.add(&m_intFieldRightOfGroup, caf::PdmUiOrdering::LayoutOptions(false, 3, 2)); + + caf::PdmUiGroup* groupL = uiOrdering.addNewGroup("Left Group", caf::PdmUiOrdering::LayoutOptions(true, 1)); + groupL->add(&m_intFieldInsideGroup3); + groupL->add(&m_intFieldInsideGroup5); + caf::PdmUiGroup* groupR = uiOrdering.addNewGroup("Right Wide Group", caf::PdmUiOrdering::LayoutOptions(false, 3)); + groupR->setEnableFrame(false); + groupR->add(&m_intFieldInsideGroup4); + groupR->add(&m_intFieldInsideGroup6); + + } +}; + +CAF_PDM_SOURCE_INIT(SmallGridDemoPdmObject, "SmallGridDemoPdmObject"); + class SmallDemoPdmObjectA: public caf::PdmObject { CAF_PDM_HEADER_INIT; @@ -270,12 +431,12 @@ class SmallDemoPdmObjectA: public caf::PdmObject caf::PdmField m_toggleField; caf::PdmField m_pushButtonField; - virtual caf::PdmFieldHandle* objectToggleField() + caf::PdmFieldHandle* objectToggleField() override { return &m_toggleField; } - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override { if (changedField == &m_toggleField) { @@ -291,7 +452,7 @@ class SmallDemoPdmObjectA: public caf::PdmObject } } - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override { QList options; @@ -339,7 +500,7 @@ class SmallDemoPdmObjectA: public caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual caf::PdmFieldHandle* userDescriptionField() + caf::PdmFieldHandle* userDescriptionField() override { return &m_textField; } @@ -348,7 +509,7 @@ class SmallDemoPdmObjectA: public caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override { if (field == &m_multipleAppEnum) { @@ -372,9 +533,9 @@ class SmallDemoPdmObjectA: public caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void defineObjectEditorAttribute(QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override + void defineObjectEditorAttribute(QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override { - caf::PdmUiTableViewEditorAttribute* attr = dynamic_cast(attribute); + caf::PdmUiTableViewPushButtonEditorAttribute* attr = dynamic_cast(attribute); if (attr) { attr->registerPushButtonTextForFieldKeyword(m_pushButtonField.keyword(), "Edit"); @@ -422,6 +583,8 @@ class DemoPdmObject: public caf::PdmObject CAF_PDM_InitFieldNoDefault(&m_multiSelectList, "MultiSelect", "Selection List", "", "List" , "This is a multi selection list" ); CAF_PDM_InitFieldNoDefault(&m_objectList, "ObjectList", "Objects list Field", "", "List" , "This is a list of PdmObjects" ); CAF_PDM_InitFieldNoDefault(&m_objectListOfSameType, "m_objectListOfSameType", "Same type Objects list Field", "", "Same type List" , "Same type list of PdmObjects" ); + m_objectListOfSameType.uiCapability()->setUiEditorTypeName(caf::PdmUiTableViewEditor::uiEditorTypeName()); + m_objectListOfSameType.uiCapability()->setCustomContextMenuEnabled(true);; CAF_PDM_InitFieldNoDefault(&m_ptrField, "m_ptrField", "PtrField", "", "Same type List", "Same type list of PdmObjects"); m_filePath.capability()->setUiEditorTypeName(caf::PdmUiFilePathEditor::uiEditorTypeName()); @@ -435,8 +598,9 @@ class DemoPdmObject: public caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override { + uiOrdering.add(&m_objectListOfSameType); uiOrdering.add(&m_ptrField); uiOrdering.add(&m_boolField); caf::PdmUiGroup* group1 = uiOrdering.addNewGroup("Name1"); @@ -444,16 +608,15 @@ class DemoPdmObject: public caf::PdmObject caf::PdmUiGroup* group2 = uiOrdering.addNewGroup("Name2"); group2->add(&m_intField); caf::PdmUiGroup* group3 = group2->addNewGroup("Name3"); - group3->add(&m_textField); + //group3->add(&m_textField); - //uiConfig->add(&f3); - //uiConfig->forgetRemainingFields(); + uiOrdering.skipRemainingFields(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override { QList options; if (&m_multiSelectList == fieldNeedingOptions) @@ -488,7 +651,7 @@ class DemoPdmObject: public caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual caf::PdmFieldHandle* userDescriptionField() + caf::PdmFieldHandle* userDescriptionField() override { return &m_textField; } @@ -516,12 +679,12 @@ class DemoPdmObject: public caf::PdmObject MenuItemProducer* m_menuItemProducer; - virtual caf::PdmFieldHandle* objectToggleField() + caf::PdmFieldHandle* objectToggleField() override { return &m_toggleField; } - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override { if (changedField == &m_toggleField) { @@ -533,7 +696,7 @@ class DemoPdmObject: public caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void onEditorWidgetsCreated() override + void onEditorWidgetsCreated() override { for (auto e : m_longText.uiCapability()->connectedEditors()) { @@ -553,6 +716,18 @@ class DemoPdmObject: public caf::PdmObject } } } +protected: + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void defineCustomContextMenu(const caf::PdmFieldHandle* fieldNeedingMenu, QMenu* menu, QWidget* fieldEditorWidget) override + { + if (fieldNeedingMenu == &m_objectListOfSameType) + { + caf::PdmUiTableView::addActionsToMenu(menu, &m_objectListOfSameType); + } + } + }; CAF_PDM_SOURCE_INIT(DemoPdmObject, "DemoPdmObject"); @@ -656,8 +831,6 @@ void MainWindow::createDockPanels() dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); m_pdmUiTableView = new caf::PdmUiTableView(dockWidget); - m_pdmUiTableView->setSelectionRole(caf::SelectionManager::CURRENT); - m_pdmUiTableView->enableDefaultContextMenu(true); dockWidget->setWidget(m_pdmUiTableView); @@ -697,6 +870,9 @@ void MainWindow::buildTestModel() SmallDemoPdmObjectA* smallObj2 = new SmallDemoPdmObjectA; m_testRoot->objects.push_back(smallObj2); + SmallGridDemoPdmObject* smallGridObj = new SmallGridDemoPdmObject; + m_testRoot->objects.push_back(smallGridObj); + DemoPdmObject* demoObj2 = new DemoPdmObject; demoObject->m_textField = "Mitt Demo Obj"; @@ -792,7 +968,7 @@ MainWindow::~MainWindow() m_pdmUiTreeView->setPdmItem(nullptr); m_pdmUiTreeView2->setPdmItem(nullptr); m_pdmUiPropertyView->showProperties(nullptr); - m_pdmUiTableView->setListField(nullptr); + m_pdmUiTableView->setChildArrayField(nullptr); delete m_pdmUiTreeView; delete m_pdmUiTreeView2; @@ -955,30 +1131,34 @@ void MainWindow::slotShowTableView() std::vector selection; m_pdmUiTreeView2->selectedUiItems(selection); caf::PdmObjectHandle* obj = nullptr; - caf::PdmChildArrayFieldHandle* listField = nullptr; + caf::PdmUiFieldHandle* uiFieldHandle = nullptr; + caf::PdmChildArrayFieldHandle* childArrayFieldHandle = nullptr; if (selection.size()) { caf::PdmUiItem* pdmUiItem = selection[0]; - caf::PdmUiFieldHandle* guiField = dynamic_cast(pdmUiItem); - - if (guiField) listField = dynamic_cast(guiField->fieldHandle()); + uiFieldHandle = dynamic_cast(pdmUiItem); + if (uiFieldHandle) + { + childArrayFieldHandle = dynamic_cast(uiFieldHandle->fieldHandle()); + } - if (listField) + if (childArrayFieldHandle) { - if (!listField->hasSameFieldCountForAllObjects()) + if (!childArrayFieldHandle->hasSameFieldCountForAllObjects()) { - listField = nullptr; + uiFieldHandle = nullptr; + childArrayFieldHandle = nullptr; } } } - m_pdmUiTableView->setListField(listField); + m_pdmUiTableView->setChildArrayField(childArrayFieldHandle); - if (listField) + if (uiFieldHandle) { - listField->uiCapability()->updateConnectedEditors(); + uiFieldHandle->updateConnectedEditors(); } } diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.h b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.h index c70c625b23..50e0ec5ce8 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.h +++ b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.h @@ -27,7 +27,7 @@ class MainWindow : public QMainWindow public: MainWindow(); - ~MainWindow(); + ~MainWindow() override; static MainWindow* instance(); void setPdmRoot(caf::PdmObjectHandle* pdmRoot); diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/ManyGroups.h b/Fwk/AppFwk/cafTests/cafTestApplication/ManyGroups.h index 49d71cafa6..b3e1688ebc 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/ManyGroups.h +++ b/Fwk/AppFwk/cafTests/cafTestApplication/ManyGroups.h @@ -19,9 +19,9 @@ class ManyGroups : public caf::PdmObject caf::PdmField > m_multiSelectList; caf::PdmField m_toggleField; - virtual caf::PdmFieldHandle* objectToggleField(); + caf::PdmFieldHandle* objectToggleField() override; - virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); + void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override; void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } @@ -30,7 +30,7 @@ class ManyGroups : public caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; + QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override; private: double m_doubleMember; @@ -39,9 +39,9 @@ class ManyGroups : public caf::PdmObject //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; - virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; + void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) override; }; diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/WidgetLayoutTest.h b/Fwk/AppFwk/cafTests/cafTestApplication/WidgetLayoutTest.h index 2099e34c90..aaedcc2bb2 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/WidgetLayoutTest.h +++ b/Fwk/AppFwk/cafTests/cafTestApplication/WidgetLayoutTest.h @@ -14,7 +14,7 @@ class WidgetLayoutTest : public QWidget public: WidgetLayoutTest(QWidget* parent = nullptr, Qt::WindowFlags f = nullptr); - ~WidgetLayoutTest(); + ~WidgetLayoutTest() override; private: QGridLayout* m_mainLayout; diff --git a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt index 25cddf2a32..0dce881b2c 100644 --- a/Fwk/AppFwk/cafUserInterface/CMakeLists.txt +++ b/Fwk/AppFwk/cafUserInterface/CMakeLists.txt @@ -1,5 +1,10 @@ cmake_minimum_required (VERSION 2.8.12) +if (MSVC) + # Define this one to tell windows.h to not define min() and max() as macros + add_definitions(-DNOMINMAX) +endif (MSVC) + # Qt find_package ( Qt4 COMPONENTS QtCore QtGui QtMain ) include (${QT_USE_FILE}) @@ -28,17 +33,17 @@ set( QOBJECT_HEADERS cafPdmUiTableView.h cafPdmUiTableViewDelegate.h cafPdmUiTableViewEditor.h - cafPdmUiTableViewModel.h + cafPdmUiTableViewQModel.h cafPdmUiTextEditor.h cafPdmUiToolButtonEditor.h cafPdmUiTreeView.h - cafPdmUiTreeViewModel.h + cafPdmUiTreeViewQModel.h cafPdmUiTreeViewEditor.h cafUiProcess.h QMinimizePanel.h cafPdmUiTreeSelectionEditor.h cafPdmUiTreeSelectionQModel.h - cafPdmUiWidgetBasedObjectEditor.h + cafPdmUiFormLayoutObjectEditor.h cafPdmUiDoubleValueEditor.h ) @@ -95,16 +100,16 @@ set( PROJECT_FILES cafPdmUiListView.h cafPdmUiListViewEditor.cpp cafPdmUiListViewEditor.h - cafPdmUiTableItemEditor.cpp - cafPdmUiTableItemEditor.h + cafPdmUiTableRowEditor.cpp + cafPdmUiTableRowEditor.h cafPdmUiTableView.cpp cafPdmUiTableView.h cafPdmUiTableViewDelegate.cpp cafPdmUiTableViewDelegate.h cafPdmUiTableViewEditor.cpp cafPdmUiTableViewEditor.h - cafPdmUiTableViewModel.cpp - cafPdmUiTableViewModel.h + cafPdmUiTableViewQModel.cpp + cafPdmUiTableViewQModel.h cafPdmUiTreeEditorHandle.cpp cafPdmUiTreeEditorHandle.h cafPdmUiTreeItemEditor.cpp @@ -113,14 +118,14 @@ set( PROJECT_FILES cafPdmUiTreeView.h cafPdmUiTreeViewEditor.cpp cafPdmUiTreeViewEditor.h - cafPdmUiTreeViewModel.cpp - cafPdmUiTreeViewModel.h + cafPdmUiTreeViewQModel.cpp + cafPdmUiTreeViewQModel.h cafPdmUiPropertyView.cpp cafPdmUiPropertyView.h cafPdmUiPropertyViewDialog.cpp cafPdmUiPropertyViewDialog.h - cafPdmUiWidgetBasedObjectEditor.cpp - cafPdmUiWidgetBasedObjectEditor.h + cafPdmUiFormLayoutObjectEditor.cpp + cafPdmUiFormLayoutObjectEditor.h cafPdmUiDoubleValueEditor.cpp cafPdmUiDoubleValueEditor.h @@ -136,6 +141,8 @@ set( PROJECT_FILES QMinimizePanel.h cafQTreeViewStateSerializer.h cafQTreeViewStateSerializer.cpp + cafMemoryInspector.h + cafMemoryInspector.cpp ) add_library( ${PROJECT_NAME} @@ -145,6 +152,10 @@ add_library( ${PROJECT_NAME} ${MOC_FILES_CPP} ) +if (MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/W4 /wd4100 /wd4127") +endif() + target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp index 8d1e3ae90a..ca69397c82 100644 --- a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp +++ b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.cpp @@ -34,6 +34,8 @@ // //################################################################################################## +#pragma warning( disable : 4125 ) + #include "QMinimizePanel.h" #include @@ -42,6 +44,10 @@ #include #include #include +#include +#include + +#include //-------------------------------------------------------------------------------------------------- /// @@ -117,6 +123,7 @@ static const QIcon& expandUpIcon() /// //-------------------------------------------------------------------------------------------------- QMinimizePanel::QMinimizePanel(QWidget* parent/*=0*/) + : QWidget(parent) { this->initialize(""); } @@ -125,6 +132,7 @@ QMinimizePanel::QMinimizePanel(QWidget* parent/*=0*/) /// //-------------------------------------------------------------------------------------------------- QMinimizePanel::QMinimizePanel(const QString &title, QWidget* parent/*=0*/) + : QWidget(parent) { this->initialize(title); } @@ -132,53 +140,17 @@ QMinimizePanel::QMinimizePanel(const QString &title, QWidget* parent/*=0*/) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void QMinimizePanel::initialize(const QString &title) +QMinimizePanel::~QMinimizePanel() { - m_titleFrame = new QFrame(this); - m_titleFrame->setFrameStyle(QFrame::Box | QFrame::Plain); - m_titleFrame->setAutoFillBackground(true); - - m_titleLabel = new QLabel(title, m_titleFrame); - QPalette titleLabelPalette = m_titleLabel->palette(); - titleLabelPalette.setBrush(QPalette::Foreground, titleLabelPalette.windowText()); - - { - QLinearGradient titleGrad(QPointF(0, 0), QPointF(0, 1)); - titleGrad.setCoordinateMode(QGradient::StretchToDeviceMode); - titleGrad.setColorAt(0, QColor(255, 255, 255, 20)); - titleGrad.setColorAt(1, QColor(0, 0, 0, 30)); - - QPalette titleFramePalette = m_titleFrame->palette(); - titleFramePalette.setBrush(QPalette::Window, titleGrad); - titleFramePalette.setBrush(QPalette::Foreground, titleFramePalette.dark()); - m_titleFrame->setPalette(titleFramePalette); - } - - m_titleLabel->setPalette(titleLabelPalette); - - m_collapseButton = new QPushButton( m_titleFrame); - m_collapseButton->setFlat(true); - m_collapseButton->setIcon(expandUpIcon()); - m_collapseButton->setDefault(false); - m_collapseButton->setAutoDefault(false); - m_contentFrame = new QFrame(this); - m_contentFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); - m_contentFrame->setAutoFillBackground(true); - - QPalette contentFramePalette = m_contentFrame->palette(); - contentFramePalette.setBrush(QPalette::Window, QColor(255,250,250,85)); - m_contentFrame->setPalette(contentFramePalette); - - connect(m_collapseButton, SIGNAL(clicked()),this, SLOT(toggleExpanded()) ); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QMinimizePanel::~QMinimizePanel() +QFrame* QMinimizePanel::contentFrame() { - + return m_contentFrame; } //-------------------------------------------------------------------------------------------------- @@ -198,26 +170,48 @@ QString QMinimizePanel::title() const } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QSize QMinimizePanel::sizeHint() const +void QMinimizePanel::enableFrame(bool showFrame) { - QSize labelSize = m_titleLabel->sizeHint(); - QSize titleBarHint = labelSize + QSize(4 + labelSize.height() + 8 - 2 + 1, 8); - - if (!m_contentFrame->isHidden()) + if (showFrame) { - QSize titleBarMin(0, labelSize.height() + 8); - QSize contentsMin(m_contentFrame->sizeHint()); - QSize total = contentsMin.expandedTo(titleBarMin); - total.rheight() += titleBarMin.height(); - - return total; + m_titleFrame->show(); + m_titleLabel->show(); + m_collapseButton->show(); + m_contentFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); + m_contentFrame->setPalette(m_contentPalette); + m_contentFrame->setAttribute(Qt::WA_SetPalette, true); } else { - return titleBarHint; + m_titleFrame->hide(); + m_titleLabel->hide(); + m_collapseButton->hide(); + m_contentFrame->setFrameStyle(QFrame::NoFrame); + if (parentWidget()) + { + m_contentFrame->setPalette(parentWidget()->palette()); + } + m_contentFrame->setAttribute(Qt::WA_SetPalette, false); } + QWidget::update(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize QMinimizePanel::minimumSizeHint() const +{ + return calculateSizeHint(true); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize QMinimizePanel::sizeHint() const +{ + return calculateSizeHint(false); } //-------------------------------------------------------------------------------------------------- @@ -242,29 +236,6 @@ void QMinimizePanel::toggleExpanded() setExpanded(m_contentFrame->isHidden()); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QSize QMinimizePanel::minimumSizeHint() const -{ - QSize labelSize = m_titleLabel->sizeHint(); - QSize titleBarHint = labelSize + QSize(4 + labelSize.height() + 8 - 2 + 1, 8); - - if (!m_contentFrame->isHidden()) - { - QSize titleBarMin(0, labelSize.height() + 8 ); - QSize contentsMin(m_contentFrame->minimumSizeHint()); - QSize total = contentsMin.expandedTo(titleBarMin); - total.rheight() += titleBarMin.height(); - - return total; - } - else - { - return titleBarHint; - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -275,15 +246,20 @@ void QMinimizePanel::resizeEvent(QResizeEvent *resizeEv ) int width = resizeEv->size().width(); int heigth = resizeEv->size().height(); int labelHeight = m_titleLabel->sizeHint().height(); + int titleHeight = labelHeight + 8; - int buttonSize = titleHeight - 2; - m_titleFrame->setGeometry(0,0,width, titleHeight); - m_titleLabel->setGeometry( 4, titleHeight - labelHeight - 4, width - 4 - buttonSize - 1, labelHeight); - m_collapseButton->setGeometry(width - buttonSize - 1, 1, buttonSize, buttonSize); - - m_contentFrame->setGeometry(0, titleHeight-1, width, heigth - (titleHeight-1)); + int contentHeightOffset = 0; + if (!m_titleFrame->isHidden()) + { + m_titleFrame->setGeometry(0, 0, width, titleHeight); + m_titleLabel->setGeometry(4, titleHeight - labelHeight - 4, width - 4 - buttonSize - 1, labelHeight); + m_collapseButton->setGeometry(width - buttonSize - 1, 1, buttonSize, buttonSize); + contentHeightOffset = titleHeight - 1; + } + + m_contentFrame->setGeometry(0, contentHeightOffset, width, heigth - contentHeightOffset); } //-------------------------------------------------------------------------------------------------- @@ -298,3 +274,78 @@ bool QMinimizePanel::event(QEvent* event) return this->QWidget::event(event); } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void QMinimizePanel::initialize(const QString &title) +{ + m_titleFrame = new QFrame(this); + m_titleFrame->setFrameStyle(QFrame::Box | QFrame::Plain); + m_titleFrame->setAutoFillBackground(true); + + m_titleLabel = new QLabel(title, m_titleFrame); + QPalette titleLabelPalette = m_titleLabel->palette(); + titleLabelPalette.setBrush(QPalette::Foreground, titleLabelPalette.windowText()); + + { + QLinearGradient titleGrad(QPointF(0, 0), QPointF(0, 1)); + titleGrad.setCoordinateMode(QGradient::StretchToDeviceMode); + titleGrad.setColorAt(0, QColor(255, 255, 255, 20)); + titleGrad.setColorAt(1, QColor(0, 0, 0, 30)); + + QPalette titleFramePalette = m_titleFrame->palette(); + titleFramePalette.setBrush(QPalette::Window, titleGrad); + titleFramePalette.setBrush(QPalette::Foreground, titleFramePalette.dark()); + m_titleFrame->setPalette(titleFramePalette); + } + + m_titleLabel->setPalette(titleLabelPalette); + + m_collapseButton = new QPushButton(m_titleFrame); + m_collapseButton->setFlat(true); + m_collapseButton->setIcon(expandUpIcon()); + m_collapseButton->setDefault(false); + m_collapseButton->setAutoDefault(false); + + m_contentFrame = new QFrame(this); + m_contentFrame->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); + m_contentFrame->setAutoFillBackground(true); + + m_contentPalette = m_contentFrame->palette(); + m_contentPalette.setBrush(QPalette::Window, QColor(255, 250, 250, 85)); + m_contentFrame->setPalette(m_contentPalette); + + connect(m_collapseButton, SIGNAL(clicked()), this, SLOT(toggleExpanded())); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize QMinimizePanel::calculateSizeHint(bool minimumSizeHint) const +{ + QSize labelSize = m_titleLabel->sizeHint(); + QSize titleBarHint = labelSize + QSize(4 + labelSize.height() + 8 - 2 + 1, 8); + if (!m_contentFrame->isHidden()) + { + int titleHeight = 0; + if (!m_titleFrame->isHidden()) + { + titleHeight = labelSize.height() + 8; + } + + QSize titleBarMin(0, titleHeight); + QSize contentsMin(minimumSizeHint ? m_contentFrame->minimumSizeHint() : m_contentFrame->sizeHint()); + QSize total = contentsMin.expandedTo(titleBarMin); + total.rheight() += titleBarMin.height(); + + return total; + } + else + { + // Retain width when collapsing the field + QSize contentsMin(minimumSizeHint ? m_contentFrame->minimumSizeHint() : m_contentFrame->sizeHint()); + titleBarHint.rwidth() = std::max(titleBarHint.width(), contentsMin.width()); + return titleBarHint; + } +} diff --git a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h index 670ffbb7c1..697e9b9008 100644 --- a/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h +++ b/Fwk/AppFwk/cafUserInterface/QMinimizePanel.h @@ -40,6 +40,7 @@ class QFrame; class QLabel; +class QPalette; class QPushButton; //================================================================================================== @@ -53,33 +54,37 @@ class QMinimizePanel : public QWidget public: explicit QMinimizePanel(QWidget* parent=nullptr); explicit QMinimizePanel(const QString &title, QWidget* parent=nullptr); - ~QMinimizePanel(); + ~QMinimizePanel() override; - QFrame* contentFrame() { return m_contentFrame; } - void setTitle (const QString& title); - QString title() const; + QFrame* contentFrame(); + void setTitle (const QString& title); + QString title() const; + void enableFrame(bool showFrame); - virtual QSize sizeHint() const override; + QSize minimumSizeHint() const override; + QSize sizeHint() const override; public slots: - void setExpanded(bool isExpanded); - void toggleExpanded(); + void setExpanded(bool isExpanded); + void toggleExpanded(); signals: - void expandedChanged(bool isExpanded); + void expandedChanged(bool isExpanded); public: - virtual QSize minimumSizeHint() const override; protected: + QFrame* m_titleFrame; QLabel* m_titleLabel; QPushButton* m_collapseButton; QFrame* m_contentFrame; + QPalette m_contentPalette; - virtual void resizeEvent(QResizeEvent *) override; - virtual bool event(QEvent* event) override; // To catch QEvent::LayoutRequest + void resizeEvent(QResizeEvent *) override; + bool event(QEvent* event) override; // To catch QEvent::LayoutRequest private: - void initialize(const QString &title); + void initialize(const QString &title); + QSize calculateSizeHint(bool minimumSizeHint) const; }; diff --git a/Fwk/AppFwk/cafUserInterface/cafMemoryInspector.cpp b/Fwk/AppFwk/cafUserInterface/cafMemoryInspector.cpp new file mode 100644 index 0000000000..85e9128111 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafMemoryInspector.cpp @@ -0,0 +1,157 @@ +#include "cafMemoryInspector.h" + +#include +#include +#include +#include + +#ifdef _WIN32 +#include "windows.h" +#include "psapi.h" +#elif defined (__linux__) +#include +#include +#include "sys/types.h" +#include "sys/sysinfo.h" +#endif + +#define MIB_DIV 1048576 + +#ifdef __linux__ +//-------------------------------------------------------------------------------------------------- +/// Read bytes of memory of different types for current process from /proc/self/statm +/// See: http://man7.org/linux/man-pages/man5/proc.5.html +/// The first three columns in statm are: +/// * VmSize: size of virtual memory +/// * RSS: resident memory size of process +/// * Shared: shared memory used by process +//-------------------------------------------------------------------------------------------------- +std::map readProcessBytesLinux() +{ + std::map quantities; + int pageSize = getpagesize(); + QFile procSelfStatus("/proc/self/statm"); + if (procSelfStatus.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QString line(procSelfStatus.readLine(256)); + QStringList lineWords = line.split(QRegExp("\\s+"), QString::SkipEmptyParts); + quantities["VmSize"] = static_cast(lineWords[0].toLongLong() * pageSize); + quantities["RSS"] = static_cast(lineWords[1].toLongLong() * pageSize); + quantities["Shared"] = static_cast(lineWords[2].toLongLong() * pageSize); + } + return quantities; +} +#endif +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +uint64_t caf::MemoryInspector::getApplicationPhysicalMemoryUsageMiB() +{ +#ifdef _WIN32 + PROCESS_MEMORY_COUNTERS_EX pmc; + GetProcessMemoryInfo(GetCurrentProcess(), (PPROCESS_MEMORY_COUNTERS) &pmc, sizeof(pmc)); + SIZE_T physicalMemUsedByMe = pmc.WorkingSetSize; + return static_cast(physicalMemUsedByMe / MIB_DIV); +#elif defined(__linux__) + return readProcessBytesLinux()["RSS"] / MIB_DIV; +#else + return 0u; +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +uint64_t caf::MemoryInspector::getApplicationVirtualMemoryUsageMiB() +{ +#ifdef _WIN32 + PROCESS_MEMORY_COUNTERS_EX pmc; + GetProcessMemoryInfo(GetCurrentProcess(), (PPROCESS_MEMORY_COUNTERS)&pmc, sizeof(pmc)); + SIZE_T virtualMemUsedByMe = pmc.PrivateUsage; + return static_cast(virtualMemUsedByMe / MIB_DIV); +#elif defined(__linux__) + return readProcessBytesLinux()["VmSize"] / MIB_DIV; +#else + return 0u; +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +uint64_t caf::MemoryInspector::getTotalVirtualMemoryMiB() +{ +#ifdef _WIN32 + MEMORYSTATUSEX memInfo; + memInfo.dwLength = sizeof(MEMORYSTATUSEX); + GlobalMemoryStatusEx(&memInfo); + DWORDLONG totalVirtualMem = memInfo.ullTotalPageFile; + return static_cast (totalVirtualMem / MIB_DIV); +#elif defined(__linux__) + struct sysinfo memInfo; + sysinfo(&memInfo); + long long totalVirtualMem = memInfo.totalram; + totalVirtualMem += memInfo.totalswap; + totalVirtualMem *= memInfo.mem_unit; + return totalVirtualMem / MIB_DIV; +#else + return 0u; +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +uint64_t caf::MemoryInspector::getTotalPhysicalMemoryMiB() +{ +#ifdef _WIN32 + MEMORYSTATUSEX memInfo; + memInfo.dwLength = sizeof(MEMORYSTATUSEX); + GlobalMemoryStatusEx(&memInfo); + DWORDLONG totalPhysMem = memInfo.ullTotalPhys; + return static_cast(totalPhysMem / MIB_DIV); +#elif defined(__linux__) + struct sysinfo memInfo; + sysinfo(&memInfo); + long long totalPhysicalMem = memInfo.totalram; + totalPhysicalMem *= memInfo.mem_unit; + return totalPhysicalMem / MIB_DIV; +#else + return 0u; +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +uint64_t caf::MemoryInspector::getAvailableVirtualMemoryMiB() +{ +#ifdef _WIN32 + MEMORYSTATUSEX memInfo; + memInfo.dwLength = sizeof(MEMORYSTATUSEX); + GlobalMemoryStatusEx(&memInfo); + DWORDLONG availVirtualMem = memInfo.ullAvailPageFile; + return static_cast (availVirtualMem / MIB_DIV); +#elif defined(__linux__) + struct sysinfo memInfo; + sysinfo(&memInfo); + long long availVirtualMem = memInfo.freeram; + availVirtualMem += memInfo.freeswap; + availVirtualMem *= memInfo.mem_unit; + return availVirtualMem / MIB_DIV; +#else + return 0u; +#endif +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +float caf::MemoryInspector::getRemainingMemoryCriticalThresholdFraction() +{ +#ifdef __linux__ + return 0.175f; +#else + return 0.05f; +#endif +} diff --git a/Fwk/AppFwk/cafUserInterface/cafMemoryInspector.h b/Fwk/AppFwk/cafUserInterface/cafMemoryInspector.h new file mode 100644 index 0000000000..d7c3fad5f8 --- /dev/null +++ b/Fwk/AppFwk/cafUserInterface/cafMemoryInspector.h @@ -0,0 +1,52 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) 2018- Ceetron AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#pragma once + +#include + +namespace caf +{ + namespace MemoryInspector + { + uint64_t getApplicationPhysicalMemoryUsageMiB(); + uint64_t getApplicationVirtualMemoryUsageMiB(); + uint64_t getTotalVirtualMemoryMiB(); + uint64_t getTotalPhysicalMemoryMiB(); + uint64_t getAvailableVirtualMemoryMiB(); + float getRemainingMemoryCriticalThresholdFraction(); + } +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.cpp index 89448602fa..ef26af9228 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.cpp @@ -59,6 +59,23 @@ PdmUiCheckBoxDelegate::~PdmUiCheckBoxDelegate() { } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QRect adjustedPaintRect(const QStyleOptionViewItem &option) +{ + const int margin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; + + QRect newRect = QStyle::alignedRect(option.direction, + Qt::AlignCenter, + QSize(option.decorationSize.width() + margin, option.rect.height()), + QRect(option.rect.x(), + option.rect.y(), + option.rect.width(), + option.rect.height())); + + return newRect; +} //-------------------------------------------------------------------------------------------------- /// @@ -66,13 +83,8 @@ PdmUiCheckBoxDelegate::~PdmUiCheckBoxDelegate() void PdmUiCheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItemV4 viewItemOption(option); - - const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; - QRect newRect = QStyle::alignedRect(option.direction, Qt::AlignCenter, - QSize(option.decorationSize.width() + 5,option.decorationSize.height()), - QRect(option.rect.x() + textMargin, option.rect.y(), - option.rect.width() - (2 * textMargin), option.rect.height())); - viewItemOption.rect = newRect; + + viewItemOption.rect = adjustedPaintRect(option); QStyledItemDelegate::paint(painter, viewItemOption, index); } @@ -81,7 +93,9 @@ void PdmUiCheckBoxDelegate::paint(QPainter *painter, const QStyleOptionViewItem //-------------------------------------------------------------------------------------------------- /// Returns true to avoid other factories to produce editors for a check box //-------------------------------------------------------------------------------------------------- -bool PdmUiCheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) +bool PdmUiCheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index) { Q_ASSERT(event); Q_ASSERT(model); @@ -99,13 +113,13 @@ bool PdmUiCheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model // make sure that we have the right event type if (event->type() == QEvent::MouseButtonRelease) { - const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; - QRect checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter, - option.decorationSize, - QRect(option.rect.x() + (2 * textMargin), option.rect.y(), - option.rect.width() - (2 * textMargin), - option.rect.height())); - + QRect paintRect = adjustedPaintRect(option); + QRect checkRect = QStyle::alignedRect(option.direction, + Qt::AlignCenter, + option.decorationSize, + paintRect); + + if (!checkRect.contains(static_cast(event)->pos())) return true; } @@ -116,13 +130,20 @@ bool PdmUiCheckBoxDelegate::editorEvent(QEvent *event, QAbstractItemModel *model } else { - return true; + return false; } Qt::CheckState state = (static_cast(value.toInt()) == Qt::Checked ? Qt::Unchecked : Qt::Checked); return model->setData(index, state, Qt::CheckStateRole); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QSize PdmUiCheckBoxDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + return QSize(option.decorationSize.width(), option.decorationSize.height()); +} } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.h index b13b8a0bfe..2a19dcf3a6 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxDelegate.h @@ -53,10 +53,13 @@ class PdmUiCheckBoxDelegate : public QStyledItemDelegate public: explicit PdmUiCheckBoxDelegate( QObject* pParent = nullptr ); - virtual ~PdmUiCheckBoxDelegate(); + ~PdmUiCheckBoxDelegate() override; + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override; + + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; - virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - virtual bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index); }; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp index 3db9a7ac74..2d8f6c493e 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.cpp @@ -34,28 +34,23 @@ // //################################################################################################## - #include "cafPdmUiCheckBoxEditor.h" #include "cafPdmUiDefaultObjectEditor.h" +#include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmUiFieldEditorHandle.h" #include "cafPdmUiOrdering.h" -#include "cafPdmField.h" #include "cafFactory.h" - - namespace caf { - CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiCheckBoxEditor); - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void PdmUiCheckBoxEditor::configureAndUpdateUi(const QString& uiConfigName) { @@ -63,35 +58,34 @@ void PdmUiCheckBoxEditor::configureAndUpdateUi(const QString& uiConfigName) CAF_ASSERT(!m_label.isNull()); PdmUiCheckBoxEditorAttribute attributes; - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &attributes); } if (attributes.m_useNativeCheckBoxLabel) { - m_checkBox->setText(field()->uiName(uiConfigName)); + m_checkBox->setText(uiField()->uiName(uiConfigName)); - m_label->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_label->setToolTip(field()->uiToolTip(uiConfigName)); + m_label->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); + m_label->setToolTip(uiField()->uiToolTip(uiConfigName)); } else { - PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); + PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); } - m_checkBox->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_checkBox->setToolTip(field()->uiToolTip(uiConfigName)); + m_checkBox->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); + m_checkBox->setToolTip(uiField()->uiToolTip(uiConfigName)); - m_checkBox->setChecked(field()->uiValue().toBool()); + m_checkBox->setChecked(uiField()->uiValue().toBool()); } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QWidget* PdmUiCheckBoxEditor::createEditorWidget(QWidget * parent) +QWidget* PdmUiCheckBoxEditor::createEditorWidget(QWidget* parent) { m_checkBox = new QCheckBox(parent); connect(m_checkBox, SIGNAL(clicked(bool)), this, SLOT(slotClicked(bool))); @@ -99,16 +93,16 @@ QWidget* PdmUiCheckBoxEditor::createEditorWidget(QWidget * parent) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QWidget* PdmUiCheckBoxEditor::createLabelWidget(QWidget * parent) +QWidget* PdmUiCheckBoxEditor::createLabelWidget(QWidget* parent) { m_label = new QLabel(parent); return m_label; } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- void PdmUiCheckBoxEditor::slotClicked(bool checked) { @@ -117,5 +111,4 @@ void PdmUiCheckBoxEditor::slotClicked(bool checked) this->setValueToField(v); } - } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.h index bf67da9809..508b3fcca5 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxEditor.h @@ -70,12 +70,12 @@ class PdmUiCheckBoxEditor : public PdmUiFieldEditorHandle public: PdmUiCheckBoxEditor() {} - virtual ~PdmUiCheckBoxEditor() {} + ~PdmUiCheckBoxEditor() override {} protected: - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; protected slots: void slotClicked(bool checked); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxTristateEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxTristateEditor.cpp index 5a4c898451..428f461646 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxTristateEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxTristateEditor.cpp @@ -30,10 +30,10 @@ void PdmUiCheckBoxTristateEditor::configureAndUpdateUi(const QString& uiConfigNa PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); - m_checkBox->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_checkBox->setToolTip(field()->uiToolTip(uiConfigName)); + m_checkBox->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); + m_checkBox->setToolTip(uiField()->uiToolTip(uiConfigName)); - Tristate state = field()->uiValue().value(); + Tristate state = uiField()->uiValue().value(); if (state == Tristate::State::True) { diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxTristateEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxTristateEditor.h index e372c1bde4..6c340ab223 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxTristateEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiCheckBoxTristateEditor.h @@ -19,12 +19,12 @@ class PdmUiCheckBoxTristateEditor : public PdmUiFieldEditorHandle public: PdmUiCheckBoxTristateEditor() {} - virtual ~PdmUiCheckBoxTristateEditor() {} + ~PdmUiCheckBoxTristateEditor() override {} protected: - virtual QWidget* createEditorWidget(QWidget* parent); - virtual QWidget* createLabelWidget(QWidget* parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget* parent) override; + QWidget* createLabelWidget(QWidget* parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; protected slots: void slotClicked(bool); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.cpp index f55319deca..287a3bd3f9 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.cpp @@ -76,14 +76,14 @@ void PdmUiColorEditor::configureAndUpdateUi(const QString& uiConfigName) PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &m_attributes); } - QColor col = field()->uiValue().value(); - setColor(col); + QColor col = uiField()->uiValue().value(); + setColorOnWidget(col); } //-------------------------------------------------------------------------------------------------- @@ -137,14 +137,17 @@ void PdmUiColorEditor::colorSelectionClicked() QColor newColor = QColorDialog::getColor(m_color, m_colorPixmapLabel, "Select color", flags); if (newColor.isValid() && newColor != m_color) { - setColor(newColor); + setColorOnWidget(newColor); + QVariant v; + v = newColor; + this->setValueToField(v); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiColorEditor::setColor(const QColor& color) +void PdmUiColorEditor::setColorOnWidget(const QColor& color) { if (m_color != color) { @@ -172,9 +175,6 @@ void PdmUiColorEditor::setColor(const QColor& color) m_colorTextLabel->setText(colorString); } - QVariant v; - v = m_color; - this->setValueToField(v); } diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.h index 32205d4795..ed1168b6dd 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiColorEditor.h @@ -75,18 +75,18 @@ class PdmUiColorEditor : public PdmUiFieldEditorHandle public: PdmUiColorEditor(); - virtual ~PdmUiColorEditor() {} + ~PdmUiColorEditor() override {} protected: - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; protected slots: - void colorSelectionClicked(); + void colorSelectionClicked(); private: - void setColor(const QColor& c); + void setColorOnWidget(const QColor& c); private: QPointer m_label; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.cpp index 02eef60c6e..817fcc7a86 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.cpp @@ -66,18 +66,18 @@ void PdmUiComboBoxEditor::configureAndUpdateUi(const QString& uiConfigName) // Handle attributes PdmUiComboBoxEditorAttribute attributes; - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &attributes); } if (!m_comboBox.isNull()) { - m_comboBox->setEnabled(!field()->isUiReadOnly(uiConfigName)); + m_comboBox->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); bool fromMenuOnly = true; - QList options = field()->valueOptions(&fromMenuOnly); + QList options = uiField()->valueOptions(&fromMenuOnly); CAF_ASSERT(fromMenuOnly); // Not supported m_comboBox->blockSignals(true); @@ -88,11 +88,11 @@ void PdmUiComboBoxEditor::configureAndUpdateUi(const QString& uiConfigName) { m_comboBox->addItem(options[i].icon(), options[i].optionUiText()); } - m_comboBox->setCurrentIndex(field()->uiValue().toInt()); + m_comboBox->setCurrentIndex(uiField()->uiValue().toInt()); } else { - m_comboBox->addItem(field()->uiValue().toString()); + m_comboBox->addItem(uiField()->uiValue().toString()); m_comboBox->setCurrentIndex(0); } @@ -104,72 +104,93 @@ void PdmUiComboBoxEditor::configureAndUpdateUi(const QString& uiConfigName) m_comboBox->blockSignals(false); } - if (attributes.showPreviousAndNextButtons) + if (!m_layout.isNull()) { - if (m_previousItemButton.isNull()) + if (attributes.showPreviousAndNextButtons) { - m_previousItemButton = new QToolButton(m_placeholder); - connect(m_previousItemButton, SIGNAL(clicked()), this, SLOT(slotPreviousButtonPressed())); + if (m_previousItemButton.isNull()) + { + m_previousItemButton = new QToolButton(m_placeholder); + connect(m_previousItemButton, SIGNAL(clicked()), this, SLOT(slotPreviousButtonPressed())); - m_previousItemButton->setToolTip("Previous"); - } + m_previousItemButton->setToolTip("Previous"); + } - if (m_nextItemButton.isNull()) - { - m_nextItemButton = new QToolButton(m_placeholder); - connect(m_nextItemButton, SIGNAL(clicked()), this, SLOT(slotNextButtonPressed())); + if (m_nextItemButton.isNull()) + { + m_nextItemButton = new QToolButton(m_placeholder); + connect(m_nextItemButton, SIGNAL(clicked()), this, SLOT(slotNextButtonPressed())); - m_nextItemButton->setToolTip("Next"); - } + m_nextItemButton->setToolTip("Next"); + } - m_layout->insertWidget(1, m_previousItemButton); - m_layout->insertWidget(2, m_nextItemButton); + m_layout->insertWidget(1, m_previousItemButton); + m_layout->insertWidget(2, m_nextItemButton); - if (m_comboBox->count() == 0 || m_comboBox->currentIndex() <= 0) - { - QIcon disabledIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowUp).pixmap(16, 16, QIcon::Disabled)); - m_previousItemButton->setIcon(disabledIcon); - } - else - { - m_previousItemButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowUp)); - } + if (m_comboBox->count() == 0 || m_comboBox->currentIndex() <= 0) + { + QIcon disabledIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowUp).pixmap(16, 16, QIcon::Disabled)); + m_previousItemButton->setIcon(disabledIcon); + } + else + { + m_previousItemButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowUp)); + } - if (m_comboBox->count() == 0 || m_comboBox->currentIndex() >= m_comboBox->count() - 1) - { - QIcon disabledIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowDown).pixmap(16, 16, QIcon::Disabled)); - m_nextItemButton->setIcon(disabledIcon); + if (m_comboBox->count() == 0 || m_comboBox->currentIndex() >= m_comboBox->count() - 1) + { + QIcon disabledIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowDown).pixmap(16, 16, QIcon::Disabled)); + m_nextItemButton->setIcon(disabledIcon); + } + else + { + m_nextItemButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowDown)); + } + + // Update button texts + if (!attributes.nextButtonText.isEmpty()) + { + m_nextItemButton->setToolTip(attributes.nextButtonText); + } + + if (!attributes.prevButtonText.isEmpty()) + { + m_previousItemButton->setToolTip(attributes.prevButtonText); + } } else { - m_nextItemButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_ArrowDown)); - } - - // Update button texts - if (!attributes.nextButtonText.isEmpty()) - { - m_nextItemButton->setToolTip(attributes.nextButtonText); - } + if (m_previousItemButton) + { + m_layout->removeWidget(m_previousItemButton); + m_previousItemButton->deleteLater(); + } - if (!attributes.prevButtonText.isEmpty()) - { - m_previousItemButton->setToolTip(attributes.prevButtonText); + if (m_nextItemButton) + { + m_layout->removeWidget(m_nextItemButton); + m_nextItemButton->deleteLater(); + } } } - else - { - if (m_previousItemButton) - { - m_layout->removeWidget(m_previousItemButton); - m_previousItemButton->deleteLater(); - } +} - if (m_nextItemButton) - { - m_layout->removeWidget(m_nextItemButton); - m_nextItemButton->deleteLater(); - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QMargins PdmUiComboBoxEditor::calculateLabelContentMargins() const +{ + QSize editorSize = m_comboBox->sizeHint(); + QSize labelSize = m_label->sizeHint(); + int heightDiff = editorSize.height() - labelSize.height(); + + QMargins contentMargins = m_label->contentsMargins(); + if (heightDiff > 0) + { + contentMargins.setTop(contentMargins.top() + heightDiff / 2); + contentMargins.setBottom(contentMargins.bottom() + heightDiff / 2); } + return contentMargins; } //-------------------------------------------------------------------------------------------------- @@ -189,7 +210,7 @@ class CustomQComboBox : public QComboBox //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - void wheelEvent(QWheelEvent *e) + void wheelEvent(QWheelEvent *e) override { if (hasFocus()) { @@ -206,7 +227,7 @@ class CustomQComboBox : public QComboBox //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void focusInEvent(QFocusEvent* e) override + void focusInEvent(QFocusEvent* e) override { setFocusPolicy(Qt::WheelFocus); QComboBox::focusInEvent(e); @@ -215,7 +236,7 @@ class CustomQComboBox : public QComboBox //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void focusOutEvent(QFocusEvent* e) override + void focusOutEvent(QFocusEvent* e) override { setFocusPolicy(Qt::StrongFocus); QComboBox::focusOutEvent(e); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.h index 485f16a00a..addd35e0d7 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiComboBoxEditor.h @@ -81,18 +81,19 @@ class PdmUiComboBoxEditor : public PdmUiFieldEditorHandle public: PdmUiComboBoxEditor() {} - virtual ~PdmUiComboBoxEditor() {} + ~PdmUiComboBoxEditor() override {} protected: - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; + QMargins calculateLabelContentMargins() const override; protected slots: - void slotIndexActivated(int index); + void slotIndexActivated(int index); - void slotNextButtonPressed(); - void slotPreviousButtonPressed(); + void slotNextButtonPressed(); + void slotPreviousButtonPressed(); private: QPointer m_comboBox; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDateEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiDateEditor.cpp index e7489a265f..1684341c47 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDateEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDateEditor.cpp @@ -73,12 +73,12 @@ void PdmUiDateEditor::configureAndUpdateUi(const QString& uiConfigName) PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); - m_dateEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); + m_dateEdit->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &m_attributes); } if (!m_attributes.dateFormat.isEmpty()) @@ -86,7 +86,7 @@ void PdmUiDateEditor::configureAndUpdateUi(const QString& uiConfigName) m_dateEdit->setDisplayFormat(m_attributes.dateFormat); } - m_dateEdit->setDate(field()->uiValue().toDate()); + m_dateEdit->setDate(uiField()->uiValue().toDate()); } diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDateEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiDateEditor.h index e4c3c16337..f3dcd4b7ca 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDateEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDateEditor.h @@ -72,12 +72,12 @@ class PdmUiDateEditor : public PdmUiFieldEditorHandle public: PdmUiDateEditor() {} - virtual ~PdmUiDateEditor() {} + ~PdmUiDateEditor() override {} protected: - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; protected slots: void slotEditingFinished(); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp index fb0916eede..620856af61 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.cpp @@ -101,11 +101,11 @@ QWidget* PdmUiDefaultObjectEditor::createWidget(QWidget* parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiDefaultObjectEditor::recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, const QString& uiConfigName) +void PdmUiDefaultObjectEditor::recursivelyConfigureAndUpdateTopLevelUiOrdering(const PdmUiOrdering& topLevelUiOrdering, const QString& uiConfigName) { CAF_ASSERT(this->widget()); - recursivelyConfigureAndUpdateUiItemsInGridLayoutColumn(topLevelUiItems, this->widget(), uiConfigName); + recursivelyConfigureAndUpdateUiOrderingInGridLayoutColumn(topLevelUiOrdering, this->widget(), uiConfigName); } } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.h index 029c24c851..e9f2aeb5b3 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDefaultObjectEditor.h @@ -37,7 +37,7 @@ #pragma once -#include "cafPdmUiWidgetBasedObjectEditor.h" +#include "cafPdmUiFormLayoutObjectEditor.h" #include @@ -55,17 +55,17 @@ class PdmUiGroup; //================================================================================================== /// The default editor for PdmObjects. Manages the field editors in a grid layout vertically //================================================================================================== -class PdmUiDefaultObjectEditor : public PdmUiWidgetBasedObjectEditor +class PdmUiDefaultObjectEditor : public PdmUiFormLayoutObjectEditor { Q_OBJECT public: PdmUiDefaultObjectEditor(); - ~PdmUiDefaultObjectEditor(); + ~PdmUiDefaultObjectEditor() override; private: - virtual QWidget* createWidget(QWidget* parent) override; - virtual void recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, - const QString& uiConfigName) override; + QWidget* createWidget(QWidget* parent) override; + void recursivelyConfigureAndUpdateTopLevelUiOrdering(const PdmUiOrdering& topLevelUiItems, + const QString& uiConfigName) override; }; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp index 92a06dc0bd..94a8ae79ea 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.cpp @@ -60,14 +60,14 @@ class PdmDoubleValidator : public QDoubleValidator { } - ~PdmDoubleValidator() + ~PdmDoubleValidator() override { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void fixup(QString& stringValue) const override + void fixup(QString& stringValue) const override { double doubleValue = stringValue.toDouble(); doubleValue = qBound(bottom(), doubleValue, top()); @@ -90,17 +90,17 @@ void PdmUiDoubleSliderEditor::configureAndUpdateUi(const QString& uiConfigName) PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); - m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_slider->setEnabled(!field()->isUiReadOnly(uiConfigName)); + m_lineEdit->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); + m_slider->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &m_attributes); } - double doubleValue = field()->uiValue().toDouble(); - QString textValue = field()->uiValue().toString(); + double doubleValue = uiField()->uiValue().toDouble(); + QString textValue = uiField()->uiValue().toString(); m_slider->blockSignals(true); m_slider->setMaximum(m_attributes.m_sliderTickCount); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.h index a616831c9a..f7e102c38e 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleSliderEditor.h @@ -81,23 +81,23 @@ class PdmUiDoubleSliderEditor : public PdmUiFieldEditorHandle public: PdmUiDoubleSliderEditor() {} - virtual ~PdmUiDoubleSliderEditor() {} + ~PdmUiDoubleSliderEditor() override {} protected: - virtual void configureAndUpdateUi(const QString& uiConfigName); - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); + void configureAndUpdateUi(const QString& uiConfigName) override; + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; protected slots: - void slotEditingFinished(); - void slotSliderValueChanged(int value); + void slotEditingFinished(); + void slotSliderValueChanged(int value); private: - void updateSliderPosition(double value); - void writeValueToField(double value); + void updateSliderPosition(double value); + void writeValueToField(double value); - int convertToSliderValue(double value); - double convertFromSliderValue(int sliderValue); + int convertToSliderValue(double value); + double convertFromSliderValue(int sliderValue); private: QPointer m_lineEdit; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleValueEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleValueEditor.cpp index 0ef047576e..d6c3ff589a 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleValueEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleValueEditor.cpp @@ -71,16 +71,16 @@ void PdmUiDoubleValueEditor::configureAndUpdateUi(const QString& uiConfigName) PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); - m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); + m_lineEdit->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &m_attributes); } bool valueOk = false; - double value = field()->uiValue().toDouble(&valueOk); + double value = uiField()->uiValue().toDouble(&valueOk); QString textValue; if (valueOk) { @@ -88,7 +88,7 @@ void PdmUiDoubleValueEditor::configureAndUpdateUi(const QString& uiConfigName) } else { - textValue = field()->uiValue().toString(); + textValue = uiField()->uiValue().toString(); } m_lineEdit->setText(textValue); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleValueEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleValueEditor.h index 3e3747e7bf..3062c34ffb 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleValueEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDoubleValueEditor.h @@ -72,7 +72,7 @@ class PdmUiDoubleValueEditor : public PdmUiFieldEditorHandle public: PdmUiDoubleValueEditor(); - virtual ~PdmUiDoubleValueEditor(); + ~PdmUiDoubleValueEditor() override; protected: void configureAndUpdateUi(const QString& uiConfigName) override; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiDragDropInterface.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiDragDropInterface.h index 20aaa9ab59..eb4ab81b75 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiDragDropInterface.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiDragDropInterface.h @@ -54,7 +54,7 @@ class PdmUiDragDropInterface protected: - friend class PdmUiTreeViewModel; + friend class PdmUiTreeViewQModel; friend class PdmUiTreeViewWidget; // Forwarding from Qt functions in QAbstractItemModel diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.cpp index 57c44b1e42..49c5ddd022 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.cpp @@ -67,16 +67,16 @@ void PdmUiFilePathEditor::configureAndUpdateUi(const QString& uiConfigName) PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); - m_lineEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_lineEdit->setToolTip(field()->uiToolTip(uiConfigName)); + m_lineEdit->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); + m_lineEdit->setToolTip(uiField()->uiToolTip(uiConfigName)); - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &m_attributes); } - m_lineEdit->setText(field()->uiValue().toString()); + m_lineEdit->setText(uiField()->uiValue().toString()); if (m_attributes.m_appendUiSelectedFolderToText) { diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.h index f067ea6f70..986a6ee349 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiFilePathEditor.h @@ -88,16 +88,16 @@ class PdmUiFilePathEditor : public PdmUiFieldEditorHandle public: PdmUiFilePathEditor() {} - virtual ~PdmUiFilePathEditor() {} + ~PdmUiFilePathEditor() override {} protected: - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; protected slots: - void slotEditingFinished(); - void fileSelectionClicked(); + void slotEditingFinished(); + void fileSelectionClicked(); private: QPointer m_lineEdit; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiWidgetBasedObjectEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.cpp similarity index 59% rename from Fwk/AppFwk/cafUserInterface/cafPdmUiWidgetBasedObjectEditor.cpp rename to Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.cpp index 4d725388c4..3d45b3a4f8 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiWidgetBasedObjectEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.cpp @@ -35,7 +35,7 @@ //################################################################################################## -#include "cafPdmUiWidgetBasedObjectEditor.h" +#include "cafPdmUiFormLayoutObjectEditor.h" #include "cafPdmObjectHandle.h" #include "cafPdmUiFieldEditorHandle.h" @@ -45,6 +45,8 @@ #include "cafPdmUiOrdering.h" #include "cafPdmXmlObjectHandle.h" +#include "cafAssert.h" + #include "QMinimizePanel.h" #include @@ -53,7 +55,7 @@ //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmUiWidgetBasedObjectEditor::PdmUiWidgetBasedObjectEditor() +caf::PdmUiFormLayoutObjectEditor::PdmUiFormLayoutObjectEditor() { } @@ -61,7 +63,7 @@ caf::PdmUiWidgetBasedObjectEditor::PdmUiWidgetBasedObjectEditor() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmUiWidgetBasedObjectEditor::~PdmUiWidgetBasedObjectEditor() +caf::PdmUiFormLayoutObjectEditor::~PdmUiFormLayoutObjectEditor() { // If there are field editor present, the usage of this editor has not cleared correctly // The intended usage is to call the method setPdmObject(NULL) before closing the dialog @@ -71,44 +73,75 @@ caf::PdmUiWidgetBasedObjectEditor::~PdmUiWidgetBasedObjectEditor() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void caf::PdmUiWidgetBasedObjectEditor::recursivelyConfigureAndUpdateUiItemsInGridLayoutColumn(const std::vector& uiItems, QWidget* containerWidgetWithGridLayout, const QString& uiConfigName) +void caf::PdmUiFormLayoutObjectEditor::recursivelyConfigureAndUpdateUiOrderingInGridLayoutColumn( + const PdmUiOrdering& uiOrdering, + QWidget* containerWidgetWithGridLayout, + const QString& uiConfigName) { CAF_ASSERT(containerWidgetWithGridLayout); - int currentRowIndex = 0; + int currentRowIndex = -1; QWidget* previousTabOrderWidget = nullptr; // Currently, only QGridLayout is supported - QGridLayout* parentLayout = dynamic_cast(containerWidgetWithGridLayout->layout()); + QGridLayout* parentLayout = dynamic_cast(containerWidgetWithGridLayout->layout()); CAF_ASSERT(parentLayout); + const std::vector& uiItems = uiOrdering.uiItemsWithLayout(); + + int columnsPerRow = uiOrdering.nrOfColumns(); + + int currentColumn = 0; + int itemsInCurrentRow = 1; for (size_t i = 0; i < uiItems.size(); ++i) { - if (uiItems[i]->isUiHidden(uiConfigName)) continue; + PdmUiItem* currentItem = uiItems[i].first; + PdmUiOrdering::LayoutOptions currentLayout = uiItems[i].second; + int itemColumnSpan = currentLayout.totalColumnSpan; - if (uiItems[i]->isUiGroup()) + if (currentRowIndex == -1 || currentLayout.newRow) { - PdmUiGroup* group = static_cast(uiItems[i]); + currentRowIndex++; + parentLayout->setRowStretch(currentRowIndex, 0); + + currentColumn = 0; + itemsInCurrentRow = 1; + for (size_t j = i+1; j < uiItems.size(); ++j) + { + if (uiItems[j].second.newRow) break; + itemsInCurrentRow++; + } + } + + if (itemColumnSpan == PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN) + { + itemColumnSpan = columnsPerRow / itemsInCurrentRow; + } + + if (currentItem->isUiHidden(uiConfigName)) continue; + + if (currentItem->isUiGroup()) + { + PdmUiGroup* group = static_cast(currentItem); QMinimizePanel* groupBox = findOrCreateGroupBox(containerWidgetWithGridLayout, group, uiConfigName); /// Insert the group box at the correct position of the parent layout - parentLayout->addWidget(groupBox, currentRowIndex, 0, 1, 2); + parentLayout->addWidget(groupBox, currentRowIndex, currentColumn, 1, itemColumnSpan); + + recursivelyConfigureAndUpdateUiOrderingInGridLayoutColumn(*group, groupBox->contentFrame(), uiConfigName); - const std::vector& groupChildren = group->uiItems(); - recursivelyConfigureAndUpdateUiItemsInGridLayoutColumn(groupChildren, groupBox->contentFrame(), uiConfigName); - - currentRowIndex++; + currentColumn += itemColumnSpan; } else { - PdmUiFieldHandle* field = dynamic_cast(uiItems[i]); + PdmUiFieldHandle* field = dynamic_cast(currentItem); PdmUiFieldEditorHandle* fieldEditor = findOrCreateFieldEditor(containerWidgetWithGridLayout, field, uiConfigName); if (fieldEditor) { - fieldEditor->setField(field); + fieldEditor->setUiField(field); // Place the widget(s) into the correct parent and layout QWidget* fieldCombinedWidget = fieldEditor->combinedWidget(); @@ -116,70 +149,116 @@ void caf::PdmUiWidgetBasedObjectEditor::recursivelyConfigureAndUpdateUiItemsInGr if (fieldCombinedWidget) { fieldCombinedWidget->setParent(containerWidgetWithGridLayout); - parentLayout->addWidget(fieldCombinedWidget, currentRowIndex, 0, 1, 2); + parentLayout->addWidget(fieldCombinedWidget, currentRowIndex, currentColumn, 1, itemColumnSpan); } else { PdmUiItemInfo::LabelPosType labelPos = field->uiLabelPosition(uiConfigName); - bool labelOnTop = (labelPos == PdmUiItemInfo::TOP); - bool editorSpanBoth = labelOnTop; QWidget* fieldEditorWidget = fieldEditor->editorWidget(); - - if (labelPos != PdmUiItemInfo::HIDDEN) + if (fieldEditorWidget) { - QWidget* fieldLabelWidget = fieldEditor->labelWidget(); - if (fieldLabelWidget) + // Hide label + if (labelPos == PdmUiItemInfo::HIDDEN) { - fieldLabelWidget->setParent(containerWidgetWithGridLayout); - - // Label widget will span two columns if aligned on top - int colSpan = labelOnTop ? 2 : 1; - // If the label is on the side, and the editor can expand vertically, allign the label with the top edge of the editor - if (!labelOnTop && (fieldEditorWidget->sizePolicy().verticalPolicy() & QSizePolicy::ExpandFlag)) - parentLayout->addWidget(fieldLabelWidget, currentRowIndex, 0, 1, colSpan, Qt::AlignTop); - else - parentLayout->addWidget(fieldLabelWidget, currentRowIndex, 0, 1, colSpan, Qt::AlignVCenter); + QWidget* fieldLabelWidget = fieldEditor->labelWidget(); + if (fieldLabelWidget) + { + fieldLabelWidget->hide(); + } - fieldLabelWidget->show(); + fieldEditorWidget->setParent(containerWidgetWithGridLayout); // To make sure this widget has the current group box as parent. + parentLayout->addWidget(fieldEditorWidget, currentRowIndex, currentColumn, 1, itemColumnSpan, Qt::AlignTop); - if (labelOnTop) currentRowIndex++; + currentColumn += itemColumnSpan; + } + else // Add label + { + QWidget* fieldLabelWidget = fieldEditor->labelWidget(); + + // For label on top we add another layer of QLayouts to avoid messing with the global rows. + if (labelPos == PdmUiItemInfo::TOP) + { + QVBoxLayout* labelAndFieldVLayout = new QVBoxLayout(); + parentLayout->addLayout(labelAndFieldVLayout, currentRowIndex, currentColumn, 1, itemColumnSpan, Qt::AlignTop); + if (fieldLabelWidget) + { + labelAndFieldVLayout->addWidget(fieldLabelWidget, 0, Qt::AlignTop); + } + labelAndFieldVLayout->addWidget(fieldEditorWidget, 1, Qt::AlignTop); + + currentColumn += itemColumnSpan; + } + else + { + int fieldColumnSpan = currentLayout.totalColumnSpan; + int leftLabelColumnSpan = 0; + if (fieldLabelWidget) + { + leftLabelColumnSpan = currentLayout.leftLabelColumnSpan; + if (fieldColumnSpan == PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN && + leftLabelColumnSpan == PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN) + { + // Rounded up half for field. Rest for left label. + fieldColumnSpan = itemColumnSpan / 2 + itemColumnSpan % 2; + leftLabelColumnSpan = itemColumnSpan - fieldColumnSpan; + } + else if (fieldColumnSpan == PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN) + { + fieldColumnSpan = itemColumnSpan - leftLabelColumnSpan; + } + else if (leftLabelColumnSpan == PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN) + { + fieldColumnSpan = 1; + leftLabelColumnSpan = itemColumnSpan - fieldColumnSpan; + } + else + { + fieldColumnSpan = itemColumnSpan - leftLabelColumnSpan; + } + CAF_ASSERT(fieldColumnSpan >= 1 && "Need at least one column for the field"); + fieldColumnSpan = std::max(1, fieldColumnSpan); + fieldLabelWidget->setParent(containerWidgetWithGridLayout); + parentLayout->addWidget(fieldLabelWidget, currentRowIndex, currentColumn, 1, leftLabelColumnSpan, Qt::AlignTop); + + // Apply margins determined by the editor type + fieldLabelWidget->setContentsMargins(fieldEditor->labelContentMargins()); + } + fieldEditorWidget->setParent(containerWidgetWithGridLayout); // To make sure this widget has the current group box as parent. + parentLayout->addWidget(fieldEditorWidget, currentRowIndex, currentColumn + leftLabelColumnSpan, 1, fieldColumnSpan, Qt::AlignTop); + + currentColumn += itemColumnSpan; + } } - } - else - { - QWidget* fieldLabelWidget = fieldEditor->labelWidget(); - if (fieldLabelWidget) fieldLabelWidget->hide(); - editorSpanBoth = true; // To span both columns when there is no label - } - - if (fieldEditorWidget) - { - fieldEditorWidget->setParent(containerWidgetWithGridLayout); // To make sure this widget has the current group box as parent. - - // Label widget will span two columns if aligned on top - int colSpan = editorSpanBoth ? 2 : 1; - int colIndex = editorSpanBoth ? 0 : 1; - parentLayout->addWidget(fieldEditorWidget, currentRowIndex, colIndex, 1, colSpan, Qt::AlignTop); - - if (previousTabOrderWidget) QWidget::setTabOrder(previousTabOrderWidget, fieldEditorWidget); - previousTabOrderWidget = fieldEditorWidget; + if (previousTabOrderWidget) + { + QWidget::setTabOrder(previousTabOrderWidget, fieldEditorWidget); + } } } - fieldEditor->updateUi(uiConfigName); - - currentRowIndex++; } } } + + // Set last row with content to stretch + if (currentRowIndex >= 0 && currentRowIndex < parentLayout->rowCount()) + { + parentLayout->setRowStretch(currentRowIndex++, 1); + } + + // Set remaining rows to stretch zero, as we want the row with content to stretch all the way + while (currentRowIndex >= 0 && currentRowIndex < parentLayout->rowCount()) + { + parentLayout->setRowStretch(currentRowIndex++, 0); + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool caf::PdmUiWidgetBasedObjectEditor::isUiGroupExpanded(const PdmUiGroup* uiGroup) const +bool caf::PdmUiFormLayoutObjectEditor::isUiGroupExpanded(const PdmUiGroup* uiGroup) const { if (uiGroup->hasForcedExpandedState()) return uiGroup->forcedExpandedState(); @@ -201,7 +280,7 @@ bool caf::PdmUiWidgetBasedObjectEditor::isUiGroupExpanded(const PdmUiGroup* uiGr //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QMinimizePanel* caf::PdmUiWidgetBasedObjectEditor::findOrCreateGroupBox(QWidget* parent, PdmUiGroup* group, const QString& uiConfigName) +QMinimizePanel* caf::PdmUiFormLayoutObjectEditor::findOrCreateGroupBox(QWidget* parent, PdmUiGroup* group, const QString& uiConfigName) { QString groupBoxKey = group->keyword(); QMinimizePanel* groupBox = nullptr; @@ -214,9 +293,15 @@ QMinimizePanel* caf::PdmUiWidgetBasedObjectEditor::findOrCreateGroupBox(QWidget* if (it == m_groupBoxes.end()) { groupBox = new QMinimizePanel(parent); + groupBox->enableFrame(group->enableFrame()); groupBox->setTitle(group->uiName(uiConfigName)); groupBox->setObjectName(group->keyword()); groupBoxLayout = new QGridLayout(); + if (!group->enableFrame()) + { + groupBoxLayout->setContentsMargins(0, 0, 0, 0); + groupBoxLayout->setHorizontalSpacing(0); + } groupBox->contentFrame()->setLayout(groupBoxLayout); connect(groupBox, SIGNAL(expandedChanged(bool)), this, SLOT(groupBoxExpandedStateToggled(bool))); @@ -243,7 +328,7 @@ QMinimizePanel* caf::PdmUiWidgetBasedObjectEditor::findOrCreateGroupBox(QWidget* //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmUiFieldEditorHandle* caf::PdmUiWidgetBasedObjectEditor::findOrCreateFieldEditor(QWidget* parent, PdmUiFieldHandle* field, const QString& uiConfigName) +caf::PdmUiFieldEditorHandle* caf::PdmUiFormLayoutObjectEditor::findOrCreateFieldEditor(QWidget* parent, PdmUiFieldHandle* field, const QString& uiConfigName) { caf::PdmUiFieldEditorHandle* fieldEditor = nullptr; @@ -283,7 +368,7 @@ caf::PdmUiFieldEditorHandle* caf::PdmUiWidgetBasedObjectEditor::findOrCreateFiel //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void caf::PdmUiWidgetBasedObjectEditor::groupBoxExpandedStateToggled(bool isExpanded) +void caf::PdmUiFormLayoutObjectEditor::groupBoxExpandedStateToggled(bool isExpanded) { if (!this->pdmObject()->xmlCapability()) return; @@ -298,7 +383,7 @@ void caf::PdmUiWidgetBasedObjectEditor::groupBoxExpandedStateToggled(bool isExpa //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void caf::PdmUiWidgetBasedObjectEditor::cleanupBeforeSettingPdmObject() +void caf::PdmUiFormLayoutObjectEditor::cleanupBeforeSettingPdmObject() { std::map::iterator it; for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it) @@ -322,7 +407,7 @@ void caf::PdmUiWidgetBasedObjectEditor::cleanupBeforeSettingPdmObject() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void caf::PdmUiWidgetBasedObjectEditor::configureAndUpdateUi(const QString& uiConfigName) +void caf::PdmUiFormLayoutObjectEditor::configureAndUpdateUi(const QString& uiConfigName) { caf::PdmUiOrdering config; if (pdmObject()) @@ -338,21 +423,20 @@ void caf::PdmUiWidgetBasedObjectEditor::configureAndUpdateUi(const QString& uiCo std::map::iterator it; for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it) { - it->second->setField(nullptr); + it->second->setUiField(nullptr); } // Set all group Boxes to be unvisited m_newGroupBoxes.clear(); - const std::vector& uiItems = config.uiItems(); - recursivelyConfigureAndUpdateTopLevelUiItems(uiItems, uiConfigName); + recursivelyConfigureAndUpdateTopLevelUiOrdering(config, uiConfigName); // Remove all fieldViews not mentioned by the configuration from the layout std::vector< PdmFieldHandle* > fvhToRemoveFromMap; for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it) { - if (it->second->field() == nullptr) + if (it->second->uiField() == nullptr) { PdmUiFieldEditorHandle* fvh = it->second; delete fvh; @@ -390,9 +474,12 @@ void caf::PdmUiWidgetBasedObjectEditor::configureAndUpdateUi(const QString& uiCo } //-------------------------------------------------------------------------------------------------- -/// +/// Unused. Should probably remove //-------------------------------------------------------------------------------------------------- -void caf::PdmUiWidgetBasedObjectEditor::recursiveVerifyUniqueNames(const std::vector& uiItems, const QString& uiConfigName, std::set* fieldKeywordNames, std::set* groupNames) +void caf::PdmUiFormLayoutObjectEditor::recursiveVerifyUniqueNames(const std::vector& uiItems, + const QString& uiConfigName, + std::set* fieldKeywordNames, + std::set* groupNames) { for (size_t i = 0; i < uiItems.size(); ++i) { diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiWidgetBasedObjectEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.h similarity index 73% rename from Fwk/AppFwk/cafUserInterface/cafPdmUiWidgetBasedObjectEditor.h rename to Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.h index 72da6eb7d8..b6c89ac393 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiWidgetBasedObjectEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiFormLayoutObjectEditor.h @@ -38,6 +38,7 @@ #pragma once #include "cafPdmUiObjectEditorHandle.h" +#include "cafPdmUiOrdering.h" #include #include @@ -51,43 +52,44 @@ namespace caf { class PdmUiFieldEditorHandle; class PdmUiGroup; +class PdmUiOrdering; //================================================================================================== /// //================================================================================================== -class PdmUiWidgetBasedObjectEditor : public PdmUiObjectEditorHandle +class PdmUiFormLayoutObjectEditor : public PdmUiObjectEditorHandle { Q_OBJECT public: - PdmUiWidgetBasedObjectEditor(); - ~PdmUiWidgetBasedObjectEditor(); + PdmUiFormLayoutObjectEditor(); + ~PdmUiFormLayoutObjectEditor() override; protected: /// When overriding this function, use findOrCreateGroupBox() or findOrCreateFieldEditor() for detailed control /// Use recursivelyConfigureAndUpdateUiItemsInGridLayoutColumn() for automatic layout of group and field widgets - virtual void recursivelyConfigureAndUpdateTopLevelUiItems(const std::vector& topLevelUiItems, - const QString& uiConfigName) = 0; + virtual void recursivelyConfigureAndUpdateTopLevelUiOrdering(const PdmUiOrdering& topLevelUiOrdering, + const QString& uiConfigName) = 0; - void recursivelyConfigureAndUpdateUiItemsInGridLayoutColumn(const std::vector& uiItems, - QWidget* containerWidgetWithGridLayout, - const QString& uiConfigName); + void recursivelyConfigureAndUpdateUiOrderingInGridLayoutColumn(const PdmUiOrdering& uiOrdering, + QWidget* containerWidgetWithGridLayout, + const QString& uiConfigName); QMinimizePanel* findOrCreateGroupBox(QWidget* parent, PdmUiGroup* group, const QString& uiConfigName); PdmUiFieldEditorHandle* findOrCreateFieldEditor(QWidget* parent, PdmUiFieldHandle* field, const QString& uiConfigName); private slots: - void groupBoxExpandedStateToggled(bool isExpanded); + void groupBoxExpandedStateToggled(bool isExpanded); private: - bool isUiGroupExpanded(const PdmUiGroup* uiGroup) const; - virtual void cleanupBeforeSettingPdmObject() override; - virtual void configureAndUpdateUi(const QString& uiConfigName) override; + bool isUiGroupExpanded(const PdmUiGroup* uiGroup) const; + void cleanupBeforeSettingPdmObject() override; + void configureAndUpdateUi(const QString& uiConfigName) override; - static void recursiveVerifyUniqueNames(const std::vector& uiItems, - const QString& uiConfigName, - std::set* fieldKeywordNames, - std::set* groupNames); + static void recursiveVerifyUniqueNames(const std::vector& uiItems, + const QString& uiConfigName, + std::set* fieldKeywordNames, + std::set* groupNames); private: std::map m_fieldViews; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.cpp index dcea9d4c1e..e827cb193d 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.cpp @@ -46,9 +46,9 @@ #include "cafSelectionManager.h" #include +#include #include #include -#include #include #include #include @@ -71,7 +71,7 @@ class PdmUniqueIdValidator : public QValidator computeNextValidId(); } - virtual State validate(QString& currentString, int &) const + State validate(QString& currentString, int &) const override { if (m_multipleSelectionOfSameFieldsSelected) { @@ -98,9 +98,7 @@ class PdmUniqueIdValidator : public QValidator if (m_usedIds.find(currentValue) != m_usedIds.end()) { - QApplication* qapplication = qobject_cast(qApp); - - foreach(QWidget* widget, qapplication->topLevelWidgets()) + foreach(QWidget* widget, QApplication::topLevelWidgets()) { if (widget->inherits("QMainWindow")) { @@ -118,7 +116,7 @@ class PdmUniqueIdValidator : public QValidator return QValidator::Acceptable; } - virtual void fixup(QString& editorText) const + void fixup(QString& editorText) const override { editorText = QString::number(m_nextValidValue); } @@ -153,6 +151,26 @@ namespace caf CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiLineEditor); +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* PdmUiLineEditor::createEditorWidget(QWidget * parent) +{ + m_lineEdit = new PdmUiLineEdit(parent); + + connect(m_lineEdit, SIGNAL(editingFinished()), this, SLOT(slotEditingFinished())); + + return m_lineEdit; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* PdmUiLineEditor::createLabelWidget(QWidget * parent) +{ + m_label = new QLabel(parent); + return m_label; +} //-------------------------------------------------------------------------------------------------- /// @@ -166,7 +184,7 @@ void PdmUiLineEditor::configureAndUpdateUi(const QString& uiConfigName) if (!m_lineEdit.isNull()) { - bool isReadOnly = field()->isUiReadOnly(uiConfigName); + bool isReadOnly = uiField()->isUiReadOnly(uiConfigName); if (isReadOnly) { m_lineEdit->setReadOnly(true); @@ -181,48 +199,50 @@ void PdmUiLineEditor::configureAndUpdateUi(const QString& uiConfigName) m_lineEdit->setStyleSheet(""); } - m_lineEdit->setToolTip(field()->uiToolTip(uiConfigName)); + m_lineEdit->setToolTip(uiField()->uiToolTip(uiConfigName)); { PdmUiLineEditorAttribute leab; - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &leab); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &leab); } if (leab.useRangeValidator) { m_lineEdit->setValidator(new QIntValidator(leab.minValue, leab.maxValue, this)); } + + m_lineEdit->setAvoidSendingEnterEventToParentWidget(leab.avoidSendingEnterEventToParentWidget); } { PdmUiLineEditorAttributeUniqueValues leab; - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &leab); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &leab); } if (leab.usedIds.size() > 0) { - if (isMultipleFieldsWithSameKeywordSelected(field()->fieldHandle())) + if (isMultipleFieldsWithSameKeywordSelected(uiField()->fieldHandle())) { QMessageBox::information(nullptr, "Invalid operation", "The field you are manipulating is defined to have unique values. A selection of multiple fields is detected. Please select a single item."); } - m_lineEdit->setValidator(new PdmUniqueIdValidator(leab.usedIds, isMultipleFieldsWithSameKeywordSelected(field()->fieldHandle()), leab.errorMessage, this)); + m_lineEdit->setValidator(new PdmUniqueIdValidator(leab.usedIds, isMultipleFieldsWithSameKeywordSelected(uiField()->fieldHandle()), leab.errorMessage, this)); } } bool fromMenuOnly = true; - QList enumNames = field()->valueOptions(&fromMenuOnly); + QList enumNames = uiField()->valueOptions(&fromMenuOnly); CAF_ASSERT(fromMenuOnly); // Not supported if (!enumNames.isEmpty() && fromMenuOnly == true) { - int enumValue = field()->uiValue().toInt(); + int enumValue = uiField()->uiValue().toInt(); if (enumValue < enumNames.size() && enumValue > -1) { @@ -232,16 +252,16 @@ void PdmUiLineEditor::configureAndUpdateUi(const QString& uiConfigName) else { PdmUiLineEditorAttributeUiDisplayString leab; - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &leab); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &leab); } QString displayString; if (leab.m_displayString.isEmpty()) { - displayString = field()->uiValue().toString(); + displayString = uiField()->uiValue().toString(); } else { @@ -253,26 +273,22 @@ void PdmUiLineEditor::configureAndUpdateUi(const QString& uiConfigName) } } - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -QWidget* PdmUiLineEditor::createEditorWidget(QWidget * parent) +QMargins PdmUiLineEditor::calculateLabelContentMargins() const { - m_lineEdit = new QLineEdit(parent); - - connect(m_lineEdit, SIGNAL(editingFinished()), this, SLOT(slotEditingFinished())); + QSize editorSize = m_lineEdit->sizeHint(); + QSize labelSize = m_label->sizeHint(); + int heightDiff = editorSize.height() - labelSize.height(); - return m_lineEdit; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QWidget* PdmUiLineEditor::createLabelWidget(QWidget * parent) -{ - m_label = new QLabel(parent); - return m_label; + QMargins contentMargins = m_label->contentsMargins(); + if (heightDiff > 0) + { + contentMargins.setTop(contentMargins.top() + heightDiff / 2); + contentMargins.setBottom(contentMargins.bottom() + heightDiff / 2); + } + return contentMargins; } //-------------------------------------------------------------------------------------------------- @@ -296,7 +312,7 @@ bool PdmUiLineEditor::isMultipleFieldsWithSameKeywordSelected(PdmFieldHandle* ed // For current selection, find all fields with same keyword std::vector items; - SelectionManager::instance()->selectedItems(items, SelectionManager::CURRENT); + SelectionManager::instance()->selectedItems(items, SelectionManager::FIRST_LEVEL); for (size_t i = 0; i < items.size(); i++) { @@ -319,4 +335,37 @@ bool PdmUiLineEditor::isMultipleFieldsWithSameKeywordSelected(PdmFieldHandle* ed } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +PdmUiLineEdit::PdmUiLineEdit(QWidget* parent) + : QLineEdit(parent), m_avoidSendingEnterEvent(false) +{ +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiLineEdit::setAvoidSendingEnterEventToParentWidget(bool avoidSendingEnterEvent) +{ + m_avoidSendingEnterEvent = avoidSendingEnterEvent; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiLineEdit::keyPressEvent(QKeyEvent * event) +{ + QLineEdit::keyPressEvent(event); + if (m_avoidSendingEnterEvent) + { + if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + { + // accept enter/return events so they won't + // be ever propagated to the parent dialog.. + event->accept(); + } + } +} + } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.h index 25a8782f98..6adf7d30d7 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiLineEditor.h @@ -58,12 +58,14 @@ class PdmUiLineEditorAttribute : public PdmUiEditorAttribute public: PdmUiLineEditorAttribute() { + avoidSendingEnterEventToParentWidget = false; useRangeValidator = false; minValue = 0; maxValue = 0; } public: + bool avoidSendingEnterEventToParentWidget; bool useRangeValidator; int minValue; int maxValue; @@ -97,6 +99,17 @@ class PdmUiLineEditorAttributeUiDisplayString : public PdmUiEditorAttribute QString m_displayString; }; +class PdmUiLineEdit : public QLineEdit +{ + Q_OBJECT +public: + PdmUiLineEdit(QWidget* parent); + void setAvoidSendingEnterEventToParentWidget(bool avoidSendingEnter); +protected: + void keyPressEvent(QKeyEvent* event) override; +private: + bool m_avoidSendingEnterEvent; +}; //-------------------------------------------------------------------------------------------------- /// @@ -108,22 +121,23 @@ class PdmUiLineEditor : public PdmUiFieldEditorHandle public: PdmUiLineEditor() {} - virtual ~PdmUiLineEditor() {} + ~PdmUiLineEditor() override {} protected: - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; + QMargins calculateLabelContentMargins() const override; protected slots: - void slotEditingFinished(); + void slotEditingFinished(); private: - bool isMultipleFieldsWithSameKeywordSelected(PdmFieldHandle* editorField) const; + bool isMultipleFieldsWithSameKeywordSelected(PdmFieldHandle* editorField) const; private: - QPointer m_lineEdit; - QPointer m_label; + QPointer m_lineEdit; + QPointer m_label; }; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp index b5a344840a..ee55444ca0 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.cpp @@ -66,7 +66,7 @@ class MyStringListModel : public QStringListModel public: explicit MyStringListModel(QObject *parent = nullptr) : QStringListModel(parent), m_isItemsEditable(false) { } - virtual Qt::ItemFlags flags (const QModelIndex& index) const + Qt::ItemFlags flags (const QModelIndex& index) const override { if (m_isItemsEditable) return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; @@ -98,7 +98,7 @@ class QListViewHeightHint : public QListView //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual QSize sizeHint() const override + QSize sizeHint() const override { QSize mySize = QListView::sizeHint(); @@ -164,13 +164,13 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); - m_listView->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_listView->setToolTip(field()->uiToolTip(uiConfigName)); + m_listView->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); + m_listView->setToolTip(uiField()->uiToolTip(uiConfigName)); bool optionsOnly = true; - QList options = field()->valueOptions(&optionsOnly); + QList options = uiField()->valueOptions(&optionsOnly); m_optionItemCount = options.size(); - if (options.size() > 0 || field()->isUiReadOnly(uiConfigName)) + if (options.size() > 0 || uiField()->isUiReadOnly(uiConfigName)) { m_isEditOperationsAvailable = false; } @@ -180,10 +180,10 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) } PdmUiListEditorAttribute attributes; - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &attributes); QPalette myPalette(m_listView->palette()); myPalette.setColor(QPalette::Base, attributes.m_baseColor); @@ -205,11 +205,11 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) QStringList texts = PdmOptionItemInfo::extractUiTexts(options); strListModel->setStringList(texts); - QVariant fieldValue = field()->uiValue(); + QVariant fieldValue = uiField()->uiValue(); if (fieldValue.type() == QVariant::Int || fieldValue.type() == QVariant::UInt) { int col = 0; - int row = field()->uiValue().toInt(); + int row = uiField()->uiValue().toInt(); QModelIndex mi = strListModel->index(row, col); @@ -253,7 +253,7 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName) QItemSelection selection = m_listView->selectionModel()->selection(); QModelIndex currentItem = m_listView->selectionModel()->currentIndex(); - QVariant fieldValue = field()->uiValue(); + QVariant fieldValue = uiField()->uiValue(); QStringList texts = fieldValue.toStringList(); texts.push_back(""); strListModel->setStringList(texts); @@ -306,7 +306,7 @@ void PdmUiListEditor::slotSelectionChanged(const QItemSelection & selected, cons { if (m_optionItemCount == 0) return; - QVariant fieldValue = field()->uiValue(); + QVariant fieldValue = uiField()->uiValue(); if (fieldValue.type() == QVariant::Int || fieldValue.type() == QVariant::UInt) { // NOTE : Workaround for update issue seen on RHEL6 with Qt 4.6.2 @@ -331,7 +331,6 @@ void PdmUiListEditor::slotSelectionChanged(const QItemSelection & selected, cons { QModelIndexList idxList = m_listView->selectionModel()->selectedIndexes(); - QVariant fieldValue = field()->uiValue(); QList valuesSelectedInField = fieldValue.toList(); if (idxList.size() == 1 && valuesSelectedInField.size() == 1) diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h index 980622e259..f80dd27473 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListEditor.h @@ -79,28 +79,28 @@ class PdmUiListEditor : public PdmUiFieldEditorHandle public: PdmUiListEditor(); - virtual ~PdmUiListEditor(); + ~PdmUiListEditor() override; protected: - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); - virtual bool eventFilter ( QObject * listView, QEvent * event ); // To catch delete key press in list view. + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; + bool eventFilter ( QObject * listView, QEvent * event ) override; // To catch delete key press in list view. protected slots: - void slotSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected ); - void slotListItemEdited(const QModelIndex&, const QModelIndex&); + void slotSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected ); + void slotListItemEdited(const QModelIndex&, const QModelIndex&); private: - QString contentAsString() const; - void pasteFromString(const QString& content); + QString contentAsString() const; + void pasteFromString(const QString& content); - void trimAndSetValuesToField(const QStringList& stringList); + void trimAndSetValuesToField(const QStringList& stringList); private: QPointer m_listView; - QPointer m_label; - QPointer m_model; + QPointer m_label; + QPointer m_model; bool m_isEditOperationsAvailable; int m_optionItemCount; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.h index 8ec2a9303f..5948ba0822 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListView.h @@ -55,7 +55,7 @@ class PdmUiListView : public QWidget Q_OBJECT public: PdmUiListView(QWidget* parent = nullptr, Qt::WindowFlags f = nullptr); - ~PdmUiListView(); + ~PdmUiListView() override; void setPdmObject(caf::PdmObjectCollection* object); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.h index 662100cf00..50da5bdffa 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiListViewEditor.h @@ -80,16 +80,16 @@ class UiListViewModelPdm : public QAbstractTableModel public: explicit UiListViewModelPdm(QObject* parent); - void setPdmData(PdmObjectCollection* objectGroup, const QString& configName); + void setPdmData(PdmObjectCollection* objectGroup, const QString& configName); // Qt overrides - virtual int rowCount( const QModelIndex &parent = QModelIndex( ) ) const; - virtual int columnCount( const QModelIndex &parent = QModelIndex( ) ) const; - virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const; - virtual QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; + int rowCount( const QModelIndex &parent = QModelIndex( ) ) const override; + int columnCount( const QModelIndex &parent = QModelIndex( ) ) const override; + QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override; + QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; private: - void computeColumnCount(); + void computeColumnCount(); private: PdmObjectCollection* m_pdmObjectGroup; @@ -107,11 +107,11 @@ class PdmUiListViewEditor : public PdmUiObjectEditorHandle { public: PdmUiListViewEditor(); - ~PdmUiListViewEditor(); + ~PdmUiListViewEditor() override; protected: - virtual QWidget* createWidget(QWidget* parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createWidget(QWidget* parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; private: QPointer m_tableView; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h index 9e50433023..6b79e932b4 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyView.h @@ -54,7 +54,7 @@ class QVerticalScrollArea : public QScrollArea Q_OBJECT public: explicit QVerticalScrollArea(QWidget* parent = nullptr); - virtual bool eventFilter(QObject* object, QEvent* event) override; + bool eventFilter(QObject* object, QEvent* event) override; }; @@ -73,15 +73,15 @@ class PdmUiPropertyView : public QWidget Q_OBJECT public: PdmUiPropertyView(QWidget* parent = nullptr, Qt::WindowFlags f = nullptr); - ~PdmUiPropertyView(); + ~PdmUiPropertyView() override; - void setUiConfigurationName(QString uiConfigName); - PdmObjectHandle* currentObject(); + void setUiConfigurationName(QString uiConfigName); + PdmObjectHandle* currentObject(); - virtual QSize sizeHint() const override; + QSize sizeHint() const override; public slots: - void showProperties(caf::PdmObjectHandle* object); // Signal/Slot system needs caf:: prefix in some cases + void showProperties(caf::PdmObjectHandle* object); // Signal/Slot system needs caf:: prefix in some cases private: PdmUiObjectEditorHandle* m_currentObjectView; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.cpp index e5febf3df8..9aa2c356c2 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.cpp @@ -96,6 +96,8 @@ void PdmUiPropertyViewDialog::initialize(PdmObject* object, const QString& windo m_windowTitle = windowTitle; m_uiConfigName = uiConfigName; + setWindowModality(Qt::WindowModal); + setupUi(); } diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.h index 63b1225d04..f00eac1c2c 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPropertyViewDialog.h @@ -52,7 +52,7 @@ class PdmUiPropertyViewDialog : public QDialog public: PdmUiPropertyViewDialog(QWidget* parent, PdmObject* object, const QString& windowTitle, const QString& uiConfigName); PdmUiPropertyViewDialog(QWidget* parent, PdmObject* object, const QString& windowTitle, const QString& uiConfigName, const QDialogButtonBox::StandardButtons& standardButtons); - ~PdmUiPropertyViewDialog(); + ~PdmUiPropertyViewDialog() override; QDialogButtonBox* dialogButtonBox(); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.cpp index f59ea4b034..4e3596ee2a 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.cpp @@ -69,17 +69,17 @@ void PdmUiPushButtonEditor::configureAndUpdateUi(const QString& uiConfigName) PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); m_pushButton->setCheckable(true); - m_pushButton->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_pushButton->setToolTip(field()->uiToolTip(uiConfigName)); + m_pushButton->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); + m_pushButton->setToolTip(uiField()->uiToolTip(uiConfigName)); PdmUiPushButtonEditorAttribute attributes; - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &attributes); } - QVariant variantFieldValue = field()->uiValue(); + QVariant variantFieldValue = uiField()->uiValue(); if (!attributes.m_buttonIcon.isNull()) { @@ -108,7 +108,7 @@ void PdmUiPushButtonEditor::configureAndUpdateUi(const QString& uiConfigName) if (variantFieldValue.type() == QVariant::Bool) { - m_pushButton->setChecked(field()->uiValue().toBool()); + m_pushButton->setChecked(uiField()->uiValue().toBool()); } } @@ -166,7 +166,7 @@ QWidget* PdmUiPushButtonEditor::createLabelWidget(QWidget * parent) //-------------------------------------------------------------------------------------------------- void PdmUiPushButtonEditor::slotClicked(bool checked) { - if (field() && dynamic_cast *> (field()->fieldHandle())) + if (uiField() && dynamic_cast *> (uiField()->fieldHandle())) { QVariant v; v = checked; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.h index fc0db1a4b3..b4c73623a6 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiPushButtonEditor.h @@ -67,17 +67,17 @@ class PdmUiPushButtonEditor : public PdmUiFieldEditorHandle public: PdmUiPushButtonEditor() {} - virtual ~PdmUiPushButtonEditor() {} + ~PdmUiPushButtonEditor() override {} static void configureEditorForField(PdmFieldHandle* fieldHandle); protected: - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; protected slots: - void slotClicked(bool checked); + void slotClicked(bool checked); private: QPointer m_pushButton; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.cpp index 84ee3e291f..6ddeff9280 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.cpp @@ -65,35 +65,34 @@ void PdmUiSliderEditor::configureAndUpdateUi(const QString& uiConfigName) PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); - m_spinBox->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_spinBox->setToolTip(field()->uiToolTip(uiConfigName)); + m_spinBox->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); + m_spinBox->setToolTip(uiField()->uiToolTip(uiConfigName)); - m_slider->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_slider->setToolTip(field()->uiToolTip(uiConfigName)); + m_slider->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); + m_slider->setToolTip(uiField()->uiToolTip(uiConfigName)); - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &m_attributes); } { m_spinBox->blockSignals(true); m_spinBox->setMinimum(m_attributes.m_minimum); m_spinBox->setMaximum(m_attributes.m_maximum); + + QString textValue = uiField()->uiValue().toString(); + m_spinBox->setValue(textValue.toInt()); m_spinBox->blockSignals(false); } { m_slider->blockSignals(true); m_slider->setRange(m_attributes.m_minimum, m_attributes.m_maximum); + updateSliderPosition(); m_slider->blockSignals(false); } - - QString textValue = field()->uiValue().toString(); - m_spinBox->setValue(textValue.toInt()); - - updateSliderPosition(); } //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.h index 668db5191a..c10e35fc4a 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiSliderEditor.h @@ -75,20 +75,20 @@ class PdmUiSliderEditor : public PdmUiFieldEditorHandle public: PdmUiSliderEditor() {} - virtual ~PdmUiSliderEditor() {} + ~PdmUiSliderEditor() override {} protected: - virtual void configureAndUpdateUi(const QString& uiConfigName); - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); + void configureAndUpdateUi(const QString& uiConfigName) override; + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; protected slots: - void slotSliderValueChanged(int position); - void slotSpinBoxValueChanged(int position); + void slotSliderValueChanged(int position); + void slotSpinBoxValueChanged(int position); private: - void updateSliderPosition(); - void writeValueToField(); + void updateSliderPosition(); + void writeValueToField(); private: QPointer m_spinBox; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableRowEditor.cpp similarity index 83% rename from Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.cpp rename to Fwk/AppFwk/cafUserInterface/cafPdmUiTableRowEditor.cpp index 54c78e8b63..f861fe79c7 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableRowEditor.cpp @@ -34,58 +34,54 @@ // //################################################################################################## - -#include "cafPdmUiTableItemEditor.h" +#include "cafPdmUiTableRowEditor.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmUiEditorHandle.h" -#include "cafPdmUiTableViewModel.h" - +#include "cafPdmUiTableViewQModel.h" namespace caf { - - //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -PdmUiTableItemEditor::PdmUiTableItemEditor(PdmUiTableViewModel* model, caf::PdmObjectHandle* pdmObject, int row) +PdmUiTableRowEditor::PdmUiTableRowEditor(PdmUiTableViewQModel* model, caf::PdmObjectHandle* pdmObject, int row) { m_model = model; - m_row = row; + m_row = row; caf::PdmUiObjectHandle* uiObject = uiObj(pdmObject); this->bindToPdmItem(uiObject); } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -PdmUiTableItemEditor::~PdmUiTableItemEditor() -{ -} +PdmUiTableRowEditor::~PdmUiTableRowEditor() {} //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void PdmUiTableItemEditor::configureAndUpdateUi(const QString& uiConfigName) +void PdmUiTableRowEditor::configureAndUpdateUi(const QString& uiConfigName) { caf::PdmUiObjectHandle* uiObject = dynamic_cast(this->pdmItem()); if (uiObject) { - // Call uiOrdering method, as this method is responsible for control of + // Call uiOrdering method, as this method is responsible for control of // object states like hidden/readOnly, etc... caf::PdmUiOrdering dummy; uiObject->uiOrdering(uiConfigName, dummy); } - QModelIndex miStart = m_model->index(m_row, 0); - QModelIndex miEnd = m_model->index(m_row, m_model->columnCount()); + if (m_model) + { + QModelIndex miStart = m_model->index(m_row, 0); + QModelIndex miEnd = m_model->index(m_row, m_model->columnCount()); - m_model->notifyDataChanged(miStart, miEnd); + m_model->notifyDataChanged(miStart, miEnd); + } } - } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableRowEditor.h similarity index 85% rename from Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.h rename to Fwk/AppFwk/cafUserInterface/cafPdmUiTableRowEditor.h index 04d8a489fc..d77aeef842 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableItemEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableRowEditor.h @@ -38,29 +38,28 @@ #include "cafPdmUiEditorHandle.h" +#include + namespace caf { -class PdmUiTableViewModel; +class PdmUiTableViewQModel; class PdmObjectHandle; - //-------------------------------------------------------------------------------------------------- /// This class is used to update a row in the model when a field value changes //-------------------------------------------------------------------------------------------------- -class PdmUiTableItemEditor : public PdmUiEditorHandle +class PdmUiTableRowEditor : public PdmUiEditorHandle { public: - PdmUiTableItemEditor(PdmUiTableViewModel* model, caf::PdmObjectHandle* pdmObject, int row); - virtual ~PdmUiTableItemEditor(); + PdmUiTableRowEditor(PdmUiTableViewQModel* model, caf::PdmObjectHandle* pdmObject, int row); + ~PdmUiTableRowEditor() override; -protected: // Interface to override: - virtual void configureAndUpdateUi(const QString& uiConfigName); +protected: + void configureAndUpdateUi(const QString& uiConfigName) override; private: - PdmUiTableViewModel* m_model; - int m_row; + QPointer m_model; + int m_row; }; - - } // End of namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.cpp index 1abfd313ea..c376a6bf7d 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.cpp @@ -37,10 +37,14 @@ #include "cafPdmUiTableView.h" +#include "cafPdmChildArrayField.h" #include "cafPdmObject.h" #include "cafPdmUiTableViewEditor.h" +#include "cafSelectionManager.h" -#include +#include +#include "cafPdmUiCommandSystemProxy.h" +#include namespace caf @@ -53,16 +57,25 @@ namespace caf PdmUiTableView::PdmUiTableView(QWidget* parent, Qt::WindowFlags f) : QWidget (parent, f) { - QHBoxLayout* layout = new QHBoxLayout(this); + QVBoxLayout* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); setLayout(layout); m_listViewEditor = new PdmUiTableViewEditor(); + + m_listViewEditor->createWidgets(this); - QWidget* widget = m_listViewEditor->createWidget(this); - layout->addWidget(widget); + { + QWidget* widget = m_listViewEditor->labelWidget(); + layout->addWidget(widget); + } + + { + QWidget* widget = m_listViewEditor->editorWidget(); + layout->addWidget(widget); + } } //-------------------------------------------------------------------------------------------------- @@ -76,11 +89,29 @@ PdmUiTableView::~PdmUiTableView() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTableView::setListField(PdmChildArrayFieldHandle* listField) +void PdmUiTableView::setChildArrayField(PdmChildArrayFieldHandle* childArrayField) { CAF_ASSERT(m_listViewEditor); - m_listViewEditor->setListField(listField); + if (childArrayField) + { + // Keep the possible custom context menu setting from the user of the table view. + // setUIField will set it based on the PdmUIItem settings, but turning the custom menu off should not + // be respected when using the field in a separate view. + auto orgContextPolicy = m_listViewEditor->tableView()->contextMenuPolicy(); + + m_listViewEditor->setUiField(childArrayField->uiCapability()); + + auto newContextPolicy = m_listViewEditor->tableView()->contextMenuPolicy(); + if (newContextPolicy == Qt::DefaultContextMenu) + { + m_listViewEditor->tableView()->setContextMenuPolicy(orgContextPolicy); + } + } + else + { + m_listViewEditor->setUiField(nullptr); + } // SIG_CAF_HACK m_listViewEditor->updateUi(m_uiConfigName); @@ -111,14 +142,6 @@ QTableView* PdmUiTableView::tableView() return m_listViewEditor->tableView(); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTableView::enableDefaultContextMenu(bool enable) -{ - m_listViewEditor->enableDefaultContextMenu(enable); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -128,27 +151,19 @@ void PdmUiTableView::enableHeaderText(bool enable) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void PdmUiTableView::setSelectionRole(SelectionManager::SelectionRole role) +void PdmUiTableView::setTableSelectionLevel(int selectionLevel) { - m_listViewEditor->setSelectionRole(role); + m_listViewEditor->setTableSelectionLevel(selectionLevel); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTableView::handleModelNotification(caf::PdmObjectHandle* itemThatChanged) +void PdmUiTableView::setRowSelectionLevel(int selectionLevel) { - // Nothing to do for now -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTableView::handleModelSelectionChange() -{ - m_listViewEditor->handleModelSelectionChange(); + m_listViewEditor->setRowSelectionLevel(selectionLevel); } //-------------------------------------------------------------------------------------------------- @@ -159,37 +174,18 @@ PdmObjectHandle* PdmUiTableView::pdmObjectFromModelIndex(const QModelIndex& mi) return m_listViewEditor->pdmObjectFromModelIndex(mi); } - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTableViewEditorAttribute::registerPushButtonTextForFieldKeyword(const QString& keyword, const QString& text) -{ - m_fieldKeywordAndPushButtonText[keyword] = text; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool PdmUiTableViewEditorAttribute::showPushButtonForFieldKeyword(const QString& keyword) const +void PdmUiTableView::addActionsToMenu(QMenu* menu, PdmChildArrayFieldHandle* childArrayField) { - if (m_fieldKeywordAndPushButtonText.count(keyword) > 0) return true; + // This is function is required to execute before populating the menu + // Several commands rely on the activeChildArrayFieldHandle in the selection manager + SelectionManager::instance()->setActiveChildArrayFieldHandle(childArrayField); - return false; + caf::PdmUiCommandSystemProxy::instance()->populateMenuWithDefaultCommands("PdmUiTreeViewEditor", menu); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QString PdmUiTableViewEditorAttribute::pushButtonText(const QString& keyword) const -{ - if (showPushButtonForFieldKeyword(keyword)) - { - return m_fieldKeywordAndPushButtonText.at(keyword); - } - - return ""; -} } //End of namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.h index 855562ee4e..a8d3d9614a 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableView.h @@ -39,13 +39,13 @@ #include "cafNotificationCenter.h" #include "cafPdmUiFieldEditorHandle.h" -#include "cafSelectionManager.h" #include #include #include class QTableView; +class QMenu; namespace caf { @@ -54,46 +54,28 @@ class PdmObjectHandle; class PdmUiTableViewEditor; class PdmChildArrayFieldHandle; -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -class PdmUiTableViewEditorAttribute : public PdmUiEditorAttribute -{ -public: - void registerPushButtonTextForFieldKeyword(const QString& keyword, const QString& text); - - bool showPushButtonForFieldKeyword(const QString& keyword) const; - QString pushButtonText(const QString& keyword) const; - -private: - std::map m_fieldKeywordAndPushButtonText; -}; //================================================================================================== /// //================================================================================================== -class PdmUiTableView : public QWidget, public DataModelObserver +class PdmUiTableView : public QWidget { Q_OBJECT public: PdmUiTableView(QWidget* parent = nullptr, Qt::WindowFlags f = nullptr); - ~PdmUiTableView(); - - PdmObjectHandle* pdmObjectFromModelIndex(const QModelIndex& mi); + ~PdmUiTableView() override; - // SIG_CAF_HACK - void setUiConfigurationName(QString uiConfigName); + void setChildArrayField(PdmChildArrayFieldHandle* childArrayField); + void setUiConfigurationName(QString uiConfigName); + void enableHeaderText(bool enable); + void setTableSelectionLevel(int selectionLevel); + void setRowSelectionLevel(int selectionLevel); - void setListField(PdmChildArrayFieldHandle* object); - - void enableDefaultContextMenu(bool enable); - void enableHeaderText(bool enable); - void setSelectionRole(SelectionManager::SelectionRole role); + PdmObjectHandle* pdmObjectFromModelIndex(const QModelIndex& mi); - QTableView* tableView(); + QTableView* tableView(); - virtual void handleModelNotification(caf::PdmObjectHandle* itemThatChanged); - virtual void handleModelSelectionChange(); + static void addActionsToMenu(QMenu* menu, PdmChildArrayFieldHandle* childArrayField); private: PdmUiTableViewEditor* m_listViewEditor; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.cpp index b106c6a0a0..d9eb426441 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.cpp @@ -37,7 +37,7 @@ #include "cafPdmUiTableViewDelegate.h" #include "cafPdmUiFieldEditorHandle.h" -#include "cafPdmUiTableViewModel.h" +#include "cafPdmUiTableViewQModel.h" @@ -47,7 +47,7 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiTableViewDelegate::PdmUiTableViewDelegate(QObject* parent, PdmUiTableViewModel* model) +PdmUiTableViewDelegate::PdmUiTableViewDelegate(QObject* parent, PdmUiTableViewQModel* model) : QStyledItemDelegate(parent), m_model(model) { @@ -112,6 +112,22 @@ bool PdmUiTableViewDelegate::isEditorOpen() const return m_activeEditorCount > 0; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItemV4 viewItemOption(option); + + QVariant fgText = index.data(Qt::ForegroundRole); + + if (fgText.canConvert()){ + viewItemOption.palette.setColor(QPalette::Active, QPalette::HighlightedText, qvariant_cast(fgText)); + viewItemOption.palette.setColor(QPalette::Inactive, QPalette::HighlightedText, qvariant_cast(fgText)); + } + + this->QStyledItemDelegate::paint(painter, viewItemOption, index); +} } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.h index 5419640c1a..83ee0982b5 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewDelegate.h @@ -43,7 +43,7 @@ namespace caf { -class PdmUiTableViewModel; +class PdmUiTableViewQModel; //-------------------------------------------------------------------------------------------------- @@ -54,20 +54,23 @@ class PdmUiTableViewDelegate : public QStyledItemDelegate Q_OBJECT public: - PdmUiTableViewDelegate(QObject* parent, PdmUiTableViewModel* model); - ~PdmUiTableViewDelegate(); + PdmUiTableViewDelegate(QObject* parent, PdmUiTableViewQModel* model); + ~PdmUiTableViewDelegate() override; - QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; - void setEditorData(QWidget* editor, const QModelIndex& index) const; - void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const; + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + void setEditorData(QWidget* editor, const QModelIndex& index) const override; + void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override; bool isEditorOpen() const; -protected slots: + protected slots: void slotEditorDestroyed(QObject* obj); +protected: + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + private: - PdmUiTableViewModel* m_model; + PdmUiTableViewQModel* m_model; // Counter for active table cell editors mutable int m_activeEditorCount; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.cpp index 05c89f41e5..6d651de5d3 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.cpp @@ -33,127 +33,107 @@ // for more details. // //################################################################################################## - - #include "cafPdmUiTableViewEditor.h" #include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmUiCheckBoxDelegate.h" -#include "cafPdmUiCommandSystemProxy.h" #include "cafPdmUiEditorHandle.h" #include "cafPdmUiTableViewDelegate.h" -#include "cafPdmUiTableViewModel.h" +#include "cafPdmUiTableViewQModel.h" +#include "cafSelectionManager.h" #include #include #include +#include #include #include #include #include - - namespace caf { -class FocusEventHandler : public QObject -{ -public: - explicit FocusEventHandler(PdmUiTableViewEditor* tableViewEditor) - : QObject(tableViewEditor) - { - m_tableViewEditor = tableViewEditor; - } - -protected: - bool eventFilter(QObject *obj, QEvent *event) - { - if (event->type() == QEvent::FocusIn || - event->type() == QEvent::FocusOut) - { - m_tableViewEditor->tableViewWidgetFocusChanged(event); - } - - // standard event processing - return QObject::eventFilter(obj, event); - } - - -private: - PdmUiTableViewEditor* m_tableViewEditor; -}; +CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiTableViewEditor); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- PdmUiTableViewEditor::PdmUiTableViewEditor() { - m_layout = nullptr;; m_tableView = nullptr; m_tableHeading = nullptr; m_tableModelPdm = nullptr; m_tableHeadingIcon = nullptr; - m_pdmListField = nullptr; m_delegate = nullptr; + m_previousFieldHandle = nullptr; m_useDefaultContextMenu = false; - m_checkboxDelegate = new PdmUiCheckBoxDelegate(this); + m_checkboxDelegate = new PdmUiCheckBoxDelegate(); - m_selectionRole = SelectionManager::CURRENT; + m_tableSelectionLevel = SelectionManager::BASE_LEVEL; + m_rowSelectionLevel = SelectionManager::FIRST_LEVEL; + m_isBlockingSelectionManagerChanged = false; + m_isUpdatingSelectionQModel = false; } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- PdmUiTableViewEditor::~PdmUiTableViewEditor() { + if (m_checkboxDelegate) m_checkboxDelegate->deleteLater(); + if (m_delegate) m_delegate->deleteLater(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QWidget* PdmUiTableViewEditor::createWidget(QWidget* parent) +QWidget* PdmUiTableViewEditor::createEditorWidget(QWidget* parent) { - m_mainWidget = new QWidget(parent); - - m_layout = new QVBoxLayout(); - m_layout->setContentsMargins(0, 0, 0, 0); - m_mainWidget->setLayout(m_layout); - - m_tableModelPdm = new PdmUiTableViewModel(m_mainWidget); + m_tableModelPdm = new PdmUiTableViewQModel(parent); - m_delegate = new PdmUiTableViewDelegate(this, m_tableModelPdm); + m_delegate = new PdmUiTableViewDelegate(nullptr, m_tableModelPdm); - m_tableView = new QTableView(m_mainWidget); + m_tableView = new QTableView(parent); m_tableView->setShowGrid(true); m_tableView->setModel(m_tableModelPdm); + m_tableView->installEventFilter(this); connect(m_tableView->selectionModel(), SIGNAL(selectionChanged( const QItemSelection & , const QItemSelection & )), SLOT(slotSelectionChanged( const QItemSelection & , const QItemSelection & ))); - connect(m_tableView->selectionModel(), SIGNAL(currentChanged( const QModelIndex & , const QModelIndex & )), SLOT(slotCurrentChanged( const QModelIndex& , const QModelIndex& ))); - FocusEventHandler* tableViewWidgetFocusEventHandler = new FocusEventHandler(this); - m_tableView->installEventFilter(tableViewWidgetFocusEventHandler); + return m_tableView; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* PdmUiTableViewEditor::createLabelWidget(QWidget * parent) +{ + if (m_tableHeading.isNull()) + { + m_tableHeading = new QLabel(parent); + } - updateContextMenuSignals(); + if (m_tableHeadingIcon.isNull()) + { + m_tableHeadingIcon = new QLabel(parent); + } QHBoxLayout* layoutForIconLabel = new QHBoxLayout(); - m_tableHeading = new QLabel(m_mainWidget); - m_tableHeadingIcon = new QLabel(m_mainWidget); + layoutForIconLabel->setMargin(0); layoutForIconLabel->addWidget(m_tableHeadingIcon); - layoutForIconLabel->addSpacing(5); + layoutForIconLabel->addSpacing(3); layoutForIconLabel->addWidget(m_tableHeading); layoutForIconLabel->addStretch(); + + QWidget* widget = new QWidget(parent); + widget->setLayout(layoutForIconLabel); - m_layout->addItem(layoutForIconLabel); - - m_layout->addWidget(m_tableView); - - return m_mainWidget; + return widget; } //-------------------------------------------------------------------------------------------------- @@ -161,7 +141,29 @@ QWidget* PdmUiTableViewEditor::createWidget(QWidget* parent) //-------------------------------------------------------------------------------------------------- void PdmUiTableViewEditor::configureAndUpdateUi(const QString& uiConfigName) { - m_tableModelPdm->setPdmData(m_pdmListField, uiConfigName); + if (!m_tableModelPdm) return; + + auto childArrayFH = childArrayFieldHandle(); + + PdmUiTableViewEditorAttribute editorAttrib; + bool editorAttribLoaded = false; + + if ( childArrayFH && childArrayFH->ownerObject() && childArrayFH->ownerObject()->uiCapability() ) + { + childArrayFH->ownerObject()->uiCapability()->editorAttribute(childArrayFH, uiConfigName, &editorAttrib); + editorAttribLoaded = true; + + this->setTableSelectionLevel(editorAttrib.tableSelectionLevel); + this->setRowSelectionLevel(editorAttrib.rowSelectionLevel); + this->enableHeaderText(editorAttrib.enableHeaderText); + + QPalette myPalette(m_tableView->palette()); + myPalette.setColor(QPalette::Base, editorAttrib.baseColor); + m_tableView->setPalette(myPalette); + + } + + m_tableModelPdm->setArrayFieldAndBuildEditors(childArrayFH, uiConfigName); if (m_tableModelPdm->rowCount() > 0) { @@ -178,12 +180,19 @@ void PdmUiTableViewEditor::configureAndUpdateUi(const QString& uiConfigName) } } - if (m_pdmListField && m_pdmListField->uiCapability()) + if (childArrayFH && childArrayFH->uiCapability()) { QString text = ""; - m_tableHeadingIcon->setPixmap(m_pdmListField->uiCapability()->uiIcon(uiConfigName).pixmap(16, 16)); - m_tableHeading->setText(m_pdmListField->uiCapability()->uiName(uiConfigName) + QString(" (%1)").arg(m_pdmListField->size())); - + if ( childArrayFH->uiCapability()->uiIcon(uiConfigName).isNull() ) + { + m_tableHeadingIcon->setText(childArrayFH->uiCapability()->uiName(uiConfigName) + QString(" (%1)").arg(childArrayFH->size())); + m_tableHeading->setText(""); + } + else + { + m_tableHeadingIcon->setPixmap(childArrayFH->uiCapability()->uiIcon(uiConfigName).pixmap(16, 16)); + m_tableHeading->setText(childArrayFH->uiCapability()->uiName(uiConfigName) + QString(" (%1)").arg(childArrayFH->size())); + } m_tableModelPdm->createPersistentPushButtonWidgets(m_tableView); } else @@ -191,29 +200,45 @@ void PdmUiTableViewEditor::configureAndUpdateUi(const QString& uiConfigName) m_tableHeading->setText(""); m_tableHeadingIcon->setPixmap(QPixmap()); } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTableViewEditor::setListField(PdmChildArrayFieldHandle* pdmListField) -{ - m_pdmListField = pdmListField; + bool firstTimeConfiguringField = m_previousFieldHandle != childArrayFH; - caf::PdmUiFieldHandle* uifield = nullptr; - if (m_pdmListField) + if (firstTimeConfiguringField) { - uifield = m_pdmListField->uiCapability(); + if (editorAttrib.minimumHeight > 0) + { + m_tableView->setMinimumHeight(editorAttrib.minimumHeight); + } + + // Set specified widths (if any) + if (editorAttribLoaded) + { + int colCount = m_tableModelPdm->columnCount(); + for (int c = 0; c < colCount && c < static_cast(editorAttrib.columnWidths.size()); c++) + { + auto w = editorAttrib.columnWidths[c]; + if (w > 0) m_tableView->setColumnWidth(c, w); + } + } } - this->bindToPdmItem(uifield); - if (!m_pdmListField) + if (firstTimeConfiguringField || editorAttrib.alwaysEnforceResizePolicy) { - m_tableModelPdm->setPdmData(nullptr, ""); - m_tableHeading->setText(""); - m_tableHeadingIcon->setPixmap(QPixmap()); + if (editorAttrib.resizePolicy == PdmUiTableViewEditorAttribute::RESIZE_TO_FIT_CONTENT) + { + // Set default column widths + m_tableView->resizeColumnsToContents(); + } + else if (editorAttrib.resizePolicy == PdmUiTableViewEditorAttribute::RESIZE_TO_FILL_CONTAINER) + { + m_tableView->horizontalHeader()->setResizeMode(QHeaderView::Stretch); + } } + + m_previousFieldHandle = childArrayFH; + + // Set default row heights + m_tableView->resizeRowsToContents(); } //-------------------------------------------------------------------------------------------------- @@ -221,9 +246,8 @@ void PdmUiTableViewEditor::setListField(PdmChildArrayFieldHandle* pdmListField) //-------------------------------------------------------------------------------------------------- void PdmUiTableViewEditor::selectedUiItems(const QModelIndexList& modelIndexList, std::vector& objects) { - for (int i = 0; i < modelIndexList.size(); i++) + for (const QModelIndex& mi : modelIndexList) { - QModelIndex mi = modelIndexList[i]; int row = mi.row(); caf::PdmUiObjectHandle* uiObject = uiObj(m_tableModelPdm->pdmObjectForRow(row)); @@ -234,27 +258,6 @@ void PdmUiTableViewEditor::selectedUiItems(const QModelIndexList& modelIndexList } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTableViewEditor::customMenuRequested(QPoint pos) -{ - // This is function is required to execute before populating the menu - // Several commands rely on the activeChildArrayFieldHandle in the selection manager - SelectionManager::instance()->setActiveChildArrayFieldHandle(m_pdmListField); - - QMenu menu; - caf::PdmUiCommandSystemProxy::instance()->populateMenuWithDefaultCommands("PdmUiTreeViewEditor", &menu); - - if (menu.actions().size() > 0) - { - // Qt doc: QAbstractScrollArea and its subclasses that map the context menu event to coordinates of the viewport(). - QPoint globalPos = m_tableView->viewport()->mapToGlobal(pos); - - menu.exec(globalPos); - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -263,16 +266,6 @@ QTableView* PdmUiTableViewEditor::tableView() return m_tableView; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTableViewEditor::enableDefaultContextMenu(bool enable) -{ - m_useDefaultContextMenu = enable; - - updateContextMenuSignals(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -283,78 +276,60 @@ void PdmUiTableViewEditor::enableHeaderText(bool enable) } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void PdmUiTableViewEditor::updateContextMenuSignals() +void PdmUiTableViewEditor::setTableSelectionLevel(int selectionLevel) { - if (!m_tableView) return; - - if (m_useDefaultContextMenu) - { - m_tableView->setContextMenuPolicy(Qt::CustomContextMenu); - connect(m_tableView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint))); - } - else - { - m_tableView->setContextMenuPolicy(Qt::DefaultContextMenu); - disconnect(m_tableView, nullptr, this, nullptr); - } + m_tableSelectionLevel = selectionLevel; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTableViewEditor::setSelectionRole(SelectionManager::SelectionRole role) +void PdmUiTableViewEditor::setRowSelectionLevel(int selectionLevel) { - m_selectionRole = role; + m_rowSelectionLevel = selectionLevel; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTableViewEditor::slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous) +void PdmUiTableViewEditor::onSelectionManagerSelectionChanged( const std::set& changedSelectionLevels ) { - if (isSelectionRoleDefined()) - { - std::vector items; - QModelIndexList list; - list.append(current); - selectedUiItems(list, items); - - SelectionManager::instance()->setSelectedItems(items, m_selectionRole); - } -} + if (!m_tableView->isVisible() || m_isBlockingSelectionManagerChanged ) return; -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTableViewEditor::handleModelSelectionChange() -{ - if (isSelectionRoleDefined()) + if (isSelectionRoleDefined() && (changedSelectionLevels.count(m_rowSelectionLevel) )) { std::vector items; - SelectionManager::instance()->selectedItems(items, m_selectionRole); + SelectionManager::instance()->selectedItems(items, m_rowSelectionLevel); - // TODO: Handle multiple selection - if (items.size() == 1) + QItemSelection totalSelection; + for (auto item: items) { - PdmObject* pdmObj = dynamic_cast(items[0]); + PdmObject* pdmObj = dynamic_cast(item); QItemSelection itemSelection = m_tableModelPdm->modelIndexFromPdmObject(pdmObj); - if (itemSelection.size() > 0) - { - m_tableView->selectionModel()->select(itemSelection, QItemSelectionModel::SelectCurrent); - } + totalSelection.merge(itemSelection, QItemSelectionModel::Select); } + + m_isUpdatingSelectionQModel = true; + m_tableView->selectionModel()->select(totalSelection, QItemSelectionModel::SelectCurrent); + m_isUpdatingSelectionQModel = false; } } + //-------------------------------------------------------------------------------------------------- /// NOTE: If no selection role is defined, the selection manager is not changed, the selection in the /// editor is local to the editor //-------------------------------------------------------------------------------------------------- void PdmUiTableViewEditor::slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected) { - updateSelectionManagerFromTableSelection(); + if (!m_isUpdatingSelectionQModel) updateSelectionManagerFromTableSelection(); + + // Hack to circumvent missing redraw from Qt in certain situations, when selection has changed + + m_tableView->resize(m_tableView->width(), m_tableView->height() +1); + m_tableView->resize(m_tableView->width(), m_tableView->height() -1); } //-------------------------------------------------------------------------------------------------- @@ -362,7 +337,7 @@ void PdmUiTableViewEditor::slotSelectionChanged(const QItemSelection & selected, //-------------------------------------------------------------------------------------------------- bool PdmUiTableViewEditor::isSelectionRoleDefined() const { - return m_selectionRole != SelectionManager::UNDEFINED; + return m_rowSelectionLevel != SelectionManager::UNDEFINED; } //-------------------------------------------------------------------------------------------------- @@ -381,60 +356,100 @@ PdmObjectHandle* PdmUiTableViewEditor::pdmObjectFromModelIndex(const QModelIndex //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTableViewEditor::tableViewWidgetFocusChanged(QEvent* focusEvent) +void PdmUiTableViewEditor::updateSelectionManagerFromTableSelection() { - if (m_delegate->isEditorOpen()) - { - // The table view emits focus out when a table cell editor is active - // Do not update the selection when this state occurs - return; - } - if (isSelectionRoleDefined()) { - if (focusEvent->type() == QEvent::FocusIn) + std::set selectedRowObjects; + QModelIndexList modelIndexList = m_tableView->selectionModel()->selectedIndexes(); + for (const QModelIndex& mi : modelIndexList) + { + PdmObjectHandle* obj = m_tableModelPdm->pdmObjectForRow(mi.row()); + + if (obj && obj->uiCapability()) + { + selectedRowObjects.insert(obj->uiCapability()); + } + } + + std::vector newCompleteSelection; + + for (auto item : selectedRowObjects) { - updateSelectionManagerFromTableSelection(); + newCompleteSelection.push_back({ item, m_rowSelectionLevel }); } - else if (focusEvent->type() == QEvent::FocusOut) + + + if ( childArrayFieldHandle() && childArrayFieldHandle()->ownerObject() ) { - // Clearing the selection here causes the Menu to not display all items - // Not sure how this can be handled correctly - // SelectionManager::instance()->clear(m_selectionRole); + newCompleteSelection.push_back({ childArrayFieldHandle()->ownerObject()->uiCapability() , + m_tableSelectionLevel }); } + + m_isBlockingSelectionManagerChanged = true; + SelectionManager::instance()->setSelection(newCompleteSelection); + m_isBlockingSelectionManagerChanged = false; + + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTableViewEditor::eventFilter(QObject* obj, QEvent* event) +{ + if (event->type() == QEvent::FocusIn) + { + this->updateSelectionManagerFromTableSelection(); } + // standard event processing + return QObject::eventFilter(obj, event); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTableViewEditor::updateSelectionManagerFromTableSelection() +caf::PdmChildArrayFieldHandle* PdmUiTableViewEditor::childArrayFieldHandle() { - if (isSelectionRoleDefined()) + caf::PdmChildArrayFieldHandle* fieldHandle = nullptr; + if (this->uiField()) { - std::vector items; + fieldHandle = dynamic_cast(this->uiField()->fieldHandle()); + } - QModelIndexList modelIndexList = m_tableView->selectionModel()->selectedIndexes(); - for (int i = 0; i < modelIndexList.size(); i++) - { - QModelIndex mi = modelIndexList[i]; - PdmFieldHandle* pdmFieldHandle = m_tableModelPdm->getField(mi); + return fieldHandle; +} - if (pdmFieldHandle && pdmFieldHandle->uiCapability()) - { - items.push_back(pdmFieldHandle->uiCapability()); - } - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTableViewPushButtonEditorAttribute::registerPushButtonTextForFieldKeyword(const QString& keyword, const QString& text) +{ + m_fieldKeywordAndPushButtonText[keyword] = text; +} - if (items.size() > 1) - { - // Selection of a single row is handled by slotCurrentChanged() - // Multiple selection of fields is handled here - SelectionManager::instance()->setSelectedItems(items, m_selectionRole); - } - } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool PdmUiTableViewPushButtonEditorAttribute::showPushButtonForFieldKeyword(const QString& keyword) const +{ + if (m_fieldKeywordAndPushButtonText.count(keyword) > 0) return true; + + return false; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString PdmUiTableViewPushButtonEditorAttribute::pushButtonText(const QString& keyword) const +{ + if (showPushButtonForFieldKeyword(keyword)) + { + return m_fieldKeywordAndPushButtonText.at(keyword); + } + + return ""; +} } // end namespace caf diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.h index 2790490d75..c55c9cd6c9 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewEditor.h @@ -40,7 +40,7 @@ #include "cafPdmDocument.h" #include "cafPdmUiFieldEditorHandle.h" #include "cafPdmUiObjectEditorHandle.h" -#include "cafSelectionManager.h" +#include "cafSelectionChangedReceiver.h" #include #include @@ -48,7 +48,6 @@ class QItemSelection; class QLabel; -class QMenu; class QTableView; namespace caf @@ -58,69 +57,118 @@ class PdmUiCheckBoxDelegate; class PdmUiFieldEditorHandle; class PdmUiItem; class PdmUiTableViewDelegate; -class PdmUiTableViewModel; +class PdmUiTableViewQModel; +class PdmChildArrayFieldHandle; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class PdmUiTableViewPushButtonEditorAttribute : public PdmUiEditorAttribute +{ +public: + void registerPushButtonTextForFieldKeyword(const QString& keyword, const QString& text); + + bool showPushButtonForFieldKeyword(const QString& keyword) const; + QString pushButtonText(const QString& keyword) const; + +private: + std::map m_fieldKeywordAndPushButtonText; +}; + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class PdmUiTableViewEditorAttribute : public PdmUiEditorAttribute +{ +public: + enum ResizePolicy + { + NO_AUTOMATIC_RESIZE, + RESIZE_TO_FIT_CONTENT, + RESIZE_TO_FILL_CONTAINER + }; + + PdmUiTableViewEditorAttribute() + : tableSelectionLevel(0) + , rowSelectionLevel(1) + , enableHeaderText(true) + , minimumHeight(-1) + , alwaysEnforceResizePolicy(false) + , resizePolicy(NO_AUTOMATIC_RESIZE) + { + QPalette myPalette; + baseColor = myPalette.color(QPalette::Active, QPalette::Base); + } + + int selectionLevel; + int tableSelectionLevel; + int rowSelectionLevel; + bool enableHeaderText; + std::vector columnWidths; + int minimumHeight; ///< Not used if If < 0 + QColor baseColor; + bool alwaysEnforceResizePolicy; + ResizePolicy resizePolicy; +}; //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -class PdmUiTableViewEditor : public PdmUiEditorHandle +class PdmUiTableViewEditor : public PdmUiFieldEditorHandle, public SelectionChangedReceiver { Q_OBJECT + CAF_PDM_UI_FIELD_EDITOR_HEADER_INIT; public: PdmUiTableViewEditor(); - ~PdmUiTableViewEditor(); + ~PdmUiTableViewEditor() override; - void enableDefaultContextMenu(bool enable); void enableHeaderText(bool enable); - void setSelectionRole(SelectionManager::SelectionRole role); - - PdmObjectHandle* pdmObjectFromModelIndex(const QModelIndex& mi); - - void setListField(PdmChildArrayFieldHandle* pdmListField); - QWidget* createWidget(QWidget* parent); + void setTableSelectionLevel(int selectionLevel); + void setRowSelectionLevel(int selectionLevel); + PdmObjectHandle* pdmObjectFromModelIndex(const QModelIndex& mi); QTableView* tableView(); - void handleModelSelectionChange(); - void updatePersistentEditors() const; - protected: - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; + + void onSelectionManagerSelectionChanged( const std::set& changedSelectionLevels ) override; private: - void updateContextMenuSignals(); void selectedUiItems(const QModelIndexList& modelIndexList, std::vector& objects); bool isSelectionRoleDefined() const; - void tableViewWidgetFocusChanged(QEvent* focusEvent); void updateSelectionManagerFromTableSelection(); + bool eventFilter(QObject* obj, QEvent* event) override; + PdmChildArrayFieldHandle* childArrayFieldHandle(); + private slots: - void customMenuRequested(QPoint pos); - void slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous); void slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); private: friend class FocusEventHandler; - std::map m_fieldViews; - - QPointer m_mainWidget; - QLayout* m_layout; - QLabel* m_tableHeading; - QLabel* m_tableHeadingIcon; + QPointer m_tableHeading; + QPointer m_tableHeadingIcon; QTableView* m_tableView; - PdmUiTableViewModel* m_tableModelPdm; + PdmUiTableViewQModel* m_tableModelPdm; - PdmChildArrayFieldHandle* m_pdmListField; PdmUiTableViewDelegate* m_delegate; PdmUiCheckBoxDelegate* m_checkboxDelegate; bool m_useDefaultContextMenu; - SelectionManager::SelectionRole m_selectionRole; + int m_tableSelectionLevel; + int m_rowSelectionLevel; + bool m_isBlockingSelectionManagerChanged; + bool m_isUpdatingSelectionQModel; + + caf::PdmChildArrayFieldHandle* m_previousFieldHandle; }; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewQModel.cpp similarity index 68% rename from Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.cpp rename to Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewQModel.cpp index eb5e0c2b61..c9d71cfaaf 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewQModel.cpp @@ -35,16 +35,17 @@ //################################################################################################## -#include "cafPdmUiTableViewModel.h" +#include "cafPdmUiTableViewQModel.h" #include "cafPdmChildArrayField.h" #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmUiComboBoxEditor.h" #include "cafPdmUiCommandSystemProxy.h" +#include "cafPdmUiDateEditor.h" #include "cafPdmUiFieldEditorHelper.h" #include "cafPdmUiLineEditor.h" -#include "cafPdmUiTableItemEditor.h" +#include "cafPdmUiTableRowEditor.h" #include "cafPdmUiTableView.h" #include "cafSelectionManager.h" @@ -59,7 +60,7 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiTableViewModel::PdmUiTableViewModel(QWidget* parent) +PdmUiTableViewQModel::PdmUiTableViewQModel(QWidget* parent) : QAbstractTableModel(parent) { m_pdmList = nullptr; @@ -68,51 +69,30 @@ PdmUiTableViewModel::PdmUiTableViewModel(QWidget* parent) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int PdmUiTableViewModel::rowCount(const QModelIndex &parent /*= QModelIndex( ) */) const +int PdmUiTableViewQModel::rowCount(const QModelIndex &parent /*= QModelIndex( ) */) const { - if (!m_pdmList) return 0; + auto childArrayField = childArrayFieldHandle(); + if (childArrayField) + { + size_t itemCount = childArrayField->size(); + return static_cast(itemCount); + } - size_t itemCount = m_pdmList->size(); - return static_cast(itemCount); + return 0; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int PdmUiTableViewModel::columnCount(const QModelIndex &parent /*= QModelIndex( ) */) const +int PdmUiTableViewQModel::columnCount(const QModelIndex &parent /*= QModelIndex( ) */) const { return static_cast(m_modelColumnIndexToFieldIndex.size()); - - // SIG_CAF_HACK - // Magne hack to comment out code that crashed - /* - std::vector listObjects; - if (m_pdmList) - { - m_pdmList->childObjects(&listObjects); - - if (listObjects.size() > 0) - { - PdmObject* pdmObject = listObjects[0]; - if (pdmObject) - { - std::vector fields; - pdmObject->fields(fields); - - return static_cast(fields.size()); - } - } - } - - return 0; - */ } - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QVariant PdmUiTableViewModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const +QVariant PdmUiTableViewQModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const { if (role == Qt::DisplayRole) { @@ -136,7 +116,7 @@ QVariant PdmUiTableViewModel::headerData(int section, Qt::Orientation orientatio //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Qt::ItemFlags PdmUiTableViewModel::flags(const QModelIndex &index) const +Qt::ItemFlags PdmUiTableViewQModel::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::ItemIsEnabled; @@ -155,9 +135,16 @@ Qt::ItemFlags PdmUiTableViewModel::flags(const QModelIndex &index) const PdmUiFieldHandle* uiFieldHandle = getUiFieldHandle(index); if (uiFieldHandle) { - if (uiFieldHandle->isUiReadOnly(m_currentConfigName)) + if ( uiFieldHandle->isUiReadOnly(m_currentConfigName) ) { - flagMask = flagMask ^ Qt::ItemIsEditable; + if ( flagMask & Qt::ItemIsUserCheckable ) + { + flagMask = flagMask & (~Qt::ItemIsEnabled); + } + else + { + flagMask = flagMask ^ Qt::ItemIsEditable; // To make it selectable, but not editable + } } } return flagMask; @@ -166,14 +153,12 @@ Qt::ItemFlags PdmUiTableViewModel::flags(const QModelIndex &index) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool PdmUiTableViewModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) +bool PdmUiTableViewQModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) { if (role == Qt::CheckStateRole) { if (isRepresentingBoolean(index)) { - // Clear current selection, UI does not behave well for multiple selection - SelectionManager::instance()->clear(SelectionManager::CURRENT); bool toggleOn = (value == Qt::Checked); @@ -193,16 +178,29 @@ bool PdmUiTableViewModel::setData(const QModelIndex &index, const QVariant &valu //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QVariant PdmUiTableViewModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole */) const +QVariant PdmUiTableViewQModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole */) const { - if (role == Qt::TextColorRole) + if (role == Qt::ForegroundRole) { PdmFieldHandle* fieldHandle = getField(index); if (fieldHandle && fieldHandle->uiCapability()) { + QColor textColor = fieldHandle->uiCapability()->uiContentTextColor(m_currentConfigName); + if (fieldHandle->uiCapability()->isUiReadOnly(m_currentConfigName)) { - return Qt::lightGray; + if (textColor.isValid()) + { + return textColor.lighter(150); + } + else + { + return Qt::lightGray; + } + } + else if (textColor.isValid()) + { + return textColor; } } } @@ -220,23 +218,23 @@ QVariant PdmUiTableViewModel::data(const QModelIndex &index, int role /*= Qt::Di QString displayText; QList valuesSelectedInField = fieldValue.toList(); - if (valuesSelectedInField.size() > 0) + if (!valuesSelectedInField.empty()) { QList options; bool useOptionsOnly = true; options = uiFieldHandle->valueOptions(&useOptionsOnly); CAF_ASSERT(useOptionsOnly); // Not supported - for (QVariant v : valuesSelectedInField) + for (const QVariant& v : valuesSelectedInField) { - int index = v.toInt(); - if (index != -1) + int optionIndex = v.toInt(); + if (optionIndex != -1) { if (!displayText.isEmpty()) displayText += ", "; - if (index < options.size()) + if (optionIndex < options.size()) { - displayText += options.at(index).optionUiText(); + displayText += options.at(optionIndex).optionUiText(); } } } @@ -271,14 +269,34 @@ QVariant PdmUiTableViewModel::data(const QModelIndex &index, int role /*= Qt::Di // TODO: Create a function in pdmObject like this // virtual void defineDisplayString(const PdmFieldHandle* field, QString uiConfigName) {} - PdmUiLineEditorAttributeUiDisplayString leab; - uiObjForRow->editorAttribute(fieldHandle, m_currentConfigName, &leab); + { + PdmUiLineEditorAttributeUiDisplayString leab; + uiObjForRow->editorAttribute(fieldHandle, m_currentConfigName, &leab); + + if (!leab.m_displayString.isEmpty()) + { + val = leab.m_displayString; + } + } - if (!leab.m_displayString.isEmpty()) + if (val.isNull()) { - val = leab.m_displayString; + PdmUiDateEditorAttribute leab; + uiObjForRow->editorAttribute(fieldHandle, m_currentConfigName, &leab); + + QString dateFormat = leab.dateFormat; + if (!dateFormat.isEmpty()) + { + QDate date = uiFieldHandle->uiValue().toDate(); + if (date.isValid()) + { + QString displayString = date.toString(dateFormat); + val = displayString; + } + } } - else + + if (val.isNull()) { val = uiFieldHandle->uiValue(); } @@ -319,7 +337,18 @@ QVariant PdmUiTableViewModel::data(const QModelIndex &index, int role /*= Qt::Di } } } - + else if ( role == Qt::ToolTipRole ) + { + PdmUiFieldHandle* uiFieldHandle = getField(index)->uiCapability(); + if ( uiFieldHandle ) + { + return uiFieldHandle->uiToolTip(); + } + else + { + return QVariant(); + } + } return QVariant(); } @@ -327,23 +356,41 @@ QVariant PdmUiTableViewModel::data(const QModelIndex &index, int role /*= Qt::Di //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTableViewModel::setPdmData(PdmChildArrayFieldHandle* listField, const QString& configName) +void PdmUiTableViewQModel::setArrayFieldAndBuildEditors(PdmChildArrayFieldHandle* listField, const QString& configName) { beginResetModel(); - m_pdmList = listField; + { + PdmObjectHandle* ownerObject = nullptr; + if (listField) + { + ownerObject = listField->ownerObject(); + } + + if (ownerObject) + { + m_pdmList = listField; + m_ownerObject = ownerObject; + } + else + { + m_ownerObject = nullptr; + m_pdmList = nullptr; + } + } + m_currentConfigName = configName; PdmUiOrdering configForFirstObject; - if (m_pdmList && m_pdmList->size() > 0) + if (m_pdmList && !m_pdmList->empty()) { - PdmObjectHandle* pdmObjHandle = m_pdmList->at(0); - PdmUiObjectHandle* uiObject = pdmObjHandle->uiCapability(); - if (uiObject) + PdmObjectHandle* firstObject = m_pdmList->at(0); + PdmUiObjectHandle* uiHandleForFirstObject = firstObject->uiCapability(); + if (uiHandleForFirstObject) { - uiObject->uiOrdering(configName, configForFirstObject); - uiObject->objectEditorAttribute(m_currentConfigName, &m_attributes); + uiHandleForFirstObject->uiOrdering(configName, configForFirstObject); + uiHandleForFirstObject->objectEditorAttribute(m_currentConfigName, &m_pushButtonEditorAttributes); } } @@ -353,23 +400,22 @@ void PdmUiTableViewModel::setPdmData(PdmChildArrayFieldHandle* listField, const std::map::iterator it; for (it = m_fieldEditors.begin(); it != m_fieldEditors.end(); ++it) { - it->second->setField(nullptr); + it->second->setUiField(nullptr); } m_modelColumnIndexToFieldIndex.clear(); - for (size_t i = 0; i < uiItems.size(); ++i) + for (auto uiItem : uiItems) { - if (uiItems[i]->isUiHidden(configName)) continue; + if (uiItem->isUiHidden(configName)) continue; - if (uiItems[i]->isUiGroup()) continue; + if (uiItem->isUiGroup()) continue; { - PdmUiFieldHandle* field = dynamic_cast(uiItems[i]); + PdmUiFieldHandle* field = dynamic_cast(uiItem); PdmUiFieldEditorHandle* fieldEditor = nullptr; // Find or create FieldEditor - std::map::iterator it; it = m_fieldEditors.find(field->fieldHandle()->keyword()); if (it == m_fieldEditors.end()) @@ -388,7 +434,7 @@ void PdmUiTableViewModel::setPdmData(PdmChildArrayFieldHandle* listField, const if (fieldEditor) { - fieldEditor->setField(field); + fieldEditor->setUiField(field); //TODO: Create/update is not required at this point, as UI is recreated in getEditorWidgetAndTransferOwnership() // Can be moved, but a move will require changes in PdmUiFieldEditorHandle @@ -407,7 +453,7 @@ void PdmUiTableViewModel::setPdmData(PdmChildArrayFieldHandle* listField, const std::vector< QString > fvhToRemoveFromMap; for (it = m_fieldEditors.begin(); it != m_fieldEditors.end(); ++it) { - if (it->second->field() == nullptr) + if (it->second->uiField() == nullptr) { PdmUiFieldEditorHandle* fvh = it->second; delete fvh; @@ -415,25 +461,39 @@ void PdmUiTableViewModel::setPdmData(PdmChildArrayFieldHandle* listField, const } } - for (size_t i = 0; i < fvhToRemoveFromMap.size(); ++i) + for (const auto& fieldEditorName : fvhToRemoveFromMap) { - m_fieldEditors.erase(fvhToRemoveFromMap[i]); + m_fieldEditors.erase(fieldEditorName); } recreateTableItemEditors(); endResetModel(); + + if (m_pdmList) + { + // Update UI for all cells, as the content potentially has changed + // This will probably cause performance issues for large tables + + for (auto tableItemEditor : m_tableRowEditors) + { + tableItemEditor->updateUi(configName); + } + + } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmFieldHandle* PdmUiTableViewModel::getField(const QModelIndex &index) const +PdmFieldHandle* PdmUiTableViewQModel::getField(const QModelIndex &index) const { - if (m_pdmList && index.row() < static_cast(m_pdmList->size())) + auto childArrayField = childArrayFieldHandle(); + + if (childArrayField && index.row() < static_cast(childArrayField->size())) { - PdmObjectHandle* pdmObject = m_pdmList->at(index.row()); + PdmObjectHandle* pdmObject = childArrayField->at(index.row()); if (pdmObject) { std::vector fields; @@ -457,7 +517,7 @@ PdmFieldHandle* PdmUiTableViewModel::getField(const QModelIndex &index) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiFieldEditorHandle* PdmUiTableViewModel::getEditor(const QModelIndex &index) +PdmUiFieldEditorHandle* PdmUiTableViewQModel::getEditor(const QModelIndex &index) { PdmFieldHandle* field = getField(index); if (!field) @@ -477,7 +537,7 @@ PdmUiFieldEditorHandle* PdmUiTableViewModel::getEditor(const QModelIndex &index) { if (field) { - editor->setField(field->uiCapability()); + editor->setUiField(field->uiCapability()); } } } @@ -488,7 +548,7 @@ PdmUiFieldEditorHandle* PdmUiTableViewModel::getEditor(const QModelIndex &index) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QWidget* PdmUiTableViewModel::getEditorWidgetAndTransferOwnership(QWidget* parent, const QModelIndex &index) +QWidget* PdmUiTableViewQModel::getEditorWidgetAndTransferOwnership(QWidget* parent, const QModelIndex &index) { PdmUiFieldEditorHandle* editor = getEditor(index); if (editor) @@ -509,7 +569,7 @@ QWidget* PdmUiTableViewModel::getEditorWidgetAndTransferOwnership(QWidget* paren //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTableViewModel::notifyDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) +void PdmUiTableViewQModel::notifyDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight) { emit dataChanged(topLeft, bottomRight); } @@ -517,20 +577,21 @@ void PdmUiTableViewModel::notifyDataChanged(const QModelIndex& topLeft, const QM //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTableViewModel::recreateTableItemEditors() +void PdmUiTableViewQModel::recreateTableItemEditors() { - for (size_t i = 0; i < m_tableItemEditors.size(); i++) + for (auto tableItemEditor : m_tableRowEditors) { - delete m_tableItemEditors[i]; + delete tableItemEditor; } - m_tableItemEditors.clear(); + m_tableRowEditors.clear(); - if (m_pdmList) + auto childArrayField = childArrayFieldHandle(); + if (childArrayField) { - for (size_t i = 0; i < m_pdmList->size(); i++) + for (size_t i = 0; i < childArrayField->size(); i++) { - PdmObjectHandle* pdmObject = m_pdmList->at(i); - m_tableItemEditors.push_back(new PdmUiTableItemEditor(this, pdmObject, static_cast(i))); + PdmObjectHandle* pdmObject = childArrayField->at(i); + m_tableRowEditors.push_back(new PdmUiTableRowEditor(this, pdmObject, static_cast(i))); } } } @@ -538,7 +599,7 @@ void PdmUiTableViewModel::recreateTableItemEditors() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -caf::PdmUiFieldHandle* PdmUiTableViewModel::getUiFieldHandle(const QModelIndex& index) const +caf::PdmUiFieldHandle* PdmUiTableViewQModel::getUiFieldHandle(const QModelIndex& index) const { auto fieldHandle = getField(index); if (fieldHandle) @@ -552,11 +613,12 @@ caf::PdmUiFieldHandle* PdmUiTableViewModel::getUiFieldHandle(const QModelIndex& //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmObjectHandle* PdmUiTableViewModel::pdmObjectForRow(int row) const +PdmObjectHandle* PdmUiTableViewQModel::pdmObjectForRow(int row) const { - if (m_pdmList && row < static_cast(m_pdmList->size())) + auto childArrayField = childArrayFieldHandle(); + if (childArrayField && row < static_cast(childArrayField->size())) { - return m_pdmList->at(row); + return childArrayField->at(row); } return nullptr; @@ -565,12 +627,12 @@ PdmObjectHandle* PdmUiTableViewModel::pdmObjectForRow(int row) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool PdmUiTableViewModel::isRepresentingBoolean(const QModelIndex &index) const +bool PdmUiTableViewQModel::isRepresentingBoolean(const QModelIndex &index) const { PdmFieldHandle* fieldHandle = getField(index); if (fieldHandle) { - if (m_attributes.showPushButtonForFieldKeyword(fieldHandle->keyword())) + if (m_pushButtonEditorAttributes.showPushButtonForFieldKeyword(fieldHandle->keyword())) { return false; } @@ -588,20 +650,20 @@ bool PdmUiTableViewModel::isRepresentingBoolean(const QModelIndex &index) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTableViewModel::createPersistentPushButtonWidgets(QTableView* tableView) +void PdmUiTableViewQModel::createPersistentPushButtonWidgets(QTableView* tableView) { if (rowCount() > 0) { for (int col = 0; col < columnCount(); col++) { PdmFieldHandle* fieldHandle = getField(createIndex(0, col)); - if (m_attributes.showPushButtonForFieldKeyword(fieldHandle->keyword())) + if (m_pushButtonEditorAttributes.showPushButtonForFieldKeyword(fieldHandle->keyword())) { for (int row = 0; row < rowCount(); row++) { QModelIndex mi = createIndex(row, col); - tableView->setIndexWidget(mi, new TableViewPushButton(getField(mi)->uiCapability(), m_attributes.pushButtonText(fieldHandle->keyword()))); + tableView->setIndexWidget(mi, new TableViewPushButton(getField(mi)->uiCapability(), m_pushButtonEditorAttributes.pushButtonText(fieldHandle->keyword()))); tableView->openPersistentEditor(mi); } } @@ -612,7 +674,7 @@ void PdmUiTableViewModel::createPersistentPushButtonWidgets(QTableView* tableVie //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QItemSelection PdmUiTableViewModel::modelIndexFromPdmObject(PdmObjectHandle* pdmObject) +QItemSelection PdmUiTableViewQModel::modelIndexFromPdmObject(PdmObjectHandle* pdmObject) { QItemSelection itemSelection; @@ -621,8 +683,8 @@ QItemSelection PdmUiTableViewModel::modelIndexFromPdmObject(PdmObjectHandle* pdm PdmObjectHandle* obj = this->pdmObjectForRow(i); if (obj == pdmObject) { - // Currently selection only on model index, can be exteded to select whole row - itemSelection.select(this->createIndex(i, 0), this->createIndex(i, 0)); + // Select whole row + itemSelection.select(this->createIndex(i, 0), this->createIndex(i, this->columnCount())); } } @@ -632,11 +694,29 @@ QItemSelection PdmUiTableViewModel::modelIndexFromPdmObject(PdmObjectHandle* pdm //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int PdmUiTableViewModel::getFieldIndex(PdmFieldHandle* field) const +caf::PdmChildArrayFieldHandle* PdmUiTableViewQModel::childArrayFieldHandle() const +{ + // Required to have a PdmPointer to the owner object. Used to guard access to a field inside this object. It is not + // possible to use a PdmPointer on a field pointer + if (m_ownerObject.isNull()) + { + return nullptr; + } + + return m_pdmList; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int PdmUiTableViewQModel::getFieldIndex(PdmFieldHandle* field) const { - if (m_pdmList && m_pdmList->size() > 0) + auto childArrayField = childArrayFieldHandle(); + + if (childArrayField && !childArrayField->empty()) { - PdmObjectHandle* pdmObject = m_pdmList->at(0); + PdmObjectHandle* pdmObject = childArrayField->at(0); if (pdmObject) { std::vector fields; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewQModel.h similarity index 75% rename from Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.h rename to Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewQModel.h index 18cde6c980..28ec360adb 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewModel.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTableViewQModel.h @@ -39,7 +39,7 @@ #include "cafPdmUiTreeOrdering.h" #include "cafPdmUiFieldHandle.h" -#include "cafPdmUiTableView.h" +#include "cafPdmUiTableViewEditor.h" #include #include @@ -52,7 +52,7 @@ class PdmChildArrayFieldHandle; class PdmObjectHandle; class PdmUiFieldEditorHandle; class PdmUiItem; -class PdmUiTableItemEditor; +class PdmUiTableRowEditor; class PdmUiTreeOrdering; class PdmUiTreeViewEditor; @@ -77,26 +77,26 @@ private slots: //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -class PdmUiTableViewModel : public QAbstractTableModel +class PdmUiTableViewQModel : public QAbstractTableModel { Q_OBJECT public: - explicit PdmUiTableViewModel(QWidget* parent); + explicit PdmUiTableViewQModel(QWidget* parent); QItemSelection modelIndexFromPdmObject(PdmObjectHandle* pdmObject); PdmFieldHandle* getField(const QModelIndex &index) const; - void setPdmData(PdmChildArrayFieldHandle* pdmObject, const QString& configName); + void setArrayFieldAndBuildEditors(PdmChildArrayFieldHandle* pdmObject, const QString& configName); PdmObjectHandle* pdmObjectForRow(int row) const; // Qt overrides - virtual int rowCount( const QModelIndex &parent = QModelIndex( ) ) const; - virtual int columnCount( const QModelIndex &parent = QModelIndex( ) ) const; - virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const; - virtual QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; + int rowCount( const QModelIndex &parent = QModelIndex( ) ) const override; + int columnCount( const QModelIndex &parent = QModelIndex( ) ) const override; + QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override; + QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + Qt::ItemFlags flags(const QModelIndex &index) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; void notifyDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); @@ -113,16 +113,20 @@ class PdmUiTableViewModel : public QAbstractTableModel QWidget* getEditorWidgetAndTransferOwnership(QWidget* parent, const QModelIndex &index); PdmUiFieldEditorHandle* getEditor(const QModelIndex &index); + PdmChildArrayFieldHandle* childArrayFieldHandle() const; + private: + // Required to have a PdmPointer to the owner object. Used to guard access to a field inside this object + PdmPointer m_ownerObject; PdmChildArrayFieldHandle* m_pdmList; QString m_currentConfigName; std::map m_fieldEditors; std::vector m_modelColumnIndexToFieldIndex; - std::vector m_tableItemEditors; + std::vector m_tableRowEditors; - PdmUiTableViewEditorAttribute m_attributes; + PdmUiTableViewPushButtonEditorAttribute m_pushButtonEditorAttributes; }; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.cpp index 737672288d..785bdb2837 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.cpp @@ -109,16 +109,16 @@ void PdmUiTextEditor::configureAndUpdateUi(const QString& uiConfigName) PdmUiFieldEditorHandle::updateLabelFromField(m_label, uiConfigName); - m_textEdit->setReadOnly(field()->isUiReadOnly(uiConfigName)); + m_textEdit->setReadOnly(uiField()->isUiReadOnly(uiConfigName)); //m_textEdit->setEnabled(!field()->isUiReadOnly(uiConfigName)); // Neccesary ? - m_textEdit->setToolTip(field()->uiToolTip(uiConfigName)); + m_textEdit->setToolTip(uiField()->uiToolTip(uiConfigName)); PdmUiTextEditorAttribute leab; - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &leab); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &leab); } m_textMode = leab.textMode; @@ -138,10 +138,10 @@ void PdmUiTextEditor::configureAndUpdateUi(const QString& uiConfigName) switch (leab.textMode) { case PdmUiTextEditorAttribute::PLAIN: - m_textEdit->setPlainText(field()->uiValue().toString()); + m_textEdit->setPlainText(uiField()->uiValue().toString()); break; case PdmUiTextEditorAttribute::HTML: - m_textEdit->setHtml(field()->uiValue().toString()); + m_textEdit->setHtml(uiField()->uiValue().toString()); break; } m_textEdit->blockSignals(false); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.h index e0e9fc07a0..5b0efa0279 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTextEditor.h @@ -94,11 +94,11 @@ class TextEdit : public QTextEdit public: explicit TextEdit(QWidget *parent = nullptr); - virtual QSize sizeHint() const override; + QSize sizeHint() const override; void setHeightHint(int heightHint); protected: - virtual void focusOutEvent(QFocusEvent *e); + void focusOutEvent(QFocusEvent *e) override; signals: void editingFinished(); @@ -118,15 +118,15 @@ class PdmUiTextEditor : public PdmUiFieldEditorHandle public: PdmUiTextEditor() { m_textMode = PdmUiTextEditorAttribute::PLAIN; } - virtual ~PdmUiTextEditor() {} + ~PdmUiTextEditor() override {} protected: - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; protected slots: - void slotSetValueToField(); + void slotSetValueToField(); private: QTextOption::WrapMode toQTextOptionWrapMode(PdmUiTextEditorAttribute::WrapMode wrapMode); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.cpp index 5841cc4ff7..addd9bce83 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.cpp @@ -166,7 +166,7 @@ void PdmUiToolBarEditor::configureAndUpdateUi(const QString& uiConfigName) m_toolbar->addWidget(widget); } - fieldEditor->setField(uiFieldHandle); + fieldEditor->setUiField(uiFieldHandle); fieldEditor->updateUi(uiConfigName); } } diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.h index fc9a4f4e4f..4b48d7be35 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolBarEditor.h @@ -59,7 +59,7 @@ class PdmUiToolBarEditor : public PdmUiEditorHandle { public: PdmUiToolBarEditor(const QString& title, QMainWindow* mainWindow); - ~PdmUiToolBarEditor(); + ~PdmUiToolBarEditor() override; bool isEditorDataValid(const std::vector& fields) const; void setFields(std::vector& fields); @@ -69,7 +69,7 @@ class PdmUiToolBarEditor : public PdmUiEditorHandle void hide(); private: - virtual void configureAndUpdateUi(const QString& uiConfigName) override; + void configureAndUpdateUi(const QString& uiConfigName) override; private: QPointer m_toolbar; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.cpp index 872565ffbf..d8cbe1169c 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.cpp @@ -56,32 +56,33 @@ void PdmUiToolButtonEditor::configureAndUpdateUi(const QString& uiConfigName) { CAF_ASSERT(!m_toolButton.isNull()); - QIcon ic = field()->uiIcon(uiConfigName); + QIcon ic = uiField()->uiIcon(uiConfigName); if (!ic.isNull()) { m_toolButton->setIcon(ic); } - QString buttonText = field()->uiName(uiConfigName); + QString buttonText = uiField()->uiName(uiConfigName); m_toolButton->setText(buttonText); - m_toolButton->setEnabled(!field()->isUiReadOnly(uiConfigName)); - m_toolButton->setToolTip(field()->uiToolTip(uiConfigName)); + m_toolButton->setEnabled(!uiField()->isUiReadOnly(uiConfigName)); + m_toolButton->setToolTip(uiField()->uiToolTip(uiConfigName)); PdmUiToolButtonEditorAttribute attributes; - PdmUiObjectHandle* pdmUiOjectHandle = uiObj(field()->fieldHandle()->ownerObject()); + PdmUiObjectHandle* pdmUiOjectHandle = uiObj(uiField()->fieldHandle()->ownerObject()); if (pdmUiOjectHandle) { - pdmUiOjectHandle->editorAttribute(field()->fieldHandle(), uiConfigName, &attributes); + pdmUiOjectHandle->editorAttribute(uiField()->fieldHandle(), uiConfigName, &attributes); } bool isCheckable = attributes.m_checkable; m_toolButton->setCheckable(isCheckable); + m_toolButton->setSizePolicy(attributes.m_sizePolicy); - QVariant variantFieldValue = field()->uiValue(); + QVariant variantFieldValue = uiField()->uiValue(); if (isCheckable) { - m_toolButton->setChecked(field()->uiValue().toBool()); + m_toolButton->setChecked(uiField()->uiValue().toBool()); } } diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.h index 6d86c9f8bc..e301e6885b 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiToolButtonEditor.h @@ -56,6 +56,7 @@ class PdmUiToolButtonEditorAttribute : public PdmUiEditorAttribute public: bool m_checkable; + QSizePolicy m_sizePolicy; }; @@ -66,15 +67,15 @@ class PdmUiToolButtonEditor : public PdmUiFieldEditorHandle public: PdmUiToolButtonEditor() {} - virtual ~PdmUiToolButtonEditor() {} + ~PdmUiToolButtonEditor() override {} protected: - virtual QWidget* createEditorWidget(QWidget * parent); - virtual QWidget* createLabelWidget(QWidget * parent); - virtual void configureAndUpdateUi(const QString& uiConfigName); + QWidget* createEditorWidget(QWidget * parent) override; + QWidget* createLabelWidget(QWidget * parent) override; + void configureAndUpdateUi(const QString& uiConfigName) override; protected slots: - void slotClicked(bool checked); + void slotClicked(bool checked); private: QPointer m_toolButton; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeEditorHandle.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeEditorHandle.h index a001cc1b84..f0030c0e06 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeEditorHandle.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeEditorHandle.h @@ -56,7 +56,7 @@ class PdmUiTreeEditorHandle: public PdmUiEditorHandle { public: PdmUiTreeEditorHandle() {} - ~PdmUiTreeEditorHandle() {} + ~PdmUiTreeEditorHandle() override {} QWidget* getOrCreateWidget(QWidget* parent); QWidget* widget() { return m_widget; } diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeItemEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeItemEditor.h index bb3915c55c..dc50856cd5 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeItemEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeItemEditor.h @@ -51,13 +51,13 @@ class PdmUiTreeItemEditor: public PdmUiEditorHandle { public: explicit PdmUiTreeItemEditor(PdmUiItem* uiItem); - virtual ~PdmUiTreeItemEditor() {}; + ~PdmUiTreeItemEditor() override {}; void setTreeViewEditor(PdmUiTreeEditorHandle* treeViewEditor) { m_treeViewEditor = treeViewEditor; } protected: // Interface to override: - virtual void configureAndUpdateUi(const QString& uiConfigName); + void configureAndUpdateUi(const QString& uiConfigName) override; private: PdmUiTreeEditorHandle* m_treeViewEditor; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.cpp index c481bfd86e..318af8448a 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.cpp @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -69,7 +70,7 @@ class QTreeViewHeightHint : public QTreeView //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual QSize sizeHint() const override + QSize sizeHint() const override { QSize mySize = QTreeView::sizeHint(); @@ -89,6 +90,21 @@ class QTreeViewHeightHint : public QTreeView m_heightHint = heightHint; } + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + void keyPressEvent(QKeyEvent *event) + { + QTreeView::keyPressEvent(event); + + if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Up || + event->key() == Qt::Key_Home || event->key() == Qt::Key_End || + event->key() == Qt::Key_PageDown || event->key() == Qt::Key_PageUp) + { + emit clicked(currentIndex()); + } + } + private: int m_heightHint; }; @@ -109,7 +125,7 @@ class FilterLeafNodesOnlyProxyModel : public QSortFilterProxyModel //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override + bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override { QModelIndex index = sourceModel()->index(source_row, 0, source_parent); @@ -141,7 +157,7 @@ class PlaceholderLineEdit : public QLineEdit //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- - virtual void paintEvent(QPaintEvent* paintEvent) override + void paintEvent(QPaintEvent* paintEvent) override { QPainter p(this); @@ -173,7 +189,6 @@ class PlaceholderLineEdit : public QLineEdit QRect lineRect(r.x() + horizontalMargin, vscroll, r.width() - 2*horizontalMargin, fm.height()); int minLB = qMax(0, -fm.minLeftBearing()); - int minRB = qMax(0, -fm.minRightBearing()); if (text().isEmpty()) { @@ -245,17 +260,17 @@ void PdmUiTreeSelectionEditor::configureAndUpdateUi(const QString& uiConfigName) m_treeView->setModel(m_proxyModel); - connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), - this, SLOT(slotCurrentChanged(QModelIndex, QModelIndex))); + connect(m_treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(slotCurrentChanged(QModelIndex, QModelIndex)), Qt::UniqueConnection); + } bool optionsOnly = true; - QList options = field()->valueOptions(&optionsOnly); + QList options = uiField()->valueOptions(&optionsOnly); bool itemCountHasChaged = false; if (m_model->optionItemCount() != options.size()) itemCountHasChaged = true; - QVariant fieldValue = field()->uiValue(); + QVariant fieldValue = uiField()->uiValue(); m_model->setUiValueCache(&fieldValue); // TODO: If the count is different between incoming and current list of items, @@ -274,10 +289,10 @@ void PdmUiTreeSelectionEditor::configureAndUpdateUi(const QString& uiConfigName) } else if (PdmUiTreeSelectionQModel::isMultipleValueField(fieldValue)) { - caf::PdmUiObjectHandle* uiObject = uiObj(field()->fieldHandle()->ownerObject()); + caf::PdmUiObjectHandle* uiObject = uiObj(uiField()->fieldHandle()->ownerObject()); if (uiObject) { - uiObject->editorAttribute(field()->fieldHandle(), uiConfigName, &m_attributes); + uiObject->editorAttribute(uiField()->fieldHandle(), uiConfigName, &m_attributes); } if (m_attributes.singleSelectionMode) @@ -292,7 +307,7 @@ void PdmUiTreeSelectionEditor::configureAndUpdateUi(const QString& uiConfigName) m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); } - connect(m_treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(slotClicked(QModelIndex))); + connect(m_treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(slotClicked(QModelIndex)), Qt::UniqueConnection); if (!m_attributes.showTextFilter) { @@ -314,21 +329,28 @@ void PdmUiTreeSelectionEditor::configureAndUpdateUi(const QString& uiConfigName) QModelIndexList indices = allVisibleSourceModelIndices(); if (indices.size() > 0) { - bool allItemsChecked = true; + size_t editableItems = 0u; + size_t checkedEditableItems = 0u; for (auto mi : indices) { - if (m_model->data(mi, Qt::CheckStateRole).toBool() == false) + if (!m_model->isReadOnly(mi)) { - allItemsChecked = false; + editableItems++; + if (m_model->isChecked(mi)) + { + checkedEditableItems++; + } } } - + bool allItemsChecked = (editableItems > 0u && checkedEditableItems == editableItems); m_toggleAllCheckBox->setChecked(allItemsChecked); } } } } - + // If the tree doesn't have grand children we treat this as a straight list + m_treeView->setRootIsDecorated(m_model->hasGrandChildren()); + m_model->resetUiValueCache(); } @@ -387,6 +409,23 @@ QWidget* PdmUiTreeSelectionEditor::createLabelWidget(QWidget * parent) return m_label; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QMargins PdmUiTreeSelectionEditor::calculateLabelContentMargins() const +{ + QSize editorSize = m_textFilterLineEdit->sizeHint(); + QSize labelSize = m_label->sizeHint(); + int heightDiff = editorSize.height() - labelSize.height(); + QMargins contentMargins = m_label->contentsMargins(); + if (heightDiff > 0) + { + contentMargins.setTop(contentMargins.top() + heightDiff / 2); + contentMargins.setBottom(contentMargins.bottom() + heightDiff / 2); + } + return contentMargins; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -448,6 +487,14 @@ void PdmUiTreeSelectionEditor::customMenuRequested(const QPoint& pos) } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeSelectionEditor::slotCurrentChanged(const QModelIndex& current, const QModelIndex& previous) +{ + currentChanged(current); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -551,7 +598,27 @@ void PdmUiTreeSelectionEditor::slotTextFilterChanged() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeSelectionEditor::slotCurrentChanged(const QModelIndex& current, const QModelIndex& previous) +void PdmUiTreeSelectionEditor::slotClicked(const QModelIndex& index) +{ + if (m_attributes.setCurrentIndexWhenItemIsChecked && index.isValid()) + { + QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes(); + if (selectedIndexes.size() < 2) + { + QVariant v = m_proxyModel->data(index, Qt::CheckStateRole); + if (v == Qt::Checked) + { + m_treeView->setCurrentIndex(index); + } + } + } + currentChanged(index); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmUiTreeSelectionEditor::currentChanged(const QModelIndex& current) { if (m_attributes.singleSelectionMode) { @@ -570,25 +637,6 @@ void PdmUiTreeSelectionEditor::slotCurrentChanged(const QModelIndex& current, co } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmUiTreeSelectionEditor::slotClicked(const QModelIndex& index) -{ - if (m_attributes.setCurrentIndexWhenItemIsChecked && index.isValid()) - { - QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes(); - if (selectedIndexes.size() < 2) - { - QVariant v = m_proxyModel->data(index, Qt::CheckStateRole); - if (v == Qt::Checked) - { - m_treeView->setCurrentIndex(index); - } - } - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.h index 41b8c6250e..5cb9fa88c3 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionEditor.h @@ -92,16 +92,18 @@ class PdmUiTreeSelectionEditor : public PdmUiFieldEditorHandle public: PdmUiTreeSelectionEditor(); - virtual ~PdmUiTreeSelectionEditor(); + ~PdmUiTreeSelectionEditor() override; protected: - virtual void configureAndUpdateUi(const QString& uiConfigName); - virtual QWidget* createEditorWidget(QWidget* parent); - virtual QWidget* createLabelWidget(QWidget* parent); + void configureAndUpdateUi(const QString& uiConfigName) override; + QWidget* createEditorWidget(QWidget* parent) override; + QWidget* createLabelWidget(QWidget* parent) override; + QMargins calculateLabelContentMargins() const override; private slots: void customMenuRequested(const QPoint& pos); + void slotCurrentChanged(const QModelIndex& current, const QModelIndex& previous); void slotSetSelectedOn(); void slotSetSelectedOff(); void slotSetSubItemsOn(); @@ -111,10 +113,11 @@ private slots: void slotTextFilterChanged(); - void slotCurrentChanged(const QModelIndex& current, const QModelIndex& previous); void slotClicked(const QModelIndex& index); private: + void currentChanged(const QModelIndex& current); + void setCheckedStateOfSelected(bool checked); void setCheckedStateForSubItemsOfSelected(bool checked); void checkAllItems(); diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionQModel.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionQModel.cpp index 0823e063bb..6dc9496bb0 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionQModel.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionQModel.cpp @@ -38,7 +38,7 @@ #include "cafPdmObject.h" #include "cafPdmUiCommandSystemProxy.h" -#include "cafPdmUiTreeViewModel.h" +#include "cafPdmUiTreeViewQModel.h" #include #include @@ -46,6 +46,7 @@ #include +#include //-------------------------------------------------------------------------------------------------- /// @@ -91,11 +92,11 @@ int caf::PdmUiTreeSelectionQModel::optionItemValueRole() //-------------------------------------------------------------------------------------------------- void caf::PdmUiTreeSelectionQModel::setCheckedStateForItems(const QModelIndexList& sourceModelIndices, bool checked) { - if (!m_uiFieldHandle || !m_uiFieldHandle->field()) return; + if (!m_uiFieldHandle || !m_uiFieldHandle->uiField()) return; std::set selectedIndices; { - QVariant fieldValue = m_uiFieldHandle->field()->uiValue(); + QVariant fieldValue = m_uiFieldHandle->uiField()->uiValue(); QList fieldValueSelection = fieldValue.toList(); for (auto v : fieldValueSelection) @@ -108,14 +109,22 @@ void caf::PdmUiTreeSelectionQModel::setCheckedStateForItems(const QModelIndexLis { for (auto mi : sourceModelIndices) { - selectedIndices.insert(static_cast(optionIndex(mi))); + const caf::PdmOptionItemInfo* optionItemInfo = optionItem(mi); + if (!optionItemInfo->isReadOnly()) + { + selectedIndices.insert(static_cast(optionIndex(mi))); + } } } else { for (auto mi : sourceModelIndices) { - selectedIndices.erase(static_cast(optionIndex(mi))); + const caf::PdmOptionItemInfo* optionItemInfo = optionItem(mi); + if (!optionItemInfo->isReadOnly()) + { + selectedIndices.erase(static_cast(optionIndex(mi))); + } } } @@ -125,7 +134,7 @@ void caf::PdmUiTreeSelectionQModel::setCheckedStateForItems(const QModelIndexLis fieldValueSelection.push_back(QVariant(v)); } - PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->field(), fieldValueSelection); + PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->uiField(), fieldValueSelection); } //-------------------------------------------------------------------------------------------------- @@ -194,6 +203,30 @@ void caf::PdmUiTreeSelectionQModel::resetUiValueCache() m_uiValueCache = nullptr; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool caf::PdmUiTreeSelectionQModel::isReadOnly(const QModelIndex& index) const +{ + return optionItem(index)->isReadOnly(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool caf::PdmUiTreeSelectionQModel::isChecked(const QModelIndex& index) const +{ + return data(index, Qt::CheckStateRole).toBool(); +} + +//-------------------------------------------------------------------------------------------------- +/// Checks if this is a real tree with grand children or just a list of children. +//-------------------------------------------------------------------------------------------------- +bool caf::PdmUiTreeSelectionQModel::hasGrandChildren() const +{ + return m_tree && m_tree->hasGrandChildren(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -326,11 +359,11 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role } else if (role == Qt::CheckStateRole && !optionItemInfo->isHeading()) { - if (m_uiFieldHandle && m_uiFieldHandle->field()) + if (m_uiFieldHandle && m_uiFieldHandle->uiField()) { // Avoid calling the seriously heavy uiValue method if we have a temporary valid cache. - QVariant fieldValue = m_uiValueCache ? *m_uiValueCache : m_uiFieldHandle->field()->uiValue(); + QVariant fieldValue = m_uiValueCache ? *m_uiValueCache : m_uiFieldHandle->uiField()->uiValue(); if (isSingleValueField(fieldValue)) { int row = fieldValue.toInt(); @@ -389,17 +422,17 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role //-------------------------------------------------------------------------------------------------- bool caf::PdmUiTreeSelectionQModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) { - if (!m_uiFieldHandle || !m_uiFieldHandle->field()) return false; + if (!m_uiFieldHandle || !m_uiFieldHandle->uiField()) return false; if (role == Qt::CheckStateRole) { - QVariant fieldValue = m_uiFieldHandle->field()->uiValue(); + QVariant fieldValue = m_uiFieldHandle->uiField()->uiValue(); if (isSingleValueField(fieldValue)) { if (value.toBool() == true) { QVariant v = static_cast(optionIndex(index)); - PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->field(), v); + PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->uiField(), v); return true; } @@ -452,8 +485,8 @@ bool caf::PdmUiTreeSelectionQModel::setData(const QModelIndex &index, const QVar fieldValueSelection.push_back(QVariant(v)); } - PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->field(), fieldValueSelection); - + PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->uiField(), fieldValueSelection); + emit dataChanged(index, index); return true; } } diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionQModel.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionQModel.h index 9b4191a793..c317288b75 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionQModel.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeSelectionQModel.h @@ -59,30 +59,34 @@ class PdmUiTreeSelectionQModel : public QAbstractItemModel Q_OBJECT public: explicit PdmUiTreeSelectionQModel(QObject *parent = nullptr); - ~PdmUiTreeSelectionQModel(); + ~PdmUiTreeSelectionQModel() override; - static int headingRole(); - static int optionItemValueRole(); + static int headingRole(); + static int optionItemValueRole(); - void setCheckedStateForItems(const QModelIndexList& indices, bool checked); - void enableSingleSelectionMode(bool enable); + void setCheckedStateForItems(const QModelIndexList& indices, bool checked); + void enableSingleSelectionMode(bool enable); - int optionItemCount() const; - void setOptions(caf::PdmUiFieldEditorHandle* field, const QList& options); - void setUiValueCache(const QVariant* uiValuesCache ); - void resetUiValueCache(); + int optionItemCount() const; + void setOptions(caf::PdmUiFieldEditorHandle* field, const QList& options); + void setUiValueCache(const QVariant* uiValuesCache ); + void resetUiValueCache(); + bool isReadOnly(const QModelIndex& index) const; + bool isChecked(const QModelIndex& index) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const override; - virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; - virtual QModelIndex parent(const QModelIndex &child) const override; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + bool hasGrandChildren() const; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; // Consider moving these functions to PdmUiFieldHandle - static bool isSingleValueField(const QVariant& fieldValue); - static bool isMultipleValueField(const QVariant& fieldValue); + static bool isSingleValueField(const QVariant& fieldValue); + static bool isMultipleValueField(const QVariant& fieldValue); private: typedef caf::UiTreeItem TreeItemType; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.h index 366e0baaf2..d3d254082e 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeView.h @@ -62,7 +62,7 @@ class PdmUiTreeView : public QWidget Q_OBJECT public: PdmUiTreeView(QWidget* parent = nullptr, Qt::WindowFlags f = nullptr); - ~PdmUiTreeView(); + ~PdmUiTreeView() override; void enableDefaultContextMenu(bool enable); void enableSelectionManagerUpdating(bool enable); // TODO: rename diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.cpp index e6dbc4cacf..919ae9aa2a 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.cpp @@ -43,7 +43,7 @@ #include "cafPdmUiDragDropInterface.h" #include "cafPdmUiEditorHandle.h" #include "cafPdmUiTreeOrdering.h" -#include "cafPdmUiTreeViewModel.h" +#include "cafPdmUiTreeViewQModel.h" #include "cafSelectionManager.h" #include @@ -65,7 +65,7 @@ class PdmUiTreeViewWidget : public QTreeView { public: explicit PdmUiTreeViewWidget(QWidget* parent = nullptr) : QTreeView(parent) {}; - virtual ~PdmUiTreeViewWidget() {}; + ~PdmUiTreeViewWidget() override {}; bool isTreeItemEditWidgetActive() const { @@ -73,9 +73,9 @@ class PdmUiTreeViewWidget : public QTreeView } protected: - virtual void dragMoveEvent(QDragMoveEvent* event) + void dragMoveEvent(QDragMoveEvent* event) override { - caf::PdmUiTreeViewModel* treeViewModel = dynamic_cast(model()); + caf::PdmUiTreeViewQModel* treeViewModel = dynamic_cast(model()); if (treeViewModel && treeViewModel->dragDropInterface()) { treeViewModel->dragDropInterface()->onProposedDropActionUpdated(event->proposedAction()); @@ -84,9 +84,9 @@ class PdmUiTreeViewWidget : public QTreeView QTreeView::dragMoveEvent(event); } - virtual void dragLeaveEvent(QDragLeaveEvent* event) + void dragLeaveEvent(QDragLeaveEvent* event) override { - caf::PdmUiTreeViewModel* treeViewModel = dynamic_cast(model()); + caf::PdmUiTreeViewQModel* treeViewModel = dynamic_cast(model()); if (treeViewModel && treeViewModel->dragDropInterface()) { treeViewModel->dragDropInterface()->onDragCanceled(); @@ -128,7 +128,7 @@ QWidget* PdmUiTreeViewEditor::createWidget(QWidget* parent) m_layout->setContentsMargins(0, 0, 0, 0); m_mainWidget->setLayout(m_layout); - m_treeViewModel = new caf::PdmUiTreeViewModel(this); + m_treeViewModel = new caf::PdmUiTreeViewQModel(this); m_treeView = new PdmUiTreeViewWidget(m_mainWidget); m_treeView->setModel(m_treeViewModel); m_treeView->installEventFilter(this); @@ -279,7 +279,7 @@ void PdmUiTreeViewEditor::customMenuRequested(QPoint pos) //-------------------------------------------------------------------------------------------------- PdmChildArrayFieldHandle* PdmUiTreeViewEditor::currentChildArrayFieldHandle() { - PdmUiItem* currentSelectedItem = SelectionManager::instance()->selectedItem(SelectionManager::CURRENT); + PdmUiItem* currentSelectedItem = SelectionManager::instance()->selectedItem(SelectionManager::FIRST_LEVEL); PdmUiFieldHandle* uiFieldHandle = dynamic_cast(currentSelectedItem); if (uiFieldHandle) diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.h index 031bd00736..c73c5e964e 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewEditor.h @@ -39,7 +39,7 @@ #include "cafPdmUiTreeEditorHandle.h" #include "cafPdmUiFieldEditorHandle.h" -#include "cafPdmUiTreeViewModel.h" +#include "cafPdmUiTreeViewQModel.h" #include #include @@ -61,7 +61,7 @@ namespace caf class PdmChildArrayFieldHandle; class PdmUiDragDropInterface; class PdmUiItem; -class PdmUiTreeViewModel; +class PdmUiTreeViewQModel; class PdmUiTreeViewWidget; //-------------------------------------------------------------------------------------------------- @@ -90,55 +90,55 @@ class PdmUiTreeViewEditor : public PdmUiTreeEditorHandle Q_OBJECT public: PdmUiTreeViewEditor(); - ~PdmUiTreeViewEditor(); + ~PdmUiTreeViewEditor() override; - void enableDefaultContextMenu(bool enable); - void enableSelectionManagerUpdating(bool enable); + void enableDefaultContextMenu(bool enable); + void enableSelectionManagerUpdating(bool enable); - void enableAppendOfClassNameToUiItemText(bool enable); - bool isAppendOfClassNameToUiItemTextEnabled(); + void enableAppendOfClassNameToUiItemText(bool enable); + bool isAppendOfClassNameToUiItemTextEnabled(); - QTreeView* treeView(); - bool isTreeItemEditWidgetActive() const; + QTreeView* treeView(); + bool isTreeItemEditWidgetActive() const; - void selectAsCurrentItem(const PdmUiItem* uiItem); - void selectedUiItems(std::vector& objects); - void setExpanded(const PdmUiItem* uiItem, bool doExpand) const; + void selectAsCurrentItem(const PdmUiItem* uiItem); + void selectedUiItems(std::vector& objects); + void setExpanded(const PdmUiItem* uiItem, bool doExpand) const; - PdmUiItem* uiItemFromModelIndex(const QModelIndex& index) const; - QModelIndex findModelIndex(const PdmUiItem* object) const; + PdmUiItem* uiItemFromModelIndex(const QModelIndex& index) const; + QModelIndex findModelIndex(const PdmUiItem* object) const; - QWidget* createWidget(QWidget* parent); + QWidget* createWidget(QWidget* parent) override; - void setDragDropInterface(PdmUiDragDropInterface* dragDropInterface); + void setDragDropInterface(PdmUiDragDropInterface* dragDropInterface); signals: - void selectionChanged(); + void selectionChanged(); protected: - virtual void configureAndUpdateUi(const QString& uiConfigName); + void configureAndUpdateUi(const QString& uiConfigName) override; - virtual void updateMySubTree(PdmUiItem* uiItem); + void updateMySubTree(PdmUiItem* uiItem) override; - void updateContextMenuSignals(); + void updateContextMenuSignals(); private slots: - void customMenuRequested(QPoint pos); - void slotOnSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); + void customMenuRequested(QPoint pos); + void slotOnSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); private: PdmChildArrayFieldHandle* currentChildArrayFieldHandle(); - void updateSelectionManager(); + void updateSelectionManager(); - virtual bool eventFilter(QObject *obj, QEvent *event); + bool eventFilter(QObject *obj, QEvent *event) override; private: QPointer m_mainWidget; QVBoxLayout* m_layout; PdmUiTreeViewWidget* m_treeView; - PdmUiTreeViewModel* m_treeViewModel; + PdmUiTreeViewQModel* m_treeViewModel; bool m_useDefaultContextMenu; bool m_updateSelectionManager; diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewQModel.cpp similarity index 92% rename from Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp rename to Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewQModel.cpp index 846581f362..f87092a278 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewQModel.cpp @@ -35,7 +35,7 @@ //################################################################################################## -#include "cafPdmUiTreeViewModel.h" +#include "cafPdmUiTreeViewQModel.h" #include "cafPdmField.h" #include "cafPdmObject.h" @@ -54,7 +54,7 @@ namespace caf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiTreeViewModel::PdmUiTreeViewModel(PdmUiTreeViewEditor* treeViewEditor) +PdmUiTreeViewQModel::PdmUiTreeViewQModel(PdmUiTreeViewEditor* treeViewEditor) { m_treeOrderingRoot = nullptr; m_dragDropInterface = nullptr; @@ -66,7 +66,7 @@ PdmUiTreeViewModel::PdmUiTreeViewModel(PdmUiTreeViewEditor* treeViewEditor) /// Will populate the tree with the contents of the Pdm data structure rooted at rootItem. /// Will not show the rootItem itself, only the children and downwards //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::setPdmItemRoot(PdmUiItem* rootItem) +void PdmUiTreeViewQModel::setPdmItemRoot(PdmUiItem* rootItem) { // Check if we are already watching this root if (m_treeOrderingRoot && m_treeOrderingRoot->activeItem() == rootItem) @@ -102,7 +102,7 @@ void PdmUiTreeViewModel::setPdmItemRoot(PdmUiItem* rootItem) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::resetTree(PdmUiTreeOrdering* newRoot) +void PdmUiTreeViewQModel::resetTree(PdmUiTreeOrdering* newRoot) { beginResetModel(); @@ -121,7 +121,7 @@ void PdmUiTreeViewModel::resetTree(PdmUiTreeOrdering* newRoot) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::setColumnHeaders(const QStringList& columnHeaders) +void PdmUiTreeViewQModel::setColumnHeaders(const QStringList& columnHeaders) { m_columnHeaders = columnHeaders; } @@ -129,7 +129,7 @@ void PdmUiTreeViewModel::setColumnHeaders(const QStringList& columnHeaders) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::emitDataChanged(const QModelIndex& index) +void PdmUiTreeViewQModel::emitDataChanged(const QModelIndex& index) { emit dataChanged(index, index); } @@ -137,7 +137,7 @@ void PdmUiTreeViewModel::emitDataChanged(const QModelIndex& index) //-------------------------------------------------------------------------------------------------- /// Refreshes the UI-tree below the supplied root PdmUiItem //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::updateSubTree(PdmUiItem* pdmRoot) +void PdmUiTreeViewQModel::updateSubTree(PdmUiItem* pdmRoot) { // Build the new "Correct" Tree @@ -214,7 +214,7 @@ class RecursiveUpdateData /// calling begin..() end..() to make the UI update accordingly. /// This assumes that all the items have a pointer an unique PdmObject //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::updateSubTreeRecursive(const QModelIndex& existingSubTreeRootModIdx, +void PdmUiTreeViewQModel::updateSubTreeRecursive(const QModelIndex& existingSubTreeRootModIdx, PdmUiTreeOrdering* existingSubTreeRoot, PdmUiTreeOrdering* sourceSubTreeRoot) { @@ -373,7 +373,7 @@ void PdmUiTreeViewModel::updateSubTreeRecursive(const QModelIndex& existingSubTr //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::updateEditorsForSubTree(PdmUiTreeOrdering* root) +void PdmUiTreeViewQModel::updateEditorsForSubTree(PdmUiTreeOrdering* root) { if (!root) return; @@ -399,7 +399,7 @@ void PdmUiTreeViewModel::updateEditorsForSubTree(PdmUiTreeOrdering* root) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiTreeOrdering* caf::PdmUiTreeViewModel::treeItemFromIndex(const QModelIndex& index) const +PdmUiTreeOrdering* caf::PdmUiTreeViewQModel::treeItemFromIndex(const QModelIndex& index) const { if (!index.isValid()) { @@ -416,7 +416,7 @@ PdmUiTreeOrdering* caf::PdmUiTreeViewModel::treeItemFromIndex(const QModelIndex& //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QModelIndex caf::PdmUiTreeViewModel::findModelIndex( const PdmUiItem * object) const +QModelIndex caf::PdmUiTreeViewQModel::findModelIndex( const PdmUiItem * object) const { QModelIndex foundIndex; int numRows = rowCount(QModelIndex()); @@ -432,7 +432,7 @@ QModelIndex caf::PdmUiTreeViewModel::findModelIndex( const PdmUiItem * object) c //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QModelIndex caf::PdmUiTreeViewModel::findModelIndexRecursive(const QModelIndex& currentIndex, const PdmUiItem * pdmItem) const +QModelIndex caf::PdmUiTreeViewQModel::findModelIndexRecursive(const QModelIndex& currentIndex, const PdmUiItem * pdmItem) const { if (currentIndex.internalPointer()) { @@ -455,7 +455,7 @@ QModelIndex caf::PdmUiTreeViewModel::findModelIndexRecursive(const QModelIndex& /// An invalid parent index is implicitly meaning the root item, and not "above" root, since /// we are not showing the root item itself //-------------------------------------------------------------------------------------------------- -QModelIndex PdmUiTreeViewModel::index(int row, int column, const QModelIndex &parentIndex ) const +QModelIndex PdmUiTreeViewQModel::index(int row, int column, const QModelIndex &parentIndex ) const { if (!m_treeOrderingRoot) return QModelIndex(); @@ -484,7 +484,7 @@ QModelIndex PdmUiTreeViewModel::index(int row, int column, const QModelIndex &pa //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QModelIndex PdmUiTreeViewModel::parent(const QModelIndex &childIndex) const +QModelIndex PdmUiTreeViewQModel::parent(const QModelIndex &childIndex) const { if (!childIndex.isValid()) return QModelIndex(); @@ -502,7 +502,7 @@ QModelIndex PdmUiTreeViewModel::parent(const QModelIndex &childIndex) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int PdmUiTreeViewModel::rowCount(const QModelIndex &parentIndex ) const +int PdmUiTreeViewQModel::rowCount(const QModelIndex &parentIndex ) const { if (!m_treeOrderingRoot) return 0; @@ -518,7 +518,7 @@ int PdmUiTreeViewModel::rowCount(const QModelIndex &parentIndex ) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int PdmUiTreeViewModel::columnCount(const QModelIndex &parentIndex ) const +int PdmUiTreeViewQModel::columnCount(const QModelIndex &parentIndex ) const { if (!m_treeOrderingRoot) return 0; @@ -529,7 +529,7 @@ int PdmUiTreeViewModel::columnCount(const QModelIndex &parentIndex ) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QVariant PdmUiTreeViewModel::data(const QModelIndex &index, int role ) const +QVariant PdmUiTreeViewQModel::data(const QModelIndex &index, int role ) const { if (!index.isValid()) { @@ -672,14 +672,14 @@ QVariant PdmUiTreeViewModel::data(const QModelIndex &index, int role ) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool PdmUiTreeViewModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) +bool PdmUiTreeViewQModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) { if (!index.isValid()) { return false; } - PdmUiTreeOrdering* treeItem = PdmUiTreeViewModel::treeItemFromIndex(index); + PdmUiTreeOrdering* treeItem = PdmUiTreeViewQModel::treeItemFromIndex(index); CAF_ASSERT(treeItem); if (!treeItem->isRepresentingObject()) return false; @@ -720,7 +720,7 @@ bool PdmUiTreeViewModel::setData(const QModelIndex &index, const QVariant &value /// Enable edit of this item if we have a editable user description field for a pdmObject /// Disable edit for other items //-------------------------------------------------------------------------------------------------- -Qt::ItemFlags PdmUiTreeViewModel::flags(const QModelIndex &index) const +Qt::ItemFlags PdmUiTreeViewQModel::flags(const QModelIndex &index) const { if (!index.isValid()) { @@ -770,7 +770,7 @@ Qt::ItemFlags PdmUiTreeViewModel::flags(const QModelIndex &index) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QVariant PdmUiTreeViewModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const +QVariant PdmUiTreeViewQModel::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole */) const { if (role != Qt::DisplayRole) return QVariant(); @@ -786,7 +786,7 @@ QVariant PdmUiTreeViewModel::headerData(int section, Qt::Orientation orientation //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiItem* PdmUiTreeViewModel::uiItemFromModelIndex(const QModelIndex& index) const +PdmUiItem* PdmUiTreeViewQModel::uiItemFromModelIndex(const QModelIndex& index) const { PdmUiTreeOrdering* treeItem = this->treeItemFromIndex(index); if (treeItem) @@ -800,7 +800,7 @@ PdmUiItem* PdmUiTreeViewModel::uiItemFromModelIndex(const QModelIndex& index) co //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void PdmUiTreeViewModel::setDragDropInterface(PdmUiDragDropInterface* dragDropInterface) +void PdmUiTreeViewQModel::setDragDropInterface(PdmUiDragDropInterface* dragDropInterface) { m_dragDropInterface = dragDropInterface; } @@ -808,7 +808,7 @@ void PdmUiTreeViewModel::setDragDropInterface(PdmUiDragDropInterface* dragDropIn //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -PdmUiDragDropInterface* PdmUiTreeViewModel::dragDropInterface() +PdmUiDragDropInterface* PdmUiTreeViewQModel::dragDropInterface() { return m_dragDropInterface; } @@ -816,7 +816,7 @@ PdmUiDragDropInterface* PdmUiTreeViewModel::dragDropInterface() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QStringList PdmUiTreeViewModel::mimeTypes() const +QStringList PdmUiTreeViewQModel::mimeTypes() const { if (m_dragDropInterface) { @@ -831,7 +831,7 @@ QStringList PdmUiTreeViewModel::mimeTypes() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QMimeData * PdmUiTreeViewModel::mimeData(const QModelIndexList &indexes) const +QMimeData * PdmUiTreeViewQModel::mimeData(const QModelIndexList &indexes) const { if (m_dragDropInterface) { @@ -846,7 +846,7 @@ QMimeData * PdmUiTreeViewModel::mimeData(const QModelIndexList &indexes) const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool PdmUiTreeViewModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +bool PdmUiTreeViewQModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (m_dragDropInterface) { @@ -861,7 +861,7 @@ bool PdmUiTreeViewModel::dropMimeData(const QMimeData *data, Qt::DropAction acti //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -Qt::DropActions PdmUiTreeViewModel::supportedDropActions() const +Qt::DropActions PdmUiTreeViewQModel::supportedDropActions() const { if (m_dragDropInterface) { diff --git a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewQModel.h similarity index 76% rename from Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h rename to Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewQModel.h index 6744255077..94b19dd49b 100644 --- a/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewModel.h +++ b/Fwk/AppFwk/cafUserInterface/cafPdmUiTreeViewQModel.h @@ -55,12 +55,12 @@ class PdmUiDragDropInterface; // This class is intended to replace UiTreeModelPdm (cafUiTreeModelPdm) // //================================================================================================== -class PdmUiTreeViewModel : public QAbstractItemModel +class PdmUiTreeViewQModel : public QAbstractItemModel { Q_OBJECT public: - explicit PdmUiTreeViewModel(PdmUiTreeViewEditor* treeViewEditor); + explicit PdmUiTreeViewQModel(PdmUiTreeViewEditor* treeViewEditor); void setPdmItemRoot(PdmUiItem* rootItem); void updateSubTree(PdmUiItem* subTreeRoot); @@ -98,22 +98,22 @@ class PdmUiTreeViewModel : public QAbstractItemModel // Overrides from QAbstractItemModel - virtual QModelIndex index(int row, int column, const QModelIndex &parentIndex = QModelIndex( )) const; - virtual QModelIndex parent(const QModelIndex &index) const; + QModelIndex index(int row, int column, const QModelIndex &parentIndex = QModelIndex( )) const override; + QModelIndex parent(const QModelIndex &index) const override; - virtual int rowCount(const QModelIndex &parentIndex = QModelIndex( ) ) const; - virtual int columnCount(const QModelIndex &parentIndex = QModelIndex( ) ) const; + int rowCount(const QModelIndex &parentIndex = QModelIndex( ) ) const override; + int columnCount(const QModelIndex &parentIndex = QModelIndex( ) ) const override; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; + Qt::ItemFlags flags(const QModelIndex &index) const override; - virtual QStringList mimeTypes() const; - virtual QMimeData* mimeData(const QModelIndexList &indexes) const; - virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); - virtual Qt::DropActions supportedDropActions() const; + QStringList mimeTypes() const override; + QMimeData* mimeData(const QModelIndexList &indexes) const override; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; + Qt::DropActions supportedDropActions() const override; }; diff --git a/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp b/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp index b81453a92a..8cd8a121dd 100644 --- a/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp +++ b/Fwk/AppFwk/cafUserInterface/cafProgressInfo.cpp @@ -37,6 +37,7 @@ #include "cafProgressInfo.h" #include "cafAssert.h" +#include "cafMemoryInspector.h" #include "cafProgressState.h" #include @@ -45,6 +46,8 @@ #include #include +#include + namespace caf { //================================================================================================== @@ -149,6 +152,16 @@ namespace caf { ProgressInfoStatic::incrementProgress(); } + //-------------------------------------------------------------------------------------------------- + /// Convenience method for incrementing progress and setting step size and description for next step + //-------------------------------------------------------------------------------------------------- + void ProgressInfo::incrementProgressAndUpdateNextStep(size_t nextStepSize, const QString& nextDescription) + { + incrementProgress(); + setNextProgressIncrement(nextStepSize); + setProgressDescription(nextDescription); + } + //-------------------------------------------------------------------------------------------------- /// To make a certain operation span more of the progress bar than one tick, /// set the number of progress ticks that you want it to use before calling it. @@ -181,6 +194,29 @@ namespace caf { /// //================================================================================================== + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + QString createMemoryLabelText() + { + uint64_t currentUsage = caf::MemoryInspector::getApplicationPhysicalMemoryUsageMiB(); + uint64_t totalPhysicalMemory = caf::MemoryInspector::getTotalPhysicalMemoryMiB(); + + float currentUsageFraction = 0.0f; + if (currentUsage > 0u && totalPhysicalMemory > 0u) + { + currentUsageFraction = std::min(1.0f, static_cast(currentUsage) / totalPhysicalMemory); + } + + QString labelText("\n"); + if (currentUsageFraction > 0.5) + { + labelText = QString("Memory Used: %1 MiB, Total Physical Memory: %2 MiB\n").arg(currentUsage).arg(totalPhysicalMemory); + } + return labelText; + } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -194,6 +230,7 @@ namespace caf { progDialog->hide(); progDialog->setAutoClose(false); progDialog->setAutoReset(false); + progDialog->setMinimumWidth(400); } return progDialog; } @@ -301,7 +338,7 @@ namespace caf { if (!descriptionStack()[i].isEmpty()) labelText += descriptionStack()[i]; if (!(titleStack()[i].isEmpty() && descriptionStack()[i].isEmpty())) labelText += "\n"; } - labelText += "\n "; + labelText += createMemoryLabelText(); return labelText; } diff --git a/Fwk/AppFwk/cafUserInterface/cafProgressInfo.h b/Fwk/AppFwk/cafUserInterface/cafProgressInfo.h index a889a1dda2..fd58b0131c 100644 --- a/Fwk/AppFwk/cafUserInterface/cafProgressInfo.h +++ b/Fwk/AppFwk/cafUserInterface/cafProgressInfo.h @@ -52,6 +52,7 @@ class ProgressInfo void setProgressDescription(const QString& description); void setProgress(size_t progressValue); void incrementProgress(); + void incrementProgressAndUpdateNextStep(size_t nextStepSize, const QString& nextDescription); void setNextProgressIncrement(size_t nextStepSize); }; diff --git a/Fwk/AppFwk/cafViewer/CMakeLists.txt b/Fwk/AppFwk/cafViewer/CMakeLists.txt index 2850fc3b0d..2d0661008c 100644 --- a/Fwk/AppFwk/cafViewer/CMakeLists.txt +++ b/Fwk/AppFwk/cafViewer/CMakeLists.txt @@ -52,4 +52,8 @@ target_link_libraries ( ${PROJECT_NAME} ${QT_LIBRARIES} ) +if (MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/W4 /wd4100 /wd4127") +endif() + source_group("" FILES ${PROJECT_FILES}) diff --git a/Fwk/AppFwk/cafViewer/cafTrackBallBasedNavigation.cpp b/Fwk/AppFwk/cafViewer/cafTrackBallBasedNavigation.cpp index 7352ff7994..e71b46b904 100644 --- a/Fwk/AppFwk/cafViewer/cafTrackBallBasedNavigation.cpp +++ b/Fwk/AppFwk/cafViewer/cafTrackBallBasedNavigation.cpp @@ -47,6 +47,8 @@ #include +#include + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -169,6 +171,27 @@ void caf::TrackBallBasedNavigation::zoomAlongRay(cvf::Ray* ray, int delta) m_viewer->updateParallelProjectionHeightFromMoveZoom(m_pointOfInterest); m_viewer->updateParallelProjectionCameraPosFromPointOfInterestMove(m_pointOfInterest); + // Ceeviz Workaround for #3697: + // Ceeviz may create a singular projection*view matrix internally. In which case we need to revert. + cvf::Mat4d projectionMatrix = m_viewer->mainCamera()->projectionMatrix(); + cvf::Mat4d viewMatrix = m_viewer->mainCamera()->viewMatrix(); + cvf::Mat4d multMatrix = projectionMatrix * viewMatrix; + double determinant = std::fabs(multMatrix.determinant()); + + if (determinant < 1.0e-15) + { + m_viewer->mainCamera()->setFromLookAt(pos, vrp, up); + m_viewer->updateParallelProjectionHeightFromMoveZoom(m_pointOfInterest); + m_viewer->updateParallelProjectionCameraPosFromPointOfInterestMove(m_pointOfInterest); +#ifndef NDEBUG + projectionMatrix = m_viewer->mainCamera()->projectionMatrix(); + viewMatrix = m_viewer->mainCamera()->viewMatrix(); + multMatrix = projectionMatrix * viewMatrix; + determinant = std::fabs(multMatrix.determinant()); + CVF_ASSERT(determinant > 1.0e-15); +#endif + } + m_viewer->navigationPolicyUpdate(); } } diff --git a/Fwk/VizFwk/LibRender/cvfDrawableGeo.cpp b/Fwk/VizFwk/LibRender/cvfDrawableGeo.cpp index f3cddc528b..576d30f98a 100644 --- a/Fwk/VizFwk/LibRender/cvfDrawableGeo.cpp +++ b/Fwk/VizFwk/LibRender/cvfDrawableGeo.cpp @@ -1332,7 +1332,7 @@ bool DrawableGeo::rayIntersect(const Ray& ray, Vec3d* intersectionPoint, uint* f { const double distSquared = (ray.origin() - localIntersect).lengthSquared(); - #pragma omp critical + #pragma omp critical(critical_section_rayIntersect2) { if (distSquared < minDistSquared) { @@ -1415,7 +1415,7 @@ bool DrawableGeo::rayIntersect(const Ray& ray, Vec3dArray* intersectionPoints, U if (hitThisFace) { - #pragma omp critical + #pragma omp critical(critical_section_rayIntersect1) { isectPts.push_back(localIntersect); diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index 232083c869..1cfe71074a 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,28 +1,30 @@ set(RESINSIGHT_MAJOR_VERSION 2018) -set(RESINSIGHT_MINOR_VERSION 05) -set(RESINSIGHT_PATCH_VERSION 1) +set(RESINSIGHT_MINOR_VERSION 11) +set(RESINSIGHT_PATCH_VERSION 0) # Opional text with no restrictions -#set(RESINSIGHT_VERSION_TEXT "-dev") +#set(RESINSIGHT_VERSION_TEXT "-RC1") # Optional text # Must be unique and increasing within one combination of major/minor/patch version # The uniqueness of this text is independent of RESINSIGHT_VERSION_TEXT # Format of text must be ".xx" -#set(RESINSIGHT_DEV_VERSION ".01") +#set(RESINSIGHT_DEV_VERSION ".12") # https://github.com/CRAVA/crava/tree/master/libs/nrlib set(NRLIB_GITHUB_SHA "ba35d4359882f1c6f5e9dc30eb95fe52af50fd6f") # https://github.com/Statoil/libecl -set(ECL_GITHUB_SHA "0188b08081eb1ac4ade89ac224b8128b4c9b0481") +# Note: +# Apply patches fix-synthetic-odb-cases.patch and install-ert.patch after update +set(ECL_GITHUB_SHA "7f93730c08a4d981a4b738b42146d099977572ce") # https://github.com/OPM/opm-flowdiagnostics set(OPM_FLOWDIAGNOSTICS_SHA "f8af0914f8b1ddcda41f040f539c945a6057f5e4") # https://github.com/OPM/opm-flowdiagnostics-applications -set(OPM_FLOWDIAGNOSTICS_APPLICATIONS_SHA "e769c492ccd3fc4e1f834ed60f4f9279ba8524bc") +set(OPM_FLOWDIAGNOSTICS_APPLICATIONS_SHA "24ff768dc509b6c6bbd0121ef46a5932fae92961") # https://github.com/OPM/opm-parser/blob/master/opm/parser/eclipse/Units/Units.hpp # This file was moved from opm-core to opm-parser october 2016 diff --git a/ThirdParty/Ert/.travis.yml b/ThirdParty/Ert/.travis.yml index 5d137e94ad..6fdc81f1a6 100644 --- a/ThirdParty/Ert/.travis.yml +++ b/ThirdParty/Ert/.travis.yml @@ -54,16 +54,20 @@ install: - if [[ $PYTHON_VERSION == 2.7 ]]; then export TRAVIS_PYTHON_VERSION="2.7"; fi + - if [[ $PYTHON_VERSION == 3.6 ]]; then + export TRAVIS_PYTHON_VERSION="3.6"; + fi # We do this conditionally because it saves us some downloading if the version is the same. - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then wget https://repo.continuum.io/miniconda/Miniconda2-latest-${CONDA_OS}-x86_64.sh -O miniconda.sh; else - wget https://repo.continuum.io/miniconda/Miniconda3-latest-${CONDA_OS}-x86_64.sh -O miniconda.sh; + wget https://repo.continuum.io/miniconda/Miniconda3-4.4.10-${CONDA_OS}-x86_64.sh -O miniconda.sh; fi - bash miniconda.sh -b -p $HOME/miniconda - export CONDA_HOME="$HOME/miniconda" - export PATH="$CONDA_HOME/bin:$PATH" - hash -r + - python --version - pip install -r requirements.txt - conda config --set always_yes yes --set changeps1 no - conda update -q conda diff --git a/ThirdParty/Ert/CMakeLists.txt b/ThirdParty/Ert/CMakeLists.txt index bddc356a17..5e2e1e42b4 100644 --- a/ThirdParty/Ert/CMakeLists.txt +++ b/ThirdParty/Ert/CMakeLists.txt @@ -1,7 +1,8 @@ -cmake_minimum_required( VERSION 2.8.12 ) +cmake_minimum_required( VERSION 2.8.12 ) # If you are creating Python wrappers for Windows, the actual version requirement is 3.4 project( ERT C CXX ) include(GNUInstallDirs) +include(TestBigEndian) if(POLICY CMP0042) cmake_policy(SET CMP0042 OLD) @@ -115,7 +116,7 @@ endif() # Treat warnings as errors if not on Windows if (NOT ERT_WINDOWS) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wno-unknown-pragmas ") - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall " ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unknown-pragmas -Wno-unused-result -Wno-unused-parameter" ) endif() if (MSVC) @@ -191,11 +192,6 @@ if (SHLWAPI_LIBRARY) set(shlwapi ${SHLWAPI_LIBRARY}) endif () -find_library(WS2_32_LIBRARY NAMES Ws2_32) -if (WS2_32_LIBRARY) - set(ws2_32 ${WS2_32_LIBRARY}) -endif () - #----------------------------------------------------------------- # feature tests @@ -227,9 +223,6 @@ check_function_exists( mkdir HAVE_POSIX_MKDIR) check_function_exists( _mkdir HAVE_WINDOWS_MKDIR) check_function_exists( opendir ERT_HAVE_OPENDIR ) check_function_exists( posix_spawn ERT_HAVE_SPAWN ) -check_function_exists( pthread_timedjoin_np HAVE_TIMEDJOIN) -check_function_exists( pthread_yield HAVE_YIELD) -check_function_exists( pthread_yield_np HAVE_YIELD_NP) check_function_exists( readlinkat ERT_HAVE_READLINKAT ) check_function_exists( realpath HAVE_REALPATH ) check_function_exists( regexec ERT_HAVE_REGEXP ) @@ -247,10 +240,7 @@ check_include_file(execinfo.h HAVE_EXECINFO) check_include_file(getopt.h ERT_HAVE_GETOPT) check_include_file(unistd.h ERT_HAVE_UNISTD) -# Portability checks; look for htons function -check_include_file("netinet/in.h" HAVE_NETINET_IN_H) -check_include_file("arpa/inet.h" HAVE_ARPA_INET_H) -check_include_file("winsock2.h" HAVE_WINSOCK2_H) +test_big_endian(BIG_ENDIAN) check_type_size(time_t SIZE_OF_TIME_T) if (${SIZE_OF_TIME_T} EQUAL 8) @@ -329,33 +319,31 @@ if (MSVC) add_definitions( -D__func__="\\"????\\"") endif() -if (ERT_WINDOWS) - message(WARNING "Python is not supported on Windows") - set( ENABLE_PYTHON OFF ) -endif () - if (ERT_LINUX) add_definitions( -DHAVE_PROC ) endif() +add_subdirectory( external/catch2 ) add_subdirectory( lib ) add_subdirectory( applications ) add_subdirectory( bin ) +if (ENABLE_PYTHON AND ERT_WINDOWS) + if ((NOT MSVC) OR (MSVC_VERSION LESS 1900)) + message(FATAL_ERROR "The Python wrappers require Visual Studio 2015 or newer") + endif() +endif() + if (ENABLE_PYTHON) - if (ERT_WINDOWS) - message(WARNING "Python is not supported on Windows") - set( ENABLE_PYTHON OFF ) - else() - # If finding the Python interpreter and required packages - # fails in the python/CMakeLists.txt file the ENABLE_PYTHON - # will be set to OFF. - add_subdirectory( python ) - - if(RST_DOC) - add_subdirectory( docs ) - endif() - endif() + # If finding the Python interpreter and required packages + # fails in the python/CMakeLists.txt file the ENABLE_PYTHON + # will be set to OFF. + add_subdirectory( python ) + + if(RST_DOC) + add_subdirectory( docs ) + endif() + endif() if (ENABLE_PYTHON) diff --git a/ThirdParty/Ert/MANIFEST.in b/ThirdParty/Ert/MANIFEST.in new file mode 100644 index 0000000000..a2aeac11a9 --- /dev/null +++ b/ThirdParty/Ert/MANIFEST.in @@ -0,0 +1,7 @@ +include README.md COPYING +global-include CMakeLists.txt *.cmake +recursive-include external/catch2 * +recursive-include lib * +recursive-include applications * +recursive-include bin * +recursive-include cmake * diff --git a/ThirdParty/Ert/README.md b/ThirdParty/Ert/README.md index 41e4c9eab2..07d72dec3a 100644 --- a/ThirdParty/Ert/README.md +++ b/ThirdParty/Ert/README.md @@ -8,53 +8,75 @@ non-unified and formatted and unformatted files are supported. *libecl* is mainly developed on *Linux* and *OS X*, in addition there is a portability layer which ensures that most of the functionality is -available on *Windows*. The main functionality is written in C, and +available on *Windows*. The main functionality is written in C/C++, and should typically be linked in in other compiled programs. *libecl* was initially developed as part of the [Ensemble Reservoir Tool](http://github.com/Statoil/ert), other applications using *libecl* are the reservoir simulator flow and Resinsight from the [OPM project](http://github.com/OPM/). -In addition to the C code there are Python wrappers which make most of -the *libecl* functionality available from Python. For small interactive -scripts, forward models e.t.c. this is recommended way to use *libecl* -functionality. +In addition to the compiled C/C++ code there are Python wrappers which make most +of the *libecl* functionality available from Python. For small interactive +scripts, forward models e.t.c. this is the recommended way to use *libecl* +functionality. You decide wether to build include the Python wrappers when +configuring the `cmake` build - pass the option `-DENABLE_PYTHON=ON` to enable +Python wrappers, by default the Python wrappers are *not* included. +By default `cmake` is configured to install to a system location like +`/usr/local`, if you want to install to an alternative location that should be +configured with `-DCMAKE_INSTALL_PREFIX=/path/to/install`. -### Compiling the C code ### +### Alternative 1: Building without Python ### *libecl* uses CMake as build system: ```bash -git clone https://github.com/Statoil/libecl.git +git clone https://github.com/Statoil/libecl cd libecl mkdir build cd build -cmake .. +cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install make +make install ``` If you intend to develop and change *libecl* you should build the tests by passing `-DBUILD_TESTS=ON` and run the tests with `ctest`. +### Alternative 2: Building with Python ### +To build *libecl* with Python wrappers you just pass the option +`-DENABLE_PYTHON=ON` when running `cmake`. In addition you need to install some +dependencies first. Python is not a compiled language, but the `cmake` configuration contains a +rudimentary "build system" which does a basic Python syntax check and configures some +files to correctly set up the interaction between the Python classes and the +shared libraries built from the C code: +```bash +git clone https://github.com/Statoil/libecl +cd libecl +sudo pip install -r requirements.txt +mkdir build +cd build +cmake .. -DENABLE_PYTHON=ON -DCMAKE_INSTALL_PREFIX=/path/to/install +make +make install +``` -### Compiling the Python code ### - -Python is not a compiled language, but there is a basic "build system" -which does a basic Python syntax check and configures some files to -correctly set up the interaction between the Python classes and the -shared libraries built from the C code. - -You need to install some Python requirements before the Python code -will work: +After you have installed the Python wrappers you must tell `Python` where to +find the package[1]: - sudo pip install -r requirements.txt +```bash +export PYTHONPATH=/path/to/install/lib/python2.7/site-packages:$PYTHONPATH +export LD_LIBRARY_PATH=/path/to/install/lib64:$LD_LIBRARY_PATH +``` -The Python + cmake interaction is handled in a separate project called -[pycmake](https://github.com/Statoil/pycmake); you can either install -that manually or use the git submodule functionality to fetch the -correct version of `pycmake` into your *libecl* code: +Then you can fire up your Python interpreter and try it out: +``` +from ecl.summary import EclSum +import sys - git submodule update --init pycmake +summary = EclSum(sys.argv[1]) +fopt = summary.numpy_vector("FOPT") +``` +[1]: The exact paths here will depend on your system and Python version. The example given is for a RedHat system with Python version 2.7. diff --git a/ThirdParty/Ert/applications/ecl/ecl_pack.c b/ThirdParty/Ert/applications/ecl/ecl_pack.c index ad6822c0ad..9cd98fc5a3 100644 --- a/ThirdParty/Ert/applications/ecl/ecl_pack.c +++ b/ThirdParty/Ert/applications/ecl/ecl_pack.c @@ -99,7 +99,7 @@ int main(int argc, char ** argv) { if (seqnum_kw != NULL) ecl_kw_free(seqnum_kw); } free(ecl_base); - util_safe_free(path); + free(path); } } diff --git a/ThirdParty/Ert/applications/ecl/ecl_unpack.c b/ThirdParty/Ert/applications/ecl/ecl_unpack.c index 58f9cde244..fa08a9042f 100644 --- a/ThirdParty/Ert/applications/ecl/ecl_unpack.c +++ b/ThirdParty/Ert/applications/ecl/ecl_unpack.c @@ -93,7 +93,7 @@ void unpack_file(const char * filename) { block_index++; } ecl_file_close( src_file ); - util_safe_free(path); + free(path); free(base); } } diff --git a/ThirdParty/Ert/applications/ecl/kw_extract.c b/ThirdParty/Ert/applications/ecl/kw_extract.c index 165ad67f7d..9247ff073a 100644 --- a/ThirdParty/Ert/applications/ecl/kw_extract.c +++ b/ThirdParty/Ert/applications/ecl/kw_extract.c @@ -20,9 +20,9 @@ #include #include -#include #include #include +#include #include #include @@ -47,12 +47,14 @@ int main(int argc, char ** argv) { { const char * src_file = argv[1]; const char * target_file = argv[2]; - const char ** kw_list = (const char **) &argv[3]; - int num_kw = argc - 3; fortio_type * fortio_src; fortio_type * fortio_target; bool fmt_src , fmt_target; - set_type * kw_set = set_alloc( num_kw , kw_list ); + stringlist_type * kw_set = stringlist_alloc_new(); + + + for (int iarg=3; iarg < argc; iarg++) + stringlist_append_copy(kw_set, argv[iarg]); if (!ecl_util_fmt_file(src_file, &fmt_src)) util_exit("Hmm - could not determine formatted/unformatted status for:%s \n",src_file); @@ -66,7 +68,7 @@ int main(int argc, char ** argv) { while (true) { if (ecl_kw_fread_header( ecl_kw , fortio_src ) == ECL_KW_READ_OK) { const char * header = ecl_kw_get_header( ecl_kw ); - if (set_has_key( kw_set , header )) { + if (stringlist_contains( kw_set , header )) { ecl_kw_fread_realloc_data(ecl_kw , fortio_src ); ecl_kw_fwrite( ecl_kw , fortio_target ); } else @@ -79,6 +81,6 @@ int main(int argc, char ** argv) { fortio_fclose(fortio_src); fortio_fclose(fortio_target); - set_free( kw_set ); + stringlist_free( kw_set ); } } diff --git a/ThirdParty/Ert/applications/ecl/make_grid.c b/ThirdParty/Ert/applications/ecl/make_grid.c index a369b22ae9..f3c7adfd4e 100644 --- a/ThirdParty/Ert/applications/ecl/make_grid.c +++ b/ThirdParty/Ert/applications/ecl/make_grid.c @@ -63,7 +63,7 @@ int main(int argc, char ** argv) { } free( basename ); - util_safe_free( path ); + free( path ); ecl_grid_free( ecl_grid ); } } diff --git a/ThirdParty/Ert/applications/ecl/run_gravity.c b/ThirdParty/Ert/applications/ecl/run_gravity.c index eab217cd1a..f2ea723750 100644 --- a/ThirdParty/Ert/applications/ecl/run_gravity.c +++ b/ThirdParty/Ert/applications/ecl/run_gravity.c @@ -442,9 +442,9 @@ ecl_file_type ** load_restart_info(const char ** input, /* Input taken *arg_offset = 3; - util_safe_free( file1 ); - util_safe_free( file2 ); - util_safe_free( unified_file ); + free( file1 ); + free( file2 ); + free( unified_file ); } } } diff --git a/ThirdParty/Ert/applications/ecl/sum_write.c b/ThirdParty/Ert/applications/ecl/sum_write.c index da1be0cab5..77234e4800 100644 --- a/ThirdParty/Ert/applications/ecl/sum_write.c +++ b/ThirdParty/Ert/applications/ecl/sum_write.c @@ -163,11 +163,6 @@ int main( int argc , char ** argv) { int nz = 10; - smspec_node_type * wwct_wellx; - smspec_node_type * wopr_wellx; - vector_type * blank_nodes = vector_alloc_new(); - - /* We create a new summary case which will be used for writing. The arguments are: @@ -211,9 +206,7 @@ int main( int argc , char ** argv) { 3. The WGNAME value for this variable. WGNAME is the well or group name; if the variable in question is neither a well nor - a group variable you can just send in NULL. The WGNAME value - can be changed runtime with the ecl_sum_update_wgname() - function. + a group variable you can just send in NULL. 4. The NUMS value for this variable. @@ -221,15 +214,6 @@ int main( int argc , char ** argv) { 6. A defualt value for this variable. - Observe that as an alternative to ecl_sum_add_var() you can use - the combination: - - smspec_node_type * var = ecl_sum_add_blank_var( ecl_sum , DEFAULT_VALUE ); - ..... - ecl_sum_init_var( ecl_sum , var , keyword , wgname , num , unit ); - - This is an alternative when e.g. the name of wells is not known in - advance. */ ecl_sum_add_var( ecl_sum , "FOPT" , NULL , 0 , "Barrels" , 99.0 ); ecl_sum_add_var( ecl_sum , "BPR" , NULL , 567 , "BARS" , 0.0 ); @@ -257,43 +241,10 @@ int main( int argc , char ** argv) { then later on call one of the smspec_node_get_params_index() or smspec_node_get_gen_key1() functions. - If you wish to change the WGNAME value with - ecl_sum_update_wgname() a later stage you must hold on to - the smspec_node instance. - - ECLIPSE supports the 'dynamic' creation of wells, however you must - specify up-front how many wells (max) you will have, and then the - name will be specified as the wells 'pop up' in the Schedule - file. In the current implementation this is supported by requering - that you first add all wells/groups with ecl_sum_add_var(), and - then you can subsequently update the WGNAME value later. This is - illustrated with the two lines below where we add the WWCT and - WOPR variables for a well without name, and then call - ecl_sum_update_wganme() further down in the code. - */ - - wwct_wellx = ecl_sum_add_var( ecl_sum , "WWCT" , NULL , 0 , "(1)" , 0.0); - wopr_wellx = ecl_sum_add_var( ecl_sum , "WOPR" , NULL , 0 , "Barrels" , 0.0); - - /* - Here we add a collection of ten variables which are not - initialized. Before they can be actually used you must initialize - them with: - - ecl_sum_init_var( ecl_sum , node , keyword , wgname , num , unit ); - - If you do not init them at all they will appear in the SMSPEC file - as WWCT variable of the DUMMY_WELL (i.e. they will be discarded in - a subsequent load, but the will be there). */ - { - int i; - for (i=0; i < 10; i++) { - smspec_node_type * blank_node = ecl_sum_add_blank_var( ecl_sum , i * 1.0 ); - vector_append_ref( blank_nodes , blank_node ); - } - } + smspec_node_type * wwct_wellx = ecl_sum_add_var( ecl_sum , "WWCT" , NULL , 0 , "(1)" , 0.0); + smspec_node_type * wopr_wellx = ecl_sum_add_var( ecl_sum , "WOPR" , NULL , 0 , "Barrels" , 0.0); { @@ -341,25 +292,19 @@ int main( int argc , char ** argv) { smpec_get_gen_key1() function: */ ecl_sum_tstep_set_from_key( tstep , "WWCT:OP-1" , sim_days / 10); - if (report_step >= 5) + if (report_step >= 5) { /* We can use the smspec_node value from the ecl_sum_add_var() function directly: */ ecl_sum_tstep_set_from_node( tstep , wwct_wellx , sim_days ); + ecl_sum_tstep_set_from_node( tstep, wopr_wellx, sim_days * 100); + } } } } } - /* - Suddenly someone calls in and tell us the name of the mystery - well: - */ - ecl_sum_update_wgname( ecl_sum , wwct_wellx , "OPX"); - ecl_sum_update_wgname( ecl_sum , wopr_wellx , "OPX"); - - vector_free( blank_nodes ); // Only frees the container - the actual nodes are handled by the ecl_sum instance. ecl_sum_fwrite( ecl_sum ); ecl_sum_free( ecl_sum ); } diff --git a/ThirdParty/Ert/applications/ecl/view_summary.c b/ThirdParty/Ert/applications/ecl/view_summary.c index 579466d2a3..986f390db4 100644 --- a/ThirdParty/Ert/applications/ecl/view_summary.c +++ b/ThirdParty/Ert/applications/ecl/view_summary.c @@ -26,10 +26,10 @@ #endif #include -#include +#include -#include -#include +#include +#include @@ -201,7 +201,7 @@ int main(int argc , char ** argv) { const char ** arg_list = (const char **) &argv[arg_offset + 1]; - ecl_sum = ecl_sum_fread_alloc_case__( data_file , ":" , include_restart); + ecl_sum = ecl_sum_fread_alloc_case2__( data_file , ":" , include_restart, true, 0); /** If no keys have been presented the function will list available keys. */ if (num_keys == 0) list_mode = true; diff --git a/ThirdParty/Ert/applications/ecl/vprofile.c b/ThirdParty/Ert/applications/ecl/vprofile.c index fc9017dca2..e6edb40b55 100644 --- a/ThirdParty/Ert/applications/ecl/vprofile.c +++ b/ThirdParty/Ert/applications/ecl/vprofile.c @@ -223,7 +223,7 @@ int main (int argc , char ** argv) { vprofile( i - 1, j - 1, ecl_grid , ecl_file , kw , tstep , output_fmt ); if (!unified) - util_safe_free( restart_file ); + free( restart_file ); } else fprintf(stderr,"** The string: \'%s\' was not interpreted as a time-step - ignored \n",tlist[it]); } diff --git a/ThirdParty/Ert/appveyor.yml b/ThirdParty/Ert/appveyor.yml index 78604583b0..73887395f0 100644 --- a/ThirdParty/Ert/appveyor.yml +++ b/ThirdParty/Ert/appveyor.yml @@ -1,12 +1,27 @@ version: 1.0.{build} + clone_depth: 1 -build_script: -- cmd: >- - mkdir build - cd build +configuration: + - Release + +os: Visual Studio 2015 +image: Visual Studio 2015 - cmake .. -G"Visual Studio 14 2015 Win64" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DERT_BUILD_CXX=OFF -DENABLE_PYTHON=OFF -DBUILD_APPLICATIONS=ON +platform: + - x64 +matrix: + fast_finish: true + +build_script: + - IF "%platform%" == "x64" set W64="-GVisual Studio 14 2015 Win64" + - cmake %W64% -DBUILD_SHARED_LIBS=ON + -DCMAKE_BUILD_TYPE=Release + -DENABLE_PYTHON=ON + -DERT_BUILD_CXX=OFF + -DBUILD_APPLICATIONS=ON + - cmake --build . --config %configuration% --target install - msbuild /m /p:Configuration=Release /p:Platform="x64" ERT.sln +test_script: + - ctest --config %configuration% --output-on-failure diff --git a/ThirdParty/Ert/debian/changelog b/ThirdParty/Ert/debian/changelog index 5e52ee78b4..f12cdfca3a 100644 --- a/ThirdParty/Ert/debian/changelog +++ b/ThirdParty/Ert/debian/changelog @@ -1,4 +1,4 @@ -ecl (2017.09-test1-1~xenial) xenial; urgency=low +ecl (2018.10-rfinal-1~xenial) xenial; urgency=low * New release diff --git a/ThirdParty/Ert/debian/control b/ThirdParty/Ert/debian/control index f1cee7a739..739099511d 100644 --- a/ThirdParty/Ert/debian/control +++ b/ThirdParty/Ert/debian/control @@ -2,7 +2,8 @@ Source: ecl Priority: extra Maintainer: Arne Morten Kvarving Build-Depends: debhelper (>= 8.0.0), cmake, liblapack-dev, libquadmath0, - iputils-ping, zlib1g-dev, git, python-dev, python-numpy, python-cwrap + iputils-ping, zlib1g-dev, git, python-dev, python-numpy, python-cwrap, + python-pandas Standards-Version: 3.9.2 Section: libs Homepage: http://ert.nr.no @@ -26,6 +27,6 @@ Description: libecl Eclipse IO library Package: python-ecl Section: python Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, libecl1, python-cwrap +Depends: ${shlibs:Depends}, ${misc:Depends}, libecl1, python-cwrap, python-pandas, python-numpy Description: libecl Eclipse IO library - Python bindings libecl is a package for reading and writing the result files from the Eclipse reservoir simulator. diff --git a/ThirdParty/Ert/debian/rules b/ThirdParty/Ert/debian/rules index a2fd90c353..3a61564aa7 100644 --- a/ThirdParty/Ert/debian/rules +++ b/ThirdParty/Ert/debian/rules @@ -12,5 +12,14 @@ %: dh $@ +override_dh_auto_clean: + dh_auto_clean --buildsystem=cmake + +override_dh_auto_build: + dh_auto_build --buildsystem=cmake + override_dh_auto_configure: - DESTDIR=$$(pwd)/debian/tmp dh_auto_configure -- -DBUILD_SHARED_LIBS=1 -DBUILD_ECL_SUMMARY=1 -DENABLE_PYTHON=1 -DCMAKE_BUILD_TYPE=Release + DESTDIR=$$(pwd)/debian/tmp dh_auto_configure --buildsystem=cmake -- -DBUILD_SHARED_LIBS=1 -DBUILD_ECL_SUMMARY=1 -DENABLE_PYTHON=1 -DCMAKE_BUILD_TYPE=Release + +override_dh_auto_install: + dh_auto_install --buildsystem=cmake diff --git a/ThirdParty/Ert/external/catch2/CMakeLists.txt b/ThirdParty/Ert/external/catch2/CMakeLists.txt new file mode 100644 index 0000000000..acc362ba8a --- /dev/null +++ b/ThirdParty/Ert/external/catch2/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.8.12) +project(catch2 CXX) + +# Dummy source file added because INTERFACE type +# library is not available in CMake 2.8.12 +add_library(catch2 dummy.cpp) +target_include_directories(catch2 SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/ThirdParty/Ert/external/catch2/catch/catch.hpp b/ThirdParty/Ert/external/catch2/catch/catch.hpp new file mode 100644 index 0000000000..28448ddb22 --- /dev/null +++ b/ThirdParty/Ert/external/catch2/catch/catch.hpp @@ -0,0 +1,13287 @@ +/* + * Catch v2.2.3 + * Generated: 2018-06-06 23:11:57.601416 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp + + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 2 +#define CATCH_VERSION_PATCH 3 + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// start catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic ignored "-Wunused-variable" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic ignored "-Wparentheses" +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wpadded" +#endif +// end catch_suppress_warnings.h +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +# define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +# define CATCH_CONFIG_EXTERNAL_INTERFACES +# if defined(CATCH_CONFIG_DISABLE_MATCHERS) +# undef CATCH_CONFIG_DISABLE_MATCHERS +# endif +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +#ifdef __APPLE__ +# include +# if TARGET_OS_OSX == 1 +# define CATCH_PLATFORM_MAC +# elif TARGET_OS_IPHONE == 1 +# define CATCH_PLATFORM_IPHONE +# endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +# define CATCH_PLATFORM_WINDOWS +#endif + +// end catch_platform.h + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// start catch_user_interfaces.h + +namespace Catch { + unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h + +// start catch_common.h + +// start catch_compiler_capabilities.h + +// Detect a number of compiler features - by compiler +// The following features are defined: +// +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +#ifdef __cplusplus + +# if __cplusplus >= 201402L +# define CATCH_CPP14_OR_GREATER +# endif + +# if __cplusplus >= 201703L +# define CATCH_CPP17_OR_GREATER +# endif + +#endif + +#if defined(CATCH_CPP17_OR_GREATER) +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +#ifdef __clang__ + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic push" ) \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") +# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic pop" ) + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic push" ) \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic pop" ) + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#endif + +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE + +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +# if _MSC_VER >= 1900 // Visual Studio 2015 or newer +# define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +# endif + +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define CATCH_CONFIG_COLOUR_NONE +# else +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# endif + +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// + +// DJGPP +#ifdef __DJGPP__ +# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ + +//////////////////////////////////////////////////////////////////////////////// + +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) + #define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) +# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +# define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS +#endif + +// end catch_compiler_capabilities.h +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#include +#include +#include + +namespace Catch { + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; + + protected: + NonCopyable(); + virtual ~NonCopyable(); + }; + + struct SourceLineInfo { + + SourceLineInfo() = delete; + SourceLineInfo( char const* _file, std::size_t _line ) noexcept + : file( _file ), + line( _line ) + {} + + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo( SourceLineInfo && ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo& operator = ( SourceLineInfo && ) = default; + + bool empty() const noexcept; + bool operator == ( SourceLineInfo const& other ) const noexcept; + bool operator < ( SourceLineInfo const& other ) const noexcept; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() const; + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO \ + ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) + +// end catch_common.h +namespace Catch { + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h + +// start catch_interfaces_testcase.h + +#include +#include + +namespace Catch { + + class TestSpec; + + struct ITestInvoker { + virtual void invoke () const = 0; + virtual ~ITestInvoker(); + }; + + using ITestCasePtr = std::shared_ptr; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +// end catch_interfaces_testcase.h +// start catch_stringref.h + +#include +#include +#include + +namespace Catch { + + class StringData; + + /// A non-owning string class (similar to the forthcoming std::string_view) + /// Note that, because a StringRef may be a substring of another string, + /// it may not be null terminated. c_str() must return a null terminated + /// string, however, and so the StringRef will internally take ownership + /// (taking a copy), if necessary. In theory this ownership is not externally + /// visible - but it does mean (substring) StringRefs should not be shared between + /// threads. + class StringRef { + public: + using size_type = std::size_t; + + private: + friend struct StringRefTestAccess; + + char const* m_start; + size_type m_size; + + char* m_data = nullptr; + + void takeOwnership(); + + static constexpr char const* const s_empty = ""; + + public: // construction/ assignment + StringRef() noexcept + : StringRef( s_empty, 0 ) + {} + + StringRef( StringRef const& other ) noexcept + : m_start( other.m_start ), + m_size( other.m_size ) + {} + + StringRef( StringRef&& other ) noexcept + : m_start( other.m_start ), + m_size( other.m_size ), + m_data( other.m_data ) + { + other.m_data = nullptr; + } + + StringRef( char const* rawChars ) noexcept; + + StringRef( char const* rawChars, size_type size ) noexcept + : m_start( rawChars ), + m_size( size ) + {} + + StringRef( std::string const& stdString ) noexcept + : m_start( stdString.c_str() ), + m_size( stdString.size() ) + {} + + ~StringRef() noexcept { + delete[] m_data; + } + + auto operator = ( StringRef const &other ) noexcept -> StringRef& { + delete[] m_data; + m_data = nullptr; + m_start = other.m_start; + m_size = other.m_size; + return *this; + } + + operator std::string() const; + + void swap( StringRef& other ) noexcept; + + public: // operators + auto operator == ( StringRef const& other ) const noexcept -> bool; + auto operator != ( StringRef const& other ) const noexcept -> bool; + + auto operator[] ( size_type index ) const noexcept -> char; + + public: // named queries + auto empty() const noexcept -> bool { + return m_size == 0; + } + auto size() const noexcept -> size_type { + return m_size; + } + + auto numberOfCharacters() const noexcept -> size_type; + auto c_str() const -> char const*; + + public: // substrings and searches + auto substr( size_type start, size_type size ) const noexcept -> StringRef; + + // Returns the current start pointer. + // Note that the pointer can change when if the StringRef is a substring + auto currentData() const noexcept -> char const*; + + private: // ownership queries - may not be consistent between calls + auto isOwned() const noexcept -> bool; + auto isSubstring() const noexcept -> bool; + }; + + auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string; + auto operator + ( StringRef const& lhs, char const* rhs ) -> std::string; + auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string; + + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; + + inline auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + return StringRef( rawChars, size ); + } + +} // namespace Catch + +// end catch_stringref.h +namespace Catch { + +template +class TestInvokerAsMethod : public ITestInvoker { + void (C::*m_testAsMethod)(); +public: + TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {} + + void invoke() const override { + C obj; + (obj.*m_testAsMethod)(); + } +}; + +auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*; + +template +auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* { + return new(std::nothrow) TestInvokerAsMethod( testAsMethod ); +} + +struct NameAndTags { + NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept; + StringRef name; + StringRef tags; +}; + +struct AutoReg : NonCopyable { + AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept; + ~AutoReg(); +}; + +} // end namespace Catch + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF + +#if defined(CATCH_CONFIG_DISABLE) + #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \ + static void TestName() + #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \ + namespace{ \ + struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ + void test(); \ + }; \ + } \ + void TestName::test() + +#endif + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ + static void TestName(); \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + static void TestName() + #define INTERNAL_CATCH_TESTCASE( ... ) \ + INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ \ + struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ + } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + void TestName::test() + #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ + INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) + + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, "", Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + +// end catch_test_registry.h +// start catch_capture.hpp + +// start catch_assertionhandler.h + +// start catch_assertioninfo.h + +// start catch_result_type.h + +namespace Catch { + + // ResultWas::OfType enum + struct ResultWas { enum OfType { + Unknown = -1, + Ok = 0, + Info = 1, + Warning = 2, + + FailureBit = 0x10, + + ExpressionFailed = FailureBit | 1, + ExplicitFailure = FailureBit | 2, + + Exception = 0x100 | FailureBit, + + ThrewException = Exception | 1, + DidntThrowException = Exception | 2, + + FatalErrorCondition = 0x200 | FailureBit + + }; }; + + bool isOk( ResultWas::OfType resultType ); + bool isJustInfo( int flags ); + + // ResultDisposition::Flags enum + struct ResultDisposition { enum Flags { + Normal = 0x01, + + ContinueOnFailure = 0x02, // Failures fail test, but execution continues + FalseTest = 0x04, // Prefix expression with ! + SuppressFail = 0x08 // Failures are reported but do not fail the test + }; }; + + ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ); + + bool shouldContinueOnFailure( int flags ); + inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } + bool shouldSuppressFailure( int flags ); + +} // end namespace Catch + +// end catch_result_type.h +namespace Catch { + + struct AssertionInfo + { + StringRef macroName; + SourceLineInfo lineInfo; + StringRef capturedExpression; + ResultDisposition::Flags resultDisposition; + + // We want to delete this constructor but a compiler bug in 4.8 means + // the struct is then treated as non-aggregate + //AssertionInfo() = delete; + }; + +} // end namespace Catch + +// end catch_assertioninfo.h +// start catch_decomposer.h + +// start catch_tostring.h + +#include +#include +#include +#include +// start catch_stream.h + +#include +#include +#include + +namespace Catch { + + std::ostream& cout(); + std::ostream& cerr(); + std::ostream& clog(); + + class StringRef; + + struct IStream { + virtual ~IStream(); + virtual std::ostream& stream() const = 0; + }; + + auto makeStream( StringRef const &filename ) -> IStream const*; + + class ReusableStringStream { + std::size_t m_index; + std::ostream* m_oss; + public: + ReusableStringStream(); + ~ReusableStringStream(); + + auto str() const -> std::string; + + template + auto operator << ( T const& value ) -> ReusableStringStream& { + *m_oss << value; + return *this; + } + auto get() -> std::ostream& { return *m_oss; } + + static void cleanup(); + }; +} + +// end catch_stream.h + +#ifdef __OBJC__ +// start catch_objc_arc.hpp + +#import + +#ifdef __has_feature +#define CATCH_ARC_ENABLED __has_feature(objc_arc) +#else +#define CATCH_ARC_ENABLED 0 +#endif + +void arcSafeRelease( NSObject* obj ); +id performOptionalSelector( id obj, SEL sel ); + +#if !CATCH_ARC_ENABLED +inline void arcSafeRelease( NSObject* obj ) { + [obj release]; +} +inline id performOptionalSelector( id obj, SEL sel ) { + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; + return nil; +} +#define CATCH_UNSAFE_UNRETAINED +#define CATCH_ARC_STRONG +#else +inline void arcSafeRelease( NSObject* ){} +inline id performOptionalSelector( id obj, SEL sel ) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#endif + if( [obj respondsToSelector: sel] ) + return [obj performSelector: sel]; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + return nil; +} +#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained +#define CATCH_ARC_STRONG __strong +#endif + +// end catch_objc_arc.hpp +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless +#endif + +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); + +namespace Catch { + // Bring in operator<< from global namespace into Catch namespace + using ::operator<<; + + namespace Detail { + + extern const std::string unprintableString; + + std::string rawMemoryToString( const void *object, std::size_t size ); + + template + std::string rawMemoryToString( const T& object ) { + return rawMemoryToString( &object, sizeof(object) ); + } + + template + class IsStreamInsertable { + template + static auto test(int) + -> decltype(std::declval() << std::declval(), std::true_type()); + + template + static auto test(...)->std::false_type; + + public: + static const bool value = decltype(test(0))::value; + }; + + template + std::string convertUnknownEnumToString( E e ); + + template + typename std::enable_if< + !std::is_enum::value && !std::is_base_of::value, + std::string>::type convertUnstreamable( T const& ) { + return Detail::unprintableString; + } + template + typename std::enable_if< + !std::is_enum::value && std::is_base_of::value, + std::string>::type convertUnstreamable(T const& ex) { + return ex.what(); + } + + template + typename std::enable_if< + std::is_enum::value + , std::string>::type convertUnstreamable( T const& value ) { + return convertUnknownEnumToString( value ); + } + +#if defined(_MANAGED) + //! Convert a CLR string to a utf8 std::string + template + std::string clrReferenceToString( T^ ref ) { + if (ref == nullptr) + return std::string("null"); + auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString()); + cli::pin_ptr p = &bytes[0]; + return std::string(reinterpret_cast(p), bytes->Length); + } +#endif + + } // namespace Detail + + // If we decide for C++14, change these to enable_if_ts + template + struct StringMaker { + template + static + typename std::enable_if<::Catch::Detail::IsStreamInsertable::value, std::string>::type + convert(const Fake& value) { + ReusableStringStream rss; + // NB: call using the function-like syntax to avoid ambiguity with + // user-defined templated operator<< under clang. + rss.operator<<(value); + return rss.str(); + } + + template + static + typename std::enable_if::value, std::string>::type + convert( const Fake& value ) { +#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) + return Detail::convertUnstreamable(value); +#else + return CATCH_CONFIG_FALLBACK_STRINGIFIER(value); +#endif + } + }; + + namespace Detail { + + // This function dispatches all stringification requests inside of Catch. + // Should be preferably called fully qualified, like ::Catch::Detail::stringify + template + std::string stringify(const T& e) { + return ::Catch::StringMaker::type>::type>::convert(e); + } + + template + std::string convertUnknownEnumToString( E e ) { + return ::Catch::Detail::stringify(static_cast::type>(e)); + } + +#if defined(_MANAGED) + template + std::string stringify( T^ e ) { + return ::Catch::StringMaker::convert(e); + } +#endif + + } // namespace Detail + + // Some predefined specializations + + template<> + struct StringMaker { + static std::string convert(const std::string& str); + }; +#ifdef CATCH_CONFIG_WCHAR + template<> + struct StringMaker { + static std::string convert(const std::wstring& wstr); + }; +#endif + + template<> + struct StringMaker { + static std::string convert(char const * str); + }; + template<> + struct StringMaker { + static std::string convert(char * str); + }; + +#ifdef CATCH_CONFIG_WCHAR + template<> + struct StringMaker { + static std::string convert(wchar_t const * str); + }; + template<> + struct StringMaker { + static std::string convert(wchar_t * str); + }; +#endif + + // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer, + // while keeping string semantics? + template + struct StringMaker { + static std::string convert(char const* str) { + return ::Catch::Detail::stringify(std::string{ str }); + } + }; + template + struct StringMaker { + static std::string convert(signed char const* str) { + return ::Catch::Detail::stringify(std::string{ reinterpret_cast(str) }); + } + }; + template + struct StringMaker { + static std::string convert(unsigned char const* str) { + return ::Catch::Detail::stringify(std::string{ reinterpret_cast(str) }); + } + }; + + template<> + struct StringMaker { + static std::string convert(int value); + }; + template<> + struct StringMaker { + static std::string convert(long value); + }; + template<> + struct StringMaker { + static std::string convert(long long value); + }; + template<> + struct StringMaker { + static std::string convert(unsigned int value); + }; + template<> + struct StringMaker { + static std::string convert(unsigned long value); + }; + template<> + struct StringMaker { + static std::string convert(unsigned long long value); + }; + + template<> + struct StringMaker { + static std::string convert(bool b); + }; + + template<> + struct StringMaker { + static std::string convert(char c); + }; + template<> + struct StringMaker { + static std::string convert(signed char c); + }; + template<> + struct StringMaker { + static std::string convert(unsigned char c); + }; + + template<> + struct StringMaker { + static std::string convert(std::nullptr_t); + }; + + template<> + struct StringMaker { + static std::string convert(float value); + }; + template<> + struct StringMaker { + static std::string convert(double value); + }; + + template + struct StringMaker { + template + static std::string convert(U* p) { + if (p) { + return ::Catch::Detail::rawMemoryToString(p); + } else { + return "nullptr"; + } + } + }; + + template + struct StringMaker { + static std::string convert(R C::* p) { + if (p) { + return ::Catch::Detail::rawMemoryToString(p); + } else { + return "nullptr"; + } + } + }; + +#if defined(_MANAGED) + template + struct StringMaker { + static std::string convert( T^ ref ) { + return ::Catch::Detail::clrReferenceToString(ref); + } + }; +#endif + + namespace Detail { + template + std::string rangeToString(InputIterator first, InputIterator last) { + ReusableStringStream rss; + rss << "{ "; + if (first != last) { + rss << ::Catch::Detail::stringify(*first); + for (++first; first != last; ++first) + rss << ", " << ::Catch::Detail::stringify(*first); + } + rss << " }"; + return rss.str(); + } + } + +#ifdef __OBJC__ + template<> + struct StringMaker { + static std::string convert(NSString * nsstring) { + if (!nsstring) + return "nil"; + return std::string("@") + [nsstring UTF8String]; + } + }; + template<> + struct StringMaker { + static std::string convert(NSObject* nsObject) { + return ::Catch::Detail::stringify([nsObject description]); + } + + }; + namespace Detail { + inline std::string stringify( NSString* nsstring ) { + return StringMaker::convert( nsstring ); + } + + } // namespace Detail +#endif // __OBJC__ + +} // namespace Catch + +////////////////////////////////////////////////////// +// Separate std-lib types stringification, so it can be selectively enabled +// This means that we do not bring in + +#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS) +# define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER +# define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif + +// Separate std::pair specialization +#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER) +#include +namespace Catch { + template + struct StringMaker > { + static std::string convert(const std::pair& pair) { + ReusableStringStream rss; + rss << "{ " + << ::Catch::Detail::stringify(pair.first) + << ", " + << ::Catch::Detail::stringify(pair.second) + << " }"; + return rss.str(); + } + }; +} +#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER + +// Separate std::tuple specialization +#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER) +#include +namespace Catch { + namespace Detail { + template< + typename Tuple, + std::size_t N = 0, + bool = (N < std::tuple_size::value) + > + struct TupleElementPrinter { + static void print(const Tuple& tuple, std::ostream& os) { + os << (N ? ", " : " ") + << ::Catch::Detail::stringify(std::get(tuple)); + TupleElementPrinter::print(tuple, os); + } + }; + + template< + typename Tuple, + std::size_t N + > + struct TupleElementPrinter { + static void print(const Tuple&, std::ostream&) {} + }; + + } + + template + struct StringMaker> { + static std::string convert(const std::tuple& tuple) { + ReusableStringStream rss; + rss << '{'; + Detail::TupleElementPrinter>::print(tuple, rss.get()); + rss << " }"; + return rss.str(); + } + }; +} +#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER + +namespace Catch { + struct not_this_one {}; // Tag type for detecting which begin/ end are being selected + + // Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace + using std::begin; + using std::end; + + not_this_one begin( ... ); + not_this_one end( ... ); + + template + struct is_range { + static const bool value = + !std::is_same())), not_this_one>::value && + !std::is_same())), not_this_one>::value; + }; + +#if defined(_MANAGED) // Managed types are never ranges + template + struct is_range { + static const bool value = false; + }; +#endif + + template + std::string rangeToString( Range const& range ) { + return ::Catch::Detail::rangeToString( begin( range ), end( range ) ); + } + + // Handle vector specially + template + std::string rangeToString( std::vector const& v ) { + ReusableStringStream rss; + rss << "{ "; + bool first = true; + for( bool b : v ) { + if( first ) + first = false; + else + rss << ", "; + rss << ::Catch::Detail::stringify( b ); + } + rss << " }"; + return rss.str(); + } + + template + struct StringMaker::value && !::Catch::Detail::IsStreamInsertable::value>::type> { + static std::string convert( R const& range ) { + return rangeToString( range ); + } + }; + + template + struct StringMaker { + static std::string convert(T const(&arr)[SZ]) { + return rangeToString(arr); + } + }; + +} // namespace Catch + +// Separate std::chrono::duration specialization +#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +#include +#include +#include + +namespace Catch { + +template +struct ratio_string { + static std::string symbol(); +}; + +template +std::string ratio_string::symbol() { + Catch::ReusableStringStream rss; + rss << '[' << Ratio::num << '/' + << Ratio::den << ']'; + return rss.str(); +} +template <> +struct ratio_string { + static std::string symbol(); +}; +template <> +struct ratio_string { + static std::string symbol(); +}; +template <> +struct ratio_string { + static std::string symbol(); +}; +template <> +struct ratio_string { + static std::string symbol(); +}; +template <> +struct ratio_string { + static std::string symbol(); +}; +template <> +struct ratio_string { + static std::string symbol(); +}; + + //////////// + // std::chrono::duration specializations + template + struct StringMaker> { + static std::string convert(std::chrono::duration const& duration) { + ReusableStringStream rss; + rss << duration.count() << ' ' << ratio_string::symbol() << 's'; + return rss.str(); + } + }; + template + struct StringMaker>> { + static std::string convert(std::chrono::duration> const& duration) { + ReusableStringStream rss; + rss << duration.count() << " s"; + return rss.str(); + } + }; + template + struct StringMaker>> { + static std::string convert(std::chrono::duration> const& duration) { + ReusableStringStream rss; + rss << duration.count() << " m"; + return rss.str(); + } + }; + template + struct StringMaker>> { + static std::string convert(std::chrono::duration> const& duration) { + ReusableStringStream rss; + rss << duration.count() << " h"; + return rss.str(); + } + }; + + //////////// + // std::chrono::time_point specialization + // Generic time_point cannot be specialized, only std::chrono::time_point + template + struct StringMaker> { + static std::string convert(std::chrono::time_point const& time_point) { + return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch"; + } + }; + // std::chrono::time_point specialization + template + struct StringMaker> { + static std::string convert(std::chrono::time_point const& time_point) { + auto converted = std::chrono::system_clock::to_time_t(time_point); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &converted); +#else + std::tm* timeInfo = std::gmtime(&converted); +#endif + + auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); + char timeStamp[timeStampSize]; + const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp); + } + }; +} +#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// end catch_tostring.h +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4389) // '==' : signed/unsigned mismatch +#pragma warning(disable:4018) // more "signed/unsigned mismatch" +#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) +#pragma warning(disable:4180) // qualifier applied to function type has no meaning +#endif + +namespace Catch { + + struct ITransientExpression { + auto isBinaryExpression() const -> bool { return m_isBinaryExpression; } + auto getResult() const -> bool { return m_result; } + virtual void streamReconstructedExpression( std::ostream &os ) const = 0; + + ITransientExpression( bool isBinaryExpression, bool result ) + : m_isBinaryExpression( isBinaryExpression ), + m_result( result ) + {} + + // We don't actually need a virtual destructor, but many static analysers + // complain if it's not here :-( + virtual ~ITransientExpression(); + + bool m_isBinaryExpression; + bool m_result; + + }; + + void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ); + + template + class BinaryExpr : public ITransientExpression { + LhsT m_lhs; + StringRef m_op; + RhsT m_rhs; + + void streamReconstructedExpression( std::ostream &os ) const override { + formatReconstructedExpression + ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) ); + } + + public: + BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs ) + : ITransientExpression{ true, comparisonResult }, + m_lhs( lhs ), + m_op( op ), + m_rhs( rhs ) + {} + }; + + template + class UnaryExpr : public ITransientExpression { + LhsT m_lhs; + + void streamReconstructedExpression( std::ostream &os ) const override { + os << Catch::Detail::stringify( m_lhs ); + } + + public: + explicit UnaryExpr( LhsT lhs ) + : ITransientExpression{ false, lhs ? true : false }, + m_lhs( lhs ) + {} + }; + + // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int) + template + auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast(lhs == rhs); } + template + auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast( rhs ); } + template + auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast( rhs ); } + template + auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) == rhs; } + template + auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) == rhs; } + + template + auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast(lhs != rhs); } + template + auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast( rhs ); } + template + auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast( rhs ); } + template + auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) != rhs; } + template + auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast( lhs ) != rhs; } + + template + class ExprLhs { + LhsT m_lhs; + public: + explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {} + + template + auto operator == ( RhsT const& rhs ) -> BinaryExpr const { + return { compareEqual( m_lhs, rhs ), m_lhs, "==", rhs }; + } + auto operator == ( bool rhs ) -> BinaryExpr const { + return { m_lhs == rhs, m_lhs, "==", rhs }; + } + + template + auto operator != ( RhsT const& rhs ) -> BinaryExpr const { + return { compareNotEqual( m_lhs, rhs ), m_lhs, "!=", rhs }; + } + auto operator != ( bool rhs ) -> BinaryExpr const { + return { m_lhs != rhs, m_lhs, "!=", rhs }; + } + + template + auto operator > ( RhsT const& rhs ) -> BinaryExpr const { + return { static_cast(m_lhs > rhs), m_lhs, ">", rhs }; + } + template + auto operator < ( RhsT const& rhs ) -> BinaryExpr const { + return { static_cast(m_lhs < rhs), m_lhs, "<", rhs }; + } + template + auto operator >= ( RhsT const& rhs ) -> BinaryExpr const { + return { static_cast(m_lhs >= rhs), m_lhs, ">=", rhs }; + } + template + auto operator <= ( RhsT const& rhs ) -> BinaryExpr const { + return { static_cast(m_lhs <= rhs), m_lhs, "<=", rhs }; + } + + auto makeUnaryExpr() const -> UnaryExpr { + return UnaryExpr{ m_lhs }; + } + }; + + void handleExpression( ITransientExpression const& expr ); + + template + void handleExpression( ExprLhs const& expr ) { + handleExpression( expr.makeUnaryExpr() ); + } + + struct Decomposer { + template + auto operator <= ( T const& lhs ) -> ExprLhs { + return ExprLhs{ lhs }; + } + + auto operator <=( bool value ) -> ExprLhs { + return ExprLhs{ value }; + } + }; + +} // end namespace Catch + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// end catch_decomposer.h +// start catch_interfaces_capture.h + +#include + +namespace Catch { + + class AssertionResult; + struct AssertionInfo; + struct SectionInfo; + struct SectionEndInfo; + struct MessageInfo; + struct Counts; + struct BenchmarkInfo; + struct BenchmarkStats; + struct AssertionReaction; + + struct ITransientExpression; + + struct IResultCapture { + + virtual ~IResultCapture(); + + virtual bool sectionStarted( SectionInfo const& sectionInfo, + Counts& assertions ) = 0; + virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; + virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; + + virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0; + virtual void benchmarkEnded( BenchmarkStats const& stats ) = 0; + + virtual void pushScopedMessage( MessageInfo const& message ) = 0; + virtual void popScopedMessage( MessageInfo const& message ) = 0; + + virtual void handleFatalErrorCondition( StringRef message ) = 0; + + virtual void handleExpr + ( AssertionInfo const& info, + ITransientExpression const& expr, + AssertionReaction& reaction ) = 0; + virtual void handleMessage + ( AssertionInfo const& info, + ResultWas::OfType resultType, + StringRef const& message, + AssertionReaction& reaction ) = 0; + virtual void handleUnexpectedExceptionNotThrown + ( AssertionInfo const& info, + AssertionReaction& reaction ) = 0; + virtual void handleUnexpectedInflightException + ( AssertionInfo const& info, + std::string const& message, + AssertionReaction& reaction ) = 0; + virtual void handleIncomplete + ( AssertionInfo const& info ) = 0; + virtual void handleNonExpr + ( AssertionInfo const &info, + ResultWas::OfType resultType, + AssertionReaction &reaction ) = 0; + + virtual bool lastAssertionPassed() = 0; + virtual void assertionPassed() = 0; + + // Deprecated, do not use: + virtual std::string getCurrentTestName() const = 0; + virtual const AssertionResult* getLastResult() const = 0; + virtual void exceptionEarlyReported() = 0; + }; + + IResultCapture& getResultCapture(); +} + +// end catch_interfaces_capture.h +namespace Catch { + + struct TestFailureException{}; + struct AssertionResultData; + struct IResultCapture; + class RunContext; + + class LazyExpression { + friend class AssertionHandler; + friend struct AssertionStats; + friend class RunContext; + + ITransientExpression const* m_transientExpression = nullptr; + bool m_isNegated; + public: + LazyExpression( bool isNegated ); + LazyExpression( LazyExpression const& other ); + LazyExpression& operator = ( LazyExpression const& ) = delete; + + explicit operator bool() const; + + friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&; + }; + + struct AssertionReaction { + bool shouldDebugBreak = false; + bool shouldThrow = false; + }; + + class AssertionHandler { + AssertionInfo m_assertionInfo; + AssertionReaction m_reaction; + bool m_completed = false; + IResultCapture& m_resultCapture; + + public: + AssertionHandler + ( StringRef macroName, + SourceLineInfo const& lineInfo, + StringRef capturedExpression, + ResultDisposition::Flags resultDisposition ); + ~AssertionHandler() { + if ( !m_completed ) { + m_resultCapture.handleIncomplete( m_assertionInfo ); + } + } + + template + void handleExpr( ExprLhs const& expr ) { + handleExpr( expr.makeUnaryExpr() ); + } + void handleExpr( ITransientExpression const& expr ); + + void handleMessage(ResultWas::OfType resultType, StringRef const& message); + + void handleExceptionThrownAsExpected(); + void handleUnexpectedExceptionNotThrown(); + void handleExceptionNotThrownAsExpected(); + void handleThrowingCallSkipped(); + void handleUnexpectedInflightException(); + + void complete(); + void setCompleted(); + + // query + auto allowThrows() const -> bool; + }; + + void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString ); + +} // namespace Catch + +// end catch_assertionhandler.h +// start catch_message.h + +#include + +namespace Catch { + + struct MessageInfo { + MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ); + + std::string macroName; + std::string message; + SourceLineInfo lineInfo; + ResultWas::OfType type; + unsigned int sequence; + + bool operator == ( MessageInfo const& other ) const; + bool operator < ( MessageInfo const& other ) const; + private: + static unsigned int globalCount; + }; + + struct MessageStream { + + template + MessageStream& operator << ( T const& value ) { + m_stream << value; + return *this; + } + + ReusableStringStream m_stream; + }; + + struct MessageBuilder : MessageStream { + MessageBuilder( std::string const& macroName, + SourceLineInfo const& lineInfo, + ResultWas::OfType type ); + + template + MessageBuilder& operator << ( T const& value ) { + m_stream << value; + return *this; + } + + MessageInfo m_info; + }; + + class ScopedMessage { + public: + explicit ScopedMessage( MessageBuilder const& builder ); + ~ScopedMessage(); + + MessageInfo m_info; + }; + +} // end namespace Catch + +// end catch_message.h +#if !defined(CATCH_CONFIG_DISABLE) + +#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) + #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__ +#else + #define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" +#endif + +#if defined(CATCH_CONFIG_FAST_COMPILE) + +/////////////////////////////////////////////////////////////////////////////// +// Another way to speed-up compilation is to omit local try-catch for REQUIRE* +// macros. +#define INTERNAL_CATCH_TRY +#define INTERNAL_CATCH_CATCH( capturer ) + +#else // CATCH_CONFIG_FAST_COMPILE + +#define INTERNAL_CATCH_TRY try +#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); } + +#endif + +#define INTERNAL_CATCH_REACT( handler ) handler.complete(); + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ + INTERNAL_CATCH_TRY { \ + CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \ + CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( (void)0, false && static_cast( !!(__VA_ARGS__) ) ) // the expression here is never evaluated at runtime but it forces the compiler to give it a look + // The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \ + INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ + if( Catch::getResultCapture().lastAssertionPassed() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \ + INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \ + if( !Catch::getResultCapture().lastAssertionPassed() ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \ + try { \ + static_cast(__VA_ARGS__); \ + catchAssertionHandler.handleExceptionNotThrownAsExpected(); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast(__VA_ARGS__); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleExceptionThrownAsExpected(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast(expr); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( exceptionType const& ) { \ + catchAssertionHandler.handleExceptionThrownAsExpected(); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ + catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_INFO( macroName, log ) \ + Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log ); + +/////////////////////////////////////////////////////////////////////////////// +// Although this is matcher-based, it can be used with just a string +#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast(__VA_ARGS__); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( ... ) { \ + Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher ); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +#endif // CATCH_CONFIG_DISABLE + +// end catch_capture.hpp +// start catch_section.h + +// start catch_section_info.h + +// start catch_totals.h + +#include + +namespace Catch { + + struct Counts { + Counts operator - ( Counts const& other ) const; + Counts& operator += ( Counts const& other ); + + std::size_t total() const; + bool allPassed() const; + bool allOk() const; + + std::size_t passed = 0; + std::size_t failed = 0; + std::size_t failedButOk = 0; + }; + + struct Totals { + + Totals operator - ( Totals const& other ) const; + Totals& operator += ( Totals const& other ); + + Totals delta( Totals const& prevTotals ) const; + + int error = 0; + Counts assertions; + Counts testCases; + }; +} + +// end catch_totals.h +#include + +namespace Catch { + + struct SectionInfo { + SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description = std::string() ); + + std::string name; + std::string description; + SourceLineInfo lineInfo; + }; + + struct SectionEndInfo { + SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ); + + SectionInfo sectionInfo; + Counts prevAssertions; + double durationInSeconds; + }; + +} // end namespace Catch + +// end catch_section_info.h +// start catch_timer.h + +#include + +namespace Catch { + + auto getCurrentNanosecondsSinceEpoch() -> uint64_t; + auto getEstimatedClockResolution() -> uint64_t; + + class Timer { + uint64_t m_nanoseconds = 0; + public: + void start(); + auto getElapsedNanoseconds() const -> uint64_t; + auto getElapsedMicroseconds() const -> uint64_t; + auto getElapsedMilliseconds() const -> unsigned int; + auto getElapsedSeconds() const -> double; + }; + +} // namespace Catch + +// end catch_timer.h +#include + +namespace Catch { + + class Section : NonCopyable { + public: + Section( SectionInfo const& info ); + ~Section(); + + // This indicates whether the section should be executed or not + explicit operator bool() const; + + private: + SectionInfo m_info; + + std::string m_name; + Counts m_assertions; + bool m_sectionIncluded; + Timer m_timer; + }; + +} // end namespace Catch + + #define INTERNAL_CATCH_SECTION( ... ) \ + if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) + +// end catch_section.h +// start catch_benchmark.h + +#include +#include + +namespace Catch { + + class BenchmarkLooper { + + std::string m_name; + std::size_t m_count = 0; + std::size_t m_iterationsToRun = 1; + uint64_t m_resolution; + Timer m_timer; + + static auto getResolution() -> uint64_t; + public: + // Keep most of this inline as it's on the code path that is being timed + BenchmarkLooper( StringRef name ) + : m_name( name ), + m_resolution( getResolution() ) + { + reportStart(); + m_timer.start(); + } + + explicit operator bool() { + if( m_count < m_iterationsToRun ) + return true; + return needsMoreIterations(); + } + + void increment() { + ++m_count; + } + + void reportStart(); + auto needsMoreIterations() -> bool; + }; + +} // end namespace Catch + +#define BENCHMARK( name ) \ + for( Catch::BenchmarkLooper looper( name ); looper; looper.increment() ) + +// end catch_benchmark.h +// start catch_interfaces_exception.h + +// start catch_interfaces_registry_hub.h + +#include +#include + +namespace Catch { + + class TestCase; + struct ITestCaseRegistry; + struct IExceptionTranslatorRegistry; + struct IExceptionTranslator; + struct IReporterRegistry; + struct IReporterFactory; + struct ITagAliasRegistry; + class StartupExceptionRegistry; + + using IReporterFactoryPtr = std::shared_ptr; + + struct IRegistryHub { + virtual ~IRegistryHub(); + + virtual IReporterRegistry const& getReporterRegistry() const = 0; + virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; + virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0; + + virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; + + virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0; + }; + + struct IMutableRegistryHub { + virtual ~IMutableRegistryHub(); + virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0; + virtual void registerListener( IReporterFactoryPtr const& factory ) = 0; + virtual void registerTest( TestCase const& testInfo ) = 0; + virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; + virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0; + virtual void registerStartupException() noexcept = 0; + }; + + IRegistryHub& getRegistryHub(); + IMutableRegistryHub& getMutableRegistryHub(); + void cleanUp(); + std::string translateActiveException(); + +} + +// end catch_interfaces_registry_hub.h +#if defined(CATCH_CONFIG_DISABLE) + #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \ + static std::string translatorName( signature ) +#endif + +#include +#include +#include + +namespace Catch { + using exceptionTranslateFunction = std::string(*)(); + + struct IExceptionTranslator; + using ExceptionTranslators = std::vector>; + + struct IExceptionTranslator { + virtual ~IExceptionTranslator(); + virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; + }; + + struct IExceptionTranslatorRegistry { + virtual ~IExceptionTranslatorRegistry(); + + virtual std::string translateActiveException() const = 0; + }; + + class ExceptionTranslatorRegistrar { + template + class ExceptionTranslator : public IExceptionTranslator { + public: + + ExceptionTranslator( std::string(*translateFunction)( T& ) ) + : m_translateFunction( translateFunction ) + {} + + std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override { + try { + if( it == itEnd ) + std::rethrow_exception(std::current_exception()); + else + return (*it)->translate( it+1, itEnd ); + } + catch( T& ex ) { + return m_translateFunction( ex ); + } + } + + protected: + std::string(*m_translateFunction)( T& ); + }; + + public: + template + ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { + getMutableRegistryHub().registerTranslator + ( new ExceptionTranslator( translateFunction ) ); + } + }; +} + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ + static std::string translatorName( signature ); \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + static std::string translatorName( signature ) + +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) + +// end catch_interfaces_exception.h +// start catch_approx.h + +#include +#include + +namespace Catch { +namespace Detail { + + class Approx { + private: + bool equalityComparisonImpl(double other) const; + + public: + explicit Approx ( double value ); + + static Approx custom(); + + template ::value>::type> + Approx operator()( T const& value ) { + Approx approx( static_cast(value) ); + approx.epsilon( m_epsilon ); + approx.margin( m_margin ); + approx.scale( m_scale ); + return approx; + } + + template ::value>::type> + explicit Approx( T const& value ): Approx(static_cast(value)) + {} + + template ::value>::type> + friend bool operator == ( const T& lhs, Approx const& rhs ) { + auto lhs_v = static_cast(lhs); + return rhs.equalityComparisonImpl(lhs_v); + } + + template ::value>::type> + friend bool operator == ( Approx const& lhs, const T& rhs ) { + return operator==( rhs, lhs ); + } + + template ::value>::type> + friend bool operator != ( T const& lhs, Approx const& rhs ) { + return !operator==( lhs, rhs ); + } + + template ::value>::type> + friend bool operator != ( Approx const& lhs, T const& rhs ) { + return !operator==( rhs, lhs ); + } + + template ::value>::type> + friend bool operator <= ( T const& lhs, Approx const& rhs ) { + return static_cast(lhs) < rhs.m_value || lhs == rhs; + } + + template ::value>::type> + friend bool operator <= ( Approx const& lhs, T const& rhs ) { + return lhs.m_value < static_cast(rhs) || lhs == rhs; + } + + template ::value>::type> + friend bool operator >= ( T const& lhs, Approx const& rhs ) { + return static_cast(lhs) > rhs.m_value || lhs == rhs; + } + + template ::value>::type> + friend bool operator >= ( Approx const& lhs, T const& rhs ) { + return lhs.m_value > static_cast(rhs) || lhs == rhs; + } + + template ::value>::type> + Approx& epsilon( T const& newEpsilon ) { + double epsilonAsDouble = static_cast(newEpsilon); + if( epsilonAsDouble < 0 || epsilonAsDouble > 1.0 ) { + throw std::domain_error + ( "Invalid Approx::epsilon: " + + Catch::Detail::stringify( epsilonAsDouble ) + + ", Approx::epsilon has to be between 0 and 1" ); + } + m_epsilon = epsilonAsDouble; + return *this; + } + + template ::value>::type> + Approx& margin( T const& newMargin ) { + double marginAsDouble = static_cast(newMargin); + if( marginAsDouble < 0 ) { + throw std::domain_error + ( "Invalid Approx::margin: " + + Catch::Detail::stringify( marginAsDouble ) + + ", Approx::Margin has to be non-negative." ); + + } + m_margin = marginAsDouble; + return *this; + } + + template ::value>::type> + Approx& scale( T const& newScale ) { + m_scale = static_cast(newScale); + return *this; + } + + std::string toString() const; + + private: + double m_epsilon; + double m_margin; + double m_scale; + double m_value; + }; +} + +template<> +struct StringMaker { + static std::string convert(Catch::Detail::Approx const& value); +}; + +} // end namespace Catch + +// end catch_approx.h +// start catch_string_manip.h + +#include +#include + +namespace Catch { + + bool startsWith( std::string const& s, std::string const& prefix ); + bool startsWith( std::string const& s, char prefix ); + bool endsWith( std::string const& s, std::string const& suffix ); + bool endsWith( std::string const& s, char suffix ); + bool contains( std::string const& s, std::string const& infix ); + void toLowerInPlace( std::string& s ); + std::string toLower( std::string const& s ); + std::string trim( std::string const& str ); + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); + + struct pluralise { + pluralise( std::size_t count, std::string const& label ); + + friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); + + std::size_t m_count; + std::string m_label; + }; +} + +// end catch_string_manip.h +#ifndef CATCH_CONFIG_DISABLE_MATCHERS +// start catch_capture_matchers.h + +// start catch_matchers.h + +#include +#include + +namespace Catch { +namespace Matchers { + namespace Impl { + + template struct MatchAllOf; + template struct MatchAnyOf; + template struct MatchNotOf; + + class MatcherUntypedBase { + public: + MatcherUntypedBase() = default; + MatcherUntypedBase ( MatcherUntypedBase const& ) = default; + MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete; + std::string toString() const; + + protected: + virtual ~MatcherUntypedBase(); + virtual std::string describe() const = 0; + mutable std::string m_cachedToString; + }; + + template + struct MatcherMethod { + virtual bool match( ObjectT const& arg ) const = 0; + }; + template + struct MatcherMethod { + virtual bool match( PtrT* arg ) const = 0; + }; + + template + struct MatcherBase : MatcherUntypedBase, MatcherMethod { + + MatchAllOf operator && ( MatcherBase const& other ) const; + MatchAnyOf operator || ( MatcherBase const& other ) const; + MatchNotOf operator ! () const; + }; + + template + struct MatchAllOf : MatcherBase { + bool match( ArgT const& arg ) const override { + for( auto matcher : m_matchers ) { + if (!matcher->match(arg)) + return false; + } + return true; + } + std::string describe() const override { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + bool first = true; + for( auto matcher : m_matchers ) { + if( first ) + first = false; + else + description += " and "; + description += matcher->toString(); + } + description += " )"; + return description; + } + + MatchAllOf& operator && ( MatcherBase const& other ) { + m_matchers.push_back( &other ); + return *this; + } + + std::vector const*> m_matchers; + }; + template + struct MatchAnyOf : MatcherBase { + + bool match( ArgT const& arg ) const override { + for( auto matcher : m_matchers ) { + if (matcher->match(arg)) + return true; + } + return false; + } + std::string describe() const override { + std::string description; + description.reserve( 4 + m_matchers.size()*32 ); + description += "( "; + bool first = true; + for( auto matcher : m_matchers ) { + if( first ) + first = false; + else + description += " or "; + description += matcher->toString(); + } + description += " )"; + return description; + } + + MatchAnyOf& operator || ( MatcherBase const& other ) { + m_matchers.push_back( &other ); + return *this; + } + + std::vector const*> m_matchers; + }; + + template + struct MatchNotOf : MatcherBase { + + MatchNotOf( MatcherBase const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {} + + bool match( ArgT const& arg ) const override { + return !m_underlyingMatcher.match( arg ); + } + + std::string describe() const override { + return "not " + m_underlyingMatcher.toString(); + } + MatcherBase const& m_underlyingMatcher; + }; + + template + MatchAllOf MatcherBase::operator && ( MatcherBase const& other ) const { + return MatchAllOf() && *this && other; + } + template + MatchAnyOf MatcherBase::operator || ( MatcherBase const& other ) const { + return MatchAnyOf() || *this || other; + } + template + MatchNotOf MatcherBase::operator ! () const { + return MatchNotOf( *this ); + } + + } // namespace Impl + +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch + +// end catch_matchers.h +// start catch_matchers_floating.h + +#include +#include + +namespace Catch { +namespace Matchers { + + namespace Floating { + + enum class FloatingPointKind : uint8_t; + + struct WithinAbsMatcher : MatcherBase { + WithinAbsMatcher(double target, double margin); + bool match(double const& matchee) const override; + std::string describe() const override; + private: + double m_target; + double m_margin; + }; + + struct WithinUlpsMatcher : MatcherBase { + WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType); + bool match(double const& matchee) const override; + std::string describe() const override; + private: + double m_target; + int m_ulps; + FloatingPointKind m_type; + }; + + } // namespace Floating + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff); + Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff); + Floating::WithinAbsMatcher WithinAbs(double target, double margin); + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_floating.h +// start catch_matchers_generic.hpp + +#include +#include + +namespace Catch { +namespace Matchers { +namespace Generic { + +namespace Detail { + std::string finalizeDescription(const std::string& desc); +} + +template +class PredicateMatcher : public MatcherBase { + std::function m_predicate; + std::string m_description; +public: + + PredicateMatcher(std::function const& elem, std::string const& descr) + :m_predicate(std::move(elem)), + m_description(Detail::finalizeDescription(descr)) + {} + + bool match( T const& item ) const override { + return m_predicate(item); + } + + std::string describe() const override { + return m_description; + } +}; + +} // namespace Generic + + // The following functions create the actual matcher objects. + // The user has to explicitly specify type to the function, because + // infering std::function is hard (but possible) and + // requires a lot of TMP. + template + Generic::PredicateMatcher Predicate(std::function const& predicate, std::string const& description = "") { + return Generic::PredicateMatcher(predicate, description); + } + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_generic.hpp +// start catch_matchers_string.h + +#include + +namespace Catch { +namespace Matchers { + + namespace StdString { + + struct CasedString + { + CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ); + std::string adjustString( std::string const& str ) const; + std::string caseSensitivitySuffix() const; + + CaseSensitive::Choice m_caseSensitivity; + std::string m_str; + }; + + struct StringMatcherBase : MatcherBase { + StringMatcherBase( std::string const& operation, CasedString const& comparator ); + std::string describe() const override; + + CasedString m_comparator; + std::string m_operation; + }; + + struct EqualsMatcher : StringMatcherBase { + EqualsMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + struct ContainsMatcher : StringMatcherBase { + ContainsMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + struct StartsWithMatcher : StringMatcherBase { + StartsWithMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + struct EndsWithMatcher : StringMatcherBase { + EndsWithMatcher( CasedString const& comparator ); + bool match( std::string const& source ) const override; + }; + + struct RegexMatcher : MatcherBase { + RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity ); + bool match( std::string const& matchee ) const override; + std::string describe() const override; + + private: + std::string m_regex; + CaseSensitive::Choice m_caseSensitivity; + }; + + } // namespace StdString + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ); + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_string.h +// start catch_matchers_vector.h + +#include + +namespace Catch { +namespace Matchers { + + namespace Vector { + namespace Detail { + template + size_t count(InputIterator first, InputIterator last, T const& item) { + size_t cnt = 0; + for (; first != last; ++first) { + if (*first == item) { + ++cnt; + } + } + return cnt; + } + template + bool contains(InputIterator first, InputIterator last, T const& item) { + for (; first != last; ++first) { + if (*first == item) { + return true; + } + } + return false; + } + } + + template + struct ContainsElementMatcher : MatcherBase> { + + ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {} + + bool match(std::vector const &v) const override { + for (auto const& el : v) { + if (el == m_comparator) { + return true; + } + } + return false; + } + + std::string describe() const override { + return "Contains: " + ::Catch::Detail::stringify( m_comparator ); + } + + T const& m_comparator; + }; + + template + struct ContainsMatcher : MatcherBase> { + + ContainsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector const &v) const override { + // !TBD: see note in EqualsMatcher + if (m_comparator.size() > v.size()) + return false; + for (auto const& comparator : m_comparator) { + auto present = false; + for (const auto& el : v) { + if (el == comparator) { + present = true; + break; + } + } + if (!present) { + return false; + } + } + return true; + } + std::string describe() const override { + return "Contains: " + ::Catch::Detail::stringify( m_comparator ); + } + + std::vector const& m_comparator; + }; + + template + struct EqualsMatcher : MatcherBase> { + + EqualsMatcher(std::vector const &comparator) : m_comparator( comparator ) {} + + bool match(std::vector const &v) const override { + // !TBD: This currently works if all elements can be compared using != + // - a more general approach would be via a compare template that defaults + // to using !=. but could be specialised for, e.g. std::vector etc + // - then just call that directly + if (m_comparator.size() != v.size()) + return false; + for (std::size_t i = 0; i < v.size(); ++i) + if (m_comparator[i] != v[i]) + return false; + return true; + } + std::string describe() const override { + return "Equals: " + ::Catch::Detail::stringify( m_comparator ); + } + std::vector const& m_comparator; + }; + + template + struct UnorderedEqualsMatcher : MatcherBase> { + UnorderedEqualsMatcher(std::vector const& target) : m_target(target) {} + bool match(std::vector const& vec) const override { + // Note: This is a reimplementation of std::is_permutation, + // because I don't want to include inside the common path + if (m_target.size() != vec.size()) { + return false; + } + auto lfirst = m_target.begin(), llast = m_target.end(); + auto rfirst = vec.begin(), rlast = vec.end(); + // Cut common prefix to optimize checking of permuted parts + while (lfirst != llast && *lfirst != *rfirst) { + ++lfirst; ++rfirst; + } + if (lfirst == llast) { + return true; + } + + for (auto mid = lfirst; mid != llast; ++mid) { + // Skip already counted items + if (Detail::contains(lfirst, mid, *mid)) { + continue; + } + size_t num_vec = Detail::count(rfirst, rlast, *mid); + if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) { + return false; + } + } + + return true; + } + + std::string describe() const override { + return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target); + } + private: + std::vector const& m_target; + }; + + } // namespace Vector + + // The following functions create the actual matcher objects. + // This allows the types to be inferred + + template + Vector::ContainsMatcher Contains( std::vector const& comparator ) { + return Vector::ContainsMatcher( comparator ); + } + + template + Vector::ContainsElementMatcher VectorContains( T const& comparator ) { + return Vector::ContainsElementMatcher( comparator ); + } + + template + Vector::EqualsMatcher Equals( std::vector const& comparator ) { + return Vector::EqualsMatcher( comparator ); + } + + template + Vector::UnorderedEqualsMatcher UnorderedEquals(std::vector const& target) { + return Vector::UnorderedEqualsMatcher(target); + } + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_vector.h +namespace Catch { + + template + class MatchExpr : public ITransientExpression { + ArgT const& m_arg; + MatcherT m_matcher; + StringRef m_matcherString; + public: + MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString ) + : ITransientExpression{ true, matcher.match( arg ) }, + m_arg( arg ), + m_matcher( matcher ), + m_matcherString( matcherString ) + {} + + void streamReconstructedExpression( std::ostream &os ) const override { + auto matcherAsString = m_matcher.toString(); + os << Catch::Detail::stringify( m_arg ) << ' '; + if( matcherAsString == Detail::unprintableString ) + os << m_matcherString; + else + os << matcherAsString; + } + }; + + using StringMatcher = Matchers::Impl::MatcherBase; + + void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString ); + + template + auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef matcherString ) -> MatchExpr { + return MatchExpr( arg, matcher, matcherString ); + } + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + INTERNAL_CATCH_TRY { \ + catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher ) ); \ + } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \ + if( catchAssertionHandler.allowThrows() ) \ + try { \ + static_cast(__VA_ARGS__ ); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } \ + catch( exceptionType const& ex ) { \ + catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher ) ); \ + } \ + catch( ... ) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT( catchAssertionHandler ) \ + } while( false ) + +// end catch_capture_matchers.h +#endif + +// These files are included here so the single_include script doesn't put them +// in the conditionally compiled sections +// start catch_test_case_info.h + +#include +#include +#include + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + + struct ITestInvoker; + + struct TestCaseInfo { + enum SpecialProperties{ + None = 0, + IsHidden = 1 << 1, + ShouldFail = 1 << 2, + MayFail = 1 << 3, + Throws = 1 << 4, + NonPortable = 1 << 5, + Benchmark = 1 << 6 + }; + + TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::vector const& _tags, + SourceLineInfo const& _lineInfo ); + + friend void setTags( TestCaseInfo& testCaseInfo, std::vector tags ); + + bool isHidden() const; + bool throws() const; + bool okToFail() const; + bool expectedToFail() const; + + std::string tagsAsString() const; + + std::string name; + std::string className; + std::string description; + std::vector tags; + std::vector lcaseTags; + SourceLineInfo lineInfo; + SpecialProperties properties; + }; + + class TestCase : public TestCaseInfo { + public: + + TestCase( ITestInvoker* testCase, TestCaseInfo&& info ); + + TestCase withName( std::string const& _newName ) const; + + void invoke() const; + + TestCaseInfo const& getTestCaseInfo() const; + + bool operator == ( TestCase const& other ) const; + bool operator < ( TestCase const& other ) const; + + private: + std::shared_ptr test; + }; + + TestCase makeTestCase( ITestInvoker* testCase, + std::string const& className, + NameAndTags const& nameAndTags, + SourceLineInfo const& lineInfo ); +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_case_info.h +// start catch_interfaces_runner.h + +namespace Catch { + + struct IRunner { + virtual ~IRunner(); + virtual bool aborting() const = 0; + }; +} + +// end catch_interfaces_runner.h + +#ifdef __OBJC__ +// start catch_objc.hpp + +#import + +#include + +// NB. Any general catch headers included here must be included +// in catch.hpp first to make sure they are included by the single +// header for non obj-usage + +/////////////////////////////////////////////////////////////////////////////// +// This protocol is really only here for (self) documenting purposes, since +// all its methods are optional. +@protocol OcFixture + +@optional + +-(void) setUp; +-(void) tearDown; + +@end + +namespace Catch { + + class OcMethod : public ITestInvoker { + + public: + OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} + + virtual void invoke() const { + id obj = [[m_cls alloc] init]; + + performOptionalSelector( obj, @selector(setUp) ); + performOptionalSelector( obj, m_sel ); + performOptionalSelector( obj, @selector(tearDown) ); + + arcSafeRelease( obj ); + } + private: + virtual ~OcMethod() {} + + Class m_cls; + SEL m_sel; + }; + + namespace Detail{ + + inline std::string getAnnotation( Class cls, + std::string const& annotationName, + std::string const& testCaseName ) { + NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; + SEL sel = NSSelectorFromString( selStr ); + arcSafeRelease( selStr ); + id value = performOptionalSelector( cls, sel ); + if( value ) + return [(NSString*)value UTF8String]; + return ""; + } + } + + inline std::size_t registerTestMethods() { + std::size_t noTestMethods = 0; + int noClasses = objc_getClassList( nullptr, 0 ); + + Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); + objc_getClassList( classes, noClasses ); + + for( int c = 0; c < noClasses; c++ ) { + Class cls = classes[c]; + { + u_int count; + Method* methods = class_copyMethodList( cls, &count ); + for( u_int m = 0; m < count ; m++ ) { + SEL selector = method_getName(methods[m]); + std::string methodName = sel_getName(selector); + if( startsWith( methodName, "Catch_TestCase_" ) ) { + std::string testCaseName = methodName.substr( 15 ); + std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); + std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); + const char* className = class_getName( cls ); + + getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo("",0) ) ); + noTestMethods++; + } + } + free(methods); + } + } + return noTestMethods; + } + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) + + namespace Matchers { + namespace Impl { + namespace NSStringMatchers { + + struct StringHolder : MatcherBase{ + StringHolder( NSString* substr ) : m_substr( [substr copy] ){} + StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} + StringHolder() { + arcSafeRelease( m_substr ); + } + + bool match( NSString* arg ) const override { + return false; + } + + NSString* CATCH_ARC_STRONG m_substr; + }; + + struct Equals : StringHolder { + Equals( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const override { + return (str != nil || m_substr == nil ) && + [str isEqualToString:m_substr]; + } + + std::string describe() const override { + return "equals string: " + Catch::Detail::stringify( m_substr ); + } + }; + + struct Contains : StringHolder { + Contains( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location != NSNotFound; + } + + std::string describe() const override { + return "contains string: " + Catch::Detail::stringify( m_substr ); + } + }; + + struct StartsWith : StringHolder { + StartsWith( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const override { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == 0; + } + + std::string describe() const override { + return "starts with: " + Catch::Detail::stringify( m_substr ); + } + }; + struct EndsWith : StringHolder { + EndsWith( NSString* substr ) : StringHolder( substr ){} + + bool match( NSString* str ) const override { + return (str != nil || m_substr == nil ) && + [str rangeOfString:m_substr].location == [str length] - [m_substr length]; + } + + std::string describe() const override { + return "ends with: " + Catch::Detail::stringify( m_substr ); + } + }; + + } // namespace NSStringMatchers + } // namespace Impl + + inline Impl::NSStringMatchers::Equals + Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } + + inline Impl::NSStringMatchers::Contains + Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } + + inline Impl::NSStringMatchers::StartsWith + StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } + + inline Impl::NSStringMatchers::EndsWith + EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } + + } // namespace Matchers + + using namespace Matchers; + +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix +#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \ ++(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \ +{ \ +return @ name; \ +} \ ++(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \ +{ \ +return @ desc; \ +} \ +-(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix ) + +#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ ) + +// end catch_objc.hpp +#endif + +#ifdef CATCH_CONFIG_EXTERNAL_INTERFACES +// start catch_external_interfaces.h + +// start catch_reporter_bases.hpp + +// start catch_interfaces_reporter.h + +// start catch_config.hpp + +// start catch_test_spec_parser.h + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// start catch_test_spec.h + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// start catch_wildcard_pattern.h + +namespace Catch +{ + class WildcardPattern { + enum WildcardPosition { + NoWildcard = 0, + WildcardAtStart = 1, + WildcardAtEnd = 2, + WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd + }; + + public: + + WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ); + virtual ~WildcardPattern() = default; + virtual bool matches( std::string const& str ) const; + + private: + std::string adjustCase( std::string const& str ) const; + CaseSensitive::Choice m_caseSensitivity; + WildcardPosition m_wildcard = NoWildcard; + std::string m_pattern; + }; +} + +// end catch_wildcard_pattern.h +#include +#include +#include + +namespace Catch { + + class TestSpec { + struct Pattern { + virtual ~Pattern(); + virtual bool matches( TestCaseInfo const& testCase ) const = 0; + }; + using PatternPtr = std::shared_ptr; + + class NamePattern : public Pattern { + public: + NamePattern( std::string const& name ); + virtual ~NamePattern(); + virtual bool matches( TestCaseInfo const& testCase ) const override; + private: + WildcardPattern m_wildcardPattern; + }; + + class TagPattern : public Pattern { + public: + TagPattern( std::string const& tag ); + virtual ~TagPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const override; + private: + std::string m_tag; + }; + + class ExcludedPattern : public Pattern { + public: + ExcludedPattern( PatternPtr const& underlyingPattern ); + virtual ~ExcludedPattern(); + virtual bool matches( TestCaseInfo const& testCase ) const override; + private: + PatternPtr m_underlyingPattern; + }; + + struct Filter { + std::vector m_patterns; + + bool matches( TestCaseInfo const& testCase ) const; + }; + + public: + bool hasFilters() const; + bool matches( TestCaseInfo const& testCase ) const; + + private: + std::vector m_filters; + + friend class TestSpecParser; + }; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_spec.h +// start catch_interfaces_tag_alias_registry.h + +#include + +namespace Catch { + + struct TagAlias; + + struct ITagAliasRegistry { + virtual ~ITagAliasRegistry(); + // Nullptr if not present + virtual TagAlias const* find( std::string const& alias ) const = 0; + virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; + + static ITagAliasRegistry const& get(); + }; + +} // end namespace Catch + +// end catch_interfaces_tag_alias_registry.h +namespace Catch { + + class TestSpecParser { + enum Mode{ None, Name, QuotedName, Tag, EscapedName }; + Mode m_mode = None; + bool m_exclusion = false; + std::size_t m_start = std::string::npos, m_pos = 0; + std::string m_arg; + std::vector m_escapeChars; + TestSpec::Filter m_currentFilter; + TestSpec m_testSpec; + ITagAliasRegistry const* m_tagAliases = nullptr; + + public: + TestSpecParser( ITagAliasRegistry const& tagAliases ); + + TestSpecParser& parse( std::string const& arg ); + TestSpec testSpec(); + + private: + void visitChar( char c ); + void startNewMode( Mode mode, std::size_t start ); + void escape(); + std::string subString() const; + + template + void addPattern() { + std::string token = subString(); + for( std::size_t i = 0; i < m_escapeChars.size(); ++i ) + token = token.substr( 0, m_escapeChars[i]-m_start-i ) + token.substr( m_escapeChars[i]-m_start-i+1 ); + m_escapeChars.clear(); + if( startsWith( token, "exclude:" ) ) { + m_exclusion = true; + token = token.substr( 8 ); + } + if( !token.empty() ) { + TestSpec::PatternPtr pattern = std::make_shared( token ); + if( m_exclusion ) + pattern = std::make_shared( pattern ); + m_currentFilter.m_patterns.push_back( pattern ); + } + m_exclusion = false; + m_mode = None; + } + + void addFilter(); + }; + TestSpec parseTestSpec( std::string const& arg ); + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_spec_parser.h +// start catch_interfaces_config.h + +#include +#include +#include +#include + +namespace Catch { + + enum class Verbosity { + Quiet = 0, + Normal, + High + }; + + struct WarnAbout { enum What { + Nothing = 0x00, + NoAssertions = 0x01, + NoTests = 0x02 + }; }; + + struct ShowDurations { enum OrNot { + DefaultForReporter, + Always, + Never + }; }; + struct RunTests { enum InWhatOrder { + InDeclarationOrder, + InLexicographicalOrder, + InRandomOrder + }; }; + struct UseColour { enum YesOrNo { + Auto, + Yes, + No + }; }; + struct WaitForKeypress { enum When { + Never, + BeforeStart = 1, + BeforeExit = 2, + BeforeStartAndExit = BeforeStart | BeforeExit + }; }; + + class TestSpec; + + struct IConfig : NonCopyable { + + virtual ~IConfig(); + + virtual bool allowThrows() const = 0; + virtual std::ostream& stream() const = 0; + virtual std::string name() const = 0; + virtual bool includeSuccessfulResults() const = 0; + virtual bool shouldDebugBreak() const = 0; + virtual bool warnAboutMissingAssertions() const = 0; + virtual bool warnAboutNoTests() const = 0; + virtual int abortAfter() const = 0; + virtual bool showInvisibles() const = 0; + virtual ShowDurations::OrNot showDurations() const = 0; + virtual TestSpec const& testSpec() const = 0; + virtual bool hasTestFilters() const = 0; + virtual RunTests::InWhatOrder runOrder() const = 0; + virtual unsigned int rngSeed() const = 0; + virtual int benchmarkResolutionMultiple() const = 0; + virtual UseColour::YesOrNo useColour() const = 0; + virtual std::vector const& getSectionsToRun() const = 0; + virtual Verbosity verbosity() const = 0; + }; + + using IConfigPtr = std::shared_ptr; +} + +// end catch_interfaces_config.h +// Libstdc++ doesn't like incomplete classes for unique_ptr + +#include +#include +#include + +#ifndef CATCH_CONFIG_CONSOLE_WIDTH +#define CATCH_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { + + struct IStream; + + struct ConfigData { + bool listTests = false; + bool listTags = false; + bool listReporters = false; + bool listTestNamesOnly = false; + + bool showSuccessfulTests = false; + bool shouldDebugBreak = false; + bool noThrow = false; + bool showHelp = false; + bool showInvisibles = false; + bool filenamesAsTags = false; + bool libIdentify = false; + + int abortAfter = -1; + unsigned int rngSeed = 0; + int benchmarkResolutionMultiple = 100; + + Verbosity verbosity = Verbosity::Normal; + WarnAbout::What warnings = WarnAbout::Nothing; + ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter; + RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder; + UseColour::YesOrNo useColour = UseColour::Auto; + WaitForKeypress::When waitForKeypress = WaitForKeypress::Never; + + std::string outputFilename; + std::string name; + std::string processName; +#ifndef CATCH_CONFIG_DEFAULT_REPORTER +#define CATCH_CONFIG_DEFAULT_REPORTER "console" +#endif + std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER; +#undef CATCH_CONFIG_DEFAULT_REPORTER + + std::vector testsOrTags; + std::vector sectionsToRun; + }; + + class Config : public IConfig { + public: + + Config() = default; + Config( ConfigData const& data ); + virtual ~Config() = default; + + std::string const& getFilename() const; + + bool listTests() const; + bool listTestNamesOnly() const; + bool listTags() const; + bool listReporters() const; + + std::string getProcessName() const; + std::string const& getReporterName() const; + + std::vector const& getTestsOrTags() const; + std::vector const& getSectionsToRun() const override; + + virtual TestSpec const& testSpec() const override; + bool hasTestFilters() const override; + + bool showHelp() const; + + // IConfig interface + bool allowThrows() const override; + std::ostream& stream() const override; + std::string name() const override; + bool includeSuccessfulResults() const override; + bool warnAboutMissingAssertions() const override; + bool warnAboutNoTests() const override; + ShowDurations::OrNot showDurations() const override; + RunTests::InWhatOrder runOrder() const override; + unsigned int rngSeed() const override; + int benchmarkResolutionMultiple() const override; + UseColour::YesOrNo useColour() const override; + bool shouldDebugBreak() const override; + int abortAfter() const override; + bool showInvisibles() const override; + Verbosity verbosity() const override; + + private: + + IStream const* openStream(); + ConfigData m_data; + + std::unique_ptr m_stream; + TestSpec m_testSpec; + bool m_hasTestFilters = false; + }; + +} // end namespace Catch + +// end catch_config.hpp +// start catch_assertionresult.h + +#include + +namespace Catch { + + struct AssertionResultData + { + AssertionResultData() = delete; + + AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression ); + + std::string message; + mutable std::string reconstructedExpression; + LazyExpression lazyExpression; + ResultWas::OfType resultType; + + std::string reconstructExpression() const; + }; + + class AssertionResult { + public: + AssertionResult() = delete; + AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); + + bool isOk() const; + bool succeeded() const; + ResultWas::OfType getResultType() const; + bool hasExpression() const; + bool hasMessage() const; + std::string getExpression() const; + std::string getExpressionInMacro() const; + bool hasExpandedExpression() const; + std::string getExpandedExpression() const; + std::string getMessage() const; + SourceLineInfo getSourceInfo() const; + StringRef getTestMacroName() const; + + //protected: + AssertionInfo m_info; + AssertionResultData m_resultData; + }; + +} // end namespace Catch + +// end catch_assertionresult.h +// start catch_option.hpp + +namespace Catch { + + // An optional type + template + class Option { + public: + Option() : nullableValue( nullptr ) {} + Option( T const& _value ) + : nullableValue( new( storage ) T( _value ) ) + {} + Option( Option const& _other ) + : nullableValue( _other ? new( storage ) T( *_other ) : nullptr ) + {} + + ~Option() { + reset(); + } + + Option& operator= ( Option const& _other ) { + if( &_other != this ) { + reset(); + if( _other ) + nullableValue = new( storage ) T( *_other ); + } + return *this; + } + Option& operator = ( T const& _value ) { + reset(); + nullableValue = new( storage ) T( _value ); + return *this; + } + + void reset() { + if( nullableValue ) + nullableValue->~T(); + nullableValue = nullptr; + } + + T& operator*() { return *nullableValue; } + T const& operator*() const { return *nullableValue; } + T* operator->() { return nullableValue; } + const T* operator->() const { return nullableValue; } + + T valueOr( T const& defaultValue ) const { + return nullableValue ? *nullableValue : defaultValue; + } + + bool some() const { return nullableValue != nullptr; } + bool none() const { return nullableValue == nullptr; } + + bool operator !() const { return nullableValue == nullptr; } + explicit operator bool() const { + return some(); + } + + private: + T *nullableValue; + alignas(alignof(T)) char storage[sizeof(T)]; + }; + +} // end namespace Catch + +// end catch_option.hpp +#include +#include +#include +#include +#include + +namespace Catch { + + struct ReporterConfig { + explicit ReporterConfig( IConfigPtr const& _fullConfig ); + + ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream ); + + std::ostream& stream() const; + IConfigPtr fullConfig() const; + + private: + std::ostream* m_stream; + IConfigPtr m_fullConfig; + }; + + struct ReporterPreferences { + bool shouldRedirectStdOut = false; + }; + + template + struct LazyStat : Option { + LazyStat& operator=( T const& _value ) { + Option::operator=( _value ); + used = false; + return *this; + } + void reset() { + Option::reset(); + used = false; + } + bool used = false; + }; + + struct TestRunInfo { + TestRunInfo( std::string const& _name ); + std::string name; + }; + struct GroupInfo { + GroupInfo( std::string const& _name, + std::size_t _groupIndex, + std::size_t _groupsCount ); + + std::string name; + std::size_t groupIndex; + std::size_t groupsCounts; + }; + + struct AssertionStats { + AssertionStats( AssertionResult const& _assertionResult, + std::vector const& _infoMessages, + Totals const& _totals ); + + AssertionStats( AssertionStats const& ) = default; + AssertionStats( AssertionStats && ) = default; + AssertionStats& operator = ( AssertionStats const& ) = default; + AssertionStats& operator = ( AssertionStats && ) = default; + virtual ~AssertionStats(); + + AssertionResult assertionResult; + std::vector infoMessages; + Totals totals; + }; + + struct SectionStats { + SectionStats( SectionInfo const& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ); + SectionStats( SectionStats const& ) = default; + SectionStats( SectionStats && ) = default; + SectionStats& operator = ( SectionStats const& ) = default; + SectionStats& operator = ( SectionStats && ) = default; + virtual ~SectionStats(); + + SectionInfo sectionInfo; + Counts assertions; + double durationInSeconds; + bool missingAssertions; + }; + + struct TestCaseStats { + TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string const& _stdOut, + std::string const& _stdErr, + bool _aborting ); + + TestCaseStats( TestCaseStats const& ) = default; + TestCaseStats( TestCaseStats && ) = default; + TestCaseStats& operator = ( TestCaseStats const& ) = default; + TestCaseStats& operator = ( TestCaseStats && ) = default; + virtual ~TestCaseStats(); + + TestCaseInfo testInfo; + Totals totals; + std::string stdOut; + std::string stdErr; + bool aborting; + }; + + struct TestGroupStats { + TestGroupStats( GroupInfo const& _groupInfo, + Totals const& _totals, + bool _aborting ); + TestGroupStats( GroupInfo const& _groupInfo ); + + TestGroupStats( TestGroupStats const& ) = default; + TestGroupStats( TestGroupStats && ) = default; + TestGroupStats& operator = ( TestGroupStats const& ) = default; + TestGroupStats& operator = ( TestGroupStats && ) = default; + virtual ~TestGroupStats(); + + GroupInfo groupInfo; + Totals totals; + bool aborting; + }; + + struct TestRunStats { + TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ); + + TestRunStats( TestRunStats const& ) = default; + TestRunStats( TestRunStats && ) = default; + TestRunStats& operator = ( TestRunStats const& ) = default; + TestRunStats& operator = ( TestRunStats && ) = default; + virtual ~TestRunStats(); + + TestRunInfo runInfo; + Totals totals; + bool aborting; + }; + + struct BenchmarkInfo { + std::string name; + }; + struct BenchmarkStats { + BenchmarkInfo info; + std::size_t iterations; + uint64_t elapsedTimeInNanoseconds; + }; + + struct IStreamingReporter { + virtual ~IStreamingReporter() = default; + + // Implementing class must also provide the following static methods: + // static std::string getDescription(); + // static std::set getSupportedVerbosities() + + virtual ReporterPreferences getPreferences() const = 0; + + virtual void noMatchingTestCases( std::string const& spec ) = 0; + + virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; + virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; + + virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; + virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; + + // *** experimental *** + virtual void benchmarkStarting( BenchmarkInfo const& ) {} + + virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; + + // *** experimental *** + virtual void benchmarkEnded( BenchmarkStats const& ) {} + + virtual void sectionEnded( SectionStats const& sectionStats ) = 0; + virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; + virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; + virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; + + virtual void skipTest( TestCaseInfo const& testInfo ) = 0; + + // Default empty implementation provided + virtual void fatalErrorEncountered( StringRef name ); + + virtual bool isMulti() const; + }; + using IStreamingReporterPtr = std::unique_ptr; + + struct IReporterFactory { + virtual ~IReporterFactory(); + virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0; + virtual std::string getDescription() const = 0; + }; + using IReporterFactoryPtr = std::shared_ptr; + + struct IReporterRegistry { + using FactoryMap = std::map; + using Listeners = std::vector; + + virtual ~IReporterRegistry(); + virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0; + virtual FactoryMap const& getFactories() const = 0; + virtual Listeners const& getListeners() const = 0; + }; + +} // end namespace Catch + +// end catch_interfaces_reporter.h +#include +#include +#include +#include +#include +#include +#include + +namespace Catch { + void prepareExpandedExpression(AssertionResult& result); + + // Returns double formatted as %.3f (format expected on output) + std::string getFormattedDuration( double duration ); + + template + struct StreamingReporterBase : IStreamingReporter { + + StreamingReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) ) + throw std::domain_error( "Verbosity level not supported by this reporter" ); + } + + ReporterPreferences getPreferences() const override { + return m_reporterPrefs; + } + + static std::set getSupportedVerbosities() { + return { Verbosity::Normal }; + } + + ~StreamingReporterBase() override = default; + + void noMatchingTestCases(std::string const&) override {} + + void testRunStarting(TestRunInfo const& _testRunInfo) override { + currentTestRunInfo = _testRunInfo; + } + void testGroupStarting(GroupInfo const& _groupInfo) override { + currentGroupInfo = _groupInfo; + } + + void testCaseStarting(TestCaseInfo const& _testInfo) override { + currentTestCaseInfo = _testInfo; + } + void sectionStarting(SectionInfo const& _sectionInfo) override { + m_sectionStack.push_back(_sectionInfo); + } + + void sectionEnded(SectionStats const& /* _sectionStats */) override { + m_sectionStack.pop_back(); + } + void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override { + currentTestCaseInfo.reset(); + } + void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override { + currentGroupInfo.reset(); + } + void testRunEnded(TestRunStats const& /* _testRunStats */) override { + currentTestCaseInfo.reset(); + currentGroupInfo.reset(); + currentTestRunInfo.reset(); + } + + void skipTest(TestCaseInfo const&) override { + // Don't do anything with this by default. + // It can optionally be overridden in the derived class. + } + + IConfigPtr m_config; + std::ostream& stream; + + LazyStat currentTestRunInfo; + LazyStat currentGroupInfo; + LazyStat currentTestCaseInfo; + + std::vector m_sectionStack; + ReporterPreferences m_reporterPrefs; + }; + + template + struct CumulativeReporterBase : IStreamingReporter { + template + struct Node { + explicit Node( T const& _value ) : value( _value ) {} + virtual ~Node() {} + + using ChildNodes = std::vector>; + T value; + ChildNodes children; + }; + struct SectionNode { + explicit SectionNode(SectionStats const& _stats) : stats(_stats) {} + virtual ~SectionNode() = default; + + bool operator == (SectionNode const& other) const { + return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; + } + bool operator == (std::shared_ptr const& other) const { + return operator==(*other); + } + + SectionStats stats; + using ChildSections = std::vector>; + using Assertions = std::vector; + ChildSections childSections; + Assertions assertions; + std::string stdOut; + std::string stdErr; + }; + + struct BySectionInfo { + BySectionInfo( SectionInfo const& other ) : m_other( other ) {} + BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} + bool operator() (std::shared_ptr const& node) const { + return ((node->stats.sectionInfo.name == m_other.name) && + (node->stats.sectionInfo.lineInfo == m_other.lineInfo)); + } + void operator=(BySectionInfo const&) = delete; + + private: + SectionInfo const& m_other; + }; + + using TestCaseNode = Node; + using TestGroupNode = Node; + using TestRunNode = Node; + + CumulativeReporterBase( ReporterConfig const& _config ) + : m_config( _config.fullConfig() ), + stream( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = false; + if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) ) + throw std::domain_error( "Verbosity level not supported by this reporter" ); + } + ~CumulativeReporterBase() override = default; + + ReporterPreferences getPreferences() const override { + return m_reporterPrefs; + } + + static std::set getSupportedVerbosities() { + return { Verbosity::Normal }; + } + + void testRunStarting( TestRunInfo const& ) override {} + void testGroupStarting( GroupInfo const& ) override {} + + void testCaseStarting( TestCaseInfo const& ) override {} + + void sectionStarting( SectionInfo const& sectionInfo ) override { + SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); + std::shared_ptr node; + if( m_sectionStack.empty() ) { + if( !m_rootSection ) + m_rootSection = std::make_shared( incompleteStats ); + node = m_rootSection; + } + else { + SectionNode& parentNode = *m_sectionStack.back(); + auto it = + std::find_if( parentNode.childSections.begin(), + parentNode.childSections.end(), + BySectionInfo( sectionInfo ) ); + if( it == parentNode.childSections.end() ) { + node = std::make_shared( incompleteStats ); + parentNode.childSections.push_back( node ); + } + else + node = *it; + } + m_sectionStack.push_back( node ); + m_deepestSection = std::move(node); + } + + void assertionStarting(AssertionInfo const&) override {} + + bool assertionEnded(AssertionStats const& assertionStats) override { + assert(!m_sectionStack.empty()); + // AssertionResult holds a pointer to a temporary DecomposedExpression, + // which getExpandedExpression() calls to build the expression string. + // Our section stack copy of the assertionResult will likely outlive the + // temporary, so it must be expanded or discarded now to avoid calling + // a destroyed object later. + prepareExpandedExpression(const_cast( assertionStats.assertionResult ) ); + SectionNode& sectionNode = *m_sectionStack.back(); + sectionNode.assertions.push_back(assertionStats); + return true; + } + void sectionEnded(SectionStats const& sectionStats) override { + assert(!m_sectionStack.empty()); + SectionNode& node = *m_sectionStack.back(); + node.stats = sectionStats; + m_sectionStack.pop_back(); + } + void testCaseEnded(TestCaseStats const& testCaseStats) override { + auto node = std::make_shared(testCaseStats); + assert(m_sectionStack.size() == 0); + node->children.push_back(m_rootSection); + m_testCases.push_back(node); + m_rootSection.reset(); + + assert(m_deepestSection); + m_deepestSection->stdOut = testCaseStats.stdOut; + m_deepestSection->stdErr = testCaseStats.stdErr; + } + void testGroupEnded(TestGroupStats const& testGroupStats) override { + auto node = std::make_shared(testGroupStats); + node->children.swap(m_testCases); + m_testGroups.push_back(node); + } + void testRunEnded(TestRunStats const& testRunStats) override { + auto node = std::make_shared(testRunStats); + node->children.swap(m_testGroups); + m_testRuns.push_back(node); + testRunEndedCumulative(); + } + virtual void testRunEndedCumulative() = 0; + + void skipTest(TestCaseInfo const&) override {} + + IConfigPtr m_config; + std::ostream& stream; + std::vector m_assertions; + std::vector>> m_sections; + std::vector> m_testCases; + std::vector> m_testGroups; + + std::vector> m_testRuns; + + std::shared_ptr m_rootSection; + std::shared_ptr m_deepestSection; + std::vector> m_sectionStack; + ReporterPreferences m_reporterPrefs; + }; + + template + char const* getLineOfChars() { + static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; + if( !*line ) { + std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); + line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; + } + return line; + } + + struct TestEventListenerBase : StreamingReporterBase { + TestEventListenerBase( ReporterConfig const& _config ); + + void assertionStarting(AssertionInfo const&) override; + bool assertionEnded(AssertionStats const&) override; + }; + +} // end namespace Catch + +// end catch_reporter_bases.hpp +// start catch_console_colour.h + +namespace Catch { + + struct Colour { + enum Code { + None = 0, + + White, + Red, + Green, + Blue, + Cyan, + Yellow, + Grey, + + Bright = 0x10, + + BrightRed = Bright | Red, + BrightGreen = Bright | Green, + LightGrey = Bright | Grey, + BrightWhite = Bright | White, + BrightYellow = Bright | Yellow, + + // By intention + FileName = LightGrey, + Warning = BrightYellow, + ResultError = BrightRed, + ResultSuccess = BrightGreen, + ResultExpectedFailure = Warning, + + Error = BrightRed, + Success = Green, + + OriginalExpression = Cyan, + ReconstructedExpression = BrightYellow, + + SecondaryText = LightGrey, + Headers = White + }; + + // Use constructed object for RAII guard + Colour( Code _colourCode ); + Colour( Colour&& other ) noexcept; + Colour& operator=( Colour&& other ) noexcept; + ~Colour(); + + // Use static method for one-shot changes + static void use( Code _colourCode ); + + private: + bool m_moved = false; + }; + + std::ostream& operator << ( std::ostream& os, Colour const& ); + +} // end namespace Catch + +// end catch_console_colour.h +// start catch_reporter_registrars.hpp + + +namespace Catch { + + template + class ReporterRegistrar { + + class ReporterFactory : public IReporterFactory { + + virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override { + return std::unique_ptr( new T( config ) ); + } + + virtual std::string getDescription() const override { + return T::getDescription(); + } + }; + + public: + + explicit ReporterRegistrar( std::string const& name ) { + getMutableRegistryHub().registerReporter( name, std::make_shared() ); + } + }; + + template + class ListenerRegistrar { + + class ListenerFactory : public IReporterFactory { + + virtual IStreamingReporterPtr create( ReporterConfig const& config ) const override { + return std::unique_ptr( new T( config ) ); + } + virtual std::string getDescription() const override { + return std::string(); + } + }; + + public: + + ListenerRegistrar() { + getMutableRegistryHub().registerListener( std::make_shared() ); + } + }; +} + +#if !defined(CATCH_CONFIG_DISABLE) + +#define CATCH_REGISTER_REPORTER( name, reporterType ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + +#define CATCH_REGISTER_LISTENER( listenerType ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#else // CATCH_CONFIG_DISABLE + +#define CATCH_REGISTER_REPORTER(name, reporterType) +#define CATCH_REGISTER_LISTENER(listenerType) + +#endif // CATCH_CONFIG_DISABLE + +// end catch_reporter_registrars.hpp +// Allow users to base their work off existing reporters +// start catch_reporter_compact.h + +namespace Catch { + + struct CompactReporter : StreamingReporterBase { + + using StreamingReporterBase::StreamingReporterBase; + + ~CompactReporter() override; + + static std::string getDescription(); + + ReporterPreferences getPreferences() const override; + + void noMatchingTestCases(std::string const& spec) override; + + void assertionStarting(AssertionInfo const&) override; + + bool assertionEnded(AssertionStats const& _assertionStats) override; + + void sectionEnded(SectionStats const& _sectionStats) override; + + void testRunEnded(TestRunStats const& _testRunStats) override; + + }; + +} // end namespace Catch + +// end catch_reporter_compact.h +// start catch_reporter_console.h + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch + // Note that 4062 (not all labels are handled + // and default is missing) is enabled +#endif + +namespace Catch { + // Fwd decls + struct SummaryColumn; + class TablePrinter; + + struct ConsoleReporter : StreamingReporterBase { + std::unique_ptr m_tablePrinter; + + ConsoleReporter(ReporterConfig const& config); + ~ConsoleReporter() override; + static std::string getDescription(); + + void noMatchingTestCases(std::string const& spec) override; + + void assertionStarting(AssertionInfo const&) override; + + bool assertionEnded(AssertionStats const& _assertionStats) override; + + void sectionStarting(SectionInfo const& _sectionInfo) override; + void sectionEnded(SectionStats const& _sectionStats) override; + + void benchmarkStarting(BenchmarkInfo const& info) override; + void benchmarkEnded(BenchmarkStats const& stats) override; + + void testCaseEnded(TestCaseStats const& _testCaseStats) override; + void testGroupEnded(TestGroupStats const& _testGroupStats) override; + void testRunEnded(TestRunStats const& _testRunStats) override; + + private: + + void lazyPrint(); + + void lazyPrintWithoutClosingBenchmarkTable(); + void lazyPrintRunInfo(); + void lazyPrintGroupInfo(); + void printTestCaseAndSectionHeader(); + + void printClosedHeader(std::string const& _name); + void printOpenHeader(std::string const& _name); + + // if string has a : in first line will set indent to follow it on + // subsequent lines + void printHeaderString(std::string const& _string, std::size_t indent = 0); + + void printTotals(Totals const& totals); + void printSummaryRow(std::string const& label, std::vector const& cols, std::size_t row); + + void printTotalsDivider(Totals const& totals); + void printSummaryDivider(); + + private: + bool m_headerPrinted = false; + }; + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +// end catch_reporter_console.h +// start catch_reporter_junit.h + +// start catch_xmlwriter.h + +#include + +namespace Catch { + + class XmlEncode { + public: + enum ForWhat { ForTextNodes, ForAttributes }; + + XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ); + + void encodeTo( std::ostream& os ) const; + + friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ); + + private: + std::string m_str; + ForWhat m_forWhat; + }; + + class XmlWriter { + public: + + class ScopedElement { + public: + ScopedElement( XmlWriter* writer ); + + ScopedElement( ScopedElement&& other ) noexcept; + ScopedElement& operator=( ScopedElement&& other ) noexcept; + + ~ScopedElement(); + + ScopedElement& writeText( std::string const& text, bool indent = true ); + + template + ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { + m_writer->writeAttribute( name, attribute ); + return *this; + } + + private: + mutable XmlWriter* m_writer = nullptr; + }; + + XmlWriter( std::ostream& os = Catch::cout() ); + ~XmlWriter(); + + XmlWriter( XmlWriter const& ) = delete; + XmlWriter& operator=( XmlWriter const& ) = delete; + + XmlWriter& startElement( std::string const& name ); + + ScopedElement scopedElement( std::string const& name ); + + XmlWriter& endElement(); + + XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ); + + XmlWriter& writeAttribute( std::string const& name, bool attribute ); + + template + XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { + ReusableStringStream rss; + rss << attribute; + return writeAttribute( name, rss.str() ); + } + + XmlWriter& writeText( std::string const& text, bool indent = true ); + + XmlWriter& writeComment( std::string const& text ); + + void writeStylesheetRef( std::string const& url ); + + XmlWriter& writeBlankLine(); + + void ensureTagClosed(); + + private: + + void writeDeclaration(); + + void newlineIfNecessary(); + + bool m_tagIsOpen = false; + bool m_needsNewline = false; + std::vector m_tags; + std::string m_indent; + std::ostream& m_os; + }; + +} + +// end catch_xmlwriter.h +namespace Catch { + + class JunitReporter : public CumulativeReporterBase { + public: + JunitReporter(ReporterConfig const& _config); + + ~JunitReporter() override; + + static std::string getDescription(); + + void noMatchingTestCases(std::string const& /*spec*/) override; + + void testRunStarting(TestRunInfo const& runInfo) override; + + void testGroupStarting(GroupInfo const& groupInfo) override; + + void testCaseStarting(TestCaseInfo const& testCaseInfo) override; + bool assertionEnded(AssertionStats const& assertionStats) override; + + void testCaseEnded(TestCaseStats const& testCaseStats) override; + + void testGroupEnded(TestGroupStats const& testGroupStats) override; + + void testRunEndedCumulative() override; + + void writeGroup(TestGroupNode const& groupNode, double suiteTime); + + void writeTestCase(TestCaseNode const& testCaseNode); + + void writeSection(std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode); + + void writeAssertions(SectionNode const& sectionNode); + void writeAssertion(AssertionStats const& stats); + + XmlWriter xml; + Timer suiteTimer; + std::string stdOutForSuite; + std::string stdErrForSuite; + unsigned int unexpectedExceptions = 0; + bool m_okToFail = false; + }; + +} // end namespace Catch + +// end catch_reporter_junit.h +// start catch_reporter_xml.h + +namespace Catch { + class XmlReporter : public StreamingReporterBase { + public: + XmlReporter(ReporterConfig const& _config); + + ~XmlReporter() override; + + static std::string getDescription(); + + virtual std::string getStylesheetRef() const; + + void writeSourceInfo(SourceLineInfo const& sourceInfo); + + public: // StreamingReporterBase + + void noMatchingTestCases(std::string const& s) override; + + void testRunStarting(TestRunInfo const& testInfo) override; + + void testGroupStarting(GroupInfo const& groupInfo) override; + + void testCaseStarting(TestCaseInfo const& testInfo) override; + + void sectionStarting(SectionInfo const& sectionInfo) override; + + void assertionStarting(AssertionInfo const&) override; + + bool assertionEnded(AssertionStats const& assertionStats) override; + + void sectionEnded(SectionStats const& sectionStats) override; + + void testCaseEnded(TestCaseStats const& testCaseStats) override; + + void testGroupEnded(TestGroupStats const& testGroupStats) override; + + void testRunEnded(TestRunStats const& testRunStats) override; + + private: + Timer m_testCaseTimer; + XmlWriter m_xml; + int m_sectionDepth = 0; + }; + +} // end namespace Catch + +// end catch_reporter_xml.h + +// end catch_external_interfaces.h +#endif + +#endif // ! CATCH_CONFIG_IMPL_ONLY + +#ifdef CATCH_IMPL +// start catch_impl.hpp + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#endif + +// Keep these here for external reporters +// start catch_test_case_tracker.h + +#include +#include +#include + +namespace Catch { +namespace TestCaseTracking { + + struct NameAndLocation { + std::string name; + SourceLineInfo location; + + NameAndLocation( std::string const& _name, SourceLineInfo const& _location ); + }; + + struct ITracker; + + using ITrackerPtr = std::shared_ptr; + + struct ITracker { + virtual ~ITracker(); + + // static queries + virtual NameAndLocation const& nameAndLocation() const = 0; + + // dynamic queries + virtual bool isComplete() const = 0; // Successfully completed or failed + virtual bool isSuccessfullyCompleted() const = 0; + virtual bool isOpen() const = 0; // Started but not complete + virtual bool hasChildren() const = 0; + + virtual ITracker& parent() = 0; + + // actions + virtual void close() = 0; // Successfully complete + virtual void fail() = 0; + virtual void markAsNeedingAnotherRun() = 0; + + virtual void addChild( ITrackerPtr const& child ) = 0; + virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0; + virtual void openChild() = 0; + + // Debug/ checking + virtual bool isSectionTracker() const = 0; + virtual bool isIndexTracker() const = 0; + }; + + class TrackerContext { + + enum RunState { + NotStarted, + Executing, + CompletedCycle + }; + + ITrackerPtr m_rootTracker; + ITracker* m_currentTracker = nullptr; + RunState m_runState = NotStarted; + + public: + + static TrackerContext& instance(); + + ITracker& startRun(); + void endRun(); + + void startCycle(); + void completeCycle(); + + bool completedCycle() const; + ITracker& currentTracker(); + void setCurrentTracker( ITracker* tracker ); + }; + + class TrackerBase : public ITracker { + protected: + enum CycleState { + NotStarted, + Executing, + ExecutingChildren, + NeedsAnotherRun, + CompletedSuccessfully, + Failed + }; + + class TrackerHasName { + NameAndLocation m_nameAndLocation; + public: + TrackerHasName( NameAndLocation const& nameAndLocation ); + bool operator ()( ITrackerPtr const& tracker ) const; + }; + + using Children = std::vector; + NameAndLocation m_nameAndLocation; + TrackerContext& m_ctx; + ITracker* m_parent; + Children m_children; + CycleState m_runState = NotStarted; + + public: + TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); + + NameAndLocation const& nameAndLocation() const override; + bool isComplete() const override; + bool isSuccessfullyCompleted() const override; + bool isOpen() const override; + bool hasChildren() const override; + + void addChild( ITrackerPtr const& child ) override; + + ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override; + ITracker& parent() override; + + void openChild() override; + + bool isSectionTracker() const override; + bool isIndexTracker() const override; + + void open(); + + void close() override; + void fail() override; + void markAsNeedingAnotherRun() override; + + private: + void moveToParent(); + void moveToThis(); + }; + + class SectionTracker : public TrackerBase { + std::vector m_filters; + public: + SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ); + + bool isSectionTracker() const override; + + static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ); + + void tryOpen(); + + void addInitialFilters( std::vector const& filters ); + void addNextFilters( std::vector const& filters ); + }; + + class IndexTracker : public TrackerBase { + int m_size; + int m_index = -1; + public: + IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ); + + bool isIndexTracker() const override; + void close() override; + + static IndexTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ); + + int index() const; + + void moveNext(); + }; + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +} // namespace Catch + +// end catch_test_case_tracker.h + +// start catch_leak_detector.h + +namespace Catch { + + struct LeakDetector { + LeakDetector(); + }; + +} +// end catch_leak_detector.h +// Cpp files will be included in the single-header file here +// start catch_approx.cpp + +#include +#include + +namespace { + +// Performs equivalent check of std::fabs(lhs - rhs) <= margin +// But without the subtraction to allow for INFINITY in comparison +bool marginComparison(double lhs, double rhs, double margin) { + return (lhs + margin >= rhs) && (rhs + margin >= lhs); +} + +} + +namespace Catch { +namespace Detail { + + Approx::Approx ( double value ) + : m_epsilon( std::numeric_limits::epsilon()*100 ), + m_margin( 0.0 ), + m_scale( 0.0 ), + m_value( value ) + {} + + Approx Approx::custom() { + return Approx( 0 ); + } + + std::string Approx::toString() const { + ReusableStringStream rss; + rss << "Approx( " << ::Catch::Detail::stringify( m_value ) << " )"; + return rss.str(); + } + + bool Approx::equalityComparisonImpl(const double other) const { + // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value + // Thanks to Richard Harris for his help refining the scaled margin value + return marginComparison(m_value, other, m_margin) || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value))); + } + +} // end namespace Detail + +std::string StringMaker::convert(Catch::Detail::Approx const& value) { + return value.toString(); +} + +} // end namespace Catch +// end catch_approx.cpp +// start catch_assertionhandler.cpp + +// start catch_context.h + +#include + +namespace Catch { + + struct IResultCapture; + struct IRunner; + struct IConfig; + struct IMutableContext; + + using IConfigPtr = std::shared_ptr; + + struct IContext + { + virtual ~IContext(); + + virtual IResultCapture* getResultCapture() = 0; + virtual IRunner* getRunner() = 0; + virtual IConfigPtr const& getConfig() const = 0; + }; + + struct IMutableContext : IContext + { + virtual ~IMutableContext(); + virtual void setResultCapture( IResultCapture* resultCapture ) = 0; + virtual void setRunner( IRunner* runner ) = 0; + virtual void setConfig( IConfigPtr const& config ) = 0; + + private: + static IMutableContext *currentContext; + friend IMutableContext& getCurrentMutableContext(); + friend void cleanUpContext(); + static void createContext(); + }; + + inline IMutableContext& getCurrentMutableContext() + { + if( !IMutableContext::currentContext ) + IMutableContext::createContext(); + return *IMutableContext::currentContext; + } + + inline IContext& getCurrentContext() + { + return getCurrentMutableContext(); + } + + void cleanUpContext(); +} + +// end catch_context.h +// start catch_debugger.h + +namespace Catch { + bool isDebuggerActive(); +} + +#ifdef CATCH_PLATFORM_MAC + + #define CATCH_TRAP() __asm__("int $3\n" : : ) /* NOLINT */ + +#elif defined(CATCH_PLATFORM_LINUX) + // If we can use inline assembler, do it because this allows us to break + // directly at the location of the failing check instead of breaking inside + // raise() called from it, i.e. one stack frame below. + #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) + #define CATCH_TRAP() asm volatile ("int $3") /* NOLINT */ + #else // Fall back to the generic way. + #include + + #define CATCH_TRAP() raise(SIGTRAP) + #endif +#elif defined(_MSC_VER) + #define CATCH_TRAP() __debugbreak() +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) void __stdcall DebugBreak(); + #define CATCH_TRAP() DebugBreak() +#endif + +#ifdef CATCH_TRAP + #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } +#else + namespace Catch { + inline void doNothing() {} + } + #define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing() +#endif + +// end catch_debugger.h +// start catch_run_context.h + +// start catch_fatal_condition.h + +// start catch_windows_h_proxy.h + + +#if defined(CATCH_PLATFORM_WINDOWS) + +#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) +# define CATCH_DEFINED_NOMINMAX +# define NOMINMAX +#endif +#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) +# define CATCH_DEFINED_WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif + +#ifdef __AFXDLL +#include +#else +#include +#endif + +#ifdef CATCH_DEFINED_NOMINMAX +# undef NOMINMAX +#endif +#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN +# undef WIN32_LEAN_AND_MEAN +#endif + +#endif // defined(CATCH_PLATFORM_WINDOWS) + +// end catch_windows_h_proxy.h +#if defined( CATCH_CONFIG_WINDOWS_SEH ) + +namespace Catch { + + struct FatalConditionHandler { + + static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo); + FatalConditionHandler(); + static void reset(); + ~FatalConditionHandler(); + + private: + static bool isSet; + static ULONG guaranteeSize; + static PVOID exceptionHandlerHandle; + }; + +} // namespace Catch + +#elif defined ( CATCH_CONFIG_POSIX_SIGNALS ) + +#include + +namespace Catch { + + struct FatalConditionHandler { + + static bool isSet; + static struct sigaction oldSigActions[]; + static stack_t oldSigStack; + static char altStackMem[]; + + static void handleSignal( int sig ); + + FatalConditionHandler(); + ~FatalConditionHandler(); + static void reset(); + }; + +} // namespace Catch + +#else + +namespace Catch { + struct FatalConditionHandler { + void reset(); + }; +} + +#endif + +// end catch_fatal_condition.h +#include + +namespace Catch { + + struct IMutableContext; + + /////////////////////////////////////////////////////////////////////////// + + class RunContext : public IResultCapture, public IRunner { + + public: + RunContext( RunContext const& ) = delete; + RunContext& operator =( RunContext const& ) = delete; + + explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter ); + + ~RunContext() override; + + void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ); + void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ); + + Totals runTest(TestCase const& testCase); + + IConfigPtr config() const; + IStreamingReporter& reporter() const; + + public: // IResultCapture + + // Assertion handlers + void handleExpr + ( AssertionInfo const& info, + ITransientExpression const& expr, + AssertionReaction& reaction ) override; + void handleMessage + ( AssertionInfo const& info, + ResultWas::OfType resultType, + StringRef const& message, + AssertionReaction& reaction ) override; + void handleUnexpectedExceptionNotThrown + ( AssertionInfo const& info, + AssertionReaction& reaction ) override; + void handleUnexpectedInflightException + ( AssertionInfo const& info, + std::string const& message, + AssertionReaction& reaction ) override; + void handleIncomplete + ( AssertionInfo const& info ) override; + void handleNonExpr + ( AssertionInfo const &info, + ResultWas::OfType resultType, + AssertionReaction &reaction ) override; + + bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override; + + void sectionEnded( SectionEndInfo const& endInfo ) override; + void sectionEndedEarly( SectionEndInfo const& endInfo ) override; + + void benchmarkStarting( BenchmarkInfo const& info ) override; + void benchmarkEnded( BenchmarkStats const& stats ) override; + + void pushScopedMessage( MessageInfo const& message ) override; + void popScopedMessage( MessageInfo const& message ) override; + + std::string getCurrentTestName() const override; + + const AssertionResult* getLastResult() const override; + + void exceptionEarlyReported() override; + + void handleFatalErrorCondition( StringRef message ) override; + + bool lastAssertionPassed() override; + + void assertionPassed() override; + + public: + // !TBD We need to do this another way! + bool aborting() const final; + + private: + + void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ); + void invokeActiveTestCase(); + + void resetAssertionInfo(); + bool testForMissingAssertions( Counts& assertions ); + + void assertionEnded( AssertionResult const& result ); + void reportExpr + ( AssertionInfo const &info, + ResultWas::OfType resultType, + ITransientExpression const *expr, + bool negated ); + + void populateReaction( AssertionReaction& reaction ); + + private: + + void handleUnfinishedSections(); + + TestRunInfo m_runInfo; + IMutableContext& m_context; + TestCase const* m_activeTestCase = nullptr; + ITracker* m_testCaseTracker; + Option m_lastResult; + + IConfigPtr m_config; + Totals m_totals; + IStreamingReporterPtr m_reporter; + std::vector m_messages; + AssertionInfo m_lastAssertionInfo; + std::vector m_unfinishedSections; + std::vector m_activeSections; + TrackerContext m_trackerContext; + bool m_lastAssertionPassed = false; + bool m_shouldReportUnexpected = true; + bool m_includeSuccessfulResults; + }; + +} // end namespace Catch + +// end catch_run_context.h +namespace Catch { + + auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& { + expr.streamReconstructedExpression( os ); + return os; + } + + LazyExpression::LazyExpression( bool isNegated ) + : m_isNegated( isNegated ) + {} + + LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {} + + LazyExpression::operator bool() const { + return m_transientExpression != nullptr; + } + + auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& { + if( lazyExpr.m_isNegated ) + os << "!"; + + if( lazyExpr ) { + if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() ) + os << "(" << *lazyExpr.m_transientExpression << ")"; + else + os << *lazyExpr.m_transientExpression; + } + else { + os << "{** error - unchecked empty expression requested **}"; + } + return os; + } + + AssertionHandler::AssertionHandler + ( StringRef macroName, + SourceLineInfo const& lineInfo, + StringRef capturedExpression, + ResultDisposition::Flags resultDisposition ) + : m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition }, + m_resultCapture( getResultCapture() ) + {} + + void AssertionHandler::handleExpr( ITransientExpression const& expr ) { + m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction ); + } + void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) { + m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction ); + } + + auto AssertionHandler::allowThrows() const -> bool { + return getCurrentContext().getConfig()->allowThrows(); + } + + void AssertionHandler::complete() { + setCompleted(); + if( m_reaction.shouldDebugBreak ) { + + // If you find your debugger stopping you here then go one level up on the + // call-stack for the code that caused it (typically a failed assertion) + + // (To go back to the test and change execution, jump over the throw, next) + CATCH_BREAK_INTO_DEBUGGER(); + } + if( m_reaction.shouldThrow ) + throw Catch::TestFailureException(); + } + void AssertionHandler::setCompleted() { + m_completed = true; + } + + void AssertionHandler::handleUnexpectedInflightException() { + m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction ); + } + + void AssertionHandler::handleExceptionThrownAsExpected() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); + } + void AssertionHandler::handleExceptionNotThrownAsExpected() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); + } + + void AssertionHandler::handleUnexpectedExceptionNotThrown() { + m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction ); + } + + void AssertionHandler::handleThrowingCallSkipped() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); + } + + // This is the overload that takes a string and infers the Equals matcher from it + // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp + void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef matcherString ) { + handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString ); + } + +} // namespace Catch +// end catch_assertionhandler.cpp +// start catch_assertionresult.cpp + +namespace Catch { + AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression): + lazyExpression(_lazyExpression), + resultType(_resultType) {} + + std::string AssertionResultData::reconstructExpression() const { + + if( reconstructedExpression.empty() ) { + if( lazyExpression ) { + ReusableStringStream rss; + rss << lazyExpression; + reconstructedExpression = rss.str(); + } + } + return reconstructedExpression; + } + + AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) + : m_info( info ), + m_resultData( data ) + {} + + // Result was a success + bool AssertionResult::succeeded() const { + return Catch::isOk( m_resultData.resultType ); + } + + // Result was a success, or failure is suppressed + bool AssertionResult::isOk() const { + return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); + } + + ResultWas::OfType AssertionResult::getResultType() const { + return m_resultData.resultType; + } + + bool AssertionResult::hasExpression() const { + return m_info.capturedExpression[0] != 0; + } + + bool AssertionResult::hasMessage() const { + return !m_resultData.message.empty(); + } + + std::string AssertionResult::getExpression() const { + if( isFalseTest( m_info.resultDisposition ) ) + return "!(" + m_info.capturedExpression + ")"; + else + return m_info.capturedExpression; + } + + std::string AssertionResult::getExpressionInMacro() const { + std::string expr; + if( m_info.macroName[0] == 0 ) + expr = m_info.capturedExpression; + else { + expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 ); + expr += m_info.macroName; + expr += "( "; + expr += m_info.capturedExpression; + expr += " )"; + } + return expr; + } + + bool AssertionResult::hasExpandedExpression() const { + return hasExpression() && getExpandedExpression() != getExpression(); + } + + std::string AssertionResult::getExpandedExpression() const { + std::string expr = m_resultData.reconstructExpression(); + return expr.empty() + ? getExpression() + : expr; + } + + std::string AssertionResult::getMessage() const { + return m_resultData.message; + } + SourceLineInfo AssertionResult::getSourceInfo() const { + return m_info.lineInfo; + } + + StringRef AssertionResult::getTestMacroName() const { + return m_info.macroName; + } + +} // end namespace Catch +// end catch_assertionresult.cpp +// start catch_benchmark.cpp + +namespace Catch { + + auto BenchmarkLooper::getResolution() -> uint64_t { + return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple(); + } + + void BenchmarkLooper::reportStart() { + getResultCapture().benchmarkStarting( { m_name } ); + } + auto BenchmarkLooper::needsMoreIterations() -> bool { + auto elapsed = m_timer.getElapsedNanoseconds(); + + // Exponentially increasing iterations until we're confident in our timer resolution + if( elapsed < m_resolution ) { + m_iterationsToRun *= 10; + return true; + } + + getResultCapture().benchmarkEnded( { { m_name }, m_count, elapsed } ); + return false; + } + +} // end namespace Catch +// end catch_benchmark.cpp +// start catch_capture_matchers.cpp + +namespace Catch { + + using StringMatcher = Matchers::Impl::MatcherBase; + + // This is the general overload that takes a any string matcher + // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers + // the Equals matcher (so the header does not mention matchers) + void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef matcherString ) { + std::string exceptionMessage = Catch::translateActiveException(); + MatchExpr expr( exceptionMessage, matcher, matcherString ); + handler.handleExpr( expr ); + } + +} // namespace Catch +// end catch_capture_matchers.cpp +// start catch_commandline.cpp + +// start catch_commandline.h + +// start catch_clara.h + +// Use Catch's value for console width (store Clara's off to the side, if present) +#ifdef CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#endif +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1 + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#pragma clang diagnostic ignored "-Wshadow" +#endif + +// start clara.hpp +// Copyright 2017 Two Blue Cubes Ltd. All rights reserved. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See https://github.com/philsquared/Clara for more details + +// Clara v1.1.4 + + +#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80 +#endif + +#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +#ifndef CLARA_CONFIG_OPTIONAL_TYPE +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#include +#define CLARA_CONFIG_OPTIONAL_TYPE std::optional +#endif +#endif +#endif + +// ----------- #included from clara_textflow.hpp ----------- + +// TextFlowCpp +// +// A single-header library for wrapping and laying out basic text, by Phil Nash +// +// This work is licensed under the BSD 2-Clause license. +// See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause +// +// This project is hosted at https://github.com/philsquared/textflowcpp + + +#include +#include +#include +#include + +#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { namespace clara { namespace TextFlow { + + inline auto isWhitespace( char c ) -> bool { + static std::string chars = " \t\n\r"; + return chars.find( c ) != std::string::npos; + } + inline auto isBreakableBefore( char c ) -> bool { + static std::string chars = "[({<|"; + return chars.find( c ) != std::string::npos; + } + inline auto isBreakableAfter( char c ) -> bool { + static std::string chars = "])}>.,:;*+-=&/\\"; + return chars.find( c ) != std::string::npos; + } + + class Columns; + + class Column { + std::vector m_strings; + size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH; + size_t m_indent = 0; + size_t m_initialIndent = std::string::npos; + + public: + class iterator { + friend Column; + + Column const& m_column; + size_t m_stringIndex = 0; + size_t m_pos = 0; + + size_t m_len = 0; + size_t m_end = 0; + bool m_suffix = false; + + iterator( Column const& column, size_t stringIndex ) + : m_column( column ), + m_stringIndex( stringIndex ) + {} + + auto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; } + + auto isBoundary( size_t at ) const -> bool { + assert( at > 0 ); + assert( at <= line().size() ); + + return at == line().size() || + ( isWhitespace( line()[at] ) && !isWhitespace( line()[at-1] ) ) || + isBreakableBefore( line()[at] ) || + isBreakableAfter( line()[at-1] ); + } + + void calcLength() { + assert( m_stringIndex < m_column.m_strings.size() ); + + m_suffix = false; + auto width = m_column.m_width-indent(); + m_end = m_pos; + while( m_end < line().size() && line()[m_end] != '\n' ) + ++m_end; + + if( m_end < m_pos + width ) { + m_len = m_end - m_pos; + } + else { + size_t len = width; + while (len > 0 && !isBoundary(m_pos + len)) + --len; + while (len > 0 && isWhitespace( line()[m_pos + len - 1] )) + --len; + + if (len > 0) { + m_len = len; + } else { + m_suffix = true; + m_len = width - 1; + } + } + } + + auto indent() const -> size_t { + auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos; + return initial == std::string::npos ? m_column.m_indent : initial; + } + + auto addIndentAndSuffix(std::string const &plain) const -> std::string { + return std::string( indent(), ' ' ) + (m_suffix ? plain + "-" : plain); + } + + public: + explicit iterator( Column const& column ) : m_column( column ) { + assert( m_column.m_width > m_column.m_indent ); + assert( m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent ); + calcLength(); + if( m_len == 0 ) + m_stringIndex++; // Empty string + } + + auto operator *() const -> std::string { + assert( m_stringIndex < m_column.m_strings.size() ); + assert( m_pos <= m_end ); + if( m_pos + m_column.m_width < m_end ) + return addIndentAndSuffix(line().substr(m_pos, m_len)); + else + return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos)); + } + + auto operator ++() -> iterator& { + m_pos += m_len; + if( m_pos < line().size() && line()[m_pos] == '\n' ) + m_pos += 1; + else + while( m_pos < line().size() && isWhitespace( line()[m_pos] ) ) + ++m_pos; + + if( m_pos == line().size() ) { + m_pos = 0; + ++m_stringIndex; + } + if( m_stringIndex < m_column.m_strings.size() ) + calcLength(); + return *this; + } + auto operator ++(int) -> iterator { + iterator prev( *this ); + operator++(); + return prev; + } + + auto operator ==( iterator const& other ) const -> bool { + return + m_pos == other.m_pos && + m_stringIndex == other.m_stringIndex && + &m_column == &other.m_column; + } + auto operator !=( iterator const& other ) const -> bool { + return !operator==( other ); + } + }; + using const_iterator = iterator; + + explicit Column( std::string const& text ) { m_strings.push_back( text ); } + + auto width( size_t newWidth ) -> Column& { + assert( newWidth > 0 ); + m_width = newWidth; + return *this; + } + auto indent( size_t newIndent ) -> Column& { + m_indent = newIndent; + return *this; + } + auto initialIndent( size_t newIndent ) -> Column& { + m_initialIndent = newIndent; + return *this; + } + + auto width() const -> size_t { return m_width; } + auto begin() const -> iterator { return iterator( *this ); } + auto end() const -> iterator { return { *this, m_strings.size() }; } + + inline friend std::ostream& operator << ( std::ostream& os, Column const& col ) { + bool first = true; + for( auto line : col ) { + if( first ) + first = false; + else + os << "\n"; + os << line; + } + return os; + } + + auto operator + ( Column const& other ) -> Columns; + + auto toString() const -> std::string { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + }; + + class Spacer : public Column { + + public: + explicit Spacer( size_t spaceWidth ) : Column( "" ) { + width( spaceWidth ); + } + }; + + class Columns { + std::vector m_columns; + + public: + + class iterator { + friend Columns; + struct EndTag {}; + + std::vector const& m_columns; + std::vector m_iterators; + size_t m_activeIterators; + + iterator( Columns const& columns, EndTag ) + : m_columns( columns.m_columns ), + m_activeIterators( 0 ) + { + m_iterators.reserve( m_columns.size() ); + + for( auto const& col : m_columns ) + m_iterators.push_back( col.end() ); + } + + public: + explicit iterator( Columns const& columns ) + : m_columns( columns.m_columns ), + m_activeIterators( m_columns.size() ) + { + m_iterators.reserve( m_columns.size() ); + + for( auto const& col : m_columns ) + m_iterators.push_back( col.begin() ); + } + + auto operator ==( iterator const& other ) const -> bool { + return m_iterators == other.m_iterators; + } + auto operator !=( iterator const& other ) const -> bool { + return m_iterators != other.m_iterators; + } + auto operator *() const -> std::string { + std::string row, padding; + + for( size_t i = 0; i < m_columns.size(); ++i ) { + auto width = m_columns[i].width(); + if( m_iterators[i] != m_columns[i].end() ) { + std::string col = *m_iterators[i]; + row += padding + col; + if( col.size() < width ) + padding = std::string( width - col.size(), ' ' ); + else + padding = ""; + } + else { + padding += std::string( width, ' ' ); + } + } + return row; + } + auto operator ++() -> iterator& { + for( size_t i = 0; i < m_columns.size(); ++i ) { + if (m_iterators[i] != m_columns[i].end()) + ++m_iterators[i]; + } + return *this; + } + auto operator ++(int) -> iterator { + iterator prev( *this ); + operator++(); + return prev; + } + }; + using const_iterator = iterator; + + auto begin() const -> iterator { return iterator( *this ); } + auto end() const -> iterator { return { *this, iterator::EndTag() }; } + + auto operator += ( Column const& col ) -> Columns& { + m_columns.push_back( col ); + return *this; + } + auto operator + ( Column const& col ) -> Columns { + Columns combined = *this; + combined += col; + return combined; + } + + inline friend std::ostream& operator << ( std::ostream& os, Columns const& cols ) { + + bool first = true; + for( auto line : cols ) { + if( first ) + first = false; + else + os << "\n"; + os << line; + } + return os; + } + + auto toString() const -> std::string { + std::ostringstream oss; + oss << *this; + return oss.str(); + } + }; + + inline auto Column::operator + ( Column const& other ) -> Columns { + Columns cols; + cols += *this; + cols += other; + return cols; + } +}}} // namespace Catch::clara::TextFlow + +// ----------- end of #include from clara_textflow.hpp ----------- +// ........... back in clara.hpp + +#include +#include +#include + +#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) ) +#define CATCH_PLATFORM_WINDOWS +#endif + +namespace Catch { namespace clara { +namespace detail { + + // Traits for extracting arg and return type of lambdas (for single argument lambdas) + template + struct UnaryLambdaTraits : UnaryLambdaTraits {}; + + template + struct UnaryLambdaTraits { + static const bool isValid = false; + }; + + template + struct UnaryLambdaTraits { + static const bool isValid = true; + using ArgType = typename std::remove_const::type>::type; + using ReturnType = ReturnT; + }; + + class TokenStream; + + // Transport for raw args (copied from main args, or supplied via init list for testing) + class Args { + friend TokenStream; + std::string m_exeName; + std::vector m_args; + + public: + Args( int argc, char const* const* argv ) + : m_exeName(argv[0]), + m_args(argv + 1, argv + argc) {} + + Args( std::initializer_list args ) + : m_exeName( *args.begin() ), + m_args( args.begin()+1, args.end() ) + {} + + auto exeName() const -> std::string { + return m_exeName; + } + }; + + // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string + // may encode an option + its argument if the : or = form is used + enum class TokenType { + Option, Argument + }; + struct Token { + TokenType type; + std::string token; + }; + + inline auto isOptPrefix( char c ) -> bool { + return c == '-' +#ifdef CATCH_PLATFORM_WINDOWS + || c == '/' +#endif + ; + } + + // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled + class TokenStream { + using Iterator = std::vector::const_iterator; + Iterator it; + Iterator itEnd; + std::vector m_tokenBuffer; + + void loadBuffer() { + m_tokenBuffer.resize( 0 ); + + // Skip any empty strings + while( it != itEnd && it->empty() ) + ++it; + + if( it != itEnd ) { + auto const &next = *it; + if( isOptPrefix( next[0] ) ) { + auto delimiterPos = next.find_first_of( " :=" ); + if( delimiterPos != std::string::npos ) { + m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } ); + m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } ); + } else { + if( next[1] != '-' && next.size() > 2 ) { + std::string opt = "- "; + for( size_t i = 1; i < next.size(); ++i ) { + opt[1] = next[i]; + m_tokenBuffer.push_back( { TokenType::Option, opt } ); + } + } else { + m_tokenBuffer.push_back( { TokenType::Option, next } ); + } + } + } else { + m_tokenBuffer.push_back( { TokenType::Argument, next } ); + } + } + } + + public: + explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {} + + TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) { + loadBuffer(); + } + + explicit operator bool() const { + return !m_tokenBuffer.empty() || it != itEnd; + } + + auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); } + + auto operator*() const -> Token { + assert( !m_tokenBuffer.empty() ); + return m_tokenBuffer.front(); + } + + auto operator->() const -> Token const * { + assert( !m_tokenBuffer.empty() ); + return &m_tokenBuffer.front(); + } + + auto operator++() -> TokenStream & { + if( m_tokenBuffer.size() >= 2 ) { + m_tokenBuffer.erase( m_tokenBuffer.begin() ); + } else { + if( it != itEnd ) + ++it; + loadBuffer(); + } + return *this; + } + }; + + class ResultBase { + public: + enum Type { + Ok, LogicError, RuntimeError + }; + + protected: + ResultBase( Type type ) : m_type( type ) {} + virtual ~ResultBase() = default; + + virtual void enforceOk() const = 0; + + Type m_type; + }; + + template + class ResultValueBase : public ResultBase { + public: + auto value() const -> T const & { + enforceOk(); + return m_value; + } + + protected: + ResultValueBase( Type type ) : ResultBase( type ) {} + + ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) { + if( m_type == ResultBase::Ok ) + new( &m_value ) T( other.m_value ); + } + + ResultValueBase( Type, T const &value ) : ResultBase( Ok ) { + new( &m_value ) T( value ); + } + + auto operator=( ResultValueBase const &other ) -> ResultValueBase & { + if( m_type == ResultBase::Ok ) + m_value.~T(); + ResultBase::operator=(other); + if( m_type == ResultBase::Ok ) + new( &m_value ) T( other.m_value ); + return *this; + } + + ~ResultValueBase() override { + if( m_type == Ok ) + m_value.~T(); + } + + union { + T m_value; + }; + }; + + template<> + class ResultValueBase : public ResultBase { + protected: + using ResultBase::ResultBase; + }; + + template + class BasicResult : public ResultValueBase { + public: + template + explicit BasicResult( BasicResult const &other ) + : ResultValueBase( other.type() ), + m_errorMessage( other.errorMessage() ) + { + assert( type() != ResultBase::Ok ); + } + + template + static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; } + static auto ok() -> BasicResult { return { ResultBase::Ok }; } + static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; } + static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; } + + explicit operator bool() const { return m_type == ResultBase::Ok; } + auto type() const -> ResultBase::Type { return m_type; } + auto errorMessage() const -> std::string { return m_errorMessage; } + + protected: + void enforceOk() const override { + + // Errors shouldn't reach this point, but if they do + // the actual error message will be in m_errorMessage + assert( m_type != ResultBase::LogicError ); + assert( m_type != ResultBase::RuntimeError ); + if( m_type != ResultBase::Ok ) + std::abort(); + } + + std::string m_errorMessage; // Only populated if resultType is an error + + BasicResult( ResultBase::Type type, std::string const &message ) + : ResultValueBase(type), + m_errorMessage(message) + { + assert( m_type != ResultBase::Ok ); + } + + using ResultValueBase::ResultValueBase; + using ResultBase::m_type; + }; + + enum class ParseResultType { + Matched, NoMatch, ShortCircuitAll, ShortCircuitSame + }; + + class ParseState { + public: + + ParseState( ParseResultType type, TokenStream const &remainingTokens ) + : m_type(type), + m_remainingTokens( remainingTokens ) + {} + + auto type() const -> ParseResultType { return m_type; } + auto remainingTokens() const -> TokenStream { return m_remainingTokens; } + + private: + ParseResultType m_type; + TokenStream m_remainingTokens; + }; + + using Result = BasicResult; + using ParserResult = BasicResult; + using InternalParseResult = BasicResult; + + struct HelpColumns { + std::string left; + std::string right; + }; + + template + inline auto convertInto( std::string const &source, T& target ) -> ParserResult { + std::stringstream ss; + ss << source; + ss >> target; + if( ss.fail() ) + return ParserResult::runtimeError( "Unable to convert '" + source + "' to destination type" ); + else + return ParserResult::ok( ParseResultType::Matched ); + } + inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult { + target = source; + return ParserResult::ok( ParseResultType::Matched ); + } + inline auto convertInto( std::string const &source, bool &target ) -> ParserResult { + std::string srcLC = source; + std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( char c ) { return static_cast( ::tolower(c) ); } ); + if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") + target = true; + else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") + target = false; + else + return ParserResult::runtimeError( "Expected a boolean value but did not recognise: '" + source + "'" ); + return ParserResult::ok( ParseResultType::Matched ); + } +#ifdef CLARA_CONFIG_OPTIONAL_TYPE + template + inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE& target ) -> ParserResult { + T temp; + auto result = convertInto( source, temp ); + if( result ) + target = std::move(temp); + return result; + } +#endif // CLARA_CONFIG_OPTIONAL_TYPE + + struct NonCopyable { + NonCopyable() = default; + NonCopyable( NonCopyable const & ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable &operator=( NonCopyable const & ) = delete; + NonCopyable &operator=( NonCopyable && ) = delete; + }; + + struct BoundRef : NonCopyable { + virtual ~BoundRef() = default; + virtual auto isContainer() const -> bool { return false; } + virtual auto isFlag() const -> bool { return false; } + }; + struct BoundValueRefBase : BoundRef { + virtual auto setValue( std::string const &arg ) -> ParserResult = 0; + }; + struct BoundFlagRefBase : BoundRef { + virtual auto setFlag( bool flag ) -> ParserResult = 0; + virtual auto isFlag() const -> bool { return true; } + }; + + template + struct BoundValueRef : BoundValueRefBase { + T &m_ref; + + explicit BoundValueRef( T &ref ) : m_ref( ref ) {} + + auto setValue( std::string const &arg ) -> ParserResult override { + return convertInto( arg, m_ref ); + } + }; + + template + struct BoundValueRef> : BoundValueRefBase { + std::vector &m_ref; + + explicit BoundValueRef( std::vector &ref ) : m_ref( ref ) {} + + auto isContainer() const -> bool override { return true; } + + auto setValue( std::string const &arg ) -> ParserResult override { + T temp; + auto result = convertInto( arg, temp ); + if( result ) + m_ref.push_back( temp ); + return result; + } + }; + + struct BoundFlagRef : BoundFlagRefBase { + bool &m_ref; + + explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {} + + auto setFlag( bool flag ) -> ParserResult override { + m_ref = flag; + return ParserResult::ok( ParseResultType::Matched ); + } + }; + + template + struct LambdaInvoker { + static_assert( std::is_same::value, "Lambda must return void or clara::ParserResult" ); + + template + static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult { + return lambda( arg ); + } + }; + + template<> + struct LambdaInvoker { + template + static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult { + lambda( arg ); + return ParserResult::ok( ParseResultType::Matched ); + } + }; + + template + inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult { + ArgType temp{}; + auto result = convertInto( arg, temp ); + return !result + ? result + : LambdaInvoker::ReturnType>::invoke( lambda, temp ); + } + + template + struct BoundLambda : BoundValueRefBase { + L m_lambda; + + static_assert( UnaryLambdaTraits::isValid, "Supplied lambda must take exactly one argument" ); + explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {} + + auto setValue( std::string const &arg ) -> ParserResult override { + return invokeLambda::ArgType>( m_lambda, arg ); + } + }; + + template + struct BoundFlagLambda : BoundFlagRefBase { + L m_lambda; + + static_assert( UnaryLambdaTraits::isValid, "Supplied lambda must take exactly one argument" ); + static_assert( std::is_same::ArgType, bool>::value, "flags must be boolean" ); + + explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {} + + auto setFlag( bool flag ) -> ParserResult override { + return LambdaInvoker::ReturnType>::invoke( m_lambda, flag ); + } + }; + + enum class Optionality { Optional, Required }; + + struct Parser; + + class ParserBase { + public: + virtual ~ParserBase() = default; + virtual auto validate() const -> Result { return Result::ok(); } + virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult = 0; + virtual auto cardinality() const -> size_t { return 1; } + + auto parse( Args const &args ) const -> InternalParseResult { + return parse( args.exeName(), TokenStream( args ) ); + } + }; + + template + class ComposableParserImpl : public ParserBase { + public: + template + auto operator|( T const &other ) const -> Parser; + + template + auto operator+( T const &other ) const -> Parser; + }; + + // Common code and state for Args and Opts + template + class ParserRefImpl : public ComposableParserImpl { + protected: + Optionality m_optionality = Optionality::Optional; + std::shared_ptr m_ref; + std::string m_hint; + std::string m_description; + + explicit ParserRefImpl( std::shared_ptr const &ref ) : m_ref( ref ) {} + + public: + template + ParserRefImpl( T &ref, std::string const &hint ) + : m_ref( std::make_shared>( ref ) ), + m_hint( hint ) + {} + + template + ParserRefImpl( LambdaT const &ref, std::string const &hint ) + : m_ref( std::make_shared>( ref ) ), + m_hint(hint) + {} + + auto operator()( std::string const &description ) -> DerivedT & { + m_description = description; + return static_cast( *this ); + } + + auto optional() -> DerivedT & { + m_optionality = Optionality::Optional; + return static_cast( *this ); + }; + + auto required() -> DerivedT & { + m_optionality = Optionality::Required; + return static_cast( *this ); + }; + + auto isOptional() const -> bool { + return m_optionality == Optionality::Optional; + } + + auto cardinality() const -> size_t override { + if( m_ref->isContainer() ) + return 0; + else + return 1; + } + + auto hint() const -> std::string { return m_hint; } + }; + + class ExeName : public ComposableParserImpl { + std::shared_ptr m_name; + std::shared_ptr m_ref; + + template + static auto makeRef(LambdaT const &lambda) -> std::shared_ptr { + return std::make_shared>( lambda) ; + } + + public: + ExeName() : m_name( std::make_shared( "" ) ) {} + + explicit ExeName( std::string &ref ) : ExeName() { + m_ref = std::make_shared>( ref ); + } + + template + explicit ExeName( LambdaT const& lambda ) : ExeName() { + m_ref = std::make_shared>( lambda ); + } + + // The exe name is not parsed out of the normal tokens, but is handled specially + auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override { + return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) ); + } + + auto name() const -> std::string { return *m_name; } + auto set( std::string const& newName ) -> ParserResult { + + auto lastSlash = newName.find_last_of( "\\/" ); + auto filename = ( lastSlash == std::string::npos ) + ? newName + : newName.substr( lastSlash+1 ); + + *m_name = filename; + if( m_ref ) + return m_ref->setValue( filename ); + else + return ParserResult::ok( ParseResultType::Matched ); + } + }; + + class Arg : public ParserRefImpl { + public: + using ParserRefImpl::ParserRefImpl; + + auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override { + auto validationResult = validate(); + if( !validationResult ) + return InternalParseResult( validationResult ); + + auto remainingTokens = tokens; + auto const &token = *remainingTokens; + if( token.type != TokenType::Argument ) + return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) ); + + assert( !m_ref->isFlag() ); + auto valueRef = static_cast( m_ref.get() ); + + auto result = valueRef->setValue( remainingTokens->token ); + if( !result ) + return InternalParseResult( result ); + else + return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) ); + } + }; + + inline auto normaliseOpt( std::string const &optName ) -> std::string { +#ifdef CATCH_PLATFORM_WINDOWS + if( optName[0] == '/' ) + return "-" + optName.substr( 1 ); + else +#endif + return optName; + } + + class Opt : public ParserRefImpl { + protected: + std::vector m_optNames; + + public: + template + explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared>( ref ) ) {} + + explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared( ref ) ) {} + + template + Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} + + template + Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {} + + auto operator[]( std::string const &optName ) -> Opt & { + m_optNames.push_back( optName ); + return *this; + } + + auto getHelpColumns() const -> std::vector { + std::ostringstream oss; + bool first = true; + for( auto const &opt : m_optNames ) { + if (first) + first = false; + else + oss << ", "; + oss << opt; + } + if( !m_hint.empty() ) + oss << " <" << m_hint << ">"; + return { { oss.str(), m_description } }; + } + + auto isMatch( std::string const &optToken ) const -> bool { + auto normalisedToken = normaliseOpt( optToken ); + for( auto const &name : m_optNames ) { + if( normaliseOpt( name ) == normalisedToken ) + return true; + } + return false; + } + + using ParserBase::parse; + + auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override { + auto validationResult = validate(); + if( !validationResult ) + return InternalParseResult( validationResult ); + + auto remainingTokens = tokens; + if( remainingTokens && remainingTokens->type == TokenType::Option ) { + auto const &token = *remainingTokens; + if( isMatch(token.token ) ) { + if( m_ref->isFlag() ) { + auto flagRef = static_cast( m_ref.get() ); + auto result = flagRef->setFlag( true ); + if( !result ) + return InternalParseResult( result ); + if( result.value() == ParseResultType::ShortCircuitAll ) + return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) ); + } else { + auto valueRef = static_cast( m_ref.get() ); + ++remainingTokens; + if( !remainingTokens ) + return InternalParseResult::runtimeError( "Expected argument following " + token.token ); + auto const &argToken = *remainingTokens; + if( argToken.type != TokenType::Argument ) + return InternalParseResult::runtimeError( "Expected argument following " + token.token ); + auto result = valueRef->setValue( argToken.token ); + if( !result ) + return InternalParseResult( result ); + if( result.value() == ParseResultType::ShortCircuitAll ) + return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) ); + } + return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) ); + } + } + return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) ); + } + + auto validate() const -> Result override { + if( m_optNames.empty() ) + return Result::logicError( "No options supplied to Opt" ); + for( auto const &name : m_optNames ) { + if( name.empty() ) + return Result::logicError( "Option name cannot be empty" ); +#ifdef CATCH_PLATFORM_WINDOWS + if( name[0] != '-' && name[0] != '/' ) + return Result::logicError( "Option name must begin with '-' or '/'" ); +#else + if( name[0] != '-' ) + return Result::logicError( "Option name must begin with '-'" ); +#endif + } + return ParserRefImpl::validate(); + } + }; + + struct Help : Opt { + Help( bool &showHelpFlag ) + : Opt([&]( bool flag ) { + showHelpFlag = flag; + return ParserResult::ok( ParseResultType::ShortCircuitAll ); + }) + { + static_cast( *this ) + ("display usage information") + ["-?"]["-h"]["--help"] + .optional(); + } + }; + + struct Parser : ParserBase { + + mutable ExeName m_exeName; + std::vector m_options; + std::vector m_args; + + auto operator|=( ExeName const &exeName ) -> Parser & { + m_exeName = exeName; + return *this; + } + + auto operator|=( Arg const &arg ) -> Parser & { + m_args.push_back(arg); + return *this; + } + + auto operator|=( Opt const &opt ) -> Parser & { + m_options.push_back(opt); + return *this; + } + + auto operator|=( Parser const &other ) -> Parser & { + m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end()); + m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end()); + return *this; + } + + template + auto operator|( T const &other ) const -> Parser { + return Parser( *this ) |= other; + } + + // Forward deprecated interface with '+' instead of '|' + template + auto operator+=( T const &other ) -> Parser & { return operator|=( other ); } + template + auto operator+( T const &other ) const -> Parser { return operator|( other ); } + + auto getHelpColumns() const -> std::vector { + std::vector cols; + for (auto const &o : m_options) { + auto childCols = o.getHelpColumns(); + cols.insert( cols.end(), childCols.begin(), childCols.end() ); + } + return cols; + } + + void writeToStream( std::ostream &os ) const { + if (!m_exeName.name().empty()) { + os << "usage:\n" << " " << m_exeName.name() << " "; + bool required = true, first = true; + for( auto const &arg : m_args ) { + if (first) + first = false; + else + os << " "; + if( arg.isOptional() && required ) { + os << "["; + required = false; + } + os << "<" << arg.hint() << ">"; + if( arg.cardinality() == 0 ) + os << " ... "; + } + if( !required ) + os << "]"; + if( !m_options.empty() ) + os << " options"; + os << "\n\nwhere options are:" << std::endl; + } + + auto rows = getHelpColumns(); + size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH; + size_t optWidth = 0; + for( auto const &cols : rows ) + optWidth = (std::max)(optWidth, cols.left.size() + 2); + + optWidth = (std::min)(optWidth, consoleWidth/2); + + for( auto const &cols : rows ) { + auto row = + TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) + + TextFlow::Spacer(4) + + TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth ); + os << row << std::endl; + } + } + + friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& { + parser.writeToStream( os ); + return os; + } + + auto validate() const -> Result override { + for( auto const &opt : m_options ) { + auto result = opt.validate(); + if( !result ) + return result; + } + for( auto const &arg : m_args ) { + auto result = arg.validate(); + if( !result ) + return result; + } + return Result::ok(); + } + + using ParserBase::parse; + + auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override { + + struct ParserInfo { + ParserBase const* parser = nullptr; + size_t count = 0; + }; + const size_t totalParsers = m_options.size() + m_args.size(); + assert( totalParsers < 512 ); + // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do + ParserInfo parseInfos[512]; + + { + size_t i = 0; + for (auto const &opt : m_options) parseInfos[i++].parser = &opt; + for (auto const &arg : m_args) parseInfos[i++].parser = &arg; + } + + m_exeName.set( exeName ); + + auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) ); + while( result.value().remainingTokens() ) { + bool tokenParsed = false; + + for( size_t i = 0; i < totalParsers; ++i ) { + auto& parseInfo = parseInfos[i]; + if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) { + result = parseInfo.parser->parse(exeName, result.value().remainingTokens()); + if (!result) + return result; + if (result.value().type() != ParseResultType::NoMatch) { + tokenParsed = true; + ++parseInfo.count; + break; + } + } + } + + if( result.value().type() == ParseResultType::ShortCircuitAll ) + return result; + if( !tokenParsed ) + return InternalParseResult::runtimeError( "Unrecognised token: " + result.value().remainingTokens()->token ); + } + // !TBD Check missing required options + return result; + } + }; + + template + template + auto ComposableParserImpl::operator|( T const &other ) const -> Parser { + return Parser() | static_cast( *this ) | other; + } +} // namespace detail + +// A Combined parser +using detail::Parser; + +// A parser for options +using detail::Opt; + +// A parser for arguments +using detail::Arg; + +// Wrapper for argc, argv from main() +using detail::Args; + +// Specifies the name of the executable +using detail::ExeName; + +// Convenience wrapper for option parser that specifies the help option +using detail::Help; + +// enum of result types from a parse +using detail::ParseResultType; + +// Result type for parser operation +using detail::ParserResult; + +}} // namespace Catch::clara + +// end clara.hpp +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// Restore Clara's value for console width, if present +#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +// end catch_clara.h +namespace Catch { + + clara::Parser makeCommandLineParser( ConfigData& config ); + +} // end namespace Catch + +// end catch_commandline.h +#include +#include + +namespace Catch { + + clara::Parser makeCommandLineParser( ConfigData& config ) { + + using namespace clara; + + auto const setWarning = [&]( std::string const& warning ) { + auto warningSet = [&]() { + if( warning == "NoAssertions" ) + return WarnAbout::NoAssertions; + + if ( warning == "NoTests" ) + return WarnAbout::NoTests; + + return WarnAbout::Nothing; + }(); + + if (warningSet == WarnAbout::Nothing) + return ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" ); + config.warnings = static_cast( config.warnings | warningSet ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const loadTestNamesFromFile = [&]( std::string const& filename ) { + std::ifstream f( filename.c_str() ); + if( !f.is_open() ) + return ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" ); + + std::string line; + while( std::getline( f, line ) ) { + line = trim(line); + if( !line.empty() && !startsWith( line, '#' ) ) { + if( !startsWith( line, '"' ) ) + line = '"' + line + '"'; + config.testsOrTags.push_back( line + ',' ); + } + } + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setTestOrder = [&]( std::string const& order ) { + if( startsWith( "declared", order ) ) + config.runOrder = RunTests::InDeclarationOrder; + else if( startsWith( "lexical", order ) ) + config.runOrder = RunTests::InLexicographicalOrder; + else if( startsWith( "random", order ) ) + config.runOrder = RunTests::InRandomOrder; + else + return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setRngSeed = [&]( std::string const& seed ) { + if( seed != "time" ) + return clara::detail::convertInto( seed, config.rngSeed ); + config.rngSeed = static_cast( std::time(nullptr) ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setColourUsage = [&]( std::string const& useColour ) { + auto mode = toLower( useColour ); + + if( mode == "yes" ) + config.useColour = UseColour::Yes; + else if( mode == "no" ) + config.useColour = UseColour::No; + else if( mode == "auto" ) + config.useColour = UseColour::Auto; + else + return ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setWaitForKeypress = [&]( std::string const& keypress ) { + auto keypressLc = toLower( keypress ); + if( keypressLc == "start" ) + config.waitForKeypress = WaitForKeypress::BeforeStart; + else if( keypressLc == "exit" ) + config.waitForKeypress = WaitForKeypress::BeforeExit; + else if( keypressLc == "both" ) + config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; + else + return ParserResult::runtimeError( "keypress argument must be one of: start, exit or both. '" + keypress + "' not recognised" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + auto const setVerbosity = [&]( std::string const& verbosity ) { + auto lcVerbosity = toLower( verbosity ); + if( lcVerbosity == "quiet" ) + config.verbosity = Verbosity::Quiet; + else if( lcVerbosity == "normal" ) + config.verbosity = Verbosity::Normal; + else if( lcVerbosity == "high" ) + config.verbosity = Verbosity::High; + else + return ParserResult::runtimeError( "Unrecognised verbosity, '" + verbosity + "'" ); + return ParserResult::ok( ParseResultType::Matched ); + }; + + auto cli + = ExeName( config.processName ) + | Help( config.showHelp ) + | Opt( config.listTests ) + ["-l"]["--list-tests"] + ( "list all/matching test cases" ) + | Opt( config.listTags ) + ["-t"]["--list-tags"] + ( "list all/matching tags" ) + | Opt( config.showSuccessfulTests ) + ["-s"]["--success"] + ( "include successful tests in output" ) + | Opt( config.shouldDebugBreak ) + ["-b"]["--break"] + ( "break into debugger on failure" ) + | Opt( config.noThrow ) + ["-e"]["--nothrow"] + ( "skip exception tests" ) + | Opt( config.showInvisibles ) + ["-i"]["--invisibles"] + ( "show invisibles (tabs, newlines)" ) + | Opt( config.outputFilename, "filename" ) + ["-o"]["--out"] + ( "output filename" ) + | Opt( config.reporterName, "name" ) + ["-r"]["--reporter"] + ( "reporter to use (defaults to console)" ) + | Opt( config.name, "name" ) + ["-n"]["--name"] + ( "suite name" ) + | Opt( [&]( bool ){ config.abortAfter = 1; } ) + ["-a"]["--abort"] + ( "abort at first failure" ) + | Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" ) + ["-x"]["--abortx"] + ( "abort after x failures" ) + | Opt( setWarning, "warning name" ) + ["-w"]["--warn"] + ( "enable warnings" ) + | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, "yes|no" ) + ["-d"]["--durations"] + ( "show test durations" ) + | Opt( loadTestNamesFromFile, "filename" ) + ["-f"]["--input-file"] + ( "load test names to run from a file" ) + | Opt( config.filenamesAsTags ) + ["-#"]["--filenames-as-tags"] + ( "adds a tag for the filename" ) + | Opt( config.sectionsToRun, "section name" ) + ["-c"]["--section"] + ( "specify section to run" ) + | Opt( setVerbosity, "quiet|normal|high" ) + ["-v"]["--verbosity"] + ( "set output verbosity" ) + | Opt( config.listTestNamesOnly ) + ["--list-test-names-only"] + ( "list all/matching test cases names only" ) + | Opt( config.listReporters ) + ["--list-reporters"] + ( "list all reporters" ) + | Opt( setTestOrder, "decl|lex|rand" ) + ["--order"] + ( "test case order (defaults to decl)" ) + | Opt( setRngSeed, "'time'|number" ) + ["--rng-seed"] + ( "set a specific seed for random numbers" ) + | Opt( setColourUsage, "yes|no" ) + ["--use-colour"] + ( "should output be colourised" ) + | Opt( config.libIdentify ) + ["--libidentify"] + ( "report name and version according to libidentify standard" ) + | Opt( setWaitForKeypress, "start|exit|both" ) + ["--wait-for-keypress"] + ( "waits for a keypress before exiting" ) + | Opt( config.benchmarkResolutionMultiple, "multiplier" ) + ["--benchmark-resolution-multiple"] + ( "multiple of clock resolution to run benchmarks" ) + + | Arg( config.testsOrTags, "test name|pattern|tags" ) + ( "which test or tests to use" ); + + return cli; + } + +} // end namespace Catch +// end catch_commandline.cpp +// start catch_common.cpp + +#include +#include + +namespace Catch { + + bool SourceLineInfo::empty() const noexcept { + return file[0] == '\0'; + } + bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept { + return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); + } + bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept { + return line < other.line || ( line == other.line && (std::strcmp(file, other.file) < 0)); + } + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { +#ifndef __GNUG__ + os << info.file << '(' << info.line << ')'; +#else + os << info.file << ':' << info.line; +#endif + return os; + } + + std::string StreamEndStop::operator+() const { + return std::string(); + } + + NonCopyable::NonCopyable() = default; + NonCopyable::~NonCopyable() = default; + +} +// end catch_common.cpp +// start catch_config.cpp + +// start catch_enforce.h + +#include + +#define CATCH_PREPARE_EXCEPTION( type, msg ) \ + type( ( Catch::ReusableStringStream() << msg ).str() ) +#define CATCH_INTERNAL_ERROR( msg ) \ + throw CATCH_PREPARE_EXCEPTION( std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg); +#define CATCH_ERROR( msg ) \ + throw CATCH_PREPARE_EXCEPTION( std::domain_error, msg ) +#define CATCH_ENFORCE( condition, msg ) \ + do{ if( !(condition) ) CATCH_ERROR( msg ); } while(false) + +// end catch_enforce.h +namespace Catch { + + Config::Config( ConfigData const& data ) + : m_data( data ), + m_stream( openStream() ) + { + TestSpecParser parser(ITagAliasRegistry::get()); + if (data.testsOrTags.empty()) { + parser.parse("~[.]"); // All not hidden tests + } + else { + m_hasTestFilters = true; + for( auto const& testOrTags : data.testsOrTags ) + parser.parse( testOrTags ); + } + m_testSpec = parser.testSpec(); + } + + std::string const& Config::getFilename() const { + return m_data.outputFilename ; + } + + bool Config::listTests() const { return m_data.listTests; } + bool Config::listTestNamesOnly() const { return m_data.listTestNamesOnly; } + bool Config::listTags() const { return m_data.listTags; } + bool Config::listReporters() const { return m_data.listReporters; } + + std::string Config::getProcessName() const { return m_data.processName; } + std::string const& Config::getReporterName() const { return m_data.reporterName; } + + std::vector const& Config::getTestsOrTags() const { return m_data.testsOrTags; } + std::vector const& Config::getSectionsToRun() const { return m_data.sectionsToRun; } + + TestSpec const& Config::testSpec() const { return m_testSpec; } + bool Config::hasTestFilters() const { return m_hasTestFilters; } + + bool Config::showHelp() const { return m_data.showHelp; } + + // IConfig interface + bool Config::allowThrows() const { return !m_data.noThrow; } + std::ostream& Config::stream() const { return m_stream->stream(); } + std::string Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } + bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; } + bool Config::warnAboutMissingAssertions() const { return !!(m_data.warnings & WarnAbout::NoAssertions); } + bool Config::warnAboutNoTests() const { return !!(m_data.warnings & WarnAbout::NoTests); } + ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; } + RunTests::InWhatOrder Config::runOrder() const { return m_data.runOrder; } + unsigned int Config::rngSeed() const { return m_data.rngSeed; } + int Config::benchmarkResolutionMultiple() const { return m_data.benchmarkResolutionMultiple; } + UseColour::YesOrNo Config::useColour() const { return m_data.useColour; } + bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; } + int Config::abortAfter() const { return m_data.abortAfter; } + bool Config::showInvisibles() const { return m_data.showInvisibles; } + Verbosity Config::verbosity() const { return m_data.verbosity; } + + IStream const* Config::openStream() { + return Catch::makeStream(m_data.outputFilename); + } + +} // end namespace Catch +// end catch_config.cpp +// start catch_console_colour.cpp + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +// start catch_errno_guard.h + +namespace Catch { + + class ErrnoGuard { + public: + ErrnoGuard(); + ~ErrnoGuard(); + private: + int m_oldErrno; + }; + +} + +// end catch_errno_guard.h +#include + +namespace Catch { + namespace { + + struct IColourImpl { + virtual ~IColourImpl() = default; + virtual void use( Colour::Code _colourCode ) = 0; + }; + + struct NoColourImpl : IColourImpl { + void use( Colour::Code ) {} + + static IColourImpl* instance() { + static NoColourImpl s_instance; + return &s_instance; + } + }; + + } // anon namespace +} // namespace Catch + +#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) +# ifdef CATCH_PLATFORM_WINDOWS +# define CATCH_CONFIG_COLOUR_WINDOWS +# else +# define CATCH_CONFIG_COLOUR_ANSI +# endif +#endif + +#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// + +namespace Catch { +namespace { + + class Win32ColourImpl : public IColourImpl { + public: + Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) + { + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); + originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); + originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); + } + + virtual void use( Colour::Code _colourCode ) override { + switch( _colourCode ) { + case Colour::None: return setTextAttribute( originalForegroundAttributes ); + case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + case Colour::Red: return setTextAttribute( FOREGROUND_RED ); + case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); + case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); + case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); + case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); + case Colour::Grey: return setTextAttribute( 0 ); + + case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); + case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); + case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); + case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); + case Colour::BrightYellow: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN ); + + case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" ); + + default: + CATCH_ERROR( "Unknown colour requested" ); + } + } + + private: + void setTextAttribute( WORD _textAttribute ) { + SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); + } + HANDLE stdoutHandle; + WORD originalForegroundAttributes; + WORD originalBackgroundAttributes; + }; + + IColourImpl* platformColourInstance() { + static Win32ColourImpl s_instance; + + IConfigPtr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = UseColour::Yes; + return colourMode == UseColour::Yes + ? &s_instance + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// + +#include + +namespace Catch { +namespace { + + // use POSIX/ ANSI console terminal codes + // Thanks to Adam Strzelecki for original contribution + // (http://github.com/nanoant) + // https://github.com/philsquared/Catch/pull/131 + class PosixColourImpl : public IColourImpl { + public: + virtual void use( Colour::Code _colourCode ) override { + switch( _colourCode ) { + case Colour::None: + case Colour::White: return setColour( "[0m" ); + case Colour::Red: return setColour( "[0;31m" ); + case Colour::Green: return setColour( "[0;32m" ); + case Colour::Blue: return setColour( "[0;34m" ); + case Colour::Cyan: return setColour( "[0;36m" ); + case Colour::Yellow: return setColour( "[0;33m" ); + case Colour::Grey: return setColour( "[1;30m" ); + + case Colour::LightGrey: return setColour( "[0;37m" ); + case Colour::BrightRed: return setColour( "[1;31m" ); + case Colour::BrightGreen: return setColour( "[1;32m" ); + case Colour::BrightWhite: return setColour( "[1;37m" ); + case Colour::BrightYellow: return setColour( "[1;33m" ); + + case Colour::Bright: CATCH_INTERNAL_ERROR( "not a colour" ); + default: CATCH_INTERNAL_ERROR( "Unknown colour requested" ); + } + } + static IColourImpl* instance() { + static PosixColourImpl s_instance; + return &s_instance; + } + + private: + void setColour( const char* _escapeCode ) { + Catch::cout() << '\033' << _escapeCode; + } + }; + + bool useColourOnPlatform() { + return +#ifdef CATCH_PLATFORM_MAC + !isDebuggerActive() && +#endif +#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__)) + isatty(STDOUT_FILENO) +#else + false +#endif + ; + } + IColourImpl* platformColourInstance() { + ErrnoGuard guard; + IConfigPtr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config + ? config->useColour() + : UseColour::Auto; + if( colourMode == UseColour::Auto ) + colourMode = useColourOnPlatform() + ? UseColour::Yes + : UseColour::No; + return colourMode == UseColour::Yes + ? PosixColourImpl::instance() + : NoColourImpl::instance(); + } + +} // end anon namespace +} // end namespace Catch + +#else // not Windows or ANSI /////////////////////////////////////////////// + +namespace Catch { + + static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } + +} // end namespace Catch + +#endif // Windows/ ANSI/ None + +namespace Catch { + + Colour::Colour( Code _colourCode ) { use( _colourCode ); } + Colour::Colour( Colour&& rhs ) noexcept { + m_moved = rhs.m_moved; + rhs.m_moved = true; + } + Colour& Colour::operator=( Colour&& rhs ) noexcept { + m_moved = rhs.m_moved; + rhs.m_moved = true; + return *this; + } + + Colour::~Colour(){ if( !m_moved ) use( None ); } + + void Colour::use( Code _colourCode ) { + static IColourImpl* impl = platformColourInstance(); + impl->use( _colourCode ); + } + + std::ostream& operator << ( std::ostream& os, Colour const& ) { + return os; + } + +} // end namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +// end catch_console_colour.cpp +// start catch_context.cpp + +namespace Catch { + + class Context : public IMutableContext, NonCopyable { + + public: // IContext + virtual IResultCapture* getResultCapture() override { + return m_resultCapture; + } + virtual IRunner* getRunner() override { + return m_runner; + } + + virtual IConfigPtr const& getConfig() const override { + return m_config; + } + + virtual ~Context() override; + + public: // IMutableContext + virtual void setResultCapture( IResultCapture* resultCapture ) override { + m_resultCapture = resultCapture; + } + virtual void setRunner( IRunner* runner ) override { + m_runner = runner; + } + virtual void setConfig( IConfigPtr const& config ) override { + m_config = config; + } + + friend IMutableContext& getCurrentMutableContext(); + + private: + IConfigPtr m_config; + IRunner* m_runner = nullptr; + IResultCapture* m_resultCapture = nullptr; + }; + + IMutableContext *IMutableContext::currentContext = nullptr; + + void IMutableContext::createContext() + { + currentContext = new Context(); + } + + void cleanUpContext() { + delete IMutableContext::currentContext; + IMutableContext::currentContext = nullptr; + } + IContext::~IContext() = default; + IMutableContext::~IMutableContext() = default; + Context::~Context() = default; +} +// end catch_context.cpp +// start catch_debug_console.cpp + +// start catch_debug_console.h + +#include + +namespace Catch { + void writeToDebugConsole( std::string const& text ); +} + +// end catch_debug_console.h +#ifdef CATCH_PLATFORM_WINDOWS + + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + ::OutputDebugStringA( text.c_str() ); + } + } + +#else + + namespace Catch { + void writeToDebugConsole( std::string const& text ) { + // !TBD: Need a version for Mac/ XCode and other IDEs + Catch::cout() << text; + } + } + +#endif // Platform +// end catch_debug_console.cpp +// start catch_debugger.cpp + +#ifdef CATCH_PLATFORM_MAC + +# include +# include +# include +# include +# include +# include +# include + +namespace Catch { + + // The following function is taken directly from the following technical note: + // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html + + // Returns true if the current process is being debugged (either + // running under the debugger or has a debugger attached post facto). + bool isDebuggerActive(){ + + int mib[4]; + struct kinfo_proc info; + std::size_t size; + + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) { + Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; + return false; + } + + // We're being debugged if the P_TRACED flag is set. + + return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); + } + } // namespace Catch + +#elif defined(CATCH_PLATFORM_LINUX) + #include + #include + + namespace Catch{ + // The standard POSIX way of detecting a debugger is to attempt to + // ptrace() the process, but this needs to be done from a child and not + // this process itself to still allow attaching to this process later + // if wanted, so is rather heavy. Under Linux we have the PID of the + // "debugger" (which doesn't need to be gdb, of course, it could also + // be strace, for example) in /proc/$PID/status, so just get it from + // there instead. + bool isDebuggerActive(){ + // Libstdc++ has a bug, where std::ifstream sets errno to 0 + // This way our users can properly assert over errno values + ErrnoGuard guard; + std::ifstream in("/proc/self/status"); + for( std::string line; std::getline(in, line); ) { + static const int PREFIX_LEN = 11; + if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { + // We're traced if the PID is not 0 and no other PID starts + // with 0 digit, so it's enough to check for just a single + // character. + return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; + } + } + + return false; + } + } // namespace Catch +#elif defined(_MSC_VER) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#elif defined(__MINGW32__) + extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); + namespace Catch { + bool isDebuggerActive() { + return IsDebuggerPresent() != 0; + } + } +#else + namespace Catch { + bool isDebuggerActive() { return false; } + } +#endif // Platform +// end catch_debugger.cpp +// start catch_decomposer.cpp + +namespace Catch { + + ITransientExpression::~ITransientExpression() = default; + + void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) { + if( lhs.size() + rhs.size() < 40 && + lhs.find('\n') == std::string::npos && + rhs.find('\n') == std::string::npos ) + os << lhs << " " << op << " " << rhs; + else + os << lhs << "\n" << op << "\n" << rhs; + } +} +// end catch_decomposer.cpp +// start catch_errno_guard.cpp + +#include + +namespace Catch { + ErrnoGuard::ErrnoGuard():m_oldErrno(errno){} + ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; } +} +// end catch_errno_guard.cpp +// start catch_exception_translator_registry.cpp + +// start catch_exception_translator_registry.h + +#include +#include +#include + +namespace Catch { + + class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { + public: + ~ExceptionTranslatorRegistry(); + virtual void registerTranslator( const IExceptionTranslator* translator ); + virtual std::string translateActiveException() const override; + std::string tryTranslators() const; + + private: + std::vector> m_translators; + }; +} + +// end catch_exception_translator_registry.h +#ifdef __OBJC__ +#import "Foundation/Foundation.h" +#endif + +namespace Catch { + + ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() { + } + + void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) { + m_translators.push_back( std::unique_ptr( translator ) ); + } + + std::string ExceptionTranslatorRegistry::translateActiveException() const { + try { +#ifdef __OBJC__ + // In Objective-C try objective-c exceptions first + @try { + return tryTranslators(); + } + @catch (NSException *exception) { + return Catch::Detail::stringify( [exception description] ); + } +#else + // Compiling a mixed mode project with MSVC means that CLR + // exceptions will be caught in (...) as well. However, these + // do not fill-in std::current_exception and thus lead to crash + // when attempting rethrow. + // /EHa switch also causes structured exceptions to be caught + // here, but they fill-in current_exception properly, so + // at worst the output should be a little weird, instead of + // causing a crash. + if (std::current_exception() == nullptr) { + return "Non C++ exception. Possibly a CLR exception."; + } + return tryTranslators(); +#endif + } + catch( TestFailureException& ) { + std::rethrow_exception(std::current_exception()); + } + catch( std::exception& ex ) { + return ex.what(); + } + catch( std::string& msg ) { + return msg; + } + catch( const char* msg ) { + return msg; + } + catch(...) { + return "Unknown exception"; + } + } + + std::string ExceptionTranslatorRegistry::tryTranslators() const { + if( m_translators.empty() ) + std::rethrow_exception(std::current_exception()); + else + return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); + } +} +// end catch_exception_translator_registry.cpp +// start catch_fatal_condition.cpp + +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS ) + +namespace { + // Report the error condition + void reportFatal( char const * const message ) { + Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message ); + } +} + +#endif // signals/SEH handling + +#if defined( CATCH_CONFIG_WINDOWS_SEH ) + +namespace Catch { + struct SignalDefs { DWORD id; const char* name; }; + + // There is no 1-1 mapping between signals and windows exceptions. + // Windows can easily distinguish between SO and SigSegV, + // but SigInt, SigTerm, etc are handled differently. + static SignalDefs signalDefs[] = { + { EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal" }, + { EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow" }, + { EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal" }, + { EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error" }, + }; + + LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { + for (auto const& def : signalDefs) { + if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) { + reportFatal(def.name); + } + } + // If its not an exception we care about, pass it along. + // This stops us from eating debugger breaks etc. + return EXCEPTION_CONTINUE_SEARCH; + } + + FatalConditionHandler::FatalConditionHandler() { + isSet = true; + // 32k seems enough for Catch to handle stack overflow, + // but the value was found experimentally, so there is no strong guarantee + guaranteeSize = 32 * 1024; + exceptionHandlerHandle = nullptr; + // Register as first handler in current chain + exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); + // Pass in guarantee size to be filled + SetThreadStackGuarantee(&guaranteeSize); + } + + void FatalConditionHandler::reset() { + if (isSet) { + RemoveVectoredExceptionHandler(exceptionHandlerHandle); + SetThreadStackGuarantee(&guaranteeSize); + exceptionHandlerHandle = nullptr; + isSet = false; + } + } + + FatalConditionHandler::~FatalConditionHandler() { + reset(); + } + +bool FatalConditionHandler::isSet = false; +ULONG FatalConditionHandler::guaranteeSize = 0; +PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; + +} // namespace Catch + +#elif defined( CATCH_CONFIG_POSIX_SIGNALS ) + +namespace Catch { + + struct SignalDefs { + int id; + const char* name; + }; + + // 32kb for the alternate stack seems to be sufficient. However, this value + // is experimentally determined, so that's not guaranteed. + constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ; + + static SignalDefs signalDefs[] = { + { SIGINT, "SIGINT - Terminal interrupt signal" }, + { SIGILL, "SIGILL - Illegal instruction signal" }, + { SIGFPE, "SIGFPE - Floating point error signal" }, + { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, + { SIGTERM, "SIGTERM - Termination request signal" }, + { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } + }; + + void FatalConditionHandler::handleSignal( int sig ) { + char const * name = ""; + for (auto const& def : signalDefs) { + if (sig == def.id) { + name = def.name; + break; + } + } + reset(); + reportFatal(name); + raise( sig ); + } + + FatalConditionHandler::FatalConditionHandler() { + isSet = true; + stack_t sigStack; + sigStack.ss_sp = altStackMem; + sigStack.ss_size = sigStackSize; + sigStack.ss_flags = 0; + sigaltstack(&sigStack, &oldSigStack); + struct sigaction sa = { }; + + sa.sa_handler = handleSignal; + sa.sa_flags = SA_ONSTACK; + for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); + } + } + + FatalConditionHandler::~FatalConditionHandler() { + reset(); + } + + void FatalConditionHandler::reset() { + if( isSet ) { + // Set signals back to previous values -- hopefully nobody overwrote them in the meantime + for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) { + sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); + } + // Return the old stack + sigaltstack(&oldSigStack, nullptr); + isSet = false; + } + } + + bool FatalConditionHandler::isSet = false; + struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs)/sizeof(SignalDefs)] = {}; + stack_t FatalConditionHandler::oldSigStack = {}; + char FatalConditionHandler::altStackMem[sigStackSize] = {}; + +} // namespace Catch + +#else + +namespace Catch { + void FatalConditionHandler::reset() {} +} + +#endif // signals/SEH handling + +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#endif +// end catch_fatal_condition.cpp +// start catch_interfaces_capture.cpp + +namespace Catch { + IResultCapture::~IResultCapture() = default; +} +// end catch_interfaces_capture.cpp +// start catch_interfaces_config.cpp + +namespace Catch { + IConfig::~IConfig() = default; +} +// end catch_interfaces_config.cpp +// start catch_interfaces_exception.cpp + +namespace Catch { + IExceptionTranslator::~IExceptionTranslator() = default; + IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default; +} +// end catch_interfaces_exception.cpp +// start catch_interfaces_registry_hub.cpp + +namespace Catch { + IRegistryHub::~IRegistryHub() = default; + IMutableRegistryHub::~IMutableRegistryHub() = default; +} +// end catch_interfaces_registry_hub.cpp +// start catch_interfaces_reporter.cpp + +// start catch_reporter_listening.h + +namespace Catch { + + class ListeningReporter : public IStreamingReporter { + using Reporters = std::vector; + Reporters m_listeners; + IStreamingReporterPtr m_reporter = nullptr; + + public: + void addListener( IStreamingReporterPtr&& listener ); + void addReporter( IStreamingReporterPtr&& reporter ); + + public: // IStreamingReporter + + ReporterPreferences getPreferences() const override; + + void noMatchingTestCases( std::string const& spec ) override; + + static std::set getSupportedVerbosities(); + + void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override; + void benchmarkEnded( BenchmarkStats const& benchmarkStats ) override; + + void testRunStarting( TestRunInfo const& testRunInfo ) override; + void testGroupStarting( GroupInfo const& groupInfo ) override; + void testCaseStarting( TestCaseInfo const& testInfo ) override; + void sectionStarting( SectionInfo const& sectionInfo ) override; + void assertionStarting( AssertionInfo const& assertionInfo ) override; + + // The return value indicates if the messages buffer should be cleared: + bool assertionEnded( AssertionStats const& assertionStats ) override; + void sectionEnded( SectionStats const& sectionStats ) override; + void testCaseEnded( TestCaseStats const& testCaseStats ) override; + void testGroupEnded( TestGroupStats const& testGroupStats ) override; + void testRunEnded( TestRunStats const& testRunStats ) override; + + void skipTest( TestCaseInfo const& testInfo ) override; + bool isMulti() const override; + + }; + +} // end namespace Catch + +// end catch_reporter_listening.h +namespace Catch { + + ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig ) + : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} + + ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream ) + : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} + + std::ostream& ReporterConfig::stream() const { return *m_stream; } + IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; } + + TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {} + + GroupInfo::GroupInfo( std::string const& _name, + std::size_t _groupIndex, + std::size_t _groupsCount ) + : name( _name ), + groupIndex( _groupIndex ), + groupsCounts( _groupsCount ) + {} + + AssertionStats::AssertionStats( AssertionResult const& _assertionResult, + std::vector const& _infoMessages, + Totals const& _totals ) + : assertionResult( _assertionResult ), + infoMessages( _infoMessages ), + totals( _totals ) + { + assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression; + + if( assertionResult.hasMessage() ) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); + builder << assertionResult.getMessage(); + builder.m_info.message = builder.m_stream.str(); + + infoMessages.push_back( builder.m_info ); + } + } + + AssertionStats::~AssertionStats() = default; + + SectionStats::SectionStats( SectionInfo const& _sectionInfo, + Counts const& _assertions, + double _durationInSeconds, + bool _missingAssertions ) + : sectionInfo( _sectionInfo ), + assertions( _assertions ), + durationInSeconds( _durationInSeconds ), + missingAssertions( _missingAssertions ) + {} + + SectionStats::~SectionStats() = default; + + TestCaseStats::TestCaseStats( TestCaseInfo const& _testInfo, + Totals const& _totals, + std::string const& _stdOut, + std::string const& _stdErr, + bool _aborting ) + : testInfo( _testInfo ), + totals( _totals ), + stdOut( _stdOut ), + stdErr( _stdErr ), + aborting( _aborting ) + {} + + TestCaseStats::~TestCaseStats() = default; + + TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo, + Totals const& _totals, + bool _aborting ) + : groupInfo( _groupInfo ), + totals( _totals ), + aborting( _aborting ) + {} + + TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo ) + : groupInfo( _groupInfo ), + aborting( false ) + {} + + TestGroupStats::~TestGroupStats() = default; + + TestRunStats::TestRunStats( TestRunInfo const& _runInfo, + Totals const& _totals, + bool _aborting ) + : runInfo( _runInfo ), + totals( _totals ), + aborting( _aborting ) + {} + + TestRunStats::~TestRunStats() = default; + + void IStreamingReporter::fatalErrorEncountered( StringRef ) {} + bool IStreamingReporter::isMulti() const { return false; } + + IReporterFactory::~IReporterFactory() = default; + IReporterRegistry::~IReporterRegistry() = default; + +} // end namespace Catch +// end catch_interfaces_reporter.cpp +// start catch_interfaces_runner.cpp + +namespace Catch { + IRunner::~IRunner() = default; +} +// end catch_interfaces_runner.cpp +// start catch_interfaces_testcase.cpp + +namespace Catch { + ITestInvoker::~ITestInvoker() = default; + ITestCaseRegistry::~ITestCaseRegistry() = default; +} +// end catch_interfaces_testcase.cpp +// start catch_leak_detector.cpp + +#ifdef CATCH_CONFIG_WINDOWS_CRTDBG +#include + +namespace Catch { + + LeakDetector::LeakDetector() { + int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + flag |= _CRTDBG_LEAK_CHECK_DF; + flag |= _CRTDBG_ALLOC_MEM_DF; + _CrtSetDbgFlag(flag); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + // Change this to leaking allocation's number to break there + _CrtSetBreakAlloc(-1); + } +} + +#else + + Catch::LeakDetector::LeakDetector() {} + +#endif +// end catch_leak_detector.cpp +// start catch_list.cpp + +// start catch_list.h + +#include + +namespace Catch { + + std::size_t listTests( Config const& config ); + + std::size_t listTestsNamesOnly( Config const& config ); + + struct TagInfo { + void add( std::string const& spelling ); + std::string all() const; + + std::set spellings; + std::size_t count = 0; + }; + + std::size_t listTags( Config const& config ); + + std::size_t listReporters( Config const& /*config*/ ); + + Option list( Config const& config ); + +} // end namespace Catch + +// end catch_list.h +// start catch_text.h + +namespace Catch { + using namespace clara::TextFlow; +} + +// end catch_text.h +#include +#include +#include + +namespace Catch { + + std::size_t listTests( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( config.hasTestFilters() ) + Catch::cout() << "Matching test cases:\n"; + else { + Catch::cout() << "All available test cases:\n"; + } + + auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( auto const& testCaseInfo : matchedTestCases ) { + Colour::Code colour = testCaseInfo.isHidden() + ? Colour::SecondaryText + : Colour::None; + Colour colourGuard( colour ); + + Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n"; + if( config.verbosity() >= Verbosity::High ) { + Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl; + std::string description = testCaseInfo.description; + if( description.empty() ) + description = "(NO DESCRIPTION)"; + Catch::cout() << Column( description ).indent(4) << std::endl; + } + if( !testCaseInfo.tags.empty() ) + Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << "\n"; + } + + if( !config.hasTestFilters() ) + Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl; + else + Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl; + return matchedTestCases.size(); + } + + std::size_t listTestsNamesOnly( Config const& config ) { + TestSpec testSpec = config.testSpec(); + std::size_t matchedTests = 0; + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( auto const& testCaseInfo : matchedTestCases ) { + matchedTests++; + if( startsWith( testCaseInfo.name, '#' ) ) + Catch::cout() << '"' << testCaseInfo.name << '"'; + else + Catch::cout() << testCaseInfo.name; + if ( config.verbosity() >= Verbosity::High ) + Catch::cout() << "\t@" << testCaseInfo.lineInfo; + Catch::cout() << std::endl; + } + return matchedTests; + } + + void TagInfo::add( std::string const& spelling ) { + ++count; + spellings.insert( spelling ); + } + + std::string TagInfo::all() const { + std::string out; + for( auto const& spelling : spellings ) + out += "[" + spelling + "]"; + return out; + } + + std::size_t listTags( Config const& config ) { + TestSpec testSpec = config.testSpec(); + if( config.hasTestFilters() ) + Catch::cout() << "Tags for matching test cases:\n"; + else { + Catch::cout() << "All available tags:\n"; + } + + std::map tagCounts; + + std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); + for( auto const& testCase : matchedTestCases ) { + for( auto const& tagName : testCase.getTestCaseInfo().tags ) { + std::string lcaseTagName = toLower( tagName ); + auto countIt = tagCounts.find( lcaseTagName ); + if( countIt == tagCounts.end() ) + countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; + countIt->second.add( tagName ); + } + } + + for( auto const& tagCount : tagCounts ) { + ReusableStringStream rss; + rss << " " << std::setw(2) << tagCount.second.count << " "; + auto str = rss.str(); + auto wrapper = Column( tagCount.second.all() ) + .initialIndent( 0 ) + .indent( str.size() ) + .width( CATCH_CONFIG_CONSOLE_WIDTH-10 ); + Catch::cout() << str << wrapper << '\n'; + } + Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; + return tagCounts.size(); + } + + std::size_t listReporters( Config const& /*config*/ ) { + Catch::cout() << "Available reporters:\n"; + IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); + std::size_t maxNameLen = 0; + for( auto const& factoryKvp : factories ) + maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() ); + + for( auto const& factoryKvp : factories ) { + Catch::cout() + << Column( factoryKvp.first + ":" ) + .indent(2) + .width( 5+maxNameLen ) + + Column( factoryKvp.second->getDescription() ) + .initialIndent(0) + .indent(2) + .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) + << "\n"; + } + Catch::cout() << std::endl; + return factories.size(); + } + + Option list( Config const& config ) { + Option listedCount; + if( config.listTests() ) + listedCount = listedCount.valueOr(0) + listTests( config ); + if( config.listTestNamesOnly() ) + listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); + if( config.listTags() ) + listedCount = listedCount.valueOr(0) + listTags( config ); + if( config.listReporters() ) + listedCount = listedCount.valueOr(0) + listReporters( config ); + return listedCount; + } + +} // end namespace Catch +// end catch_list.cpp +// start catch_matchers.cpp + +namespace Catch { +namespace Matchers { + namespace Impl { + + std::string MatcherUntypedBase::toString() const { + if( m_cachedToString.empty() ) + m_cachedToString = describe(); + return m_cachedToString; + } + + MatcherUntypedBase::~MatcherUntypedBase() = default; + + } // namespace Impl +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch +// end catch_matchers.cpp +// start catch_matchers_floating.cpp + +// start catch_to_string.hpp + +#include + +namespace Catch { + template + std::string to_string(T const& t) { +#if defined(CATCH_CONFIG_CPP11_TO_STRING) + return std::to_string(t); +#else + ReusableStringStream rss; + rss << t; + return rss.str(); +#endif + } +} // end namespace Catch + +// end catch_to_string.hpp +#include +#include +#include +#include + +namespace Catch { +namespace Matchers { +namespace Floating { +enum class FloatingPointKind : uint8_t { + Float, + Double +}; +} +} +} + +namespace { + +template +struct Converter; + +template <> +struct Converter { + static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated"); + Converter(float f) { + std::memcpy(&i, &f, sizeof(f)); + } + int32_t i; +}; + +template <> +struct Converter { + static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated"); + Converter(double d) { + std::memcpy(&i, &d, sizeof(d)); + } + int64_t i; +}; + +template +auto convert(T t) -> Converter { + return Converter(t); +} + +template +bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) { + // Comparison with NaN should always be false. + // This way we can rule it out before getting into the ugly details + if (std::isnan(lhs) || std::isnan(rhs)) { + return false; + } + + auto lc = convert(lhs); + auto rc = convert(rhs); + + if ((lc.i < 0) != (rc.i < 0)) { + // Potentially we can have +0 and -0 + return lhs == rhs; + } + + auto ulpDiff = std::abs(lc.i - rc.i); + return ulpDiff <= maxUlpDiff; +} + +} + +namespace Catch { +namespace Matchers { +namespace Floating { + WithinAbsMatcher::WithinAbsMatcher(double target, double margin) + :m_target{ target }, m_margin{ margin } { + if (m_margin < 0) { + throw std::domain_error("Allowed margin difference has to be >= 0"); + } + } + + // Performs equivalent check of std::fabs(lhs - rhs) <= margin + // But without the subtraction to allow for INFINITY in comparison + bool WithinAbsMatcher::match(double const& matchee) const { + return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee); + } + + std::string WithinAbsMatcher::describe() const { + return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target); + } + + WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType) + :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } { + if (m_ulps < 0) { + throw std::domain_error("Allowed ulp difference has to be >= 0"); + } + } + + bool WithinUlpsMatcher::match(double const& matchee) const { + switch (m_type) { + case FloatingPointKind::Float: + return almostEqualUlps(static_cast(matchee), static_cast(m_target), m_ulps); + case FloatingPointKind::Double: + return almostEqualUlps(matchee, m_target, m_ulps); + default: + throw std::domain_error("Unknown FloatingPointKind value"); + } + } + + std::string WithinUlpsMatcher::describe() const { + return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : ""); + } + +}// namespace Floating + +Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) { + return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double); +} + +Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) { + return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float); +} + +Floating::WithinAbsMatcher WithinAbs(double target, double margin) { + return Floating::WithinAbsMatcher(target, margin); +} + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_floating.cpp +// start catch_matchers_generic.cpp + +std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) { + if (desc.empty()) { + return "matches undescribed predicate"; + } else { + return "matches predicate: \"" + desc + '"'; + } +} +// end catch_matchers_generic.cpp +// start catch_matchers_string.cpp + +#include + +namespace Catch { +namespace Matchers { + + namespace StdString { + + CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_str( adjustString( str ) ) + {} + std::string CasedString::adjustString( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No + ? toLower( str ) + : str; + } + std::string CasedString::caseSensitivitySuffix() const { + return m_caseSensitivity == CaseSensitive::No + ? " (case insensitive)" + : std::string(); + } + + StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator ) + : m_comparator( comparator ), + m_operation( operation ) { + } + + std::string StringMatcherBase::describe() const { + std::string description; + description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + + m_comparator.caseSensitivitySuffix().size()); + description += m_operation; + description += ": \""; + description += m_comparator.m_str; + description += "\""; + description += m_comparator.caseSensitivitySuffix(); + return description; + } + + EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( "equals", comparator ) {} + + bool EqualsMatcher::match( std::string const& source ) const { + return m_comparator.adjustString( source ) == m_comparator.m_str; + } + + ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( "contains", comparator ) {} + + bool ContainsMatcher::match( std::string const& source ) const { + return contains( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "starts with", comparator ) {} + + bool StartsWithMatcher::match( std::string const& source ) const { + return startsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( "ends with", comparator ) {} + + bool EndsWithMatcher::match( std::string const& source ) const { + return endsWith( m_comparator.adjustString( source ), m_comparator.m_str ); + } + + RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {} + + bool RegexMatcher::match(std::string const& matchee) const { + auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway + if (m_caseSensitivity == CaseSensitive::Choice::No) { + flags |= std::regex::icase; + } + auto reg = std::regex(m_regex, flags); + return std::regex_match(matchee, reg); + } + + std::string RegexMatcher::describe() const { + return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively"); + } + + } // namespace StdString + + StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) { + return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) ); + } + + StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) { + return StdString::RegexMatcher(regex, caseSensitivity); + } + +} // namespace Matchers +} // namespace Catch +// end catch_matchers_string.cpp +// start catch_message.cpp + +// start catch_uncaught_exceptions.h + +namespace Catch { + bool uncaught_exceptions(); +} // end namespace Catch + +// end catch_uncaught_exceptions.h +namespace Catch { + + MessageInfo::MessageInfo( std::string const& _macroName, + SourceLineInfo const& _lineInfo, + ResultWas::OfType _type ) + : macroName( _macroName ), + lineInfo( _lineInfo ), + type( _type ), + sequence( ++globalCount ) + {} + + bool MessageInfo::operator==( MessageInfo const& other ) const { + return sequence == other.sequence; + } + + bool MessageInfo::operator<( MessageInfo const& other ) const { + return sequence < other.sequence; + } + + // This may need protecting if threading support is added + unsigned int MessageInfo::globalCount = 0; + + //////////////////////////////////////////////////////////////////////////// + + Catch::MessageBuilder::MessageBuilder( std::string const& macroName, + SourceLineInfo const& lineInfo, + ResultWas::OfType type ) + :m_info(macroName, lineInfo, type) {} + + //////////////////////////////////////////////////////////////////////////// + + ScopedMessage::ScopedMessage( MessageBuilder const& builder ) + : m_info( builder.m_info ) + { + m_info.message = builder.m_stream.str(); + getResultCapture().pushScopedMessage( m_info ); + } + + ScopedMessage::~ScopedMessage() { + if ( !uncaught_exceptions() ){ + getResultCapture().popScopedMessage(m_info); + } + } +} // end namespace Catch +// end catch_message.cpp +// start catch_output_redirect.cpp + +// start catch_output_redirect.h +#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H +#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H + +#include +#include +#include + +namespace Catch { + + class RedirectedStream { + std::ostream& m_originalStream; + std::ostream& m_redirectionStream; + std::streambuf* m_prevBuf; + + public: + RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ); + ~RedirectedStream(); + }; + + class RedirectedStdOut { + ReusableStringStream m_rss; + RedirectedStream m_cout; + public: + RedirectedStdOut(); + auto str() const -> std::string; + }; + + // StdErr has two constituent streams in C++, std::cerr and std::clog + // This means that we need to redirect 2 streams into 1 to keep proper + // order of writes + class RedirectedStdErr { + ReusableStringStream m_rss; + RedirectedStream m_cerr; + RedirectedStream m_clog; + public: + RedirectedStdErr(); + auto str() const -> std::string; + }; + + // Windows's implementation of std::tmpfile is terrible (it tries + // to create a file inside system folder, thus requiring elevated + // privileges for the binary), so we have to use tmpnam(_s) and + // create the file ourselves there. + class TempFile { + public: + TempFile(TempFile const&) = delete; + TempFile& operator=(TempFile const&) = delete; + TempFile(TempFile&&) = delete; + TempFile& operator=(TempFile&&) = delete; + + TempFile(); + ~TempFile(); + + std::FILE* getFile(); + std::string getContents(); + + private: + std::FILE* m_file = nullptr; + #if defined(_MSC_VER) + char m_buffer[L_tmpnam] = { 0 }; + #endif + }; + + class OutputRedirect { + public: + OutputRedirect(OutputRedirect const&) = delete; + OutputRedirect& operator=(OutputRedirect const&) = delete; + OutputRedirect(OutputRedirect&&) = delete; + OutputRedirect& operator=(OutputRedirect&&) = delete; + + OutputRedirect(std::string& stdout_dest, std::string& stderr_dest); + ~OutputRedirect(); + + private: + int m_originalStdout = -1; + int m_originalStderr = -1; + TempFile m_stdoutFile; + TempFile m_stderrFile; + std::string& m_stdoutDest; + std::string& m_stderrDest; + }; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H +// end catch_output_redirect.h +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +#include //_dup and _dup2 +#define dup _dup +#define dup2 _dup2 +#define fileno _fileno +#else +#include // dup and dup2 +#endif + +namespace Catch { + + RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ) + : m_originalStream( originalStream ), + m_redirectionStream( redirectionStream ), + m_prevBuf( m_originalStream.rdbuf() ) + { + m_originalStream.rdbuf( m_redirectionStream.rdbuf() ); + } + + RedirectedStream::~RedirectedStream() { + m_originalStream.rdbuf( m_prevBuf ); + } + + RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {} + auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); } + + RedirectedStdErr::RedirectedStdErr() + : m_cerr( Catch::cerr(), m_rss.get() ), + m_clog( Catch::clog(), m_rss.get() ) + {} + auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); } + +#if defined(_MSC_VER) + TempFile::TempFile() { + if (tmpnam_s(m_buffer)) { + throw std::runtime_error("Could not get a temp filename"); + } + if (fopen_s(&m_file, m_buffer, "w")) { + char buffer[100]; + if (strerror_s(buffer, errno)) { + throw std::runtime_error("Could not translate errno to string"); + } + throw std::runtime_error("Could not open the temp file: " + std::string(m_buffer) + buffer); + } + } +#else + TempFile::TempFile() { + m_file = std::tmpfile(); + if (!m_file) { + throw std::runtime_error("Could not create a temp file."); + } + } + +#endif + + TempFile::~TempFile() { + // TBD: What to do about errors here? + std::fclose(m_file); + // We manually create the file on Windows only, on Linux + // it will be autodeleted +#if defined(_MSC_VER) + std::remove(m_buffer); +#endif + } + + FILE* TempFile::getFile() { + return m_file; + } + + std::string TempFile::getContents() { + std::stringstream sstr; + char buffer[100] = {}; + std::rewind(m_file); + while (std::fgets(buffer, sizeof(buffer), m_file)) { + sstr << buffer; + } + return sstr.str(); + } + + OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) : + m_originalStdout(dup(1)), + m_originalStderr(dup(2)), + m_stdoutDest(stdout_dest), + m_stderrDest(stderr_dest) { + dup2(fileno(m_stdoutFile.getFile()), 1); + dup2(fileno(m_stderrFile.getFile()), 2); + } + + OutputRedirect::~OutputRedirect() { + Catch::cout() << std::flush; + fflush(stdout); + // Since we support overriding these streams, we flush cerr + // even though std::cerr is unbuffered + Catch::cerr() << std::flush; + Catch::clog() << std::flush; + fflush(stderr); + + dup2(m_originalStdout, 1); + dup2(m_originalStderr, 2); + + m_stdoutDest += m_stdoutFile.getContents(); + m_stderrDest += m_stderrFile.getContents(); + } + +} // namespace Catch + +#if defined(_MSC_VER) +#undef dup +#undef dup2 +#undef fileno +#endif +// end catch_output_redirect.cpp +// start catch_random_number_generator.cpp + +// start catch_random_number_generator.h + +#include + +namespace Catch { + + struct IConfig; + + void seedRng( IConfig const& config ); + + unsigned int rngSeed(); + + struct RandomNumberGenerator { + using result_type = unsigned int; + + static constexpr result_type (min)() { return 0; } + static constexpr result_type (max)() { return 1000000; } + + result_type operator()( result_type n ) const; + result_type operator()() const; + + template + static void shuffle( V& vector ) { + RandomNumberGenerator rng; + std::shuffle( vector.begin(), vector.end(), rng ); + } + }; + +} + +// end catch_random_number_generator.h +#include + +namespace Catch { + + void seedRng( IConfig const& config ) { + if( config.rngSeed() != 0 ) + std::srand( config.rngSeed() ); + } + unsigned int rngSeed() { + return getCurrentContext().getConfig()->rngSeed(); + } + + RandomNumberGenerator::result_type RandomNumberGenerator::operator()( result_type n ) const { + return std::rand() % n; + } + RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const { + return std::rand() % (max)(); + } + +} +// end catch_random_number_generator.cpp +// start catch_registry_hub.cpp + +// start catch_test_case_registry_impl.h + +#include +#include +#include +#include + +namespace Catch { + + class TestCase; + struct IConfig; + + std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + + void enforceNoDuplicateTestCases( std::vector const& functions ); + + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + + class TestRegistry : public ITestCaseRegistry { + public: + virtual ~TestRegistry() = default; + + virtual void registerTest( TestCase const& testCase ); + + std::vector const& getAllTests() const override; + std::vector const& getAllTestsSorted( IConfig const& config ) const override; + + private: + std::vector m_functions; + mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder; + mutable std::vector m_sortedFunctions; + std::size_t m_unnamedCount = 0; + std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised + }; + + /////////////////////////////////////////////////////////////////////////// + + class TestInvokerAsFunction : public ITestInvoker { + void(*m_testAsFunction)(); + public: + TestInvokerAsFunction( void(*testAsFunction)() ) noexcept; + + void invoke() const override; + }; + + std::string extractClassName( StringRef const& classOrQualifiedMethodName ); + + /////////////////////////////////////////////////////////////////////////// + +} // end namespace Catch + +// end catch_test_case_registry_impl.h +// start catch_reporter_registry.h + +#include + +namespace Catch { + + class ReporterRegistry : public IReporterRegistry { + + public: + + ~ReporterRegistry() override; + + IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override; + + void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ); + void registerListener( IReporterFactoryPtr const& factory ); + + FactoryMap const& getFactories() const override; + Listeners const& getListeners() const override; + + private: + FactoryMap m_factories; + Listeners m_listeners; + }; +} + +// end catch_reporter_registry.h +// start catch_tag_alias_registry.h + +// start catch_tag_alias.h + +#include + +namespace Catch { + + struct TagAlias { + TagAlias(std::string const& _tag, SourceLineInfo _lineInfo); + + std::string tag; + SourceLineInfo lineInfo; + }; + +} // end namespace Catch + +// end catch_tag_alias.h +#include + +namespace Catch { + + class TagAliasRegistry : public ITagAliasRegistry { + public: + ~TagAliasRegistry() override; + TagAlias const* find( std::string const& alias ) const override; + std::string expandAliases( std::string const& unexpandedTestSpec ) const override; + void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ); + + private: + std::map m_registry; + }; + +} // end namespace Catch + +// end catch_tag_alias_registry.h +// start catch_startup_exception_registry.h + +#include +#include + +namespace Catch { + + class StartupExceptionRegistry { + public: + void add(std::exception_ptr const& exception) noexcept; + std::vector const& getExceptions() const noexcept; + private: + std::vector m_exceptions; + }; + +} // end namespace Catch + +// end catch_startup_exception_registry.h +namespace Catch { + + namespace { + + class RegistryHub : public IRegistryHub, public IMutableRegistryHub, + private NonCopyable { + + public: // IRegistryHub + RegistryHub() = default; + IReporterRegistry const& getReporterRegistry() const override { + return m_reporterRegistry; + } + ITestCaseRegistry const& getTestCaseRegistry() const override { + return m_testCaseRegistry; + } + IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override { + return m_exceptionTranslatorRegistry; + } + ITagAliasRegistry const& getTagAliasRegistry() const override { + return m_tagAliasRegistry; + } + StartupExceptionRegistry const& getStartupExceptionRegistry() const override { + return m_exceptionRegistry; + } + + public: // IMutableRegistryHub + void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override { + m_reporterRegistry.registerReporter( name, factory ); + } + void registerListener( IReporterFactoryPtr const& factory ) override { + m_reporterRegistry.registerListener( factory ); + } + void registerTest( TestCase const& testInfo ) override { + m_testCaseRegistry.registerTest( testInfo ); + } + void registerTranslator( const IExceptionTranslator* translator ) override { + m_exceptionTranslatorRegistry.registerTranslator( translator ); + } + void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override { + m_tagAliasRegistry.add( alias, tag, lineInfo ); + } + void registerStartupException() noexcept override { + m_exceptionRegistry.add(std::current_exception()); + } + + private: + TestRegistry m_testCaseRegistry; + ReporterRegistry m_reporterRegistry; + ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; + TagAliasRegistry m_tagAliasRegistry; + StartupExceptionRegistry m_exceptionRegistry; + }; + + // Single, global, instance + RegistryHub*& getTheRegistryHub() { + static RegistryHub* theRegistryHub = nullptr; + if( !theRegistryHub ) + theRegistryHub = new RegistryHub(); + return theRegistryHub; + } + } + + IRegistryHub& getRegistryHub() { + return *getTheRegistryHub(); + } + IMutableRegistryHub& getMutableRegistryHub() { + return *getTheRegistryHub(); + } + void cleanUp() { + delete getTheRegistryHub(); + getTheRegistryHub() = nullptr; + cleanUpContext(); + ReusableStringStream::cleanup(); + } + std::string translateActiveException() { + return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); + } + +} // end namespace Catch +// end catch_registry_hub.cpp +// start catch_reporter_registry.cpp + +namespace Catch { + + ReporterRegistry::~ReporterRegistry() = default; + + IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const { + auto it = m_factories.find( name ); + if( it == m_factories.end() ) + return nullptr; + return it->second->create( ReporterConfig( config ) ); + } + + void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) { + m_factories.emplace(name, factory); + } + void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) { + m_listeners.push_back( factory ); + } + + IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const { + return m_factories; + } + IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const { + return m_listeners; + } + +} +// end catch_reporter_registry.cpp +// start catch_result_type.cpp + +namespace Catch { + + bool isOk( ResultWas::OfType resultType ) { + return ( resultType & ResultWas::FailureBit ) == 0; + } + bool isJustInfo( int flags ) { + return flags == ResultWas::Info; + } + + ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { + return static_cast( static_cast( lhs ) | static_cast( rhs ) ); + } + + bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } + bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } + +} // end namespace Catch +// end catch_result_type.cpp +// start catch_run_context.cpp + +#include +#include +#include + +namespace Catch { + + RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter) + : m_runInfo(_config->name()), + m_context(getCurrentMutableContext()), + m_config(_config), + m_reporter(std::move(reporter)), + m_lastAssertionInfo{ StringRef(), SourceLineInfo("",0), StringRef(), ResultDisposition::Normal }, + m_includeSuccessfulResults( m_config->includeSuccessfulResults() ) + { + m_context.setRunner(this); + m_context.setConfig(m_config); + m_context.setResultCapture(this); + m_reporter->testRunStarting(m_runInfo); + } + + RunContext::~RunContext() { + m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting())); + } + + void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) { + m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount)); + } + + void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) { + m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting())); + } + + Totals RunContext::runTest(TestCase const& testCase) { + Totals prevTotals = m_totals; + + std::string redirectedCout; + std::string redirectedCerr; + + auto const& testInfo = testCase.getTestCaseInfo(); + + m_reporter->testCaseStarting(testInfo); + + m_activeTestCase = &testCase; + + ITracker& rootTracker = m_trackerContext.startRun(); + assert(rootTracker.isSectionTracker()); + static_cast(rootTracker).addInitialFilters(m_config->getSectionsToRun()); + do { + m_trackerContext.startCycle(); + m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo)); + runCurrentTest(redirectedCout, redirectedCerr); + } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting()); + + Totals deltaTotals = m_totals.delta(prevTotals); + if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) { + deltaTotals.assertions.failed++; + deltaTotals.testCases.passed--; + deltaTotals.testCases.failed++; + } + m_totals.testCases += deltaTotals.testCases; + m_reporter->testCaseEnded(TestCaseStats(testInfo, + deltaTotals, + redirectedCout, + redirectedCerr, + aborting())); + + m_activeTestCase = nullptr; + m_testCaseTracker = nullptr; + + return deltaTotals; + } + + IConfigPtr RunContext::config() const { + return m_config; + } + + IStreamingReporter& RunContext::reporter() const { + return *m_reporter; + } + + void RunContext::assertionEnded(AssertionResult const & result) { + if (result.getResultType() == ResultWas::Ok) { + m_totals.assertions.passed++; + m_lastAssertionPassed = true; + } else if (!result.isOk()) { + m_lastAssertionPassed = false; + if( m_activeTestCase->getTestCaseInfo().okToFail() ) + m_totals.assertions.failedButOk++; + else + m_totals.assertions.failed++; + } + else { + m_lastAssertionPassed = true; + } + + // We have no use for the return value (whether messages should be cleared), because messages were made scoped + // and should be let to clear themselves out. + static_cast(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); + + // Reset working state + resetAssertionInfo(); + m_lastResult = result; + } + void RunContext::resetAssertionInfo() { + m_lastAssertionInfo.macroName = StringRef(); + m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr; + } + + bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) { + ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo)); + if (!sectionTracker.isOpen()) + return false; + m_activeSections.push_back(§ionTracker); + + m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; + + m_reporter->sectionStarting(sectionInfo); + + assertions = m_totals.assertions; + + return true; + } + + bool RunContext::testForMissingAssertions(Counts& assertions) { + if (assertions.total() != 0) + return false; + if (!m_config->warnAboutMissingAssertions()) + return false; + if (m_trackerContext.currentTracker().hasChildren()) + return false; + m_totals.assertions.failed++; + assertions.failed++; + return true; + } + + void RunContext::sectionEnded(SectionEndInfo const & endInfo) { + Counts assertions = m_totals.assertions - endInfo.prevAssertions; + bool missingAssertions = testForMissingAssertions(assertions); + + if (!m_activeSections.empty()) { + m_activeSections.back()->close(); + m_activeSections.pop_back(); + } + + m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions)); + m_messages.clear(); + } + + void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) { + if (m_unfinishedSections.empty()) + m_activeSections.back()->fail(); + else + m_activeSections.back()->close(); + m_activeSections.pop_back(); + + m_unfinishedSections.push_back(endInfo); + } + void RunContext::benchmarkStarting( BenchmarkInfo const& info ) { + m_reporter->benchmarkStarting( info ); + } + void RunContext::benchmarkEnded( BenchmarkStats const& stats ) { + m_reporter->benchmarkEnded( stats ); + } + + void RunContext::pushScopedMessage(MessageInfo const & message) { + m_messages.push_back(message); + } + + void RunContext::popScopedMessage(MessageInfo const & message) { + m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end()); + } + + std::string RunContext::getCurrentTestName() const { + return m_activeTestCase + ? m_activeTestCase->getTestCaseInfo().name + : std::string(); + } + + const AssertionResult * RunContext::getLastResult() const { + return &(*m_lastResult); + } + + void RunContext::exceptionEarlyReported() { + m_shouldReportUnexpected = false; + } + + void RunContext::handleFatalErrorCondition( StringRef message ) { + // First notify reporter that bad things happened + m_reporter->fatalErrorEncountered(message); + + // Don't rebuild the result -- the stringification itself can cause more fatal errors + // Instead, fake a result data. + AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } ); + tempResult.message = message; + AssertionResult result(m_lastAssertionInfo, tempResult); + + assertionEnded(result); + + handleUnfinishedSections(); + + // Recreate section for test case (as we will lose the one that was in scope) + auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description); + + Counts assertions; + assertions.failed = 1; + SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false); + m_reporter->sectionEnded(testCaseSectionStats); + + auto const& testInfo = m_activeTestCase->getTestCaseInfo(); + + Totals deltaTotals; + deltaTotals.testCases.failed = 1; + deltaTotals.assertions.failed = 1; + m_reporter->testCaseEnded(TestCaseStats(testInfo, + deltaTotals, + std::string(), + std::string(), + false)); + m_totals.testCases.failed++; + testGroupEnded(std::string(), m_totals, 1, 1); + m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false)); + } + + bool RunContext::lastAssertionPassed() { + return m_lastAssertionPassed; + } + + void RunContext::assertionPassed() { + m_lastAssertionPassed = true; + ++m_totals.assertions.passed; + resetAssertionInfo(); + } + + bool RunContext::aborting() const { + return m_totals.assertions.failed == static_cast(m_config->abortAfter()); + } + + void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) { + auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description); + m_reporter->sectionStarting(testCaseSection); + Counts prevAssertions = m_totals.assertions; + double duration = 0; + m_shouldReportUnexpected = true; + m_lastAssertionInfo = { "TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal }; + + seedRng(*m_config); + + Timer timer; + try { + if (m_reporter->getPreferences().shouldRedirectStdOut) { +#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) + RedirectedStdOut redirectedStdOut; + RedirectedStdErr redirectedStdErr; + + timer.start(); + invokeActiveTestCase(); + redirectedCout += redirectedStdOut.str(); + redirectedCerr += redirectedStdErr.str(); +#else + OutputRedirect r(redirectedCout, redirectedCerr); + timer.start(); + invokeActiveTestCase(); +#endif + } else { + timer.start(); + invokeActiveTestCase(); + } + duration = timer.getElapsedSeconds(); + } catch (TestFailureException&) { + // This just means the test was aborted due to failure + } catch (...) { + // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions + // are reported without translation at the point of origin. + if( m_shouldReportUnexpected ) { + AssertionReaction dummyReaction; + handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction ); + } + } + Counts assertions = m_totals.assertions - prevAssertions; + bool missingAssertions = testForMissingAssertions(assertions); + + m_testCaseTracker->close(); + handleUnfinishedSections(); + m_messages.clear(); + + SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); + m_reporter->sectionEnded(testCaseSectionStats); + } + + void RunContext::invokeActiveTestCase() { + FatalConditionHandler fatalConditionHandler; // Handle signals + m_activeTestCase->invoke(); + fatalConditionHandler.reset(); + } + + void RunContext::handleUnfinishedSections() { + // If sections ended prematurely due to an exception we stored their + // infos here so we can tear them down outside the unwind process. + for (auto it = m_unfinishedSections.rbegin(), + itEnd = m_unfinishedSections.rend(); + it != itEnd; + ++it) + sectionEnded(*it); + m_unfinishedSections.clear(); + } + + void RunContext::handleExpr( + AssertionInfo const& info, + ITransientExpression const& expr, + AssertionReaction& reaction + ) { + m_reporter->assertionStarting( info ); + + bool negated = isFalseTest( info.resultDisposition ); + bool result = expr.getResult() != negated; + + if( result ) { + if (!m_includeSuccessfulResults) { + assertionPassed(); + } + else { + reportExpr(info, ResultWas::Ok, &expr, negated); + } + } + else { + reportExpr(info, ResultWas::ExpressionFailed, &expr, negated ); + populateReaction( reaction ); + } + } + void RunContext::reportExpr( + AssertionInfo const &info, + ResultWas::OfType resultType, + ITransientExpression const *expr, + bool negated ) { + + m_lastAssertionInfo = info; + AssertionResultData data( resultType, LazyExpression( negated ) ); + + AssertionResult assertionResult{ info, data }; + assertionResult.m_resultData.lazyExpression.m_transientExpression = expr; + + assertionEnded( assertionResult ); + } + + void RunContext::handleMessage( + AssertionInfo const& info, + ResultWas::OfType resultType, + StringRef const& message, + AssertionReaction& reaction + ) { + m_reporter->assertionStarting( info ); + + m_lastAssertionInfo = info; + + AssertionResultData data( resultType, LazyExpression( false ) ); + data.message = message; + AssertionResult assertionResult{ m_lastAssertionInfo, data }; + assertionEnded( assertionResult ); + if( !assertionResult.isOk() ) + populateReaction( reaction ); + } + void RunContext::handleUnexpectedExceptionNotThrown( + AssertionInfo const& info, + AssertionReaction& reaction + ) { + handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction); + } + + void RunContext::handleUnexpectedInflightException( + AssertionInfo const& info, + std::string const& message, + AssertionReaction& reaction + ) { + m_lastAssertionInfo = info; + + AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); + data.message = message; + AssertionResult assertionResult{ info, data }; + assertionEnded( assertionResult ); + populateReaction( reaction ); + } + + void RunContext::populateReaction( AssertionReaction& reaction ) { + reaction.shouldDebugBreak = m_config->shouldDebugBreak(); + reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal); + } + + void RunContext::handleIncomplete( + AssertionInfo const& info + ) { + m_lastAssertionInfo = info; + + AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) ); + data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; + AssertionResult assertionResult{ info, data }; + assertionEnded( assertionResult ); + } + void RunContext::handleNonExpr( + AssertionInfo const &info, + ResultWas::OfType resultType, + AssertionReaction &reaction + ) { + m_lastAssertionInfo = info; + + AssertionResultData data( resultType, LazyExpression( false ) ); + AssertionResult assertionResult{ info, data }; + assertionEnded( assertionResult ); + + if( !assertionResult.isOk() ) + populateReaction( reaction ); + } + + IResultCapture& getResultCapture() { + if (auto* capture = getCurrentContext().getResultCapture()) + return *capture; + else + CATCH_INTERNAL_ERROR("No result capture instance"); + } +} +// end catch_run_context.cpp +// start catch_section.cpp + +namespace Catch { + + Section::Section( SectionInfo const& info ) + : m_info( info ), + m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) + { + m_timer.start(); + } + + Section::~Section() { + if( m_sectionIncluded ) { + SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); + if( uncaught_exceptions() ) + getResultCapture().sectionEndedEarly( endInfo ); + else + getResultCapture().sectionEnded( endInfo ); + } + } + + // This indicates whether the section should be executed or not + Section::operator bool() const { + return m_sectionIncluded; + } + +} // end namespace Catch +// end catch_section.cpp +// start catch_section_info.cpp + +namespace Catch { + + SectionInfo::SectionInfo + ( SourceLineInfo const& _lineInfo, + std::string const& _name, + std::string const& _description ) + : name( _name ), + description( _description ), + lineInfo( _lineInfo ) + {} + + SectionEndInfo::SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ) + : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) + {} + +} // end namespace Catch +// end catch_section_info.cpp +// start catch_session.cpp + +// start catch_session.h + +#include + +namespace Catch { + + class Session : NonCopyable { + public: + + Session(); + ~Session() override; + + void showHelp() const; + void libIdentify(); + + int applyCommandLine( int argc, char const * const * argv ); + + void useConfigData( ConfigData const& configData ); + + int run( int argc, char* argv[] ); + #if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) + int run( int argc, wchar_t* const argv[] ); + #endif + int run(); + + clara::Parser const& cli() const; + void cli( clara::Parser const& newParser ); + ConfigData& configData(); + Config& config(); + private: + int runInternal(); + + clara::Parser m_cli; + ConfigData m_configData; + std::shared_ptr m_config; + bool m_startupExceptions = false; + }; + +} // end namespace Catch + +// end catch_session.h +// start catch_version.h + +#include + +namespace Catch { + + // Versioning information + struct Version { + Version( Version const& ) = delete; + Version& operator=( Version const& ) = delete; + Version( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + char const * const _branchName, + unsigned int _buildNumber ); + + unsigned int const majorVersion; + unsigned int const minorVersion; + unsigned int const patchNumber; + + // buildNumber is only used if branchName is not null + char const * const branchName; + unsigned int const buildNumber; + + friend std::ostream& operator << ( std::ostream& os, Version const& version ); + }; + + Version const& libraryVersion(); +} + +// end catch_version.h +#include +#include + +namespace Catch { + + namespace { + const int MaxExitCode = 255; + + IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) { + auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config); + CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'"); + + return reporter; + } + + IStreamingReporterPtr makeReporter(std::shared_ptr const& config) { + if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) { + return createReporter(config->getReporterName(), config); + } + + auto multi = std::unique_ptr(new ListeningReporter); + + auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners(); + for (auto const& listener : listeners) { + multi->addListener(listener->create(Catch::ReporterConfig(config))); + } + multi->addReporter(createReporter(config->getReporterName(), config)); + return std::move(multi); + } + + Catch::Totals runTests(std::shared_ptr const& config) { + // FixMe: Add listeners in order first, then add reporters. + + auto reporter = makeReporter(config); + + RunContext context(config, std::move(reporter)); + + Totals totals; + + context.testGroupStarting(config->name(), 1, 1); + + TestSpec testSpec = config->testSpec(); + + auto const& allTestCases = getAllTestCasesSorted(*config); + for (auto const& testCase : allTestCases) { + if (!context.aborting() && matchTest(testCase, testSpec, *config)) + totals += context.runTest(testCase); + else + context.reporter().skipTest(testCase); + } + + if (config->warnAboutNoTests() && totals.testCases.total() == 0) { + ReusableStringStream testConfig; + + bool first = true; + for (const auto& input : config->getTestsOrTags()) { + if (!first) { testConfig << ' '; } + first = false; + testConfig << input; + } + + context.reporter().noMatchingTestCases(testConfig.str()); + totals.error = -1; + } + + context.testGroupEnded(config->name(), totals, 1, 1); + return totals; + } + + void applyFilenamesAsTags(Catch::IConfig const& config) { + auto& tests = const_cast&>(getAllTestCasesSorted(config)); + for (auto& testCase : tests) { + auto tags = testCase.tags; + + std::string filename = testCase.lineInfo.file; + auto lastSlash = filename.find_last_of("\\/"); + if (lastSlash != std::string::npos) { + filename.erase(0, lastSlash); + filename[0] = '#'; + } + + auto lastDot = filename.find_last_of('.'); + if (lastDot != std::string::npos) { + filename.erase(lastDot); + } + + tags.push_back(std::move(filename)); + setTags(testCase, tags); + } + } + + } // anon namespace + + Session::Session() { + static bool alreadyInstantiated = false; + if( alreadyInstantiated ) { + try { CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); } + catch(...) { getMutableRegistryHub().registerStartupException(); } + } + + const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions(); + if ( !exceptions.empty() ) { + m_startupExceptions = true; + Colour colourGuard( Colour::Red ); + Catch::cerr() << "Errors occurred during startup!" << '\n'; + // iterate over all exceptions and notify user + for ( const auto& ex_ptr : exceptions ) { + try { + std::rethrow_exception(ex_ptr); + } catch ( std::exception const& ex ) { + Catch::cerr() << Column( ex.what() ).indent(2) << '\n'; + } + } + } + + alreadyInstantiated = true; + m_cli = makeCommandLineParser( m_configData ); + } + Session::~Session() { + Catch::cleanUp(); + } + + void Session::showHelp() const { + Catch::cout() + << "\nCatch v" << libraryVersion() << "\n" + << m_cli << std::endl + << "For more detailed usage please see the project docs\n" << std::endl; + } + void Session::libIdentify() { + Catch::cout() + << std::left << std::setw(16) << "description: " << "A Catch test executable\n" + << std::left << std::setw(16) << "category: " << "testframework\n" + << std::left << std::setw(16) << "framework: " << "Catch Test\n" + << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; + } + + int Session::applyCommandLine( int argc, char const * const * argv ) { + if( m_startupExceptions ) + return 1; + + auto result = m_cli.parse( clara::Args( argc, argv ) ); + if( !result ) { + Catch::cerr() + << Colour( Colour::Red ) + << "\nError(s) in input:\n" + << Column( result.errorMessage() ).indent( 2 ) + << "\n\n"; + Catch::cerr() << "Run with -? for usage\n" << std::endl; + return MaxExitCode; + } + + if( m_configData.showHelp ) + showHelp(); + if( m_configData.libIdentify ) + libIdentify(); + m_config.reset(); + return 0; + } + + void Session::useConfigData( ConfigData const& configData ) { + m_configData = configData; + m_config.reset(); + } + + int Session::run( int argc, char* argv[] ) { + if( m_startupExceptions ) + return 1; + int returnCode = applyCommandLine( argc, argv ); + if( returnCode == 0 ) + returnCode = run(); + return returnCode; + } + +#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) + int Session::run( int argc, wchar_t* const argv[] ) { + + char **utf8Argv = new char *[ argc ]; + + for ( int i = 0; i < argc; ++i ) { + int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL ); + + utf8Argv[ i ] = new char[ bufSize ]; + + WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL ); + } + + int returnCode = run( argc, utf8Argv ); + + for ( int i = 0; i < argc; ++i ) + delete [] utf8Argv[ i ]; + + delete [] utf8Argv; + + return returnCode; + } +#endif + int Session::run() { + if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) { + Catch::cout() << "...waiting for enter/ return before starting" << std::endl; + static_cast(std::getchar()); + } + int exitCode = runInternal(); + if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) { + Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl; + static_cast(std::getchar()); + } + return exitCode; + } + + clara::Parser const& Session::cli() const { + return m_cli; + } + void Session::cli( clara::Parser const& newParser ) { + m_cli = newParser; + } + ConfigData& Session::configData() { + return m_configData; + } + Config& Session::config() { + if( !m_config ) + m_config = std::make_shared( m_configData ); + return *m_config; + } + + int Session::runInternal() { + if( m_startupExceptions ) + return 1; + + if( m_configData.showHelp || m_configData.libIdentify ) + return 0; + + try + { + config(); // Force config to be constructed + + seedRng( *m_config ); + + if( m_configData.filenamesAsTags ) + applyFilenamesAsTags( *m_config ); + + // Handle list request + if( Option listed = list( config() ) ) + return static_cast( *listed ); + + auto totals = runTests( m_config ); + // Note that on unices only the lower 8 bits are usually used, clamping + // the return value to 255 prevents false negative when some multiple + // of 256 tests has failed + return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast(totals.assertions.failed))); + } + catch( std::exception& ex ) { + Catch::cerr() << ex.what() << std::endl; + return MaxExitCode; + } + } + +} // end namespace Catch +// end catch_session.cpp +// start catch_startup_exception_registry.cpp + +namespace Catch { + void StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept { + try { + m_exceptions.push_back(exception); + } + catch(...) { + // If we run out of memory during start-up there's really not a lot more we can do about it + std::terminate(); + } + } + + std::vector const& StartupExceptionRegistry::getExceptions() const noexcept { + return m_exceptions; + } + +} // end namespace Catch +// end catch_startup_exception_registry.cpp +// start catch_stream.cpp + +#include +#include +#include +#include +#include +#include + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +namespace Catch { + + Catch::IStream::~IStream() = default; + + namespace detail { namespace { + template + class StreamBufImpl : public std::streambuf { + char data[bufferSize]; + WriterF m_writer; + + public: + StreamBufImpl() { + setp( data, data + sizeof(data) ); + } + + ~StreamBufImpl() noexcept { + StreamBufImpl::sync(); + } + + private: + int overflow( int c ) override { + sync(); + + if( c != EOF ) { + if( pbase() == epptr() ) + m_writer( std::string( 1, static_cast( c ) ) ); + else + sputc( static_cast( c ) ); + } + return 0; + } + + int sync() override { + if( pbase() != pptr() ) { + m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) ); + setp( pbase(), epptr() ); + } + return 0; + } + }; + + /////////////////////////////////////////////////////////////////////////// + + struct OutputDebugWriter { + + void operator()( std::string const&str ) { + writeToDebugConsole( str ); + } + }; + + /////////////////////////////////////////////////////////////////////////// + + class FileStream : public IStream { + mutable std::ofstream m_ofs; + public: + FileStream( StringRef filename ) { + m_ofs.open( filename.c_str() ); + CATCH_ENFORCE( !m_ofs.fail(), "Unable to open file: '" << filename << "'" ); + } + ~FileStream() override = default; + public: // IStream + std::ostream& stream() const override { + return m_ofs; + } + }; + + /////////////////////////////////////////////////////////////////////////// + + class CoutStream : public IStream { + mutable std::ostream m_os; + public: + // Store the streambuf from cout up-front because + // cout may get redirected when running tests + CoutStream() : m_os( Catch::cout().rdbuf() ) {} + ~CoutStream() override = default; + + public: // IStream + std::ostream& stream() const override { return m_os; } + }; + + /////////////////////////////////////////////////////////////////////////// + + class DebugOutStream : public IStream { + std::unique_ptr> m_streamBuf; + mutable std::ostream m_os; + public: + DebugOutStream() + : m_streamBuf( new StreamBufImpl() ), + m_os( m_streamBuf.get() ) + {} + + ~DebugOutStream() override = default; + + public: // IStream + std::ostream& stream() const override { return m_os; } + }; + + }} // namespace anon::detail + + /////////////////////////////////////////////////////////////////////////// + + auto makeStream( StringRef const &filename ) -> IStream const* { + if( filename.empty() ) + return new detail::CoutStream(); + else if( filename[0] == '%' ) { + if( filename == "%debug" ) + return new detail::DebugOutStream(); + else + CATCH_ERROR( "Unrecognised stream: '" << filename << "'" ); + } + else + return new detail::FileStream( filename ); + } + + // This class encapsulates the idea of a pool of ostringstreams that can be reused. + struct StringStreams { + std::vector> m_streams; + std::vector m_unused; + std::ostringstream m_referenceStream; // Used for copy state/ flags from + static StringStreams* s_instance; + + auto add() -> std::size_t { + if( m_unused.empty() ) { + m_streams.push_back( std::unique_ptr( new std::ostringstream ) ); + return m_streams.size()-1; + } + else { + auto index = m_unused.back(); + m_unused.pop_back(); + return index; + } + } + + void release( std::size_t index ) { + m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state + m_unused.push_back(index); + } + + // !TBD: put in TLS + static auto instance() -> StringStreams& { + if( !s_instance ) + s_instance = new StringStreams(); + return *s_instance; + } + static void cleanup() { + delete s_instance; + s_instance = nullptr; + } + }; + + StringStreams* StringStreams::s_instance = nullptr; + + void ReusableStringStream::cleanup() { + StringStreams::cleanup(); + } + + ReusableStringStream::ReusableStringStream() + : m_index( StringStreams::instance().add() ), + m_oss( StringStreams::instance().m_streams[m_index].get() ) + {} + + ReusableStringStream::~ReusableStringStream() { + static_cast( m_oss )->str(""); + m_oss->clear(); + StringStreams::instance().release( m_index ); + } + + auto ReusableStringStream::str() const -> std::string { + return static_cast( m_oss )->str(); + } + + /////////////////////////////////////////////////////////////////////////// + +#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions + std::ostream& cout() { return std::cout; } + std::ostream& cerr() { return std::cerr; } + std::ostream& clog() { return std::clog; } +#endif +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +// end catch_stream.cpp +// start catch_string_manip.cpp + +#include +#include +#include +#include + +namespace Catch { + + bool startsWith( std::string const& s, std::string const& prefix ) { + return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); + } + bool startsWith( std::string const& s, char prefix ) { + return !s.empty() && s[0] == prefix; + } + bool endsWith( std::string const& s, std::string const& suffix ) { + return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); + } + bool endsWith( std::string const& s, char suffix ) { + return !s.empty() && s[s.size()-1] == suffix; + } + bool contains( std::string const& s, std::string const& infix ) { + return s.find( infix ) != std::string::npos; + } + char toLowerCh(char c) { + return static_cast( std::tolower( c ) ); + } + void toLowerInPlace( std::string& s ) { + std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); + } + std::string toLower( std::string const& s ) { + std::string lc = s; + toLowerInPlace( lc ); + return lc; + } + std::string trim( std::string const& str ) { + static char const* whitespaceChars = "\n\r\t "; + std::string::size_type start = str.find_first_not_of( whitespaceChars ); + std::string::size_type end = str.find_last_not_of( whitespaceChars ); + + return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string(); + } + + bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { + bool replaced = false; + std::size_t i = str.find( replaceThis ); + while( i != std::string::npos ) { + replaced = true; + str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); + if( i < str.size()-withThis.size() ) + i = str.find( replaceThis, i+withThis.size() ); + else + i = std::string::npos; + } + return replaced; + } + + pluralise::pluralise( std::size_t count, std::string const& label ) + : m_count( count ), + m_label( label ) + {} + + std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { + os << pluraliser.m_count << ' ' << pluraliser.m_label; + if( pluraliser.m_count != 1 ) + os << 's'; + return os; + } + +} +// end catch_string_manip.cpp +// start catch_stringref.cpp + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +#include +#include +#include + +namespace { + const uint32_t byte_2_lead = 0xC0; + const uint32_t byte_3_lead = 0xE0; + const uint32_t byte_4_lead = 0xF0; +} + +namespace Catch { + StringRef::StringRef( char const* rawChars ) noexcept + : StringRef( rawChars, static_cast(std::strlen(rawChars) ) ) + {} + + StringRef::operator std::string() const { + return std::string( m_start, m_size ); + } + + void StringRef::swap( StringRef& other ) noexcept { + std::swap( m_start, other.m_start ); + std::swap( m_size, other.m_size ); + std::swap( m_data, other.m_data ); + } + + auto StringRef::c_str() const -> char const* { + if( isSubstring() ) + const_cast( this )->takeOwnership(); + return m_start; + } + auto StringRef::currentData() const noexcept -> char const* { + return m_start; + } + + auto StringRef::isOwned() const noexcept -> bool { + return m_data != nullptr; + } + auto StringRef::isSubstring() const noexcept -> bool { + return m_start[m_size] != '\0'; + } + + void StringRef::takeOwnership() { + if( !isOwned() ) { + m_data = new char[m_size+1]; + memcpy( m_data, m_start, m_size ); + m_data[m_size] = '\0'; + m_start = m_data; + } + } + auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef { + if( start < m_size ) + return StringRef( m_start+start, size ); + else + return StringRef(); + } + auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool { + return + size() == other.size() && + (std::strncmp( m_start, other.m_start, size() ) == 0); + } + auto StringRef::operator != ( StringRef const& other ) const noexcept -> bool { + return !operator==( other ); + } + + auto StringRef::operator[](size_type index) const noexcept -> char { + return m_start[index]; + } + + auto StringRef::numberOfCharacters() const noexcept -> size_type { + size_type noChars = m_size; + // Make adjustments for uft encodings + for( size_type i=0; i < m_size; ++i ) { + char c = m_start[i]; + if( ( c & byte_2_lead ) == byte_2_lead ) { + noChars--; + if (( c & byte_3_lead ) == byte_3_lead ) + noChars--; + if( ( c & byte_4_lead ) == byte_4_lead ) + noChars--; + } + } + return noChars; + } + + auto operator + ( StringRef const& lhs, StringRef const& rhs ) -> std::string { + std::string str; + str.reserve( lhs.size() + rhs.size() ); + str += lhs; + str += rhs; + return str; + } + auto operator + ( StringRef const& lhs, const char* rhs ) -> std::string { + return std::string( lhs ) + std::string( rhs ); + } + auto operator + ( char const* lhs, StringRef const& rhs ) -> std::string { + return std::string( lhs ) + std::string( rhs ); + } + + auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& { + return os.write(str.currentData(), str.size()); + } + + auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& { + lhs.append(rhs.currentData(), rhs.size()); + return lhs; + } + +} // namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +// end catch_stringref.cpp +// start catch_tag_alias.cpp + +namespace Catch { + TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {} +} +// end catch_tag_alias.cpp +// start catch_tag_alias_autoregistrar.cpp + +namespace Catch { + + RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) { + try { + getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo); + } catch (...) { + // Do not throw when constructing global objects, instead register the exception to be processed later + getMutableRegistryHub().registerStartupException(); + } + } + +} +// end catch_tag_alias_autoregistrar.cpp +// start catch_tag_alias_registry.cpp + +#include + +namespace Catch { + + TagAliasRegistry::~TagAliasRegistry() {} + + TagAlias const* TagAliasRegistry::find( std::string const& alias ) const { + auto it = m_registry.find( alias ); + if( it != m_registry.end() ) + return &(it->second); + else + return nullptr; + } + + std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { + std::string expandedTestSpec = unexpandedTestSpec; + for( auto const& registryKvp : m_registry ) { + std::size_t pos = expandedTestSpec.find( registryKvp.first ); + if( pos != std::string::npos ) { + expandedTestSpec = expandedTestSpec.substr( 0, pos ) + + registryKvp.second.tag + + expandedTestSpec.substr( pos + registryKvp.first.size() ); + } + } + return expandedTestSpec; + } + + void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) { + CATCH_ENFORCE( startsWith(alias, "[@") && endsWith(alias, ']'), + "error: tag alias, '" << alias << "' is not of the form [@alias name].\n" << lineInfo ); + + CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second, + "error: tag alias, '" << alias << "' already registered.\n" + << "\tFirst seen at: " << find(alias)->lineInfo << "\n" + << "\tRedefined at: " << lineInfo ); + } + + ITagAliasRegistry::~ITagAliasRegistry() {} + + ITagAliasRegistry const& ITagAliasRegistry::get() { + return getRegistryHub().getTagAliasRegistry(); + } + +} // end namespace Catch +// end catch_tag_alias_registry.cpp +// start catch_test_case_info.cpp + +#include +#include +#include +#include + +namespace Catch { + + TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { + if( startsWith( tag, '.' ) || + tag == "!hide" ) + return TestCaseInfo::IsHidden; + else if( tag == "!throws" ) + return TestCaseInfo::Throws; + else if( tag == "!shouldfail" ) + return TestCaseInfo::ShouldFail; + else if( tag == "!mayfail" ) + return TestCaseInfo::MayFail; + else if( tag == "!nonportable" ) + return TestCaseInfo::NonPortable; + else if( tag == "!benchmark" ) + return static_cast( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden ); + else + return TestCaseInfo::None; + } + bool isReservedTag( std::string const& tag ) { + return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast(tag[0]) ); + } + void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { + CATCH_ENFORCE( !isReservedTag(tag), + "Tag name: [" << tag << "] is not allowed.\n" + << "Tag names starting with non alpha-numeric characters are reserved\n" + << _lineInfo ); + } + + TestCase makeTestCase( ITestInvoker* _testCase, + std::string const& _className, + NameAndTags const& nameAndTags, + SourceLineInfo const& _lineInfo ) + { + bool isHidden = false; + + // Parse out tags + std::vector tags; + std::string desc, tag; + bool inTag = false; + std::string _descOrTags = nameAndTags.tags; + for (char c : _descOrTags) { + if( !inTag ) { + if( c == '[' ) + inTag = true; + else + desc += c; + } + else { + if( c == ']' ) { + TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); + if( ( prop & TestCaseInfo::IsHidden ) != 0 ) + isHidden = true; + else if( prop == TestCaseInfo::None ) + enforceNotReservedTag( tag, _lineInfo ); + + tags.push_back( tag ); + tag.clear(); + inTag = false; + } + else + tag += c; + } + } + if( isHidden ) { + tags.push_back( "." ); + } + + TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo ); + return TestCase( _testCase, std::move(info) ); + } + + void setTags( TestCaseInfo& testCaseInfo, std::vector tags ) { + std::sort(begin(tags), end(tags)); + tags.erase(std::unique(begin(tags), end(tags)), end(tags)); + testCaseInfo.lcaseTags.clear(); + + for( auto const& tag : tags ) { + std::string lcaseTag = toLower( tag ); + testCaseInfo.properties = static_cast( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); + testCaseInfo.lcaseTags.push_back( lcaseTag ); + } + testCaseInfo.tags = std::move(tags); + } + + TestCaseInfo::TestCaseInfo( std::string const& _name, + std::string const& _className, + std::string const& _description, + std::vector const& _tags, + SourceLineInfo const& _lineInfo ) + : name( _name ), + className( _className ), + description( _description ), + lineInfo( _lineInfo ), + properties( None ) + { + setTags( *this, _tags ); + } + + bool TestCaseInfo::isHidden() const { + return ( properties & IsHidden ) != 0; + } + bool TestCaseInfo::throws() const { + return ( properties & Throws ) != 0; + } + bool TestCaseInfo::okToFail() const { + return ( properties & (ShouldFail | MayFail ) ) != 0; + } + bool TestCaseInfo::expectedToFail() const { + return ( properties & (ShouldFail ) ) != 0; + } + + std::string TestCaseInfo::tagsAsString() const { + std::string ret; + // '[' and ']' per tag + std::size_t full_size = 2 * tags.size(); + for (const auto& tag : tags) { + full_size += tag.size(); + } + ret.reserve(full_size); + for (const auto& tag : tags) { + ret.push_back('['); + ret.append(tag); + ret.push_back(']'); + } + + return ret; + } + + TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {} + + TestCase TestCase::withName( std::string const& _newName ) const { + TestCase other( *this ); + other.name = _newName; + return other; + } + + void TestCase::invoke() const { + test->invoke(); + } + + bool TestCase::operator == ( TestCase const& other ) const { + return test.get() == other.test.get() && + name == other.name && + className == other.className; + } + + bool TestCase::operator < ( TestCase const& other ) const { + return name < other.name; + } + + TestCaseInfo const& TestCase::getTestCaseInfo() const + { + return *this; + } + +} // end namespace Catch +// end catch_test_case_info.cpp +// start catch_test_case_registry_impl.cpp + +#include + +namespace Catch { + + std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) { + + std::vector sorted = unsortedTestCases; + + switch( config.runOrder() ) { + case RunTests::InLexicographicalOrder: + std::sort( sorted.begin(), sorted.end() ); + break; + case RunTests::InRandomOrder: + seedRng( config ); + RandomNumberGenerator::shuffle( sorted ); + break; + case RunTests::InDeclarationOrder: + // already in declaration order + break; + } + return sorted; + } + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { + return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); + } + + void enforceNoDuplicateTestCases( std::vector const& functions ) { + std::set seenFunctions; + for( auto const& function : functions ) { + auto prev = seenFunctions.insert( function ); + CATCH_ENFORCE( prev.second, + "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n" + << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n" + << "\tRedefined at " << function.getTestCaseInfo().lineInfo ); + } + } + + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) { + std::vector filtered; + filtered.reserve( testCases.size() ); + for( auto const& testCase : testCases ) + if( matchTest( testCase, testSpec, config ) ) + filtered.push_back( testCase ); + return filtered; + } + std::vector const& getAllTestCasesSorted( IConfig const& config ) { + return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); + } + + void TestRegistry::registerTest( TestCase const& testCase ) { + std::string name = testCase.getTestCaseInfo().name; + if( name.empty() ) { + ReusableStringStream rss; + rss << "Anonymous test case " << ++m_unnamedCount; + return registerTest( testCase.withName( rss.str() ) ); + } + m_functions.push_back( testCase ); + } + + std::vector const& TestRegistry::getAllTests() const { + return m_functions; + } + std::vector const& TestRegistry::getAllTestsSorted( IConfig const& config ) const { + if( m_sortedFunctions.empty() ) + enforceNoDuplicateTestCases( m_functions ); + + if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { + m_sortedFunctions = sortTests( config, m_functions ); + m_currentSortOrder = config.runOrder(); + } + return m_sortedFunctions; + } + + /////////////////////////////////////////////////////////////////////////// + TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {} + + void TestInvokerAsFunction::invoke() const { + m_testAsFunction(); + } + + std::string extractClassName( StringRef const& classOrQualifiedMethodName ) { + std::string className = classOrQualifiedMethodName; + if( startsWith( className, '&' ) ) + { + std::size_t lastColons = className.rfind( "::" ); + std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); + if( penultimateColons == std::string::npos ) + penultimateColons = 1; + className = className.substr( penultimateColons, lastColons-penultimateColons ); + } + return className; + } + +} // end namespace Catch +// end catch_test_case_registry_impl.cpp +// start catch_test_case_tracker.cpp + +#include +#include +#include +#include +#include + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +namespace Catch { +namespace TestCaseTracking { + + NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location ) + : name( _name ), + location( _location ) + {} + + ITracker::~ITracker() = default; + + TrackerContext& TrackerContext::instance() { + static TrackerContext s_instance; + return s_instance; + } + + ITracker& TrackerContext::startRun() { + m_rootTracker = std::make_shared( NameAndLocation( "{root}", CATCH_INTERNAL_LINEINFO ), *this, nullptr ); + m_currentTracker = nullptr; + m_runState = Executing; + return *m_rootTracker; + } + + void TrackerContext::endRun() { + m_rootTracker.reset(); + m_currentTracker = nullptr; + m_runState = NotStarted; + } + + void TrackerContext::startCycle() { + m_currentTracker = m_rootTracker.get(); + m_runState = Executing; + } + void TrackerContext::completeCycle() { + m_runState = CompletedCycle; + } + + bool TrackerContext::completedCycle() const { + return m_runState == CompletedCycle; + } + ITracker& TrackerContext::currentTracker() { + return *m_currentTracker; + } + void TrackerContext::setCurrentTracker( ITracker* tracker ) { + m_currentTracker = tracker; + } + + TrackerBase::TrackerHasName::TrackerHasName( NameAndLocation const& nameAndLocation ) : m_nameAndLocation( nameAndLocation ) {} + bool TrackerBase::TrackerHasName::operator ()( ITrackerPtr const& tracker ) const { + return + tracker->nameAndLocation().name == m_nameAndLocation.name && + tracker->nameAndLocation().location == m_nameAndLocation.location; + } + + TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : m_nameAndLocation( nameAndLocation ), + m_ctx( ctx ), + m_parent( parent ) + {} + + NameAndLocation const& TrackerBase::nameAndLocation() const { + return m_nameAndLocation; + } + bool TrackerBase::isComplete() const { + return m_runState == CompletedSuccessfully || m_runState == Failed; + } + bool TrackerBase::isSuccessfullyCompleted() const { + return m_runState == CompletedSuccessfully; + } + bool TrackerBase::isOpen() const { + return m_runState != NotStarted && !isComplete(); + } + bool TrackerBase::hasChildren() const { + return !m_children.empty(); + } + + void TrackerBase::addChild( ITrackerPtr const& child ) { + m_children.push_back( child ); + } + + ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) { + auto it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( nameAndLocation ) ); + return( it != m_children.end() ) + ? *it + : nullptr; + } + ITracker& TrackerBase::parent() { + assert( m_parent ); // Should always be non-null except for root + return *m_parent; + } + + void TrackerBase::openChild() { + if( m_runState != ExecutingChildren ) { + m_runState = ExecutingChildren; + if( m_parent ) + m_parent->openChild(); + } + } + + bool TrackerBase::isSectionTracker() const { return false; } + bool TrackerBase::isIndexTracker() const { return false; } + + void TrackerBase::open() { + m_runState = Executing; + moveToThis(); + if( m_parent ) + m_parent->openChild(); + } + + void TrackerBase::close() { + + // Close any still open children (e.g. generators) + while( &m_ctx.currentTracker() != this ) + m_ctx.currentTracker().close(); + + switch( m_runState ) { + case NeedsAnotherRun: + break; + + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if( m_children.empty() || m_children.back()->isComplete() ) + m_runState = CompletedSuccessfully; + break; + + case NotStarted: + case CompletedSuccessfully: + case Failed: + CATCH_INTERNAL_ERROR( "Illogical state: " << m_runState ); + + default: + CATCH_INTERNAL_ERROR( "Unknown state: " << m_runState ); + } + moveToParent(); + m_ctx.completeCycle(); + } + void TrackerBase::fail() { + m_runState = Failed; + if( m_parent ) + m_parent->markAsNeedingAnotherRun(); + moveToParent(); + m_ctx.completeCycle(); + } + void TrackerBase::markAsNeedingAnotherRun() { + m_runState = NeedsAnotherRun; + } + + void TrackerBase::moveToParent() { + assert( m_parent ); + m_ctx.setCurrentTracker( m_parent ); + } + void TrackerBase::moveToThis() { + m_ctx.setCurrentTracker( this ); + } + + SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ) + : TrackerBase( nameAndLocation, ctx, parent ) + { + if( parent ) { + while( !parent->isSectionTracker() ) + parent = &parent->parent(); + + SectionTracker& parentSection = static_cast( *parent ); + addNextFilters( parentSection.m_filters ); + } + } + + bool SectionTracker::isSectionTracker() const { return true; } + + SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) { + std::shared_ptr section; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isSectionTracker() ); + section = std::static_pointer_cast( childTracker ); + } + else { + section = std::make_shared( nameAndLocation, ctx, ¤tTracker ); + currentTracker.addChild( section ); + } + if( !ctx.completedCycle() ) + section->tryOpen(); + return *section; + } + + void SectionTracker::tryOpen() { + if( !isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name ) ) + open(); + } + + void SectionTracker::addInitialFilters( std::vector const& filters ) { + if( !filters.empty() ) { + m_filters.push_back(""); // Root - should never be consulted + m_filters.push_back(""); // Test Case - not a section filter + m_filters.insert( m_filters.end(), filters.begin(), filters.end() ); + } + } + void SectionTracker::addNextFilters( std::vector const& filters ) { + if( filters.size() > 1 ) + m_filters.insert( m_filters.end(), ++filters.begin(), filters.end() ); + } + + IndexTracker::IndexTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent, int size ) + : TrackerBase( nameAndLocation, ctx, parent ), + m_size( size ) + {} + + bool IndexTracker::isIndexTracker() const { return true; } + + IndexTracker& IndexTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation, int size ) { + std::shared_ptr tracker; + + ITracker& currentTracker = ctx.currentTracker(); + if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) { + assert( childTracker ); + assert( childTracker->isIndexTracker() ); + tracker = std::static_pointer_cast( childTracker ); + } + else { + tracker = std::make_shared( nameAndLocation, ctx, ¤tTracker, size ); + currentTracker.addChild( tracker ); + } + + if( !ctx.completedCycle() && !tracker->isComplete() ) { + if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) + tracker->moveNext(); + tracker->open(); + } + + return *tracker; + } + + int IndexTracker::index() const { return m_index; } + + void IndexTracker::moveNext() { + m_index++; + m_children.clear(); + } + + void IndexTracker::close() { + TrackerBase::close(); + if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) + m_runState = Executing; + } + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +} // namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +// end catch_test_case_tracker.cpp +// start catch_test_registry.cpp + +namespace Catch { + + auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* { + return new(std::nothrow) TestInvokerAsFunction( testAsFunction ); + } + + NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {} + + AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept { + try { + getMutableRegistryHub() + .registerTest( + makeTestCase( + invoker, + extractClassName( classOrMethod ), + nameAndTags, + lineInfo)); + } catch (...) { + // Do not throw when constructing global objects, instead register the exception to be processed later + getMutableRegistryHub().registerStartupException(); + } + } + + AutoReg::~AutoReg() = default; +} +// end catch_test_registry.cpp +// start catch_test_spec.cpp + +#include +#include +#include +#include + +namespace Catch { + + TestSpec::Pattern::~Pattern() = default; + TestSpec::NamePattern::~NamePattern() = default; + TestSpec::TagPattern::~TagPattern() = default; + TestSpec::ExcludedPattern::~ExcludedPattern() = default; + + TestSpec::NamePattern::NamePattern( std::string const& name ) + : m_wildcardPattern( toLower( name ), CaseSensitive::No ) + {} + bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const { + return m_wildcardPattern.matches( toLower( testCase.name ) ); + } + + TestSpec::TagPattern::TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} + bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const { + return std::find(begin(testCase.lcaseTags), + end(testCase.lcaseTags), + m_tag) != end(testCase.lcaseTags); + } + + TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} + bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } + + bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const { + // All patterns in a filter must match for the filter to be a match + for( auto const& pattern : m_patterns ) { + if( !pattern->matches( testCase ) ) + return false; + } + return true; + } + + bool TestSpec::hasFilters() const { + return !m_filters.empty(); + } + bool TestSpec::matches( TestCaseInfo const& testCase ) const { + // A TestSpec matches if any filter matches + for( auto const& filter : m_filters ) + if( filter.matches( testCase ) ) + return true; + return false; + } +} +// end catch_test_spec.cpp +// start catch_test_spec_parser.cpp + +namespace Catch { + + TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} + + TestSpecParser& TestSpecParser::parse( std::string const& arg ) { + m_mode = None; + m_exclusion = false; + m_start = std::string::npos; + m_arg = m_tagAliases->expandAliases( arg ); + m_escapeChars.clear(); + for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) + visitChar( m_arg[m_pos] ); + if( m_mode == Name ) + addPattern(); + return *this; + } + TestSpec TestSpecParser::testSpec() { + addFilter(); + return m_testSpec; + } + + void TestSpecParser::visitChar( char c ) { + if( m_mode == None ) { + switch( c ) { + case ' ': return; + case '~': m_exclusion = true; return; + case '[': return startNewMode( Tag, ++m_pos ); + case '"': return startNewMode( QuotedName, ++m_pos ); + case '\\': return escape(); + default: startNewMode( Name, m_pos ); break; + } + } + if( m_mode == Name ) { + if( c == ',' ) { + addPattern(); + addFilter(); + } + else if( c == '[' ) { + if( subString() == "exclude:" ) + m_exclusion = true; + else + addPattern(); + startNewMode( Tag, ++m_pos ); + } + else if( c == '\\' ) + escape(); + } + else if( m_mode == EscapedName ) + m_mode = Name; + else if( m_mode == QuotedName && c == '"' ) + addPattern(); + else if( m_mode == Tag && c == ']' ) + addPattern(); + } + void TestSpecParser::startNewMode( Mode mode, std::size_t start ) { + m_mode = mode; + m_start = start; + } + void TestSpecParser::escape() { + if( m_mode == None ) + m_start = m_pos; + m_mode = EscapedName; + m_escapeChars.push_back( m_pos ); + } + std::string TestSpecParser::subString() const { return m_arg.substr( m_start, m_pos - m_start ); } + + void TestSpecParser::addFilter() { + if( !m_currentFilter.m_patterns.empty() ) { + m_testSpec.m_filters.push_back( m_currentFilter ); + m_currentFilter = TestSpec::Filter(); + } + } + + TestSpec parseTestSpec( std::string const& arg ) { + return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); + } + +} // namespace Catch +// end catch_test_spec_parser.cpp +// start catch_timer.cpp + +#include + +static const uint64_t nanosecondsInSecond = 1000000000; + +namespace Catch { + + auto getCurrentNanosecondsSinceEpoch() -> uint64_t { + return std::chrono::duration_cast( std::chrono::high_resolution_clock::now().time_since_epoch() ).count(); + } + + auto estimateClockResolution() -> uint64_t { + uint64_t sum = 0; + static const uint64_t iterations = 1000000; + + auto startTime = getCurrentNanosecondsSinceEpoch(); + + for( std::size_t i = 0; i < iterations; ++i ) { + + uint64_t ticks; + uint64_t baseTicks = getCurrentNanosecondsSinceEpoch(); + do { + ticks = getCurrentNanosecondsSinceEpoch(); + } while( ticks == baseTicks ); + + auto delta = ticks - baseTicks; + sum += delta; + + // If we have been calibrating for over 3 seconds -- the clock + // is terrible and we should move on. + // TBD: How to signal that the measured resolution is probably wrong? + if (ticks > startTime + 3 * nanosecondsInSecond) { + return sum / i; + } + } + + // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers + // - and potentially do more iterations if there's a high variance. + return sum/iterations; + } + auto getEstimatedClockResolution() -> uint64_t { + static auto s_resolution = estimateClockResolution(); + return s_resolution; + } + + void Timer::start() { + m_nanoseconds = getCurrentNanosecondsSinceEpoch(); + } + auto Timer::getElapsedNanoseconds() const -> uint64_t { + return getCurrentNanosecondsSinceEpoch() - m_nanoseconds; + } + auto Timer::getElapsedMicroseconds() const -> uint64_t { + return getElapsedNanoseconds()/1000; + } + auto Timer::getElapsedMilliseconds() const -> unsigned int { + return static_cast(getElapsedMicroseconds()/1000); + } + auto Timer::getElapsedSeconds() const -> double { + return getElapsedMicroseconds()/1000000.0; + } + +} // namespace Catch +// end catch_timer.cpp +// start catch_tostring.cpp + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wexit-time-destructors" +# pragma clang diagnostic ignored "-Wglobal-constructors" +#endif + +// Enable specific decls locally +#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif + +#include +#include + +namespace Catch { + +namespace Detail { + + const std::string unprintableString = "{?}"; + + namespace { + const int hexThreshold = 255; + + struct Endianness { + enum Arch { Big, Little }; + + static Arch which() { + union _{ + int asInt; + char asChar[sizeof (int)]; + } u; + + u.asInt = 1; + return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; + } + }; + } + + std::string rawMemoryToString( const void *object, std::size_t size ) { + // Reverse order for little endian architectures + int i = 0, end = static_cast( size ), inc = 1; + if( Endianness::which() == Endianness::Little ) { + i = end-1; + end = inc = -1; + } + + unsigned char const *bytes = static_cast(object); + ReusableStringStream rss; + rss << "0x" << std::setfill('0') << std::hex; + for( ; i != end; i += inc ) + rss << std::setw(2) << static_cast(bytes[i]); + return rss.str(); + } +} + +template +std::string fpToString( T value, int precision ) { + if (std::isnan(value)) { + return "nan"; + } + + ReusableStringStream rss; + rss << std::setprecision( precision ) + << std::fixed + << value; + std::string d = rss.str(); + std::size_t i = d.find_last_not_of( '0' ); + if( i != std::string::npos && i != d.size()-1 ) { + if( d[i] == '.' ) + i++; + d = d.substr( 0, i+1 ); + } + return d; +} + +//// ======================================================= //// +// +// Out-of-line defs for full specialization of StringMaker +// +//// ======================================================= //// + +std::string StringMaker::convert(const std::string& str) { + if (!getCurrentContext().getConfig()->showInvisibles()) { + return '"' + str + '"'; + } + + std::string s("\""); + for (char c : str) { + switch (c) { + case '\n': + s.append("\\n"); + break; + case '\t': + s.append("\\t"); + break; + default: + s.push_back(c); + break; + } + } + s.append("\""); + return s; +} + +#ifdef CATCH_CONFIG_WCHAR +std::string StringMaker::convert(const std::wstring& wstr) { + std::string s; + s.reserve(wstr.size()); + for (auto c : wstr) { + s += (c <= 0xff) ? static_cast(c) : '?'; + } + return ::Catch::Detail::stringify(s); +} +#endif + +std::string StringMaker::convert(char const* str) { + if (str) { + return ::Catch::Detail::stringify(std::string{ str }); + } else { + return{ "{null string}" }; + } +} +std::string StringMaker::convert(char* str) { + if (str) { + return ::Catch::Detail::stringify(std::string{ str }); + } else { + return{ "{null string}" }; + } +} +#ifdef CATCH_CONFIG_WCHAR +std::string StringMaker::convert(wchar_t const * str) { + if (str) { + return ::Catch::Detail::stringify(std::wstring{ str }); + } else { + return{ "{null string}" }; + } +} +std::string StringMaker::convert(wchar_t * str) { + if (str) { + return ::Catch::Detail::stringify(std::wstring{ str }); + } else { + return{ "{null string}" }; + } +} +#endif + +std::string StringMaker::convert(int value) { + return ::Catch::Detail::stringify(static_cast(value)); +} +std::string StringMaker::convert(long value) { + return ::Catch::Detail::stringify(static_cast(value)); +} +std::string StringMaker::convert(long long value) { + ReusableStringStream rss; + rss << value; + if (value > Detail::hexThreshold) { + rss << " (0x" << std::hex << value << ')'; + } + return rss.str(); +} + +std::string StringMaker::convert(unsigned int value) { + return ::Catch::Detail::stringify(static_cast(value)); +} +std::string StringMaker::convert(unsigned long value) { + return ::Catch::Detail::stringify(static_cast(value)); +} +std::string StringMaker::convert(unsigned long long value) { + ReusableStringStream rss; + rss << value; + if (value > Detail::hexThreshold) { + rss << " (0x" << std::hex << value << ')'; + } + return rss.str(); +} + +std::string StringMaker::convert(bool b) { + return b ? "true" : "false"; +} + +std::string StringMaker::convert(char value) { + if (value == '\r') { + return "'\\r'"; + } else if (value == '\f') { + return "'\\f'"; + } else if (value == '\n') { + return "'\\n'"; + } else if (value == '\t') { + return "'\\t'"; + } else if ('\0' <= value && value < ' ') { + return ::Catch::Detail::stringify(static_cast(value)); + } else { + char chstr[] = "' '"; + chstr[1] = value; + return chstr; + } +} +std::string StringMaker::convert(signed char c) { + return ::Catch::Detail::stringify(static_cast(c)); +} +std::string StringMaker::convert(unsigned char c) { + return ::Catch::Detail::stringify(static_cast(c)); +} + +std::string StringMaker::convert(std::nullptr_t) { + return "nullptr"; +} + +std::string StringMaker::convert(float value) { + return fpToString(value, 5) + 'f'; +} +std::string StringMaker::convert(double value) { + return fpToString(value, 10); +} + +std::string ratio_string::symbol() { return "a"; } +std::string ratio_string::symbol() { return "f"; } +std::string ratio_string::symbol() { return "p"; } +std::string ratio_string::symbol() { return "n"; } +std::string ratio_string::symbol() { return "u"; } +std::string ratio_string::symbol() { return "m"; } + +} // end namespace Catch + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +// end catch_tostring.cpp +// start catch_totals.cpp + +namespace Catch { + + Counts Counts::operator - ( Counts const& other ) const { + Counts diff; + diff.passed = passed - other.passed; + diff.failed = failed - other.failed; + diff.failedButOk = failedButOk - other.failedButOk; + return diff; + } + + Counts& Counts::operator += ( Counts const& other ) { + passed += other.passed; + failed += other.failed; + failedButOk += other.failedButOk; + return *this; + } + + std::size_t Counts::total() const { + return passed + failed + failedButOk; + } + bool Counts::allPassed() const { + return failed == 0 && failedButOk == 0; + } + bool Counts::allOk() const { + return failed == 0; + } + + Totals Totals::operator - ( Totals const& other ) const { + Totals diff; + diff.assertions = assertions - other.assertions; + diff.testCases = testCases - other.testCases; + return diff; + } + + Totals& Totals::operator += ( Totals const& other ) { + assertions += other.assertions; + testCases += other.testCases; + return *this; + } + + Totals Totals::delta( Totals const& prevTotals ) const { + Totals diff = *this - prevTotals; + if( diff.assertions.failed > 0 ) + ++diff.testCases.failed; + else if( diff.assertions.failedButOk > 0 ) + ++diff.testCases.failedButOk; + else + ++diff.testCases.passed; + return diff; + } + +} +// end catch_totals.cpp +// start catch_uncaught_exceptions.cpp + +#include + +namespace Catch { + bool uncaught_exceptions() { +#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) + return std::uncaught_exceptions() > 0; +#else + return std::uncaught_exception(); +#endif + } +} // end namespace Catch +// end catch_uncaught_exceptions.cpp +// start catch_version.cpp + +#include + +namespace Catch { + + Version::Version + ( unsigned int _majorVersion, + unsigned int _minorVersion, + unsigned int _patchNumber, + char const * const _branchName, + unsigned int _buildNumber ) + : majorVersion( _majorVersion ), + minorVersion( _minorVersion ), + patchNumber( _patchNumber ), + branchName( _branchName ), + buildNumber( _buildNumber ) + {} + + std::ostream& operator << ( std::ostream& os, Version const& version ) { + os << version.majorVersion << '.' + << version.minorVersion << '.' + << version.patchNumber; + // branchName is never null -> 0th char is \0 if it is empty + if (version.branchName[0]) { + os << '-' << version.branchName + << '.' << version.buildNumber; + } + return os; + } + + Version const& libraryVersion() { + static Version version( 2, 2, 3, "", 0 ); + return version; + } + +} +// end catch_version.cpp +// start catch_wildcard_pattern.cpp + +#include + +namespace Catch { + + WildcardPattern::WildcardPattern( std::string const& pattern, + CaseSensitive::Choice caseSensitivity ) + : m_caseSensitivity( caseSensitivity ), + m_pattern( adjustCase( pattern ) ) + { + if( startsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 1 ); + m_wildcard = WildcardAtStart; + } + if( endsWith( m_pattern, '*' ) ) { + m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); + m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); + } + } + + bool WildcardPattern::matches( std::string const& str ) const { + switch( m_wildcard ) { + case NoWildcard: + return m_pattern == adjustCase( str ); + case WildcardAtStart: + return endsWith( adjustCase( str ), m_pattern ); + case WildcardAtEnd: + return startsWith( adjustCase( str ), m_pattern ); + case WildcardAtBothEnds: + return contains( adjustCase( str ), m_pattern ); + default: + CATCH_INTERNAL_ERROR( "Unknown enum" ); + } + } + + std::string WildcardPattern::adjustCase( std::string const& str ) const { + return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; + } +} +// end catch_wildcard_pattern.cpp +// start catch_xmlwriter.cpp + +#include + +using uchar = unsigned char; + +namespace Catch { + +namespace { + + size_t trailingBytes(unsigned char c) { + if ((c & 0xE0) == 0xC0) { + return 2; + } + if ((c & 0xF0) == 0xE0) { + return 3; + } + if ((c & 0xF8) == 0xF0) { + return 4; + } + CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); + } + + uint32_t headerValue(unsigned char c) { + if ((c & 0xE0) == 0xC0) { + return c & 0x1F; + } + if ((c & 0xF0) == 0xE0) { + return c & 0x0F; + } + if ((c & 0xF8) == 0xF0) { + return c & 0x07; + } + CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); + } + + void hexEscapeChar(std::ostream& os, unsigned char c) { + os << "\\x" + << std::uppercase << std::hex << std::setfill('0') << std::setw(2) + << static_cast(c); + } + +} // anonymous namespace + + XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat ) + : m_str( str ), + m_forWhat( forWhat ) + {} + + void XmlEncode::encodeTo( std::ostream& os ) const { + // Apostrophe escaping not necessary if we always use " to write attributes + // (see: http://www.w3.org/TR/xml/#syntax) + + for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) { + uchar c = m_str[idx]; + switch (c) { + case '<': os << "<"; break; + case '&': os << "&"; break; + + case '>': + // See: http://www.w3.org/TR/xml/#syntax + if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') + os << ">"; + else + os << c; + break; + + case '\"': + if (m_forWhat == ForAttributes) + os << """; + else + os << c; + break; + + default: + // Check for control characters and invalid utf-8 + + // Escape control characters in standard ascii + // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { + hexEscapeChar(os, c); + break; + } + + // Plain ASCII: Write it to stream + if (c < 0x7F) { + os << c; + break; + } + + // UTF-8 territory + // Check if the encoding is valid and if it is not, hex escape bytes. + // Important: We do not check the exact decoded values for validity, only the encoding format + // First check that this bytes is a valid lead byte: + // This means that it is not encoded as 1111 1XXX + // Or as 10XX XXXX + if (c < 0xC0 || + c >= 0xF8) { + hexEscapeChar(os, c); + break; + } + + auto encBytes = trailingBytes(c); + // Are there enough bytes left to avoid accessing out-of-bounds memory? + if (idx + encBytes - 1 >= m_str.size()) { + hexEscapeChar(os, c); + break; + } + // The header is valid, check data + // The next encBytes bytes must together be a valid utf-8 + // This means: bitpattern 10XX XXXX and the extracted value is sane (ish) + bool valid = true; + uint32_t value = headerValue(c); + for (std::size_t n = 1; n < encBytes; ++n) { + uchar nc = m_str[idx + n]; + valid &= ((nc & 0xC0) == 0x80); + value = (value << 6) | (nc & 0x3F); + } + + if ( + // Wrong bit pattern of following bytes + (!valid) || + // Overlong encodings + (value < 0x80) || + (0x80 <= value && value < 0x800 && encBytes > 2) || + (0x800 < value && value < 0x10000 && encBytes > 3) || + // Encoded value out of range + (value >= 0x110000) + ) { + hexEscapeChar(os, c); + break; + } + + // If we got here, this is in fact a valid(ish) utf-8 sequence + for (std::size_t n = 0; n < encBytes; ++n) { + os << m_str[idx + n]; + } + idx += encBytes - 1; + break; + } + } + } + + std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { + xmlEncode.encodeTo( os ); + return os; + } + + XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer ) + : m_writer( writer ) + {} + + XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept + : m_writer( other.m_writer ){ + other.m_writer = nullptr; + } + XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept { + if ( m_writer ) { + m_writer->endElement(); + } + m_writer = other.m_writer; + other.m_writer = nullptr; + return *this; + } + + XmlWriter::ScopedElement::~ScopedElement() { + if( m_writer ) + m_writer->endElement(); + } + + XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) { + m_writer->writeText( text, indent ); + return *this; + } + + XmlWriter::XmlWriter( std::ostream& os ) : m_os( os ) + { + writeDeclaration(); + } + + XmlWriter::~XmlWriter() { + while( !m_tags.empty() ) + endElement(); + } + + XmlWriter& XmlWriter::startElement( std::string const& name ) { + ensureTagClosed(); + newlineIfNecessary(); + m_os << m_indent << '<' << name; + m_tags.push_back( name ); + m_indent += " "; + m_tagIsOpen = true; + return *this; + } + + XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) { + ScopedElement scoped( this ); + startElement( name ); + return scoped; + } + + XmlWriter& XmlWriter::endElement() { + newlineIfNecessary(); + m_indent = m_indent.substr( 0, m_indent.size()-2 ); + if( m_tagIsOpen ) { + m_os << "/>"; + m_tagIsOpen = false; + } + else { + m_os << m_indent << ""; + } + m_os << std::endl; + m_tags.pop_back(); + return *this; + } + + XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) { + if( !name.empty() && !attribute.empty() ) + m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; + return *this; + } + + XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) { + m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; + return *this; + } + + XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) { + if( !text.empty() ){ + bool tagWasOpen = m_tagIsOpen; + ensureTagClosed(); + if( tagWasOpen && indent ) + m_os << m_indent; + m_os << XmlEncode( text ); + m_needsNewline = true; + } + return *this; + } + + XmlWriter& XmlWriter::writeComment( std::string const& text ) { + ensureTagClosed(); + m_os << m_indent << ""; + m_needsNewline = true; + return *this; + } + + void XmlWriter::writeStylesheetRef( std::string const& url ) { + m_os << "\n"; + } + + XmlWriter& XmlWriter::writeBlankLine() { + ensureTagClosed(); + m_os << '\n'; + return *this; + } + + void XmlWriter::ensureTagClosed() { + if( m_tagIsOpen ) { + m_os << ">" << std::endl; + m_tagIsOpen = false; + } + } + + void XmlWriter::writeDeclaration() { + m_os << "\n"; + } + + void XmlWriter::newlineIfNecessary() { + if( m_needsNewline ) { + m_os << std::endl; + m_needsNewline = false; + } + } +} +// end catch_xmlwriter.cpp +// start catch_reporter_bases.cpp + +#include +#include +#include +#include +#include + +namespace Catch { + void prepareExpandedExpression(AssertionResult& result) { + result.getExpandedExpression(); + } + + // Because formatting using c++ streams is stateful, drop down to C is required + // Alternatively we could use stringstream, but its performance is... not good. + std::string getFormattedDuration( double duration ) { + // Max exponent + 1 is required to represent the whole part + // + 1 for decimal point + // + 3 for the 3 decimal places + // + 1 for null terminator + const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; + char buffer[maxDoubleSize]; + + // Save previous errno, to prevent sprintf from overwriting it + ErrnoGuard guard; +#ifdef _MSC_VER + sprintf_s(buffer, "%.3f", duration); +#else + sprintf(buffer, "%.3f", duration); +#endif + return std::string(buffer); + } + + TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config) + :StreamingReporterBase(_config) {} + + void TestEventListenerBase::assertionStarting(AssertionInfo const &) {} + + bool TestEventListenerBase::assertionEnded(AssertionStats const &) { + return false; + } + +} // end namespace Catch +// end catch_reporter_bases.cpp +// start catch_reporter_compact.cpp + +namespace { + +#ifdef CATCH_PLATFORM_MAC + const char* failedString() { return "FAILED"; } + const char* passedString() { return "PASSED"; } +#else + const char* failedString() { return "failed"; } + const char* passedString() { return "passed"; } +#endif + + // Colour::LightGrey + Catch::Colour::Code dimColour() { return Catch::Colour::FileName; } + + std::string bothOrAll( std::size_t count ) { + return count == 1 ? std::string() : + count == 2 ? "both " : "all " ; + } + +} // anon namespace + +namespace Catch { +namespace { +// Colour, message variants: +// - white: No tests ran. +// - red: Failed [both/all] N test cases, failed [both/all] M assertions. +// - white: Passed [both/all] N test cases (no assertions). +// - red: Failed N tests cases, failed M assertions. +// - green: Passed [both/all] N tests cases with M assertions. +void printTotals(std::ostream& out, const Totals& totals) { + if (totals.testCases.total() == 0) { + out << "No tests ran."; + } else if (totals.testCases.failed == totals.testCases.total()) { + Colour colour(Colour::ResultError); + const std::string qualify_assertions_failed = + totals.assertions.failed == totals.assertions.total() ? + bothOrAll(totals.assertions.failed) : std::string(); + out << + "Failed " << bothOrAll(totals.testCases.failed) + << pluralise(totals.testCases.failed, "test case") << ", " + "failed " << qualify_assertions_failed << + pluralise(totals.assertions.failed, "assertion") << '.'; + } else if (totals.assertions.total() == 0) { + out << + "Passed " << bothOrAll(totals.testCases.total()) + << pluralise(totals.testCases.total(), "test case") + << " (no assertions)."; + } else if (totals.assertions.failed) { + Colour colour(Colour::ResultError); + out << + "Failed " << pluralise(totals.testCases.failed, "test case") << ", " + "failed " << pluralise(totals.assertions.failed, "assertion") << '.'; + } else { + Colour colour(Colour::ResultSuccess); + out << + "Passed " << bothOrAll(totals.testCases.passed) + << pluralise(totals.testCases.passed, "test case") << + " with " << pluralise(totals.assertions.passed, "assertion") << '.'; + } +} + +// Implementation of CompactReporter formatting +class AssertionPrinter { +public: + AssertionPrinter& operator= (AssertionPrinter const&) = delete; + AssertionPrinter(AssertionPrinter const&) = delete; + AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages) + : stream(_stream) + , result(_stats.assertionResult) + , messages(_stats.infoMessages) + , itMessage(_stats.infoMessages.begin()) + , printInfoMessages(_printInfoMessages) {} + + void print() { + printSourceInfo(); + + itMessage = messages.begin(); + + switch (result.getResultType()) { + case ResultWas::Ok: + printResultType(Colour::ResultSuccess, passedString()); + printOriginalExpression(); + printReconstructedExpression(); + if (!result.hasExpression()) + printRemainingMessages(Colour::None); + else + printRemainingMessages(); + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) + printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok")); + else + printResultType(Colour::Error, failedString()); + printOriginalExpression(); + printReconstructedExpression(); + printRemainingMessages(); + break; + case ResultWas::ThrewException: + printResultType(Colour::Error, failedString()); + printIssue("unexpected exception with message:"); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::FatalErrorCondition: + printResultType(Colour::Error, failedString()); + printIssue("fatal error condition with message:"); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::DidntThrowException: + printResultType(Colour::Error, failedString()); + printIssue("expected exception, got none"); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::Info: + printResultType(Colour::None, "info"); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::Warning: + printResultType(Colour::None, "warning"); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::ExplicitFailure: + printResultType(Colour::Error, failedString()); + printIssue("explicitly"); + printRemainingMessages(Colour::None); + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + printResultType(Colour::Error, "** internal error **"); + break; + } + } + +private: + void printSourceInfo() const { + Colour colourGuard(Colour::FileName); + stream << result.getSourceInfo() << ':'; + } + + void printResultType(Colour::Code colour, std::string const& passOrFail) const { + if (!passOrFail.empty()) { + { + Colour colourGuard(colour); + stream << ' ' << passOrFail; + } + stream << ':'; + } + } + + void printIssue(std::string const& issue) const { + stream << ' ' << issue; + } + + void printExpressionWas() { + if (result.hasExpression()) { + stream << ';'; + { + Colour colour(dimColour()); + stream << " expression was:"; + } + printOriginalExpression(); + } + } + + void printOriginalExpression() const { + if (result.hasExpression()) { + stream << ' ' << result.getExpression(); + } + } + + void printReconstructedExpression() const { + if (result.hasExpandedExpression()) { + { + Colour colour(dimColour()); + stream << " for: "; + } + stream << result.getExpandedExpression(); + } + } + + void printMessage() { + if (itMessage != messages.end()) { + stream << " '" << itMessage->message << '\''; + ++itMessage; + } + } + + void printRemainingMessages(Colour::Code colour = dimColour()) { + if (itMessage == messages.end()) + return; + + // using messages.end() directly yields (or auto) compilation error: + std::vector::const_iterator itEnd = messages.end(); + const std::size_t N = static_cast(std::distance(itMessage, itEnd)); + + { + Colour colourGuard(colour); + stream << " with " << pluralise(N, "message") << ':'; + } + + for (; itMessage != itEnd; ) { + // If this assertion is a warning ignore any INFO messages + if (printInfoMessages || itMessage->type != ResultWas::Info) { + stream << " '" << itMessage->message << '\''; + if (++itMessage != itEnd) { + Colour colourGuard(dimColour()); + stream << " and"; + } + } + } + } + +private: + std::ostream& stream; + AssertionResult const& result; + std::vector messages; + std::vector::const_iterator itMessage; + bool printInfoMessages; +}; + +} // anon namespace + + std::string CompactReporter::getDescription() { + return "Reports test results on a single line, suitable for IDEs"; + } + + ReporterPreferences CompactReporter::getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = false; + return prefs; + } + + void CompactReporter::noMatchingTestCases( std::string const& spec ) { + stream << "No test cases matched '" << spec << '\'' << std::endl; + } + + void CompactReporter::assertionStarting( AssertionInfo const& ) {} + + bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) { + AssertionResult const& result = _assertionStats.assertionResult; + + bool printInfoMessages = true; + + // Drop out if result was successful and we're not printing those + if( !m_config->includeSuccessfulResults() && result.isOk() ) { + if( result.getResultType() != ResultWas::Warning ) + return false; + printInfoMessages = false; + } + + AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); + printer.print(); + + stream << std::endl; + return true; + } + + void CompactReporter::sectionEnded(SectionStats const& _sectionStats) { + if (m_config->showDurations() == ShowDurations::Always) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + } + + void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) { + printTotals( stream, _testRunStats.totals ); + stream << '\n' << std::endl; + StreamingReporterBase::testRunEnded( _testRunStats ); + } + + CompactReporter::~CompactReporter() {} + + CATCH_REGISTER_REPORTER( "compact", CompactReporter ) + +} // end namespace Catch +// end catch_reporter_compact.cpp +// start catch_reporter_console.cpp + +#include +#include + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch + // Note that 4062 (not all labels are handled + // and default is missing) is enabled +#endif + +namespace Catch { + +namespace { + +// Formatter impl for ConsoleReporter +class ConsoleAssertionPrinter { +public: + ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete; + ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete; + ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages) + : stream(_stream), + stats(_stats), + result(_stats.assertionResult), + colour(Colour::None), + message(result.getMessage()), + messages(_stats.infoMessages), + printInfoMessages(_printInfoMessages) { + switch (result.getResultType()) { + case ResultWas::Ok: + colour = Colour::Success; + passOrFail = "PASSED"; + //if( result.hasMessage() ) + if (_stats.infoMessages.size() == 1) + messageLabel = "with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "with messages"; + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) { + colour = Colour::Success; + passOrFail = "FAILED - but was ok"; + } else { + colour = Colour::Error; + passOrFail = "FAILED"; + } + if (_stats.infoMessages.size() == 1) + messageLabel = "with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "with messages"; + break; + case ResultWas::ThrewException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to unexpected exception with "; + if (_stats.infoMessages.size() == 1) + messageLabel += "message"; + if (_stats.infoMessages.size() > 1) + messageLabel += "messages"; + break; + case ResultWas::FatalErrorCondition: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to a fatal error condition"; + break; + case ResultWas::DidntThrowException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "because no exception was thrown where one was expected"; + break; + case ResultWas::Info: + messageLabel = "info"; + break; + case ResultWas::Warning: + messageLabel = "warning"; + break; + case ResultWas::ExplicitFailure: + passOrFail = "FAILED"; + colour = Colour::Error; + if (_stats.infoMessages.size() == 1) + messageLabel = "explicitly with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "explicitly with messages"; + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + passOrFail = "** internal error **"; + colour = Colour::Error; + break; + } + } + + void print() const { + printSourceInfo(); + if (stats.totals.assertions.total() > 0) { + if (result.isOk()) + stream << '\n'; + printResultType(); + printOriginalExpression(); + printReconstructedExpression(); + } else { + stream << '\n'; + } + printMessage(); + } + +private: + void printResultType() const { + if (!passOrFail.empty()) { + Colour colourGuard(colour); + stream << passOrFail << ":\n"; + } + } + void printOriginalExpression() const { + if (result.hasExpression()) { + Colour colourGuard(Colour::OriginalExpression); + stream << " "; + stream << result.getExpressionInMacro(); + stream << '\n'; + } + } + void printReconstructedExpression() const { + if (result.hasExpandedExpression()) { + stream << "with expansion:\n"; + Colour colourGuard(Colour::ReconstructedExpression); + stream << Column(result.getExpandedExpression()).indent(2) << '\n'; + } + } + void printMessage() const { + if (!messageLabel.empty()) + stream << messageLabel << ':' << '\n'; + for (auto const& msg : messages) { + // If this assertion is a warning ignore any INFO messages + if (printInfoMessages || msg.type != ResultWas::Info) + stream << Column(msg.message).indent(2) << '\n'; + } + } + void printSourceInfo() const { + Colour colourGuard(Colour::FileName); + stream << result.getSourceInfo() << ": "; + } + + std::ostream& stream; + AssertionStats const& stats; + AssertionResult const& result; + Colour::Code colour; + std::string passOrFail; + std::string messageLabel; + std::string message; + std::vector messages; + bool printInfoMessages; +}; + +std::size_t makeRatio(std::size_t number, std::size_t total) { + std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0; + return (ratio == 0 && number > 0) ? 1 : ratio; +} + +std::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) { + if (i > j && i > k) + return i; + else if (j > k) + return j; + else + return k; +} + +struct ColumnInfo { + enum Justification { Left, Right }; + std::string name; + int width; + Justification justification; +}; +struct ColumnBreak {}; +struct RowBreak {}; + +class Duration { + enum class Unit { + Auto, + Nanoseconds, + Microseconds, + Milliseconds, + Seconds, + Minutes + }; + static const uint64_t s_nanosecondsInAMicrosecond = 1000; + static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond; + static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond; + static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond; + + uint64_t m_inNanoseconds; + Unit m_units; + +public: + explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto) + : m_inNanoseconds(inNanoseconds), + m_units(units) { + if (m_units == Unit::Auto) { + if (m_inNanoseconds < s_nanosecondsInAMicrosecond) + m_units = Unit::Nanoseconds; + else if (m_inNanoseconds < s_nanosecondsInAMillisecond) + m_units = Unit::Microseconds; + else if (m_inNanoseconds < s_nanosecondsInASecond) + m_units = Unit::Milliseconds; + else if (m_inNanoseconds < s_nanosecondsInAMinute) + m_units = Unit::Seconds; + else + m_units = Unit::Minutes; + } + + } + + auto value() const -> double { + switch (m_units) { + case Unit::Microseconds: + return m_inNanoseconds / static_cast(s_nanosecondsInAMicrosecond); + case Unit::Milliseconds: + return m_inNanoseconds / static_cast(s_nanosecondsInAMillisecond); + case Unit::Seconds: + return m_inNanoseconds / static_cast(s_nanosecondsInASecond); + case Unit::Minutes: + return m_inNanoseconds / static_cast(s_nanosecondsInAMinute); + default: + return static_cast(m_inNanoseconds); + } + } + auto unitsAsString() const -> std::string { + switch (m_units) { + case Unit::Nanoseconds: + return "ns"; + case Unit::Microseconds: + return "µs"; + case Unit::Milliseconds: + return "ms"; + case Unit::Seconds: + return "s"; + case Unit::Minutes: + return "m"; + default: + return "** internal error **"; + } + + } + friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& { + return os << duration.value() << " " << duration.unitsAsString(); + } +}; +} // end anon namespace + +class TablePrinter { + std::ostream& m_os; + std::vector m_columnInfos; + std::ostringstream m_oss; + int m_currentColumn = -1; + bool m_isOpen = false; + +public: + TablePrinter( std::ostream& os, std::vector columnInfos ) + : m_os( os ), + m_columnInfos( std::move( columnInfos ) ) {} + + auto columnInfos() const -> std::vector const& { + return m_columnInfos; + } + + void open() { + if (!m_isOpen) { + m_isOpen = true; + *this << RowBreak(); + for (auto const& info : m_columnInfos) + *this << info.name << ColumnBreak(); + *this << RowBreak(); + m_os << Catch::getLineOfChars<'-'>() << "\n"; + } + } + void close() { + if (m_isOpen) { + *this << RowBreak(); + m_os << std::endl; + m_isOpen = false; + } + } + + template + friend TablePrinter& operator << (TablePrinter& tp, T const& value) { + tp.m_oss << value; + return tp; + } + + friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) { + auto colStr = tp.m_oss.str(); + // This takes account of utf8 encodings + auto strSize = Catch::StringRef(colStr).numberOfCharacters(); + tp.m_oss.str(""); + tp.open(); + if (tp.m_currentColumn == static_cast(tp.m_columnInfos.size() - 1)) { + tp.m_currentColumn = -1; + tp.m_os << "\n"; + } + tp.m_currentColumn++; + + auto colInfo = tp.m_columnInfos[tp.m_currentColumn]; + auto padding = (strSize + 2 < static_cast(colInfo.width)) + ? std::string(colInfo.width - (strSize + 2), ' ') + : std::string(); + if (colInfo.justification == ColumnInfo::Left) + tp.m_os << colStr << padding << " "; + else + tp.m_os << padding << colStr << " "; + return tp; + } + + friend TablePrinter& operator << (TablePrinter& tp, RowBreak) { + if (tp.m_currentColumn > 0) { + tp.m_os << "\n"; + tp.m_currentColumn = -1; + } + return tp; + } +}; + +ConsoleReporter::ConsoleReporter(ReporterConfig const& config) + : StreamingReporterBase(config), + m_tablePrinter(new TablePrinter(config.stream(), + { + { "benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left }, + { "iters", 8, ColumnInfo::Right }, + { "elapsed ns", 14, ColumnInfo::Right }, + { "average", 14, ColumnInfo::Right } + })) {} +ConsoleReporter::~ConsoleReporter() = default; + +std::string ConsoleReporter::getDescription() { + return "Reports test results as plain lines of text"; +} + +void ConsoleReporter::noMatchingTestCases(std::string const& spec) { + stream << "No test cases matched '" << spec << '\'' << std::endl; +} + +void ConsoleReporter::assertionStarting(AssertionInfo const&) {} + +bool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) { + AssertionResult const& result = _assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + // Drop out if result was successful but we're not printing them. + if (!includeResults && result.getResultType() != ResultWas::Warning) + return false; + + lazyPrint(); + + ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults); + printer.print(); + stream << std::endl; + return true; +} + +void ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) { + m_headerPrinted = false; + StreamingReporterBase::sectionStarting(_sectionInfo); +} +void ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) { + m_tablePrinter->close(); + if (_sectionStats.missingAssertions) { + lazyPrint(); + Colour colour(Colour::ResultError); + if (m_sectionStack.size() > 1) + stream << "\nNo assertions in section"; + else + stream << "\nNo assertions in test case"; + stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; + } + if (m_config->showDurations() == ShowDurations::Always) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name << std::endl; + } + if (m_headerPrinted) { + m_headerPrinted = false; + } + StreamingReporterBase::sectionEnded(_sectionStats); +} + +void ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) { + lazyPrintWithoutClosingBenchmarkTable(); + + auto nameCol = Column( info.name ).width( static_cast( m_tablePrinter->columnInfos()[0].width - 2 ) ); + + bool firstLine = true; + for (auto line : nameCol) { + if (!firstLine) + (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak(); + else + firstLine = false; + + (*m_tablePrinter) << line << ColumnBreak(); + } +} +void ConsoleReporter::benchmarkEnded(BenchmarkStats const& stats) { + Duration average(stats.elapsedTimeInNanoseconds / stats.iterations); + (*m_tablePrinter) + << stats.iterations << ColumnBreak() + << stats.elapsedTimeInNanoseconds << ColumnBreak() + << average << ColumnBreak(); +} + +void ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) { + m_tablePrinter->close(); + StreamingReporterBase::testCaseEnded(_testCaseStats); + m_headerPrinted = false; +} +void ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) { + if (currentGroupInfo.used) { + printSummaryDivider(); + stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; + printTotals(_testGroupStats.totals); + stream << '\n' << std::endl; + } + StreamingReporterBase::testGroupEnded(_testGroupStats); +} +void ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) { + printTotalsDivider(_testRunStats.totals); + printTotals(_testRunStats.totals); + stream << std::endl; + StreamingReporterBase::testRunEnded(_testRunStats); +} + +void ConsoleReporter::lazyPrint() { + + m_tablePrinter->close(); + lazyPrintWithoutClosingBenchmarkTable(); +} + +void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() { + + if (!currentTestRunInfo.used) + lazyPrintRunInfo(); + if (!currentGroupInfo.used) + lazyPrintGroupInfo(); + + if (!m_headerPrinted) { + printTestCaseAndSectionHeader(); + m_headerPrinted = true; + } +} +void ConsoleReporter::lazyPrintRunInfo() { + stream << '\n' << getLineOfChars<'~'>() << '\n'; + Colour colour(Colour::SecondaryText); + stream << currentTestRunInfo->name + << " is a Catch v" << libraryVersion() << " host application.\n" + << "Run with -? for options\n\n"; + + if (m_config->rngSeed() != 0) + stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; + + currentTestRunInfo.used = true; +} +void ConsoleReporter::lazyPrintGroupInfo() { + if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) { + printClosedHeader("Group: " + currentGroupInfo->name); + currentGroupInfo.used = true; + } +} +void ConsoleReporter::printTestCaseAndSectionHeader() { + assert(!m_sectionStack.empty()); + printOpenHeader(currentTestCaseInfo->name); + + if (m_sectionStack.size() > 1) { + Colour colourGuard(Colour::Headers); + + auto + it = m_sectionStack.begin() + 1, // Skip first section (test case) + itEnd = m_sectionStack.end(); + for (; it != itEnd; ++it) + printHeaderString(it->name, 2); + } + + SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; + + if (!lineInfo.empty()) { + stream << getLineOfChars<'-'>() << '\n'; + Colour colourGuard(Colour::FileName); + stream << lineInfo << '\n'; + } + stream << getLineOfChars<'.'>() << '\n' << std::endl; +} + +void ConsoleReporter::printClosedHeader(std::string const& _name) { + printOpenHeader(_name); + stream << getLineOfChars<'.'>() << '\n'; +} +void ConsoleReporter::printOpenHeader(std::string const& _name) { + stream << getLineOfChars<'-'>() << '\n'; + { + Colour colourGuard(Colour::Headers); + printHeaderString(_name); + } +} + +// if string has a : in first line will set indent to follow it on +// subsequent lines +void ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) { + std::size_t i = _string.find(": "); + if (i != std::string::npos) + i += 2; + else + i = 0; + stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n'; +} + +struct SummaryColumn { + + SummaryColumn( std::string _label, Colour::Code _colour ) + : label( std::move( _label ) ), + colour( _colour ) {} + SummaryColumn addRow( std::size_t count ) { + ReusableStringStream rss; + rss << count; + std::string row = rss.str(); + for (auto& oldRow : rows) { + while (oldRow.size() < row.size()) + oldRow = ' ' + oldRow; + while (oldRow.size() > row.size()) + row = ' ' + row; + } + rows.push_back(row); + return *this; + } + + std::string label; + Colour::Code colour; + std::vector rows; + +}; + +void ConsoleReporter::printTotals( Totals const& totals ) { + if (totals.testCases.total() == 0) { + stream << Colour(Colour::Warning) << "No tests ran\n"; + } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) { + stream << Colour(Colour::ResultSuccess) << "All tests passed"; + stream << " (" + << pluralise(totals.assertions.passed, "assertion") << " in " + << pluralise(totals.testCases.passed, "test case") << ')' + << '\n'; + } else { + + std::vector columns; + columns.push_back(SummaryColumn("", Colour::None) + .addRow(totals.testCases.total()) + .addRow(totals.assertions.total())); + columns.push_back(SummaryColumn("passed", Colour::Success) + .addRow(totals.testCases.passed) + .addRow(totals.assertions.passed)); + columns.push_back(SummaryColumn("failed", Colour::ResultError) + .addRow(totals.testCases.failed) + .addRow(totals.assertions.failed)); + columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure) + .addRow(totals.testCases.failedButOk) + .addRow(totals.assertions.failedButOk)); + + printSummaryRow("test cases", columns, 0); + printSummaryRow("assertions", columns, 1); + } +} +void ConsoleReporter::printSummaryRow(std::string const& label, std::vector const& cols, std::size_t row) { + for (auto col : cols) { + std::string value = col.rows[row]; + if (col.label.empty()) { + stream << label << ": "; + if (value != "0") + stream << value; + else + stream << Colour(Colour::Warning) << "- none -"; + } else if (value != "0") { + stream << Colour(Colour::LightGrey) << " | "; + stream << Colour(col.colour) + << value << ' ' << col.label; + } + } + stream << '\n'; +} + +void ConsoleReporter::printTotalsDivider(Totals const& totals) { + if (totals.testCases.total() > 0) { + std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total()); + std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total()); + std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total()); + while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1) + findMax(failedRatio, failedButOkRatio, passedRatio)++; + while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1) + findMax(failedRatio, failedButOkRatio, passedRatio)--; + + stream << Colour(Colour::Error) << std::string(failedRatio, '='); + stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '='); + if (totals.testCases.allPassed()) + stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '='); + else + stream << Colour(Colour::Success) << std::string(passedRatio, '='); + } else { + stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '='); + } + stream << '\n'; +} +void ConsoleReporter::printSummaryDivider() { + stream << getLineOfChars<'-'>() << '\n'; +} + +CATCH_REGISTER_REPORTER("console", ConsoleReporter) + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +// end catch_reporter_console.cpp +// start catch_reporter_junit.cpp + +#include +#include +#include +#include + +namespace Catch { + + namespace { + std::string getCurrentTimestamp() { + // Beware, this is not reentrant because of backward compatibility issues + // Also, UTC only, again because of backward compatibility (%z is C++11) + time_t rawtime; + std::time(&rawtime); + auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &rawtime); +#else + std::tm* timeInfo; + timeInfo = std::gmtime(&rawtime); +#endif + + char timeStamp[timeStampSize]; + const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp); + } + + std::string fileNameTag(const std::vector &tags) { + auto it = std::find_if(begin(tags), + end(tags), + [] (std::string const& tag) {return tag.front() == '#'; }); + if (it != tags.end()) + return it->substr(1); + return std::string(); + } + } // anonymous namespace + + JunitReporter::JunitReporter( ReporterConfig const& _config ) + : CumulativeReporterBase( _config ), + xml( _config.stream() ) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + JunitReporter::~JunitReporter() {} + + std::string JunitReporter::getDescription() { + return "Reports test results in an XML format that looks like Ant's junitreport target"; + } + + void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {} + + void JunitReporter::testRunStarting( TestRunInfo const& runInfo ) { + CumulativeReporterBase::testRunStarting( runInfo ); + xml.startElement( "testsuites" ); + } + + void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) { + suiteTimer.start(); + stdOutForSuite.clear(); + stdErrForSuite.clear(); + unexpectedExceptions = 0; + CumulativeReporterBase::testGroupStarting( groupInfo ); + } + + void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) { + m_okToFail = testCaseInfo.okToFail(); + } + + bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) { + if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail ) + unexpectedExceptions++; + return CumulativeReporterBase::assertionEnded( assertionStats ); + } + + void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { + stdOutForSuite += testCaseStats.stdOut; + stdErrForSuite += testCaseStats.stdErr; + CumulativeReporterBase::testCaseEnded( testCaseStats ); + } + + void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { + double suiteTime = suiteTimer.getElapsedSeconds(); + CumulativeReporterBase::testGroupEnded( testGroupStats ); + writeGroup( *m_testGroups.back(), suiteTime ); + } + + void JunitReporter::testRunEndedCumulative() { + xml.endElement(); + } + + void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); + TestGroupStats const& stats = groupNode.value; + xml.writeAttribute( "name", stats.groupInfo.name ); + xml.writeAttribute( "errors", unexpectedExceptions ); + xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); + xml.writeAttribute( "tests", stats.totals.assertions.total() ); + xml.writeAttribute( "hostname", "tbd" ); // !TBD + if( m_config->showDurations() == ShowDurations::Never ) + xml.writeAttribute( "time", "" ); + else + xml.writeAttribute( "time", suiteTime ); + xml.writeAttribute( "timestamp", getCurrentTimestamp() ); + + // Write test cases + for( auto const& child : groupNode.children ) + writeTestCase( *child ); + + xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false ); + xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false ); + } + + void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) { + TestCaseStats const& stats = testCaseNode.value; + + // All test cases have exactly one section - which represents the + // test case itself. That section may have 0-n nested sections + assert( testCaseNode.children.size() == 1 ); + SectionNode const& rootSection = *testCaseNode.children.front(); + + std::string className = stats.testInfo.className; + + if( className.empty() ) { + className = fileNameTag(stats.testInfo.tags); + if ( className.empty() ) + className = "global"; + } + + if ( !m_config->name().empty() ) + className = m_config->name() + "." + className; + + writeSection( className, "", rootSection ); + } + + void JunitReporter::writeSection( std::string const& className, + std::string const& rootName, + SectionNode const& sectionNode ) { + std::string name = trim( sectionNode.stats.sectionInfo.name ); + if( !rootName.empty() ) + name = rootName + '/' + name; + + if( !sectionNode.assertions.empty() || + !sectionNode.stdOut.empty() || + !sectionNode.stdErr.empty() ) { + XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); + if( className.empty() ) { + xml.writeAttribute( "classname", name ); + xml.writeAttribute( "name", "root" ); + } + else { + xml.writeAttribute( "classname", className ); + xml.writeAttribute( "name", name ); + } + xml.writeAttribute( "time", ::Catch::Detail::stringify( sectionNode.stats.durationInSeconds ) ); + + writeAssertions( sectionNode ); + + if( !sectionNode.stdOut.empty() ) + xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); + if( !sectionNode.stdErr.empty() ) + xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); + } + for( auto const& childNode : sectionNode.childSections ) + if( className.empty() ) + writeSection( name, "", *childNode ); + else + writeSection( className, name, *childNode ); + } + + void JunitReporter::writeAssertions( SectionNode const& sectionNode ) { + for( auto const& assertion : sectionNode.assertions ) + writeAssertion( assertion ); + } + + void JunitReporter::writeAssertion( AssertionStats const& stats ) { + AssertionResult const& result = stats.assertionResult; + if( !result.isOk() ) { + std::string elementName; + switch( result.getResultType() ) { + case ResultWas::ThrewException: + case ResultWas::FatalErrorCondition: + elementName = "error"; + break; + case ResultWas::ExplicitFailure: + elementName = "failure"; + break; + case ResultWas::ExpressionFailed: + elementName = "failure"; + break; + case ResultWas::DidntThrowException: + elementName = "failure"; + break; + + // We should never see these here: + case ResultWas::Info: + case ResultWas::Warning: + case ResultWas::Ok: + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + elementName = "internalError"; + break; + } + + XmlWriter::ScopedElement e = xml.scopedElement( elementName ); + + xml.writeAttribute( "message", result.getExpandedExpression() ); + xml.writeAttribute( "type", result.getTestMacroName() ); + + ReusableStringStream rss; + if( !result.getMessage().empty() ) + rss << result.getMessage() << '\n'; + for( auto const& msg : stats.infoMessages ) + if( msg.type == ResultWas::Info ) + rss << msg.message << '\n'; + + rss << "at " << result.getSourceInfo(); + xml.writeText( rss.str(), false ); + } + } + + CATCH_REGISTER_REPORTER( "junit", JunitReporter ) + +} // end namespace Catch +// end catch_reporter_junit.cpp +// start catch_reporter_listening.cpp + +#include + +namespace Catch { + + void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) { + m_listeners.push_back( std::move( listener ) ); + } + + void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) { + assert(!m_reporter && "Listening reporter can wrap only 1 real reporter"); + m_reporter = std::move( reporter ); + } + + ReporterPreferences ListeningReporter::getPreferences() const { + return m_reporter->getPreferences(); + } + + std::set ListeningReporter::getSupportedVerbosities() { + return std::set{ }; + } + + void ListeningReporter::noMatchingTestCases( std::string const& spec ) { + for ( auto const& listener : m_listeners ) { + listener->noMatchingTestCases( spec ); + } + m_reporter->noMatchingTestCases( spec ); + } + + void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) { + for ( auto const& listener : m_listeners ) { + listener->benchmarkStarting( benchmarkInfo ); + } + m_reporter->benchmarkStarting( benchmarkInfo ); + } + void ListeningReporter::benchmarkEnded( BenchmarkStats const& benchmarkStats ) { + for ( auto const& listener : m_listeners ) { + listener->benchmarkEnded( benchmarkStats ); + } + m_reporter->benchmarkEnded( benchmarkStats ); + } + + void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) { + for ( auto const& listener : m_listeners ) { + listener->testRunStarting( testRunInfo ); + } + m_reporter->testRunStarting( testRunInfo ); + } + + void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) { + for ( auto const& listener : m_listeners ) { + listener->testGroupStarting( groupInfo ); + } + m_reporter->testGroupStarting( groupInfo ); + } + + void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) { + for ( auto const& listener : m_listeners ) { + listener->testCaseStarting( testInfo ); + } + m_reporter->testCaseStarting( testInfo ); + } + + void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) { + for ( auto const& listener : m_listeners ) { + listener->sectionStarting( sectionInfo ); + } + m_reporter->sectionStarting( sectionInfo ); + } + + void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) { + for ( auto const& listener : m_listeners ) { + listener->assertionStarting( assertionInfo ); + } + m_reporter->assertionStarting( assertionInfo ); + } + + // The return value indicates if the messages buffer should be cleared: + bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) { + for( auto const& listener : m_listeners ) { + static_cast( listener->assertionEnded( assertionStats ) ); + } + return m_reporter->assertionEnded( assertionStats ); + } + + void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) { + for ( auto const& listener : m_listeners ) { + listener->sectionEnded( sectionStats ); + } + m_reporter->sectionEnded( sectionStats ); + } + + void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { + for ( auto const& listener : m_listeners ) { + listener->testCaseEnded( testCaseStats ); + } + m_reporter->testCaseEnded( testCaseStats ); + } + + void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { + for ( auto const& listener : m_listeners ) { + listener->testGroupEnded( testGroupStats ); + } + m_reporter->testGroupEnded( testGroupStats ); + } + + void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) { + for ( auto const& listener : m_listeners ) { + listener->testRunEnded( testRunStats ); + } + m_reporter->testRunEnded( testRunStats ); + } + + void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) { + for ( auto const& listener : m_listeners ) { + listener->skipTest( testInfo ); + } + m_reporter->skipTest( testInfo ); + } + + bool ListeningReporter::isMulti() const { + return true; + } + +} // end namespace Catch +// end catch_reporter_listening.cpp +// start catch_reporter_xml.cpp + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch + // Note that 4062 (not all labels are handled + // and default is missing) is enabled +#endif + +namespace Catch { + XmlReporter::XmlReporter( ReporterConfig const& _config ) + : StreamingReporterBase( _config ), + m_xml(_config.stream()) + { + m_reporterPrefs.shouldRedirectStdOut = true; + } + + XmlReporter::~XmlReporter() = default; + + std::string XmlReporter::getDescription() { + return "Reports test results as an XML document"; + } + + std::string XmlReporter::getStylesheetRef() const { + return std::string(); + } + + void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) { + m_xml + .writeAttribute( "filename", sourceInfo.file ) + .writeAttribute( "line", sourceInfo.line ); + } + + void XmlReporter::noMatchingTestCases( std::string const& s ) { + StreamingReporterBase::noMatchingTestCases( s ); + } + + void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) { + StreamingReporterBase::testRunStarting( testInfo ); + std::string stylesheetRef = getStylesheetRef(); + if( !stylesheetRef.empty() ) + m_xml.writeStylesheetRef( stylesheetRef ); + m_xml.startElement( "Catch" ); + if( !m_config->name().empty() ) + m_xml.writeAttribute( "name", m_config->name() ); + } + + void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) { + StreamingReporterBase::testGroupStarting( groupInfo ); + m_xml.startElement( "Group" ) + .writeAttribute( "name", groupInfo.name ); + } + + void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) { + StreamingReporterBase::testCaseStarting(testInfo); + m_xml.startElement( "TestCase" ) + .writeAttribute( "name", trim( testInfo.name ) ) + .writeAttribute( "description", testInfo.description ) + .writeAttribute( "tags", testInfo.tagsAsString() ); + + writeSourceInfo( testInfo.lineInfo ); + + if ( m_config->showDurations() == ShowDurations::Always ) + m_testCaseTimer.start(); + m_xml.ensureTagClosed(); + } + + void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) { + StreamingReporterBase::sectionStarting( sectionInfo ); + if( m_sectionDepth++ > 0 ) { + m_xml.startElement( "Section" ) + .writeAttribute( "name", trim( sectionInfo.name ) ) + .writeAttribute( "description", sectionInfo.description ); + writeSourceInfo( sectionInfo.lineInfo ); + m_xml.ensureTagClosed(); + } + } + + void XmlReporter::assertionStarting( AssertionInfo const& ) { } + + bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) { + + AssertionResult const& result = assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + if( includeResults || result.getResultType() == ResultWas::Warning ) { + // Print any info messages in tags. + for( auto const& msg : assertionStats.infoMessages ) { + if( msg.type == ResultWas::Info && includeResults ) { + m_xml.scopedElement( "Info" ) + .writeText( msg.message ); + } else if ( msg.type == ResultWas::Warning ) { + m_xml.scopedElement( "Warning" ) + .writeText( msg.message ); + } + } + } + + // Drop out if result was successful but we're not printing them. + if( !includeResults && result.getResultType() != ResultWas::Warning ) + return true; + + // Print the expression if there is one. + if( result.hasExpression() ) { + m_xml.startElement( "Expression" ) + .writeAttribute( "success", result.succeeded() ) + .writeAttribute( "type", result.getTestMacroName() ); + + writeSourceInfo( result.getSourceInfo() ); + + m_xml.scopedElement( "Original" ) + .writeText( result.getExpression() ); + m_xml.scopedElement( "Expanded" ) + .writeText( result.getExpandedExpression() ); + } + + // And... Print a result applicable to each result type. + switch( result.getResultType() ) { + case ResultWas::ThrewException: + m_xml.startElement( "Exception" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::FatalErrorCondition: + m_xml.startElement( "FatalErrorCondition" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + case ResultWas::Info: + m_xml.scopedElement( "Info" ) + .writeText( result.getMessage() ); + break; + case ResultWas::Warning: + // Warning will already have been written + break; + case ResultWas::ExplicitFailure: + m_xml.startElement( "Failure" ); + writeSourceInfo( result.getSourceInfo() ); + m_xml.writeText( result.getMessage() ); + m_xml.endElement(); + break; + default: + break; + } + + if( result.hasExpression() ) + m_xml.endElement(); + + return true; + } + + void XmlReporter::sectionEnded( SectionStats const& sectionStats ) { + StreamingReporterBase::sectionEnded( sectionStats ); + if( --m_sectionDepth > 0 ) { + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); + e.writeAttribute( "successes", sectionStats.assertions.passed ); + e.writeAttribute( "failures", sectionStats.assertions.failed ); + e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); + + m_xml.endElement(); + } + } + + void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) { + StreamingReporterBase::testCaseEnded( testCaseStats ); + XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); + e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); + + if ( m_config->showDurations() == ShowDurations::Always ) + e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); + + if( !testCaseStats.stdOut.empty() ) + m_xml.scopedElement( "StdOut" ).writeText( trim( testCaseStats.stdOut ), false ); + if( !testCaseStats.stdErr.empty() ) + m_xml.scopedElement( "StdErr" ).writeText( trim( testCaseStats.stdErr ), false ); + + m_xml.endElement(); + } + + void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) { + StreamingReporterBase::testGroupEnded( testGroupStats ); + // TODO: Check testGroupStats.aborting and act accordingly. + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) + .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) { + StreamingReporterBase::testRunEnded( testRunStats ); + m_xml.scopedElement( "OverallResults" ) + .writeAttribute( "successes", testRunStats.totals.assertions.passed ) + .writeAttribute( "failures", testRunStats.totals.assertions.failed ) + .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); + m_xml.endElement(); + } + + CATCH_REGISTER_REPORTER( "xml", XmlReporter ) + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +// end catch_reporter_xml.cpp + +namespace Catch { + LeakDetector leakDetector; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_impl.hpp +#endif + +#ifdef CATCH_CONFIG_MAIN +// start catch_default_main.hpp + +#ifndef __OBJC__ + +#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) +// Standard C/C++ Win32 Unicode wmain entry point +extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) { +#else +// Standard C/C++ main entry point +int main (int argc, char * argv[]) { +#endif + + return Catch::Session().run( argc, argv ); +} + +#else // __OBJC__ + +// Objective-C entry point +int main (int argc, char * const argv[]) { +#if !CATCH_ARC_ENABLED + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +#endif + + Catch::registerTestMethods(); + int result = Catch::Session().run( argc, (char**)argv ); + +#if !CATCH_ARC_ENABLED + [pool drain]; +#endif + + return result; +} + +#endif // __OBJC__ + +// end catch_default_main.hpp +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) + +#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED +# undef CLARA_CONFIG_MAIN +#endif + +#if !defined(CATCH_CONFIG_DISABLE) +////// +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) + +#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__ ) +#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) +#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) +#endif// CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) + +#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) +#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CATCH_CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) + +#define CATCH_CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__ ) +#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CATCH_CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) + +#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( "CATCH_INFO", msg ) +#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( "CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) +#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( "CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) ) + +#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) +#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) +#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) +#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) +#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( "CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) + +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() + +// "BDD-style" convenience wrappers +#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) +#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc ) +#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc ) +#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc ) +#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc ) +#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc ) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE( ... ) INTERNAL_CATCH_TEST( "REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( "REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) + +#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( "REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr ) +#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, expr ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__ ) + +#define CHECK( ... ) INTERNAL_CATCH_TEST( "CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( "CHECK_FALSE", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ ) +#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( "CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( "CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( "CHECK_NOFAIL", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ ) + +#define CHECK_THROWS( ... ) INTERNAL_CATCH_THROWS( "CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( "CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr ) +#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( "CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( "CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( "CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg ) + +#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( "REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg ) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define INFO( msg ) INTERNAL_CATCH_INFO( "INFO", msg ) +#define WARN( msg ) INTERNAL_CATCH_MSG( "WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg ) +#define CAPTURE( msg ) INTERNAL_CATCH_INFO( "CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg) ) + +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) +#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) +#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) +#define FAIL( ... ) INTERNAL_CATCH_MSG( "FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ ) +#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( "FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() + +#endif + +#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) + +// "BDD-style" convenience wrappers +#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) + +#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc ) +#define WHEN( desc ) SECTION( std::string(" When: ") + desc ) +#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc ) +#define THEN( desc ) SECTION( std::string(" Then: ") + desc ) +#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc ) + +using Catch::Detail::Approx; + +#else +////// +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE( ... ) (void)(0) +#define CATCH_REQUIRE_FALSE( ... ) (void)(0) + +#define CATCH_REQUIRE_THROWS( ... ) (void)(0) +#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) +#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif// CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0) + +#define CATCH_CHECK( ... ) (void)(0) +#define CATCH_CHECK_FALSE( ... ) (void)(0) +#define CATCH_CHECKED_IF( ... ) if (__VA_ARGS__) +#define CATCH_CHECKED_ELSE( ... ) if (!(__VA_ARGS__)) +#define CATCH_CHECK_NOFAIL( ... ) (void)(0) + +#define CATCH_CHECK_THROWS( ... ) (void)(0) +#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0) +#define CATCH_CHECK_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_CHECK_NOTHROW( ... ) (void)(0) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THAT( arg, matcher ) (void)(0) + +#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define CATCH_INFO( msg ) (void)(0) +#define CATCH_WARN( msg ) (void)(0) +#define CATCH_CAPTURE( msg ) (void)(0) + +#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_METHOD_AS_TEST_CASE( method, ... ) +#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0) +#define CATCH_SECTION( ... ) +#define CATCH_FAIL( ... ) (void)(0) +#define CATCH_FAIL_CHECK( ... ) (void)(0) +#define CATCH_SUCCEED( ... ) (void)(0) + +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) + +// "BDD-style" convenience wrappers +#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) +#define CATCH_GIVEN( desc ) +#define CATCH_WHEN( desc ) +#define CATCH_AND_WHEN( desc ) +#define CATCH_THEN( desc ) +#define CATCH_AND_THEN( desc ) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE( ... ) (void)(0) +#define REQUIRE_FALSE( ... ) (void)(0) + +#define REQUIRE_THROWS( ... ) (void)(0) +#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0) +#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define REQUIRE_NOTHROW( ... ) (void)(0) + +#define CHECK( ... ) (void)(0) +#define CHECK_FALSE( ... ) (void)(0) +#define CHECKED_IF( ... ) if (__VA_ARGS__) +#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__)) +#define CHECK_NOFAIL( ... ) (void)(0) + +#define CHECK_THROWS( ... ) (void)(0) +#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0) +#define CHECK_THROWS_WITH( expr, matcher ) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CHECK_NOTHROW( ... ) (void)(0) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THAT( arg, matcher ) (void)(0) + +#define REQUIRE_THAT( arg, matcher ) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define INFO( msg ) (void)(0) +#define WARN( msg ) (void)(0) +#define CAPTURE( msg ) (void)(0) + +#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#define METHOD_AS_TEST_CASE( method, ... ) +#define REGISTER_TEST_CASE( Function, ... ) (void)(0) +#define SECTION( ... ) +#define FAIL( ... ) (void)(0) +#define FAIL_CHECK( ... ) (void)(0) +#define SUCCEED( ... ) (void)(0) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) + +#endif + +#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) + +// "BDD-style" convenience wrappers +#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) ) +#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) + +#define GIVEN( desc ) +#define WHEN( desc ) +#define AND_WHEN( desc ) +#define THEN( desc ) +#define AND_THEN( desc ) + +using Catch::Detail::Approx; + +#endif + +#endif // ! CATCH_CONFIG_IMPL_ONLY + +// start catch_reenable_warnings.h + + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(pop) +# else +# pragma clang diagnostic pop +# endif +#elif defined __GNUC__ +# pragma GCC diagnostic pop +#endif + +// end catch_reenable_warnings.h +// end catch.hpp +#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED + diff --git a/ThirdParty/Ert/external/catch2/dummy.cpp b/ThirdParty/Ert/external/catch2/dummy.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ThirdParty/Ert/lib/CMakeLists.txt b/ThirdParty/Ert/lib/CMakeLists.txt index 6b6ef43667..a57e50e212 100644 --- a/ThirdParty/Ert/lib/CMakeLists.txt +++ b/ThirdParty/Ert/lib/CMakeLists.txt @@ -55,8 +55,7 @@ if (ZLIB_FOUND) endif () if (ERT_BUILD_CXX) - list(APPEND opt_srcs util/TestArea.cpp - ecl/FortIO.cpp + list(APPEND opt_srcs ecl/FortIO.cpp ecl/Smspec.cpp ecl/EclFilename.cpp ) @@ -71,9 +70,9 @@ add_library(ecl util/rng.cpp util/lookup_table.cpp util/statistics.cpp util/mzran.cpp - util/set.cpp util/hash_node.cpp util/hash_sll.cpp + util/path.cpp util/hash.cpp util/node_data.cpp util/node_ctype.cpp @@ -81,7 +80,6 @@ add_library(ecl util/rng.cpp util/util_symlink.cpp util/util_lfs.c util/util_unlink.cpp - util/arg_pack.cpp util/vector.cpp util/parser.cpp util/stringlist.cpp @@ -90,9 +88,9 @@ add_library(ecl util/rng.cpp util/string_util.cpp util/type_vector_functions.cpp util/ecl_version.cpp - util/struct_vector.cpp util/perm_vector.cpp util/test_util.cpp + util/cxx_string_util.cpp ${opt_srcs} ecl/ecl_rsthead.cpp @@ -107,7 +105,9 @@ add_library(ecl util/rng.cpp ecl/ecl_grav.cpp ecl/ecl_grav_calc.cpp ecl/ecl_smspec.cpp + ecl/ecl_unsmry_loader.cpp ecl/ecl_sum_data.cpp + ecl/ecl_sum_file_data.cpp ecl/ecl_util.cpp ecl/ecl_kw.cpp ecl/ecl_sum.cpp @@ -152,15 +152,23 @@ add_library(ecl util/rng.cpp geometry/geo_region.cpp geometry/geo_polygon.cpp geometry/geo_polygon_collection.cpp + + src/fortio.cpp ) +if (ERT_WINDOWS) + set_target_properties(ecl PROPERTIES PREFIX "lib") + if (MSVC) + set_target_properties(ecl PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + endif() +endif () + target_link_libraries(ecl PUBLIC ${m} ${dl} ${pthread} ${blas} ${zlib} ${shlwapi} - ${ws2_32} ) target_include_directories(ecl @@ -170,6 +178,8 @@ target_include_directories(ecl PRIVATE ${ZLIB_INCLUDE_DIRS} util include + e3 + ${CMAKE_CURRENT_SOURCE_DIR}/private-include ${CMAKE_CURRENT_BINARY_DIR}/include ) @@ -179,14 +189,15 @@ target_compile_definitions(ecl PRIVATE -DECL_VERSION_MAJOR=${ECL_VERSION_MAJOR} -DECL_VERSION_MINOR=${ECL_VERSION_MINOR} -DECL_VERSION_MICRO=${ECL_VERSION_MICRO} + $<$:HOST_BIG_ENDIAN> ) target_compile_options(ecl PUBLIC ${pthreadarg}) if (ERT_USE_OPENMP) - target_compile_options(ecl PUBLIC ${OpenMP_C_FLAGS}) - set_property(TARGET ecl APPEND PROPERTY LINK_FLAGS ${OpenMP_C_FLAGS}) + target_compile_options(ecl PUBLIC ${OpenMP_CXX_FLAGS}) + set_property(TARGET ecl APPEND PROPERTY LINK_FLAGS ${OpenMP_CXX_FLAGS}) target_link_libraries( ecl PUBLIC ${OpenMP_EXE_LINKER_FLAGS}) endif () @@ -224,9 +235,19 @@ if (NOT BUILD_TESTS) return () endif () +add_executable(ecl3-testsuite test/testsuite.cpp + test/fortio.cpp +) +target_include_directories(ecl3-testsuite + PRIVATE e3 +) +target_link_libraries(ecl3-testsuite catch2 ecl) + +add_test(NAME ecl3 COMMAND ecl3-testsuite) + foreach (name ert_util_alloc_file_components + ert_util_split_path ert_util_approx_equal - ert_util_arg_pack ert_util_before_after ert_util_binary_split ert_util_buffer @@ -238,7 +259,6 @@ foreach (name ert_util_alloc_file_components ert_util_realpath ert_util_relpath_test ert_util_rng - ert_util_sprintf_escape ert_util_sscan_test ert_util_statistics ert_util_strcat_test @@ -249,19 +269,21 @@ foreach (name ert_util_alloc_file_components ert_util_vector_test ert_util_datetime ert_util_normal_path + ert_util_mkdir_p ) - add_executable(${name} util/tests/${name}.c) + add_executable(${name} util/tests/${name}.cpp) + target_include_directories(${name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/private-include) target_link_libraries(${name} ecl) add_test(NAME ${name} COMMAND ${name}) endforeach () -add_executable(ecl_smspec_node ecl/tests/ecl_smspec_node.c) +add_executable(ecl_smspec_node ecl/tests/ecl_smspec_node.cpp) target_link_libraries( ecl_smspec_node ecl) add_test(NAME ecl_smspec_node COMMAND ecl_smspec_node) -add_executable(ert_util_work_area util/tests/ert_util_work_area.c) +add_executable(ert_util_work_area util/tests/ert_util_work_area.cpp) target_link_libraries(ert_util_work_area ecl) add_test(NAME ert_util_work_area COMMAND ert_util_work_area data2/file1 @@ -270,48 +292,44 @@ add_test(NAME ert_util_work_area WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/util/tests ) -add_executable(ert_util_cwd_test util/tests/ert_util_cwd_test.c) +add_executable(ert_util_cwd_test util/tests/ert_util_cwd_test.cpp) target_link_libraries(ert_util_cwd_test ecl) add_test(NAME ert_util_cwd_test COMMAND ert_util_cwd_test ${CMAKE_CURRENT_BINARY_DIR}) -add_executable(ert_util_copy_file util/tests/ert_util_copy_file.c) +add_executable(ert_util_copy_file util/tests/ert_util_copy_file.cpp) target_link_libraries(ert_util_copy_file ecl) add_test(NAME ert_util_copy_file COMMAND ert_util_copy_file $) -add_executable(ert_util_file_readable util/tests/ert_util_file_readable.c) +add_executable(ert_util_file_readable util/tests/ert_util_file_readable.cpp) target_link_libraries(ert_util_file_readable ecl) add_test(NAME ert_util_file_readable COMMAND ert_util_file_readable) -add_executable(ert_util_path_stack_test util/tests/ert_util_path_stack_test.c) +add_executable(ert_util_path_stack_test util/tests/ert_util_path_stack_test.cpp) target_link_libraries(ert_util_path_stack_test ecl) add_test(NAME ert_util_path_stack_test COMMAND ert_util_path_stack_test ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) if (HAVE_BACKTRACE) - add_executable(ert_util_abort_gnu_tests util/tests/ert_util_abort_gnu_tests.c) + add_executable(ert_util_abort_gnu_tests util/tests/ert_util_abort_gnu_tests.cpp) target_link_libraries(ert_util_abort_gnu_tests ecl) add_test(NAME ert_util_abort_gnu_tests COMMAND ert_util_abort_gnu_tests) - add_executable(ert_util_addr2line util/tests/ert_util_addr2line.c) + add_executable(ert_util_addr2line util/tests/ert_util_addr2line.cpp) target_link_libraries(ert_util_addr2line ecl) add_test(NAME ert_util_addr2line COMMAND ert_util_addr2line) endif() if (HAVE_UTIL_ABORT_INTERCEPT) - add_executable(ert_util_struct_vector util/tests/ert_util_struct_vector.c) - target_link_libraries(ert_util_struct_vector ecl) - add_test(NAME ert_util_struct_vector COMMAND ert_util_struct_vector) - - add_executable(ert_util_type_vector_test util/tests/ert_util_type_vector_test.c) + add_executable(ert_util_type_vector_test util/tests/ert_util_type_vector_test.cpp) target_link_libraries(ert_util_type_vector_test ecl) add_test(NAME ert_util_type_vector_test COMMAND ert_util_type_vector_test) endif() if (ERT_HAVE_SPAWN) - add_executable(ert_util_spawn util/tests/ert_util_spawn.c) + add_executable(ert_util_spawn util/tests/ert_util_spawn.cpp) target_link_libraries(ert_util_spawn ecl) add_test(NAME ert_util_spawn COMMAND ert_util_spawn) endif() @@ -328,9 +346,14 @@ foreach (name ecl_alloc_cpgrid ecl_grid_copy ecl_grid_create ecl_grid_DEPTHZ + ecl_grid_unit_system ecl_grid_export ecl_grid_init_fwrite ecl_grid_reset_actnum + ecl_grid_ext_actnum + ecl_sum_data_intermediate_test + ecl_grid_cell_contains + ecl_unsmry_loader_test ecl_init_file ecl_kw_cmp_string ecl_kw_equal @@ -349,6 +372,7 @@ foreach (name ecl_alloc_cpgrid ecl_sum_writer ecl_util_filenames ecl_util_make_date_no_shift + ecl_util_make_date_shift ecl_util_month_range ecl_valid_basename test_ecl_nnc_data @@ -362,26 +386,24 @@ foreach (name ecl_alloc_cpgrid well_segment_collection ecl_file ) - add_executable(${name} ecl/tests/${name}.c) + add_executable(${name} ecl/tests/${name}.cpp) target_link_libraries(${name} ecl) + target_include_directories(${name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/private-include) add_test(NAME ${name} COMMAND ${name}) endforeach () -add_executable(ecl_grid_cell_contains ecl/tests/ecl_grid_cell_contains.c) -target_link_libraries(ecl_grid_cell_contains ecl) -add_test(NAME ecl_grid_cell_contains1 COMMAND ecl_grid_cell_contains) - if (HAVE_UTIL_ABORT_INTERCEPT) - add_executable(ecl_grid_corner ecl/tests/ecl_grid_corner.c) + add_executable(ecl_grid_corner ecl/tests/ecl_grid_corner.cpp) target_link_libraries(ecl_grid_corner ecl) add_test(NAME ecl_grid_corner COMMAND ecl_grid_corner) - add_executable(ecl_layer ecl/tests/ecl_layer.c) + add_executable(ecl_layer ecl/tests/ecl_layer.cpp) target_link_libraries(ecl_layer ecl) + target_include_directories(ecl_layer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/private-include) add_test(NAME ecl_layer COMMAND ecl_layer) endif() -add_executable(ecl_get_num_cpu ecl/tests/ecl_get_num_cpu_test.c) +add_executable(ecl_get_num_cpu ecl/tests/ecl_get_num_cpu_test.cpp) target_link_libraries(ecl_get_num_cpu ecl) add_test(NAME ecl_get_num_cpu COMMAND ecl_get_num_cpu ${CMAKE_CURRENT_SOURCE_DIR}/ecl/tests/data/num_cpu1 @@ -392,7 +414,7 @@ add_test(NAME ecl_get_num_cpu COMMAND ecl_get_num_cpu # The ecl_win64 application is not built as a proper test integrated # into the CTEST system. Should be invoked manually on Windows. if (ERT_WINDOWS) - add_executable(ecl_lfs ecl/tests/ecl_lfs.c) + add_executable(ecl_lfs ecl/tests/ecl_lfs.cpp) target_link_libraries(ecl_lfs ecl) endif() @@ -402,13 +424,13 @@ endif() foreach (name geo_util_xlines geo_polygon geo_polygon_collection) - add_executable(${name} geometry/tests/${name}.c) + add_executable(${name} geometry/tests/${name}.cpp) target_link_libraries(${name} ecl) add_test(NAME ${name} COMMAND ${name}) endforeach () if (ERT_BUILD_CXX) - foreach (test ert_util_unique_ptr ert_util_test_area_xx) + foreach (test ert_util_unique_ptr) add_executable(${test} util/tests/${test}.cpp) target_link_libraries(${test} ecl) add_test(NAME ${test} COMMAND ${test}) @@ -421,6 +443,52 @@ if (ERT_BUILD_CXX) endforeach () endif () +foreach(name ecl_coarse_test + ecl_grid_layer_contains + ecl_restart_test + ecl_nnc_export + ecl_nnc_export_get_tran + ecl_nnc_data_statoil_root + ecl_sum_case_exists + ecl_grid_lgr_name + ecl_region + ecl_grid_cell_contains_wellpath + ecl_region2region + ecl_grid_case + ecl_grid_simple + ecl_grid_volume + ecl_grid_dims + ecl_nnc_test + ecl_lgr_test + ecl_layer_statoil + ecl_dualp + ecl_grid_dx_dy_dz + ecl_sum_test + ecl_sum_report_step_equal + ecl_sum_report_step_compatible + ecl_file_statoil + ecl_fmt + ecl_rsthead + ecl_smspec + ecl_rft + ecl_grid_copy_statoil + ecl_fault_block_layer_statoil + well_state_load + well_state_load_missing_RSEG + well_segment_load + well_segment_branch_conn_load + well_info + well_conn_CF + well_conn_load + well_ts + well_dualp + well_lgr_load) + + add_executable(${name} ecl/tests/${name}.cpp) + target_link_libraries(${name} ecl) + target_include_directories(${name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/private-include) +endforeach() + if (NOT STATOIL_TESTDATA_ROOT) return () @@ -430,26 +498,21 @@ endif() # ecl # +add_test(NAME ecl_grid_dx_dy_dz1 COMMAND ecl_grid_dx_dy_dz ${_eclpath}/Gurbat/ECLIPSE) +add_test(NAME ecl_grid_dx_dy_dz3 COMMAND ecl_grid_dx_dy_dz ${_eclpath}/Troll/Ref2014/T07-4A-W2014-06) -add_executable(ecl_coarse_test ecl/tests/ecl_coarse_test.c) -target_link_libraries(ecl_coarse_test ecl) add_test(NAME ecl_coarse_test COMMAND ecl_coarse_test ${_eclpath}/LGCcase/LGC_TESTCASE2) -add_executable(ecl_grid_layer_contains ecl/tests/ecl_grid_layer_contains.c) -target_link_libraries(ecl_grid_layer_contains ecl) add_test(NAME ecl_grid_layer_contains1 COMMAND ecl_grid_layer_contains ${_eclpath}/Gurbat/ECLIPSE.EGRID) + add_test(NAME ecl_grid_layer_contains2 COMMAND ecl_grid_layer_contains ${_eclpath}/Mariner/MARINER.EGRID) -add_executable(ecl_restart_test ecl/tests/ecl_restart_test.c) -target_link_libraries(ecl_restart_test ecl) add_test(NAME ecl_restart_test COMMAND ecl_restart_test ${_eclpath}/Gurbat/ECLIPSE.UNRST) -add_executable(ecl_nnc_export ecl/tests/ecl_nnc_export.c) -target_link_libraries(ecl_nnc_export ecl) add_test(NAME ecl_nnc_export1 COMMAND ecl_nnc_export ${_eclpath}/Gurbat/ECLIPSE TRUE) add_test(NAME ecl_nnc_export2 COMMAND ecl_nnc_export ${_eclpath}/10kcase/TEST10K_FLT_LGR_NNC TRUE) add_test(NAME ecl_nnc_export3 COMMAND ecl_nnc_export ${_eclpath}/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3 TRUE) @@ -458,86 +521,53 @@ add_test(NAME ecl_nnc_export5 COMMAND ecl_nnc_export ${_eclpath}/DualPoro/DUALPO add_test(NAME ecl_nnc_export6 COMMAND ecl_nnc_export ${_eclpath}/nestedLGRcase/TESTCASE_NESTEDLGR TRUE) add_test(NAME ecl_nnc_export7 COMMAND ecl_nnc_export ${_eclpath}/TYRIHANS/BASE20150218_MULTFLT FALSE) -add_executable(ecl_nnc_export_get_tran ecl/tests/ecl_nnc_export_get_tran.c) -target_link_libraries(ecl_nnc_export_get_tran ecl) add_test(NAME ecl_nnc_export_get_tran COMMAND ecl_nnc_export_get_tran ${_eclpath}/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3) -add_executable(ecl_nnc_data_statoil_root ecl/tests/test_ecl_nnc_data_statoil_root.c) -target_link_libraries(ecl_nnc_data_statoil_root ecl) add_test(NAME ecl_nnc_data_statoil_root COMMAND ecl_nnc_data_statoil_root ${_eclpath}/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3 ${_eclpath}/flow-nnc/Simple4/SIMPLE_SUMMARY4 ${_eclpath}/flow-nnc/Gullfaks/GF_ACT_NEW_TEMP) -add_executable(ecl_util_make_date_shift ecl/tests/ecl_util_make_date_shift.c) -target_link_libraries(ecl_util_make_date_shift ecl) -add_test(NAME ecl_util_make_date_shift COMMAND ecl_util_make_date_shift) - -add_executable(ecl_sum_case_exists ecl/tests/ecl_sum_case_exists.c) -target_link_libraries(ecl_sum_case_exists ecl) add_test(NAME ecl_sum_case_exists COMMAND ecl_sum_case_exists ${_eclpath}/Gurbat/ECLIPSE ${_eclpath}/GurbatSummary/missingHeader/ECLIPSE ${_eclpath}/GurbatSummary/missingData/ECLIPSE) -add_executable(ecl_grid_lgr_name ecl/tests/ecl_grid_lgr_name.c) -target_link_libraries(ecl_grid_lgr_name ecl) add_test(NAME ecl_grid_lgr_name COMMAND ecl_grid_lgr_name ${_eclpath}/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3.EGRID) -add_executable(ecl_region ecl/tests/ecl_region.c) -target_link_libraries(ecl_region ecl) add_test(NAME ecl_region COMMAND ecl_region ${_eclpath}/Gurbat/ECLIPSE.EGRID) add_test(NAME ecl_grid_cell_contains2 COMMAND ecl_grid_cell_contains ${_eclpath}/Gurbat/ECLIPSE.EGRID) add_test(NAME ecl_grid_cell_contains3 COMMAND ecl_grid_cell_contains ${_eclpath}/FF12/FF12_2013B2.EGRID) add_test(NAME ecl_grid_cell_contains4 COMMAND ecl_grid_cell_contains ${_eclpath}/Brazil/R3_ICD.EGRID) -add_executable(ecl_grid_cell_contains_wellpath ecl/tests/ecl_grid_cell_contains_wellpath.c) -target_link_libraries(ecl_grid_cell_contains_wellpath ecl) add_test(NAME ecl_grid_cell_contains_wellpath1 COMMAND ecl_grid_cell_contains_wellpath ${_eclpath}/CellContains/model/SMS-0.EGRID ${_eclpath}/CellContains/R_PB-4H.jira) -add_executable(ecl_grid_cell_volume ecl/tests/ecl_grid_cell_volume.c) -target_link_libraries(ecl_grid_cell_volume ecl) -add_test(NAME ecl_grid_cell_volume1 COMMAND ecl_grid_cell_volume) -add_test(NAME ecl_grid_cell_volume2 COMMAND ecl_grid_cell_volume ${_eclpath}/Gurbat/ECLIPSE.EGRID) -add_test(NAME ecl_grid_cell_volume3 COMMAND ecl_grid_cell_volume ${_eclpath}/Heidrun/Summary/FF12_2013B3_CLEAN_RS.EGRID) -add_executable(ecl_region2region ecl/tests/ecl_region2region_test.c) -target_link_libraries(ecl_region2region ecl) add_test(NAME ecl_region2region COMMAND ecl_region2region ${_eclpath}/R2R/R2R.SMSPEC) -add_executable(ecl_grid_case ecl/tests/ecl_grid_case.c) -target_link_libraries(ecl_grid_case ecl) add_test(NAME ecl_grid_case COMMAND ecl_grid_case ${_eclpath}/Gurbat/ECLIPSE.EGRID ${_eclpath}/Gurbat/ECLIPSE) -add_executable(ecl_lgr_test ecl/tests/ecl_lgr_test.c) -target_link_libraries(ecl_lgr_test ecl) add_test(NAME ecl_lgr_test1 COMMAND ecl_lgr_test ${_eclpath}/10kcase/TEST10K_FLT_LGR_NNC.EGRID) add_test(NAME ecl_lgr_test2 COMMAND ecl_lgr_test ${_eclpath}/10kcase/TEST10K_FLT_LGR_NNC.GRID) add_test(NAME ecl_lgr_test3 COMMAND ecl_lgr_test ${_eclpath}/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3.EGRID) -add_executable(ecl_grid_simple ecl/tests/ecl_grid_simple.c) -target_link_libraries(ecl_grid_simple ecl) add_test(NAME ecl_grid_simple COMMAND ecl_grid_simple ${_eclpath}/Gurbat/ECLIPSE.EGRID) add_test(NAME ecl_grid_ecl2015_2 COMMAND ecl_grid_simple ${_eclpath}/Eclipse2015_NNC_BUG/FF15_2015B2_LGRM_RDI15_HIST_RDIREAL1_20142.EGRID) -add_executable(ecl_grid_export_statoil ecl/tests/ecl_grid_export.c) -target_link_libraries(ecl_grid_export_statoil ecl) add_test(NAME ecl_grid_export_statoil - COMMAND ecl_grid_export_statoil ${_eclpath}/Gurbat/ECLIPSE.EGRID) + COMMAND ecl_grid_export ${_eclpath}/Gurbat/ECLIPSE.EGRID) -add_executable(ecl_grid_volume ecl/tests/ecl_grid_volume.c) -target_link_libraries(ecl_grid_volume ecl) add_test(NAME ecl_grid_volume1 COMMAND ecl_grid_volume ${_eclpath}/Gurbat/ECLIPSE) add_test(NAME ecl_grid_volume2 COMMAND ecl_grid_volume ${_eclpath}/VolumeTest/TEST1) add_test(NAME ecl_grid_volume3 COMMAND ecl_grid_volume ${_eclpath}/OsebergSyd/Omega/OMEGA-0) @@ -550,8 +580,6 @@ add_test(NAME ecl_grid_volume4 COMMAND ecl_grid_volume ${_eclpath}/Norne/reservo # algorithm gets volumes ~ 0 whereas ECLIPSE reports ~10^9 for the same cell. # add_test( ecl_grid_volume5 ${EXECUTABLE_OUTPUT_PATH}/ecl_grid_volume ${_eclpath}/Heidrun/Summary/FF12_2013B3_CLEAN_RS) -add_executable(ecl_grid_dims ecl/tests/ecl_grid_dims.c) -target_link_libraries(ecl_grid_dims ecl) add_test(NAME ecl_grid_dims0 COMMAND ecl_grid_dims) add_test(NAME ecl_grid_dims1 COMMAND ecl_grid_dims ${_eclpath}/Gurbat/ECLIPSE.EGRID ${_eclpath}/Gurbat/ECLIPSE.INIT) add_test(NAME ecl_grid_dims2 COMMAND ecl_grid_dims ${_eclpath}/Gurbat/ECLIPSE.GRID ${_eclpath}/Gurbat/ECLIPSE.INIT) @@ -559,30 +587,20 @@ add_test(NAME ecl_grid_dims3 COMMAND ecl_grid_dims ${_eclpath}/Gurbat/ECLIPSE.EG add_test(NAME ecl_grid_dims4 COMMAND ecl_grid_dims ${_eclpath}/Gurbat/ECLIPSE.GRID ) add_test(NAME ecl_grid_dims5 COMMAND ecl_grid_dims ${_eclpath}/AmalgLGRcase/TESTCASE_AMALG_LGR.EGRID) -add_executable(ecl_nnc_test ecl/tests/ecl_nnc_test.c) -target_link_libraries(ecl_nnc_test ecl) add_test(NAME ecl_nnc_test1 COMMAND ecl_nnc_test ${_eclpath}/Gurbat/ECLIPSE.EGRID ) add_test(NAME ecl_nnc_test2 COMMAND ecl_nnc_test ${_eclpath}/10kcase/TEST10K_FLT_LGR_NNC.EGRID ) add_test(NAME ecl_nnc_test3 COMMAND ecl_nnc_test ${_eclpath}/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3.EGRID) add_test(NAME ecl_nnc_test4 COMMAND ecl_nnc_test ${_eclpath}/DualPoro/DUAL_DIFF.EGRID ) add_test(NAME ecl_nnc_test5 COMMAND ecl_nnc_test ${_eclpath}/nestedLGRcase/TESTCASE_NESTEDLGR.EGRID) -add_executable(ecl_layer_statoil ecl/tests/ecl_layer_statoil.c) -target_link_libraries(ecl_layer_statoil ecl) add_test(NAME ecl_layer_statoil COMMAND ecl_layer_statoil ${_eclpath}/Mariner/MARINER.EGRID ${_eclpath}/Mariner/faultblock.grdecl) -add_executable(ecl_dualp ecl/tests/ecl_dualp.c) -target_link_libraries(ecl_dualp ecl) add_test(NAME ecl_dualp COMMAND ecl_dualp ${_eclpath}/LGCcase/LGC_TESTCASE2) -add_executable(ecl_sum_test ecl/tests/ecl_sum_test.c) -target_link_libraries(ecl_sum_test ecl) add_test(NAME ecl_sum_test COMMAND ecl_sum_test ${_eclpath}/Gurbat/ECLIPSE) -add_executable(ecl_sum_report_step_equal ecl/tests/ecl_sum_report_step_equal.c) -target_link_libraries(ecl_sum_report_step_equal ecl) add_test(NAME ecl_sum_report_step_equal1 COMMAND ecl_sum_report_step_equal ${_eclpath}/Gurbat/ECLIPSE ${_eclpath}/Snorre/SNORRE FALSE) add_test(NAME ecl_sum_report_step_equal2 COMMAND ecl_sum_report_step_equal ${_eclpath}/Gurbat/ECLIPSE ${_eclpath}/Gurbat/ECLIPSE TRUE) add_test(NAME ecl_sum_report_step_equal3 COMMAND ecl_sum_report_step_equal ${_eclpath}/Gurbat/ECLIPSE ${_eclpath}/modGurbat/extraMinistep/ECLIPSE TRUE) @@ -590,8 +608,6 @@ add_test(NAME ecl_sum_report_step_equal4 COMMAND ecl_sum_report_step_equal ${_ec add_test(NAME ecl_sum_report_step_equal5 COMMAND ecl_sum_report_step_equal ${_eclpath}/Gurbat/ECLIPSE ${_eclpath}/modGurbat/enkf/ECLIPSE FALSE) add_test(NAME ecl_sum_report_step_equal6 COMMAND ecl_sum_report_step_equal ${_eclpath}/Snorre/SNORRE ${_eclpath}/Snorre2/SNORRE2 FALSE) -add_executable(ecl_sum_report_step_compatible ecl/tests/ecl_sum_report_step_compatible.c) -target_link_libraries(ecl_sum_report_step_compatible ecl) add_test(NAME ecl_sum_report_step_compatible1 COMMAND ecl_sum_report_step_compatible ${_eclpath}/Gurbat/ECLIPSE ${_eclpath}/Snorre/SNORRE FALSE) add_test(NAME ecl_sum_report_step_compatible2 COMMAND ecl_sum_report_step_compatible ${_eclpath}/Gurbat/ECLIPSE ${_eclpath}/Gurbat/ECLIPSE TRUE) add_test(NAME ecl_sum_report_step_compatible3 COMMAND ecl_sum_report_step_compatible ${_eclpath}/Gurbat/ECLIPSE ${_eclpath}/modGurbat/extraMinistep/ECLIPSE TRUE) @@ -599,64 +615,44 @@ add_test(NAME ecl_sum_report_step_compatible4 COMMAND ecl_sum_report_step_compat add_test(NAME ecl_sum_report_step_compatible5 COMMAND ecl_sum_report_step_compatible ${_eclpath}/Gurbat/ECLIPSE ${_eclpath}/modGurbat/enkf/ECLIPSE TRUE) add_test(NAME ecl_sum_report_step_compatible6 COMMAND ecl_sum_report_step_equal ${_eclpath}/Snorre/SNORRE ${_eclpath}/Snorre2/SNORRE2 FALSE) -add_executable(ecl_file_statoil ecl/tests/ecl_file_statoil.c) -target_link_libraries(ecl_file_statoil ecl) add_test(NAME ecl_file_statoil COMMAND ecl_file_statoil ${_eclpath}/Gurbat/ECLIPSE.UNRST ECLIPSE.UNRST) -add_executable(ecl_fmt ecl/tests/ecl_fmt.c) -target_link_libraries(ecl_fmt ecl) add_test(NAME ecl_fmt COMMAND ecl_fmt ${_eclpath}/Gurbat/ECLIPSE.UNRST ${_eclpath}/Gurbat/ECLIPSE.DATA) -add_executable(ecl_rsthead ecl/tests/ecl_rsthead.c) -target_link_libraries(ecl_rsthead ecl) add_test(NAME ecl_rsthead COMMAND ecl_rsthead ${_eclpath}/Gurbat/ECLIPSE.UNRST ${_eclpath}/DualPoro/DUALPORO.X0005) -add_executable(ecl_smspec ecl/tests/ecl_smspec.c) -target_link_libraries(ecl_smspec ecl) add_test(NAME ecl_smspec COMMAND ecl_smspec ${_eclpath}/Gurbat/ECLIPSE.SMSPEC ${_eclpath}/Heidrun/Summary/FF12_2013B3_CLEAN_RS.SMSPEC) -add_executable(ecl_rft ecl/tests/ecl_rft.c) -target_link_libraries(ecl_rft ecl) add_test(NAME ecl_rft_rft COMMAND ecl_rft ${_eclpath}/Gurbat/ECLIPSE.RFT RFT) add_test(NAME ecl_rft_rft_rw COMMAND ecl_rft ${_eclpath}/Gurbat/ECLIPSE.RFT RFT_RW) add_test(NAME ecl_rft_plt COMMAND ecl_rft ${_eclpath}/RFT/TEST1_1A.RFT PLT) add_test(NAME ecl_rft_mswplt COMMAND ecl_rft ${_eclpath}/RFT/RFT2.RFT MSW-PLT) add_test(NAME ecl_rft_alloc COMMAND ecl_rft ${_eclpath}/RFT/NORNE_ATW2013_RFTPLT_V2.RFT SIMPLE) -add_executable(ecl_grid_copy_statoil ecl/tests/ecl_grid_copy_statoil.c) -target_link_libraries(ecl_grid_copy_statoil ecl) - add_test(NAME ecl_grid_copy_statoil1 COMMAND ecl_grid_copy_statoil ${_eclpath}/Gurbat/ECLIPSE.EGRID) add_test(NAME ecl_grid_copy_statoil2 COMMAND ecl_grid_copy_statoil ${_eclpath}/Mariner/MARINER.EGRID) add_test(NAME ecl_grid_copy_statoil3 COMMAND ecl_grid_copy_statoil ${_eclpath}/LGCcase/LGC_TESTCASE2.EGRID) add_test(NAME ecl_grid_copy_statoil4 COMMAND ecl_grid_copy_statoil ${_eclpath}/10kcase/TEST10K_FLT_LGR_NNC.EGRID) -add_executable(ecl_fault_block_layer_statoil ecl/tests/ecl_fault_block_layer_statoil.c) -target_link_libraries(ecl_fault_block_layer_statoil ecl) add_test(NAME ecl_fault_block_layer_statoil COMMAND ecl_fault_block_layer_statoil ${_eclpath}/Mariner/MARINER.EGRID ${_eclpath}/Mariner/faultblock.grdecl) if (HAVE_UTIL_ABORT_INTERCEPT) - add_executable(ecl_fortio ecl/tests/ecl_fortio.c) + add_executable(ecl_fortio ecl/tests/ecl_fortio.cpp) target_link_libraries( ecl_fortio ecl) add_test(NAME ecl_fortio COMMAND ecl_fortio ${_eclpath}/Gurbat/ECLIPSE.UNRST) endif() -add_executable(well_state_load ecl/tests/well_state_load.c) -target_link_libraries( well_state_load ecl) - -add_executable(well_state_load_missing_RSEG ecl/tests/well_state_load_missing_RSEG.c) -target_link_libraries(well_state_load_missing_RSEG ecl) add_test(NAME well_state_load1 COMMAND well_state_load ${_eclpath}/Gurbat/ECLIPSE.EGRID ${_eclpath}/Gurbat/ECLIPSE.X0030) @@ -675,26 +671,16 @@ add_test(NAME well_state_load_missing_RSEG2 COMMAND well_state_load_missing_RSEG ${_eclpath}/Troll/MSW/MSW.EGRID ${_eclpath}/Troll/MSW/MSW.X0123) -add_executable(well_segment_load ecl/tests/well_segment_load.c) -target_link_libraries(well_segment_load ecl) add_test(NAME well_segment_load COMMAND well_segment_load ${_eclpath}/MSWcase/MSW_CASE.X0021) -add_executable(well_segment_branch_conn_load ecl/tests/well_segment_branch_conn_load.c) -target_link_libraries(well_segment_branch_conn_load ecl) add_test(NAME well_segment_branch_conn_load COMMAND well_segment_branch_conn_load ${_eclpath}/MSWcase/MSW_CASE.X0021) -add_executable(well_info ecl/tests/well_info.c) -target_link_libraries(well_info ecl) add_test(NAME well_info COMMAND well_info ${_eclpath}/Gurbat/ECLIPSE.EGRID) -add_executable(well_conn_CF ecl/tests/well_conn_CF.c) -target_link_libraries(well_conn_CF ecl) add_test(NAME well_conn_CF COMMAND well_conn_CF ${_eclpath}/Gurbat/ECLIPSE.X0060) -add_executable(well_conn_load ecl/tests/well_conn_load.c) -target_link_libraries(well_conn_load ecl) add_test(NAME well_conn_load1 COMMAND well_conn_load ${_eclpath}/Gurbat/ECLIPSE.X0030 F) add_test(NAME well_conn_load2 COMMAND well_conn_load ${_eclpath}/10kcase/TEST10K_FLT_LGR_NNC.X0021 F) add_test(NAME well_conn_load3 COMMAND well_conn_load ${_eclpath}/MSWcase/MSW_CASE.X0021 T) @@ -702,18 +688,12 @@ add_test(NAME well_conn_load4 COMMAND well_conn_load ${_eclpath}/AmalgLGRcase/TE add_test(NAME well_conn_load5 COMMAND well_conn_load ${_eclpath}/DualPoro/DUALPORO.X0009 F) add_test(NAME well_conn_load6 COMMAND well_conn_load ${_eclpath}/0.9.2_LGR/BASE_REF_XY3Z1_T30_WI.X0003 F) -add_executable(well_ts ecl/tests/well_ts.c) -target_link_libraries(well_ts ecl) add_test(NAME well_ts COMMAND well_ts ${_eclpath}/CO2case/BASE_CASE) -add_executable(well_dualp ecl/tests/well_dualp.c) -target_link_libraries(well_dualp ecl) add_test(NAME well_dualp COMMAND well_dualp ${_eclpath}/Gurbat/ECLIPSE.UNRST ${_eclpath}/DualPoro/DUALPORO.X0005) -add_executable(well_lgr_load ecl/tests/well_lgr_load.c) -target_link_libraries(well_lgr_load ecl) add_test(NAME well_lgr_load1 COMMAND well_lgr_load ${_eclpath}/0.9.2_LGR/BASE_REF_XY3Z1_T30_WI.EGRID ${_eclpath}/0.9.2_LGR/BASE_REF_XY3Z1_T30_WI.X0003) @@ -723,7 +703,7 @@ add_test(NAME well_lgr_load2 COMMAND well_lgr_load ${_eclpath}/AmalgLGRcase/TEST # # geometry # -add_executable(geo_surface geometry/tests/geo_surface.c) +add_executable(geo_surface geometry/tests/geo_surface.cpp) target_link_libraries(geo_surface ecl) add_test(NAME geo_surface COMMAND geo_surface ${_geopath}/Surface.irap diff --git a/ThirdParty/Ert/lib/build_config.h.in b/ThirdParty/Ert/lib/build_config.h.in index 2c4c6aa5fb..49d8e6f462 100644 --- a/ThirdParty/Ert/lib/build_config.h.in +++ b/ThirdParty/Ert/lib/build_config.h.in @@ -2,9 +2,6 @@ #cmakedefine HAVE_TIMEGM #cmakedefine HAVE_LOCALTIME_R #cmakedefine HAVE_REALPATH -#cmakedefine HAVE_TIMEDJOIN -#cmakedefine HAVE_YIELD_NP -#cmakedefine HAVE_YIELD #cmakedefine HAVE__USLEEP #cmakedefine HAVE_FNMATCH #cmakedefine HAVE_FTRUNCATE @@ -29,9 +26,6 @@ #cmakedefine HAVE_CXX_SHARED_PTR #cmakedefine HAVE_POSIX_UNLINK #cmakedefine HAVE_WINDOWS_UNLINK -#cmakedefine HAVE_NETINET_IN_H -#cmakedefine HAVE_ARPA_INET_H -#cmakedefine HAVE_WINSOCK2_H #cmakedefine HAVE_POSIX_ACCESS diff --git a/ThirdParty/Ert/lib/e3/ecl/fortio.h b/ThirdParty/Ert/lib/e3/ecl/fortio.h new file mode 100644 index 0000000000..3fcb5d95d5 --- /dev/null +++ b/ThirdParty/Ert/lib/e3/ecl/fortio.h @@ -0,0 +1,183 @@ +#ifndef ECL_FORTIO_H +#define ECL_FORTIO_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * As per the gnu fortran manual, int32 is sufficient for the record byte + * marker. optionally we could support 8-byte markers with either compile-time + * configuration or a run-time switch + * + * http://gcc.gnu.org/onlinedocs/gfortran/File-format-of-unformatted-sequential-files.html + * + * By default, all functions assume strict fortran compatibility (i.e. with + * trailing record size) and network (big-endian) byte order. + * + * + * A Fortran program writes unformatted data to file in a statemente like: + * + * integer array(100) + * write(unit) array + * + * it actually writes a head and tail in addition to the actual + * data. The header and tail is a 4 byte integer, which value is the + * number of bytes in the immediately following record. I.e. what is + * actually found on disk after the Fortran code above is: + * + * | 400 | array ...... | 400 | + * + */ + +/* + * The ecl_fio functions are exception safe, that is, if a function fails, the + * file pointer is rewinded to before the function was called, and output + * parameters are not modified, as if the function was never called. + * + * This comes with a few exceptions: + * 1. if ECL_ERR_SEEK is returned, the roll-back of the file pointer itself + * failed and NOTHING IS GUARANTEED. The file stream is left in an unspecified + * state, and must be recovered accordingly. + * 2. in eclfio_get, the output record buffer must always be considered dirty + * and incomplete unless the function suceeds, or ECL_EINVAL is returned. + * + * + * ECL_ERR_SEEK should be rather rare, but to provide strong guarantees, this + * error must be handled carefully. + */ + +/* + * every function takes a const char* opts parameter. This is a tiny + * configuration language inspired by printf and fopen. every character not in + * the set of keys is ignored. the opts parameter must be null terminated. + * + * if two options setting the same parameter (e.g. i and f, or e and E), the + * last one in the option string takes effect. + * + * options + * ------- + * record data types: + * c - characters, sizeof(char) + * i - (signed)integers, sizeof(int32_t), default + * f - single-precision float, sizeof(float) + * d - double-precision float, sizeof(double) + * + * behaviour: + * E - assume big-endian record data (default) + * e - assume little-endian record data + * t - transform/byteswap data according to data type (default) + * T - don't transform/byteswap data (does not affect heads/tails) + * + * endianness parameter applies to both head, tail, and data, but head/tail can + * be interepreted with endianness byteswapping data by disabling transform + * + * fault tolerance: + * # - ignore size hint + * ~ - force no-tail (assume only head) + * $ - allow no-tail (don't fail on missing tail) + */ + +/* + * Get the size (number of elements) of the current record. The file position + * is approperiately rewinded afterwards, as if the function was never called. + * + * If this function fails, out is not modified. + * + * If the read fails, ECL_ERR_READ is returned. + * + * This function is largely intended for peeking the size of the next record, + * to approperiately allocate a large enough buffer, which is useful when + * dealing with unknown files. If it is know in advance how large the records + * are, it is not necessary to call this function before reading a record. + */ +int eclfio_sizeof( FILE*, const char* opts, int32_t* out ); + +/* + * Advance the file position n records. The file position is reset if the + * function fails, as if the function was never called. + * + * Returns ECL_OK if all records were skipped. If it fails, either + * ECL_INVALID_RECORD or ECL_ERR_READ is returned, depending on the source of + * the error, same rules as that of eclfio_get. + * + * This function does not distinguish seek errors for any n not +-1, so to + * figure out which record fails, one record at a time must be skipped. + */ +int eclfio_skip( FILE*, const char* opts, int n ); + +/* + * Get the next record, and its number of elements. + * + * The record buffer is generally assumed to be of approperiate size, which can + * be queried with eclfio_sizeof. + * + * On success, the value of recordsize denotes the number of elements read, + * whose size is determined by the "cifd" options. It is generally assumed that + * recordsize upon calling this function contains the size of the record + * buffer, as a failsafe mechanism - if a record is larger than this value, the + * read will be aborted and the file position rolled back. To opt out of this + * check, add # to opts. + * + * Both recordsize and record can be NULL, in which case the number of elements + * read is not returned, and no data is returned respectively. This allows + * precise reporting on how many elements each skipped records contains. + * + * If the elementsize is larger than 1, and transformation has not been + * explicitly disabled, endianness will be converted appropriately. + * + * It is assumed that all record has an appropriate head and tail. If it is + * know that no record has a tail, force this by passing ~ in opts. However, if + * it is uncertain if all records has tails, or it's alternating between tail + * and no-tail, the $ option tries to recover from missing tails by assuming + * the current position is the start of the next record. + * + * The contents of record* is unspecified in case of read failures, and may not + * be relied upon. If the function returns ECL_EINVAL, the output record is + * untouched. + * + * This function returns ECL_OK upon success, ECL_ERR_READ in case of read- or + * seek errors, ECL_INVALID_RECORD if either the record tail is broken and + * options is set accordingly. The list of error codes is not exhaustive, and + * robust code should have fallthrough error handling cases. + */ +int eclfio_get( FILE*, const char* opts, int32_t* recordsize, void* record ); + +/* + * Put a record of nmemb elements + * + * This function will write both head and tail, unless tail writing is + * explicitly disabled with ~. If (nmemb * elemsize) overflows int32, the write + * is aborted and ECL_EINVAL is returned. + * + * put largely follows the same rules as get, including those of endianness. + * The file pointer is rolled back if any part of the function should fail, as + * if the function was never called. + * + * If a write fails after partial writes, no attempts are made to roll back + * written changes. + * + * Returns ECL_OK on success, or ECL_ERR_WRITE on failure. If ECL_ERR_SEEK is + * returned, the integrity of the file stream can not be guaranteed, and its + * state is considered unspecified. + */ +int eclfio_put( FILE*, const char* opts, int nmemb, const void* ); + +enum ecl_errno { + ECL_OK = 0, + ECL_ERR_UNKNOWN, + ECL_ERR_SEEK, + ECL_ERR_READ, + ECL_ERR_WRITE, + ECL_INVALID_RECORD, + ECL_EINVAL, +}; + +#ifdef __cplusplus +} +#endif + +#endif //ECL_FORTIO_H diff --git a/ThirdParty/Ert/lib/ecl/FortIO.cpp b/ThirdParty/Ert/lib/ecl/FortIO.cpp index 803640ad6e..c76985f173 100644 --- a/ThirdParty/Ert/lib/ecl/FortIO.cpp +++ b/ThirdParty/Ert/lib/ecl/FortIO.cpp @@ -19,7 +19,7 @@ #include -#include +#include #include diff --git a/ThirdParty/Ert/lib/ecl/ecl_box.cpp b/ThirdParty/Ert/lib/ecl/ecl_box.cpp index f5fc900fab..292e7a78b5 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_box.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_box.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_box.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_box.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ @@ -21,195 +21,36 @@ #include #include -#include +#include #include #include -#define ECL_BOX_TYPE_ID 6610643 - -struct ecl_box_struct { - UTIL_TYPE_ID_DECLARATION; - int grid_nx , grid_ny , grid_nz; - int grid_sx , grid_sy , grid_sz; /* xxx_sx : x stride */ - - int i1,i2,j1,j2,k1,k2; - int box_nx , box_ny , box_nz; - int box_sx , box_sy , box_sz; - int box_offset; - int active_size; - int *active_list; /* This is a list with active_size elements containing the index active index of the elemtents in the box. Will be NULL if there are no active elements. */ - int *global_list; /* This is a list of global indices which are present in the box. */ - const ecl_grid_type * parent_grid; -}; - - - -UTIL_IS_INSTANCE_FUNCTION( ecl_box , ECL_BOX_TYPE_ID) -UTIL_SAFE_CAST_FUNCTION( ecl_box , ECL_BOX_TYPE_ID) - - -/** - Observe that: - - 1. The coordinates i1,i2...k2 are assumed to be ZERO offset. - 2. The corrdinates are _INCLUSIVE_, i.e. the box is [i1..i2] x [j1..j2] x [k1..k2] - 3. Coordinates are truncated to [0,ni). - 4. Coordinates are interchanged, so __i1 can be greater than __i2. -*/ - -ecl_box_type * ecl_box_alloc(const ecl_grid_type * ecl_grid , int __i1,int __i2 , int __j1 , int __j2 , int __k1, int __k2) { - ecl_box_type * ecl_box = (ecl_box_type *)util_malloc(sizeof * ecl_box ); - UTIL_TYPE_ID_INIT( ecl_box , ECL_BOX_TYPE_ID); - ecl_box->parent_grid = ecl_grid; - /* Properties of the parent grid. */ - ecl_grid_get_dims( ecl_grid , &ecl_box->grid_nx , &ecl_box->grid_ny , &ecl_box->grid_nz , NULL); - ecl_box->grid_sx = 1; - ecl_box->grid_sy = ecl_box->grid_nx; - ecl_box->grid_sz = ecl_box->grid_nx * ecl_box->grid_ny; - +namespace ecl { + ecl_box::ecl_box(const ecl_grid_type * grid, int i1, int i2, int j1, int j2, int k1, int k2) : + grid(grid), + i1(std::min(i1,i2)), + i2(std::max(i1,i2)), + j1(std::min(j1,j2)), + j2(std::max(j1,j2)), + k1(std::min(k1,k2)), + k2(std::max(k1,k2)) { - int i1 = util_int_max( util_int_min(__i1 , __i2 ) , 0); - int i2 = util_int_min( util_int_max(__i1 , __i2 ) , ecl_box->grid_nx - 1); - - int j1 = util_int_max( util_int_min(__j1 , __j2 ) , 0 ); - int j2 = util_int_min( util_int_max(__j1 , __j2 ) , ecl_box->grid_ny - 1); - - int k1 = util_int_max( util_int_min(__k1 , __k2 ) , 0 ); - int k2 = util_int_min( util_int_max(__k1 , __k2 ) , ecl_box->grid_nz - 1); - - ecl_box->i1 = i1; - ecl_box->i2 = i2; - ecl_box->j1 = j1; - ecl_box->j2 = j2; - ecl_box->k1 = k1; - ecl_box->k2 = k2; - - /*Properties of the box: */ - ecl_box->box_nx = i2 - i1 + 1; - ecl_box->box_ny = j2 - j1 + 1; - ecl_box->box_nz = k2 - k1 + 1; - - ecl_box->box_sx = 1; - ecl_box->box_sy = ecl_box->box_nx; - ecl_box->box_sz = ecl_box->box_nx * ecl_box->box_ny; - ecl_box->box_offset = i1 * ecl_box->box_sx + j1 * ecl_box->box_sy + k1 * ecl_box->box_sz; - /* Counting the number of active elements in the box */ - - - { - int global_counter = 0; - int i,j,k; - ecl_box->active_size = 0; - ecl_box->active_list = (int*)util_calloc( ecl_box->box_nx * ecl_box->box_ny * ecl_box->box_nz , sizeof * ecl_box->active_list ); - ecl_box->global_list = (int*)util_calloc( ecl_box->box_nx * ecl_box->box_ny * ecl_box->box_nz , sizeof * ecl_box->global_list ); - for (k=k1; k <= k2; k++) - for (j=j1; j <= j2; j++) - for (i=i1; i <= i2; i++) { - { - int global_index = ecl_grid_get_global_index3( ecl_box->parent_grid , i , j , k); - ecl_box->global_list[global_counter] = global_index; - global_counter++; - } - { - int active_index = ecl_grid_get_active_index3( ecl_box->parent_grid , i,j,k); - if (active_index >= 0) { - ecl_box->active_list[ecl_box->active_size] = active_index; - ecl_box->active_size++; - } - } - } - - ecl_box->active_list = (int*)util_realloc( ecl_box->active_list , ecl_box->active_size * sizeof * ecl_box->active_list ); - } + for (int k=this->k1; k <= this->k2; k++) + for (int j=this->j1; j <= this->j2; j++) + for (int i=this->i1; i <= this->i2; i++) { + int active_index = ecl_grid_get_active_index3(this->grid, i, j , k); + if (active_index >= 0) + this->active_index_list.push_back(active_index); + this->global_index_list.push_back(ecl_grid_get_global_index3(this->grid, i, j, k)); + } } - return ecl_box; -} - - -/** - Returns true if the box contains the point (i,j,k). Observe the - following: - - ijk: These are zero offset. - ijk: Which are ON one of the box surfaces will return true. - -*/ - - -bool ecl_box_contains(const ecl_box_type * box , int i , int j , int k) { - - return (( box->i1 >= i ) && (i <= box->i2) && - ( box->j1 >= j ) && (j <= box->j2) && - ( box->k1 >= k ) && (k <= box->k2)); - -} - - - - -void ecl_box_free(ecl_box_type * ecl_box) { - util_safe_free(ecl_box->active_list ); - util_safe_free(ecl_box->global_list ); - free(ecl_box); -} - - - -/* -void ecl_kw_merge(ecl_kw_type * main_kw , const ecl_kw_type * sub_kw , const ecl_box_type * ecl_box) { - if (main_kw->sizeof_ctype != sub_kw->sizeof_ctype) - util_abort("%s: trying to combine two different underlying datatypes - aborting \n",__func__); - - if (ecl_kw_get_size(main_kw) != ecl_box_get_total_size(ecl_box)) - util_abort("%s box size and total_kw mismatch - aborting \n",__func__); - - if (ecl_kw_get_size(sub_kw) != ecl_box_get_box_size(ecl_box)) - util_abort("%s box size and total_kw mismatch - aborting \n",__func__); - - ecl_box_set_values(ecl_box , ecl_kw_get_data_ref(main_kw) , ecl_kw_get_data_ref(sub_kw) , main_kw->sizeof_ctype); -} -*/ - -void ecl_box_set_values(const ecl_box_type * ecl_box , char * main_field , const char * sub_field , int element_size) { - int i,j,k; - - for (k=0; k < ecl_box->box_nz; k++) - for(j=0; j < ecl_box->box_ny; j++) - for (i=0; i < ecl_box->box_nx; i++) { - int grid_index = k*ecl_box->grid_sz + j*ecl_box->grid_sy + i*ecl_box->grid_sx + ecl_box->box_offset; - int box_index = k*ecl_box->box_sz + j*ecl_box->box_sy + i*ecl_box->box_sx; - memcpy(&main_field[grid_index * element_size] , &sub_field[box_index * element_size] , element_size); - } -} - - -/* - Return the number of active element in the box. -*/ -int ecl_box_get_active_size( const ecl_box_type * ecl_box ) { - return ecl_box->active_size; -} -const int * ecl_box_get_active_list( const ecl_box_type * ecl_box ) { - return ecl_box->active_list; -} - - -/* - Return the number of global element in the box. -*/ -int ecl_box_get_global_size( const ecl_box_type * ecl_box ) { - return ecl_box->box_nx * ecl_box->box_ny * ecl_box->box_nz; -} + const std::vector& ecl_box::active_list() const { + return this->active_index_list; + } -const int * ecl_box_get_global_list( const ecl_box_type * ecl_box ) { - return ecl_box->global_list; } - - - - diff --git a/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp b/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp index 48e688d011..44fb620c58 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_coarse_cell.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include @@ -57,7 +57,7 @@ the cells represents the cells global index. - The grid contains a coarse cell of dimensions 4 x 3, the coarse - cell is in the global region: i \in [1,4] and j \in [1,3]. + cell is in the global region: i \in [1,4] and j \in [1,3]. - When solving the dynamical equations the properties of the coarse cell will enter as one entity, but when defining the grid initially @@ -68,7 +68,7 @@ - In the global grid the cells marked with [X] are active, i.e. when counting from zero the coarse cell will be the fourth active cell. This particular grid has a total of ten normal active cells - (i.e. 10 x [X]) and one coarse cell which is active. + (i.e. 10 x [X]) and one coarse cell which is active. - The dynamic variables like PRESSURE and SWAT are only represented @@ -100,7 +100,7 @@ following content: cell_list = {7,8,9,10,13,14,15,16,19,20,21,22} active_cells = {13,15,21} active_values = {1,1,1} <= This can 2/3 for dual porosity. - + */ @@ -114,7 +114,7 @@ struct ecl_coarse_cell_struct { int active_index; int active_fracture_index; - bool __cell_list_sorted; + bool __cell_list_sorted; int_vector_type * cell_list; int_vector_type * active_cells; int_vector_type * active_values; @@ -168,16 +168,16 @@ bool ecl_coarse_cell_equal( const ecl_coarse_cell_type * coarse_cell1 , const ec if (coarse_cell1->active_fracture_index != coarse_cell2->active_fracture_index) equal = false; - + if (equal) { if (memcmp( coarse_cell1->ijk , coarse_cell2->ijk , 6 * sizeof * coarse_cell1->ijk) != 0) equal = false; } - + if (equal) equal = int_vector_equal(coarse_cell1->active_cells , coarse_cell2->active_cells); - + if (equal) equal = int_vector_equal(coarse_cell1->active_values , coarse_cell2->active_values); @@ -188,7 +188,7 @@ bool ecl_coarse_cell_equal( const ecl_coarse_cell_type * coarse_cell1 , const ec ecl_coarse_cell_fprintf( coarse_cell1 , stdout ); ecl_coarse_cell_fprintf( coarse_cell2 , stdout ); } - + return equal; } @@ -295,17 +295,17 @@ void ecl_coarse_cell_update_index( ecl_coarse_cell_type * coarse_cell , int glob (*active_index) += 1; } } - + if (active_value & CELL_ACTIVE_FRACTURE) { if (coarse_cell->active_fracture_index == -1) { coarse_cell->active_fracture_index = *active_fracture_index; (*active_fracture_index) += 1; } } - + int_vector_append( coarse_cell->active_cells , global_index ); int_vector_append( coarse_cell->active_values , active_value ); - + if (int_vector_size( coarse_cell->active_values ) > 1) { if (int_vector_reverse_iget( coarse_cell->active_values , -2 ) != active_value) util_abort("%s: Sorry - current coarse cell implementation requires that all active cells have the same active value\n",__func__); @@ -346,7 +346,7 @@ void ecl_coarse_cell_fprintf( const ecl_coarse_cell_type * coarse_cell , FILE * fprintf(stream," i : %3d - %3d\n",coarse_cell->ijk[0] , coarse_cell->ijk[1]); fprintf(stream," j : %3d - %3d\n",coarse_cell->ijk[2] , coarse_cell->ijk[3]); fprintf(stream," k : %3d - %3d\n",coarse_cell->ijk[4] , coarse_cell->ijk[5]); - fprintf(stream," active_cells : " ); int_vector_fprintf( coarse_cell->active_cells , stream , "" , "%5d "); - fprintf(stream," active_values : " ); int_vector_fprintf( coarse_cell->active_values , stream , "" , "%5d "); + fprintf(stream," active_cells : " ); int_vector_fprintf( coarse_cell->active_cells , stream , "" , "%5d "); + fprintf(stream," active_values : " ); int_vector_fprintf( coarse_cell->active_values , stream , "" , "%5d "); //fprintf(stream," Cells : " ); int_vector_fprintf( coarse_cell->cell_list , stream , "" , "%5d "); } diff --git a/ThirdParty/Ert/lib/ecl/ecl_file.cpp b/ThirdParty/Ert/lib/ecl/ecl_file.cpp index 510c87f2cf..6384912bf6 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_file.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_file.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -505,24 +505,26 @@ ecl_file_view_type * ecl_file_get_summary_view( ecl_file_type * ecl_file , int r */ /** - The ecl_file_scan() function will scan through the whole file and - build up an index of all the kewyords. The map created from this - scan will be stored under the 'global_view' field; and all - subsequent lookup operations will ultimately be based on the global - map. + The ecl_file_scan() function will scan through the whole file and build up an + index of all the kewyords. The map created from this scan will be stored + under the 'global_view' field; and all subsequent lookup operations will + ultimately be based on the global map. + + The ecl_file_scan function will scan through the file as long as it finds + valid ecl_kw instances on the disk; it will return when EOF is encountered or + an invalid ecl_kw instance is detected. This implies that for a partly broken + file the ecl_file_scan function will index the valid keywords which are in + the file, possible garbage at the end will be ignored. */ -static bool ecl_file_scan( ecl_file_type * ecl_file ) { - bool scan_ok = false; +static void ecl_file_scan( ecl_file_type * ecl_file ) { fortio_fseek( ecl_file->fortio , 0 , SEEK_SET ); { ecl_kw_type * work_kw = ecl_kw_alloc_new("WORK-KW" , 0 , ECL_INT , NULL); while (true) { - if (fortio_read_at_eof(ecl_file->fortio)) { - scan_ok = true; + if (fortio_read_at_eof(ecl_file->fortio)) break; - } { offset_type current_offset = fortio_ftell( ecl_file->fortio ); @@ -542,10 +544,7 @@ static bool ecl_file_scan( ecl_file_type * ecl_file ) { ecl_kw_free( work_kw ); } - if (scan_ok) - ecl_file_view_make_index( ecl_file->global_view ); - - return scan_ok; + ecl_file_view_make_index( ecl_file->global_view ); } @@ -590,19 +589,16 @@ ecl_file_type * ecl_file_open( const char * filename , int flags) { ecl_file->fortio = fortio; ecl_file->global_view = ecl_file_view_alloc( ecl_file->fortio , &ecl_file->flags , ecl_file->inv_view , true ); - if (ecl_file_scan( ecl_file )) { - ecl_file_select_global( ecl_file ); + ecl_file_scan( ecl_file ); + ecl_file_select_global( ecl_file ); - if (ecl_file_view_check_flags( ecl_file->flags , ECL_FILE_CLOSE_STREAM)) - fortio_fclose_stream( ecl_file->fortio ); + if (ecl_file_view_check_flags( ecl_file->flags , ECL_FILE_CLOSE_STREAM)) + fortio_fclose_stream( ecl_file->fortio ); - return ecl_file; - } else { - ecl_file_close( ecl_file ); - return NULL; - } + return ecl_file; } else return NULL; + } @@ -800,6 +796,7 @@ ecl_version_enum ecl_file_get_ecl_version( const ecl_file_type * file ) { return FRONTSIM; util_abort("%s: Simulator version value:%d not recognized \n",__func__ , int_value ); + return (ecl_version_enum)0; } /* diff --git a/ThirdParty/Ert/lib/ecl/ecl_file_kw.cpp b/ThirdParty/Ert/lib/ecl/ecl_file_kw.cpp index e07c9884d6..5d5065c370 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_file_kw.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_file_kw.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include diff --git a/ThirdParty/Ert/lib/ecl/ecl_file_view.cpp b/ThirdParty/Ert/lib/ecl/ecl_file_view.cpp index ed3e549ebd..0a6e0a7622 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_file_view.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_file_view.cpp @@ -17,9 +17,11 @@ */ +#include +#include + #include #include -#include #include #include @@ -33,7 +35,7 @@ struct ecl_file_view_struct { vector_type * kw_list; /* This is a vector of ecl_file_kw instances corresponding to the content of the file. */ hash_type * kw_index; /* A hash table with integer vectors of indices - see comment below. */ - stringlist_type * distinct_kw; /* A stringlist of the keywords occuring in the file - each string occurs ONLY ONCE. */ + std::vector distinct_kw; /* A list of the keywords occuring in the file - each string occurs ONLY ONCE. */ fortio_type * fortio; /* The same fortio instance pointer as in the ecl_file styructure. */ bool owner; /* Is this map the owner of the ecl_file_kw instances; only true for the global_map. */ inv_map_type * inv_map; /* Shared reference owned by the ecl_file structure. */ @@ -71,15 +73,16 @@ const char * ecl_file_view_get_src_file( const ecl_file_view_type * file_view ) ecl_file_view_type * ecl_file_view_alloc( fortio_type * fortio , int * flags , inv_map_type * inv_map , bool owner ) { - ecl_file_view_type * ecl_file_view = (ecl_file_view_type*)util_malloc( sizeof * ecl_file_view ); + ecl_file_view_type * ecl_file_view = new ecl_file_view_type(); + ecl_file_view->kw_list = vector_alloc_new(); ecl_file_view->kw_index = hash_alloc(); - ecl_file_view->distinct_kw = stringlist_alloc_new(); ecl_file_view->child_list = vector_alloc_new(); ecl_file_view->owner = owner; ecl_file_view->fortio = fortio; ecl_file_view->inv_map = inv_map; ecl_file_view->flags = flags; + return ecl_file_view; } @@ -101,7 +104,7 @@ int ecl_file_view_get_global_index( const ecl_file_view_type * ecl_file_view , c void ecl_file_view_make_index( ecl_file_view_type * ecl_file_view ) { - stringlist_clear( ecl_file_view->distinct_kw ); + ecl_file_view->distinct_kw.clear(); hash_clear( ecl_file_view->kw_index ); { int i; @@ -111,7 +114,7 @@ void ecl_file_view_make_index( ecl_file_view_type * ecl_file_view ) { if ( !hash_has_key( ecl_file_view->kw_index , header )) { int_vector_type * index_vector = int_vector_alloc( 0 , -1 ); hash_insert_hash_owned_ref( ecl_file_view->kw_index , header , index_vector , int_vector_free__); - stringlist_append_copy( ecl_file_view->distinct_kw , header); + ecl_file_view->distinct_kw.push_back(header); } { @@ -200,11 +203,12 @@ int ecl_file_view_find_kw_value( const ecl_file_view_type * ecl_file_view , cons } const char * ecl_file_view_iget_distinct_kw( const ecl_file_view_type * ecl_file_view , int index) { - return stringlist_iget( ecl_file_view->distinct_kw , index); + const std::string& string = ecl_file_view->distinct_kw[index]; + return string.c_str(); } int ecl_file_view_get_num_distinct_kw( const ecl_file_view_type * ecl_file_view ) { - return stringlist_get_size( ecl_file_view->distinct_kw ); + return ecl_file_view->distinct_kw.size(); } int ecl_file_view_get_size( const ecl_file_view_type * ecl_file_view ) { @@ -301,9 +305,9 @@ void ecl_file_view_add_kw( ecl_file_view_type * ecl_file_view , ecl_file_kw_type void ecl_file_view_free( ecl_file_view_type * ecl_file_view ) { vector_free( ecl_file_view->child_list ); hash_free( ecl_file_view->kw_index ); - stringlist_free( ecl_file_view->distinct_kw ); vector_free( ecl_file_view->kw_list ); - free( ecl_file_view ); + + delete ecl_file_view; } void ecl_file_view_free__( void * arg ) { @@ -558,7 +562,7 @@ bool ecl_file_view_has_report_step( const ecl_file_view_type * ecl_file_view , i time_t ecl_file_view_iget_restart_sim_date(const ecl_file_view_type * ecl_file_view , int seqnum_index) { time_t sim_time = -1; - ecl_file_view_type * seqnum_map = seqnum_map = ecl_file_view_alloc_blockview( ecl_file_view , SEQNUM_KW , seqnum_index); + ecl_file_view_type * seqnum_map = ecl_file_view_alloc_blockview( ecl_file_view , SEQNUM_KW , seqnum_index); if (seqnum_map != NULL) { ecl_kw_type * intehead_kw = ecl_file_view_iget_named_kw( seqnum_map , INTEHEAD_KW , 0); @@ -778,7 +782,7 @@ void ecl_file_view_fclose_stream( ecl_file_view_type * file_view ) { void ecl_file_view_write_index(const ecl_file_view_type * file_view, FILE * ostream) { int size = ecl_file_view_get_size(file_view); util_fwrite_int( size , ostream); - + ecl_file_kw_type * file_kw; for (int i = 0; i < size; i++) { file_kw = ecl_file_view_iget_file_kw( file_view, i ); @@ -791,7 +795,7 @@ ecl_file_view_type * ecl_file_view_fread_alloc( fortio_type * fortio , int * fla int index_size = util_fread_int(istream); ecl_file_kw_type ** file_kw_list = ecl_file_kw_fread_alloc_multiple( istream, index_size); if (file_kw_list) { - ecl_file_view_type * file_view = ecl_file_view_alloc( fortio , flags , inv_map , true ); + ecl_file_view_type * file_view = ecl_file_view_alloc( fortio , flags , inv_map , true ); for (int i=0; i < index_size; i++) ecl_file_view_add_kw(file_view , file_kw_list[i]); diff --git a/ThirdParty/Ert/lib/ecl/ecl_grav.cpp b/ThirdParty/Ert/lib/ecl/ecl_grav.cpp index 5d25b9b966..42e96c240b 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grav.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grav.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include @@ -28,12 +28,12 @@ #include #include #include -#include #include #include #include #include +#include "detail/ecl/ecl_grid_cache.hpp" /** This file contains datastructures for calculating changes in @@ -67,7 +67,7 @@ typedef struct ecl_grav_phase_struct ecl_grav_phase_type; struct ecl_grav_struct { const ecl_file_type * init_file; /* The init file - a shared reference owned by calling scope. */ - ecl_grid_cache_type * grid_cache; /* An internal specialized structure to facilitate fast grid lookup. */ + ecl::ecl_grid_cache * grid_cache; /* An internal specialized structure to facilitate fast grid lookup. */ bool * aquifer_cell; /* Numerical aquifer cells should be ignored. */ hash_type * surveys; /* A hash table containg ecl_grav_survey_type instances; one instance for each interesting time. */ @@ -88,7 +88,7 @@ struct ecl_grav_struct { #define ECL_GRAV_SURVEY_ID 88517 struct ecl_grav_survey_struct { UTIL_TYPE_ID_DECLARATION; - const ecl_grid_cache_type * grid_cache; + const ecl::ecl_grid_cache * grid_cache; const bool * aquifer_cell; char * name; /* Name of the survey - arbitrary string. */ double * porv; /* Reference shared by the ecl_grav_phase structures - i.e. it must not be updated. */ @@ -104,7 +104,7 @@ struct ecl_grav_survey_struct { #define ECL_GRAV_PHASE_TYPE_ID 1066652 struct ecl_grav_phase_struct { UTIL_TYPE_ID_DECLARATION; - const ecl_grid_cache_type * grid_cache; + const ecl::ecl_grid_cache * grid_cache; const bool * aquifer_cell; double * fluid_mass; /* The total fluid in place (mass) of this phase - for each active cell.*/ double * work; /* Temporary used in the summation over all cells. */ @@ -157,7 +157,7 @@ static const char * get_den_kw( ecl_phase_enum phase , ecl_version_enum ecl_vers static void ecl_grav_phase_ensure_work( ecl_grav_phase_type * grav_phase) { if (grav_phase->work == NULL) - grav_phase->work = (double*)util_calloc( ecl_grid_cache_get_size( grav_phase->grid_cache ) , sizeof * grav_phase->work ); + grav_phase->work = (double*)util_calloc( grav_phase->grid_cache->size() , sizeof * grav_phase->work ); } @@ -168,7 +168,7 @@ static double ecl_grav_phase_eval( ecl_grav_phase_type * base_phase , ecl_grav_phase_ensure_work( base_phase ); if ((monitor_phase == NULL) || (base_phase->phase == monitor_phase->phase)) { - const ecl_grid_cache_type * grid_cache = base_phase->grid_cache; + const ecl::ecl_grid_cache& grid_cache = *(base_phase->grid_cache); const bool * aquifer = base_phase->aquifer_cell; double * mass_diff = base_phase->work; double deltag; @@ -179,10 +179,10 @@ static double ecl_grav_phase_eval( ecl_grav_phase_type * base_phase , { int index; if (monitor_phase == NULL) { - for (index = 0; index < ecl_grid_cache_get_size( grid_cache ); index++) + for (index = 0; index < grid_cache.size(); index++) mass_diff[index] = - base_phase->fluid_mass[index]; } else { - for (index = 0; index < ecl_grid_cache_get_size( grid_cache ); index++) + for (index = 0; index < grid_cache.size(); index++) mass_diff[index] = monitor_phase->fluid_mass[index] - base_phase->fluid_mass[index]; } } @@ -210,11 +210,11 @@ static ecl_grav_phase_type * ecl_grav_phase_alloc( ecl_grav_type * ecl_grav , grav_calc_type calc_type) { const ecl_file_type * init_file = ecl_grav->init_file; - const ecl_grid_cache_type * grid_cache = ecl_grav->grid_cache; + const ecl::ecl_grid_cache * grid_cache = ecl_grav->grid_cache; const char * sat_kw_name = ecl_util_get_phase_name( phase ); { ecl_grav_phase_type * grav_phase = (ecl_grav_phase_type*)util_malloc( sizeof * grav_phase ); - const int size = ecl_grid_cache_get_size( grid_cache ); + const int size = grid_cache->size(); UTIL_TYPE_ID_INIT( grav_phase , ECL_GRAV_PHASE_TYPE_ID ); grav_phase->grid_cache = grid_cache; @@ -305,7 +305,7 @@ static ecl_grav_phase_type * ecl_grav_phase_alloc( ecl_grav_type * ecl_grav , static void ecl_grav_phase_free( ecl_grav_phase_type * grav_phase ) { - util_safe_free( grav_phase->work ); + free( grav_phase->work ); free( grav_phase->fluid_mass ); free( grav_phase ); } @@ -358,7 +358,7 @@ static ecl_grav_survey_type * ecl_grav_survey_alloc_empty(const ecl_grav_type * survey->phase_map = hash_alloc(); if (calc_type & GRAV_CALC_USE_PORV) - survey->porv = (double*)util_calloc( ecl_grid_cache_get_size( ecl_grav->grid_cache ) , sizeof * survey->porv ); + survey->porv = (double*)util_calloc( ecl_grav->grid_cache->size() , sizeof * survey->porv ); else survey->porv = NULL; @@ -375,17 +375,17 @@ static UTIL_SAFE_CAST_FUNCTION( ecl_grav_survey , ECL_GRAV_SURVEY_ID ) */ static void ecl_grav_survey_assert_RPORV( const ecl_grav_survey_type * survey , const ecl_file_type * init_file ) { - const ecl_grid_cache_type * grid_cache = survey->grid_cache; - int active_size = ecl_grid_cache_get_size( grid_cache ); + const ecl::ecl_grid_cache& grid_cache = *(survey->grid_cache); + int active_size = grid_cache.size(); const ecl_kw_type * init_porv_kw = ecl_file_iget_named_kw( init_file , PORV_KW , 0); int check_points = 100; int check_nr = 0; + const std::vector& global_index = grid_cache.global_index(); while (check_nr < check_points) { - int active_index = rand() % active_size; - int global_index = ecl_grid_cache_iget_global_index( grid_cache , active_index ); + int active_index = rand() % active_size; - double init_porv = ecl_kw_iget_as_double( init_porv_kw , global_index ); /* NB - this uses global indexing. */ + double init_porv = ecl_kw_iget_as_double( init_porv_kw , global_index[active_index] ); /* NB - this uses global indexing. */ if (init_porv > 0) { double rporv = survey->porv[ active_index ]; double log_pormod = log10( rporv / init_porv ); @@ -479,12 +479,12 @@ static ecl_grav_survey_type * ecl_grav_survey_alloc_RPORV(ecl_grav_type * ecl_gr static ecl_grav_survey_type * ecl_grav_survey_alloc_PORMOD(ecl_grav_type * ecl_grav , const ecl_file_view_type * restart_file , const char * name ) { - ecl_grid_cache_type * grid_cache = ecl_grav->grid_cache; + ecl::ecl_grid_cache& grid_cache = *(ecl_grav->grid_cache); ecl_grav_survey_type * survey = ecl_grav_survey_alloc_empty( ecl_grav , name , GRAV_CALC_PORMOD); ecl_kw_type * init_porv_kw = ecl_file_iget_named_kw( ecl_grav->init_file , PORV_KW , 0 ); /* Global indexing */ ecl_kw_type * pormod_kw = ecl_file_view_iget_named_kw( restart_file , PORMOD_KW , 0 ); /* Active indexing */ - const int size = ecl_grid_cache_get_size( grid_cache ); - const int * global_index = ecl_grid_cache_get_global_index( grid_cache ); + const int size = grid_cache.size(); + const auto& global_index = grid_cache.global_index(); int active_index; for (active_index = 0; active_index < size; active_index++) @@ -529,7 +529,7 @@ static ecl_grav_survey_type * ecl_grav_survey_alloc_RFIP(ecl_grav_type * ecl_gra static void ecl_grav_survey_free( ecl_grav_survey_type * grav_survey ) { free( grav_survey->name ); - util_safe_free( grav_survey->porv ); + free( grav_survey->porv ); vector_free( grav_survey->phase_list ); hash_free( grav_survey->phase_map ); free( grav_survey ); @@ -572,8 +572,8 @@ static double ecl_grav_survey_eval( const ecl_grav_survey_type * base_survey, ecl_grav_type * ecl_grav_alloc( const ecl_grid_type * ecl_grid, const ecl_file_type * init_file) { ecl_grav_type * ecl_grav = (ecl_grav_type*)util_malloc( sizeof * ecl_grav ); ecl_grav->init_file = init_file; - ecl_grav->grid_cache = ecl_grid_cache_alloc( ecl_grid ); - ecl_grav->aquifer_cell = ecl_grav_common_alloc_aquifer_cell( ecl_grav->grid_cache , ecl_grav->init_file ); + ecl_grav->grid_cache = new ecl::ecl_grid_cache(ecl_grid); + ecl_grav->aquifer_cell = ecl_grav_common_alloc_aquifer_cell( *(ecl_grav->grid_cache) , ecl_grav->init_file ); ecl_grav->surveys = hash_alloc(); ecl_grav->std_density = hash_alloc(); @@ -687,7 +687,7 @@ void ecl_grav_add_std_density( ecl_grav_type * grav , ecl_phase_enum phase , int void ecl_grav_free( ecl_grav_type * ecl_grav ) { - ecl_grid_cache_free( ecl_grav->grid_cache ); + delete ecl_grav->grid_cache; free( ecl_grav->aquifer_cell ); hash_free( ecl_grav->surveys ); hash_free( ecl_grav->std_density ); diff --git a/ThirdParty/Ert/lib/ecl/ecl_grav_calc.cpp b/ThirdParty/Ert/lib/ecl/ecl_grav_calc.cpp index ae41b98c69..240fc64a87 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grav_calc.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grav_calc.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include diff --git a/ThirdParty/Ert/lib/ecl/ecl_grav_common.cpp b/ThirdParty/Ert/lib/ecl/ecl_grav_common.cpp index 37da5a000c..9f63c9583c 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grav_common.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grav_common.cpp @@ -21,32 +21,32 @@ #include #include -#include +#include #include #include #include -#include #include #include +#include "detail/ecl/ecl_grid_cache.hpp" /* This file contains code which is common to both the ecl_grav implementation for gravity changes, and the ecl_subsidence implementation for changes in subsidence. */ -bool * ecl_grav_common_alloc_aquifer_cell( const ecl_grid_cache_type * grid_cache , const ecl_file_type * init_file) { - bool * aquifer_cell = (bool*)util_calloc( ecl_grid_cache_get_size( grid_cache ) , sizeof * aquifer_cell ); +bool * ecl_grav_common_alloc_aquifer_cell( const ecl::ecl_grid_cache& grid_cache , const ecl_file_type * init_file) { + bool * aquifer_cell = (bool*) util_calloc( grid_cache.size() , sizeof * aquifer_cell ); - for (int active_index = 0; active_index < ecl_grid_cache_get_size( grid_cache ); active_index++) + for (int active_index = 0; active_index < grid_cache.size(); active_index++) aquifer_cell[ active_index ] = false; if (ecl_file_has_kw( init_file , AQUIFER_KW)) { ecl_kw_type * aquifer_kw = ecl_file_iget_named_kw( init_file , AQUIFER_KW , 0); const int * aquifer_data = ecl_kw_get_int_ptr( aquifer_kw ); - for (int active_index = 0; active_index < ecl_grid_cache_get_size( grid_cache ); active_index++) { + for (int active_index = 0; active_index < grid_cache.size(); active_index++) { if (aquifer_data[ active_index ] < 0) aquifer_cell[ active_index ] = true; } @@ -57,13 +57,13 @@ bool * ecl_grav_common_alloc_aquifer_cell( const ecl_grid_cache_type * grid_cach -double ecl_grav_common_eval_biot_savart( const ecl_grid_cache_type * grid_cache , ecl_region_type * region , const bool * aquifer , const double * weight , double utm_x , double utm_y , double depth) { - const double * xpos = ecl_grid_cache_get_xpos( grid_cache ); - const double * ypos = ecl_grid_cache_get_ypos( grid_cache ); - const double * zpos = ecl_grid_cache_get_zpos( grid_cache ); +double ecl_grav_common_eval_biot_savart( const ecl::ecl_grid_cache& grid_cache , ecl_region_type * region , const bool * aquifer , const double * weight , double utm_x , double utm_y , double depth) { + const auto& xpos = grid_cache.xpos(); + const auto& ypos = grid_cache.ypos(); + const auto& zpos = grid_cache.zpos(); double sum = 0; if (region == NULL) { - const int size = ecl_grid_cache_get_size( grid_cache ); + const int size = grid_cache.size(); int index; for ( index = 0; index < size; index++) { if (!aquifer[index]) { @@ -125,18 +125,18 @@ static inline double ecl_grav_common_eval_geertsma_kernel(int index, const doubl } -double ecl_grav_common_eval_geertsma( const ecl_grid_cache_type * grid_cache , ecl_region_type * region , const bool * aquifer , const double * weight , double utm_x , double utm_y , double depth, double poisson_ratio, double seabed) { - const double * xpos = ecl_grid_cache_get_xpos( grid_cache ); - const double * ypos = ecl_grid_cache_get_ypos( grid_cache ); - const double * zpos = ecl_grid_cache_get_zpos( grid_cache ); +double ecl_grav_common_eval_geertsma( const ecl::ecl_grid_cache& grid_cache , ecl_region_type * region , const bool * aquifer , const double * weight , double utm_x , double utm_y , double depth, double poisson_ratio, double seabed) { + const auto& xpos = grid_cache.xpos(); + const auto& ypos = grid_cache.ypos(); + const auto& zpos = grid_cache.zpos(); double sum = 0; if (region == NULL) { - const int size = ecl_grid_cache_get_size( grid_cache ); + const int size = grid_cache.size(); int index; for ( index = 0; index < size; index++) { if (!aquifer[index]) { - double displacement = ecl_grav_common_eval_geertsma_kernel( index, xpos , ypos , zpos, utm_x, utm_y , depth, poisson_ratio, seabed); + double displacement = ecl_grav_common_eval_geertsma_kernel( index, xpos.data() , ypos.data() , zpos.data(), utm_x, utm_y , depth, poisson_ratio, seabed); /** For numerical precision it might be benficial to use the @@ -153,7 +153,7 @@ double ecl_grav_common_eval_geertsma( const ecl_grid_cache_type * grid_cache , e for (i = 0; i < size; i++) { index = index_list[i]; if (!aquifer[index]) { - double displacement = ecl_grav_common_eval_geertsma_kernel( index, xpos , ypos , zpos, utm_x, utm_y , depth , poisson_ratio, seabed); + double displacement = ecl_grav_common_eval_geertsma_kernel( index, xpos.data() , ypos.data() , zpos.data(), utm_x, utm_y , depth , poisson_ratio, seabed); sum += weight[index] * displacement; } } diff --git a/ThirdParty/Ert/lib/ecl/ecl_grid.cpp b/ThirdParty/Ert/lib/ecl/ecl_grid.cpp index 4f494d0ffc..ed0830b8ff 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grid.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grid.cpp @@ -21,16 +21,17 @@ #include #include #include +#include -#include +#include #include #include #include #include #include -#include -#include +#include +#include #include #include @@ -698,7 +699,7 @@ struct ecl_cell_struct { }; - +static ert_ecl_unit_enum ecl_grid_check_unit_system(const ecl_kw_type * gridunit_kw); static void ecl_grid_init_mapaxes_data_float( const ecl_grid_type * grid , float * mapaxes); float * ecl_grid_alloc_coord_data( const ecl_grid_type * grid ); static const float * ecl_grid_get_mapaxes( const ecl_grid_type * grid ); @@ -763,6 +764,10 @@ struct ecl_grid_struct { int eclipse_version; }; +ert_ecl_unit_enum ecl_grid_get_unit_system(const ecl_grid_type * grid) { + return grid->unit_system; +} + static void ecl_cell_compare(const ecl_cell_type * c1 , const ecl_cell_type * c2, bool include_nnc , bool * equal) { int i; @@ -1167,7 +1172,7 @@ static double C(double *r,int f1,int f2,int f3){ } -static double ecl_cell_get_volume_tskille( ecl_cell_type * cell ) { +static double ecl_cell_get_volume( ecl_cell_type * cell ) { double volume = 0; int pb,pg,qa,qg,ra,rb; double X[8]; @@ -1269,79 +1274,6 @@ static bool tetrahedron_contains(tetrahedron_type tet, const point_type p) { return (fabs(tetra_volume - decomposition_volume) < epsilon); } -/* - * This function used to account for a significant amount of execution time - * when used in opm-parser and has been optimised significantly. This means - * inlining several operations, e.g. vector operations, and other tricks. - */ -static double ecl_cell_get_signed_volume( ecl_cell_type * cell) { - if (GET_CELL_FLAG(cell , CELL_FLAG_VOLUME)) - return cell->volume; - - ecl_cell_assert_center( cell ); - { - /* - * We make an activation record local copy of the cell's corners for less - * jumping in memory and better cache performance. - */ - point_type center = cell->center; - point_type corners[ 8 ]; - memcpy( corners, cell->corner_list, sizeof( point_type ) * 8 ); - - tetrahedron_type tet; - tet.p0 = center; - double volume = 0; - /* - using both tetrahedron decompositions - gives good agreement - with porv from eclipse init files. - */ - - /* - * The order of these loops is intentional and guided by profiling. It's much - * faster to access method, then the number, rather than the other way - * around. If you are to change this, please measure performance impact. - */ - for( int method = 0; method < 2; ++method ) { - for( int itet = 0; itet < 12; ++itet ) { - const int point0 = tetrahedron_permutations[ method ][ itet ][ 0 ]; - const int point1 = tetrahedron_permutations[ method ][ itet ][ 1 ]; - const int point2 = tetrahedron_permutations[ method ][ itet ][ 2 ]; - - tet.p1 = corners[ point0 ]; - tet.p2 = corners[ point1 ]; - tet.p3 = corners[ point2 ]; - volume += tetrahedron_volume6( tet ) / 6; - } - } - - /* The volume of a tetrahedron is - * |a·(b x c)| - * V = ----------- - * 6 - * Since sum( |a·(b x c)| ) / 6 is equal to - * sum( |a·(b x c)| / 6 ) we can do the (rather expensive) division only once - * and still get the correct result. We multiply by 0.5 because we've now - * considered two decompositions of the tetrahedron, and want their average. - * - * - * Note added: these volume calculations are used to calculate pore - * volumes in OPM, it turns out that opm is very sensitive to these - * volumes. Extracting the divison by 6.0 was actually enough to - * induce a regression test failure in flow, this has therefore been - * reverted. - */ - - cell->volume = volume * 0.5; - SET_CELL_FLAG( cell , CELL_FLAG_VOLUME ); - } - return cell->volume; -} - - -static double ecl_cell_get_volume( ecl_cell_type * cell ) { - return fabs( ecl_cell_get_signed_volume(cell)); -} - @@ -1595,6 +1527,7 @@ static bool ecl_grid_alloc_cells( ecl_grid_type * grid , bool init_valid) { */ static ecl_grid_type * ecl_grid_alloc_empty(ecl_grid_type * global_grid, + ert_ecl_unit_enum unit_system, int dualp_flag, int nx, int ny, @@ -1621,7 +1554,7 @@ static ecl_grid_type * ecl_grid_alloc_empty(ecl_grid_type * global_grid, grid->index_map = NULL; grid->fracture_index_map = NULL; grid->inv_fracture_index_map = NULL; - grid->unit_system = ECL_METRIC_UNITS; + grid->unit_system = unit_system; if (global_grid != NULL) { @@ -2299,6 +2232,80 @@ int ecl_grid_zcorn_index__(int nx, int ny , int i, int j , int k , int c) { int ecl_grid_zcorn_index(const ecl_grid_type * grid , int i, int j , int k , int c) { return ecl_grid_zcorn_index__( grid->nx, grid->ny , i , j , k , c ); } +static void ecl_grid_init_GRDECL_data_jslice(ecl_grid_type * ecl_grid, + const double * zcorn, + const double * coord, + const int * actnum, + const int * corsnum, + int j) { + const int nx = ecl_grid->nx; + const int ny = ecl_grid->ny; + const int nz = ecl_grid->nz; + int i; + + + for (i=0; i < nx; i++) { + point_type pillars[4][2]; + int pillar_index[4]; + pillar_index[0] = 6 * ( j * (nx + 1) + i ); + pillar_index[1] = 6 * ( j * (nx + 1) + i + 1); + pillar_index[2] = 6 * ((j + 1) * (nx + 1) + i ); + pillar_index[3] = 6 * ((j + 1) * (nx + 1) + i + 1); + + { + int ip; + for (ip = 0; ip < 4; ip++) { + int index = pillar_index[ip]; + point_set(&pillars[ip][0] , coord[index] , coord[index + 1] , coord[index + 2]); + + index += 3; + point_set(&pillars[ip][1] , coord[index] , coord[index + 1] , coord[index + 2]); + } + } + + { + double ex[4]; + double ey[4]; + double ez[4]; + int k; + + { + int ip; + for (ip = 0; ip < 4; ip++) { + ex[ip] = pillars[ip][1].x - pillars[ip][0].x; + ey[ip] = pillars[ip][1].y - pillars[ip][0].y; + ez[ip] = pillars[ip][1].z - pillars[ip][0].z; + } + } + + + for (k=0; k < nz; k++) { + double x[4][2]; + double y[4][2]; + double z[4][2]; + + { + int c; + for (c = 0; c < 2; c++) { + z[0][c] = zcorn[k*8*nx*ny + j*4*nx + 2*i + c*4*nx*ny]; + z[1][c] = zcorn[k*8*nx*ny + j*4*nx + 2*i + 1 + c*4*nx*ny]; + z[2][c] = zcorn[k*8*nx*ny + j*4*nx + 2*nx + 2*i + c*4*nx*ny]; + z[3][c] = zcorn[k*8*nx*ny + j*4*nx + 2*nx + 2*i + 1 + c*4*nx*ny]; + } + } + + { + int ip; + for (ip = 0; ip < 4; ip++) + ecl_grid_pillar_cross_planes(&pillars[ip][0] , ex[ip], ey[ip] , ez[ip] , z[ip] , x[ip] , y[ip]); + } + + ecl_grid_set_cell_EGRID(ecl_grid , i , j , k , x , y , z , actnum , corsnum); + } + } + } +} + static void ecl_grid_init_GRDECL_data_jslice(ecl_grid_type * ecl_grid, @@ -2375,6 +2382,19 @@ static void ecl_grid_init_GRDECL_data_jslice(ecl_grid_type * ecl_grid, } } +void ecl_grid_init_GRDECL_data(ecl_grid_type * ecl_grid, + const double * zcorn, + const double * coord, + const int * actnum, + const int * corsnum) { + const int ny = ecl_grid->ny; + int j; +#pragma omp parallel for + for ( j=0; j < ny; j++) + ecl_grid_init_GRDECL_data_jslice( ecl_grid , zcorn, coord , actnum , corsnum , j ); +} + + void ecl_grid_init_GRDECL_data(ecl_grid_type * ecl_grid, const float * zcorn, @@ -2397,6 +2417,44 @@ void ecl_grid_init_GRDECL_data(ecl_grid_type * ecl_grid, */ static ecl_grid_type * ecl_grid_alloc_GRDECL_data__(ecl_grid_type * global_grid, + ert_ecl_unit_enum unit_system, + int dualp_flag, + bool apply_mapaxes, + int nx, + int ny, + int nz, + const double * zcorn, + const double * coord, + const int * actnum, + const float * mapaxes, + const int * corsnum, + int lgr_nr) { + + ecl_grid_type * ecl_grid = ecl_grid_alloc_empty(global_grid , unit_system, dualp_flag , nx,ny,nz,lgr_nr,true); + if (ecl_grid) { + if (mapaxes != NULL) + ecl_grid_init_mapaxes( ecl_grid , apply_mapaxes, mapaxes ); + + if (corsnum != NULL) + ecl_grid->coarsening_active = true; + + ecl_grid->coord_kw = ecl_kw_alloc("COORD" , 6*(nx + 1) * (ny + 1) , ECL_FLOAT); + { + float * coord_float = (float *)ecl_kw_get_ptr(ecl_grid->coord_kw); + for (int i=0; i < ecl_kw_get_size(ecl_grid->coord_kw); i++) + coord_float[i] = coord[i]; + } + ecl_grid_init_GRDECL_data( ecl_grid , zcorn , coord , actnum , corsnum); + + ecl_grid_init_coarse_cells( ecl_grid ); + ecl_grid_update_index( ecl_grid ); + ecl_grid_taint_cells( ecl_grid ); + } + return ecl_grid; +} + +static ecl_grid_type * ecl_grid_alloc_GRDECL_data__(ecl_grid_type * global_grid, + ert_ecl_unit_enum unit_system, int dualp_flag, bool apply_mapaxes, int nx, @@ -2409,7 +2467,7 @@ static ecl_grid_type * ecl_grid_alloc_GRDECL_data__(ecl_grid_type * global_grid, const int * corsnum, int lgr_nr) { - ecl_grid_type * ecl_grid = ecl_grid_alloc_empty(global_grid , dualp_flag , nx,ny,nz,lgr_nr,true); + ecl_grid_type * ecl_grid = ecl_grid_alloc_empty(global_grid, unit_system, dualp_flag , nx,ny,nz,lgr_nr,true); if (ecl_grid) { if (mapaxes != NULL) ecl_grid_init_mapaxes( ecl_grid , apply_mapaxes, mapaxes ); @@ -2428,6 +2486,8 @@ static ecl_grid_type * ecl_grid_alloc_GRDECL_data__(ecl_grid_type * global_grid, } + + static void ecl_grid_copy_mapaxes( ecl_grid_type * target_grid , const ecl_grid_type * src_grid ) { target_grid->use_mapaxes = src_grid->use_mapaxes; if (src_grid->mapaxes) @@ -2464,6 +2524,7 @@ static void ecl_grid_copy_content( ecl_grid_type * target_grid , const ecl_grid_ static ecl_grid_type * ecl_grid_alloc_copy__( const ecl_grid_type * src_grid, ecl_grid_type * main_grid ) { ecl_grid_type * copy_grid = ecl_grid_alloc_empty( main_grid , + src_grid->unit_system, src_grid->dualp_flag , ecl_grid_get_nx( src_grid ) , ecl_grid_get_ny( src_grid ) , @@ -2568,7 +2629,10 @@ ecl_grid_type * ecl_grid_alloc_GRDECL_data(int nx, const int * actnum, bool apply_mapaxes, const float * mapaxes) { + + ert_ecl_unit_enum unit_system = ECL_METRIC_UNITS; return ecl_grid_alloc_GRDECL_data__(NULL, + unit_system, FILEHEAD_SINGLE_POROSITY, apply_mapaxes, nx, @@ -2582,6 +2646,34 @@ ecl_grid_type * ecl_grid_alloc_GRDECL_data(int nx, 0); } +namespace ecl { + + ecl_grid_type * ecl_grid_alloc_GRDECL_data(int nx, + int ny, + int nz, + const double * zcorn, + const double * coord, + const int * actnum, + bool apply_mapaxes, + const float * mapaxes) { + ert_ecl_unit_enum unit_system = ECL_METRIC_UNITS; + return ecl_grid_alloc_GRDECL_data__(NULL, + unit_system, + FILEHEAD_SINGLE_POROSITY, + apply_mapaxes, + nx, + ny, + nz, + zcorn, + coord, + actnum, + mapaxes, + NULL, + 0); + } + +} + const float * ecl_grid_get_mapaxes_from_kw__(const ecl_kw_type * mapaxes_kw) { const float * mapaxes_data = ecl_kw_get_float_ptr(mapaxes_kw); @@ -2606,11 +2698,12 @@ static ecl_grid_type * ecl_grid_alloc_GRDECL_kw__(ecl_grid_type * global_grid , const ecl_kw_type * gridhead_kw , const ecl_kw_type * zcorn_kw , const ecl_kw_type * coord_kw , - const ecl_kw_type * actnum_kw , /* Can be NULL */ + const ecl_kw_type * gridunit_kw, /* Can be NULL */ const ecl_kw_type * mapaxes_kw , /* Can be NULL */ - const ecl_kw_type * corsnum_kw) { /* Can be NULL */ - int gtype, nx,ny,nz, lgr_nr; - + const ecl_kw_type * corsnum_kw, /* Can be NULL */ + const int * actnum_data) { /* Can be NULL */ + int gtype, nx,ny,nz, lgr_nr; + ert_ecl_unit_enum unit_system = ECL_METRIC_UNITS; gtype = ecl_kw_iget_int(gridhead_kw , GRIDHEAD_TYPE_INDEX); nx = ecl_kw_iget_int(gridhead_kw , GRIDHEAD_NX_INDEX); ny = ecl_kw_iget_int(gridhead_kw , GRIDHEAD_NY_INDEX); @@ -2631,19 +2724,19 @@ static ecl_grid_type * ecl_grid_alloc_GRDECL_kw__(ecl_grid_type * global_grid , { const float * mapaxes_data = NULL; - const int * actnum_data = NULL; const int * corsnum_data = NULL; - if (mapaxes_kw != NULL) + if (mapaxes_kw) mapaxes_data = ecl_grid_get_mapaxes_from_kw__(mapaxes_kw); - if (actnum_kw != NULL) - actnum_data = ecl_kw_get_int_ptr(actnum_kw); - - if (corsnum_kw != NULL) + if (corsnum_kw) corsnum_data = ecl_kw_get_int_ptr( corsnum_kw ); + if (gridunit_kw) + unit_system = ecl_grid_check_unit_system(gridunit_kw); + return ecl_grid_alloc_GRDECL_data__(global_grid , + unit_system, dualp_flag , apply_mapaxes, nx , ny , nz , @@ -2670,17 +2763,23 @@ ecl_grid_type * ecl_grid_alloc_GRDECL_kw( int nx, int ny , int nz , const ecl_kw_type * actnum_kw , /* Can be NULL */ const ecl_kw_type * mapaxes_kw ) { /* Can be NULL */ + const int * actnum_data = NULL; + if (actnum_kw) + actnum_data = ecl_kw_get_int_ptr(actnum_kw); + bool apply_mapaxes = true; ecl_kw_type * gridhead_kw = ecl_grid_alloc_gridhead_kw( nx, ny, nz, 0); + ecl_kw_type * gridunit_kw = NULL; ecl_grid_type * ecl_grid = ecl_grid_alloc_GRDECL_kw__(NULL, FILEHEAD_SINGLE_POROSITY, apply_mapaxes, gridhead_kw, zcorn_kw, coord_kw, - actnum_kw, + gridunit_kw, mapaxes_kw, - NULL); + NULL, + actnum_data); ecl_kw_free( gridhead_kw ); return ecl_grid; @@ -2903,12 +3002,13 @@ static void ecl_grid_init_nnc_amalgamated(ecl_grid_type * main_grid, ecl_file_ty */ -static ecl_grid_type * ecl_grid_alloc_EGRID__( ecl_grid_type * main_grid , const ecl_file_type * ecl_file , int grid_nr, bool apply_mapaxes) { +static ecl_grid_type * ecl_grid_alloc_EGRID__( ecl_grid_type * main_grid , const ecl_file_type * ecl_file , int grid_nr, bool apply_mapaxes, const int * ext_actnum) { ecl_kw_type * gridhead_kw = ecl_file_iget_named_kw( ecl_file , GRIDHEAD_KW , grid_nr); ecl_kw_type * zcorn_kw = ecl_file_iget_named_kw( ecl_file , ZCORN_KW , grid_nr); ecl_kw_type * coord_kw = ecl_file_iget_named_kw( ecl_file , COORD_KW , grid_nr); ecl_kw_type * corsnum_kw = NULL; ecl_kw_type * actnum_kw = NULL; + ecl_kw_type * gridunit_kw = NULL; ecl_kw_type * mapaxes_kw = NULL; int dualp_flag; int eclipse_version; @@ -2921,10 +3021,23 @@ static ecl_grid_type * ecl_grid_alloc_EGRID__( ecl_grid_type * main_grid , const eclipse_version = main_grid->eclipse_version; } - - /** If ACTNUM is not present - that is is interpreted as - all active. */ - if (ecl_file_get_num_named_kw(ecl_file , ACTNUM_KW) > grid_nr) + // If ACTNUM and ext_actnum are not present - that is is interpreted as all active. + const int * actnum_data; + std::vector actnum_product; + if (ecl_file_get_num_named_kw(ecl_file , ACTNUM_KW) > grid_nr) { actnum_kw = ecl_file_iget_named_kw( ecl_file , ACTNUM_KW , grid_nr); + actnum_data = ecl_kw_get_int_ptr(actnum_kw); + if (ext_actnum) { + int size = ecl_kw_get_size(actnum_kw); + actnum_product.resize(size); + for (int i = 0; i < size; i++) + actnum_product[i] = actnum_data[i] * ext_actnum[i]; + actnum_data = actnum_product.data(); + } + } + else + actnum_data = ext_actnum; + if (grid_nr == 0) { /* MAPAXES and COARSENING only apply to the global grid. */ @@ -2933,9 +3046,10 @@ static ecl_grid_type * ecl_grid_alloc_EGRID__( ecl_grid_type * main_grid , const if (ecl_file_has_kw( ecl_file , CORSNUM_KW)) corsnum_kw = ecl_file_iget_named_kw( ecl_file , CORSNUM_KW , 0); - } - + if (ecl_file_has_kw(ecl_file, GRIDUNIT_KW)) + gridunit_kw = ecl_file_iget_named_kw( ecl_file, GRIDUNIT_KW, 0); + } { ecl_grid_type * ecl_grid = ecl_grid_alloc_GRDECL_kw__( main_grid , @@ -2944,9 +3058,10 @@ static ecl_grid_type * ecl_grid_alloc_EGRID__( ecl_grid_type * main_grid , const gridhead_kw , zcorn_kw , coord_kw , - actnum_kw , + gridunit_kw, mapaxes_kw , - corsnum_kw ); + corsnum_kw, + actnum_data); if (ECL_GRID_MAINGRID_LGR_NR != grid_nr) ecl_grid_set_lgr_name_EGRID(ecl_grid , ecl_file , grid_nr); ecl_grid->eclipse_version = eclipse_version; @@ -2955,8 +3070,13 @@ static ecl_grid_type * ecl_grid_alloc_EGRID__( ecl_grid_type * main_grid , const } +static ecl_grid_type * ecl_grid_alloc_GRID_all_grids(const char * filename) { + util_abort("%s .GRID files - %s - not supported \n", __func__ , filename); + return NULL; +} -ecl_grid_type * ecl_grid_alloc_EGRID(const char * grid_file, bool apply_mapaxes) { + +static ecl_grid_type * ecl_grid_alloc_EGRID_all_grids(const char * grid_file, bool apply_mapaxes, const int * ext_actnum) { ecl_file_enum file_type; file_type = ecl_util_get_file_type(grid_file , NULL , NULL); if (file_type != ECL_EGRID_FILE) @@ -2965,11 +3085,13 @@ ecl_grid_type * ecl_grid_alloc_EGRID(const char * grid_file, bool apply_mapaxes) ecl_file_type * ecl_file = ecl_file_open( grid_file , 0); if (ecl_file) { int num_grid = ecl_file_get_num_named_kw( ecl_file , GRIDHEAD_KW ); - ecl_grid_type * main_grid = ecl_grid_alloc_EGRID__( NULL , ecl_file , 0 , apply_mapaxes); + ecl_grid_type * main_grid = ecl_grid_alloc_EGRID__( NULL , ecl_file , 0 , apply_mapaxes, ext_actnum ); int grid_nr; for ( grid_nr = 1; grid_nr < num_grid; grid_nr++) { - ecl_grid_type * lgr_grid = ecl_grid_alloc_EGRID__( main_grid , ecl_file , grid_nr , false); /* The apply_mapaxes argument is ignored for LGR - it inherits from parent anyway. */ + // The apply_mapaxes argument is ignored for LGR - + // it inherits from parent anyway. + ecl_grid_type * lgr_grid = ecl_grid_alloc_EGRID__( main_grid , ecl_file , grid_nr , false, NULL ); ecl_grid_add_lgr( main_grid , lgr_grid ); { ecl_grid_type * host_grid; @@ -2994,14 +3116,19 @@ ecl_grid_type * ecl_grid_alloc_EGRID(const char * grid_file, bool apply_mapaxes) } +ecl_grid_type * ecl_grid_alloc_EGRID(const char * grid_file, bool apply_mapaxes) { + return ecl_grid_alloc_EGRID_all_grids(grid_file, apply_mapaxes, NULL); +} + -static ecl_grid_type * ecl_grid_alloc_GRID_data__(ecl_grid_type * global_grid , int num_coords , int dualp_flag , bool apply_mapaxes, int nx, int ny , int nz , int grid_nr , int coords_size , int ** coords , float ** corners , const float * mapaxes) { + +static ecl_grid_type * ecl_grid_alloc_GRID_data__(ecl_grid_type * global_grid , int num_coords , ert_ecl_unit_enum unit_system, int dualp_flag , bool apply_mapaxes, int nx, int ny , int nz , int grid_nr , int coords_size , int ** coords , float ** corners , const float * mapaxes) { if (dualp_flag != FILEHEAD_SINGLE_POROSITY) nz = nz / 2; { - ecl_grid_type * grid = ecl_grid_alloc_empty( global_grid , dualp_flag , nx , ny , nz , grid_nr, false); + ecl_grid_type * grid = ecl_grid_alloc_empty( global_grid , unit_system, dualp_flag , nx , ny , nz , grid_nr, false); if (grid) { if (mapaxes != NULL) ecl_grid_init_mapaxes( grid , apply_mapaxes , mapaxes); @@ -3027,8 +3154,10 @@ static ecl_grid_type * ecl_grid_alloc_GRID_data__(ecl_grid_type * global_grid , */ ecl_grid_type * ecl_grid_alloc_GRID_data(int num_coords , int nx , int ny , int nz , int coords_size , int ** coords , float ** corners , bool apply_mapaxes, const float * mapaxes) { + ert_ecl_unit_enum unit_system = ECL_METRIC_UNITS; return ecl_grid_alloc_GRID_data__( NULL , num_coords , + unit_system, FILEHEAD_SINGLE_POROSITY , /* Does currently not support to determine dualp_flag from inspection. */ apply_mapaxes, nx , ny , nz , 0 , coords_size , coords , corners , mapaxes); @@ -3082,6 +3211,7 @@ static ecl_grid_type * ecl_grid_alloc_GRID__(ecl_grid_type * global_grid , const int nx,ny,nz; const float * mapaxes_data = NULL; ecl_grid_type * grid; + ert_ecl_unit_enum unit_system = ECL_METRIC_UNITS; // 1: Fetching header data from the DIMENS keyword. { @@ -3101,6 +3231,8 @@ static ecl_grid_type * ecl_grid_alloc_GRID__(ecl_grid_type * global_grid , const } } + if ((grid_nr == 0) && (ecl_file_has_kw( ecl_file , GRIDUNIT_KW))) + unit_system = ecl_grid_check_unit_system( ecl_file_iget_named_kw(ecl_file, GRIDUNIT_KW, 0)); /* The number of COORDS/CORNERS blocks depends on the GRIDFILE option @@ -3173,7 +3305,7 @@ static ecl_grid_type * ecl_grid_alloc_GRID__(ecl_grid_type * global_grid , const coords_size = ecl_kw_get_size( coords_kw ); } // Create the grid: - grid = ecl_grid_alloc_GRID_data__( global_grid , num_coords , dualp_flag , apply_mapaxes, nx , ny , nz , grid_nr , coords_size , coords , corners , mapaxes_data ); + grid = ecl_grid_alloc_GRID_data__( global_grid , num_coords , unit_system, dualp_flag , apply_mapaxes, nx , ny , nz , grid_nr , coords_size , coords , corners , mapaxes_data ); free( coords ); free( corners ); @@ -3240,7 +3372,8 @@ ecl_grid_type * ecl_grid_alloc_GRID(const char * grid_file, bool apply_mapaxes) which case all cells will be active. */ ecl_grid_type * ecl_grid_alloc_regular( int nx, int ny , int nz , const double * ivec, const double * jvec , const double * kvec , const int * actnum) { - ecl_grid_type * grid = ecl_grid_alloc_empty(NULL , FILEHEAD_SINGLE_POROSITY , nx , ny , nz , 0, true); + ert_ecl_unit_enum unit_system = ECL_METRIC_UNITS; + ecl_grid_type * grid = ecl_grid_alloc_empty(NULL , unit_system, FILEHEAD_SINGLE_POROSITY , nx , ny , nz , 0, true); if (grid) { const double grid_offset[3] = {0,0,0}; @@ -3297,7 +3430,9 @@ ecl_grid_type * ecl_grid_alloc_rectangular( int nx , int ny , int nz , double dx all cells will be active. */ ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv( int nx, int ny , int nz , const double * dxv , const double * dyv , const double * dzv , const int * actnum) { + ert_ecl_unit_enum unit_system = ECL_METRIC_UNITS; ecl_grid_type* grid = ecl_grid_alloc_empty(NULL, + unit_system, FILEHEAD_SINGLE_POROSITY, nx, ny, nz, /*lgr_nr=*/0, /*init_valid=*/true); @@ -3340,7 +3475,9 @@ ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv( int nx, int ny , int nz , const doub ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv_depthz( int nx, int ny , int nz , const double * dxv , const double * dyv , const double * dzv , const double * depthz , const int * actnum) { + ert_ecl_unit_enum unit_system = ECL_METRIC_UNITS; ecl_grid_type* grid = ecl_grid_alloc_empty(NULL, + unit_system, FILEHEAD_SINGLE_POROSITY, nx, ny, nz, /*lgr_nr=*/0, /*init_valid=*/true); @@ -3443,8 +3580,9 @@ ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv_depthz( int nx, int ny , int nz , con */ ecl_grid_type * ecl_grid_alloc_dx_dy_dz_tops( int nx, int ny , int nz , const double * dx , const double * dy , const double * dz , const double * tops , const int * actnum) { - + ert_ecl_unit_enum unit_system = ECL_METRIC_UNITS; ecl_grid_type* grid = ecl_grid_alloc_empty(NULL, + unit_system, FILEHEAD_SINGLE_POROSITY, nx, ny, nz, 0, true); @@ -3524,6 +3662,23 @@ ecl_grid_type * ecl_grid_alloc(const char * grid_file ) { } +// This function is used to override use of the keyword ACTNUM from the EGRID file. +// ext_actnum must have size equal to the number of cells in the main grid +// if ext_actnum = NULL, actnum is taken from file, otherwise ext_actnums +// determines which cells are active. +ecl_grid_type * ecl_grid_alloc_ext_actnum(const char * grid_file, const int * ext_actnum) { + ecl_file_enum file_type = ecl_util_get_file_type(grid_file , NULL , NULL); + if (file_type == ECL_EGRID_FILE) + return ecl_grid_alloc_EGRID_all_grids(grid_file, true, ext_actnum); + else if (file_type == ECL_GRID_FILE) + ecl_grid_alloc_GRID_all_grids(grid_file); + else + util_abort("%s must have .EGRID file - %s not recognized \n", __func__ , grid_file); + + return NULL; +} + + static void ecl_grid_file_nactive_dims( fortio_type * data_fortio , int * dims) { if (data_fortio) { if (ecl_kw_fseek_kw( INTEHEAD_KW , false , false , data_fortio )) { @@ -4458,12 +4613,12 @@ int ecl_grid_get_block_count3d(const ecl_grid_type * grid , int i , int j, int k void ecl_grid_free(ecl_grid_type * grid) { ecl_grid_free_cells( grid ); - util_safe_free(grid->index_map); - util_safe_free(grid->inv_index_map); + free(grid->index_map); + free(grid->inv_index_map); - util_safe_free(grid->fracture_index_map); - util_safe_free(grid->inv_fracture_index_map); - util_safe_free(grid->mapaxes); + free(grid->fracture_index_map); + free(grid->inv_fracture_index_map); + free(grid->mapaxes); if (grid->values != NULL) { int i; @@ -4481,9 +4636,9 @@ void ecl_grid_free(ecl_grid_type * grid) { vector_free( grid->coarse_cells ); hash_free( grid->children ); - util_safe_free( grid->parent_name ); - util_safe_free( grid->visited ); - util_safe_free( grid->name ); + free( grid->parent_name ); + free( grid->visited ); + free( grid->name ); free( grid ); } @@ -4997,12 +5152,16 @@ double ecl_grid_get_cell_dx1A( const ecl_grid_type * grid , int active_index) { /* - The current algorithm for calculating the cell dimensions DX,DY and - DZ reproduces the Eclipse results from the INIT file, but we are in - general *not* guaranteed to satisfy the relationship: + The current algorithm for calculating the cell dimensions DX,DY and DZ + reproduces the Eclipse results from the INIT file quite well, relative error + on the order 1e-4 for DX and DY and 1e-3 for DZ. + + Observe that the DX, DY and DZ values are not tied to the cell volume; i.e. + the relationship: - DX * DY * DZ = V + DX * DY * DZ = V + does generally not hold. */ double ecl_grid_get_cell_dy1( const ecl_grid_type * grid , int global_index ) { @@ -5389,15 +5548,6 @@ double ecl_grid_get_cell_volume1A( const ecl_grid_type * ecl_grid, int active_in -double ecl_grid_get_cell_volume1_tskille( const ecl_grid_type * ecl_grid, int global_index ) { - ecl_cell_type * cell = ecl_grid_get_cell( ecl_grid , global_index ); - return ecl_cell_get_volume_tskille( cell ); -} - - - - - double ecl_grid_get_cell_volume3( const ecl_grid_type * ecl_grid, int i , int j , int k) { int global_index = ecl_grid_get_global_index3( ecl_grid , i , j , k); return ecl_grid_get_cell_volume1( ecl_grid , global_index ); @@ -5936,6 +6086,19 @@ static ecl_kw_type * ecl_grid_alloc_gridunits_kw( ert_ecl_unit_enum output_unit return gridunits_kw; } +static ert_ecl_unit_enum ecl_grid_check_unit_system(const ecl_kw_type * gridunit_kw) { + const char * length_unit = ecl_kw_iget_char_ptr(gridunit_kw, 0); + + if (strncmp(length_unit, "FEET", 4) == 0) + return ECL_FIELD_UNITS; + + if (strncmp(length_unit, "CM", 2) == 0) + return ECL_LAB_UNITS; + + return ECL_METRIC_UNITS; +} + + /*****************************************************************/ static float ecl_grid_output_scaling( const ecl_grid_type * grid , ert_ecl_unit_enum output_unit) { @@ -6927,4 +7090,79 @@ ecl_kw_type * ecl_grid_alloc_volume_kw( const ecl_grid_type * grid , bool active else return ecl_grid_alloc_volume_kw_global( grid ); } + +//This function is meant to be used w/ pandas datafram and numpy +//Note: global_index must be allocated w/ ecl_grid->total_active or ecl_grid->global_size int32 data points +// index_data must be allocated w/ (4 * ecl_grid->total_active or ecl_grid->global_size) int32 data points. +void ecl_grid_export_index(const ecl_grid_type * grid, int * global_index, int * index_data , bool active_only) { + int pos_indx = 0; + int pos_data = 0; + for (int k = 0; k < grid->nz; k++) + for (int j = 0; j < grid->ny; j++) + for (int i = 0; i < grid->nx; i++) { + int g = ecl_grid_get_global_index__(grid, i, j, k); + if (!active_only || grid->cells[g].active_index[0] >= 0) { + global_index[pos_indx++] = g; + index_data[pos_data++] = i; + index_data[pos_data++] = j; + index_data[pos_data++] = k; + index_data[pos_data++] = grid->cells[g].active_index[0]; + } + } +} + +//This function is meant to be used w/ pandas datafram and numpy +//Note: index_size must equal allocated size of output +void ecl_grid_export_data_as_int( int index_size, const int * data_index, const ecl_kw_type * kw, int * output) { + int * input = ecl_kw_get_int_ptr(kw); + for (int i=0; i < index_size; i++) { + int di = data_index[i]; + if (di >= 0) + output[i] = input[di]; + } +} + +//This function is meant to be used w/ pandas datafram and numpy +//Note: index_size must equal allocated size of output +void ecl_grid_export_data_as_double( int index_size, const int * data_index, const ecl_kw_type * kw, double * output) { + for (int i=0; i < index_size; i++) { + int di = data_index[i]; + if (di >= 0) + output[i] = ecl_kw_iget_as_double(kw, di); + } +} + +//This function is meant to be used w/ pandas datafram and numpy +void ecl_grid_export_volume( const ecl_grid_type * grid, int index_size, const int * global_index, double * output ) { + for (int i = 0; i < index_size; i++) { + int g = global_index[i]; + output[i] = ecl_grid_get_cell_volume1(grid, g); + } +} + +//This function is meant to be used w/ pandas datafram and numpy +void ecl_grid_export_position( const ecl_grid_type * grid, int index_size, const int * global_index, double * output) { + for (int i = 0; i < index_size; i++) { + int g = global_index[i]; + int j = 3 * i; + ecl_grid_get_xyz1(grid, g, &output[j], &output[j+1], &output[j+2]); + } +} + +//This function is meant to be used w/ pandas dataframe and numpy +void export_corners( const ecl_grid_type * grid, int index_size, const int * global_index, double * output) { + double x[8], y[8], z[8]; + int pos = 0; + for (int i = 0; i < index_size; i++) { + int g = global_index[i]; + ecl_grid_export_cell_corners1(grid, g, x, y, z); + for (int j = 0; j < 8; j++) { + output[pos++] = x[j]; + output[pos++] = y[j]; + output[pos++] = z[j]; + } + } +} + + // diff --git a/ThirdParty/Ert/lib/ecl/ecl_grid_cache.cpp b/ThirdParty/Ert/lib/ecl/ecl_grid_cache.cpp index f856b9cc41..46dd0d9db5 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grid_cache.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grid_cache.cpp @@ -21,13 +21,14 @@ #include #include -#include +#include #include #include #include #include -#include + +#include "detail/ecl/ecl_grid_cache.hpp" @@ -39,94 +40,31 @@ coordinates of a cell. */ -struct ecl_grid_cache_struct { - int size; /* The length of the vectors, equal to the number of active elements in the grid. */ - double * xpos; - double * ypos; - double * zpos; - double * volume; /* Will be initialized on demand. */ - int * global_index; /* Maps from active index (i.e. natural index in this context) - to the corresponding global index. */ - const ecl_grid_type * grid; -}; - - - - - -ecl_grid_cache_type * ecl_grid_cache_alloc( const ecl_grid_type * grid ) { - ecl_grid_cache_type * grid_cache = (ecl_grid_cache_type*)util_malloc( sizeof * grid_cache ); - - grid_cache->grid = grid; - grid_cache->volume = NULL; - grid_cache->size = ecl_grid_get_active_size( grid ); - grid_cache->xpos = (double*)util_calloc( grid_cache->size , sizeof * grid_cache->xpos ); - grid_cache->ypos = (double*)util_calloc( grid_cache->size , sizeof * grid_cache->ypos ); - grid_cache->zpos = (double*)util_calloc( grid_cache->size , sizeof * grid_cache->zpos ); - grid_cache->global_index = (int*)util_calloc( grid_cache->size , sizeof * grid_cache->global_index ); +namespace ecl { + ecl_grid_cache::ecl_grid_cache(const ecl_grid_type * grid) : + grid(grid) { - int active_index; - - - /* Go trough all the active cells and extract the cell center - position and store it in xpos/ypos/zpos. */ - - for (active_index = 0; active_index < grid_cache->size; active_index++) { - int global_index = ecl_grid_get_global_index1A( grid , active_index ); - grid_cache->global_index[ active_index ] = global_index; - ecl_grid_get_xyz1( grid , global_index , - &grid_cache->xpos[ active_index ] , - &grid_cache->ypos[ active_index ] , - &grid_cache->zpos[ active_index ]); + for (int active_index = 0; active_index < ecl_grid_get_active_size(this->grid); active_index++) { + double x,y,z; + int global_index = ecl_grid_get_global_index1A(this->grid, active_index); + ecl_grid_get_xyz1(this->grid, global_index, &x, &y, &z); + + this->gi.push_back(global_index); + this->xp.push_back(x); + this->yp.push_back(y); + this->zp.push_back(z); } - } - return grid_cache; -} -int ecl_grid_cache_get_size( const ecl_grid_cache_type * grid_cache ) { - return grid_cache->size; -} -int ecl_grid_cache_iget_global_index( const ecl_grid_cache_type * grid_cache , int active_index) { - return grid_cache->global_index[ active_index ]; -} - - -const int * ecl_grid_cache_get_global_index( const ecl_grid_cache_type * grid_cache) { - return grid_cache->global_index; -} - -const double * ecl_grid_cache_get_xpos( const ecl_grid_cache_type * grid_cache ) { - return grid_cache->xpos; -} - -const double * ecl_grid_cache_get_ypos( const ecl_grid_cache_type * grid_cache ) { - return grid_cache->ypos; -} - -const double * ecl_grid_cache_get_zpos( const ecl_grid_cache_type * grid_cache ) { - return grid_cache->zpos; -} - -const double * ecl_grid_cache_get_volume( const ecl_grid_cache_type * grid_cache ) { - - if (!grid_cache->volume) { - // C++ style const cast. - ecl_grid_cache_type * gc = (ecl_grid_cache_type *) grid_cache; - gc->volume = (double*)util_calloc( gc->size , sizeof * gc->volume ); - for (int active_index = 0; active_index < grid_cache->size; active_index++) - gc->volume[active_index] = ecl_grid_get_cell_volume1A( gc->grid , active_index ); + const std::vector& ecl_grid_cache::volume() const { + if (this->v.empty()) { + for (int active_index = 0; active_index < this->size(); active_index++) + this->v.push_back( ecl_grid_get_cell_volume1A(this->grid, active_index)); + } + return this->v; } - return grid_cache->volume; } -void ecl_grid_cache_free( ecl_grid_cache_type * grid_cache ) { - free( grid_cache->xpos ); - free( grid_cache->ypos ); - free( grid_cache->zpos ); - free( grid_cache->global_index ); - free( grid_cache->volume ); - free( grid_cache ); -} diff --git a/ThirdParty/Ert/lib/ecl/ecl_grid_dims.cpp b/ThirdParty/Ert/lib/ecl/ecl_grid_dims.cpp index 24e6b671c3..8df249dcf1 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_grid_dims.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_grid_dims.cpp @@ -1,24 +1,24 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include #include @@ -40,11 +40,11 @@ static void ecl_grid_dims_read_EGRID( ecl_grid_dims_type * grid_dims , fortio_ty grid_dims_type * dims; { ecl_kw_type * gridhead_kw = ecl_kw_fread_alloc( grid_fortio ); - + int nx = ecl_kw_iget_int( gridhead_kw , GRIDHEAD_NX_INDEX ); int ny = ecl_kw_iget_int( gridhead_kw , GRIDHEAD_NY_INDEX ); int nz = ecl_kw_iget_int( gridhead_kw , GRIDHEAD_NZ_INDEX ); - + dims = grid_dims_alloc( nx , ny , nz , 0 ); ecl_kw_free( gridhead_kw ); } @@ -56,9 +56,9 @@ static void ecl_grid_dims_read_EGRID( ecl_grid_dims_type * grid_dims , fortio_ty ecl_kw_free( intehead_kw ); } } - + vector_append_owned_ref( grid_dims->dims_list , dims, grid_dims_free__ ); - } + } } @@ -68,11 +68,11 @@ static void ecl_grid_dims_read_GRID( ecl_grid_dims_type * grid_dims , fortio_typ grid_dims_type * dims; { ecl_kw_type * dimens_kw = ecl_kw_fread_alloc( grid_fortio ); - + int nx = ecl_kw_iget_int( dimens_kw , DIMENS_NX_INDEX ); int ny = ecl_kw_iget_int( dimens_kw , DIMENS_NY_INDEX ); int nz = ecl_kw_iget_int( dimens_kw , DIMENS_NZ_INDEX ); - + dims = grid_dims_alloc( nx , ny , nz , 0 ); ecl_kw_free( dimens_kw ); } @@ -84,9 +84,9 @@ static void ecl_grid_dims_read_GRID( ecl_grid_dims_type * grid_dims , fortio_typ ecl_kw_free( intehead_kw ); } } - + vector_append_owned_ref( grid_dims->dims_list , dims, grid_dims_free__ ); - } + } } @@ -96,37 +96,37 @@ ecl_grid_dims_type * ecl_grid_dims_alloc( const char * grid_file , const char * ecl_grid_dims_type * grid_dims = NULL; bool grid_fmt_file; ecl_file_enum grid_file_type = ecl_util_get_file_type( grid_file , &grid_fmt_file , NULL ); - - + + if ((grid_file_type == ECL_GRID_FILE) || (grid_file_type == ECL_EGRID_FILE)) { fortio_type * grid_fortio = fortio_open_reader( grid_file , grid_fmt_file , ECL_ENDIAN_FLIP ); if (grid_fortio) { grid_dims = (ecl_grid_dims_type*)util_malloc( sizeof * grid_dims ); grid_dims->dims_list = vector_alloc_new( ); - + { fortio_type * data_fortio = NULL; bool data_fmt_file; - + if (data_file) { ecl_util_get_file_type( data_file , &data_fmt_file , NULL ); data_fortio = fortio_open_reader( data_file , data_fmt_file , ECL_ENDIAN_FLIP ); } - - + + if (grid_file_type == ECL_EGRID_FILE) ecl_grid_dims_read_EGRID( grid_dims , grid_fortio , data_fortio ); else ecl_grid_dims_read_GRID( grid_dims , grid_fortio , data_fortio ); - + if (data_fortio) fortio_fclose( data_fortio ); - + } fortio_fclose( grid_fortio ); } } - + return grid_dims; } diff --git a/ThirdParty/Ert/lib/ecl/ecl_init_file.cpp b/ThirdParty/Ert/lib/ecl/ecl_init_file.cpp index 98b1ce5ba9..f8b1bc656f 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_init_file.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_init_file.cpp @@ -31,7 +31,7 @@ */ -#include +#include #include #include diff --git a/ThirdParty/Ert/lib/ecl/ecl_io_config.cpp b/ThirdParty/Ert/lib/ecl/ecl_io_config.cpp index 5c5ee3a4d8..9ad54c46be 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_io_config.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_io_config.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_io_config.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_io_config.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include #include @@ -33,7 +33,7 @@ * formatted : whether to use formatted files. * unified : whether unified summary || restart files should be used. - + All types are implemented by an internal enum which supports a undefined type. The rationale for this is to provide functionality to 'guess' type based on arbitrary input. If for instance the input @@ -43,7 +43,7 @@ typedef enum { UNIFIED = 0, - MULTIPLE = 1, + MULTIPLE = 1, UNIF_UNDEFINED = 2 } unified_type; typedef enum { FORMATTED = 0, @@ -142,11 +142,11 @@ ecl_io_config_type * ecl_io_config_alloc(bool formatted , bool unified_summary return ecl_io_config; } - - - - + + + + void ecl_io_config_free(ecl_io_config_type * io_config) { free(io_config); } - + diff --git a/ThirdParty/Ert/lib/ecl/ecl_kw.cpp b/ThirdParty/Ert/lib/ecl/ecl_kw.cpp index 8fed785eed..b71c0c0ac6 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_kw.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_kw.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include @@ -651,8 +651,8 @@ ecl_kw_type * ecl_kw_alloc_empty() { void ecl_kw_free(ecl_kw_type *ecl_kw) { - util_safe_free( ecl_kw->header ); - util_safe_free(ecl_kw->header8); + free( ecl_kw->header ); + free(ecl_kw->header8); ecl_kw_free_data(ecl_kw); free(ecl_kw); } @@ -951,7 +951,7 @@ void ecl_kw_iset_string_ptr( ecl_kw_type * ecl_kw, int index, const char * s) { { char * ecl_string = (char *) ecl_kw_iget_ptr(ecl_kw, index); - int i; + size_t i; for(i = 0; i < input_len; ++i) ecl_string[i] = s[i]; @@ -1376,7 +1376,9 @@ ecl_read_status_enum ecl_kw_fread_header(ecl_kw_type *ecl_kw , fortio_type * for return ECL_KW_READ_FAIL; memcpy( header , &buffer[0] , ECL_STRING8_LENGTH); - size = *( (int *) &buffer[ECL_STRING8_LENGTH] ); + void * ptr = &buffer[ECL_STRING8_LENGTH]; + size = *((int*)ptr); + memcpy( ecl_type_str , &buffer[ECL_STRING8_LENGTH + sizeof(size)] , ECL_TYPE_LENGTH); if(!fortio_complete_read(fortio , record_size)) @@ -1483,7 +1485,7 @@ bool ecl_kw_fseek_last_kw(const char * kw , bool abort_on_error , fortio_type *f void ecl_kw_set_data_ptr(ecl_kw_type * ecl_kw , void * data) { if (!ecl_kw->shared_data) - util_safe_free( ecl_kw->data ); + free( ecl_kw->data ); ecl_kw->data = (char*)data; } @@ -1506,7 +1508,7 @@ void ecl_kw_alloc_data(ecl_kw_type *ecl_kw) { void ecl_kw_free_data(ecl_kw_type *ecl_kw) { if (!ecl_kw->shared_data) - util_safe_free(ecl_kw->data); + free(ecl_kw->data); ecl_kw->data = NULL; } @@ -1519,7 +1521,7 @@ void ecl_kw_set_header_name(ecl_kw_type * ecl_kw , const char * header) { sprintf(ecl_kw->header8 , "%-8s" , header); /* Internalizing a header without the trailing spaces as well. */ - util_safe_free( ecl_kw->header ); + free( ecl_kw->header ); ecl_kw->header = util_alloc_strip_copy( ecl_kw->header8 ); } else { @@ -1932,7 +1934,7 @@ ecl_kw_type * ecl_kw_alloc_global_copy(const ecl_kw_type * src, const ecl_kw_typ return NULL; const int global_size = ecl_kw_get_size(actnum); - ecl_kw_type * global_copy = ecl_kw_alloc( ecl_kw_get_header(src), global_size, src->data_type); + ecl_kw_type * global_copy = ecl_kw_alloc( ecl_kw_get_header(src), global_size, src->data_type); const int * mapping = ecl_kw_get_int_ptr(actnum); const int src_size = ecl_kw_get_size(src); int src_index = 0; diff --git a/ThirdParty/Ert/lib/ecl/ecl_kw_grdecl.cpp b/ThirdParty/Ert/lib/ecl/ecl_kw_grdecl.cpp index fc51a42e8d..5d76c7f36d 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_kw_grdecl.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_kw_grdecl.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include @@ -215,11 +215,13 @@ bool ecl_kw_grdecl_fseek_kw(const char * kw , bool rewind , FILE * stream) { which (might) have been used in the input. */ - -static void iset_range( char * data , int data_offset , int sizeof_ctype , void * value_ptr , int multiplier) { - int index; - for ( index =0; index < multiplier; index++) - memcpy( &data[ (index + data_offset) * sizeof_ctype ] , value_ptr , sizeof_ctype); +static void iset_range( char * data , int data_index, int sizeof_ctype , void * value_ptr , int multiplier) { + size_t byte_offset; + for (int index =0; index < multiplier; index++) { + byte_offset = static_cast(data_index) + static_cast(index); + byte_offset *= sizeof_ctype; + memcpy( &data[ byte_offset ] , value_ptr , sizeof_ctype); + } } @@ -255,11 +257,11 @@ static void iset_range( char * data , int data_offset , int sizeof_ctype , void static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_data_type data_type , int * kw_size , FILE * stream ) { char newline = '\n'; bool atEOF = false; - int init_size = 32; - int buffer_size = 64; - int data_index = 0; + size_t init_size = 32; + size_t buffer_size = 64; + size_t data_index = 0; int sizeof_ctype = ecl_type_get_sizeof_ctype( data_type ); - int data_size = init_size; + size_t data_size = init_size; char * buffer = (char*)util_calloc( (buffer_size + 1) , sizeof * buffer ); char * data = (char*)util_calloc( sizeof_ctype * data_size , sizeof * data ); @@ -347,7 +349,7 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_ data_size = util_size_t_min( ECL_KW_MAX_SIZE , 2*(data_index + multiplier)); byte_size *= data_size; - data = (char*)util_realloc( data , byte_size ); + data = (char*) util_realloc( data , byte_size ); } else { /* We are asking for more elements than can possible be adressed in @@ -394,9 +396,9 @@ static char * fscanf_alloc_grdecl_data( const char * header , bool strict , ecl_ The ecl_kw class has a quite deeply wired assumption that the header is a string of length 8 (I hope/think that is an ECLIPSE - limitation). The class cannot read/write kw with headers longer than 8 bytes. + limitation). The class cannot read/write kw with headers longer than 8 bytes. ecl_kw_grdecl is a workaround allowing for reading/writing kw with long - headers. + headers. ----------------------------------------------------------------- @@ -454,7 +456,7 @@ static ecl_kw_type * __ecl_kw_fscanf_alloc_grdecl__(FILE * stream , const char * // Verify size if (size > 0) if (size != kw_size) { - util_safe_free( data ); + free( data ); util_abort("%s: size mismatch when loading:%s. File:%d elements. Requested:%d elements \n", __func__ , file_header , kw_size , size); } diff --git a/ThirdParty/Ert/lib/ecl/ecl_nnc_data.cpp b/ThirdParty/Ert/lib/ecl/ecl_nnc_data.cpp index ca35f63fb8..1e9f813927 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_nnc_data.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_nnc_data.cpp @@ -26,9 +26,9 @@ #include enum kw_data_type { - TRANS_DATA = 1, - WTR_FLUX_DATA = 2, - OIL_FLUX_DATA = 3, + TRANS_DATA = 1, + WTR_FLUX_DATA = 2, + OIL_FLUX_DATA = 3, GAS_FLUX_DATA = 4 }; @@ -40,8 +40,8 @@ struct ecl_nnc_data_struct { static const char * ecl_nnc_data_get_str_kw(int kw_type, int grid1, int grid2) { - char * kw = NULL; - switch (kw_type) { + const char * kw = NULL; + switch (kw_type) { case TRANS_DATA: if (grid1 == grid2) @@ -65,11 +65,11 @@ static const char * ecl_nnc_data_get_str_kw(int kw_type, int grid1, int grid2) { if (grid1 == grid2) kw = FLROILNNC_KW; else if (grid1 == 0) - kw = FLROILLG_KW; + kw = FLROILLG_KW; else kw = FLROILLL_KW; break; - + case GAS_FLUX_DATA: if (grid1 == grid2) kw = FLRGASNNC_KW; @@ -92,7 +92,7 @@ static ecl_kw_type * ecl_nnc_data_get_gl_kw( const ecl_file_view_type * init_fil return NULL; if (lgr_nr == 0) { - if(ecl_file_view_has_kw(init_file_view, kw)) + if(ecl_file_view_has_kw(init_file_view, kw)) return ecl_file_view_iget_named_kw(init_file_view, kw, 0); else return NULL; @@ -180,20 +180,20 @@ static bool ecl_nnc_data_set_values(ecl_nnc_data_type * data, const ecl_grid_typ ecl_kw_type * current_kw = NULL; int correct_kw_count = 0; int kw_count = 0; - int nnc_size = ecl_nnc_geometry_size( nnc_geo ); + int nnc_size = ecl_nnc_geometry_size( nnc_geo ); for (int nnc_index = 0; nnc_index < nnc_size; nnc_index++) { const ecl_nnc_pair_type * pair = ecl_nnc_geometry_iget( nnc_geo, nnc_index ); int grid1 = pair->grid_nr1; int grid2 = pair->grid_nr2; - + if (grid1 != current_grid1 || grid2 != current_grid2) { current_grid1 = grid1; current_grid2 = grid2; assert_correct_kw_count(current_kw, __func__, correct_kw_count, kw_count); current_kw = ecl_nnc_data_get_kw( grid, init_file, grid1 , grid2 , kw_type); kw_count = 0; - if (current_kw) { + if (current_kw) { correct_kw_count = ecl_kw_get_size( current_kw ); } else { @@ -204,7 +204,7 @@ static bool ecl_nnc_data_set_values(ecl_nnc_data_type * data, const ecl_grid_typ data->values[nnc_index] = ecl_kw_iget_as_double(current_kw, pair->input_index); kw_count++; } - + } assert_correct_kw_count(current_kw, __func__, correct_kw_count, kw_count); return true; diff --git a/ThirdParty/Ert/lib/ecl/ecl_nnc_geometry.cpp b/ThirdParty/Ert/lib/ecl/ecl_nnc_geometry.cpp index 84251d8f47..b1e1996de4 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_nnc_geometry.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_nnc_geometry.cpp @@ -16,7 +16,8 @@ for more details. */ -#include +#include +#include #include @@ -24,7 +25,7 @@ struct ecl_nnc_geometry_struct { UTIL_TYPE_ID_DECLARATION; - struct_vector_type * data; + std::vector * data; }; @@ -32,7 +33,7 @@ UTIL_IS_INSTANCE_FUNCTION( ecl_nnc_geometry, ECL_NNC_GEOMETRY_TYPE_ID ) int ecl_nnc_geometry_size( const ecl_nnc_geometry_type * nnc_geo ) { - return struct_vector_get_size( nnc_geo->data ); + return nnc_geo->data->size(); } /* @@ -71,30 +72,27 @@ static void ecl_nnc_geometry_add_pairs( const ecl_nnc_geometry_type * nnc_geo , pair.grid_nr2 = lgr_nr2; pair.global_index2 = int_vector_iget( grid2_index_list , index2 ); pair.input_index = int_vector_iget( nnc_index_list, index2 ); - struct_vector_append( nnc_geo->data , &pair); + nnc_geo->data->push_back(pair); } } } } -static int ecl_nnc_cmp(const void * _nnc1 , const void * _nnc2) { - const ecl_nnc_pair_type * nnc1 = (const ecl_nnc_pair_type * ) _nnc1; - const ecl_nnc_pair_type * nnc2 = (const ecl_nnc_pair_type * ) _nnc2; +static bool ecl_nnc_cmp(const ecl_nnc_pair_type& nnc1, const ecl_nnc_pair_type& nnc2) { + if (nnc1.grid_nr1 != nnc2.grid_nr1) + return nnc1.grid_nr1 < nnc2.grid_nr1; - if (nnc1->grid_nr1 != nnc2->grid_nr1) - return nnc1->grid_nr1 - nnc2->grid_nr1; + if (nnc1.grid_nr2 != nnc2.grid_nr2) + return nnc1.grid_nr2 < nnc2.grid_nr2; - if (nnc1->grid_nr2 != nnc2->grid_nr2) - return nnc1->grid_nr2 - nnc2->grid_nr2; + if (nnc1.global_index1 != nnc2.global_index1) + return nnc1.global_index1 < nnc2.global_index1; - if (nnc1->global_index1 != nnc2->global_index1) - return nnc1->global_index1 - nnc2->global_index1; + if (nnc1.global_index2 != nnc2.global_index2) + return nnc1.global_index2 < nnc2.global_index2; - if (nnc1->global_index2 != nnc2->global_index2) - return nnc1->global_index2 - nnc2->global_index2; - - return 0; + return true; } @@ -102,27 +100,27 @@ static int ecl_nnc_cmp(const void * _nnc1 , const void * _nnc2) { ecl_nnc_geometry_type * ecl_nnc_geometry_alloc( const ecl_grid_type * grid ) { ecl_nnc_geometry_type * nnc_geo = (ecl_nnc_geometry_type*)util_malloc( sizeof * nnc_geo ); UTIL_TYPE_ID_INIT( nnc_geo , ECL_NNC_GEOMETRY_TYPE_ID ); - nnc_geo->data = struct_vector_alloc( sizeof( struct ecl_nnc_pair_struct )); + nnc_geo->data = new std::vector(); ecl_nnc_geometry_add_pairs( nnc_geo , grid ); for (int lgr_index = 0; lgr_index < ecl_grid_get_num_lgr(grid); lgr_index++) { ecl_grid_type * igrid = ecl_grid_iget_lgr( grid , lgr_index ); ecl_nnc_geometry_add_pairs( nnc_geo, igrid ); } - struct_vector_sort( nnc_geo->data , ecl_nnc_cmp ); + std::sort(nnc_geo->data->begin(), nnc_geo->data->end(), ecl_nnc_cmp); return nnc_geo; } void ecl_nnc_geometry_free( ecl_nnc_geometry_type * nnc_geo) { - struct_vector_free( nnc_geo->data ); + delete nnc_geo->data; free( nnc_geo ); } const ecl_nnc_pair_type * ecl_nnc_geometry_iget( const ecl_nnc_geometry_type * nnc_geo , int index) { - return (const ecl_nnc_pair_type*)struct_vector_iget_ptr( nnc_geo->data , index ); - + const std::vector& nnc_data = *nnc_geo->data; + return &nnc_data[index]; } diff --git a/ThirdParty/Ert/lib/ecl/ecl_region.cpp b/ThirdParty/Ert/lib/ecl/ecl_region.cpp index f76c7fc5a0..db63184266 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_region.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_region.cpp @@ -21,10 +21,10 @@ #include #include -#include +#include -#include -#include +#include +#include #include #include @@ -170,7 +170,7 @@ void ecl_region_free( ecl_region_type * region ) { int_vector_free( region->active_index_list ); int_vector_free( region->global_index_list ); int_vector_free( region->global_active_list ); - util_safe_free( region->name ); + free( region->name ); free( region ); } @@ -633,26 +633,14 @@ void ecl_region_cmp_deselect_more( ecl_region_type * ecl_region , const ecl_kw_t input and create a temporary box object. */ -static void ecl_region_select_from_box__( ecl_region_type * region , const ecl_box_type * ecl_box , bool select) { - const int box_size = ecl_box_get_global_size( ecl_box ); - const int * active_list = ecl_box_get_global_list( ecl_box ); - int box_index; - - for (box_index = 0; box_index < box_size; box_index++) - region->active_mask[ active_list[box_index] ] = select; +static void ecl_region_select_from_box__( ecl_region_type * region , const ecl::ecl_box& ecl_box , bool select) { + for (auto global_index : ecl_box.active_list()) + region->active_mask[ global_index ] = select; ecl_region_invalidate_index_list( region ); } -void ecl_region_select_from_box( ecl_region_type * region , const ecl_box_type * ecl_box ) { - ecl_region_select_from_box__( region , ecl_box , true ); -} - - -void ecl_region_deselect_from_box( ecl_region_type * region , const ecl_box_type * ecl_box ) { - ecl_region_select_from_box__( region , ecl_box , false ); -} /*****************************************************************/ /** @@ -665,9 +653,8 @@ void ecl_region_deselect_from_box( ecl_region_type * region , const ecl_box_type */ static void ecl_region_select_from_ijkbox__( ecl_region_type * region , int i1 , int i2 , int j1 , int j2 , int k1 , int k2 , bool select) { - ecl_box_type * tmp_box = ecl_box_alloc( region->parent_grid , i1 , i2 , j1 , j2 , k1 , k2); + ecl::ecl_box tmp_box(region->parent_grid, i1, i2, j1, j2, k1, k2); ecl_region_select_from_box__( region , tmp_box , select ); - ecl_box_free( tmp_box ); } diff --git a/ThirdParty/Ert/lib/ecl/ecl_rft_cell.cpp b/ThirdParty/Ert/lib/ecl/ecl_rft_cell.cpp index ae683086f4..b5c023689f 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_rft_cell.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_rft_cell.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_rft_cell.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_rft_cell.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -43,7 +43,7 @@ struct ecl_rft_cell_struct { int i,j,k; double pressure; double depth; - + void * data; }; @@ -67,7 +67,7 @@ struct plt_data_struct { double wrat; double grat; double connection_start; - double connection_end; + double connection_end; double flowrate; double oil_flowrate; double gas_flowrate; @@ -83,7 +83,7 @@ static rft_data_type * rft_data_alloc( double swat , double sgas) { data->swat = swat; data->sgas = sgas; - + return data; } @@ -108,9 +108,9 @@ static UTIL_IS_INSTANCE_FUNCTION( rft_data , RFT_DATA_TYPE_ID) data->connection_end = connection_end; data->flowrate = flowrate; data->oil_flowrate = oil_flowrate; - data->gas_flowrate = gas_flowrate; + data->gas_flowrate = gas_flowrate; data->water_flowrate = water_flowrate; - + return data; } @@ -141,7 +141,7 @@ static ecl_rft_cell_type * ecl_rft_cell_alloc_common(int i , int j , int k , dou cell->k = k; cell->depth = depth; cell->pressure = pressure; - + return cell; } @@ -155,19 +155,19 @@ ecl_rft_cell_type * ecl_rft_cell_alloc_RFT( int i , int j , int k , double depth } -ecl_rft_cell_type * ecl_rft_cell_alloc_PLT( int i , - int j , - int k , - double depth , - double pressure , - double orat , - double grat , - double wrat, - double connection_start, +ecl_rft_cell_type * ecl_rft_cell_alloc_PLT( int i , + int j , + int k , + double depth , + double pressure , + double orat , + double grat , + double wrat, + double connection_start, double connection_end, double flowrate , - double oil_flowrate , - double gas_flowrate , + double oil_flowrate , + double gas_flowrate , double water_flowrate) { ecl_rft_cell_type * cell = ecl_rft_cell_alloc_common( i , j , k , depth , pressure ); @@ -226,107 +226,107 @@ double ecl_rft_cell_get_pressure( const ecl_rft_cell_type * cell ) { double ecl_rft_cell_get_swat( const ecl_rft_cell_type * cell ) { const rft_data_type * data = rft_data_try_cast_const( cell->data ); - if (data) + if (data) return data->swat; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } double ecl_rft_cell_get_sgas( const ecl_rft_cell_type * cell ) { const rft_data_type * data = rft_data_try_cast_const( cell->data ); - if (data) + if (data) return data->sgas; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } double ecl_rft_cell_get_soil( const ecl_rft_cell_type * cell ) { const rft_data_type * data = rft_data_try_cast_const( cell->data ); - if (data) + if (data) return 1 - (data->swat + data->sgas); else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } /*****************************************************************/ double ecl_rft_cell_get_orat( const ecl_rft_cell_type * cell ) { const plt_data_type * data = plt_data_try_cast_const( cell->data ); - if (data) + if (data) return data->orat; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } double ecl_rft_cell_get_grat( const ecl_rft_cell_type * cell ) { const plt_data_type * data = plt_data_try_cast_const( cell->data ); - if (data) + if (data) return data->grat; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } double ecl_rft_cell_get_wrat( const ecl_rft_cell_type * cell ) { const plt_data_type * data = plt_data_try_cast_const( cell->data ); - if (data) + if (data) return data->wrat; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } double ecl_rft_cell_get_connection_start( const ecl_rft_cell_type * cell ) { const plt_data_type * data = plt_data_try_cast_const( cell->data ); - if (data) + if (data) return data->connection_start; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } double ecl_rft_cell_get_connection_end( const ecl_rft_cell_type * cell ) { const plt_data_type * data = plt_data_try_cast_const( cell->data ); - if (data) + if (data) return data->connection_end; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } double ecl_rft_cell_get_flowrate( const ecl_rft_cell_type * cell ) { const plt_data_type * data = plt_data_try_cast_const( cell->data ); - if (data) + if (data) return data->flowrate; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } double ecl_rft_cell_get_oil_flowrate( const ecl_rft_cell_type * cell ) { const plt_data_type * data = plt_data_try_cast_const( cell->data ); - if (data) + if (data) return data->oil_flowrate; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } double ecl_rft_cell_get_gas_flowrate( const ecl_rft_cell_type * cell ) { const plt_data_type * data = plt_data_try_cast_const( cell->data ); - if (data) + if (data) return data->gas_flowrate; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } double ecl_rft_cell_get_water_flowrate( const ecl_rft_cell_type * cell ) { const plt_data_type * data = plt_data_try_cast_const( cell->data ); - if (data) + if (data) return data->water_flowrate; else - return ECL_RFT_CELL_INVALID_VALUE; + return ECL_RFT_CELL_INVALID_VALUE; } @@ -338,14 +338,14 @@ double ecl_rft_cell_get_water_flowrate( const ecl_rft_cell_type * cell ) { bool ecl_rft_cell_ijk_equal( const ecl_rft_cell_type * cell , int i , int j , int k) { - return ( (i == cell->i) && - (j == cell->j) && + return ( (i == cell->i) && + (j == cell->j) && (k == cell->k) ); } /* - Currently only comparison based on connection length along PLT is supported. + Currently only comparison based on connection length along PLT is supported. */ int ecl_rft_cell_cmp( const ecl_rft_cell_type * cell1 , const ecl_rft_cell_type * cell2) { double val1 = ecl_rft_cell_get_connection_start( cell1 ); @@ -357,7 +357,7 @@ int ecl_rft_cell_cmp( const ecl_rft_cell_type * cell1 , const ecl_rft_cell_type return 0; else return 1; - + } diff --git a/ThirdParty/Ert/lib/ecl/ecl_rft_file.cpp b/ThirdParty/Ert/lib/ecl/ecl_rft_file.cpp index 0600a94efe..553cb1c56d 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_rft_file.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_rft_file.cpp @@ -25,7 +25,7 @@ #include #endif -#include +#include #include #include #include diff --git a/ThirdParty/Ert/lib/ecl/ecl_rft_node.cpp b/ThirdParty/Ert/lib/ecl/ecl_rft_node.cpp index d4681bf3f6..7290dccb73 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_rft_node.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_rft_node.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -166,7 +166,7 @@ static ecl_kw_type * ecl_rft_node_get_pressure_kw( ecl_rft_node_type * rft_node else { fprintf(stderr, "WARNING: %s returned a CONPRES_KW with all values at zero. PRESSURE_KW not found.\n", __func__); return conpres_kw; - } + } } } @@ -541,7 +541,7 @@ void ecl_rft_node_fwrite(const ecl_rft_node_type * rft_node, fortio_type * forti ecl_rft_enum type = ecl_rft_node_get_type(rft_node); if (type != RFT) util_abort("%s: sorry - only writing of simple RFT is currently implemented",__func__); - + { ecl_kw_type * time = ecl_kw_alloc(TIME_KW, 1, ECL_FLOAT); ecl_kw_iset_float(time, 0, ecl_rft_node_get_days(rft_node)); diff --git a/ThirdParty/Ert/lib/ecl/ecl_rst_file.cpp b/ThirdParty/Ert/lib/ecl/ecl_rst_file.cpp index 646f6c6598..4c3e903f6e 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_rst_file.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_rst_file.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include diff --git a/ThirdParty/Ert/lib/ecl/ecl_rsthead.cpp b/ThirdParty/Ert/lib/ecl/ecl_rsthead.cpp index 56c3a87ac7..3c002cb9c5 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_rsthead.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_rsthead.cpp @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include diff --git a/ThirdParty/Ert/lib/ecl/ecl_smspec.cpp b/ThirdParty/Ert/lib/ecl/ecl_smspec.cpp index 2e774554b2..f49f4e7b6b 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_smspec.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_smspec.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -117,7 +117,6 @@ struct ecl_smspec_struct { vector_type * smspec_nodes; bool write_mode; bool need_nums; - bool locked; int_vector_type * index_map; /*-----------------------------------------------------------------*/ @@ -217,7 +216,10 @@ Completion var: VAR_TYPE:WELL_NAME:NUM */ static const char* special_vars[] = {"NEWTON", + "NAIMFRAC", "NLINEARS", + "NLINSMIN", + "NLINSMAX", "ELAPSED", "MAXDPR", "MAXDSO", @@ -272,7 +274,6 @@ ecl_smspec_type * ecl_smspec_alloc_empty(bool write_mode , const char * key_join ecl_smspec->day_index = -1; ecl_smspec->year_index = -1; ecl_smspec->month_index = -1; - ecl_smspec->locked = false; ecl_smspec->time_seconds = -1; /* @@ -303,14 +304,12 @@ int * ecl_smspec_alloc_mapping( const ecl_smspec_type * self, const ecl_smspec_t for (int i=0; i < ecl_smspec_num_nodes( self ); i++) { const smspec_node_type * self_node = ecl_smspec_iget_node( self , i ); - if (smspec_node_is_valid( self_node )) { - int self_index = smspec_node_get_params_index( self_node ); - const char * key = smspec_node_get_gen_key1( self_node ); - if (ecl_smspec_has_general_var( other , key)) { - const smspec_node_type * other_node = ecl_smspec_get_general_var_node( other , key); - int other_index = smspec_node_get_params_index(other_node); - mapping[ self_index ] = other_index; - } + int self_index = smspec_node_get_params_index( self_node ); + const char * key = smspec_node_get_gen_key1( self_node ); + if (ecl_smspec_has_general_var( other , key)) { + const smspec_node_type * other_node = ecl_smspec_get_general_var_node( other , key); + int other_index = smspec_node_get_params_index(other_node); + mapping[ self_index ] = other_index; } } @@ -334,21 +333,6 @@ int ecl_smspec_num_nodes( const ecl_smspec_type * smspec) { } -/* - In the current implementation it is impossible to mix calls to - ecl_sum_add_var() and ecl_sum_add_tstep() - i.e. one must first add - *all* the variables with ecl_sum_add_var() calls, and then - subsequently add timesteps with ecl_sum_add_tstep(). - - The locked property of the smspec structure is to ensure that no new - variables are added to the ecl_smspec structure after the first - timestep has been added. -*/ - -void ecl_smspec_lock( ecl_smspec_type * smspec ) { - smspec->locked = true; -} - /** * Returns an ecl data type for which all names will fit. If the maximum name * length is at most 8, an ECL_CHAR is returned and otherwise a large enough @@ -358,11 +342,9 @@ static ecl_data_type get_wgnames_type(const ecl_smspec_type * smspec) { size_t max_len = 0; for(int i = 0; i < ecl_smspec_num_nodes(smspec); ++i) { const smspec_node_type * node = ecl_smspec_iget_node(smspec, i); - if (smspec_node_is_valid( node )) { - const char * name = smspec_node_get_wgname( node ); - if(name) - max_len = util_size_t_max(max_len, strlen(name)); - } + const char * name = smspec_node_get_wgname( node ); + if(name) + max_len = util_size_t_max(max_len, strlen(name)); } return max_len <= ECL_STRING8_LENGTH ? ECL_CHAR : ECL_STRING(max_len); @@ -510,7 +492,7 @@ void ecl_smspec_fwrite( const ecl_smspec_type * smspec , const char * ecl_case , fortio_type * fortio = fortio_open_writer( filename , fmt_file , ECL_ENDIAN_FLIP); if (!fortio) { - char * error_fmt_msg = "%s: Unable to open fortio file %s, error: %s .\n"; + const char * error_fmt_msg = "%s: Unable to open fortio file %s, error: %s .\n"; util_abort( error_fmt_msg , __func__ , filename , strerror( errno ) ); } @@ -922,6 +904,7 @@ static void ecl_smspec_install_special_keys( ecl_smspec_type * ecl_smspec , smsp case(ECL_SMSPEC_AQUIFER_VAR): break; default: + smspec_node_fprintf(smspec_node, stderr); util_abort("%: Internal error - should never be here ?? \n",__func__); break; } @@ -1077,8 +1060,8 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi } } - util_safe_free( path ); - util_safe_free( smspec_header ); + free( path ); + free( smspec_header ); } free( restart_base ); } @@ -1087,18 +1070,11 @@ static void ecl_smspec_load_restart( ecl_smspec_type * ecl_smspec , const ecl_fi void ecl_smspec_index_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node) { - /* - It is possible crate a node which is not fully specified, e.g. the - well or group name can be left at NULL. In that case the node is - not installed in the different indexes. - */ - if (smspec_node_is_valid( smspec_node )) { - ecl_smspec_install_gen_keys( ecl_smspec , smspec_node ); - ecl_smspec_install_special_keys( ecl_smspec , smspec_node ); + ecl_smspec_install_gen_keys( ecl_smspec , smspec_node ); + ecl_smspec_install_special_keys( ecl_smspec , smspec_node ); - if (smspec_node_need_nums( smspec_node )) - ecl_smspec->need_nums = true; - } + if (smspec_node_need_nums( smspec_node )) + ecl_smspec->need_nums = true; } @@ -1110,30 +1086,27 @@ static void ecl_smspec_set_params_size( ecl_smspec_type * ecl_smspec , int param void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node){ - if (!ecl_smspec->locked) { - int internal_index = vector_get_size( ecl_smspec->smspec_nodes ); + int internal_index = vector_get_size( ecl_smspec->smspec_nodes ); - /* This IF test should only apply in write_mode. */ - if (smspec_node_get_params_index( smspec_node ) < 0) { - if (!ecl_smspec->write_mode) - util_abort("%s: internal error \n",__func__); - smspec_node_set_params_index( smspec_node , internal_index); + /* This IF test should only apply in write_mode. */ + if (smspec_node_get_params_index( smspec_node ) < 0) { + if (!ecl_smspec->write_mode) + util_abort("%s: internal error \n",__func__); + smspec_node_set_params_index( smspec_node , internal_index); - if (internal_index >= ecl_smspec->params_size) - ecl_smspec_set_params_size( ecl_smspec , internal_index + 1); - } - vector_append_owned_ref( ecl_smspec->smspec_nodes , smspec_node , smspec_node_free__ ); + if (internal_index >= ecl_smspec->params_size) + ecl_smspec_set_params_size( ecl_smspec , internal_index + 1); + } + vector_append_owned_ref( ecl_smspec->smspec_nodes , smspec_node , smspec_node_free__ ); - { - int params_index = smspec_node_get_params_index( smspec_node ); + { + int params_index = smspec_node_get_params_index( smspec_node ); - /* This indexing must be used when writing. */ - int_vector_iset( ecl_smspec->index_map , internal_index , params_index); + /* This indexing must be used when writing. */ + int_vector_iset( ecl_smspec->index_map , internal_index , params_index); - float_vector_iset( ecl_smspec->params_default , params_index , smspec_node_get_default(smspec_node) ); - } - } else - util_abort("%s: sorry - the smspec header has been locked (can not mix ecl_sum_add_var() and ecl_sum_add_tstep() calls.)\n",__func__); + float_vector_iset( ecl_smspec->params_default , params_index , smspec_node_get_default(smspec_node) ); + } } @@ -1168,7 +1141,7 @@ static const char * get_active_keyword_alias(ecl_file_type * header, const char static bool ecl_smspec_check_header( ecl_file_type * header ) { bool OK = true; - for (int i=0; i < num_req_keywords && OK; i++) { + for (size_t i=0; i < num_req_keywords && OK; i++) { OK &= ecl_file_has_kw( header, get_active_keyword_alias(header, smspec_required_keywords[i]) @@ -1257,13 +1230,13 @@ static bool ecl_smspec_fread_header(ecl_smspec_type * ecl_smspec, const char * h } else smspec_node = smspec_node_alloc( var_type , well , kw , unit , ecl_smspec->key_join_string , ecl_smspec->grid_dims , num , params_index , default_value); - - ecl_smspec_add_node( ecl_smspec , smspec_node ); + if (smspec_node) + ecl_smspec_add_node( ecl_smspec , smspec_node ); free( kw ); free( well ); free( unit ); - util_safe_free( lgr_name ); + free( lgr_name ); } } @@ -1287,7 +1260,7 @@ ecl_smspec_type * ecl_smspec_fread_alloc(const char *header_file, const char * k char *path; util_alloc_file_components(header_file , &path , NULL , NULL); ecl_smspec = ecl_smspec_alloc_empty(false , key_join_string); - util_safe_free(path); + free(path); } if (ecl_smspec_fread_header(ecl_smspec , header_file , include_restart)) { @@ -1710,6 +1683,13 @@ int ecl_smspec_get_restart_step(const ecl_smspec_type * ecl_smspec) { return ecl_smspec->restart_step; } +int ecl_smspec_get_first_step(const ecl_smspec_type * ecl_smspec) { + if (ecl_smspec->restart_step > 0) + return ecl_smspec->restart_step + 1; + else + return 1; +} + const char * ecl_smspec_get_restart_case( const ecl_smspec_type * ecl_smspec) { return ecl_smspec->restart_case; @@ -1731,7 +1711,7 @@ void ecl_smspec_free(ecl_smspec_type *ecl_smspec) { hash_free(ecl_smspec->misc_var_index); hash_free(ecl_smspec->block_var_index); hash_free(ecl_smspec->gen_var_index); - util_safe_free( ecl_smspec->header_file ); + free( ecl_smspec->header_file ); int_vector_free( ecl_smspec->index_map ); float_vector_free( ecl_smspec->params_default ); vector_free( ecl_smspec->smspec_nodes ); @@ -1932,10 +1912,6 @@ const int * ecl_smspec_get_grid_dims( const ecl_smspec_type * smspec ) { } -void ecl_smspec_update_wgname( ecl_smspec_type * smspec , smspec_node_type * node , const char * wgname ) { - smspec_node_update_wgname( node , wgname , smspec->key_join_string); - ecl_smspec_index_node( smspec , node ); -} /*****************************************************************/ diff --git a/ThirdParty/Ert/lib/ecl/ecl_subsidence.cpp b/ThirdParty/Ert/lib/ecl/ecl_subsidence.cpp index 301e3ce9a9..1e06968afd 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_subsidence.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_subsidence.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -32,10 +32,10 @@ #include #include #include -#include #include #include +#include "detail/ecl/ecl_grid_cache.hpp" /** This file contains datastructures for calculating changes in @@ -52,7 +52,7 @@ struct ecl_subsidence_struct { const ecl_file_type * init_file; /* The init file - a shared reference owned by calling scope. */ - ecl_grid_cache_type * grid_cache; /* An internal specialized structure to facilitate fast grid lookup. */ + ecl::ecl_grid_cache * grid_cache; bool * aquifer_cell; hash_type * surveys; /* A hash table containg ecl_subsidence_survey_type instances; one instance for each interesting time. */ @@ -70,7 +70,7 @@ struct ecl_subsidence_struct { #define ECL_SUBSIDENCE_SURVEY_ID 88517 struct ecl_subsidence_survey_struct { UTIL_TYPE_ID_DECLARATION; - const ecl_grid_cache_type * grid_cache; + const ecl::ecl_grid_cache * grid_cache; const bool * aquifer_cell; /* Is this cell a numerical aquifer cell - must be disregarded. */ char * name; /* Name of the survey - arbitrary string. */ double * porv; /* Reference pore volume */ @@ -90,8 +90,8 @@ static ecl_subsidence_survey_type * ecl_subsidence_survey_alloc_empty(const ecl_ survey->aquifer_cell = sub->aquifer_cell; survey->name = util_alloc_string_copy( name ); - survey->porv = (double*)util_calloc( ecl_grid_cache_get_size( sub->grid_cache ) , sizeof * survey->porv ); - survey->pressure = (double*)util_calloc( ecl_grid_cache_get_size( sub->grid_cache ) , sizeof * survey->pressure ); + survey->porv = (double*) util_calloc( sub->grid_cache->size() , sizeof * survey->porv ); + survey->pressure = (double*) util_calloc( sub->grid_cache->size() , sizeof * survey->pressure ); return survey; } @@ -103,9 +103,10 @@ static ecl_subsidence_survey_type * ecl_subsidence_survey_alloc_PRESSURE(ecl_sub const char * name ) { ecl_subsidence_survey_type * survey = ecl_subsidence_survey_alloc_empty( ecl_subsidence , name ); - ecl_grid_cache_type * grid_cache = ecl_subsidence->grid_cache; - const int * global_index = ecl_grid_cache_get_global_index( grid_cache ); - const int size = ecl_grid_cache_get_size( grid_cache ); + const ecl::ecl_grid_cache& grid_cache = *(ecl_subsidence->grid_cache); + const auto& global_index = grid_cache.global_index(); + const int size = grid_cache.size(); + int active_index; ecl_kw_type * init_porv_kw = ecl_file_iget_named_kw( ecl_subsidence->init_file , PORV_KW , 0); /*Global indexing*/ ecl_kw_type * pressure_kw = ecl_file_view_iget_named_kw( restart_view , PRESSURE_KW , 0); /*Active indexing*/ @@ -123,8 +124,8 @@ static ecl_subsidence_survey_type * ecl_subsidence_survey_alloc_PRESSURE(ecl_sub static void ecl_subsidence_survey_free( ecl_subsidence_survey_type * subsidence_survey ) { free( subsidence_survey->name ); - util_safe_free( subsidence_survey->porv ); - util_safe_free( subsidence_survey->pressure ); + free( subsidence_survey->porv ); + free( subsidence_survey->pressure ); free( subsidence_survey ); } @@ -142,8 +143,8 @@ static double ecl_subsidence_survey_eval( const ecl_subsidence_survey_type * bas double utm_x , double utm_y , double depth, double compressibility, double poisson_ratio) { - const ecl_grid_cache_type * grid_cache = base_survey->grid_cache; - const int size = ecl_grid_cache_get_size( grid_cache ); + const ecl::ecl_grid_cache& grid_cache = *(base_survey->grid_cache); + const int size = grid_cache.size(); double * weight = (double*)util_calloc( size , sizeof * weight ); double deltaz; int index; @@ -170,9 +171,9 @@ static double ecl_subsidence_survey_eval_geertsma( const ecl_subsidence_survey_t double utm_x , double utm_y , double depth, double youngs_modulus, double poisson_ratio, double seabed) { - const ecl_grid_cache_type * grid_cache = base_survey->grid_cache; - const double * cell_volume = ecl_grid_cache_get_volume( grid_cache ); - const int size = ecl_grid_cache_get_size( grid_cache ); + const ecl::ecl_grid_cache& grid_cache = *(base_survey->grid_cache); + const auto& cell_volume = grid_cache.volume(); + const int size = grid_cache.size(); double scale_factor = 1e4 *(1 + poisson_ratio) * ( 1 - 2*poisson_ratio) / ( 4*M_PI*( 1 - poisson_ratio) * youngs_modulus ); double * weight = (double*)util_calloc( size , sizeof * weight ); double deltaz; @@ -204,8 +205,8 @@ static double ecl_subsidence_survey_eval_geertsma( const ecl_subsidence_survey_t ecl_subsidence_type * ecl_subsidence_alloc( const ecl_grid_type * ecl_grid, const ecl_file_type * init_file) { ecl_subsidence_type * ecl_subsidence = (ecl_subsidence_type*)util_malloc( sizeof * ecl_subsidence ); ecl_subsidence->init_file = init_file; - ecl_subsidence->grid_cache = ecl_grid_cache_alloc( ecl_grid ); - ecl_subsidence->aquifer_cell = ecl_grav_common_alloc_aquifer_cell( ecl_subsidence->grid_cache , init_file ); + ecl_subsidence->grid_cache = new ecl::ecl_grid_cache(ecl_grid); + ecl_subsidence->aquifer_cell = ecl_grav_common_alloc_aquifer_cell( *(ecl_subsidence->grid_cache) , init_file ); ecl_subsidence->surveys = hash_alloc(); return ecl_subsidence; @@ -254,7 +255,8 @@ double ecl_subsidence_eval_geertsma( const ecl_subsidence_type * subsidence , co } void ecl_subsidence_free( ecl_subsidence_type * ecl_subsidence ) { - ecl_grid_cache_free( ecl_subsidence->grid_cache ); + delete ecl_subsidence->grid_cache; + free( ecl_subsidence->aquifer_cell ); hash_free( ecl_subsidence->surveys ); free( ecl_subsidence ); diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum.cpp index 070a70d00b..c5c27b58ee 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum.cpp @@ -16,6 +16,8 @@ for more details. */ +#include + #include #include #include @@ -23,9 +25,8 @@ #include #include -#include -#include -#include +#include +#include #include #include #include @@ -40,6 +41,7 @@ #include #include +#include "detail/util/path.hpp" /** The ECLIPSE summary data is organised in a header file (.SMSPEC) @@ -124,28 +126,37 @@ UTIL_IS_INSTANCE_FUNCTION( ecl_sum , ECL_SUM_ID ); */ void ecl_sum_set_case( ecl_sum_type * ecl_sum , const char * input_arg) { - util_safe_free( ecl_sum->ecl_case ); - util_safe_free( ecl_sum->path ); - util_safe_free( ecl_sum->abs_path ); - util_safe_free( ecl_sum->base ); - util_safe_free( ecl_sum->ext ); + free( ecl_sum->ecl_case ); + free( ecl_sum->path ); + free( ecl_sum->abs_path ); + free( ecl_sum->base ); + free( ecl_sum->ext ); { - char *path , *base, *ext; + std::string path = ecl::util::path::dirname(input_arg); + std::string base = ecl::util::path::basename(input_arg); + std::string ext = ecl::util::path::extension(input_arg); + + ecl_sum->ecl_case = util_alloc_filename(path.c_str(), base.c_str(), NULL); + if (path.size()) + ecl_sum->path = util_alloc_string_copy( path.c_str() ); + else + ecl_sum->path = NULL; + + if (base.size()) + ecl_sum->base = util_alloc_string_copy( base.c_str() ); + else + ecl_sum->base = NULL; - util_alloc_file_components( input_arg, &path , &base , &ext); + if (ext.size()) + ecl_sum->ext = util_alloc_string_copy( ext.c_str() ); + else + ecl_sum->ext = NULL; - ecl_sum->ecl_case = util_alloc_filename( path, base, NULL ); - ecl_sum->path = util_alloc_string_copy( path ); - ecl_sum->base = util_alloc_string_copy( base ); - ecl_sum->ext = util_alloc_string_copy( ext ); - if (path != NULL) - ecl_sum->abs_path = util_alloc_abs_path( path ); + if (path.size() > 0) + ecl_sum->abs_path = util_alloc_abs_path( path.c_str() ); else ecl_sum->abs_path = util_alloc_cwd(); - util_safe_free( base ); - util_safe_free( path ); - util_safe_free( ext ); } } @@ -173,22 +184,22 @@ static ecl_sum_type * ecl_sum_alloc__( const char * input_arg , const char * key } -static bool ecl_sum_fread_data( ecl_sum_type * ecl_sum , const stringlist_type * data_files , bool include_restart) { +static bool ecl_sum_fread_data( ecl_sum_type * ecl_sum , const stringlist_type * data_files , bool include_restart, bool lazy_load, int file_options) { if (ecl_sum->data != NULL) ecl_sum_free_data( ecl_sum ); ecl_sum->data = ecl_sum_data_alloc( ecl_sum->smspec ); - return ecl_sum_data_fread( ecl_sum->data , data_files); + return ecl_sum_data_fread( ecl_sum->data , data_files, lazy_load, file_options); } -static void ecl_sum_fread_history( ecl_sum_type * ecl_sum ) { +static void ecl_sum_fread_history( ecl_sum_type * ecl_sum, bool lazy_load, int file_options) { char * restart_header = ecl_util_alloc_filename(NULL, ecl_smspec_get_restart_case(ecl_sum->smspec), ECL_SUMMARY_HEADER_FILE, ecl_smspec_get_formatted(ecl_sum->smspec), -1); - ecl_sum_type * restart_case = ecl_sum_fread_alloc_case__(restart_header, ":" , true); + ecl_sum_type * restart_case = ecl_sum_fread_alloc_case2__(restart_header, ":" , true, lazy_load, file_options); if (restart_case) { ecl_sum->restart_case = restart_case; ecl_sum_data_add_case(ecl_sum->data , restart_case->data ); @@ -198,7 +209,7 @@ static void ecl_sum_fread_history( ecl_sum_type * ecl_sum ) { -static bool ecl_sum_fread(ecl_sum_type * ecl_sum , const char *header_file , const stringlist_type *data_files , bool include_restart) { +static bool ecl_sum_fread(ecl_sum_type * ecl_sum , const char *header_file , const stringlist_type *data_files , bool include_restart, bool lazy_load, int file_options) { ecl_sum->smspec = ecl_smspec_fread_alloc( header_file , ecl_sum->key_join_string , include_restart); if (ecl_sum->smspec) { bool fmt_file; @@ -207,7 +218,7 @@ static bool ecl_sum_fread(ecl_sum_type * ecl_sum , const char *header_file , con } else return false; - if (ecl_sum_fread_data( ecl_sum , data_files , include_restart )) { + if (ecl_sum_fread_data( ecl_sum , data_files , include_restart, lazy_load, file_options )) { ecl_file_enum file_type = ecl_util_get_file_type( stringlist_iget( data_files , 0 ) , NULL , NULL); if (file_type == ECL_SUMMARY_FILE) @@ -220,13 +231,13 @@ static bool ecl_sum_fread(ecl_sum_type * ecl_sum , const char *header_file , con return false; if (include_restart && ecl_smspec_get_restart_case( ecl_sum->smspec )) - ecl_sum_fread_history( ecl_sum ); + ecl_sum_fread_history( ecl_sum, lazy_load, file_options); return true; } -static bool ecl_sum_fread_case( ecl_sum_type * ecl_sum , bool include_restart) { +static bool ecl_sum_fread_case( ecl_sum_type * ecl_sum , bool include_restart, bool lazy_load, int file_options) { char * header_file; stringlist_type * summary_file_list = stringlist_alloc_new(); @@ -234,9 +245,9 @@ static bool ecl_sum_fread_case( ecl_sum_type * ecl_sum , bool include_restart) { ecl_util_alloc_summary_files( ecl_sum->path , ecl_sum->base , ecl_sum->ext , &header_file , summary_file_list ); if ((header_file != NULL) && (stringlist_get_size( summary_file_list ) > 0)) { - caseOK = ecl_sum_fread( ecl_sum , header_file , summary_file_list , include_restart ); + caseOK = ecl_sum_fread( ecl_sum , header_file , summary_file_list , include_restart, lazy_load, file_options ); } - util_safe_free( header_file ); + free( header_file ); stringlist_free( summary_file_list ); return caseOK; @@ -254,10 +265,10 @@ static bool ecl_sum_fread_case( ecl_sum_type * ecl_sum , bool include_restart) { */ -ecl_sum_type * ecl_sum_fread_alloc(const char *header_file , const stringlist_type *data_files , const char * key_join_string, bool include_restart) { +ecl_sum_type * ecl_sum_fread_alloc(const char *header_file , const stringlist_type *data_files , const char * key_join_string, bool include_restart, bool lazy_load, int file_options) { ecl_sum_type * ecl_sum = ecl_sum_alloc__( header_file , key_join_string ); if (ecl_sum) { - if (!ecl_sum_fread( ecl_sum , header_file , data_files , include_restart)) { + if (!ecl_sum_fread( ecl_sum , header_file , data_files , include_restart, lazy_load, file_options)) { ecl_sum_free( ecl_sum ); ecl_sum = NULL; } @@ -277,14 +288,24 @@ void ecl_sum_set_fmt_case( ecl_sum_type * ecl_sum , bool fmt_case ) { } -void ecl_sum_init_var( ecl_sum_type * ecl_sum , smspec_node_type * smspec_node , const char * keyword , const char * wgname , int num , const char * unit) { - ecl_smspec_init_var( ecl_sum->smspec , smspec_node , keyword , wgname , num, unit ); -} smspec_node_type * ecl_sum_add_var( ecl_sum_type * ecl_sum , const char * keyword , const char * wgname , int num , const char * unit , float default_value) { - smspec_node_type * smspec_node = ecl_sum_add_blank_var( ecl_sum , default_value ); - ecl_sum_init_var( ecl_sum , smspec_node , keyword , wgname , num , unit ); + if (ecl_sum_data_get_length(ecl_sum->data) > 0) + throw std::invalid_argument("Can not interchange variable adding and timesteps.\n"); + + + smspec_node_type * smspec_node = smspec_node_alloc( ecl_smspec_identify_var_type(keyword), + wgname, + keyword, + unit, + ecl_sum->key_join_string, + ecl_smspec_get_grid_dims(ecl_sum->smspec), + num, + -1, + default_value); + ecl_smspec_add_node(ecl_sum->smspec, smspec_node); + ecl_sum_data_reset_self_map( ecl_sum->data ); return smspec_node; } @@ -298,11 +319,6 @@ smspec_node_type * ecl_sum_add_smspec_node(ecl_sum_type * ecl_sum, const smspec_ } -smspec_node_type * ecl_sum_add_blank_var( ecl_sum_type * ecl_sum , float default_value) { - smspec_node_type * smspec_node = smspec_node_alloc_new( -1 , default_value ); - ecl_smspec_add_node( ecl_sum->smspec , smspec_node ); - return smspec_node; -} @@ -371,6 +387,10 @@ void ecl_sum_fwrite( const ecl_sum_type * ecl_sum ) { } +bool ecl_sum_can_write(const ecl_sum_type * ecl_sum) { + return ecl_sum_data_can_write(ecl_sum->data); +} + void ecl_sum_fwrite_smspec( const ecl_sum_type * ecl_sum ) { ecl_smspec_fwrite( ecl_sum->smspec , ecl_sum->ecl_case , ecl_sum->fmt_case ); } @@ -400,9 +420,9 @@ void ecl_sum_free( ecl_sum_type * ecl_sum ) { if (ecl_sum->smspec) ecl_smspec_free( ecl_sum->smspec ); - util_safe_free( ecl_sum->path ); - util_safe_free( ecl_sum->ext ); - util_safe_free( ecl_sum->abs_path ); + free( ecl_sum->path ); + free( ecl_sum->ext ); + free( ecl_sum->abs_path ); free( ecl_sum->base ); free( ecl_sum->ecl_case ); @@ -441,12 +461,12 @@ void ecl_sum_free__(void * __ecl_sum) { */ -ecl_sum_type * ecl_sum_fread_alloc_case__(const char * input_file , const char * key_join_string , bool include_restart){ +ecl_sum_type * ecl_sum_fread_alloc_case2__(const char * input_file , const char * key_join_string , bool include_restart, bool lazy_load, int file_options){ ecl_sum_type * ecl_sum = ecl_sum_alloc__(input_file , key_join_string); if (!ecl_sum) return NULL; - if (ecl_sum_fread_case( ecl_sum , include_restart)) + if (ecl_sum_fread_case( ecl_sum , include_restart, lazy_load, file_options)) return ecl_sum; else { /* @@ -458,11 +478,18 @@ ecl_sum_type * ecl_sum_fread_alloc_case__(const char * input_file , const char * } } +ecl_sum_type * ecl_sum_fread_alloc_case__(const char * input_file , const char * key_join_string , bool include_restart) { + bool lazy_load = true; + int file_options = 0; + return ecl_sum_fread_alloc_case2__(input_file, key_join_string, include_restart, lazy_load, file_options); +} ecl_sum_type * ecl_sum_fread_alloc_case(const char * input_file , const char * key_join_string){ bool include_restart = true; - return ecl_sum_fread_alloc_case__( input_file , key_join_string , include_restart ); + bool lazy_load = true; + int file_options = 0; + return ecl_sum_fread_alloc_case2__( input_file , key_join_string , include_restart, lazy_load, file_options ); } @@ -477,10 +504,10 @@ bool ecl_sum_case_exists( const char * input_file ) { util_alloc_file_components( input_file , &path , &basename , &extension); case_exists = ecl_util_alloc_summary_files( path , basename , extension , &smspec_file , data_files ); - util_safe_free( path ); - util_safe_free( basename ); - util_safe_free( extension ); - util_safe_free( smspec_file ); + free( path ); + free( basename ); + free( extension ); + free( smspec_file ); stringlist_free( data_files ); return case_exists; @@ -755,7 +782,7 @@ const char * ecl_sum_get_general_var_unit( const ecl_sum_type * ecl_sum , const ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times) { time_t start_time = ecl_sum_get_data_start(ecl_sum); - if ( time_t_vector_get_first(times) < start_time ) + if ( time_t_vector_get_first(times) < start_time ) return NULL; if ( time_t_vector_get_last(times) > ecl_sum_get_end_time(ecl_sum) ) return NULL; @@ -778,9 +805,6 @@ ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * if (util_string_equal(smspec_node_get_gen_key1(node), "TIME")) continue; - if (!smspec_node_is_valid(node)) - continue; - ecl_sum_add_smspec_node( ecl_sum_resampled, node ); } @@ -885,33 +909,17 @@ int ecl_sum_iget_report_end( const ecl_sum_type * ecl_sum, int report_step) { return ecl_sum_data_iget_report_end(ecl_sum->data , report_step ); } -int ecl_sum_iget_report_start( const ecl_sum_type * ecl_sum, int report_step) { - return ecl_sum_data_iget_report_start(ecl_sum->data , report_step ); -} int ecl_sum_iget_report_step( const ecl_sum_type * ecl_sum , int internal_index ){ return ecl_sum_data_iget_report_step( ecl_sum->data , internal_index ); } -int ecl_sum_iget_mini_step( const ecl_sum_type * ecl_sum , int internal_index ){ - return ecl_sum_data_iget_mini_step( ecl_sum->data , internal_index ); -} - - -void ecl_sum_init_time_vector( const ecl_sum_type * ecl_sum , time_t_vector_type * time_vector , bool report_only ) { - ecl_sum_data_init_time_vector( ecl_sum->data , time_vector , report_only ); -} - time_t_vector_type * ecl_sum_alloc_time_vector( const ecl_sum_type * ecl_sum , bool report_only) { return ecl_sum_data_alloc_time_vector( ecl_sum->data , report_only ); } -void ecl_sum_init_data_vector( const ecl_sum_type * ecl_sum , double_vector_type * data_vector , int data_index , bool report_only ) { - ecl_sum_data_init_data_vector( ecl_sum->data , data_vector , data_index , report_only ); -} - void ecl_sum_init_double_vector__(const ecl_sum_type * ecl_sum, int params_index, double * data) { ecl_sum_data_init_double_vector(ecl_sum->data, params_index, data); @@ -1259,8 +1267,8 @@ bool ecl_sum_same_case( const ecl_sum_type * ecl_sum , const char * input_file ) } } - util_safe_free( path ); - util_safe_free( base ); + free( path ); + free( base ); } return same_case; } @@ -1346,14 +1354,6 @@ int ecl_sum_get_data_length( const ecl_sum_type * ecl_sum ) { return ecl_sum_data_get_length( ecl_sum->data ); } -void ecl_sum_scale_vector( ecl_sum_type * ecl_sum, int index, double scalar ) { - ecl_sum_data_scale_vector( ecl_sum->data, index, scalar ); -} - -void ecl_sum_shift_vector( ecl_sum_type * ecl_sum, int index, double addend ) { - ecl_sum_data_shift_vector( ecl_sum->data, index, addend ); -} - bool ecl_sum_check_sim_time( const ecl_sum_type * sum , time_t sim_time) { return ecl_sum_data_check_sim_time( sum->data , sim_time ); } @@ -1381,9 +1381,6 @@ const ecl_smspec_type * ecl_sum_get_smspec( const ecl_sum_type * ecl_sum ) { return ecl_sum->smspec; } -void ecl_sum_update_wgname( ecl_sum_type * ecl_sum , smspec_node_type * node , const char * wgname ) { - ecl_smspec_update_wgname( ecl_sum->smspec ,node , wgname ); -} /*****************************************************************/ diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum_data.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum_data.cpp index a1d3e0f3f1..7cf72a309c 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum_data.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum_data.cpp @@ -19,11 +19,17 @@ #include #include -#include +#include +#include +#include +#include + +#include #include #include #include #include +#include #include #include @@ -36,240 +42,242 @@ #include #include - +#include "detail/ecl/ecl_sum_file_data.hpp" /* - This file implements the type ecl_sum_data_type. The data structure - is involved with holding all the actual summary data (i.e. the - PARAMS vectors in ECLIPSE speak), in addition the time-information - with MINISTEPS / REPORT_STEPS and so on is implemented here. - - This file has no information about how to index into the PARAMS - vector, i.e. at which location can the WWCT for well P6 be found, - that is responsability of the ecl_smspec_type. - - The time direction in this system is implemented in terms of - ministeps. There are some query / convert functons based on report - steps. + This file implements the sruct ecl_sum_data which manages the actual simulated + values from a summary file, including all time-related information. In the + case of restarted simulations the different summary cases will be internalized + as separate ecl_sum_file_data instances. The ecl_sum_file_data class is an + internal implemenation detail which is not exported. More details about the + internal storage of summary data can be found in that file. + + For this file the implementation mainly consists of maintaining an ordered + list of ecl_sum_file_data instances and dispatching method calls to the right + ecl_sum_file_data instance. */ +namespace { -/*****************************************************************/ /* - About ministeps and report steps. - --------------------------------- - - A sequence of summary data will typically look like this: - - ------------------ - SEQHDR \ - MINISTEP 0 | - PARAMS ..... | - MINISTEP 1 |==> This is REPORT STEP 1, in file BASE.S00001 - PARAMS ..... | - MINISTEP 2 | - PARAMS ..... / - ------------------ - SEQHDR \ - MINISTEP 3 | - PARAMS ..... | - MINISTEP 4 | - PARAMS ..... | - MINISTEP 5 |==> This is REPORT STEP 2, in file BASE.S0002 - PARAMS ..... | - MINISTEP 6 | - PARAMS ..... | - SEQHDR | - MINISTEP 7 | - PARAMS ..... / - ------------------ - - - Observe the following: - - * The MINISTEP counter runs continously, and does not - differentiate between unified files and not unified files. - - * When using multiple files we can read off the report number - from the filename, for unified files this is IMPOSSIBLE, and we - just have to assume that the first block corresponds to - report_step 1 and then count afterwards. - - * When asking for a summary variable at a particular REPORT STEP - (as we do in enkf) it is ambigous as to which ministep within - the block one should use. The convention we have employed - (which corresponds to the old RPTONLY based behaviour) is to - use the last ministep in the block. + The class CaseIndex and the struct IndexNode are used to maintain a list of + the ecl_sum_file_data instances, and lookup the correct one based one various + time related arguments. +*/ - * There is no BASE.SOOOO file + struct IndexNode { + IndexNode(int d, int o, int l) { + this->data_index = d; + this->offset = o; + this->length = l; + } - * The report steps are halfopen intervals in the "wrong way": - (....] + int end() const { + return this->offset + this->length; + } + int data_index; + int offset; + int length; + int report1; + int report2; + time_t time1; + time_t time2; + double days1; + double days2; + std::vector params_map; + }; + class CaseIndex { + public: - About MINISTEP, REPORTSTEP, rates and continous sim_time/sim_days: - ------------------------------------------------------------------ + IndexNode& add(int length) { + int offset = 0; + int data_index = this->index.size(); - For ECLIPSE summary files the smallest unit of time resolution is - called the ministep - a ministep corresponds to a time step in the - underlying partial differential equation, i.e. the length of the - timesteps is controlled by the simulator itself - there is no finer - temporal resolution. + if (!this->index.empty()) + offset = this->index.back().end(); - The user has told the simulator to store (i.e. save to file - results) the results at reportsteps. A reportstep will typically - consist of several ministeps. The timeline below shows a simulation - consisting of two reportsteps: + this->index.emplace_back(data_index, offset, length); + return this->index.back(); + } +/* + The lookup_time() and lookup_report() methods will lookup which file_data + instance corresponds to the time/report argument. The methods will return two + pointers to file_data instances, if the argument is inside one file_data + instance the pointers will be equal - otherwise they will point to the + file_data instance before and after the argument: + + File 1 File 2 + |------|-----|------| |----|----------|---| + /|\ /|\ + | | + | | + A B + + For time A the lookup_time function will return whereas for time + B the function will return . + */ + + std::pair lookup_time(time_t sim_time) const { + auto iter = this->index.begin(); + auto next = this->index.begin(); + if (sim_time < iter->time1) + throw std::invalid_argument("Simulation time out of range"); + + ++next; + while (true) { + double t1 = iter->time1; + double t2 = iter->time2; + + + if (sim_time>= t1) { + if (sim_time <= t2) + return std::make_pair(&(*iter), &(*iter)); + + if (next == this->index.end()) + throw std::invalid_argument("Simulation days out of range"); + + if (sim_time < next->time1) + return std::make_pair(&(*iter),&(*next)); + } + ++next; + ++iter; + } + } - S0001 S0002 - ||------|------|------------|------------------||----------------------|----------------------|| - M1 M2 M3 M4 M5 M6 - The first reportstep consist of four ministeps, the second - reportstep consits of only two ministeps. As a user you have no - control over the length/number of ministeps apart from: + std::pair lookup_days(double days) const { + auto iter = this->index.begin(); + auto next = this->index.begin(); + if (days < iter->days1) + throw std::invalid_argument("Simulation days out of range"); - 1. Indirectly through the TUNING keywords. - 2. A ministep will always end at a report step. + ++next; + while (true) { + double d1 = iter->days1; + double d2 = iter->days2; - RPTONLY: In conjunction with enkf it has been customary to use the - keyword RPTONLY. This is purely a storage directive, the effect is - that only the ministep ending at the REPORT step is reported, - i.e. in the case above we would get the ministeps [M4 , M6], where - the ministeps M4 and M6 will be unchanged, and there will be many - 'holes' in the timeline. + if (days >= d1) { + if (days <= d2) + return std::make_pair(&(*iter), &(*iter)); - About truetime: The ministeps have a finite length; this implies - that + if (next == this->index.end()) + throw std::invalid_argument("Simulation days out of range"); - [rates]: The ministep value is NOT actually an instantaneous - value, it is the total production during the ministepd period - - divided by the length of the ministep. I.e. it is an average - value. (I.e. the differential time element dt is actually quite - looong). + if (days < next->days1) + return std::make_pair(&(*iter),&(*next)); + } + ++next; + ++iter; + } + } - [state]: For state variables (this will include total production - of various phases), the ministep value corresponds to the - reservoir state at THE END OF THE MINISTEP. + const IndexNode& lookup(int internal_index) const { + for (const auto& node : this->index) + if (internal_index >= node.offset && internal_index < node.end()) + return node; - This difference between state variables and rates implies a - difference in how continous time-variables (in the middle of a - ministep) are reported, i.e. + throw std::invalid_argument("Internal error when looking up index: " + std::to_string(internal_index)); + } - S0000 S0001 - ||--------------|---------------|------------X-------------|| - M1 M2 /|\ M3 - | - | + const IndexNode& lookup_report(int report) const { + for (const auto& node : this->index) + if (node.report1 <= report && node.report2 >= report) + return node; - We have enteeed the sim_days/sim_time cooresponding to the location - of 'X' on the timeline, i.e. in the middle of ministep M3. If we - are interested in the rate at this time the function: + throw std::invalid_argument("Internal error when looking up report: " + std::to_string(report)); + } - ecl_sum_data_get_from_sim_time() + /* + This will check that we have a datafile which report range covers the + report argument, in adition there can be 'holes' in the series - that must + be checked by actually querying the data_file object. + */ - will just return the M3 value, whereas if you are interested in - e.g. pressure at this time the function will return a weighted - average of the M2 and M3 values. Whether a variable in question is - interpreted as a 'rate' is effectively determined by the - ecl_smspec_set_rate_var() function in ecl_smspec.c. + bool has_report(int report) const { + for (const auto& node : this->index) + if (node.report1 <= report && node.report2 >= report) + return true; + return false; + } + IndexNode& back() { + return this->index.back(); + } - Indexing and _get() versus _iget() - ---------------------------------- - As already mentionded the set of ministeps is not necessarrily a - continous series, we can easily have a series of ministeps with - "holes" in it, and the series can also start on a non-zero - value. Internally all the ministeps are stored in a dense, zero - offset vector instance; and we must be able to translate back and - forth between ministep_nr and internal index. + void clear() { + this->index.clear(); + } - Partly due to EnKF heritage the MINISTEP nr has been the main - method to access the time dimension of the data, i.e. all the - functions like ecl_sum_get_general_var() expect the time direction - to be given as a ministep; however it is also possible to get the - data by giving an internal (not that internal ...) index. In - ecl_sum_data.c the latter functions have _iget(): + int length() const { + return this->index.back().end(); + } + std::vector::const_iterator begin() const { + return this->index.begin(); + } - ecl_sum_data_get_xxx : Expects the time direction given as a ministep_nr. - ecl_sum_data_iget_xxx: Expects the time direction given as an internal index. + std::vector::const_iterator end() const { + return this->index.end(); + } -*/ + private: + std::vector index; + }; +} -#define INVALID_MINISTEP_NR -1 -#define INVALID_TIME_T 0 struct ecl_sum_data_struct { - ecl_smspec_type * smspec; /* A shared reference - only used for providing good error messages. */ - vector_type * data; /* Vector of ecl_sum_tstep_type instances. */ - double days_start; - double sim_length; - int_vector_type * report_first_index ; /* Indexed by report_step - giving first internal_index in report_step. */ - int_vector_type * report_last_index; /* Indexed by report_step - giving last internal_index in report_step. */ - int first_report_step; - int last_report_step; - bool index_valid; - time_t start_time; /* In the case of restarts the start might disagree with the value reported - in the smspec file. */ - time_t end_time; + const ecl_smspec_type * smspec; + std::vector data_files; // List of ecl_sum_file_data instances + CaseIndex index; }; +static void ecl_sum_data_build_index( ecl_sum_data_type * self ); +static double ecl_sum_data_iget_sim_seconds( const ecl_sum_data_type * data , int internal_index ); /*****************************************************************/ void ecl_sum_data_free( ecl_sum_data_type * data ) { - vector_free( data->data ); - int_vector_free( data->report_first_index ); - int_vector_free( data->report_last_index ); - free(data); -} + if (!data) + throw std::invalid_argument(__func__ + std::string(": invalid delete") ); -/* - This function will clear/initialize all the mapping between - ministep, report step and internal index. This function should be - called before (re)building the indexes. -*/ + if (data->data_files.size() > 0) + delete data->data_files.back(); + delete data; +} -static void ecl_sum_data_clear_index( ecl_sum_data_type * data ) { - int_vector_reset( data->report_first_index); - int_vector_reset( data->report_last_index); - data->first_report_step = 1024 * 1024; - data->last_report_step = -1024 * 1024; - data->days_start = 0; - data->sim_length = -1; - data->index_valid = false; - data->start_time = INVALID_TIME_T; - data->end_time = INVALID_TIME_T; +ecl_sum_data_type * ecl_sum_data_alloc(ecl_smspec_type * smspec) { + ecl_sum_data_type * data = new ecl_sum_data_type(); + data->smspec = smspec; + return data; } -ecl_sum_data_type * ecl_sum_data_alloc(ecl_smspec_type * smspec) { - ecl_sum_data_type * data = (ecl_sum_data_type*)util_malloc( sizeof * data ); - data->data = vector_alloc_new(); - data->smspec = smspec; +void ecl_sum_data_reset_self_map( ecl_sum_data_type * data ) { + ecl_sum_data_build_index(data); +} - data->report_first_index = int_vector_alloc( 0 , INVALID_MINISTEP_NR ); - data->report_last_index = int_vector_alloc( 0 , INVALID_MINISTEP_NR ); - ecl_sum_data_clear_index( data ); - return data; +static void ecl_sum_data_append_file_data( ecl_sum_data_type * sum_data, ecl::ecl_sum_file_data * file_data) { + sum_data->data_files.push_back( file_data ); } + /** This function will take a report as input , and update the two pointers ministep1 and ministep2 with the range of the report step @@ -292,101 +300,40 @@ ecl_sum_data_type * ecl_sum_data_alloc(ecl_smspec_type * smspec) { */ -static ecl_sum_tstep_type * ecl_sum_data_iget_ministep( const ecl_sum_data_type * data , int internal_index ) { - return (ecl_sum_tstep_type*)vector_iget( data->data , internal_index ); -} - -void ecl_sum_data_report2internal_range(const ecl_sum_data_type * data , int report_step , int * index1 , int * index2 ){ - if (index1 != NULL) - *index1 = int_vector_safe_iget( data->report_first_index , report_step ); - - if (index2 != NULL) - *index2 = int_vector_safe_iget( data->report_last_index , report_step ); +static double ecl_sum_data_iget_sim_seconds( const ecl_sum_data_type * data , int internal_index ) { + const auto index_node = data->index.lookup(internal_index); + const auto data_file = data->data_files[index_node.data_index]; + return data_file->iget_sim_seconds( internal_index - index_node.offset ); } - -ecl_sum_data_type * ecl_sum_data_alloc_writer( ecl_smspec_type * smspec ) { - ecl_sum_data_type * data = ecl_sum_data_alloc( smspec ); - return data; -} - - -static void ecl_sum_data_fwrite_report__( const ecl_sum_data_type * data , int report_step , fortio_type * fortio) { - { - ecl_kw_type * seqhdr_kw = ecl_kw_alloc( SEQHDR_KW , SEQHDR_SIZE , ECL_INT ); - ecl_kw_iset_int( seqhdr_kw , 0 , 0 ); - ecl_kw_fwrite( seqhdr_kw , fortio ); - ecl_kw_free( seqhdr_kw ); - } - - { - int index , index1 , index2; - - ecl_sum_data_report2internal_range( data , report_step , &index1 , &index2); - for (index = index1; index <= index2; index++) { - const ecl_sum_tstep_type * tstep = ecl_sum_data_iget_ministep( data , index ); - ecl_sum_tstep_fwrite( tstep , ecl_smspec_get_index_map( data->smspec ) , fortio ); - } - } -} - - - -static void ecl_sum_data_fwrite_multiple_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , int report_step) { - char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_UNIFIED_SUMMARY_FILE , fmt_case , 0 ); - fortio_type * fortio = fortio_open_readwrite( filename , fmt_case , ECL_ENDIAN_FLIP ); - - ecl_sum_data_fwrite_report__( data , report_step , fortio ); - - fortio_fclose( fortio ); - free(filename); +double ecl_sum_data_iget_sim_days( const ecl_sum_data_type * data , int internal_index ) { + const auto index_node = data->index.lookup(internal_index); + const auto data_file = data->data_files[index_node.data_index]; + return data_file->iget_sim_days( internal_index - index_node.offset ); } -static void ecl_sum_data_fwrite_unified_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , int report_step) { - char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_UNIFIED_SUMMARY_FILE , fmt_case , 0 ); - fortio_type * fortio = fortio_open_readwrite( filename , fmt_case , ECL_ENDIAN_FLIP ); - - int current_step = 1; - if (report_step > 1) { - while (true) { - if (ecl_kw_fseek_kw( SEQHDR_KW , false , false , fortio )) { - if (current_step == report_step) - break; - current_step++; - } else { - current_step++; - break; - } - } - } - if (current_step == report_step) { // We found the position: - long size = fortio_ftell( fortio ); - util_ftruncate( fortio_get_FILE( fortio ) , size ); - ecl_sum_data_fwrite_report__( data , report_step , fortio ); - } else - util_abort("%s: hmm could not locate the position for report step:%d in summary file:%s \n",__func__ , report_step , filename); - fortio_fclose( fortio ); - free( filename ); +ecl_sum_data_type * ecl_sum_data_alloc_writer( ecl_smspec_type * smspec ) { + ecl_sum_data_type * data = ecl_sum_data_alloc( smspec ); + ecl::ecl_sum_file_data * file_data = new ecl::ecl_sum_file_data( smspec ); + ecl_sum_data_append_file_data( data, file_data ); + ecl_sum_data_build_index(data); + return data; } - static void ecl_sum_data_fwrite_unified( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case ) { char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_UNIFIED_SUMMARY_FILE , fmt_case , 0 ); fortio_type * fortio = fortio_open_writer( filename , fmt_case , ECL_ENDIAN_FLIP ); - int report_step; - for (report_step = data->first_report_step; report_step <= data->last_report_step; report_step++) { - if (ecl_sum_data_has_report_step( data , report_step )) - ecl_sum_data_fwrite_report__( data , report_step , fortio ); - } + for (size_t index = 0; index < data->data_files.size(); index++) + data->data_files[index]->fwrite_unified( fortio ); fortio_fclose( fortio ); free( filename ); @@ -394,32 +341,13 @@ static void ecl_sum_data_fwrite_unified( const ecl_sum_data_type * data , const static void ecl_sum_data_fwrite_multiple( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case ) { - int report_step; - - for (report_step = data->first_report_step; report_step <= data->last_report_step; report_step++) { - if (ecl_sum_data_has_report_step( data , report_step )) { - char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_SUMMARY_FILE , fmt_case , report_step ); - fortio_type * fortio = fortio_open_writer( filename , fmt_case , ECL_ENDIAN_FLIP ); - - ecl_sum_data_fwrite_report__( data , report_step , fortio ); - fortio_fclose( fortio ); - free( filename ); - } - } + for (size_t index = 0; index < data->data_files.size(); index++) + data->data_files[index]->fwrite_multiple(ecl_case, fmt_case); } - -void ecl_sum_data_fwrite_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , bool unified, int report_step) { - if (unified) - ecl_sum_data_fwrite_unified_step( data , ecl_case , fmt_case , report_step); - else - ecl_sum_data_fwrite_multiple_step( data , ecl_case , fmt_case , report_step); -} - - void ecl_sum_data_fwrite( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , bool unified) { if (unified) ecl_sum_data_fwrite_unified( data , ecl_case , fmt_case ); @@ -428,14 +356,28 @@ void ecl_sum_data_fwrite( const ecl_sum_data_type * data , const char * ecl_case } +bool ecl_sum_data_can_write(const ecl_sum_data_type * data) { + bool can_write = true; + for (const auto& file_ptr : data->data_files) + can_write &= file_ptr->can_write(); + return can_write; +} +time_t ecl_sum_data_get_sim_end(const ecl_sum_data_type * data ) { + const auto& file_data = data->data_files.back(); + return file_data->get_sim_end(); +} -time_t ecl_sum_data_get_sim_end (const ecl_sum_data_type * data ) { return data->end_time; } - -time_t ecl_sum_data_get_data_start ( const ecl_sum_data_type * data ) { return data->start_time; } +time_t ecl_sum_data_get_data_start( const ecl_sum_data_type * data ) { + const auto& file_data = data->data_files[0]; + return file_data->get_data_start(); +} -double ecl_sum_data_get_first_day( const ecl_sum_data_type * data) { return data->days_start; } +double ecl_sum_data_get_first_day( const ecl_sum_data_type * data) { + const auto& file_data = data->data_files[0]; + return file_data->get_days_start(); +} /** Returns the number of simulations days from the start of the @@ -444,7 +386,8 @@ double ecl_sum_data_get_first_day( const ecl_sum_data_type * data) { return data */ double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ) { - return data->sim_length; + const auto& file_data = data->data_files.back(); + return file_data->get_sim_length(); } @@ -462,10 +405,10 @@ double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ) { */ bool ecl_sum_data_check_sim_time( const ecl_sum_data_type * data , time_t sim_time) { - if (sim_time < data->start_time) + if (sim_time < ecl_sum_data_get_data_start(data)) return false; - if (sim_time > data->end_time) + if (sim_time > ecl_sum_data_get_sim_end(data)) return false; return true; @@ -473,7 +416,7 @@ bool ecl_sum_data_check_sim_time( const ecl_sum_data_type * data , time_t sim_ti bool ecl_sum_data_check_sim_days( const ecl_sum_data_type * data , double sim_days) { - return sim_days >= data->days_start && sim_days <= data->sim_length; + return sim_days >= ecl_sum_data_get_first_day(data) && sim_days <= ecl_sum_data_get_sim_length(data); } @@ -518,11 +461,14 @@ bool ecl_sum_data_check_sim_days( const ecl_sum_data_type * data , double sim_da static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data , time_t sim_time) { if (!ecl_sum_data_check_sim_time(data, sim_time)) { + time_t start_time = ecl_sum_data_get_data_start(data); + time_t end_time = ecl_sum_data_get_sim_end(data); + fprintf(stderr , "Simulation start: "); util_fprintf_date_utc( ecl_smspec_get_start_time( data->smspec ) , stderr ); - fprintf(stderr , "Data start......: "); util_fprintf_date_utc( data->start_time , stderr ); - fprintf(stderr , "Simulation end .: "); util_fprintf_date_utc( data->end_time , stderr ); + fprintf(stderr , "Data start......: "); util_fprintf_date_utc( start_time , stderr ); + fprintf(stderr , "Simulation end .: "); util_fprintf_date_utc( end_time , stderr ); fprintf(stderr , "Requested date .: "); util_fprintf_date_utc( sim_time , stderr ); - util_abort("%s: invalid time_t instance:%d interval: [%d,%d]\n",__func__, sim_time , data->start_time , data->end_time); + util_abort("%s: invalid time_t instance:%d interval: [%d,%d]\n",__func__, sim_time , start_time, end_time); } /* @@ -533,13 +479,12 @@ static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data */ int low_index = 0; - int high_index = vector_get_size(data->data) - 1; + int high_index = ecl_sum_data_get_length(data) - 1; // perform binary search while (low_index+1 < high_index) { int center_index = (low_index + high_index) / 2; - const ecl_sum_tstep_type * center_step = ecl_sum_data_iget_ministep(data, center_index); - const time_t center_time = ecl_sum_tstep_get_sim_time(center_step); + const time_t center_time = ecl_sum_data_iget_sim_time(data, center_index); if (sim_time > center_time) low_index = center_index; @@ -547,8 +492,7 @@ static int ecl_sum_data_get_index_from_sim_time( const ecl_sum_data_type * data high_index = center_index; } - const ecl_sum_tstep_type * low_step = ecl_sum_data_iget_ministep(data, low_index); - return sim_time <= ecl_sum_tstep_get_sim_time(low_step) ? low_index : high_index; + return sim_time <= ecl_sum_data_iget_sim_time(data, low_index) ? low_index : high_index; } int ecl_sum_data_get_index_from_sim_days( const ecl_sum_data_type * data , double sim_days) { @@ -582,6 +526,7 @@ int ecl_sum_data_get_index_from_sim_days( const ecl_sum_data_type * data , doubl function should be used), consult documentation at the top of this file. */ + void ecl_sum_data_init_interp_from_sim_time(const ecl_sum_data_type* data, time_t sim_time, int* index1, @@ -600,11 +545,8 @@ void ecl_sum_data_init_interp_from_sim_time(const ecl_sum_data_type* data, return; } - const ecl_sum_tstep_type * ministep1 = ecl_sum_data_iget_ministep(data, idx-1); - const ecl_sum_tstep_type * ministep2 = ecl_sum_data_iget_ministep(data, idx); - - time_t sim_time1 = ecl_sum_tstep_get_sim_time(ministep1); - time_t sim_time2 = ecl_sum_tstep_get_sim_time(ministep2); + time_t sim_time1 = ecl_sum_data_iget_sim_time(data, idx-1); + time_t sim_time2 = ecl_sum_data_iget_sim_time(data, idx); *index1 = idx-1; *index2 = idx; @@ -630,36 +572,32 @@ void ecl_sum_data_init_interp_from_sim_days( const ecl_sum_data_type * data , do double_vector_type * ecl_sum_data_alloc_seconds_solution(const ecl_sum_data_type * data, const smspec_node_type * node, double cmp_value, bool rates_clamp_lower) { double_vector_type * solution = double_vector_alloc(0, 0); const int param_index = smspec_node_get_params_index(node); - const int size = vector_get_size(data->data); + const int size = ecl_sum_data_get_length(data); if (size <= 1) return solution; for (int index = 0; index < size; ++index) { - int prev_index = util_int_max(0, index-1); - - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep(data, index); - const ecl_sum_tstep_type * prev_ministep = ecl_sum_data_iget_ministep(data, prev_index); - double value = ecl_sum_tstep_iget(ministep, param_index); - double prev_value = ecl_sum_tstep_iget(prev_ministep, param_index); + int prev_index = util_int_max(0, index-1); + double value = ecl_sum_data_iget(data, index, param_index); + double prev_value = ecl_sum_data_iget(data, prev_index, param_index); // cmp_value in interval value (closed) and prev_value (open) - bool contained = value == cmp_value; + bool contained = (value == cmp_value); contained |= (util_double_min(prev_value, value) < cmp_value) && (cmp_value < util_double_max(prev_value, value)); if (!contained) continue; - double prev_time = ecl_sum_tstep_get_sim_seconds(prev_ministep); - double time = ecl_sum_tstep_get_sim_seconds(ministep); + double prev_time = ecl_sum_data_iget_sim_seconds(data, prev_index); + double time = ecl_sum_data_iget_sim_seconds(data, index); if (smspec_node_is_rate(node)) { double_vector_append(solution, rates_clamp_lower ? prev_time + 1 : time); } else { double slope = (value - prev_value) / (time - prev_time); double seconds = (cmp_value - prev_value)/slope + prev_time; - double_vector_append(solution, seconds); } } @@ -667,94 +605,49 @@ double_vector_type * ecl_sum_data_alloc_seconds_solution(const ecl_sum_data_type } +static void ecl_sum_data_build_index( ecl_sum_data_type * self ) { + std::sort(self->data_files.begin(), self->data_files.end(), + [](const ecl::ecl_sum_file_data* case1, + const ecl::ecl_sum_file_data* case2) + { + return case1->get_data_start() < case2->get_data_start(); + }); + self->index.clear(); + for (size_t i=0; i < self->data_files.size(); i++) { + const auto& data = self->data_files[i]; + bool main_case = (i == (self->data_files.size() - 1)); + time_t next_start; -static void ecl_sum_data_append_tstep__( ecl_sum_data_type * data , ecl_sum_tstep_type * tstep) { - /* - Here the tstep is just appended naively, the vector will be - sorted by ministep_nr before the data instance is returned. - */ - - vector_append_owned_ref( data->data , tstep , ecl_sum_tstep_free__); - data->index_valid = false; -} - - - -static int cmp_ministep( const void * arg1 , const void * arg2) { - const ecl_sum_tstep_type * ministep1 = ecl_sum_tstep_safe_cast_const( arg1 ); - const ecl_sum_tstep_type * ministep2 = ecl_sum_tstep_safe_cast_const( arg2 ); - - time_t time1 = ecl_sum_tstep_get_sim_time( ministep1 ); - time_t time2 = ecl_sum_tstep_get_sim_time( ministep2 ); - - if (time1 < time2) - return -1; - else if (time1 == time2) - return 0; - else - return 1; -} - - -static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) { - /* Clear the existing index (if any): */ - ecl_sum_data_clear_index( sum_data ); - - /* - Sort the internal storage vector after sim_time. - */ - vector_sort( sum_data->data , cmp_ministep ); - - - /* Identify various global first and last values. */ - { - const ecl_sum_tstep_type * first_ministep = (const ecl_sum_tstep_type*)vector_iget_const( sum_data->data, 0 ); - const ecl_sum_tstep_type * last_ministep = (const ecl_sum_tstep_type*)vector_get_last_const( sum_data->data ); - /* - In most cases the days_start and data_start_time will agree - with the global simulation start; however in the case where we - have loaded a summary case from a restarted simulation where - the case we have restarted from is not available - then there - will be a difference. - */ - sum_data->days_start = ecl_sum_tstep_get_sim_days( first_ministep ); - sum_data->sim_length = ecl_sum_tstep_get_sim_days( last_ministep ); - sum_data->start_time = ecl_sum_tstep_get_sim_time( first_ministep); - sum_data->end_time = ecl_sum_tstep_get_sim_time( last_ministep ); - } + if (main_case) + self->index.add(data->length()); + else { + const auto& next = self->data_files[i+1]; + next_start = next->get_data_start(); + self->index.add( data->length_before(next_start)); + } - /* Build up the report -> ministep mapping. */ - { - int internal_index; - for (internal_index = 0; internal_index < vector_get_size( sum_data->data ); internal_index++) { - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( sum_data , internal_index ); - int report_step = ecl_sum_tstep_get_report(ministep); + auto & node = self->index.back(); + if (node.length > 0) { + node.report1 = data->first_report(); - /* Indexing internal_index - report_step */ - { - int current_first_index = int_vector_safe_iget( sum_data->report_first_index , report_step ); - if (current_first_index < 0) /* i.e. currently not set. */ - int_vector_iset( sum_data->report_first_index , report_step , internal_index); - else - if (internal_index < current_first_index) - int_vector_iset( sum_data->report_first_index , report_step , internal_index); - } + if (main_case) + node.report2 = data->last_report(); + else + node.report2 = data->report_before( next_start ); + node.time1 = data->get_data_start(); + node.time2 = data->get_sim_end(); + node.days1 = data->get_days_start(); + node.days2 = data->get_sim_length(); { - int current_last_index = int_vector_safe_iget( sum_data->report_last_index , report_step ); - if (current_last_index < 0) - int_vector_iset( sum_data->report_last_index , report_step , internal_index); - else - if (internal_index > current_last_index) - int_vector_iset( sum_data->report_last_index , report_step , internal_index); + int * tmp_map = ecl_smspec_alloc_mapping( self->smspec , data->smspec() ); + node.params_map.assign(tmp_map, tmp_map + ecl_smspec_get_params_size(self->smspec)); + free( tmp_map ); } - - sum_data->first_report_step = util_int_min( sum_data->first_report_step , report_step ); - sum_data->last_report_step = util_int_max( sum_data->last_report_step , report_step ); } } - sum_data->index_valid = true; + } @@ -767,151 +660,30 @@ static void ecl_sum_data_build_index( ecl_sum_data_type * sum_data ) { */ ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int report_step , double sim_seconds) { - int ministep_nr = vector_get_size( data->data ); - ecl_sum_tstep_type * tstep = ecl_sum_tstep_alloc_new( report_step , ministep_nr , sim_seconds , data->smspec ); - ecl_sum_tstep_type * prev_tstep = NULL; - - if (vector_get_size( data->data ) > 0) - prev_tstep = (ecl_sum_tstep_type*)vector_get_last( data->data ); - - ecl_sum_data_append_tstep__( data , tstep ); - { - bool rebuild_index = true; - - /* - In the simple case that we just add another timestep to the - currently active report_step, we do a limited update of the - index, otherwise we call ecl_sum_data_build_index() to get a - full recalculation of the index. - */ - - if (prev_tstep != NULL) { - if (ecl_sum_tstep_get_report( prev_tstep ) == ecl_sum_tstep_get_report( tstep )) { // Same report step - if (ecl_sum_tstep_get_sim_days( prev_tstep ) < ecl_sum_tstep_get_sim_days( tstep )) { // This tstep will become the new latest tstep - int internal_index = vector_get_size( data->data ) - 1; - int_vector_iset( data->report_last_index , report_step , internal_index ); - - data->sim_length = ecl_sum_tstep_get_sim_days( tstep ); - data->end_time = ecl_sum_tstep_get_sim_time(tstep); - - rebuild_index = false; - } - } - } - if (rebuild_index) - ecl_sum_data_build_index( data ); - } - ecl_smspec_lock( data->smspec ); - + ecl::ecl_sum_file_data * file_data = data->data_files.back(); + ecl_sum_tstep_type * tstep = file_data->add_new_tstep( report_step, sim_seconds ); + ecl_sum_data_build_index( data ); return tstep; } - - -/** - Malformed/incomplete files: - ---------------------------- - Observe that ECLIPSE works in the following way: - - 1. At the start of a report step a summary data section - containing only the 'SEQHDR' keyword is written - this is - currently an 'invalid' summary section. - - 2. ECLIPSE simulates as best it can. - - 3. When the time step is complete data is written to the summary - file. - - Now - if ECLIPSE goes down in flames during step 2 a malformed - summary file will be left around, to handle this situation - reasonably gracefully we check that the ecl_file instance has at - least one "PARAMS" keyword. - - One ecl_file corresponds to one report_step (limited by SEQHDR); in - the case of non unfied summary files these objects correspond to - one BASE.Annnn or BASE.Snnnn file, in the case of unified files the - calling routine will read the unified summary file partly. -*/ - -static void ecl_sum_data_add_ecl_file(ecl_sum_data_type * data , - int report_step , - const ecl_file_view_type * summary_view, - const ecl_smspec_type * smspec) { - - - int num_ministep = ecl_file_view_get_num_named_kw( summary_view , PARAMS_KW); - if (num_ministep > 0) { - int ikw; - - for (ikw = 0; ikw < num_ministep; ikw++) { - ecl_kw_type * ministep_kw = ecl_file_view_iget_named_kw( summary_view , MINISTEP_KW , ikw); - ecl_kw_type * params_kw = ecl_file_view_iget_named_kw( summary_view , PARAMS_KW , ikw); - - { - int ministep_nr = ecl_kw_iget_int( ministep_kw , 0 ); - ecl_sum_tstep_type * tstep = ecl_sum_tstep_alloc_from_file( report_step , - ministep_nr , - params_kw , - ecl_file_view_get_src_file( summary_view ), - smspec ); - - if (tstep) - ecl_sum_data_append_tstep__( data , tstep ); - } - } +int * ecl_sum_data_alloc_param_mapping( int * current_param_mapping, int * old_param_mapping, size_t size) { + int * new_param_mapping = (int*)util_malloc( size * sizeof * new_param_mapping ); + for (size_t i = 0; i < size; i++) { + if (current_param_mapping[i] >= 0) + new_param_mapping[i] = old_param_mapping[ current_param_mapping[i] ]; + else + new_param_mapping[i] = -1; } + return new_param_mapping; } void ecl_sum_data_add_case(ecl_sum_data_type * self, const ecl_sum_data_type * other) { - int * param_mapping = NULL; - bool header_equal = ecl_smspec_equal( self->smspec , other->smspec); - float default_value = 0; - - if (!header_equal) - param_mapping = ecl_smspec_alloc_mapping( self->smspec , other->smspec ); - + for (auto other_file : other->data_files) + self->data_files.push_back( other_file ); - for (int tstep_nr = 0; tstep_nr < ecl_sum_data_get_length( other ); tstep_nr++) { - ecl_sum_tstep_type * other_tstep = ecl_sum_data_iget_ministep( other , tstep_nr ); - - /* - The dataset 'self' is the authorative in the timeinterval where it has - data, so if 'other' also has data in the same time interval that is - discarded. In most cases 'other' will represent a history case, and 'self' - is a prediction which has been restarted. - - After implementing the time_interval_contains() based check it turned out - that the smspec structure also contains a restart_step integer value in - the DIMENS vector which could probably be used to achieve the same thing. - That field is currently not used. - */ - - if (!ecl_sum_data_check_sim_time(self, ecl_sum_tstep_get_sim_time(other_tstep))) { - ecl_sum_tstep_type * new_tstep; - - if (header_equal) - new_tstep = ecl_sum_tstep_alloc_copy( other_tstep ); - else - new_tstep = ecl_sum_tstep_alloc_remap_copy( other_tstep , self->smspec , default_value , param_mapping ); - - ecl_sum_data_append_tstep__( self , new_tstep ); - - } - } - - ecl_sum_data_build_index( self ); - free( param_mapping ); -} - - -static bool ecl_sum_data_check_file( ecl_file_type * ecl_file ) { - if (ecl_file_has_kw( ecl_file , PARAMS_KW ) && - (ecl_file_get_num_named_kw( ecl_file , PARAMS_KW ) == ecl_file_get_num_named_kw( ecl_file , MINISTEP_KW))) - return true; - else - return false; + ecl_sum_data_build_index(self); } @@ -924,66 +696,14 @@ static bool ecl_sum_data_check_file( ecl_file_type * ecl_file ) { call to ecl_sum_data_build_index(). */ -bool ecl_sum_data_fread(ecl_sum_data_type * data , const stringlist_type * filelist) { - if (stringlist_get_size( filelist ) == 0) - return false; - - { - ecl_file_enum file_type = ecl_util_get_file_type( stringlist_iget( filelist , 0 ) , NULL , NULL); - if ((stringlist_get_size( filelist ) > 1) && (file_type != ECL_SUMMARY_FILE)) - util_abort("%s: internal error - when calling with more than one file - you can not supply a unified file - come on?! \n",__func__); - - { - int filenr; - if (file_type == ECL_SUMMARY_FILE) { - - /* Not unified. */ - for (filenr = 0; filenr < stringlist_get_size( filelist ); filenr++) { - const char * data_file = stringlist_iget( filelist , filenr); - ecl_file_enum file_type; - int report_step; - file_type = ecl_util_get_file_type( data_file , NULL , &report_step); - if (file_type != ECL_SUMMARY_FILE) - util_abort("%s: file:%s has wrong type \n",__func__ , data_file); - { - ecl_file_type * ecl_file = ecl_file_open( data_file , 0); - if (ecl_file && ecl_sum_data_check_file( ecl_file )) { - ecl_sum_data_add_ecl_file( data , report_step , ecl_file_get_global_view( ecl_file ) , data->smspec); - ecl_file_close( ecl_file ); - } - } - } - } else if (file_type == ECL_UNIFIED_SUMMARY_FILE) { - ecl_file_type * ecl_file = ecl_file_open( stringlist_iget(filelist ,0 ) , 0); - if (ecl_file && ecl_sum_data_check_file( ecl_file )) { - int report_step = 1; /* <- ECLIPSE numbering - starting at 1. */ - while (true) { - /* - Observe that there is a number discrepancy between ECLIPSE - and the ecl_file_select_smryblock() function. ECLIPSE - starts counting report steps at 1; whereas the first - SEQHDR block in the unified summary file is block zero (in - ert counting). - */ - ecl_file_view_type * summary_view = ecl_file_get_summary_view(ecl_file , report_step - 1 ); - if (summary_view) { - ecl_sum_data_add_ecl_file( data , report_step , summary_view , data->smspec); - report_step++; - } else break; - } - ecl_file_close( ecl_file ); - } - } - } - - - if (ecl_sum_data_get_length( data ) > 0) { - ecl_sum_data_build_index( data ); - return true; - } else - return false; - +bool ecl_sum_data_fread(ecl_sum_data_type * data , const stringlist_type * filelist, bool lazy_load, int file_options) { + ecl::ecl_sum_file_data * file_data = new ecl::ecl_sum_file_data( data->smspec ); + if (file_data->fread( filelist, lazy_load, file_options)) { + ecl_sum_data_append_file_data( data, file_data ); + ecl_sum_data_build_index(data); + return true; } + return false; } @@ -1002,9 +722,9 @@ bool ecl_sum_data_fread(ecl_sum_data_type * data , const stringlist_type * filel (manually) changed from the historical part. */ -ecl_sum_data_type * ecl_sum_data_fread_alloc( ecl_smspec_type * smspec , const stringlist_type * filelist , bool include_restart) { +ecl_sum_data_type * ecl_sum_data_fread_alloc( ecl_smspec_type * smspec , const stringlist_type * filelist , bool include_restart, bool lazy_load, int file_options) { ecl_sum_data_type * data = ecl_sum_data_alloc( smspec ); - ecl_sum_data_fread( data , filelist ); + ecl_sum_data_fread( data , filelist, lazy_load, file_options ); /*****************************************************************/ /* OK - now we have loaded all the data. Must sort the internal @@ -1021,11 +741,14 @@ void ecl_sum_data_summarize(const ecl_sum_data_type * data , FILE * stream) { fprintf(stream , "---------------------------------------------------------------\n"); { int index; - for (index = 0; index < vector_get_size( data->data ); index++) { - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , index ); + for (index = 0; index < ecl_sum_data_get_length(data); index++) { + time_t sim_time = ecl_sum_data_iget_sim_time(data, index); + int report_step = ecl_sum_data_iget_report_step(data, index); + double days = ecl_sum_data_iget_sim_days(data, index); + int day,month,year; - ecl_util_set_date_values( ecl_sum_tstep_get_sim_time( ministep ) , &day, &month , &year); - fprintf(stream , "%04d %6d %02d/%02d/%4d %7.2f \n", ecl_sum_tstep_get_report( ministep ) , index , day,month,year, ecl_sum_tstep_get_sim_days( ministep )); + ecl_util_set_date_values( sim_time, &day, &month , &year); + fprintf(stream , "%04d %6d %02d/%02d/%4d %7.2f \n", report_step , index , day,month,year, days); } } fprintf(stream , "---------------------------------------------------------------\n"); @@ -1035,11 +758,14 @@ void ecl_sum_data_summarize(const ecl_sum_data_type * data , FILE * stream) { /*****************************************************************/ + bool ecl_sum_data_has_report_step(const ecl_sum_data_type * data , int report_step ) { - if (int_vector_safe_iget( data->report_first_index , report_step) >= 0) - return true; - else + if (!data->index.has_report(report_step)) return false; + + const auto& index_node = data->index.lookup_report(report_step); + const auto& file_data = data->data_files[index_node.data_index]; + return file_data->has_report(report_step); } @@ -1052,44 +778,25 @@ bool ecl_sum_data_has_report_step(const ecl_sum_data_type * data , int report_st */ int ecl_sum_data_iget_report_end( const ecl_sum_data_type * data , int report_step ) { - return int_vector_safe_iget( data->report_last_index , report_step ); + const auto& index_node = data->index.lookup_report(report_step); + const auto& file_data = data->data_files[index_node.data_index]; + auto range = file_data->report_range(report_step); + return range.second; } -/** - Returns the first index included in report step @report_step. - Observe that if the dataset does not include @report_step at all, - the function will return INVALID_MINISTEP_NR; this must be checked for in the - calling scope. -*/ - - -int ecl_sum_data_iget_report_start( const ecl_sum_data_type * data , int report_step ) { - return int_vector_safe_iget( data->report_first_index , report_step ); -} - - int ecl_sum_data_iget_report_step(const ecl_sum_data_type * data , int internal_index) { - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , internal_index ); - return ecl_sum_tstep_get_report( ministep ); -} - - -int ecl_sum_data_iget_mini_step(const ecl_sum_data_type * data , int internal_index) { - { - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , internal_index ); - return ecl_sum_tstep_get_ministep( ministep ); - } + const auto& index_node = data->index.lookup(internal_index); + const auto& file_data = data->data_files[index_node.data_index]; + return file_data->iget_report(internal_index - index_node.offset); } - - /** This will look up a value based on an internal index. The internal index will ALWAYS run in the interval [0,num_ministep), without @@ -1098,11 +805,20 @@ int ecl_sum_data_iget_mini_step(const ecl_sum_data_type * data , int internal_in double ecl_sum_data_iget( const ecl_sum_data_type * data , int time_index , int params_index ) { - const ecl_sum_tstep_type * ministep_data = ecl_sum_data_iget_ministep( data , time_index ); - return ecl_sum_tstep_iget( ministep_data , params_index); + const auto& index_node = data->index.lookup( time_index ); + ecl::ecl_sum_file_data * file_data = data->data_files[index_node.data_index]; + const auto& params_map = index_node.params_map; + if (params_map[params_index] >= 0) + return file_data->iget( time_index - index_node.offset, params_map[params_index] ); + else { + const smspec_node_type * smspec_node = ecl_smspec_iget_node(data->smspec, params_index); + return smspec_node_get_default(smspec_node); + } } + + /** This function will form a weight average of the two ministeps @ministep1 and @ministep2. The weights and the ministep indices @@ -1115,11 +831,8 @@ double ecl_sum_data_iget( const ecl_sum_data_type * data , int time_index , int between two ministeps. */ -double ecl_sum_data_interp_get(const ecl_sum_data_type * data , int time_index1 , int time_index2 , double weight1 , double weight2 , int params_index) { - const ecl_sum_tstep_type * ministep_data1 = ecl_sum_data_iget_ministep( data , time_index1 ); - const ecl_sum_tstep_type * ministep_data2 = ecl_sum_data_iget_ministep( data , time_index2 ); - - return ecl_sum_tstep_iget( ministep_data1 , params_index ) * weight1 + ecl_sum_tstep_iget( ministep_data2 , params_index ) * weight2; +static double ecl_sum_data_interp_get(const ecl_sum_data_type * data , int time_index1 , int time_index2 , double weight1 , double weight2 , int params_index) { + return ecl_sum_data_iget(data, time_index1, params_index) * weight1 + ecl_sum_data_iget(data, time_index2, params_index) * weight2; } @@ -1223,34 +936,15 @@ double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t s int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , double sim_days) { - if ((sim_days < data->days_start) || (sim_days > data->sim_length)) + if ((sim_days < ecl_sum_data_get_first_day(data)) || (sim_days > ecl_sum_data_get_sim_length(data))) return -1; else { - int report_step = -1; + auto files = data->index.lookup_days(sim_days); + if (files.first != files.second) + return -1; - double_vector_type * days_map = double_vector_alloc( 0 , 0 ); - int_vector_type * report_map = int_vector_alloc( 0 , 0 ); - int i; - - for (i=1; i < int_vector_size( data->report_last_index ); i++) { - int ministep_index = int_vector_iget( data->report_last_index , i ); - const ecl_sum_tstep_type * ministep = (const ecl_sum_tstep_type*)vector_iget_const( data->data , ministep_index ); - - double_vector_iset( days_map , i , ecl_sum_tstep_get_sim_days( ministep )); - int_vector_iset( report_map , i , ecl_sum_tstep_get_report( ministep )); - } - - { - /** Hmmmm - double == comparison ... */ - int index = double_vector_index_sorted( days_map , sim_days ); - - if (index >= 0) - report_step = int_vector_iget( report_map , index ); - } - - int_vector_free( report_map ); - double_vector_free( days_map ); - return report_step; + const auto& data_file = data->data_files[files.first->data_index]; + return data_file->report_step_from_days(sim_days); } } @@ -1275,40 +969,18 @@ int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , doub int ecl_sum_data_get_report_step_from_time(const ecl_sum_data_type * data , time_t sim_time) { - if (!ecl_sum_data_check_sim_time(data , sim_time)) return -1; + else { + auto files = data->index.lookup_time(sim_time); + if (files.first != files.second) + return -1; - { - int report_step = -1; - - time_t_vector_type * time_map = time_t_vector_alloc( 0 , 0 ); - int_vector_type * report_map = int_vector_alloc( 0 , 0 ); - int i; - - for (i=1; i < int_vector_size( data->report_last_index ); i++) { - int ministep_index = int_vector_iget( data->report_last_index , i ); - const ecl_sum_tstep_type * ministep = (const ecl_sum_tstep_type*)vector_iget_const( data->data , ministep_index ); - - time_t_vector_iset( time_map , i , ecl_sum_tstep_get_sim_time( ministep )); - int_vector_iset( report_map , i , ecl_sum_tstep_get_report( ministep )); - - } - - { - int index = time_t_vector_index_sorted( time_map , sim_time ); - - if (index >= 0) - report_step = int_vector_iget( report_map , index ); - } - - int_vector_free( report_map ); - time_t_vector_free( time_map ); - return report_step; + const auto& data_file = data->data_files[files.first->data_index]; + return data_file->report_step_from_time(sim_time); } } - double ecl_sum_data_time2days( const ecl_sum_data_type * data , time_t sim_time) { time_t start_time = ecl_smspec_get_start_time( data->smspec ); return util_difftime_days( start_time , sim_time ); @@ -1321,9 +993,10 @@ double ecl_sum_data_get_from_sim_days( const ecl_sum_data_type * data , double s } -time_t ecl_sum_data_iget_sim_time( const ecl_sum_data_type * data , int internal_index ) { - const ecl_sum_tstep_type * ministep_data = ecl_sum_data_iget_ministep( data , internal_index ); - return ecl_sum_tstep_get_sim_time( ministep_data ); +time_t ecl_sum_data_iget_sim_time(const ecl_sum_data_type * data, int ministep_index) { + const auto& index_node = data->index.lookup( ministep_index ); + const auto data_file = data->data_files[index_node.data_index]; + return data_file->iget_sim_time(ministep_index - index_node.offset); } @@ -1332,25 +1005,21 @@ time_t ecl_sum_data_get_report_time( const ecl_sum_data_type * data , int report return ecl_smspec_get_start_time( data->smspec ); else { int internal_index = ecl_sum_data_iget_report_end( data , report_step ); - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , internal_index ); - return ecl_sum_tstep_get_sim_time( ministep ); + return ecl_sum_data_iget_sim_time(data, internal_index); } } -double ecl_sum_data_iget_sim_days( const ecl_sum_data_type * data , int internal_index ) { - const ecl_sum_tstep_type * ministep_data = ecl_sum_data_iget_ministep( data , internal_index ); - return ecl_sum_tstep_get_sim_days( ministep_data ); -} - int ecl_sum_data_get_first_report_step( const ecl_sum_data_type * data ) { - return data->first_report_step; + const auto& data_file = data->data_files[0]; + return data_file->first_report(); } int ecl_sum_data_get_last_report_step( const ecl_sum_data_type * data ) { - return data->last_report_step; + const auto& data_file = data->data_files.back(); + return data_file->last_report(); } @@ -1359,75 +1028,103 @@ int ecl_sum_data_get_last_report_step( const ecl_sum_data_type * data ) { -void ecl_sum_data_init_time_vector( const ecl_sum_data_type * data , time_t_vector_type * time_vector , bool report_only) { - time_t_vector_reset( time_vector ); - time_t_vector_append( time_vector , ecl_smspec_get_start_time( data->smspec )); - if (report_only) { - int report_step; - for (report_step = data->first_report_step; report_step <= data->last_report_step; report_step++) { - int last_index = int_vector_iget(data->report_last_index , report_step); - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , last_index ); - time_t_vector_append( time_vector , ecl_sum_tstep_get_sim_time( ministep ) ); - } - } else { - int i; - for (i = 1; i < vector_get_size(data->data); i++) { - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , i ); - time_t_vector_append( time_vector , ecl_sum_tstep_get_sim_time( ministep )); + +static void ecl_sum_data_init_time_vector__(const ecl_sum_data_type * data, time_t * output_data, bool report_only) { + int offset = 0; + for (const auto& index_node : data->index) { + const auto& data_file = data->data_files[index_node.data_index]; + + if (report_only) + offset += data_file->get_time_report(index_node.length, &output_data[offset]); + else { + data_file->get_time(index_node.length, &output_data[offset]); + offset += index_node.length; } } } + +void ecl_sum_data_init_time_vector(const ecl_sum_data_type * data, time_t * output_data) { + ecl_sum_data_init_time_vector__(data, output_data, false); +} + + + time_t_vector_type * ecl_sum_data_alloc_time_vector( const ecl_sum_data_type * data , bool report_only) { - time_t_vector_type * time_vector = time_t_vector_alloc(0,0); - ecl_sum_data_init_time_vector( data , time_vector , report_only); + std::vector output_data; + if (report_only) + output_data.resize( 1 + ecl_sum_data_get_last_report_step(data) - ecl_sum_data_get_first_report_step(data)); + else + output_data.resize( ecl_sum_data_get_length(data) ); + + ecl_sum_data_init_time_vector__(data, output_data.data(), report_only); + time_t_vector_type * time_vector = time_t_vector_alloc(output_data.size(),0); + { + time_t * tmp_data = time_t_vector_get_ptr( time_vector ); + memcpy(tmp_data, output_data.data(), output_data.size() * sizeof(time_t)); + } return time_vector; } -void ecl_sum_data_init_data_vector( const ecl_sum_data_type * data , double_vector_type * data_vector , int data_index , bool report_only) { - double_vector_reset( data_vector ); - double_vector_append( data_vector , ecl_smspec_get_start_time( data->smspec )); - if (report_only) { - int report_step; - for (report_step = data->first_report_step; report_step <= data->last_report_step; report_step++) { - int last_index = int_vector_iget(data->report_last_index , report_step); - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , last_index ); - double_vector_append( data_vector , ecl_sum_tstep_iget( ministep , data_index )); - } - } else { - int i; - for (i = 0; i < vector_get_size(data->data); i++) { - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , i ); - double_vector_append( data_vector , ecl_sum_tstep_iget( ministep , data_index )); + + +static void ecl_sum_data_init_double_vector__(const ecl_sum_data_type * data, int main_params_index, double * output_data, bool report_only) { + int offset = 0; + for (const auto& index_node : data->index) { + const auto& data_file = data->data_files[index_node.data_index]; + const auto& params_map = index_node.params_map; + int params_index = params_map[main_params_index]; + + + if (report_only) { + const smspec_node_type * smspec_node = ecl_smspec_iget_node(data->smspec, main_params_index); + double default_value = smspec_node_get_default(smspec_node); + offset += data_file->get_data_report(params_index, index_node.length, &output_data[offset], default_value); + } else { + + if (params_index >= 0) + data_file->get_data(params_index, index_node.length, &output_data[offset]); + else { + const smspec_node_type * smspec_node = ecl_smspec_iget_node(data->smspec, main_params_index); + for (int i=0; i < index_node.length; i++) + output_data[offset + i] = smspec_node_get_default(smspec_node); + } + offset += index_node.length; } } } -double_vector_type * ecl_sum_data_alloc_data_vector( const ecl_sum_data_type * data , int data_index , bool report_only) { - double_vector_type * data_vector = double_vector_alloc(0,0); - ecl_sum_data_init_data_vector( data , data_vector , data_index , report_only); - return data_vector; +void ecl_sum_data_init_datetime64_vector(const ecl_sum_data_type * data, int64_t * output_data, int multiplier) { + for (int i = 0; i < ecl_sum_data_get_length(data); i++) + output_data[i] = ecl_sum_data_iget_sim_time(data, i) * multiplier; } + void ecl_sum_data_init_double_vector(const ecl_sum_data_type * data, int params_index, double * output_data) { - int i; - for (i = 0; i < vector_get_size(data->data); i++) { - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , i ); - output_data[i] = ecl_sum_tstep_iget(ministep, params_index); - } + ecl_sum_data_init_double_vector__(data, params_index, output_data, false); } -void ecl_sum_data_init_datetime64_vector(const ecl_sum_data_type * data, int64_t * output_data, int multiplier) { - int i; - for (i = 0; i < vector_get_size(data->data); i++) { - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep( data , i ); - output_data[i] = ecl_sum_tstep_get_sim_time(ministep) * multiplier; + +double_vector_type * ecl_sum_data_alloc_data_vector( const ecl_sum_data_type * data , int params_index , bool report_only) { + std::vector output_data; + if (report_only) + output_data.resize( 1 + ecl_sum_data_get_last_report_step(data) - ecl_sum_data_get_first_report_step(data)); + else + output_data.resize( ecl_sum_data_get_length(data) ); + + ecl_sum_data_init_double_vector__(data, params_index, output_data.data(), report_only); + double_vector_type * data_vector = double_vector_alloc(output_data.size(), 0); + { + double * tmp_data = double_vector_get_ptr( data_vector ); + memcpy(tmp_data, output_data.data(), output_data.size() * sizeof(double)); } + return data_vector; } + void ecl_sum_data_init_double_vector_interp(const ecl_sum_data_type * data, const smspec_node_type * smspec_node, const time_t_vector_type * time_points, @@ -1477,13 +1174,12 @@ void ecl_sum_data_init_double_vector_interp(const ecl_sum_data_type * data, void ecl_sum_data_init_double_frame(const ecl_sum_data_type * data, const ecl_sum_vector_type * keywords, double *output_data) { int time_stride = ecl_sum_vector_get_size(keywords); int key_stride = 1; - for (int time_index=0; time_index < vector_get_size(data->data); time_index++) { - const ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep(data , time_index); + for (int time_index=0; time_index < ecl_sum_data_get_length(data); time_index++) { for (int key_index = 0; key_index < ecl_sum_vector_get_size(keywords); key_index++) { int param_index = ecl_sum_vector_iget_param_index(keywords, key_index); int data_index = key_index*key_stride + time_index * time_stride; - output_data[data_index] = ecl_sum_tstep_iget(ministep, param_index); + output_data[data_index] = ecl_sum_data_iget(data, time_index, param_index); } } } @@ -1546,78 +1242,36 @@ void ecl_sum_data_init_double_frame_interp(const ecl_sum_data_type * data, */ int ecl_sum_data_get_length( const ecl_sum_data_type * data ) { - return vector_get_size( data->data ); + return data->index.length(); } -void ecl_sum_data_scale_vector(ecl_sum_data_type * data, int index, double scalar) { - int len = vector_get_size(data->data); - for (int i = 0; i < len; i++) { - ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep(data,i); - ecl_sum_tstep_iscale(ministep, index, scalar); - } -} +static bool ecl_sum_data_report_step_equal__( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2, bool strict) { + if (data1->data_files.size() != data2->data_files.size()) + return false; -void ecl_sum_data_shift_vector(ecl_sum_data_type * data, int index, double addend) { - int len = vector_get_size(data->data); - for (int i = 0; i < len; i++) { - ecl_sum_tstep_type * ministep = ecl_sum_data_iget_ministep(data,i); - ecl_sum_tstep_ishift(ministep, index, addend); - } -} + for (size_t i=0; i < data1->data_files.size(); i++) { + const auto& data_file1 = data1->data_files[i]; + const auto& data_file2 = data2->data_files[i]; -bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2) { - bool equal = true; - if (int_vector_size( data1->report_last_index ) == int_vector_size(data2->report_last_index)) { - int i; - for (i = 0; i < int_vector_size( data1->report_last_index ); i++) { - int time_index1 = int_vector_iget( data1->report_last_index , i ); - int time_index2 = int_vector_iget( data2->report_last_index , i ); - - if ((time_index1 != INVALID_MINISTEP_NR) && (time_index2 != INVALID_MINISTEP_NR)) { - const ecl_sum_tstep_type * ministep1 = ecl_sum_data_iget_ministep( data1 , time_index1 ); - const ecl_sum_tstep_type * ministep2 = ecl_sum_data_iget_ministep( data2 , time_index2 ); - - if (!ecl_sum_tstep_sim_time_equal( ministep1 , ministep2)) { - equal = false; - break; - } - } else if (time_index1 != time_index2) { - equal = false; - break; - } - } - } else - equal = false; + if (!data_file1->report_step_equal(*data_file2, strict)) + return false; + } - return equal; + return true; } bool ecl_sum_data_report_step_compatible( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2) { - bool compatible = true; - int min_size = util_int_min( int_vector_size( data1->report_last_index ) , int_vector_size( data2->report_last_index)); - int i; - for (i = 0; i < min_size; i++) { - int time_index1 = int_vector_iget( data1->report_last_index , i ); - int time_index2 = int_vector_iget( data2->report_last_index , i ); - - if ((time_index1 != INVALID_MINISTEP_NR) && (time_index2 != INVALID_MINISTEP_NR)) { - const ecl_sum_tstep_type * ministep1 = ecl_sum_data_iget_ministep( data1 , time_index1 ); - const ecl_sum_tstep_type * ministep2 = ecl_sum_data_iget_ministep( data2 , time_index2 ); - - if (!ecl_sum_tstep_sim_time_equal( ministep1 , ministep2)) { - compatible = false; - break; - } - } - } - return compatible; + return ecl_sum_data_report_step_equal__(data1, data2, false); +} + +bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2) { + return ecl_sum_data_report_step_equal__(data1, data2, true); } double ecl_sum_data_iget_last_value(const ecl_sum_data_type * data, int param_index) { - const ecl_sum_tstep_type * tstep = (const ecl_sum_tstep_type*)vector_get_last_const(data->data); - return ecl_sum_tstep_iget( tstep, param_index); + return ecl_sum_data_iget(data, ecl_sum_data_get_length(data)-1, param_index); } double ecl_sum_data_get_last_value(const ecl_sum_data_type * data, int param_index) { @@ -1625,6 +1279,5 @@ double ecl_sum_data_get_last_value(const ecl_sum_data_type * data, int param_ind } double ecl_sum_data_iget_first_value(const ecl_sum_data_type * data, int param_index) { - const ecl_sum_tstep_type * tstep = (const ecl_sum_tstep_type*) vector_iget_const(data->data, 0); - return ecl_sum_tstep_iget(tstep, param_index); + return ecl_sum_data_iget(data, 0, param_index); } diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum_file_data.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum_file_data.cpp new file mode 100644 index 0000000000..b0367e2ec5 --- /dev/null +++ b/ThirdParty/Ert/lib/ecl/ecl_sum_file_data.cpp @@ -0,0 +1,731 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "detail/ecl/ecl_sum_file_data.hpp" +#include "detail/ecl/ecl_unsmry_loader.hpp" + +/* + This file implements the type ecl_sum_data_type. The data structure + is involved with holding all the actual summary data (i.e. the + PARAMS vectors in ECLIPSE speak), in addition the time-information + with MINISTEPS / REPORT_STEPS and so on is implemented here. + + This file has no information about how to index into the PARAMS + vector, i.e. at which location can the WWCT for well P6 be found, + that is responsability of the ecl_smspec_type. + + The time direction in this system is implemented in terms of + ministeps. There are some query / convert functons based on report + steps. +*/ + + +/*****************************************************************/ +/* + About ministeps and report steps. + --------------------------------- + + A sequence of summary data will typically look like this: + + ------------------ + SEQHDR \ + MINISTEP 0 | + PARAMS ..... | + MINISTEP 1 |==> This is REPORT STEP 1, in file BASE.S00001 + PARAMS ..... | + MINISTEP 2 | + PARAMS ..... / + ------------------ + SEQHDR \ + MINISTEP 3 | + PARAMS ..... | + MINISTEP 4 | + PARAMS ..... | + MINISTEP 5 |==> This is REPORT STEP 2, in file BASE.S0002 + PARAMS ..... | + MINISTEP 6 | + PARAMS ..... | + SEQHDR | + MINISTEP 7 | + PARAMS ..... / + ------------------ + + + Observe the following: + + * The MINISTEP counter runs continously, and does not + differentiate between unified files and not unified files. + + * When using multiple files we can read off the report number + from the filename, for unified files this is IMPOSSIBLE, and we + just have to assume that the first block corresponds to + report_step 1 and then count afterwards. + + * When asking for a summary variable at a particular REPORT STEP + (as we do in enkf) it is ambigous as to which ministep within + the block one should use. The convention we have employed + (which corresponds to the old RPTONLY based behaviour) is to + use the last ministep in the block. + + * There is no BASE.SOOOO file + + * The report steps are halfopen intervals in the "wrong way": + (....] + + + + + About MINISTEP, REPORTSTEP, rates and continous sim_time/sim_days: + ------------------------------------------------------------------ + + For ECLIPSE summary files the smallest unit of time resolution is + called the ministep - a ministep corresponds to a time step in the + underlying partial differential equation, i.e. the length of the + timesteps is controlled by the simulator itself - there is no finer + temporal resolution. + + The user has told the simulator to store (i.e. save to file + results) the results at reportsteps. A reportstep will typically + consist of several ministeps. The timeline below shows a simulation + consisting of two reportsteps: + + + S0001 S0002 + ||------|------|------------|------------------||----------------------|----------------------|| + M1 M2 M3 M4 M5 M6 + + The first reportstep consist of four ministeps, the second + reportstep consits of only two ministeps. As a user you have no + control over the length/number of ministeps apart from: + + 1. Indirectly through the TUNING keywords. + 2. A ministep will always end at a report step. + + + RPTONLY: In conjunction with enkf it has been customary to use the + keyword RPTONLY. This is purely a storage directive, the effect is + that only the ministep ending at the REPORT step is reported, + i.e. in the case above we would get the ministeps [M4 , M6], where + the ministeps M4 and M6 will be unchanged, and there will be many + 'holes' in the timeline. + + About truetime: The ministeps have a finite length; this implies + that + + [rates]: The ministep value is NOT actually an instantaneous + value, it is the total production during the ministepd period + - divided by the length of the ministep. I.e. it is an average + value. (I.e. the differential time element dt is actually quite + looong). + + [state]: For state variables (this will include total production + of various phases), the ministep value corresponds to the + reservoir state at THE END OF THE MINISTEP. + + This difference between state variables and rates implies a + difference in how continous time-variables (in the middle of a + ministep) are reported, i.e. + + + S0000 S0001 + ||--------------|---------------|------------X-------------|| + M1 M2 /|\ M3 + | + | + + We have enteeed the sim_days/sim_time cooresponding to the location + of 'X' on the timeline, i.e. in the middle of ministep M3. If we + are interested in the rate at this time the function: + + ecl_sum_data_get_from_sim_time() + + will just return the M3 value, whereas if you are interested in + e.g. pressure at this time the function will return a weighted + average of the M2 and M3 values. Whether a variable in question is + interpreted as a 'rate' is effectively determined by the + ecl_smspec_set_rate_var() function in ecl_smspec.c. + + + + Indexing and _get() versus _iget() + ---------------------------------- + As already mentionded the set of ministeps is not necessarrily a + continous series, we can easily have a series of ministeps with + "holes" in it, and the series can also start on a non-zero + value. Internally all the ministeps are stored in a dense, zero + offset vector instance; and we must be able to translate back and + forth between ministep_nr and internal index. + + Partly due to EnKF heritage the MINISTEP nr has been the main + method to access the time dimension of the data, i.e. all the + functions like ecl_sum_get_general_var() expect the time direction + to be given as a ministep; however it is also possible to get the + data by giving an internal (not that internal ...) index. In + ecl_sum_data.c the latter functions have _iget(): + + + ecl_sum_data_get_xxx : Expects the time direction given as a ministep_nr. + ecl_sum_data_iget_xxx: Expects the time direction given as an internal index. + +*/ + + +namespace ecl { + + +ecl_sum_file_data::ecl_sum_file_data(const ecl_smspec_type * smspec) : + ecl_smspec( smspec ), + data( vector_alloc_new() ) +{ +} + +ecl_sum_file_data::~ecl_sum_file_data() { + vector_free( data ); +} + + +int ecl_sum_file_data::length() const { + if (this->loader) + return this->loader->length(); + else + return this->index.size(); +} + + +int ecl_sum_file_data::length_before(time_t end_time) const { + int offset = 0; + while (true) { + time_t itime = this->iget_sim_time(offset); + if (itime >= end_time) + return offset; + + offset += 1; + if (offset == this->length()) + return offset; + } +} + + +int ecl_sum_file_data::report_before(time_t end_time) const { + if (end_time < this->first_report()) + throw std::invalid_argument("time argument before first report step"); + + int r = this->first_report(); + int last_report = this->last_report(); + while (true) { + if (r == last_report) + return last_report; + + auto next_range = this->index.report_range(r + 1); + if (this->iget_sim_time(next_range.first) > end_time) + return r; + + r += 1; + } +} + + +int ecl_sum_file_data::first_report() const{ + const auto& node = this->index[0]; + return node.report_step; +} + +int ecl_sum_file_data::last_report() const { + const auto& node = this->index.back(); + return node.report_step; +} + + + +time_t ecl_sum_file_data::get_data_start() const { + const auto& node = this->index[0]; + return node.sim_time; +} + + +time_t ecl_sum_file_data::get_sim_end() const { + const auto& node = this->index.back(); + return node.sim_time; +} + +time_t ecl_sum_file_data::iget_sim_time(int time_index) const { + const auto& node = this->index[time_index]; + return node.sim_time; +} + +/* + Will return the length of the simulation in whatever units were used in input. +*/ +double ecl_sum_file_data::get_sim_length() const { + const auto& node = this->index.back(); + return node.sim_seconds / ecl_smspec_get_time_seconds( this->ecl_smspec ); +} + +double ecl_sum_file_data::iget( int time_index , int params_index ) const { + if (this->loader) + return this->loader->iget(time_index, params_index); + else { + const ecl_sum_tstep_type * ministep_data = iget_ministep( time_index ); + return ecl_sum_tstep_iget( ministep_data , params_index); + } +} + + + +void ecl_sum_file_data::append_tstep(ecl_sum_tstep_type * tstep) { + /* + Here the tstep is just appended naively, the vector will be + sorted by ministep_nr before the data instance is returned. + */ + + vector_append_owned_ref( data , tstep , ecl_sum_tstep_free__); +} + + +/* + This function is meant to be called in write mode; and will create a + new and empty tstep which is appended to the current data. The tstep + will also be returned, so the calling scope can call + ecl_sum_tstep_iset() to set elements in the tstep. +*/ + +ecl_sum_tstep_type * ecl_sum_file_data::add_new_tstep( int report_step , double sim_seconds) { + int ministep_nr = vector_get_size( data ); + ecl_sum_tstep_type * tstep = ecl_sum_tstep_alloc_new( report_step , ministep_nr , sim_seconds , ecl_smspec ); + ecl_sum_tstep_type * prev_tstep = NULL; + + if (vector_get_size( data ) > 0) + prev_tstep = (ecl_sum_tstep_type*) vector_get_last( data ); + + append_tstep( tstep ); + + + bool rebuild_index = true; + /* + In the simple case that we just add another timestep to the + currently active report_step, we do a limited update of the + index, otherwise we call ecl_sum_data_build_index() to get a + full recalculation of the index. + */ + if (!prev_tstep) + goto exit; + + if (ecl_sum_tstep_get_report(prev_tstep) != ecl_sum_tstep_get_report( tstep )) + goto exit; + + if (ecl_sum_tstep_get_sim_days( prev_tstep ) >= ecl_sum_tstep_get_sim_days( tstep )) + goto exit; + + this->index.add(ecl_sum_tstep_get_sim_time(tstep), sim_seconds, report_step); + rebuild_index = false; + +exit: + if (rebuild_index) + this->build_index(); + + return tstep; +} + + +ecl_sum_tstep_type * ecl_sum_file_data::iget_ministep( int internal_index ) const { + return (ecl_sum_tstep_type*)vector_iget( data , internal_index ); +} + +double ecl_sum_file_data::iget_sim_days(int time_index ) const { + const auto& node = this->index[time_index]; + return node.sim_seconds / 86400; +} + +double ecl_sum_file_data::iget_sim_seconds(int time_index ) const { + const auto& node = this->index[time_index]; + return node.sim_seconds; +} + + +static int cmp_ministep( const void * arg1 , const void * arg2) { + const ecl_sum_tstep_type * ministep1 = ecl_sum_tstep_safe_cast_const( arg1 ); + const ecl_sum_tstep_type * ministep2 = ecl_sum_tstep_safe_cast_const( arg2 ); + + time_t time1 = ecl_sum_tstep_get_sim_time( ministep1 ); + time_t time2 = ecl_sum_tstep_get_sim_time( ministep2 ); + + if (time1 < time2) + return -1; + else if (time1 == time2) + return 0; + else + return 1; +} + + + +void ecl_sum_file_data::build_index( ) { + this->index.clear(); + + if (this->loader) { + int offset = ecl_smspec_get_first_step(this->ecl_smspec) - 1; + std::vector report_steps = this->loader->report_steps(offset); + std::vector sim_time = this->loader->sim_time(); + std::vector sim_seconds = this->loader->sim_seconds(); + + for (int i=0; i < this->loader->length(); i++) { + this->index.add(sim_time[i], + sim_seconds[i], + report_steps[i]); + } + } else { + vector_sort( data , cmp_ministep ); + for (int internal_index = 0; internal_index < vector_get_size( data ); internal_index++) { + const ecl_sum_tstep_type * ministep = iget_ministep( internal_index ); + this->index.add(ecl_sum_tstep_get_sim_time(ministep), + ecl_sum_tstep_get_sim_seconds(ministep), + ecl_sum_tstep_get_report(ministep)); + } + } +} + +void ecl_sum_file_data::get_time(int length, time_t * data) { + for (int time_index=0; time_index < length; time_index++) + data[time_index] = this->iget_sim_time(time_index); +} + + +int ecl_sum_file_data::get_time_report(int end_index, time_t *data) { + int offset = 0; + + for (int report_step = this->first_report(); report_step <= this->last_report(); report_step++) { + const auto& range = this->report_range(report_step); + int time_index = range.second; + if (time_index >= end_index) + break; + + data[offset] = this->iget_sim_time(time_index); + + offset += 1; + } + return offset; +} + + + +void ecl_sum_file_data::get_data(int params_index, int length, double *data) { + if (this->loader) { + const auto tmp_data = loader->get_vector(params_index); + memcpy(data, tmp_data.data(), length * sizeof data); + } else { + for (int time_index=0; time_index < length; time_index++) + data[time_index] = this->iget(time_index, params_index); + } +} + + +int ecl_sum_file_data::get_data_report(int params_index, int end_index, double *data, double default_value) { + int offset = 0; + + for (int report_step = this->first_report(); report_step <= this->last_report(); report_step++) { + int time_index = this->index.report_range(report_step).second; + if (time_index >= end_index) + break; + + if (params_index >= 0) + data[offset] = this->iget(time_index, params_index); + else + data[offset] = default_value; + + offset += 1; + } + return offset; +} + + + +bool ecl_sum_file_data::has_report(int report_step ) const { + return this->index.has_report(report_step); +} + + +// ******************** Start writing *************************************************** + + +std::pair ecl_sum_file_data::report_range(int report_step) const { + return this->index.report_range(report_step); +} + + +void ecl_sum_file_data::fwrite_report( int report_step , fortio_type * fortio) const { + { + ecl_kw_type * seqhdr_kw = ecl_kw_alloc( SEQHDR_KW , SEQHDR_SIZE , ECL_INT ); + ecl_kw_iset_int( seqhdr_kw , 0 , 0 ); + ecl_kw_fwrite( seqhdr_kw , fortio ); + ecl_kw_free( seqhdr_kw ); + } + + { + auto range = this->report_range( report_step ); + for (int index = range.first; index <= range.second; index++) { + const ecl_sum_tstep_type * tstep = iget_ministep( index ); + ecl_sum_tstep_fwrite( tstep , ecl_smspec_get_index_map( ecl_smspec ) , fortio ); + } + } +} + + +void ecl_sum_file_data::fwrite_unified( fortio_type * fortio ) const { + if (this->length() == 0) + return; + + for (int report_step = first_report(); report_step <= last_report(); report_step++) { + if (has_report( report_step )) + fwrite_report( report_step , fortio ); + } +} + + +void ecl_sum_file_data::fwrite_multiple( const char * ecl_case , bool fmt_case ) const { + if (this->length() == 0) + return; + + for (int report_step = this->first_report(); report_step <= this->last_report(); report_step++) { + if (this->has_report( report_step )) { + char * filename = ecl_util_alloc_filename( NULL , ecl_case , ECL_SUMMARY_FILE , fmt_case , report_step ); + fortio_type * fortio = fortio_open_writer( filename , fmt_case , ECL_ENDIAN_FLIP ); + + fwrite_report( report_step , fortio ); + + fortio_fclose( fortio ); + free( filename ); + } + } +} + + +bool ecl_sum_file_data::can_write() const { + if (this->loader) + return false; + + return true; +} + +double ecl_sum_file_data::get_days_start() const { + const auto& node = this->index[0]; + return node.sim_seconds * 86400; +} + + +// ***************************** End writing ************************************* + +// **************************** Start Reading ************************************ + +bool ecl_sum_file_data::check_file( ecl_file_type * ecl_file ) { + return ecl_file_has_kw( ecl_file , PARAMS_KW ) && + (ecl_file_get_num_named_kw( ecl_file , PARAMS_KW ) == ecl_file_get_num_named_kw( ecl_file , MINISTEP_KW)); +} + +/** + Malformed/incomplete files: + ---------------------------- + Observe that ECLIPSE works in the following way: + + 1. At the start of a report step a summary data section + containing only the 'SEQHDR' keyword is written - this is + currently an 'invalid' summary section. + + 2. ECLIPSE simulates as best it can. + + 3. When the time step is complete data is written to the summary + file. + + Now - if ECLIPSE goes down in flames during step 2 a malformed + summary file will be left around, to handle this situation + reasonably gracefully we check that the ecl_file instance has at + least one "PARAMS" keyword. + + One ecl_file corresponds to one report_step (limited by SEQHDR); in + the case of non unfied summary files these objects correspond to + one BASE.Annnn or BASE.Snnnn file, in the case of unified files the + calling routine will read the unified summary file partly. +*/ + +void ecl_sum_file_data::add_ecl_file(int report_step, const ecl_file_view_type * summary_view, const ecl_smspec_type * smspec) { + + int num_ministep = ecl_file_view_get_num_named_kw( summary_view , PARAMS_KW); + if (num_ministep > 0) { + int ikw; + + for (ikw = 0; ikw < num_ministep; ikw++) { + ecl_kw_type * ministep_kw = ecl_file_view_iget_named_kw( summary_view , MINISTEP_KW , ikw); + ecl_kw_type * params_kw = ecl_file_view_iget_named_kw( summary_view , PARAMS_KW , ikw); + + { + int ministep_nr = ecl_kw_iget_int( ministep_kw , 0 ); + ecl_sum_tstep_type * tstep = ecl_sum_tstep_alloc_from_file( report_step , + ministep_nr , + params_kw , + ecl_file_view_get_src_file( summary_view ), + smspec ); + + if (tstep) + append_tstep( tstep ); + } + } + } +} + + +bool ecl_sum_file_data::fread(const stringlist_type * filelist, bool lazy_load, int file_options) { + if (stringlist_get_size( filelist ) == 0) + return false; + + ecl_file_enum file_type = ecl_util_get_file_type( stringlist_iget( filelist , 0 ) , NULL , NULL); + if ((stringlist_get_size( filelist ) > 1) && (file_type != ECL_SUMMARY_FILE)) + util_abort("%s: internal error - when calling with more than one file - you can not supply a unified file - come on?! \n",__func__); + + if (file_type == ECL_SUMMARY_FILE) { + + /* Not unified. */ + for (int filenr = 0; filenr < stringlist_get_size( filelist ); filenr++) { + const char * data_file = stringlist_iget( filelist , filenr); + ecl_file_enum file_type; + int report_step; + file_type = ecl_util_get_file_type( data_file , NULL , &report_step); + if (file_type != ECL_SUMMARY_FILE) + util_abort("%s: file:%s has wrong type \n",__func__ , data_file); + { + ecl_file_type * ecl_file = ecl_file_open( data_file , 0); + if (ecl_file && check_file( ecl_file )) { + add_ecl_file( report_step , ecl_file_get_global_view( ecl_file ) , ecl_smspec); + ecl_file_close( ecl_file ); + } + } + } + } else if (file_type == ECL_UNIFIED_SUMMARY_FILE) { + if (lazy_load) { + try { + this->loader.reset( new unsmry_loader( this->ecl_smspec, stringlist_iget(filelist, 0), file_options) ); + } + catch(const std::bad_alloc& e) + { + return false; + } + } else { + + // Is this correct for a restarted chain of UNSMRY files? Looks like the + // report step sequence will be restarted? + ecl_file_type * ecl_file = ecl_file_open( stringlist_iget(filelist ,0 ) , 0); + if (ecl_file && check_file( ecl_file )) { + int first_report_step = ecl_smspec_get_first_step(this->ecl_smspec); + int block_index = 0; + while (true) { + /* + Observe that there is a number discrepancy between ECLIPSE + and the ecl_file_select_smryblock() function. ECLIPSE + starts counting report steps at 1; whereas the first + SEQHDR block in the unified summary file is block zero (in + ert counting). + */ + ecl_file_view_type * summary_view = ecl_file_get_summary_view(ecl_file , block_index); + if (summary_view) { + add_ecl_file(block_index + first_report_step , summary_view , ecl_smspec); + block_index++; + } else break; + } + ecl_file_close( ecl_file ); + } + } + } + + build_index(); + return (length() > 0); +} + +const ecl_smspec_type * ecl_sum_file_data::smspec() const { + return this->ecl_smspec; +} + + +bool ecl_sum_file_data::report_step_equal( const ecl_sum_file_data& other, bool strict) const { + if (strict && this->first_report() != other.first_report()) + return false; + + if (strict && (this->last_report() != other.last_report())) + return false; + + int report_step = std::max(this->first_report(), other.first_report()); + int last_report = std::min(this->last_report(), other.last_report()); + while (true) { + int time_index1 = this->report_range(report_step).second; + int time_index2 = other.report_range(report_step).second; + + if ((time_index1 != INVALID_MINISTEP_NR) && (time_index2 != INVALID_MINISTEP_NR)) { + time_t time1 = this->iget_sim_time(time_index1); + time_t time2 = other.iget_sim_time(time_index2); + + if (time1 != time2) + return false; + + } else if (time_index1 != time_index2) { + if (strict) + return false; + } + + report_step++; + if (report_step > last_report) + break; + } + return true; +} + + +// ***************************** End reading ************************************* + +int ecl_sum_file_data::report_step_from_days(double sim_days) const { + int report_step = this->first_report(); + double sim_seconds = sim_days * 86400; + while (true) { + const auto& range = this->index.report_range(report_step); + if (range.second >= 0) { + const auto& node = this->index[range.second]; + + // Warning - this is a double == comparison! + if (sim_seconds == node.sim_seconds) + return report_step; + + report_step++; + if (report_step > this->last_report()) + return -1; + } + } +} + +int ecl_sum_file_data::report_step_from_time(time_t sim_time) const { + int report_step = this->first_report(); + while (true) { + const auto& range = this->index.report_range(report_step); + if (range.second >= 0) { + const auto& node = this->index[range.second]; + if (sim_time == node.sim_time) + return report_step; + + report_step++; + if (report_step > this->last_report()) + return -1; + } + } +} + +int ecl_sum_file_data::iget_report(int time_index) const { + const auto& index_node = this->index[time_index]; + return index_node.report_step; +} + + +} //end namespace + + diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum_index.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum_index.cpp index 051aca0b97..3211baac34 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum_index.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum_index.cpp @@ -1,24 +1,24 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_sum_index.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_sum_index.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include -/* +/* This file contains all the internalized information from parsing a SMSPEC file. In most cases the ecl_sum object will contain a ecl_sum_index_type instance, and the end-user will not have direct @@ -30,11 +30,11 @@ struct ecl_sum_index_type { hash_type * well_var_index; /* Indexes for all well variables. */ hash_type * well_completion_var_index; /* Indexes for completion indexes .*/ - hash_type * group_var_index; /* Indexes for group variables. */ + hash_type * group_var_index; /* Indexes for group variables. */ hash_type * field_var_index; /* Indexes for field variables. */ hash_type * region_var_index; /* The stored index is an offset. */ hash_type * misc_var_index; /* Indexes for misceallous variables - typically date. */ hash_type * block_var_index; /* Indexes for block variables. */ - + hash_type * unit_hash; /* Units for the various measurements. */ }; diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum_tstep.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum_tstep.cpp index 86eeaf7ecc..380b7e5732 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum_tstep.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum_tstep.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include @@ -147,10 +147,10 @@ void ecl_sum_tstep_free__( void * __ministep) { will select the DAYS variety if both are present. */ -static void ecl_sum_tstep_set_time_info_from_seconds( ecl_sum_tstep_type * tstep , time_t sim_start , float sim_seconds) { +static void ecl_sum_tstep_set_time_info_from_seconds( ecl_sum_tstep_type * tstep , time_t sim_start , double sim_seconds) { tstep->sim_seconds = sim_seconds; tstep->sim_time = sim_start; - util_inplace_forward_seconds_utc( &tstep->sim_time , tstep->sim_seconds ); + util_inplace_forward_seconds_utc( &tstep->sim_time , tstep->sim_seconds); } diff --git a/ThirdParty/Ert/lib/ecl/ecl_sum_vector.cpp b/ThirdParty/Ert/lib/ecl/ecl_sum_vector.cpp index 731d7a5cf5..8bcfebfe4a 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_sum_vector.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_sum_vector.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include @@ -69,9 +69,6 @@ ecl_sum_vector_type * ecl_sum_vector_alloc(const ecl_sum_type * ecl_sum, bool ad const ecl_smspec_type * smspec = ecl_sum_get_smspec(ecl_sum); for (int i=0; i < ecl_smspec_num_nodes(smspec); i++) { const smspec_node_type * node = ecl_smspec_iget_node( smspec , i ); - if (!smspec_node_is_valid(node)) - continue; - const char * key = smspec_node_get_gen_key1(node); /* The TIME keyword is special case handled to not be included; that is diff --git a/ThirdParty/Ert/lib/ecl/ecl_type.cpp b/ThirdParty/Ert/lib/ecl/ecl_type.cpp index acf8bf4043..da180467d9 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_type.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_type.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include /*****************************************************************/ @@ -64,7 +64,7 @@ ecl_data_type ecl_type_create(const ecl_type_enum type, const size_t element_siz ecl_type_create_from_type(type) ); - if(ecl_type_get_sizeof_iotype(ecl_type) != element_size) + if((size_t)ecl_type_get_sizeof_iotype(ecl_type) != element_size) util_abort( "%s: element_size mismatch for type %d, was: %d, expected: %d\n", __func__, type, @@ -202,7 +202,7 @@ bool ecl_type_is_double(const ecl_data_type ecl_type) { bool ecl_type_is_mess(const ecl_data_type ecl_type) { return (ecl_type.type == ECL_MESS_TYPE); } - + bool ecl_type_is_bool(const ecl_data_type ecl_type) { return (ecl_type.type == ECL_BOOL_TYPE); } @@ -212,7 +212,7 @@ bool ecl_type_is_string(const ecl_data_type ecl_type) { } // Temporary fixup for OPM. - char * ecl_type_get_name(const ecl_data_type ecl_type) { - return ecl_type_alloc_name( ecl_type ); - } - + char * ecl_type_get_name(const ecl_data_type ecl_type) { + return ecl_type_alloc_name( ecl_type ); + } + diff --git a/ThirdParty/Ert/lib/ecl/ecl_unsmry_loader.cpp b/ThirdParty/Ert/lib/ecl/ecl_unsmry_loader.cpp new file mode 100644 index 0000000000..bd9eb1edde --- /dev/null +++ b/ThirdParty/Ert/lib/ecl/ecl_unsmry_loader.cpp @@ -0,0 +1,173 @@ +#include +#include +#include + +#include + +#include +#include + +#include "detail/ecl/ecl_unsmry_loader.hpp" + + +namespace ecl { + +unsmry_loader::unsmry_loader(const ecl_smspec_type * smspec, const std::string& filename, int file_options) : + size(ecl_smspec_get_params_size(smspec)), + time_index(ecl_smspec_get_time_index(smspec)), + time_seconds(ecl_smspec_get_time_seconds(smspec)), + sim_start(ecl_smspec_get_start_time(smspec)) +{ + ecl_file_type * file = ecl_file_open(filename.c_str(), file_options); + if (!file) + throw std::bad_alloc(); + + if (!ecl_file_has_kw(file, PARAMS_KW)) { + ecl_file_close(file); + throw std::bad_alloc(); + } + + if (ecl_file_get_num_named_kw(file, PARAMS_KW) != ecl_file_get_num_named_kw(file, MINISTEP_KW)) { + ecl_file_close(file); + throw std::bad_alloc(); + } + + this->date_index = {{ ecl_smspec_get_date_day_index(smspec), + ecl_smspec_get_date_month_index(smspec), + ecl_smspec_get_date_year_index(smspec) }}; + this->file = file; + this->file_view = ecl_file_get_global_view( this->file ); + this->m_length = ecl_file_view_get_num_named_kw(this->file_view, PARAMS_KW); +} + + +unsmry_loader::~unsmry_loader() { + ecl_file_close(file); +} + + +int unsmry_loader::length() const { + return this->m_length; +} + + +std::vector unsmry_loader::get_vector(int pos) const { + if (pos >= size) + throw std::invalid_argument("unsmry_loader::get_vector: argument 'pos' mst be less than size of PARAMS."); + + std::vector data(this->length()); + int_vector_type * index_map = int_vector_alloc( 1 , pos); + char buffer[4]; + + for (int index = 0; index < this->length(); index++) { + ecl_file_view_index_fload_kw(file_view, PARAMS_KW, index, index_map, buffer); + float * data_value = (float*) buffer; + data[index] = *data_value; + } + int_vector_free( index_map ); + return data; +} + + +// This is horribly inefficient +double unsmry_loader::iget(int time_index, int params_index) const { + int_vector_type * index_map = int_vector_alloc( 1 , params_index); + float value; + ecl_file_view_index_fload_kw(this->file_view, PARAMS_KW, time_index, index_map, (char *) &value); + int_vector_free(index_map); + return value; +} + + + +time_t unsmry_loader::iget_sim_time(int time_index) const { + if (this->time_index >= 0) { + double sim_seconds = this->iget_sim_seconds(time_index); + time_t sim_time = this->sim_start; + util_inplace_forward_seconds_utc( &sim_time , sim_seconds ) ; + return sim_time; + } else { + int_vector_type * index_map = int_vector_alloc(3,0); + int_vector_iset(index_map, 0, this->date_index[0]); + int_vector_iset(index_map, 1, this->date_index[1]); + int_vector_iset(index_map, 2, this->date_index[2]); + + float values[3]; + ecl_file_view_index_fload_kw(this->file_view, PARAMS_KW, time_index, index_map, (char *) &values); + int_vector_free(index_map); + + return ecl_util_make_date(util_roundf( values[0] ), + util_roundf( values[1] ), + util_roundf( values[2] )); + } +} + +double unsmry_loader::iget_sim_seconds(int time_index) const { + if (this->time_index >= 0) { + double raw_time = this->iget(time_index, this->time_index); + return raw_time * this->time_seconds; + } else { + time_t sim_time = this->iget_sim_time(time_index); + return util_difftime_seconds(this->sim_start, sim_time); + } +} + +std::vector unsmry_loader::report_steps(int offset) const { + std::vector report_steps; + int current_step = offset; + for (int i=0; i < ecl_file_view_get_size(this->file_view); i++) { + const ecl_file_kw_type * file_kw = ecl_file_view_iget_file_kw(this->file_view, i); + if (util_string_equal(SEQHDR_KW, ecl_file_kw_get_header(file_kw))) + current_step++; + + if (util_string_equal(PARAMS_KW, ecl_file_kw_get_header(file_kw))) + report_steps.push_back(current_step); + } + return report_steps; +} + +std::vector unsmry_loader::sim_time() const { + if (this->time_index >= 0) { + const std::vector sim_seconds = this->sim_seconds(); + std::vector st(this->length(), this->sim_start); + + for (size_t i=0; i < st.size(); i++) + util_inplace_forward_seconds_utc(&st[i], sim_seconds[i]); + + return st; + + } else { + const auto day = this->get_vector(this->date_index[0]); + const auto month = this->get_vector(this->date_index[1]); + const auto year = this->get_vector(this->date_index[2]); + std::vector st(this->length()); + + for (size_t i=0; i < st.size(); i++) + st[i] = ecl_util_make_date(util_round(day[i]), + util_round(month[i]), + util_round(year[i])); + + return st; + } +} + + +std::vector unsmry_loader::sim_seconds() const { + if (this->time_index >= 0) { + std::vector seconds = this->get_vector(this->time_index); + for (size_t i=0; i < seconds.size(); i++) + seconds[i] *= this->time_seconds; + + return seconds; + } else { + std::vector st = this->sim_time(); + std::vector seconds(st.size()); + + for (size_t i=0; i < st.size(); i++) + seconds[i] = util_difftime_seconds(this->sim_start, st[i]); + + return seconds; + } +} + +} diff --git a/ThirdParty/Ert/lib/ecl/ecl_util.cpp b/ThirdParty/Ert/lib/ecl/ecl_util.cpp index f94bcb8f6c..fd479ca131 100644 --- a/ThirdParty/Ert/lib/ecl/ecl_util.cpp +++ b/ThirdParty/Ert/lib/ecl/ecl_util.cpp @@ -22,9 +22,9 @@ #include #include -#include +#include -#include +#include #include #include #include @@ -342,8 +342,8 @@ static bool valid_base(const char * input_base, bool * upper_case) { if (base == NULL) base = input_base; - for (int i=0; i < strlen(base); i++) { - char c = base[i]; + for (size_t i=0; i < strlen(base); i++) { + unsigned char c = base[i]; if (isupper(c)) upper = true; @@ -455,7 +455,7 @@ static char * ecl_util_alloc_filename_static(const char * path, const char * bas } if (!upper_case) { - for (int i=0; i < strlen(ext); i++) + for (size_t i=0; i < strlen(ext); i++) ext[i] = tolower(ext[i]); } @@ -499,7 +499,7 @@ char * ecl_util_alloc_exfilename_anyfmt(const char * path, const char * base , e } if (! util_file_exists(filename)) { - util_safe_free( filename ); + free( filename ); filename = NULL; } @@ -660,7 +660,7 @@ int ecl_util_select_filelist( const char * path , const char * base , ecl_file_e char * file_pattern; if (!upper_case) { - for (int i=0; i < strlen(ext_pattern); i++) + for (size_t i=0; i < strlen(ext_pattern); i++) ext_pattern[i] = tolower(ext_pattern[i]); } @@ -809,7 +809,7 @@ void ecl_util_alloc_summary_data_files(const char * path , const char * base , b stringlist_clear( filelist ); /* Clear out all the BASE.Snnnn selections. */ stringlist_append_copy( filelist , unif_data_file ); } - util_safe_free( unif_data_file ); + free( unif_data_file ); } @@ -936,10 +936,10 @@ bool ecl_util_alloc_summary_files(const char * path , const char * _base , const if (fmt_file) { header_file = fsmspec_file; - util_safe_free( smspec_file ); + free( smspec_file ); } else { header_file = smspec_file; - util_safe_free( fsmspec_file ); + free( fsmspec_file ); } if (header_file == NULL) @@ -1106,7 +1106,7 @@ safely used as filenames, i.e for instance the substitution: The escape process is done 'in-place' memory-wise. */ void ecl_util_escape_kw(char * kw) { - int index; + size_t index; for (index = 0; index < strlen(kw); index++) { switch (kw[index]) { case('/'): diff --git a/ThirdParty/Ert/lib/ecl/fault_block.cpp b/ThirdParty/Ert/lib/ecl/fault_block.cpp index c8faddd136..8ea051204b 100644 --- a/ThirdParty/Ert/lib/ecl/fault_block.cpp +++ b/ThirdParty/Ert/lib/ecl/fault_block.cpp @@ -15,13 +15,14 @@ See the GNU General Public License at for more details. */ +#include -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include #include #include @@ -29,6 +30,8 @@ #include #include +#include "detail/ecl/layer_cxx.hpp" + #define FAULT_BLOCK_ID 3297376 @@ -182,8 +185,7 @@ const int_vector_type * fault_block_get_global_index_list( const fault_block_typ bool fault_block_trace_edge( const fault_block_type * block , double_vector_type * x_list , double_vector_type * y_list, int_vector_type * cell_list) { if (fault_block_get_size( block ) > 0) { - struct_vector_type * corner_list = struct_vector_alloc( sizeof(int_point2d_type) ); - int c; + std::vector corner_list; { int start_i = fault_block_iget_i( block , 0 ); int start_j = fault_block_iget_j( block , 0 ); @@ -194,18 +196,15 @@ bool fault_block_trace_edge( const fault_block_type * block , double_vector_type if (x_list && y_list) { double_vector_reset( x_list ); double_vector_reset( y_list ); - for (c=0; c < struct_vector_get_size( corner_list ); c++) { + for (const auto& p : corner_list) { double x,y,z; - int_point2d_type ij; - struct_vector_iget( corner_list , c , &ij ); - ecl_grid_get_corner_xyz( block->grid , ij.i , ij.j , block->k , &x , &y , &z); + ecl_grid_get_corner_xyz( block->grid , p.i, p.j , block->k , &x , &y , &z); double_vector_append( x_list , x); double_vector_append( y_list , y); } } - struct_vector_free( corner_list ); return true; } else return false; @@ -257,7 +256,7 @@ static bool fault_block_connected_neighbour( const fault_block_type * block , in */ if (!ecl_grid_cell_active3( block->grid , i2,j2,block->k)) return false; - + { int cell_id = layer_iget_cell_value( layer , i1 , j1 ); int neighbour_id = layer_iget_cell_value(layer , i2 , j2); diff --git a/ThirdParty/Ert/lib/ecl/fault_block_layer.cpp b/ThirdParty/Ert/lib/ecl/fault_block_layer.cpp index 8f44f521cb..c802705d36 100644 --- a/ThirdParty/Ert/lib/ecl/fault_block_layer.cpp +++ b/ThirdParty/Ert/lib/ecl/fault_block_layer.cpp @@ -16,16 +16,16 @@ for more details. */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include #define FAULT_BLOCK_LAYER_ID 2297476 diff --git a/ThirdParty/Ert/lib/ecl/fortio.c b/ThirdParty/Ert/lib/ecl/fortio.c index 65478d7102..bf62340816 100644 --- a/ThirdParty/Ert/lib/ecl/fortio.c +++ b/ThirdParty/Ert/lib/ecl/fortio.c @@ -23,9 +23,10 @@ #include #include -#include +#include #include +#include #define FORTIO_ID 345116 @@ -90,6 +91,7 @@ struct fortio_struct { */ bool writable; offset_type read_size; + char opts[3]; }; @@ -105,6 +107,7 @@ static fortio_type * fortio_alloc__(const char *filename , bool fmt_file , bool fortio->stream_owner = stream_owner; fortio->writable = writable; fortio->read_size = 0; + strcpy( fortio->opts, endian_flip_header ? "c" : "ce" ); return fortio; } @@ -116,13 +119,9 @@ static fortio_type * fortio_alloc__(const char *filename , bool fmt_file , bool */ static bool __read_int(FILE * stream , int * value, bool endian_flip) { - /* This fread() can legitemately fail - can not use util_fread() here. */ - if (fread(value , sizeof * value , 1 , stream) == 1) { - if (endian_flip) - util_endian_flip_vector(value , sizeof * value , 1); - return true; - } else - return false; + int ok = eclfio_sizeof( stream, endian_flip ? "c" : "ce", value ); + fseek( stream, sizeof( int32_t ), SEEK_CUR ); + return !ok; } @@ -396,7 +395,7 @@ bool fortio_assert_stream_open( fortio_type * fortio ) { static void fortio_free__(fortio_type * fortio) { - util_safe_free(fortio->filename); + free(fortio->filename); free(fortio); } @@ -416,30 +415,14 @@ void fortio_fclose(fortio_type *fortio) { bool fortio_is_fortio_file(fortio_type * fortio) { - offset_type init_pos = fortio_ftell(fortio); - int elm_read; - bool is_fortio_file = false; - int record_size; - elm_read = fread(&record_size , sizeof(record_size) , 1 , fortio->stream); - if (elm_read == 1) { - int trailer; - - if (fortio->endian_flip_header) - util_endian_flip_vector(&record_size , sizeof record_size , 1); + fpos_t init_pos; + fgetpos( fortio->stream, &init_pos ); - if (fortio_fseek(fortio , (offset_type) record_size , SEEK_CUR) == 0) { - if (fread(&trailer , sizeof(record_size) , 1 , fortio->stream) == 1) { - if (fortio->endian_flip_header) - util_endian_flip_vector(&trailer , sizeof trailer , 1); + int err = eclfio_get( fortio->stream, fortio->opts, NULL, NULL ); - if (trailer == record_size) - is_fortio_file = true; - } - } - } + fsetpos( fortio->stream, &init_pos ); - fortio_fseek(fortio , init_pos , SEEK_SET); - return is_fortio_file; + return err == ECL_OK; } @@ -451,26 +434,17 @@ bool fortio_is_fortio_file(fortio_type * fortio) { */ int fortio_init_read(fortio_type *fortio) { - int elm_read; - int record_size; - - elm_read = fread(&record_size , sizeof(record_size) , 1 , fortio->stream); - if (elm_read == 1) { - if (fortio->endian_flip_header) - util_endian_flip_vector(&record_size , sizeof record_size , 1); - - return record_size; - } else - return -1; + int32_t record_size; + int err = eclfio_sizeof( fortio->stream, fortio->opts, &record_size ); + // this function exposes successful reads as advanced file pointers + if( err == 0 ) fseek( fortio->stream, 4, SEEK_CUR ); + return err ? -1 : record_size; } bool fortio_data_fskip(fortio_type* fortio, const int element_size, const int element_count, const int block_count) { - int headers = block_count * 4; - int trailers = block_count * 4; - int bytes_to_skip = headers + trailers + (element_size * element_count); + return !eclfio_skip( fortio->stream, fortio->opts, block_count ); - return fortio_fseek(fortio, bytes_to_skip, SEEK_CUR); } @@ -482,9 +456,9 @@ void fortio_data_fseek(fortio_type* fortio, offset_type data_offset, size_t data int block_index = data_element / block_size; int headers = (block_index + 1) * 4; int trailers = block_index * 4; - offset_type bytes_to_skip = data_offset + headers + trailers + (data_element * element_size); + offset_type offset = data_offset + headers + trailers + (data_element * element_size); - fortio_fseek(fortio, bytes_to_skip, SEEK_SET); + fortio_fseek(fortio, offset, SEEK_SET); } } @@ -515,28 +489,6 @@ bool fortio_complete_read(fortio_type *fortio , int record_size) { return false; } - -/** - This function reads one record from the fortio stream, and fills - the buffer with the content. The return value is the number of - bytes read; the function will return -1 on failure. -*/ - -static int fortio_fread_record(fortio_type *fortio , char *buffer) { - int record_size = fortio_init_read(fortio); - if (record_size >= 0) { - size_t items_read = fread(buffer , 1 , record_size , fortio->stream); - if (items_read == record_size) { - bool complete_ok = fortio_complete_read(fortio , record_size); - if (!complete_ok) - record_size = -1; - } else - record_size = -1; /* Failure */ - } - return record_size; -} - - /** This function fills the buffer with 'buffer_size' bytes from the fortio stream. The function works by repeated calls to @@ -547,75 +499,107 @@ static int fortio_fread_record(fortio_type *fortio , char *buffer) { */ bool fortio_fread_buffer(fortio_type * fortio, char * buffer , int buffer_size) { - int total_bytes_read = 0; - - while (true) { - char * buffer_ptr = &buffer[total_bytes_read]; - int bytes_read = fortio_fread_record(fortio , buffer_ptr); - - if (bytes_read < 0) - break; - else { - total_bytes_read += bytes_read; - if (total_bytes_read >= buffer_size) - break; - } - } + int total_bytes_read = 0; + + while( true ) { + int32_t record_size = buffer_size - total_bytes_read; + int err = eclfio_get( fortio->stream, + fortio->opts, + &record_size, + buffer ); + + if( err == ECL_EINVAL ) { + err = eclfio_sizeof( fortio->stream, fortio->opts, &record_size ); + if( err ) util_abort("%s: unable to determine size of record, " + "%d bytes read\n", + __func__, + total_bytes_read ); + + if( total_bytes_read + record_size > buffer_size ) + util_abort("%s: internal inconsistency: " + "buffer_size:%d, would read %d bytes\n", + __func__, + buffer_size, + total_bytes_read + record_size ); + + return false; + } - if (total_bytes_read == buffer_size) - return true; + if( err ) return false; - if (total_bytes_read < buffer_size) - return false; + buffer += record_size; + total_bytes_read += record_size; - util_abort("%s: internal inconsistency: buffer_size:%d read %d bytes \n",__func__ , buffer_size , total_bytes_read); - return false; + if( total_bytes_read == buffer_size ) + return true; + } } int fortio_fskip_record(fortio_type *fortio) { - int record_size = fortio_init_read(fortio); - fortio_fseek(fortio , (offset_type) record_size , SEEK_CUR); - fortio_complete_read(fortio , record_size); - return record_size; + int32_t size = 0; + const int err = eclfio_get( fortio->stream, fortio->opts, &size, NULL ); + if( err ) return -1; + return size; } void fortio_fskip_buffer(fortio_type * fortio, int buffer_size) { int bytes_skipped = 0; - while (bytes_skipped < buffer_size) - bytes_skipped += fortio_fskip_record(fortio); + while (bytes_skipped < buffer_size) { + int size = fortio_fskip_record(fortio); + + if( size < 0 ) util_abort( "%s: broken record in %s. " + "%d bytes skipped so far\n", + __func__, + fortio->filename, + bytes_skipped ); + + bytes_skipped += fortio_fskip_record(fortio); + } if (bytes_skipped > buffer_size) util_abort("%s: hmmmm - something is broken. The individual records in %s did not sum up to the expected buffer size \n",__func__ , fortio->filename); } -void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream , int buffer_size , void * buffer , bool *at_eof) { - int bytes_read; - int record_size = fortio_init_read(src_stream); - fortio_init_write(target_stream , record_size); +void fortio_copy_record(fortio_type * src_stream , fortio_type * target_stream , int buffer_size , void * ext_buffer, bool *at_eof) { + int bytes_read = 0; - bytes_read = 0; - while (bytes_read < record_size) { - int bytes; - if (record_size > buffer_size) - bytes = buffer_size; - else - bytes = record_size - bytes_read; - util_fread(buffer , 1 , bytes , src_stream->stream , __func__); - util_fwrite(buffer , 1 , bytes , target_stream->stream , __func__); + int32_t size = 0; + int err = eclfio_sizeof( src_stream->stream, src_stream->opts, &size ); + if( err ) { + util_abort( "%s: could not peek record size after %d bytes\n", + __func__, + bytes_read ); + } - bytes_read += bytes; - } + void* buffer = ext_buffer; + if( buffer_size < size ) { + buffer = malloc( size ); + ext_buffer = NULL; + } - fortio_complete_read(src_stream , record_size); - fortio_complete_write(target_stream , record_size); + err = eclfio_get( src_stream->stream, src_stream->opts, &size, buffer ); + if( err ) { + util_abort( "%s: could not read record after %d bytes\n", + __func__, + bytes_read ); + } - if (feof(src_stream->stream)) - *at_eof = true; - else - *at_eof = false; + err = eclfio_put( target_stream->stream, + target_stream->opts, + size, + buffer ); + if( err ) { + util_abort( "%s: could not write record after %d bytes\n", + __func__, + bytes_read ); + } + + if( !ext_buffer ) free( buffer ); + + *at_eof = feof( src_stream->stream ); } @@ -640,19 +624,23 @@ void fortio_complete_write(fortio_type *fortio , int record_size) { void fortio_fwrite_record(fortio_type *fortio, const char *buffer , int record_size) { - fortio_init_write(fortio , record_size); - util_fwrite( buffer , 1 , record_size , fortio->stream , __func__); - fortio_complete_write(fortio , record_size); + int err = eclfio_put( fortio->stream, + fortio->opts, + record_size, + buffer ); + + if( err ) util_abort( "%s: unable to write %d byte record\n", + __func__, + record_size ); } void * fortio_fread_alloc_record(fortio_type * fortio) { - void * buffer; - int record_size = fortio_init_read(fortio); - buffer = util_malloc( record_size ); - util_fread(buffer , 1 , record_size , fortio->stream , __func__); - fortio_complete_read(fortio , record_size); - return buffer; + int32_t record_size = 0; + eclfio_sizeof( fortio->stream, fortio->opts, &record_size ); + void* buffer = calloc( 1, record_size ); + eclfio_get( fortio->stream, fortio->opts, &record_size, buffer ); + return buffer; } diff --git a/ThirdParty/Ert/lib/ecl/grid_dims.cpp b/ThirdParty/Ert/lib/ecl/grid_dims.cpp index 1d2115b089..7a243f2878 100644 --- a/ThirdParty/Ert/lib/ecl/grid_dims.cpp +++ b/ThirdParty/Ert/lib/ecl/grid_dims.cpp @@ -1,24 +1,24 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include -#include +#include #include diff --git a/ThirdParty/Ert/lib/ecl/layer.cpp b/ThirdParty/Ert/lib/ecl/layer.cpp index 7a79809f31..07fe65f50e 100644 --- a/ThirdParty/Ert/lib/ecl/layer.cpp +++ b/ThirdParty/Ert/lib/ecl/layer.cpp @@ -18,6 +18,8 @@ #include #include +#include + #include #include @@ -300,7 +302,14 @@ static bool point_equal(int_point2d_type * p1 , int_point2d_type *p2) { */ -static void layer_trace_block_edge__( const layer_type * layer , int_point2d_type start_point , int i , int j , int value , edge_dir_enum dir , struct_vector_type * corner_list, int_vector_type * cell_list) { +static void layer_trace_block_edge__( const layer_type * layer , + int_point2d_type start_point , + int i, + int j, + int value, + edge_dir_enum dir , + std::vector& corner_list, + int_vector_type * cell_list) { int_point2d_type current_point; int_point2d_type next_point; current_point.i = i; @@ -318,7 +327,7 @@ static void layer_trace_block_edge__( const layer_type * layer , int_point2d_typ } else if (dir == LEFT_EDGE) point_shift( ¤t_point , 0 , 1 ); - struct_vector_append( corner_list , ¤t_point ); + corner_list.push_back(current_point); { int cell_index = i + j*layer->nx; int_vector_append( cell_list , cell_index ); @@ -449,7 +458,7 @@ static bool layer_find_edge( const layer_type * layer , int *i , int *j , int va } -bool layer_trace_block_edge( const layer_type * layer , int start_i , int start_j , int value , struct_vector_type * corner_list , int_vector_type * cell_list) { +bool layer_trace_block_edge( const layer_type * layer , int start_i , int start_j , int value , std::vector& corner_list, int_vector_type * cell_list) { int g = layer_get_global_cell_index( layer , start_i , start_j); cell_type * cell = &layer->data[g]; if (cell->cell_value == value) { @@ -464,7 +473,7 @@ bool layer_trace_block_edge( const layer_type * layer , int start_i , int start_ start_corner.i = i; start_corner.j = j; - struct_vector_reset( corner_list ); + corner_list.clear(); int_vector_reset( cell_list ); diff --git a/ThirdParty/Ert/lib/ecl/nnc_info.cpp b/ThirdParty/Ert/lib/ecl/nnc_info.cpp index 3db9cf4c42..d520a985ae 100644 --- a/ThirdParty/Ert/lib/ecl/nnc_info.cpp +++ b/ThirdParty/Ert/lib/ecl/nnc_info.cpp @@ -1,25 +1,25 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'nnc_info.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'nnc_info.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include -#include -#include +#include +#include #include #include @@ -33,8 +33,8 @@ struct nnc_info_struct { UTIL_TYPE_ID_DECLARATION; vector_type * lgr_list; /*List of int vector * for nnc connections for LGRs*/ int_vector_type * lgr_index_map; /* A vector that maps LGR-nr to index into the LGR_list.*/ - int lgr_nr; /* The lgr_nr of the cell holding this nnc_info structure. */ -}; + int lgr_nr; /* The lgr_nr of the cell holding this nnc_info structure. */ +}; static void nnc_info_add_vector( nnc_info_type * nnc_info , nnc_vector_type * nnc_vector); UTIL_IS_INSTANCE_FUNCTION( nnc_info , NNC_INFO_TYPE_ID ) @@ -43,10 +43,10 @@ UTIL_IS_INSTANCE_FUNCTION( nnc_info , NNC_INFO_TYPE_ID ) nnc_info_type * nnc_info_alloc(int lgr_nr) { nnc_info_type * nnc_info = (nnc_info_type*)util_malloc( sizeof * nnc_info ); UTIL_TYPE_ID_INIT(nnc_info , NNC_INFO_TYPE_ID); - nnc_info->lgr_list = vector_alloc_new(); - nnc_info->lgr_index_map = int_vector_alloc(0, -1); + nnc_info->lgr_list = vector_alloc_new(); + nnc_info->lgr_index_map = int_vector_alloc(0, -1); nnc_info->lgr_nr = lgr_nr; - return nnc_info; + return nnc_info; } @@ -54,7 +54,7 @@ nnc_info_type * nnc_info_alloc(int lgr_nr) { nnc_info_type * nnc_info_alloc_copy( const nnc_info_type * src_info ) { nnc_info_type * copy_info = nnc_info_alloc( src_info->lgr_nr ); int ivec; - + for (ivec = 0; ivec < vector_get_size( src_info->lgr_list ); ivec++) { nnc_vector_type * copy_vector = nnc_vector_alloc_copy( (const nnc_vector_type*)vector_iget_const( src_info->lgr_list , ivec)); nnc_info_add_vector( copy_info , copy_vector ); @@ -67,30 +67,30 @@ nnc_info_type * nnc_info_alloc_copy( const nnc_info_type * src_info ) { bool nnc_info_equal( const nnc_info_type * nnc_info1 , const nnc_info_type * nnc_info2 ) { if (nnc_info1 == nnc_info2) return true; - + if ((nnc_info1 == NULL) || (nnc_info2 == NULL)) return false; { if (nnc_info1->lgr_nr != nnc_info2->lgr_nr) return false; - + if ((int_vector_size( nnc_info1->lgr_index_map ) > 0) && (int_vector_size( nnc_info2->lgr_index_map ) > 0)) { - int max_lgr_nr = util_int_max( int_vector_size( nnc_info1->lgr_index_map ), + int max_lgr_nr = util_int_max( int_vector_size( nnc_info1->lgr_index_map ), int_vector_size( nnc_info2->lgr_index_map ) ); int lgr_nr = 0; - + while (true) { nnc_vector_type * vector1 = nnc_info_get_vector( nnc_info1 , lgr_nr ); nnc_vector_type * vector2 = nnc_info_get_vector( nnc_info2 , lgr_nr ); - + if (!nnc_vector_equal(vector1 , vector2)) return false; - + lgr_nr++; if (lgr_nr > max_lgr_nr) return true; - } + } } else { if (int_vector_size( nnc_info1->lgr_index_map ) == int_vector_size( nnc_info2->lgr_index_map )) return true; @@ -102,9 +102,9 @@ bool nnc_info_equal( const nnc_info_type * nnc_info1 , const nnc_info_type * nnc void nnc_info_free( nnc_info_type * nnc_info ) { - vector_free(nnc_info->lgr_list); - int_vector_free(nnc_info->lgr_index_map); - free (nnc_info); + vector_free(nnc_info->lgr_list); + int_vector_free(nnc_info->lgr_index_map); + free (nnc_info); } nnc_vector_type * nnc_info_get_vector( const nnc_info_type * nnc_info , int lgr_nr) { @@ -148,9 +148,9 @@ void nnc_info_add_nnc(nnc_info_type * nnc_info, int lgr_nr, int global_cell_numb nnc_vector_add_nnc( nnc_vector , global_cell_number , nnc_index); } } - -const int_vector_type * nnc_info_get_grid_index_list(const nnc_info_type * nnc_info, int lgr_nr) { + +const int_vector_type * nnc_info_get_grid_index_list(const nnc_info_type * nnc_info, int lgr_nr) { nnc_vector_type * nnc_vector = nnc_info_get_vector( nnc_info , lgr_nr ); if (nnc_vector) return nnc_vector_get_grid_index_list( nnc_vector ); @@ -159,7 +159,7 @@ const int_vector_type * nnc_info_get_grid_index_list(const nnc_info_type * nnc_i } -const int_vector_type * nnc_info_iget_grid_index_list(const nnc_info_type * nnc_info, int lgr_index) { +const int_vector_type * nnc_info_iget_grid_index_list(const nnc_info_type * nnc_info, int lgr_index) { nnc_vector_type * nnc_vector = nnc_info_iget_vector( nnc_info , lgr_index ); if (nnc_vector) return nnc_vector_get_grid_index_list( nnc_vector ); @@ -169,7 +169,7 @@ const int_vector_type * nnc_info_iget_grid_index_list(const nnc_info_type * nnc_ -const int_vector_type * nnc_info_get_self_grid_index_list(const nnc_info_type * nnc_info) { +const int_vector_type * nnc_info_get_self_grid_index_list(const nnc_info_type * nnc_info) { return nnc_info_get_grid_index_list( nnc_info , nnc_info->lgr_nr ); } diff --git a/ThirdParty/Ert/lib/ecl/nnc_vector.cpp b/ThirdParty/Ert/lib/ecl/nnc_vector.cpp index 385fa91fe4..b808faa6e4 100644 --- a/ThirdParty/Ert/lib/ecl/nnc_vector.cpp +++ b/ThirdParty/Ert/lib/ecl/nnc_vector.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'nnc_vector.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'nnc_vector.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include -#include -#include +#include +#include #include #include @@ -36,7 +36,7 @@ struct nnc_vector_struct { int lgr_nr; int_vector_type * grid_index_list; int_vector_type * nnc_index_list; -}; +}; UTIL_IS_INSTANCE_FUNCTION( nnc_vector , NNC_VECTOR_TYPE_ID ) @@ -50,14 +50,14 @@ nnc_vector_type * nnc_vector_alloc(int lgr_nr) { nnc_vector->grid_index_list = int_vector_alloc(0,0); nnc_vector->nnc_index_list = int_vector_alloc(0,0); nnc_vector->lgr_nr = lgr_nr; - return nnc_vector; + return nnc_vector; } nnc_vector_type * nnc_vector_alloc_copy(const nnc_vector_type * src_vector) { nnc_vector_type * copy_vector = (nnc_vector_type*)util_malloc( sizeof * src_vector ); UTIL_TYPE_ID_INIT(copy_vector , NNC_VECTOR_TYPE_ID); - copy_vector->lgr_nr = src_vector->lgr_nr; + copy_vector->lgr_nr = src_vector->lgr_nr; copy_vector->grid_index_list = int_vector_alloc_copy( src_vector->grid_index_list ); copy_vector->nnc_index_list = int_vector_alloc_copy( src_vector->nnc_index_list ); return copy_vector; @@ -67,20 +67,20 @@ nnc_vector_type * nnc_vector_alloc_copy(const nnc_vector_type * src_vector) { bool nnc_vector_equal( const nnc_vector_type * nnc_vector1 , const nnc_vector_type * nnc_vector2) { if (nnc_vector1 == nnc_vector2) return true; - + if ((nnc_vector1 == NULL) || (nnc_vector2 == NULL)) return false; { if (nnc_vector1->lgr_nr != nnc_vector2->lgr_nr) return false; - + if (!int_vector_equal( nnc_vector1->grid_index_list , nnc_vector2->grid_index_list)) return false; - + if (!int_vector_equal( nnc_vector1->nnc_index_list , nnc_vector2->nnc_index_list)) return false; - + return true; } } @@ -89,7 +89,7 @@ bool nnc_vector_equal( const nnc_vector_type * nnc_vector1 , const nnc_vector_ty void nnc_vector_free( nnc_vector_type * nnc_vector ) { int_vector_free( nnc_vector->grid_index_list ); int_vector_free( nnc_vector->nnc_index_list ); - free( nnc_vector ); + free( nnc_vector ); } @@ -103,7 +103,7 @@ void nnc_vector_add_nnc(nnc_vector_type * nnc_vector, int global_cell_number , i int_vector_append( nnc_vector->grid_index_list , global_cell_number ); int_vector_append( nnc_vector->nnc_index_list , nnc_index); } - + const int_vector_type * nnc_vector_get_grid_index_list(const nnc_vector_type * nnc_vector) { return nnc_vector->grid_index_list; diff --git a/ThirdParty/Ert/lib/ecl/readme.overview b/ThirdParty/Ert/lib/ecl/readme.overview index 5b3c3dff52..7e395aaa73 100644 --- a/ThirdParty/Ert/lib/ecl/readme.overview +++ b/ThirdParty/Ert/lib/ecl/readme.overview @@ -3,10 +3,10 @@ functionalities. The different libraries depend on eachother, and the libraries must be built in correct order. The dependencies is as follows: -libhash : +libhash : libutil : libhash libecl : libhash libutil -librms : libecl libutil libhash +librms : libecl libutil libhash libsched : libecl linutil libhash libenkf : libecl libsched librm linutil libhash @@ -16,7 +16,7 @@ libhash: This library implements the classes hash_type, set_type and libutil: This library is a collection utility routines. Observe that this library only implements routines, and not statefull - objects. + objects. libecl: This library implements functions for reading/writing ECLIPSE restart/summary/init/grid files. @@ -27,7 +27,7 @@ librms: This library implements (basic) reader and writer for binary RMS ROFF files. libenkf: This library implements various high level objects for EnKF - functionality. + functionality. ----------------------------------------------------------------- diff --git a/ThirdParty/Ert/lib/ecl/smspec_node.cpp b/ThirdParty/Ert/lib/ecl/smspec_node.cpp index a59428f3fb..786dd87430 100644 --- a/ThirdParty/Ert/lib/ecl/smspec_node.cpp +++ b/ThirdParty/Ert/lib/ecl/smspec_node.cpp @@ -21,9 +21,12 @@ #include #include +#include +#include +#include + #include -#include -#include +#include #include #include #include @@ -36,7 +39,7 @@ #include #include - +#include "detail/util/string_util.hpp" /** @@ -52,25 +55,24 @@ struct smspec_node_struct { UTIL_TYPE_ID_DECLARATION; - char * wgname; /* The value of the WGNAMES vector for this element. */ - char * keyword; /* The value of the KEYWORDS vector for this elements. */ - char * unit; /* The value of the UNITS vector for this elements. */ + std::string wgname; + std::string keyword; /* The value of the KEYWORDS vector for this elements. */ + std::string unit; /* The value of the UNITS vector for this elements. */ int num; /* The value of the NUMS vector for this elements - NB this will have the value SMSPEC_NUMS_INVALID if the smspec file does not have a NUMS vector. */ - char * lgr_name; /* The lgr name of the current variable - will be NULL for non-lgr variables. */ - int * lgr_ijk; /* The (i,j,k) coordinate, in the local grid, if this is a LGR variable. WIll be NULL for no-lgr variables. */ + std::string lgr_name; /* The lgr name of the current variable - will be NULL for non-lgr variables. */ + std::array lgr_ijk; /*------------------------------------------- All members below this line are *derived* quantities. */ - char * gen_key1; /* The main composite key, i.e. WWCT:OP3 for this element. */ - char * gen_key2; /* Some of the ijk based elements will have both a xxx:i,j,k and a xxx:num key. Some of the region_2_region elements will have both a xxx:num and a xxx:r2-r2 key. Mostly NULL. */ + std::string gen_key1; /* The main composite key, i.e. WWCT:OP3 for this element. */ + std::string gen_key2; /* Some of the ijk based elements will have both a xxx:i,j,k and a xxx:num key. Some of the region_2_region elements will have both a xxx:num and a xxx:r2-r2 key. Mostly NULL. */ ecl_smspec_var_type var_type; /* The variable type */ - int * ijk; /* The ijk coordinates (NB: OFFSET 1) corresponding to the nums value - will be NULL if not relevant. */ + std::array ijk; /* The ijk coordinates (NB: OFFSET 1) corresponding to the nums value - will be NULL if not relevant. */ bool rate_variable; /* Is this a rate variable (i.e. WOPR) or a state variable (i.e. BPR). Relevant when doing time interpolation. */ bool total_variable; /* Is this a total variable like WOPT? */ bool historical; /* Does the name end with 'H'? */ int params_index; /* The index of this variable (applies to all the vectors - in particular the PARAMS vectors of the summary files *.Snnnn / *.UNSMRY ). */ float default_value; /* Default value for this variable. */ - bool valid; }; @@ -79,6 +81,22 @@ bool smspec_node_equal( const smspec_node_type * node1, const smspec_node_type return smspec_node_cmp( node1 , node2 ) == 0; } +static bool smspec_node_need_wgname(ecl_smspec_var_type var_type) { + if (var_type == ECL_SMSPEC_COMPLETION_VAR || + var_type == ECL_SMSPEC_GROUP_VAR || + var_type == ECL_SMSPEC_WELL_VAR || + var_type == ECL_SMSPEC_SEGMENT_VAR) + return true; + else + return false; +} + +static bool smspec_node_type_supported(ecl_smspec_var_type var_type) { + if (var_type == ECL_SMSPEC_NETWORK_VAR) + return false; + + return true; +} /*****************************************************************/ @@ -109,70 +127,64 @@ UTIL_SAFE_CAST_FUNCTION( smspec_node , SMSPEC_TYPE_ID ) static UTIL_SAFE_CAST_FUNCTION_CONST( smspec_node , SMSPEC_TYPE_ID ) -char * smspec_alloc_block_num_key( const char * join_string , const char * keyword , int num) { - return util_alloc_sprintf(ECL_SUM_KEYFMT_BLOCK_NUM, - keyword , +std::string smspec_alloc_block_num_key( const char * join_string , const std::string& keyword , int num) { + return ecl::util::string_format(ECL_SUM_KEYFMT_BLOCK_NUM, + keyword.c_str() , join_string , num ); } -char * smspec_alloc_aquifer_key( const char * join_string , const char * keyword , int num) { - return util_alloc_sprintf(ECL_SUM_KEYFMT_AQUIFER, - keyword , +std::string smspec_alloc_aquifer_key( const char * join_string , const std::string& keyword , int num) { + return ecl::util::string_format(ECL_SUM_KEYFMT_AQUIFER, + keyword.c_str(), join_string , num ); } -char * smspec_alloc_local_block_key( const char * join_string , const char * keyword , const char * lgr_name , int i , int j , int k) { - return util_alloc_sprintf(ECL_SUM_KEYFMT_LOCAL_BLOCK , - keyword , +std::string smspec_alloc_local_block_key( const char * join_string , const std::string& keyword , const std::string& lgr_name , int i , int j , int k) { + return ecl::util::string_format(ECL_SUM_KEYFMT_LOCAL_BLOCK , + keyword.c_str() , join_string , - lgr_name , + lgr_name.c_str() , join_string , i,j,k); } -char * smspec_alloc_region_key( const char * join_string , const char * keyword , int num) { - return util_alloc_sprintf(ECL_SUM_KEYFMT_REGION , - keyword , +std::string smspec_alloc_region_key( const char * join_string , const std::string& keyword , int num) { + return ecl::util::string_format(ECL_SUM_KEYFMT_REGION , + keyword.c_str(), join_string , num ); } -char * smspec_alloc_region_2_region_r1r2_key( const char * join_string , const char * keyword , int r1, int r2) { - return util_alloc_sprintf(ECL_SUM_KEYFMT_REGION_2_REGION_R1R2, - keyword, +std::string smspec_alloc_region_2_region_r1r2_key( const char * join_string , const std::string& keyword , int r1, int r2) { + return ecl::util::string_format(ECL_SUM_KEYFMT_REGION_2_REGION_R1R2, + keyword.c_str(), join_string, r1, r2); } -char * smspec_alloc_region_2_region_num_key( const char * join_string , const char * keyword , int num) { - return util_alloc_sprintf(ECL_SUM_KEYFMT_REGION_2_REGION_NUM, - keyword , +std::string smspec_alloc_region_2_region_num_key( const char * join_string , const std::string& keyword , int num) { + return ecl::util::string_format(ECL_SUM_KEYFMT_REGION_2_REGION_NUM, + keyword.c_str() , join_string , num); } -char * smspec_alloc_block_ijk_key( const char * join_string , const char * keyword , int i , int j , int k) { - return util_alloc_sprintf(ECL_SUM_KEYFMT_BLOCK_IJK , - keyword, - join_string , - i,j,k); -} -char * smspec_alloc_completion_ijk_key( const char * join_string , const char * keyword, const char * wgname , int i , int j , int k) { - if (wgname != NULL) - return util_alloc_sprintf( ECL_SUM_KEYFMT_COMPLETION_IJK , - keyword , +std::string smspec_alloc_completion_ijk_key( const char * join_string , const std::string& keyword, const std::string& wgname , int i , int j , int k) { + if (wgname.size() > 0) + return ecl::util::string_format( ECL_SUM_KEYFMT_COMPLETION_IJK , + keyword.c_str() , join_string , - wgname , + wgname.c_str(), join_string , i , j , k ); else @@ -181,12 +193,12 @@ char * smspec_alloc_completion_ijk_key( const char * join_string , const char * -char * smspec_alloc_completion_num_key( const char * join_string , const char * keyword, const char * wgname , int num) { - if (wgname != NULL) - return util_alloc_sprintf(ECL_SUM_KEYFMT_COMPLETION_NUM, - keyword , +std::string smspec_alloc_completion_num_key( const char * join_string , const std::string& keyword, const std::string& wgname , int num) { + if (wgname.size() > 0) + return ecl::util::string_format(ECL_SUM_KEYFMT_COMPLETION_NUM, + keyword.c_str() , join_string , - wgname , + wgname.c_str() , join_string , num ); else @@ -197,33 +209,59 @@ char * smspec_alloc_completion_num_key( const char * join_string , const char * To support ECLIPSE behaviour where new wells/groups can be created during the simulation it must be possible to create a smspec node with an initially unknown well/group name; all gen_key formats which - use the wgname value must therefore accept a NULL value for wgname. + use the wgname value must therefore accept a NULL value for wgname. HMM: Uncertain about this? */ -static char * smspec_alloc_wgname_key( const char * join_string , const char * keyword , const char * wgname) { - if (wgname != NULL) - return util_alloc_sprintf(ECL_SUM_KEYFMT_WELL, - keyword , - join_string , - wgname ); +static std::string smspec_alloc_wgname_key( const char * join_string , const std::string& keyword , const std::string& wgname) { + if (wgname.size() > 0) + return ecl::util::string_format(ECL_SUM_KEYFMT_WELL, + keyword.c_str() , + join_string , + wgname.c_str() ); else - return NULL; + return ""; } -char * smspec_alloc_group_key( const char * join_string , const char * keyword , const char * wgname) { +std::string smspec_alloc_group_key( const char * join_string , const std::string& keyword , const std::string& wgname) { return smspec_alloc_wgname_key( join_string , keyword , wgname ); } -char * smspec_alloc_well_key( const char * join_string , const char * keyword , const char * wgname) { +std::string smspec_alloc_well_key( const char * join_string , const std::string& keyword , const std::string& wgname) { return smspec_alloc_wgname_key( join_string , keyword , wgname ); } -char * smspec_alloc_segment_key( const char * join_string , const char * keyword , const char * wgname , int num) { - if (wgname != NULL) - return util_alloc_sprintf(ECL_SUM_KEYFMT_SEGMENT , - keyword , + +/* + The smspec_alloc_well_key and smspec_alloc_block_ijk_key() require C linkage due to external use. +*/ + +char * smspec_alloc_well_key( const char * join_string , const char * keyword , const char * wgname) { + return util_alloc_sprintf( ECL_SUM_KEYFMT_WELL, + keyword, + join_string, + wgname); +} + +char * smspec_alloc_block_ijk_key( const char * join_string , const char * keyword , int i , int j , int k) { + return util_alloc_sprintf(ECL_SUM_KEYFMT_BLOCK_IJK, + keyword, + join_string, + i,j,k); +} + +std::string smspec_alloc_block_ijk_key( const char * join_string , const std::string& keyword , int i , int j , int k) { + return ecl::util::string_format(ECL_SUM_KEYFMT_BLOCK_IJK , + keyword.c_str(), + join_string , + i,j,k); +} + +std::string smspec_alloc_segment_key( const char * join_string , const std::string& keyword , const std::string& wgname , int num) { + if (wgname.size() > 0) + return ecl::util::string_format(ECL_SUM_KEYFMT_SEGMENT , + keyword.c_str() , join_string , - wgname , + wgname.c_str(), join_string , num ); else @@ -231,26 +269,26 @@ char * smspec_alloc_segment_key( const char * join_string , const char * keyword } -char * smspec_alloc_local_well_key( const char * join_string , const char * keyword , const char * lgr_name , const char * wgname) { - if (wgname != NULL) - return util_alloc_sprintf( ECL_SUM_KEYFMT_LOCAL_WELL , - keyword , +std::string smspec_alloc_local_well_key( const char * join_string , const std::string& keyword , const std::string& lgr_name , const std::string& wgname) { + if (wgname.size() > 0) + return ecl::util::string_format( ECL_SUM_KEYFMT_LOCAL_WELL , + keyword.c_str() , join_string , - lgr_name , + lgr_name.c_str() , join_string , - wgname); + wgname.c_str()); else return NULL; } -char * smspec_alloc_local_completion_key( const char * join_string, const char * keyword , const char * lgr_name , const char * wgname , int i , int j , int k) { - if (wgname != NULL) - return util_alloc_sprintf(ECL_SUM_KEYFMT_LOCAL_COMPLETION , - keyword , +std::string smspec_alloc_local_completion_key( const char * join_string, const std::string& keyword , const std::string& lgr_name , const std::string& wgname , int i , int j , int k) { + if (wgname.size() > 0) + return ecl::util::string_format(ECL_SUM_KEYFMT_LOCAL_COMPLETION , + keyword.c_str(), join_string , - lgr_name , + lgr_name.c_str() , join_string , - wgname , + wgname.c_str(), join_string , i,j,k); else @@ -259,12 +297,12 @@ char * smspec_alloc_local_completion_key( const char * join_string, const char * /*****************************************************************/ -static void smspec_node_set_keyword( smspec_node_type * smspec_node , const char * keyword ) { +static void smspec_node_set_keyword( smspec_node_type * smspec_node , const std::string& keyword ) { // ECLIPSE Standard: Max eight characters - everything beyond is silently dropped // This function can __ONLY__ be called on time; run-time chaning of keyword is not // allowed. - if (smspec_node->keyword == NULL) - smspec_node->keyword = util_alloc_substring_copy( keyword , 0 , 8); + if (smspec_node->keyword.size() == 0) + smspec_node->keyword = keyword; else util_abort("%s: fatal error - attempt to change keyword runtime detected - aborting\n",__func__); } @@ -274,39 +312,28 @@ static void smspec_node_set_invalid_flags( smspec_node_type * smspec_node) { smspec_node->rate_variable = false; smspec_node->total_variable = false; smspec_node->historical = false; - smspec_node->valid = false; } -static char LAST_CHAR(const char * s) { - return s[ strlen(s) - 1]; -} -static void smspec_node_set_flags( smspec_node_type * smspec_node) { - /* - Check if this is a rate variabel - that info is used when - interpolating results to true_time between ministeps. - */ - { - const char *rate_vars[] = {"OPR" , "GPR" , "WPR" , "GOR" , "WCT"}; - int num_rate_vars = sizeof( rate_vars ) / sizeof( rate_vars[0] ); - bool is_rate = false; - int ivar; - for (ivar = 0; ivar < num_rate_vars; ivar++) { - const char * var_substring = &smspec_node->keyword[1]; - if (strncmp( rate_vars[ivar] , var_substring , strlen( rate_vars[ivar] )) == 0) { - is_rate = true; - break; - } + +bool smspec_node_identify_rate(const char * keyword) { + const char *rate_vars[] = {"OPR" , "GPR" , "WPR" , "LPR", "OIR", "GIR", "WIR", "LIR", "GOR" , "WCT"}; + int num_rate_vars = sizeof( rate_vars ) / sizeof( rate_vars[0] ); + bool is_rate = false; + int ivar; + for (ivar = 0; ivar < num_rate_vars; ivar++) { + const char * var_substring = &keyword[1]; + if (strncmp( rate_vars[ivar] , var_substring , strlen( rate_vars[ivar] )) == 0) { + is_rate = true; + break; } - smspec_node->rate_variable = is_rate; } + return is_rate; +} - { - if (LAST_CHAR(smspec_node->keyword) == 'H') - smspec_node->historical = true; - } - /* +bool smspec_node_identify_total(const char * keyword, ecl_smspec_var_type var_type) { + /* This code checks in a predefined list whether a certain WGNAMES variable represents a total accumulated quantity. Only the last three characters in the variable is considered (i.e. the leading 'W', 'G' or @@ -316,34 +343,45 @@ static void smspec_node_set_flags( smspec_node_type * smspec_node) { the tables 2.7 - 2.11 in the ECLIPSE fileformat documentation. Have skipped some of the most exotic keywords. */ - { - bool is_total = false; - if (smspec_node->var_type == ECL_SMSPEC_WELL_VAR || - smspec_node->var_type == ECL_SMSPEC_GROUP_VAR || - smspec_node->var_type == ECL_SMSPEC_FIELD_VAR || - smspec_node->var_type == ECL_SMSPEC_REGION_VAR || - smspec_node->var_type == ECL_SMSPEC_COMPLETION_VAR ) { - const char *total_vars[] = {"OPT" , "GPT" , "WPT" , "GIT", "WIT", "OPTF" , "OPTS" , "OIT" , "OVPT" , "OVIT" , "MWT" , - "WVPT" , "WVIT" , "GMT" , "GPTF" , "SGT" , "GST" , "FGT" , "GCT" , "GIMT" , - "WGPT" , "WGIT" , "EGT" , "EXGT" , "GVPT" , "GVIT" , "LPT" , "VPT" , "VIT" , "NPT" , "NIT"}; - - int num_total_vars = sizeof( total_vars ) / sizeof( total_vars[0] ); - int ivar; - for (ivar = 0; ivar < num_total_vars; ivar++) { - const char * var_substring = &smspec_node->keyword[1]; - /* - We want to mark both FOPT and FOPTH as historical variables; - we use strncmp() to make certain that the trailing 'H' is - not included in the comparison. - */ - if (strncmp( total_vars[ivar] , var_substring , strlen( total_vars[ivar] )) == 0) { - is_total = true; - break; - } + bool is_total = false; + if (var_type == ECL_SMSPEC_WELL_VAR || + var_type == ECL_SMSPEC_GROUP_VAR || + var_type == ECL_SMSPEC_FIELD_VAR || + var_type == ECL_SMSPEC_REGION_VAR || + var_type == ECL_SMSPEC_COMPLETION_VAR ) { + const char *total_vars[] = {"OPT" , "GPT" , "WPT" , "GIT", "WIT", "OPTF" , "OPTS" , "OIT" , "OVPT" , "OVIT" , "MWT" , + "WVPT" , "WVIT" , "GMT" , "GPTF" , "SGT" , "GST" , "FGT" , "GCT" , "GIMT" , + "WGPT" , "WGIT" , "EGT" , "EXGT" , "GVPT" , "GVIT" , "LPT" , "VPT" , "VIT" , "NPT" , "NIT", + "CPT", "CIT"}; + + int num_total_vars = sizeof( total_vars ) / sizeof( total_vars[0] ); + int ivar; + for (ivar = 0; ivar < num_total_vars; ivar++) { + const char * var_substring = &keyword[1]; + /* + We want to mark both FOPT and FOPTH as total variables; + we use strncmp() to make certain that the trailing 'H' is + not included in the comparison. + */ + if (strncmp( total_vars[ivar] , var_substring , strlen( total_vars[ivar] )) == 0) { + is_total = true; + break; } } - smspec_node->total_variable = is_total; } + return is_total; +} + + +static void smspec_node_set_flags( smspec_node_type * smspec_node) { + /* + Check if this is a rate variabel - that info is used when + interpolating results to true_time between ministeps. + */ + smspec_node->rate_variable = smspec_node_identify_rate(smspec_node->keyword.c_str()); + if (smspec_node->keyword.back() == 'H') + smspec_node->historical = true; + smspec_node->total_variable = smspec_node_identify_total(smspec_node->keyword.c_str(), smspec_node->var_type); } /** @@ -363,49 +401,30 @@ float smspec_node_get_default( const smspec_node_type * smspec_node ) { smspec_node_type * smspec_node_alloc_new(int params_index, float default_value) { - smspec_node_type * node = (smspec_node_type*)util_malloc( sizeof * node ); + smspec_node_type * node = new smspec_node_type(); UTIL_TYPE_ID_INIT( node , SMSPEC_TYPE_ID); node->params_index = params_index; smspec_node_set_default( node , default_value ); - node->wgname = NULL; - node->ijk = NULL; - - node->gen_key1 = NULL; - node->gen_key2 = NULL; - node->var_type = ECL_SMSPEC_INVALID_VAR; - node->unit = NULL; - node->keyword = NULL; - node->lgr_name = NULL; - node->lgr_ijk = NULL; - smspec_node_set_invalid_flags( node ); return node; // This is NOT usable } static void smspec_node_set_wgname( smspec_node_type * index , const char * wgname ) { - if (wgname == NULL) { - util_safe_free( index->wgname ); - index->wgname = NULL; - } else { - index->wgname = util_realloc_string_copy(index->wgname , wgname ); - } + index->wgname = wgname; } -static void smspec_node_set_lgr_name( smspec_node_type * index , const char * lgr_name ) { - index->lgr_name = util_realloc_string_copy(index->lgr_name , lgr_name); +static void smspec_node_set_lgr_name( smspec_node_type * index , const std::string& lgr_name ) { + index->lgr_name = lgr_name; } static void smspec_node_set_lgr_ijk( smspec_node_type * index , int lgr_i , int lgr_j , int lgr_k) { - if (index->lgr_ijk == NULL) - index->lgr_ijk = (int*)util_calloc( 3 , sizeof * index->lgr_ijk ); - index->lgr_ijk[0] = lgr_i; index->lgr_ijk[1] = lgr_j; index->lgr_ijk[2] = lgr_k; @@ -434,8 +453,6 @@ static void smspec_node_set_num( smspec_node_type * index , const int grid_dims[ index->num = num; if ((index->var_type == ECL_SMSPEC_COMPLETION_VAR) || (index->var_type == ECL_SMSPEC_BLOCK_VAR)) { int global_index = num - 1; - index->ijk = (int*)util_calloc( 3 , sizeof * index->ijk ); - index->ijk[2] = global_index / ( grid_dims[0] * grid_dims[1] ); global_index -= index->ijk[2] * (grid_dims[0] * grid_dims[1]); index->ijk[1] = global_index / grid_dims[0] ; global_index -= index->ijk[1] * grid_dims[0]; index->ijk[0] = global_index; @@ -477,7 +494,7 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha break; case(ECL_SMSPEC_FIELD_VAR): // KEYWORD - smspec_node->gen_key1 = util_alloc_string_copy( smspec_node->keyword ); + smspec_node->gen_key1 = util_alloc_string_copy( smspec_node->keyword.c_str() ); break; case(ECL_SMSPEC_GROUP_VAR): // KEYWORD:WGNAME @@ -507,7 +524,7 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha case(ECL_SMSPEC_MISC_VAR): // KEYWORD /* Misc variable - i.e. date or CPU time ... */ - smspec_node->gen_key1 = util_alloc_string_copy( smspec_node->keyword ); + smspec_node->gen_key1 = smspec_node->keyword; break; case(ECL_SMSPEC_BLOCK_VAR): // KEYWORD:NUM @@ -544,21 +561,13 @@ static void smspec_node_set_gen_keys( smspec_node_type * smspec_node , const cha default: util_abort("%s: internal error - should not be here? \n" , __func__); } - smspec_node->valid = true; } -void smspec_node_update_wgname( smspec_node_type * index , const char * wgname , const char * key_join_string) { - smspec_node_set_wgname( index , wgname ); - util_safe_free( index->gen_key1 ); - util_safe_free( index->gen_key2 ); - smspec_node_set_gen_keys( index , key_join_string ); -} - -static void smspec_node_common_init( smspec_node_type * node , ecl_smspec_var_type var_type , const char * keyword , const char * unit ) { +static void smspec_node_common_init( smspec_node_type * node , ecl_smspec_var_type var_type , const char * keyword , const std::string& unit ) { if (node->var_type == ECL_SMSPEC_INVALID_VAR) { - smspec_node_set_unit( node , unit ); + smspec_node_set_unit( node , unit.c_str() ); smspec_node_set_keyword( node , keyword); node->var_type = var_type; smspec_node_set_flags( node ); @@ -568,22 +577,16 @@ static void smspec_node_common_init( smspec_node_type * node , ecl_smspec_var_ty } -/* - This *should* become static. -*/ -void smspec_node_init( smspec_node_type * smspec_node, - ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * key_join_string , - const int grid_dims[3] , - int num) { +static bool smspec_node_init__( smspec_node_type * smspec_node, + ecl_smspec_var_type var_type , + const char * wgname , + const char * keyword , + const char * unit , + const char * key_join_string , + const int grid_dims[3] , + int num) { bool initOK = true; - bool wgnameOK = true; - if ((wgname != NULL) && (IS_DUMMY_WELL(wgname))) - wgnameOK = false; smspec_node_common_init( smspec_node , var_type , keyword , unit ); switch (var_type) { @@ -591,23 +594,21 @@ void smspec_node_init( smspec_node_type * smspec_node, /* Completion variable : WGNAME & NUM */ smspec_node_set_num( smspec_node , grid_dims , num ); smspec_node_set_wgname( smspec_node , wgname ); - if (!wgnameOK || num < 0) + if (num < 0) initOK = false; break; case(ECL_SMSPEC_GROUP_VAR): /* Group variable : WGNAME */ smspec_node_set_wgname( smspec_node , wgname ); - initOK = wgnameOK; break; case(ECL_SMSPEC_WELL_VAR): /* Well variable : WGNAME */ smspec_node_set_wgname( smspec_node , wgname ); - initOK = wgnameOK; break; case(ECL_SMSPEC_SEGMENT_VAR): smspec_node_set_wgname( smspec_node , wgname ); smspec_node_set_num( smspec_node , grid_dims , num ); - if (!wgnameOK || num < 0) + if (num < 0) initOK = false; break; case(ECL_SMSPEC_FIELD_VAR): @@ -654,6 +655,31 @@ void smspec_node_init( smspec_node_type * smspec_node, if (initOK) smspec_node_set_gen_keys( smspec_node , key_join_string ); + + return initOK; +} + +/* + This function should be removed from the public API. +*/ +void smspec_node_init( smspec_node_type * smspec_node, + ecl_smspec_var_type var_type , + const char * wgname , + const char * keyword , + const char * unit , + const char * key_join_string , + const int grid_dims[3] , + int num) { + + smspec_node_init__(smspec_node, + var_type, + wgname, + keyword, + unit, + key_join_string, + grid_dims, + num); + } /** @@ -673,12 +699,12 @@ void smspec_node_init( smspec_node_type * smspec_node, smspec_node_type * smspec_node_alloc( ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * key_join_string , - const int grid_dims[3] , - int num , int param_index, float default_value) { + const char * wgname , + const char * keyword , + const char * unit , + const char * key_join_string , + const int grid_dims[3] , + int num , int param_index, float default_value) { /* Well and group names in the wgname parameter is quite messy. The situation is as follows: @@ -709,8 +735,22 @@ smspec_node_type * smspec_node_alloc( ecl_smspec_var_type var_type , completely. */ + if (smspec_node_need_wgname(var_type) && IS_DUMMY_WELL(wgname)) + return NULL; + + if (!smspec_node_type_supported(var_type)) + return NULL; + + /* + TODO: The alloc_new and init functions should be joined in one function. + */ smspec_node_type * smspec_node = smspec_node_alloc_new( param_index , default_value ); - smspec_node_init( smspec_node , var_type , wgname , keyword , unit , key_join_string , grid_dims, num); + bool initOK = smspec_node_init__( smspec_node , var_type , wgname , keyword , unit , key_join_string , grid_dims, num); + if (!initOK) { + smspec_node_free(smspec_node); + smspec_node = NULL; + } + return smspec_node; } @@ -776,30 +816,19 @@ smspec_node_type* smspec_node_alloc_copy( const smspec_node_type* node ) { if( !node ) return NULL; { - smspec_node_type* copy = (smspec_node_type*)util_malloc( sizeof * copy ); + smspec_node_type * copy = new smspec_node_type(); UTIL_TYPE_ID_INIT( copy, SMSPEC_TYPE_ID ); - copy->gen_key1 = util_alloc_string_copy( node->gen_key1 ); - copy->gen_key2 = util_alloc_string_copy( node->gen_key2 ); + copy->gen_key1 = node->gen_key1; + copy->gen_key2 = node->gen_key2; copy->var_type = node->var_type; - copy->wgname = util_alloc_string_copy( node->wgname ); - copy->keyword = util_alloc_string_copy( node->keyword ); - copy->unit = util_alloc_string_copy( node->unit ); + copy->wgname = node->wgname; + copy->keyword = node->keyword; + copy->unit = node->unit; copy->num = node->num; + copy->ijk = node->ijk; + copy->lgr_name = node->lgr_name; + copy->lgr_ijk = node->lgr_ijk; - copy->ijk = NULL; - if( node->ijk ) { - copy->ijk = (int*)util_calloc( 3 , sizeof * node->ijk ); - memcpy( copy->ijk, node->ijk, 3 * sizeof( * node->ijk ) ); - } - - copy->lgr_name = util_alloc_string_copy( node->lgr_name ); - copy->lgr_ijk = NULL; - if( node->lgr_ijk ) { - copy->lgr_ijk = (int*)util_calloc( 3 , sizeof * node->lgr_ijk ); - memcpy( copy->lgr_ijk, node->lgr_ijk, 3 * sizeof( * node->lgr_ijk ) ); - } - - copy->valid = node->valid; copy->rate_variable = node->rate_variable; copy->total_variable = node->total_variable; copy->historical = node->historical; @@ -810,15 +839,7 @@ smspec_node_type* smspec_node_alloc_copy( const smspec_node_type* node ) { } void smspec_node_free( smspec_node_type * index ) { - util_safe_free( index->unit ); - util_safe_free( index->keyword ); - util_safe_free( index->ijk ); - util_safe_free( index->gen_key1 ); - util_safe_free( index->gen_key2 ); - util_safe_free( index->wgname ); - util_safe_free( index->lgr_name ); - util_safe_free( index->lgr_ijk ); - free( index ); + delete index; } void smspec_node_free__( void * arg ) { @@ -840,21 +861,33 @@ void smspec_node_set_params_index( smspec_node_type * smspec_node , int params_i smspec_node->params_index = params_index; } + +namespace { + + const char * get_cstring(const std::string& s) { + if (s.empty()) + return NULL; + else + return s.c_str(); + } + +} + const char * smspec_node_get_gen_key1( const smspec_node_type * smspec_node) { - return smspec_node->gen_key1; + return get_cstring( smspec_node->gen_key1 ); } const char * smspec_node_get_gen_key2( const smspec_node_type * smspec_node) { - return smspec_node->gen_key2; + return get_cstring( smspec_node->gen_key2 ); } const char * smspec_node_get_wgname( const smspec_node_type * smspec_node) { - return smspec_node->wgname; + return get_cstring( smspec_node->wgname ); } const char * smspec_node_get_keyword( const smspec_node_type * smspec_node) { - return smspec_node->keyword; + return get_cstring( smspec_node->keyword ); } @@ -880,36 +913,29 @@ bool smspec_node_is_historical( const smspec_node_type * smspec_node ){ return smspec_node->historical; } - -bool smspec_node_is_valid( const smspec_node_type * smspec_node ){ - return smspec_node->valid; -} - - const char * smspec_node_get_unit( const smspec_node_type * smspec_node) { - return smspec_node->unit; + return smspec_node->unit.c_str(); } -void smspec_node_set_unit( smspec_node_type * smspec_node , const char * unit ) { +void smspec_node_set_unit( smspec_node_type * smspec_node , const char * unit) { // ECLIPSE Standard: Max eight characters - everything beyond is silently dropped - util_safe_free( smspec_node->unit ); - smspec_node->unit = util_alloc_substring_copy( unit , 0 , 8); + std::string tmp = unit; + smspec_node->unit = tmp.substr(0,8); } - -// Will be NULL for smspec_nodes which do not have i,j,k +// Will be garbage for smspec_nodes which do not have i,j,k const int* smspec_node_get_ijk( const smspec_node_type * smspec_node ) { - return smspec_node->ijk; + return smspec_node->ijk.data(); } // Will be NULL for smspec_nodes which are not related to an LGR. const char* smspec_node_get_lgr_name( const smspec_node_type * smspec_node ) { - return smspec_node->lgr_name; + return smspec_node->lgr_name.c_str(); } -// Will be NULL for smspec_nodes which are not related to an LGR. +// Will be garbage for smspec_nodes which are not related to an LGR. const int* smspec_node_get_lgr_ijk( const smspec_node_type * smspec_node ) { - return smspec_node->lgr_ijk; + return smspec_node->lgr_ijk.data(); } /* @@ -961,14 +987,16 @@ bool smspec_node_need_nums( const smspec_node_type * smspec_node ) { void smspec_node_fprintf( const smspec_node_type * smspec_node , FILE * stream) { - fprintf(stream, "KEYWORD: %s \n",smspec_node->keyword); - fprintf(stream, "WGNAME : %s \n",smspec_node->wgname); - fprintf(stream, "UNIT : %s \n",smspec_node->unit); + fprintf(stream, "KEYWORD: %s \n",smspec_node->keyword.c_str()); + fprintf(stream, "WGNAME : %s \n",smspec_node->wgname.c_str()); + fprintf(stream, "UNIT : %s \n",smspec_node->unit.c_str()); + fprintf(stream, "TYPE : %d \n",smspec_node->var_type); + fprintf(stream, "NUM : %d \n\n",smspec_node->num); } static bool smspec_node_equal_MISC( const smspec_node_type * node1, const smspec_node_type * node2) { - return util_string_equal( node1->keyword , node2->keyword); + return node1->keyword == node2->keyword; } @@ -978,34 +1006,22 @@ static bool smspec_node_equal_MISC( const smspec_node_type * node1, const smspec */ static int smspec_node_cmp_MISC( const smspec_node_type * node1, const smspec_node_type * node2) { - static const char* early_vars[] = {"TIME", - "DAYS", - "DAY", - "MONTH", - "YEAR", - "YEARS"}; + static const std::set early_vars = {"TIME", "DAYS", "DAY", "MONTH", "YEAR", "YEARS"}; if (smspec_node_equal_MISC( node1, node2) ) return 0; - bool node1_early = false; - bool node2_early = false; - - for (int i=0; i < 6; i++) { - if (util_string_equal( node1->keyword, early_vars[i] )) - node1_early = true; + bool node1_early = !( early_vars.find(node1->keyword) == early_vars.end() ); + bool node2_early = !( early_vars.find(node2->keyword) == early_vars.end() ); - if (util_string_equal( node2->keyword, early_vars[i] )) - node2_early = true; - } if (node1_early && !node2_early) return -1; if (!node1_early && node2_early) return 1; - return strcmp( node1->keyword, node2->keyword); + return node1->keyword.compare(node2->keyword); } @@ -1033,11 +1049,11 @@ static int smspec_node_cmp_LGRIJK( const smspec_node_type * node1, const smspec_ static int smspec_node_cmp_KEYWORD_LGR_LGRIJK( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = strcmp( node1->keyword , node2->keyword); + int keyword_cmp = node1->keyword.compare(node2->keyword); if (keyword_cmp != 0) return keyword_cmp; - int lgr_cmp = strcmp( node1->lgr_name , node2->lgr_name); + int lgr_cmp = node1->lgr_name.compare( node2->lgr_name ); if (lgr_cmp != 0) return lgr_cmp; @@ -1046,11 +1062,11 @@ static int smspec_node_cmp_KEYWORD_LGR_LGRIJK( const smspec_node_type * node1, c static int smspec_node_cmp_KEYWORD_WGNAME_NUM( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = strcmp( node1->keyword , node2->keyword); + int keyword_cmp = node1->keyword.compare(node2->keyword); if (keyword_cmp != 0) return keyword_cmp; - int wgname_cmp = strcmp( node1->wgname , node2->wgname); + int wgname_cmp = node1->wgname.compare(node2->wgname); if (wgname_cmp != 0) return wgname_cmp; @@ -1058,28 +1074,28 @@ static int smspec_node_cmp_KEYWORD_WGNAME_NUM( const smspec_node_type * node1, c } static int smspec_node_cmp_KEYWORD_WGNAME_LGR( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = strcmp( node1->keyword , node2->keyword); + int keyword_cmp = node1->keyword.compare(node2->keyword); if (keyword_cmp != 0) return keyword_cmp; - int wgname_cmp = strcmp( node1->wgname , node2->wgname); + int wgname_cmp = node1->wgname.compare(node2->wgname); if (wgname_cmp != 0) return wgname_cmp; - return strcmp( node1->lgr_name , node2->lgr_name); + return node1->lgr_name.compare(node2->lgr_name); } static int smspec_node_cmp_KEYWORD_WGNAME_LGR_LGRIJK( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = strcmp( node1->keyword , node2->keyword); + int keyword_cmp = node1->keyword.compare(node2->keyword); if (keyword_cmp != 0) return keyword_cmp; - int wgname_cmp = strcmp( node1->wgname , node2->wgname); + int wgname_cmp = node1->wgname.compare(node2->wgname); if (wgname_cmp != 0) return wgname_cmp; - int lgr_cmp = strcmp( node1->lgr_name , node2->lgr_name); + int lgr_cmp = node1->lgr_name.compare(node2->lgr_name); if (lgr_cmp != 0) return lgr_cmp; @@ -1090,26 +1106,26 @@ static int smspec_node_cmp_KEYWORD_WGNAME_LGR_LGRIJK( const smspec_node_type * n static int smspec_node_cmp_KEYWORD_WGNAME( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = strcmp( node1->keyword , node2->keyword); + int keyword_cmp = node1->keyword.compare(node2->keyword); if (keyword_cmp != 0) return keyword_cmp; - if (IS_DUMMY_WELL( node1->wgname )) { - if (IS_DUMMY_WELL( node2->wgname )) + if (IS_DUMMY_WELL( node1->wgname.c_str() )) { + if (IS_DUMMY_WELL( node2->wgname.c_str() )) return 0; else return 1; } - if (IS_DUMMY_WELL( node2->wgname )) + if (IS_DUMMY_WELL( node2->wgname.c_str() )) return -1; - return strcmp( node1->wgname , node2->wgname); + return node1->wgname.compare(node2->wgname); } static int smspec_node_cmp_KEYWORD_NUM( const smspec_node_type * node1, const smspec_node_type * node2) { - int keyword_cmp = strcmp( node1->keyword , node2->keyword); + int keyword_cmp = node1->keyword.compare(node2->keyword); if (keyword_cmp != 0) return keyword_cmp; @@ -1118,19 +1134,19 @@ static int smspec_node_cmp_KEYWORD_NUM( const smspec_node_type * node1, const sm static int smspec_node_cmp_KEYWORD( const smspec_node_type * node1, const smspec_node_type * node2) { - return strcmp( node1->keyword , node2->keyword ); + return node1->keyword.compare(node2->keyword); } static int smspec_node_cmp_key1( const smspec_node_type * node1, const smspec_node_type * node2) { - if (!node1->gen_key1) { - if (!node2->gen_key1) + if (node1->gen_key1.empty()) { + if (node2->gen_key1.empty()) return 0; else return -1; - } else if (!node2->gen_key1) { + } else if (node2->gen_key1.empty()) { return 1; } - return util_strcmp_int( node1->gen_key1 , node2->gen_key1 ); + return util_strcmp_int( node1->gen_key1.c_str() , node2->gen_key1.c_str() ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/data/num_cpu3 b/ThirdParty/Ert/lib/ecl/tests/data/num_cpu3 index d5decfa953..ab5263e4ce 100644 --- a/ThirdParty/Ert/lib/ecl/tests/data/num_cpu3 +++ b/ThirdParty/Ert/lib/ecl/tests/data/num_cpu3 @@ -6,4 +6,4 @@ SLAVES -- "slaves token" position doesn't brake parsing -- Testing comments in middle 'RES-R5' 'base' 'sg-indigo' '/usr/models/res5' 10 / - /testRubbish -- this line also counts \ No newline at end of file + /testRubbish -- this line also counts diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_cpgrid.c b/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_cpgrid.cpp similarity index 95% rename from ThirdParty/Ert/lib/ecl/tests/ecl_alloc_cpgrid.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_alloc_cpgrid.cpp index e9417f887b..f3c1ac4e44 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_cpgrid.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_cpgrid.cpp @@ -20,11 +20,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include void test_grid(int nx, int ny, int nz) { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.c b/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.cpp similarity index 96% rename from ThirdParty/Ert/lib/ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.cpp index 8cc42aedd7..9992680f74 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_alloc_grid_dxv_dyv_dzv.cpp @@ -20,8 +20,8 @@ #include #include -#include -#include +#include +#include void test_grid() { const int nx = 5, ny = 6, nz = 7; diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_coarse_test.c b/ThirdParty/Ert/lib/ecl/tests/ecl_coarse_test.cpp similarity index 84% rename from ThirdParty/Ert/lib/ecl/tests/ecl_coarse_test.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_coarse_test.cpp index 45f4186a15..d1882092cd 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_coarse_test.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_coarse_test.cpp @@ -1,29 +1,29 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ecl_coarse_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ecl_coarse_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include @@ -40,13 +40,13 @@ void test_coarse_cell(const ecl_grid_type * grid , ecl_coarse_cell_type * cell ) /* The coordinates are right */ ecl_grid_get_ijk1( grid , gi , &i , &j , &k); if ((i < ijk[0]) || (i > ijk[1])) - test_error_exit("i:%d not inside range [%d,%d] \n",i , ijk[0] , ijk[1]); + test_error_exit("i:%d not inside range [%d,%d] \n",i , ijk[0] , ijk[1]); if ((j < ijk[2]) || (j > ijk[3])) - test_error_exit("j:%d not inside range [%d,%d] \n",j , ijk[2] , ijk[3]); + test_error_exit("j:%d not inside range [%d,%d] \n",j , ijk[2] , ijk[3]); if ((k < ijk[4]) || (k > ijk[5])) - test_error_exit("k:%d not inside range [%d,%d] \n",k , ijk[4] , ijk[4]); + test_error_exit("k:%d not inside range [%d,%d] \n",k , ijk[4] , ijk[4]); if (c == 0) prev_active = ecl_grid_get_active_index1( grid , gi ); @@ -67,7 +67,7 @@ int main(int argc , char ** argv) { char * egrid_file = ecl_util_alloc_filename( NULL , case_path , ECL_EGRID_FILE , false , 0 ); char * rst_file = ecl_util_alloc_filename( NULL , case_path , ECL_RESTART_FILE , false , 0 ); char * init_file = ecl_util_alloc_filename( NULL , case_path , ECL_INIT_FILE , false , 0 ); - + ecl_grid_type * GRID = ecl_grid_alloc(egrid_file ); ecl_file_type * RST_file = ecl_file_open( rst_file , 0); ecl_file_type * INIT_file = ecl_file_open( init_file , 0); @@ -80,11 +80,11 @@ int main(int argc , char ** argv) { { const ecl_kw_type * swat0 = ecl_file_iget_named_kw( RST_file , "SWAT" , 0 ); const ecl_kw_type * porv = ecl_file_iget_named_kw( INIT_file , "PORV" , 0 ); - + test_assert_int_equal( ecl_kw_get_size( swat0 ) , ecl_grid_get_active_size( GRID ) ); test_assert_int_equal( ecl_kw_get_size( porv ) , ecl_grid_get_global_size( GRID ) ); } - + { int ic; for (ic = 0; ic < ecl_grid_get_num_coarse_groups(GRID); ic++) { @@ -92,8 +92,8 @@ int main(int argc , char ** argv) { test_coarse_cell( GRID , coarse_cell ); } } - - + + ecl_file_close( INIT_file ); ecl_file_close( RST_file ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_dualp.c b/ThirdParty/Ert/lib/ecl/tests/ecl_dualp.cpp similarity index 84% rename from ThirdParty/Ert/lib/ecl/tests/ecl_dualp.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_dualp.cpp index fce022e675..a26d38b863 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_dualp.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_dualp.cpp @@ -1,36 +1,36 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_dualp.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_dualp.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include int main(int argc , char ** argv) { const char * case_path = argv[1]; char * grid_file = ecl_util_alloc_filename( NULL , case_path , ECL_EGRID_FILE , false , 0 ); char * init_file = ecl_util_alloc_filename( NULL , case_path , ECL_INIT_FILE , false , 0 ); char * rst_file = ecl_util_alloc_filename( NULL , case_path , ECL_RESTART_FILE , false , 0 ); - + ecl_grid_type * ecl_grid = ecl_grid_alloc( grid_file ); ecl_file_type * RST_file = ecl_file_open( rst_file , 0); ecl_file_type * INIT_file = ecl_file_open( init_file , 0 ); @@ -66,8 +66,8 @@ int main(int argc , char ** argv) { } } } - - + + ecl_file_close( RST_file ); ecl_file_close( INIT_file ); ecl_grid_free( ecl_grid ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_statoil.c b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_statoil.cpp similarity index 82% rename from ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_statoil.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_statoil.cpp index 73b6e2a2f1..73bd471390 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_statoil.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_collection_statoil.cpp @@ -1,29 +1,29 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_fault_block_collection_statoil.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_fault_block_collection_statoil.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include -#include -#include -#include +#include +#include +#include @@ -67,7 +67,7 @@ int main(int argc , char ** argv) { fclose( stream ); } - + test_create( ecl_grid , fault_blk_kw ); test_get_layer( ecl_grid , fault_blk_kw ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer.c b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer.cpp similarity index 91% rename from ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer.cpp index 37e0184688..d8de3438af 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer.cpp @@ -1,32 +1,32 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_fault_block_layer.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_fault_block_layer.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include @@ -34,10 +34,10 @@ void test_create( const ecl_grid_type * grid , ecl_kw_type * fault_block_kw) { int k = 0; int i,j; - + for (j=0; j < ecl_grid_get_ny( grid ); j++) { for (i = 0; i < ecl_grid_get_nx( grid ); i++) { - + int g = ecl_grid_get_global_index3( grid , i,j,k); ecl_kw_iset_int( fault_block_kw , g , 9 ); } @@ -54,7 +54,7 @@ void test_create( const ecl_grid_type * grid , ecl_kw_type * fault_block_kw) { test_assert_double_equal( x , fault_block_get_xc( block )); test_assert_double_equal( y , fault_block_get_yc( block )); } - + fault_block_layer_free( layer ); } } @@ -64,9 +64,9 @@ void test_create( const ecl_grid_type * grid , ecl_kw_type * fault_block_kw) { void test_create_invalid( const ecl_grid_type * grid ) { ecl_kw_type * fault_blk_kw = ecl_kw_alloc("FAULTBLK" , ecl_grid_get_global_size( grid ) - 1, ECL_INT); - + test_assert_NULL( fault_block_layer_alloc( grid , 7 )); - + ecl_kw_free( fault_blk_kw ); } @@ -78,18 +78,18 @@ void test_trace_edge( const ecl_grid_type * grid) { double_vector_type * y_list = double_vector_alloc( 0,0); fault_block_type * block = fault_block_layer_safe_get_block( layer , 99); int_vector_type * cell_list = int_vector_alloc(0,0); - + test_assert_false( fault_block_trace_edge( block , x_list , y_list , cell_list)); fault_block_add_cell( block , 0,0); test_assert_true( fault_block_trace_edge( block , x_list , y_list , cell_list)); test_assert_int_equal( 4 , double_vector_size( x_list )); test_assert_int_equal( 4 , double_vector_size( y_list )); - + test_assert_double_equal( 0 , double_vector_iget( x_list , 0 )); test_assert_double_equal( 1 , double_vector_iget( x_list , 1 )); test_assert_double_equal( 1 , double_vector_iget( x_list , 2 )); test_assert_double_equal( 0 , double_vector_iget( x_list , 3 )); - + test_assert_double_equal( 0 , double_vector_iget( y_list , 0 )); test_assert_double_equal( 0 , double_vector_iget( y_list , 1 )); test_assert_double_equal( 1 , double_vector_iget( y_list , 2 )); @@ -110,7 +110,7 @@ void test_export( const ecl_grid_type * grid) { ecl_kw_type * ecl_kw2 = ecl_kw_alloc("FAULTBLK" , ecl_grid_get_global_size( grid ) + 1 , ECL_INT); ecl_kw_type * ecl_kw3 = ecl_kw_alloc("FAULTBLK" , ecl_grid_get_global_size( grid ) , ECL_FLOAT); fault_block_type * block = fault_block_layer_add_block( layer , 10 ); - + fault_block_add_cell( block , 0 , 0 ); fault_block_add_cell( block , 1 , 0 ); fault_block_add_cell( block , 1 , 1 ); @@ -123,7 +123,7 @@ void test_export( const ecl_grid_type * grid) { { int nx = ecl_grid_get_nx( grid ); - + test_assert_int_equal( ecl_kw_iget_int( ecl_kw1 , 0 ) , 10 ); test_assert_int_equal( ecl_kw_iget_int( ecl_kw1 , 1 ) , 10 ); test_assert_int_equal( ecl_kw_iget_int( ecl_kw1 , nx ) , 10 ); @@ -150,7 +150,7 @@ void test_neighbours( const ecl_grid_type * grid) { ecl_kw_iset_int( ecl_kw , ecl_grid_get_global_index3( grid , 5,3,k) , 4); ecl_kw_iset_int( ecl_kw , ecl_grid_get_global_index3( grid , 4,2,k) , 5); fault_block_layer_load_kw( layer , ecl_kw); - + { int_vector_type * neighbours = int_vector_alloc( 0,0); { @@ -169,15 +169,15 @@ void test_neighbours( const ecl_grid_type * grid) { test_assert_true( int_vector_contains( neighbours , 3 )); } int_vector_free( neighbours ); - + } - + geo_polygon_collection_free( polylines ); - fault_block_layer_free( layer ); + fault_block_layer_free( layer ); ecl_kw_free( ecl_kw ); } - + int main(int argc , char ** argv) { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_statoil.c b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_statoil.cpp similarity index 82% rename from ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_statoil.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_statoil.cpp index 9fc2581572..6e2590397a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_statoil.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_fault_block_layer_statoil.cpp @@ -1,44 +1,44 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_fault_block_layer_statoil.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_fault_block_layer_statoil.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include -#include -#include -#include +#include +#include +#include void test_create( const ecl_grid_type * grid , const ecl_kw_type * fault_block_kw) { test_assert_NULL( fault_block_layer_alloc( grid , -1 )); test_assert_NULL( fault_block_layer_alloc( grid , ecl_grid_get_nz( grid ))); - - { + + { int k; for (k = 0; k < ecl_grid_get_nz( grid ); k++) { fault_block_layer_type * layer = fault_block_layer_alloc( grid , k); test_assert_true( fault_block_layer_is_instance( layer )); - + fault_block_layer_scan_kw( layer , fault_block_kw); { - int max_block_id = fault_block_layer_get_max_id( layer ); + int max_block_id = fault_block_layer_get_max_id( layer ); int block_id; for (block_id = 0; block_id <= max_block_id; block_id++) { @@ -49,7 +49,7 @@ void test_create( const ecl_grid_type * grid , const ecl_kw_type * fault_block_k } } } - + { int index; for (index = 0; index < fault_block_layer_get_size( layer ); index++) { @@ -58,7 +58,7 @@ void test_create( const ecl_grid_type * grid , const ecl_kw_type * fault_block_k fault_block_get_yc( block ); } } - + fault_block_layer_free( layer ); } } @@ -78,7 +78,7 @@ int main(int argc , char ** argv) { fclose( stream ); } - + test_create( ecl_grid , fault_blk_kw ); ecl_grid_free( ecl_grid ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_file.c b/ThirdParty/Ert/lib/ecl/tests/ecl_file.cpp similarity index 83% rename from ThirdParty/Ert/lib/ecl/tests/ecl_file.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_file.cpp index 2a8246e285..c680e3d10e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_file.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_file.cpp @@ -20,26 +20,26 @@ #include #include -#include +#include #include -#include +#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include void test_writable(size_t data_size) { test_work_area_type * work_area = test_work_area_alloc("ecl_file_writable"); const char * data_file_name = "test_file"; ecl_kw_type * kw = ecl_kw_alloc("TEST_KW", data_size, ECL_INT); - for(int i = 0; i < data_size; ++i) + for(size_t i = 0; i < data_size; ++i) ecl_kw_iset_int(kw, i, ((i*37)+11)%data_size); fortio_type * fortio = fortio_open_writer(data_file_name, false, true); - ecl_kw_fwrite(kw, fortio); + ecl_kw_fwrite(kw, fortio); fortio_fclose(fortio); for(int i = 0; i < 4; ++i) { @@ -59,6 +59,7 @@ void test_writable(size_t data_size) { void test_truncated() { test_work_area_type * work_area = test_work_area_alloc("ecl_file_truncated" ); + int num_kw; { ecl_grid_type * grid = ecl_grid_alloc_rectangular(20,20,20,1,1,1,NULL); ecl_grid_fwrite_EGRID2( grid , "TEST.EGRID", ECL_METRIC_UNITS ); @@ -67,6 +68,7 @@ void test_truncated() { { ecl_file_type * ecl_file = ecl_file_open("TEST.EGRID" , 0 ); test_assert_true( ecl_file_is_instance( ecl_file ) ); + num_kw = ecl_file_get_size( ecl_file ); ecl_file_close( ecl_file ); } @@ -78,7 +80,8 @@ void test_truncated() { } { ecl_file_type * ecl_file = ecl_file_open("TEST.EGRID" , 0 ); - test_assert_NULL( ecl_file ); + test_assert_true( ecl_file_get_size( ecl_file) < num_kw ); + ecl_file_close( ecl_file ); } test_work_area_free( work_area ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_file_statoil.c b/ThirdParty/Ert/lib/ecl/tests/ecl_file_statoil.cpp similarity index 80% rename from ThirdParty/Ert/lib/ecl/tests/ecl_file_statoil.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_file_statoil.cpp index c1cbcc0d03..13de6fcf40 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_file_statoil.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_file_statoil.cpp @@ -20,15 +20,15 @@ #include #include -#include +#include #include -#include +#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include void test_flags( const char * filename) { @@ -132,32 +132,6 @@ void test_writable(const char * src_file ) { -void test_truncated() { - test_work_area_type * work_area = test_work_area_alloc("ecl_file_truncated" ); - { - ecl_grid_type * grid = ecl_grid_alloc_rectangular(20,20,20,1,1,1,NULL); - ecl_grid_fwrite_EGRID2( grid , "TEST.EGRID", ECL_METRIC_UNITS ); - ecl_grid_free( grid ); - } - { - ecl_file_type * ecl_file = ecl_file_open("TEST.EGRID" , 0 ); - test_assert_true( ecl_file_is_instance( ecl_file ) ); - ecl_file_close( ecl_file ); - } - - { - offset_type file_size = util_file_size( "TEST.EGRID"); - FILE * stream = util_fopen("TEST.EGRID" , "r+"); - util_ftruncate( stream , file_size / 2 ); - fclose( stream ); - } - { - ecl_file_type * ecl_file = ecl_file_open("TEST.EGRID" , 0 ); - test_assert_NULL( ecl_file ); - } - test_work_area_free( work_area ); -} - int main( int argc , char ** argv) { const char * src_file = argv[1]; @@ -175,6 +149,5 @@ int main( int argc , char ** argv) { test_work_area_free( work_area ); } - test_truncated(); exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_file_view.c b/ThirdParty/Ert/lib/ecl/tests/ecl_file_view.cpp similarity index 95% rename from ThirdParty/Ert/lib/ecl/tests/ecl_file_view.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_file_view.cpp index f894eaf6f4..9dc7875d7c 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_file_view.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_file_view.cpp @@ -19,14 +19,14 @@ #include #include -#include +#include #include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include void test_file_kw_equal() { ecl_file_kw_type * kw1 = ecl_file_kw_alloc0( "PRESSURE" , ECL_FLOAT, 1000 , 66); @@ -106,7 +106,7 @@ void test_create_file_kw() { ecl_file_kw_free( file_kw0 ); ecl_file_kw_free( file_kw1 ); ecl_file_kw_free( file_kw2 ); - + } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_fmt.c b/ThirdParty/Ert/lib/ecl/tests/ecl_fmt.cpp similarity index 80% rename from ThirdParty/Ert/lib/ecl/tests/ecl_fmt.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_fmt.cpp index 4787c312b5..5b04922dce 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_fmt.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_fmt.cpp @@ -1,29 +1,29 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ecl_fmt.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ecl_fmt.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include #include -#include -#include +#include +#include -#include +#include void test_content( test_work_area_type * work_area , const char * src_file , bool fmt_file ) { test_work_area_install_file( work_area , src_file ); @@ -32,7 +32,7 @@ void test_content( test_work_area_type * work_area , const char * src_file , boo bool fmt; util_alloc_file_components( src_file , NULL , &base_name , NULL); util_copy_file( src_file , base_name ); - + test_assert_true( ecl_util_fmt_file( base_name , &fmt )); test_assert_bool_equal( fmt , fmt_file ); } @@ -43,11 +43,11 @@ void test_content( test_work_area_type * work_area , const char * src_file , boo void test_small( ) { bool fmt; - + FILE * stream = util_fopen("small.txt" , "w"); fprintf(stream , "Some bytes\n"); fclose( stream ); - + test_assert_false( ecl_util_fmt_file( "small.txt" , &fmt )); } @@ -71,10 +71,10 @@ int main(int argc , char ** argv) { test_assert_true( fmt_file ); test_assert_true( ecl_util_fmt_file( "TEST.EGRID" , &fmt_file )); - test_assert_false( fmt_file ); + test_assert_false( fmt_file ); test_assert_true( ecl_util_fmt_file( "TEST.FEGRID" , &fmt_file )); - test_assert_true( fmt_file ); + test_assert_true( fmt_file ); test_assert_false(ecl_util_fmt_file( "TEST_DOES_NOT_EXIST" , &fmt_file )); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_fortio.c b/ThirdParty/Ert/lib/ecl/tests/ecl_fortio.cpp similarity index 95% rename from ThirdParty/Ert/lib/ecl/tests/ecl_fortio.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_fortio.cpp index 58013a7039..e18fcd20ae 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_fortio.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_fortio.cpp @@ -18,13 +18,13 @@ #include #include -#include +#include #include -#include -#include +#include +#include #include -#include +#include void test_existing_read(const char * filename) { fortio_type * fortio = fortio_open_reader( filename , false , ECL_ENDIAN_FLIP); @@ -114,7 +114,7 @@ void test_fread_truncated_data() { test_work_area_type * work_area = test_work_area_alloc("fortio_truncated" ); { const size_t buffer_size = 1000; - void * buffer = util_malloc( buffer_size ); + char * buffer = (char *) util_malloc( buffer_size ); { fortio_type * fortio = fortio_open_writer( "PRESSURE" , false , true ); @@ -149,7 +149,7 @@ void test_fread_truncated_head() { { fortio_type * fortio = fortio_open_reader( "PRESSURE" , false , true ); - void * buffer = NULL; + char * buffer = NULL; int buffer_size = 10; test_assert_false( fortio_fread_buffer( fortio , buffer , buffer_size )); test_assert_true( fortio_read_at_eof( fortio )); @@ -164,7 +164,7 @@ void test_fread_truncated_tail() { test_work_area_type * work_area = test_work_area_alloc("fortio_truncated2" ); { const size_t buffer_size = 1000; - void * buffer = util_malloc( buffer_size ); + char * buffer = (char *) util_malloc( buffer_size ); { fortio_type * fortio = fortio_open_writer( "PRESSURE" , false , true ); @@ -190,7 +190,7 @@ void test_fread_truncated_tail() { void test_fread_invalid_tail() { test_work_area_type * work_area = test_work_area_alloc("fortio_invalid" ); int record_size = 10; - void * buffer = util_malloc( record_size ); + char * buffer = (char *) util_malloc( record_size ); { FILE * stream = util_fopen("PRESSURE" , "w"); @@ -224,7 +224,7 @@ void test_at_eof() { test_work_area_type * work_area = test_work_area_alloc("fortio_truncated2" ); { fortio_type * fortio = fortio_open_writer("PRESSURE" , false , true); - void * buffer = util_malloc( 100 ); + char * buffer = (char *) util_malloc( 100 ); fortio_fwrite_record( fortio , buffer , 100); free( buffer ); @@ -251,7 +251,7 @@ void test_fseek() { test_work_area_type * work_area = test_work_area_alloc("fortio_fseek" ); { fortio_type * fortio = fortio_open_writer("PRESSURE" , false , true); - void * buffer = util_malloc( 100 ); + char * buffer = (char *) util_malloc( 100 ); fortio_fwrite_record( fortio , buffer , 100); free( buffer ); @@ -280,7 +280,7 @@ void test_write_failure() { test_work_area_type * work_area = test_work_area_alloc("fortio_fseek" ); { fortio_type * fortio = fortio_open_writer("PRESSURE" , false , true); - void * buffer = util_malloc( 100 ); + char * buffer = (char *) util_malloc( 100 ); fortio_fwrite_record( fortio , buffer , 100); test_assert_true( util_file_exists( "PRESSURE")); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_get_num_cpu_test.c b/ThirdParty/Ert/lib/ecl/tests/ecl_get_num_cpu_test.cpp similarity index 70% rename from ThirdParty/Ert/lib/ecl/tests/ecl_get_num_cpu_test.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_get_num_cpu_test.cpp index e0a94881c7..3f715b2cd8 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_get_num_cpu_test.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_get_num_cpu_test.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ecl_get_num_cpu_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ecl_get_num_cpu_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include - +#include +#include + int main(int argc , char ** argv) { const char * filename1 = argv[1]; diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_DEPTHZ.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_DEPTHZ.cpp similarity index 70% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_DEPTHZ.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_DEPTHZ.cpp index 77c4981f81..29b14612cb 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_DEPTHZ.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_DEPTHZ.cpp @@ -1,27 +1,27 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_grid_DEPTHZ.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_grid_DEPTHZ.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include -#include +#include +#include double zfunc(double x , double y) { @@ -33,7 +33,7 @@ double center_sum(const double * DV, int index) { for (int i=0; i < index; i++) sum += DV[i]; - + return sum; } @@ -44,10 +44,10 @@ void test_create() { int ny = 100; int nz = 10; - double * DXV = util_malloc( nx * sizeof * DXV ); - double * DYV = util_malloc( ny * sizeof * DYV ); - double * DZV = util_malloc( nz * sizeof * DZV ); - double * DEPTHZ = util_malloc( (nx + 1) * (ny + 1) * sizeof * DEPTHZ); + double * DXV = (double *) util_malloc( nx * sizeof * DXV ); + double * DYV = (double *) util_malloc( ny * sizeof * DYV ); + double * DZV = (double *) util_malloc( nz * sizeof * DZV ); + double * DEPTHZ = (double *) util_malloc( (nx + 1) * (ny + 1) * sizeof * DEPTHZ); for (int i=0; i < nx; i++) DXV[i] = 1.0 / nx; @@ -57,19 +57,19 @@ void test_create() { for (int k=0; k < nz; k++) DZV[k] = 3.0 / nz; - + for (int j=0; j <= ny; j++) { double y = center_sum(DYV , j); for (int i=0; i <= nx; i++) { double x = center_sum(DXV , i); - + DEPTHZ[i + j*(nx + 1)] = zfunc( x,y ); } } ecl_grid = ecl_grid_alloc_dxv_dyv_dzv_depthz( nx,ny,nz,DXV , DYV , DZV , DEPTHZ , NULL); - + for (int k=0; k < nz; k++) { double z0 = center_sum(DZV , k ) - 0.5*DZV[0]; for (int j=0; j < ny; j++) { @@ -78,8 +78,8 @@ void test_create() { double x0 = center_sum(DXV , i ); double xc,yc,zc; int g = ecl_grid_get_global_index3( ecl_grid , i , j , k ); - - ecl_grid_get_xyz1( ecl_grid , g , &xc , &yc , &zc); + + ecl_grid_get_xyz1( ecl_grid , g , &xc , &yc , &zc); test_assert_double_equal( x0 , xc ); test_assert_double_equal( y0 , yc ); @@ -117,10 +117,10 @@ void test_compare() { ecl_grid_type * grid2; { - double * DX = util_malloc( V * sizeof * DX ); - double * DY = util_malloc( V * sizeof * DY ); - double * DZ = util_malloc( V * sizeof * DZ ); - double * TOPS = util_malloc( V * sizeof * TOPS ); + double * DX = (double *) util_malloc( V * sizeof * DX ); + double * DY = (double *) util_malloc( V * sizeof * DY ); + double * DZ = (double *) util_malloc( V * sizeof * DZ ); + double * TOPS = (double *) util_malloc( V * sizeof * TOPS ); for (int i = 0; i < V; i++) { DX[i] = dx; @@ -149,31 +149,31 @@ void test_compare() { } { - double * DXV = util_malloc( nx * sizeof * DXV ); - double * DYV = util_malloc( ny * sizeof * DYV ); - double * DZV = util_malloc( nz * sizeof * DZV ); - double * DEPTHZ = util_malloc( (nx + 1)*(ny + 1) * sizeof * DEPTHZ); + double * DXV = (double *) util_malloc( nx * sizeof * DXV ); + double * DYV = (double *) util_malloc( ny * sizeof * DYV ); + double * DZV = (double *) util_malloc( nz * sizeof * DZV ); + double * DEPTHZ = (double *) util_malloc( (nx + 1)*(ny + 1) * sizeof * DEPTHZ); - for (int i = 0; i < nx; i++) + for (int i = 0; i < nx; i++) DXV[i] = dx; - for (int i = 0; i < ny; i++) + for (int i = 0; i < ny; i++) DYV[i] = dy; - for (int i = 0; i < nz; i++) + for (int i = 0; i < nz; i++) DZV[i] = dz; - - for (int i = 0; i < (nx + 1)*(ny+ 1); i++) + + for (int i = 0; i < (nx + 1)*(ny+ 1); i++) DEPTHZ[i] = z0; - + grid2 = ecl_grid_alloc_dxv_dyv_dzv_depthz( nx , ny , nz , DXV , DYV , DZV , DEPTHZ , NULL ); free( DXV ); free( DYV ); free( DZV ); free( DEPTHZ ); } - + test_assert_true( ecl_grid_compare( grid1 , grid2 , true , true , true)); ecl_grid_free( grid1 ); ecl_grid_free( grid2 ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_add_nnc.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_add_nnc.cpp similarity index 97% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_add_nnc.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_add_nnc.cpp index 2f7d5cb878..d7d9221361 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_add_nnc.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_add_nnc.cpp @@ -18,11 +18,11 @@ #include #include -#include +#include #include -#include +#include -#include +#include void verify_simple_nnc( const ecl_grid_type * grid) { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_case.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_case.cpp similarity index 72% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_case.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_case.cpp index cbf40c6a83..6dcb7f05c2 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_case.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_case.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_grid_case.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_grid_case.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include -#include +#include void test_grid( const char * input , bool expected) { @@ -36,11 +36,11 @@ void test_grid( const char * input , bool expected) { int main(int argc , char ** argv) { const char * grid_file = argv[1]; const char * case_path = argv[2]; - + test_grid( grid_file , true ); test_grid( case_path , true ); test_grid( "/tmp/does/not/exists/file.EGRID" , false ); test_grid( "/tmp/does/not/exists/CASE" , false ); - + exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains.cpp similarity index 99% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains.cpp index 13e83f4e26..c44ccbfc2f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains.cpp @@ -21,8 +21,8 @@ #include #include -#include -#include +#include +#include bool get_test_point1(const ecl_grid_type * grid , int global_index, double *_xpos , double *_ypos , double *_zpos) { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains_wellpath.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains_wellpath.cpp similarity index 89% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains_wellpath.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains_wellpath.cpp index aa9da34651..c2eb6d8179 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains_wellpath.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_contains_wellpath.cpp @@ -21,9 +21,9 @@ #include #include -#include -#include -#include +#include +#include +#include typedef struct { @@ -50,7 +50,7 @@ vector_type * load_expected( const ecl_grid_type * grid, const char * filename ) int i,j,k,skip; if (fscanf( stream , "%lg %lg %lg %d %d %d %d" , &x,&y,&z,&i,&j,&k,&skip) == 7) { - point_type * p = util_malloc( sizeof * p ); + point_type * p = (point_type *) util_malloc( sizeof * p ); p->x = x; p->y = y; p->z = z; @@ -71,7 +71,7 @@ vector_type * load_expected( const ecl_grid_type * grid, const char * filename ) } -void test_well_point(const ecl_grid_type * grid, const point_type * expected) { +void test_well_point(ecl_grid_type * grid, const point_type * expected) { int g = ecl_grid_get_global_index_from_xyz(grid , expected->x, expected->y , expected->z , 0 ); if (g != ecl_grid_get_global_index3(grid, expected->i,expected->j, expected->k)) { int i,j,k; @@ -98,7 +98,7 @@ int main(int argc , char ** argv) { vector_type * expected = load_expected( grid, argv[2] ); for (int c=0; c < vector_get_size( expected ); c++) { - const point_type * p = vector_iget_const( expected , c ); + const point_type * p = (const point_type *) vector_iget_const( expected , c ); test_well_point(grid, p); } ecl_grid_free( grid ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_volume.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_volume.c deleted file mode 100644 index 9900ce4bd2..0000000000 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_cell_volume.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_grid_cell_contains.c' is part of ERT - Ensemble based - Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#include -#include - -#include - -#include - - -void test_cells( const ecl_grid_type * grid ) { - int error_count = 0; - int global_index; - for (global_index = 0; global_index < ecl_grid_get_global_size( grid ); global_index++) { - if ((abs(ecl_grid_get_cell_volume1( grid , global_index)) + abs(ecl_grid_get_cell_volume1_tskille( grid , global_index))) > 1e-9) { - if (!test_check_double_equal( ecl_grid_get_cell_volume1( grid , global_index) , ecl_grid_get_cell_volume1_tskille( grid , global_index))) { - fprintf(stderr," Global index:%d \n",global_index); - error_count += 1; - } - } - } - test_assert_int_equal(0 , error_count); -} - - - - - -int main(int argc , char ** argv) { - ecl_grid_type * grid; - - if (argc == 1) - grid = ecl_grid_alloc_rectangular(6,6,6,1,2,3,NULL); - else - grid = ecl_grid_alloc( argv[1] ); - - test_cells( grid ); - ecl_grid_free( grid ); - exit(0); -} diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy.cpp similarity index 69% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy.cpp index 49b8b0600e..b5e69a4eae 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_grid_copy.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_grid_copy.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ @@ -24,11 +24,11 @@ #include #include -#include -#include +#include +#include #include -#include +#include void test_copy_grid( const ecl_grid_type * grid ) { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_statoil.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_statoil.cpp similarity index 70% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_statoil.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_statoil.cpp index 798aea150e..23182906c3 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_statoil.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_copy_statoil.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_grid_copy_statoil.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_grid_copy_statoil.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ @@ -24,11 +24,11 @@ #include #include -#include -#include +#include +#include #include -#include +#include void test_copy_grid( const char * filename ) { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_corner.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_corner.cpp similarity index 96% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_corner.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_corner.cpp index efc1727ef0..5b3c2fe044 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_corner.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_corner.cpp @@ -18,9 +18,9 @@ #include #include -#include +#include -#include +#include void invalid_call1( void * arg ) { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_create.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_create.cpp similarity index 77% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_create.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_create.cpp index 2778159d71..d7d45f32e9 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_create.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_create.cpp @@ -1,28 +1,28 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_grid_create.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_grid_create.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include #include -#include +#include @@ -30,15 +30,15 @@ void test_create2() { int nx = 10; int ny = 8; int nz = 5; - double * dx = util_calloc( nx*ny*nz , sizeof * dx ); - double * dy = util_calloc( nx*ny*nz , sizeof * dy ); - double * dz = util_calloc( nx*ny*nz , sizeof * dz ); - double * tops = util_calloc( nx*ny*nz , sizeof * dz ); + double * dx = (double *) util_calloc( nx*ny*nz , sizeof * dx ); + double * dy = (double *) util_calloc( nx*ny*nz , sizeof * dy ); + double * dz = (double *) util_calloc( nx*ny*nz , sizeof * dz ); + double * tops = (double *) util_calloc( nx*ny*nz , sizeof * dz ); for (int k=0; k< nz; k++) { for (int j=0; j < ny; j++) { for (int i=0; i < nx; i++) { int g = k*nx*ny + j*nx + i; - + dx[g] = (i+1); dy[g] = (j+1); dz[g] = (k+1); @@ -49,25 +49,25 @@ void test_create2() { } } } - + { ecl_grid_type * grid = ecl_grid_alloc_dx_dy_dz_tops( nx , ny , nz , dx , dy , dz , tops , NULL ); - + test_assert_int_equal( nx*ny*nz , ecl_grid_get_global_size( grid )); test_assert_int_equal( nx*ny*nz , ecl_grid_get_active_size( grid )); - + for (int k=0; k< nz; k++) { for (int j=0; j < ny; j++) { for (int i=0; i < nx; i++) { int g = k*nx*ny + j*nx + i; - + test_assert_double_equal( ecl_grid_get_cell_volume1( grid , g ) , dx[g] * dy[g] * dz[g]); } } } { double x,y,z; - + ecl_grid_get_xyz1(grid , 0 , &x , &y , &z); test_assert_double_equal( x , dx[0] * 0.5 ); test_assert_double_equal( y , dy[0] * 0.5 ); @@ -86,15 +86,15 @@ void test_create1() { int nx = 10; int ny = 10; int nz = 10; - double * dx = util_calloc( nx*ny*nz , sizeof * dx ); - double * dy = util_calloc( nx*ny*nz , sizeof * dy ); - double * dz = util_calloc( nx*ny*nz , sizeof * dz ); - double * tops = util_calloc( nx*ny*nz , sizeof * tops ); + double * dx = (double *) util_calloc( nx*ny*nz , sizeof * dx ); + double * dy = (double *) util_calloc( nx*ny*nz , sizeof * dy ); + double * dz = (double *) util_calloc( nx*ny*nz , sizeof * dz ); + double * tops = (double *) util_calloc( nx*ny*nz , sizeof * tops ); for (int k=0; k< nz; k++) { for (int j=0; j < ny; j++) { for (int i=0; i < nx; i++) { int g = k*nx*ny + j*nx + i; - + dx[g] = 1; dy[g] = 1; dz[g] = 1; @@ -105,18 +105,18 @@ void test_create1() { } } } - + { ecl_grid_type * grid = ecl_grid_alloc_dx_dy_dz_tops( nx , ny , nz , dx , dy , dz , tops , NULL ); - + test_assert_int_equal( nx*ny*nz , ecl_grid_get_global_size( grid )); test_assert_int_equal( nx*ny*nz , ecl_grid_get_active_size( grid )); - + for (int k=0; k< nz; k++) { for (int j=0; j < ny; j++) { for (int i=0; i < nx; i++) { int g = k*nx*ny + j*nx + i; - + test_assert_double_equal( ecl_grid_get_cell_volume1( grid , g ) , dx[g] * dy[g] * dz[g]); { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dims.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dims.cpp similarity index 83% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_dims.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_dims.cpp index 371b214571..8658da7089 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dims.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dims.cpp @@ -1,29 +1,29 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include #include -#include -#include +#include +#include @@ -34,10 +34,10 @@ void test_grid( const char * grid_filename , const char * data_filename) { test_assert_not_NULL( grid_dims ); test_assert_int_equal( ecl_grid_get_num_lgr( ecl_grid ) + 1 , ecl_grid_dims_get_num_grids( grid_dims )); for (int i=0; i < ecl_grid_dims_get_num_grids( grid_dims ); i++) { - + grid_dims_type d1 = ecl_grid_iget_dims( ecl_grid , i); const grid_dims_type * d2 = ecl_grid_dims_iget_dims( grid_dims , i ); - + test_assert_int_equal( d1.nx , d2->nx ); test_assert_int_equal( d1.ny , d2->ny ); test_assert_int_equal( d1.nz , d2->nz ); @@ -51,14 +51,14 @@ void test_grid( const char * grid_filename , const char * data_filename) { void test_dims() { grid_dims_type d1; grid_dims_type * d2 = grid_dims_alloc( 100 , 100 , 100 , 0); - + grid_dims_init(&d1 , 100 , 100 , 100 , 0 ); - + test_assert_int_equal( d1.nx , d2->nx ); test_assert_int_equal( d1.ny , d2->ny ); test_assert_int_equal( d1.nz , d2->nz ); test_assert_int_equal( d1.nactive , d2->nactive ); - + grid_dims_free( d2 ); } @@ -74,7 +74,7 @@ int main(int argc , char ** argv) { } else { const char * GRID_file = argv[1]; char * data_file; - + if (argc == 3) data_file = argv[2]; else @@ -82,6 +82,6 @@ int main(int argc , char ** argv) { test_grid( GRID_file , data_file ); } - + exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dx_dy_dz.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dx_dy_dz.cpp new file mode 100644 index 0000000000..542b70b824 --- /dev/null +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_dx_dy_dz.cpp @@ -0,0 +1,79 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_grid_dims.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +double err(double a, double b) { + return (a - b) / a; +} + + + +void test_dxdydz(const std::string& grid_fname, const std::string& init_fname) { + double eps_x = 1e-4; + double eps_y = 1e-4; + double eps_z = 1e-3; + ecl_grid_type * grid = ecl_grid_alloc( grid_fname.c_str() ); + ecl_file_type * init_file = ecl_file_open( init_fname.c_str(), 0); + ecl_kw_type * dx = ecl_file_iget_named_kw( init_file, "DX", 0); + ecl_kw_type * dy = ecl_file_iget_named_kw( init_file, "DY", 0); + ecl_kw_type * dz = ecl_file_iget_named_kw( init_file, "DZ", 0); + for(int a=0; a < ecl_grid_get_active_size(grid); a+= 100) { + int g = ecl_grid_get_global_index1A(grid, a); + + double dxg = ecl_grid_get_cell_dx1(grid, g); + double dyg = ecl_grid_get_cell_dy1(grid, g); + double dzg = ecl_grid_get_cell_dz1(grid, g); + + double dxi = ecl_kw_iget_float(dx, a); + double dyi = ecl_kw_iget_float(dy, a); + double dzi = ecl_kw_iget_float(dz, a); + + double err_x = fabs(err(dxg, dxi)); + double err_y = fabs(err(dyg, dyi)); + double err_z = fabs(err(dzg, dzi)); + + test_assert_true( err_x < eps_x ); + test_assert_true( err_y < eps_y ); + test_assert_true( err_z < eps_z ); + + } + ecl_file_close(init_file); + ecl_grid_free( grid ); +} + + +int main(int argc , char ** argv) { + const std::string ecl_case = argv[1]; + std::string grid_file = ecl_case + ".EGRID"; + std::string init_file = ecl_case + ".INIT"; + + test_dxdydz(grid_file, init_file); + + exit(0); +} diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_export.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_export.cpp similarity index 82% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_export.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_export.cpp index 83cbfe878e..913269ae36 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_export.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_export.cpp @@ -18,17 +18,17 @@ #include #include -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include void export_actnum( const ecl_grid_type * ecl_grid , ecl_file_type * ecl_file ) { ecl_kw_type * actnum_kw = ecl_file_iget_named_kw( ecl_file , "ACTNUM" , 0 ); - int * actnum = util_malloc( ecl_kw_get_size( actnum_kw ) * sizeof * actnum ); + int * actnum = (int *) util_malloc( ecl_kw_get_size( actnum_kw ) * sizeof * actnum ); ecl_grid_init_actnum_data( ecl_grid , actnum ); for (int i=0; i < ecl_kw_get_size( actnum_kw); i++) @@ -42,8 +42,8 @@ void export_coord( const ecl_grid_type * grid , ecl_file_type * ecl_file ) { ecl_kw_type * coord_kw = ecl_file_iget_named_kw( ecl_file , "COORD" , 0); test_assert_int_equal( ecl_kw_get_size( coord_kw ) , ecl_grid_get_coord_size( grid )); { - float * coord_float = util_malloc( ecl_grid_get_coord_size( grid ) * sizeof * coord_float ); - double * coord_double = util_malloc( ecl_grid_get_coord_size( grid ) * sizeof * coord_double ); + float * coord_float = (float *) util_malloc( ecl_grid_get_coord_size( grid ) * sizeof * coord_float ); + double * coord_double = (double *) util_malloc( ecl_grid_get_coord_size( grid ) * sizeof * coord_double ); ecl_grid_init_coord_data( grid , coord_float ); ecl_grid_init_coord_data_double( grid , coord_double ); @@ -61,8 +61,8 @@ void export_zcorn( const ecl_grid_type * grid , ecl_file_type * ecl_file ) { ecl_kw_type * zcorn_kw = ecl_file_iget_named_kw( ecl_file , "ZCORN" , 0); test_assert_int_equal( ecl_kw_get_size( zcorn_kw ) , ecl_grid_get_zcorn_size( grid )); { - float * zcorn_float = util_malloc( ecl_grid_get_zcorn_size( grid ) * sizeof * zcorn_float ); - double * zcorn_double = util_malloc( ecl_grid_get_zcorn_size( grid ) * sizeof * zcorn_double ); + float * zcorn_float = (float *) util_malloc( ecl_grid_get_zcorn_size( grid ) * sizeof * zcorn_float ); + double * zcorn_double = (double *) util_malloc( ecl_grid_get_zcorn_size( grid ) * sizeof * zcorn_double ); ecl_grid_init_zcorn_data( grid , zcorn_float ); ecl_grid_init_zcorn_data_double( grid , zcorn_double ); @@ -88,7 +88,7 @@ void copy_processed( const ecl_grid_type * src ) { { - int * actnum = util_malloc( ecl_grid_get_global_size( src ) * sizeof * actnum ); + int * actnum = (int *) util_malloc( ecl_grid_get_global_size( src ) * sizeof * actnum ); int index = 0; ecl_grid_init_actnum_data( src , actnum ); @@ -110,7 +110,7 @@ void copy_processed( const ecl_grid_type * src ) { { - double * zcorn_double = util_malloc( ecl_grid_get_zcorn_size( src ) * sizeof * zcorn_double ); + double * zcorn_double = (double *) util_malloc( ecl_grid_get_zcorn_size( src ) * sizeof * zcorn_double ); int i = 0; int j = 0; int k = 0; @@ -122,7 +122,7 @@ void copy_processed( const ecl_grid_type * src ) { ecl_grid_free( copy ); } - + for (int c = 0; c < 4; c++) { double dz = zcorn_double[ ecl_grid_zcorn_index( src , i , j , k , c + 4 ) ] - zcorn_double[ ecl_grid_zcorn_index( src , i , j , k , c ) ]; zcorn_double[ ecl_grid_zcorn_index( src , i , j , k , c + 4 ) ] += dz; @@ -156,8 +156,8 @@ void export_mapaxes( const ecl_grid_type * grid , ecl_file_type * ecl_file ) { int main(int argc , char ** argv) { test_work_area_type * work_area = test_work_area_alloc("grid_export"); { - char * test_grid = "TEST.EGRID"; - char * grid_file; + const char * test_grid = "TEST.EGRID"; + const char * grid_file; if (argc == 1) { ecl_grid_type * grid = ecl_grid_alloc_rectangular(4,4,2,1,1,1,NULL); grid_file = test_grid; @@ -168,6 +168,8 @@ int main(int argc , char ** argv) { { ecl_grid_type * ecl_grid = ecl_grid_alloc( grid_file ); + if (argc == 1) + test_assert_true( ecl_grid_get_unit_system(ecl_grid) == ECL_METRIC_UNITS ); ecl_file_type * ecl_file = ecl_file_open( grid_file , 0) ; export_actnum( ecl_grid , ecl_file ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_ext_actnum.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_ext_actnum.cpp new file mode 100644 index 0000000000..75c497189a --- /dev/null +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_ext_actnum.cpp @@ -0,0 +1,64 @@ +#include + +#include +#include + +#include +#include +#include +#include +#include + + +void test_1() { + + test_work_area_type * work_area = test_work_area_alloc("ext_actnum_main_grid"); + { + const char * filename = "FILE.EGRID"; + + ecl_grid_type * grid_write = ecl_grid_alloc_rectangular(2,3,1, 1,1,1,NULL); + ecl_grid_fwrite_EGRID( grid_write , filename, true); + ecl_grid_free(grid_write); + + ecl_file_type * ecl_file = ecl_file_open(filename, 0); + ecl_kw_type * filehead_kw = ecl_file_iget_named_kw( ecl_file , FILEHEAD_KW , 0); + int * filehead_data = ecl_kw_get_int_ptr(filehead_kw); + filehead_data[FILEHEAD_DUALP_INDEX] = FILEHEAD_DUAL_POROSITY; + + ecl_kw_type * actnum_kw = ecl_file_iget_named_kw( ecl_file, ACTNUM_KW, 0); + int * actnum_data = ecl_kw_get_int_ptr(actnum_kw); + actnum_data[0] = 1; + actnum_data[1] = 2; + actnum_data[2] = 2; + actnum_data[3] = 0; + actnum_data[4] = 1; + actnum_data[5] = 1; + const char * filename1 = "FILE1.EGRID"; + fortio_type * f = fortio_open_writer( filename1, false, ECL_ENDIAN_FLIP ); + ecl_file_fwrite_fortio(ecl_file, f, 0); + fortio_fclose( f ); + ecl_file_close(ecl_file); + + std::vector ext_actnum = {0, 1, 0, 1, 1, 1}; + ecl_grid_type * grid = ecl_grid_alloc_ext_actnum(filename1, ext_actnum.data()); + test_assert_int_equal( 2, ecl_grid_get_nactive(grid) ); + test_assert_int_equal( 1, ecl_grid_get_nactive_fracture(grid) ); + test_assert_true( !ecl_grid_cell_active1(grid, 0) ); + + test_assert_true( !ecl_grid_cell_active1(grid, 2) ); + test_assert_true( !ecl_grid_cell_active1(grid, 3) ); + test_assert_true( ecl_grid_cell_active1(grid, 4) ); + test_assert_true( ecl_grid_cell_active1(grid, 5) ); + + ecl_grid_free( grid ); + + } + test_work_area_free( work_area ); + + +} + + +int main() { + test_1(); +} diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_fwrite.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_fwrite.cpp similarity index 72% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_fwrite.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_fwrite.cpp index a323591116..861edc0c42 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_fwrite.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_fwrite.cpp @@ -1,33 +1,33 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_kw_fwrite.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_kw_fwrite.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include +#include -#include +#include void test_fwrite_EGRID(ecl_grid_type * grid ) { test_work_area_type * work_area = test_work_area_alloc("grid-has-mapaxes"); - + ecl_grid_fwrite_EGRID2( grid , "TEST.EGRID", ECL_METRIC_UNITS); { ecl_grid_type * copy = ecl_grid_alloc( "TEST.EGRID" ); @@ -41,7 +41,7 @@ void test_fwrite_EGRID(ecl_grid_type * grid ) { int main( int argc , char **argv) { const char * src_file = argv[1]; ecl_grid_type * grid = ecl_grid_alloc( src_file ); - + test_fwrite_EGRID( grid ); ecl_grid_free( grid ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_init_fwrite.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_init_fwrite.cpp similarity index 94% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_init_fwrite.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_init_fwrite.cpp index cc0141b9ad..dc480232e0 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_init_fwrite.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_init_fwrite.cpp @@ -18,15 +18,15 @@ #include #include -#include +#include #include -#include +#include -#include -#include -#include +#include +#include +#include #include -#include +#include diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_layer_contains.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_layer_contains.cpp similarity index 73% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_layer_contains.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_layer_contains.cpp index 64a5e5db87..6af4f412be 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_layer_contains.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_layer_contains.cpp @@ -1,32 +1,32 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_grid_layer_contains' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_grid_layer_contains' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include -#include +#include void test_layer(const ecl_grid_type * grid ) { int g; - + for (g=0; g < ecl_grid_get_global_size( grid ); g += 25) { double x,y,z; int i,j,k; @@ -39,7 +39,7 @@ void test_layer(const ecl_grid_type * grid ) { test_assert_int_equal( i , find_i ); test_assert_int_equal( j , find_j ); } - + } } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_lgr_name.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_lgr_name.cpp similarity index 61% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_lgr_name.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_lgr_name.cpp index 466e1b3d51..59d314316f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_lgr_name.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_lgr_name.cpp @@ -1,48 +1,48 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_grid_lgr_name.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_grid_lgr_name.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include -#include +#include /* - Name ..................: LG003017 - Grid nr ...............: 104 + Name ..................: LG003017 + Grid nr ...............: 104 - Name ..................: LG006024 - Grid nr ...............: 2 + Name ..................: LG006024 + Grid nr ...............: 2 - Name ..................: LG005025 - Grid nr ...............: 4 + Name ..................: LG005025 + Grid nr ...............: 4 - Name ..................: LG011029 - Grid nr ...............: 82 + Name ..................: LG011029 + Grid nr ...............: 82 - Name ..................: LG007021 - Grid nr ...............: 100 + Name ..................: LG007021 + Grid nr ...............: 100 - Name ..................: LG003014 - Grid nr ...............: 110 + Name ..................: LG003014 + Grid nr ...............: 110 - Name ..................: /private/joaho/ERT/git/ert/test-data/Statoil/ECLIPSE/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3.EGRID + Name ..................: /private/joaho/ERT/git/ert/test-data/Statoil/ECLIPSE/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3.EGRID */ diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_reset_actnum.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_reset_actnum.cpp similarity index 85% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_reset_actnum.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_reset_actnum.cpp index 22f30ad0ee..c0c39aab37 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_reset_actnum.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_reset_actnum.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_grid_reset_actnum.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_grid_reset_actnum.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include -#include +#include @@ -36,7 +36,7 @@ int main(int argc , char ** argv) { const int actnum2[] = {0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0}; ecl_grid_type * grid = ecl_grid_alloc_rectangular(nx , ny , nz , 1 , 1 , 1 , actnum1 ); - + test_assert_int_equal( g , ecl_grid_get_nactive( grid )); ecl_grid_reset_actnum(grid , actnum2 ); test_assert_int_equal( nactive , ecl_grid_get_nactive( grid )); @@ -58,8 +58,8 @@ int main(int argc , char ** argv) { test_assert_int_equal( 1 , ecl_grid_get_global_index1A( grid , 1 )); test_assert_int_equal( 2 , ecl_grid_get_global_index1A( grid , 2 )); - - + + ecl_grid_free( grid ); exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_simple.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_simple.cpp similarity index 67% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_simple.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_simple.cpp index 37bcbbf180..8d9f9ed5a8 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_simple.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_simple.cpp @@ -1,33 +1,33 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_grid_simple.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_grid_simple.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include -#include +#include int main(int argc , char ** argv) { const char * grid_file = argv[1]; ecl_grid_type * ecl_grid = ecl_grid_alloc( grid_file ); - + test_assert_int_equal( ecl_grid_get_nactive_fracture( ecl_grid ) , 0 ); test_assert_int_equal( ecl_grid_get_active_fracture_index1( ecl_grid , 10 ) , -1 ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_unit_system.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_unit_system.cpp new file mode 100644 index 0000000000..2e75a1c59b --- /dev/null +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_unit_system.cpp @@ -0,0 +1,63 @@ +/* + Copyright (C) 2018 Statoil ASA, Norway. + + The file 'ecl_grid_unit_system.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ +#include +#include + +#include +#include + +#include +#include +#include + + +void test_EGRID(const char * filename, ert_ecl_unit_enum unit_system) { + ecl_grid_type * grid = ecl_grid_alloc_rectangular(4,4,2,1,1,1,NULL); + ecl_grid_fwrite_EGRID2( grid , filename, unit_system); + ecl_grid_free( grid ); + + + ecl_grid_type * grid2 = ecl_grid_alloc(filename); + test_assert_int_equal( ecl_grid_get_unit_system(grid2), unit_system); + ecl_grid_free(grid2); +} + + + +void test_GRID(const char * filename, ert_ecl_unit_enum unit_system) { + ecl_grid_type * grid = ecl_grid_alloc_rectangular(4,4,2,1,1,1,NULL); + ecl_grid_fwrite_GRID2( grid , filename, unit_system); + ecl_grid_free( grid ); + + + ecl_grid_type * grid2 = ecl_grid_alloc(filename); + test_assert_int_equal( ecl_grid_get_unit_system(grid2), unit_system); + ecl_grid_free(grid2); +} + + +int main(int argc, char **argv) { + test_work_area_type * work_area = test_work_area_alloc("grid_export"); + + test_EGRID("METRIC.EGRID", ECL_METRIC_UNITS); + test_EGRID("FIELD.EGRID", ECL_FIELD_UNITS); + test_GRID("METRIC.GRID", ECL_METRIC_UNITS); + test_GRID("FIELD.GRID", ECL_FIELD_UNITS); + + test_work_area_free(work_area); +} diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_volume.c b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_volume.cpp similarity index 95% rename from ThirdParty/Ert/lib/ecl/tests/ecl_grid_volume.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_grid_volume.cpp index 2ef4335333..eb6feb62d1 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_grid_volume.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_grid_volume.cpp @@ -20,12 +20,12 @@ #include #include -#include +#include #include -#include -#include -#include +#include +#include +#include diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_init_file.c b/ThirdParty/Ert/lib/ecl/tests/ecl_init_file.cpp similarity index 90% rename from ThirdParty/Ert/lib/ecl/tests/ecl_init_file.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_init_file.cpp index 0e3d3978d8..d4dbb4a293 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_init_file.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_init_file.cpp @@ -19,16 +19,16 @@ #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include void test_write_header() { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_cmp_string.c b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_cmp_string.cpp similarity index 93% rename from ThirdParty/Ert/lib/ecl/tests/ecl_kw_cmp_string.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_kw_cmp_string.cpp index c12009dbc5..d7d925bc49 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_cmp_string.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_cmp_string.cpp @@ -19,9 +19,9 @@ #include #include -#include -#include -#include +#include +#include +#include diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.c b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.cpp similarity index 80% rename from ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.cpp index 3e00c26c3e..912816025f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_equal.cpp @@ -1,27 +1,27 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_kw_equal.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_kw_equal.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include -#include +#include +#include int main(int argc , char ** argv) { @@ -35,7 +35,7 @@ int main(int argc , char ** argv) { { ecl_kw_type * ecl_kw2 = ecl_kw_alloc_copy( ecl_kw1 ); - + test_assert_true( ecl_kw_equal( ecl_kw1 , ecl_kw2 )); ecl_kw_iset_int( ecl_kw2 , 1 , 77 ); @@ -56,11 +56,11 @@ int main(int argc , char ** argv) { test_assert_true( ecl_kw_content_equal( ecl_kw1 , ecl_ikw )); test_assert_false( ecl_kw_content_equal( ecl_kw1 , ecl_fkw )); } - + test_assert_true( ecl_kw_data_equal( ecl_kw1 , data )); data[0] = 99; test_assert_false( ecl_kw_data_equal( ecl_kw1 , data )); - - + + } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.c b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.cpp similarity index 94% rename from ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.cpp index 4174a7e01c..2cf4a24be8 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_fread.cpp @@ -18,15 +18,15 @@ #include #include -#include +#include #include -#include +#include -#include -#include +#include +#include #include -#include -#include +#include +#include void test_truncated(const char * filename , offset_type truncate_size) { @@ -79,7 +79,7 @@ void test_fread_alloc() { void test_kw_io_charlength() { test_work_area_type * work_area = test_work_area_alloc("ecl_kw_io_charlength"); - { + { const char * KW0 = "QWERTYUI"; const char * KW1 = "ABCDEFGHIJTTTTTTTTTTTTTTTTTTTTTTABCDEFGHIJKLMNOP"; ecl_kw_type * ecl_kw_out0 = ecl_kw_alloc(KW0 , 5, ECL_FLOAT); @@ -99,13 +99,13 @@ void test_kw_io_charlength() { { test_assert_false( util_file_exists( "TEST1")); } - + { FILE * file = util_fopen("TEST2", "w"); ecl_kw_fprintf_grdecl(ecl_kw_out1 , file); fclose(file); } - + { FILE * file = util_fopen("TEST2", "r"); ecl_kw_type * ecl_kw_in = ecl_kw_fscanf_alloc_grdecl( file , KW1 , -1 , ECL_FLOAT); @@ -117,7 +117,7 @@ void test_kw_io_charlength() { fclose(file); } - + ecl_kw_free( ecl_kw_out0 ); ecl_kw_free( ecl_kw_out1 ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_grdecl.c b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_grdecl.cpp similarity index 78% rename from ThirdParty/Ert/lib/ecl/tests/ecl_kw_grdecl.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_kw_grdecl.cpp index bf3a3185b2..a1b49eb55b 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_grdecl.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_grdecl.cpp @@ -1,34 +1,34 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_kw_grdecl.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_kw_grdecl.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include +#include -#include +#include -int main(int argc , char ** argv) { +int main(int argc , char ** argv) { int i; ecl_kw_type * ecl_kw = ecl_kw_alloc("HEAD" , 10 , ECL_INT); - for (i=0; i < 10; i++) + for (i=0; i < 10; i++) ecl_kw_iset_int(ecl_kw , i , i ); { @@ -37,11 +37,11 @@ int main(int argc , char ** argv) { ecl_kw_fprintf_grdecl(ecl_kw , stream ); fclose(stream); - + stream = util_fopen( "FILE.grdecl" , "r"); { ecl_kw_type * ecl_kw2 = ecl_kw_fscanf_alloc_grdecl( stream , "HEAD" , 10 , ECL_INT); - + test_assert_not_NULL( ecl_kw2 ); test_assert_true( ecl_kw_equal( ecl_kw , ecl_kw2)); ecl_kw_free( ecl_kw2 ); @@ -55,11 +55,11 @@ int main(int argc , char ** argv) { stream = util_fopen( "FILE.grdecl" , "r"); { ecl_kw_type * ecl_kw2 = ecl_kw_fscanf_alloc_grdecl( stream , "HEAD" , 10 , ECL_INT); - + test_assert_NULL( ecl_kw2 ); ecl_kw2 = ecl_kw_fscanf_alloc_grdecl( stream , "HEAD1234" , 10 , ECL_INT); test_assert_not_NULL( ecl_kw2 ); - + test_assert_string_equal( ecl_kw_get_header( ecl_kw2 ) , "HEAD1234" ); test_assert_true( ecl_kw_content_equal( ecl_kw , ecl_kw2 )); ecl_kw_free( ecl_kw2 ); @@ -68,6 +68,6 @@ int main(int argc , char ** argv) { test_work_area_free( work_area ); } ecl_kw_free( ecl_kw ); - + exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.c b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.cpp similarity index 89% rename from ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.cpp index 5ebcee8f88..0f4a883526 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_kw_init.cpp @@ -18,15 +18,15 @@ #include #include -#include -#include +#include +#include #include -#include +#include void test_int() { - size_t N = 1000; + int N = 1000; int i; ecl_kw_type * kw = ecl_kw_alloc("KW" , N , ECL_INT); for (i=0; i < N; i++) @@ -37,7 +37,7 @@ void test_int() { void test_double() { - size_t N = 1000; + int N = 1000; double i; ecl_kw_type * kw = ecl_kw_alloc("KW" , N , ECL_DOUBLE); for (i=0; i < N; i++) @@ -48,7 +48,7 @@ void test_double() { void test_float() { - size_t N = 1000; + int N = 1000; int i; ecl_kw_type * kw = ecl_kw_alloc("KW" , N , ECL_FLOAT); for (i=0; i < N; i++) @@ -59,8 +59,8 @@ void test_float() { void test_bool() { - size_t N = 100; - bool * data = util_malloc(N * sizeof * data); + int N = 100; + bool * data = (bool *) util_malloc(N * sizeof * data); ecl_kw_type * kw = ecl_kw_alloc("BOOL", N , ECL_BOOL); for (int i=0; i < N/2; i++) { ecl_kw_iset_bool(kw, 2*i, true); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_layer.c b/ThirdParty/Ert/lib/ecl/tests/ecl_layer.cpp similarity index 92% rename from ThirdParty/Ert/lib/ecl/tests/ecl_layer.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_layer.cpp index e6420cecc4..ab5d85c6d5 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_layer.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_layer.cpp @@ -18,12 +18,13 @@ #include #include -#include -#include -#include +#include -#include +#include +#include +#include +#include "detail/ecl/layer_cxx.hpp" void test_create() { layer_type * layer = layer_alloc(10,20); @@ -199,7 +200,7 @@ void test_edge() { void test_walk() { layer_type * layer = layer_alloc(10,10); - struct_vector_type * corner_list = struct_vector_alloc( sizeof(int_point2d_type)); + std::vector corner_list; int_vector_type * cell_list = int_vector_alloc(0,0); test_assert_false( layer_trace_block_edge( layer , 4 , 4 , 100 , corner_list , cell_list)); @@ -207,26 +208,20 @@ void test_walk() { test_assert_false( layer_trace_block_edge( layer , 4 , 4 , 200 , corner_list , cell_list)); test_assert_true( layer_trace_block_edge( layer , 4 , 4 , 100 , corner_list , cell_list)); - test_assert_int_equal( struct_vector_get_size( corner_list ) , 4); + test_assert_int_equal( corner_list.size(), 4); test_assert_int_equal( int_vector_size( cell_list ) , 1 ); { - int_point2d_type point; - - struct_vector_iget( corner_list , 0 , &point); - test_assert_int_equal( 4 , point.i ); - test_assert_int_equal( 4 , point.j ); + test_assert_int_equal( 4 , corner_list[0].i ); + test_assert_int_equal( 4 , corner_list[0].j ); - struct_vector_iget( corner_list , 1 , &point); - test_assert_int_equal( 5 , point.i ); - test_assert_int_equal( 4 , point.j ); + test_assert_int_equal( 5 , corner_list[1].i ); + test_assert_int_equal( 4 , corner_list[1].j ); - struct_vector_iget( corner_list , 2 , &point); - test_assert_int_equal( 5 , point.i ); - test_assert_int_equal( 5 , point.j ); + test_assert_int_equal( 5 , corner_list[2].i ); + test_assert_int_equal( 5 , corner_list[2].j ); - struct_vector_iget( corner_list , 3 , &point); - test_assert_int_equal( 4 , point.i ); - test_assert_int_equal( 5 , point.j ); + test_assert_int_equal( 4 , corner_list[3].i ); + test_assert_int_equal( 5 , corner_list[3].j ); } { @@ -247,7 +242,7 @@ void test_walk() { int_vector_select_unique( true_cell_list ); test_assert_true( layer_trace_block_edge( layer , 3 , 3 , 100 , corner_list , cell_list)); - test_assert_int_equal( 16 , struct_vector_get_size( corner_list )); + test_assert_int_equal( 16 , corner_list.size()); test_assert_int_equal( 12 , int_vector_size( cell_list )); int_vector_fprintf( cell_list , stdout , " cell_list" , "%3d"); @@ -258,7 +253,6 @@ void test_walk() { } int_vector_free( cell_list ); - struct_vector_free( corner_list ); layer_free( layer ); } @@ -320,7 +314,7 @@ void test_content2() { int_vector_type * i_list = int_vector_alloc(0,0); int_vector_type * j_list = int_vector_alloc(0,0); int_vector_type * cell_list = int_vector_alloc(0,0); - struct_vector_type * corner_list = struct_vector_alloc( sizeof(int_point2d_type) ); + std::vector corner_list; for (j=0; j < 5; j++) { @@ -335,7 +329,6 @@ void test_content2() { } } - struct_vector_free( corner_list ); int_vector_free( i_list ); int_vector_free( j_list ); int_vector_free( cell_list ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_layer_statoil.c b/ThirdParty/Ert/lib/ecl/tests/ecl_layer_statoil.cpp similarity index 79% rename from ThirdParty/Ert/lib/ecl/tests/ecl_layer_statoil.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_layer_statoil.cpp index df41e92c53..912248dfd4 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_layer_statoil.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_layer_statoil.cpp @@ -1,30 +1,33 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_layer_statoil.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_layer_statoil.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include + +#include #include -#include -#include -#include +#include +#include +#include +#include "detail/ecl/layer_cxx.hpp" ecl_kw_type * alloc_faultblock_kw( const char * filename, int grid_size) { FILE * stream = util_fopen( filename , "r"); @@ -41,15 +44,15 @@ void test_layer( const ecl_grid_type * ecl_grid , const ecl_kw_type * faultblock layer_type * layer = layer_alloc( nx , ny ); int i,j; - for (j=0; j < ny; j++) + for (j=0; j < ny; j++) for (i=0; i < nx; i++) { int g = ecl_grid_get_global_index3( ecl_grid , i , j , k ); int fblk = ecl_kw_iget_int( faultblock_kw , g ); layer_iset_cell_value( layer , i , j , fblk ); } - + { - struct_vector_type * corner_list = struct_vector_alloc( sizeof(int_point2d_type) ); + std::vector corner_list; int_vector_type * i_list = int_vector_alloc(0,0); int_vector_type * j_list = int_vector_alloc(0,0); int_vector_type * cell_list = int_vector_alloc(0,0); @@ -64,12 +67,11 @@ void test_layer( const ecl_grid_type * ecl_grid , const ecl_kw_type * faultblock } } test_assert_int_equal( 0 , layer_get_cell_sum( layer )); - struct_vector_free( corner_list ); int_vector_free( i_list ); int_vector_free( j_list ); int_vector_free( cell_list ); } - + layer_free( layer ); } @@ -84,7 +86,7 @@ int main(int argc , char ** argv) { for (k=0; k < ecl_grid_get_nz( ecl_grid ); k++) test_layer( ecl_grid , faultblock_kw , k ); - + ecl_kw_free( faultblock_kw ); ecl_grid_free( ecl_grid ); exit(0); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_lfs.c b/ThirdParty/Ert/lib/ecl/tests/ecl_lfs.cpp similarity index 95% rename from ThirdParty/Ert/lib/ecl/tests/ecl_lfs.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_lfs.cpp index 649541b669..6d2048cfdb 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_lfs.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_lfs.cpp @@ -18,10 +18,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.c b/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.cpp similarity index 73% rename from ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.cpp index 6ce84cc4db..ca798963d8 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_name.cpp @@ -1,29 +1,29 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_lgr_name.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_lgr_name.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include -#include +#include -int main( int argc , char ** argv) { +int main( int argc , char ** argv) { ecl_grid_type * grid = ecl_grid_alloc( argv[1] ); int num_lgr = ecl_grid_get_num_lgr( grid ); @@ -32,9 +32,9 @@ int main( int argc , char ** argv) { ecl_grid_type * lgr_from_index = ecl_grid_iget_lgr( grid, lgr_index ); int lgr_nr = ecl_grid_get_lgr_nr( lgr_from_index); ecl_grid_type * lgr_from_nr = ecl_grid_get_lgr_from_lgr_nr( grid , lgr_nr); - + test_assert_ptr_equal( lgr_from_index , lgr_from_nr ); - + test_assert_string_equal( ecl_grid_get_lgr_name( grid , lgr_nr) , ecl_grid_iget_lgr_name( grid , lgr_index)); printf("Grid[%d:%d] : %s \n",lgr_index , lgr_nr , ecl_grid_iget_lgr_name( grid , lgr_index )); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.c b/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.cpp similarity index 68% rename from ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.cpp index 88dfc7552c..a585de4fb2 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_lgr_test.cpp @@ -1,41 +1,41 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_lgr_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_lgr_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include -#include -#include -#include +#include +#include +#include int main(int argc , char ** argv) { const char * grid_file = argv[1]; ecl_grid_type * ecl_grid = ecl_grid_alloc( grid_file ); ecl_file_type * ecl_file = ecl_file_open( grid_file , 0); - + ecl_grid_test_lgr_consistency( ecl_grid ); if (ecl_file_get_num_named_kw( ecl_file , COORD_KW )) test_assert_int_equal( ecl_file_get_num_named_kw( ecl_file , COORD_KW ) - 1, ecl_grid_get_num_lgr( ecl_grid )); - + ecl_grid_free( ecl_grid ); ecl_file_close( ecl_file); exit(0); diff --git a/ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data_statoil_root.c b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_data_statoil_root.cpp similarity index 92% rename from ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data_statoil_root.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_data_statoil_root.cpp index eb4ef25f7c..784864bf97 100644 --- a/ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data_statoil_root.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_data_statoil_root.cpp @@ -16,18 +16,18 @@ for more details. */ -#include -#include -#include +#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include #include -#include -#include +#include +#include @@ -62,7 +62,7 @@ void test_alloc_file_tran(char * filename) { int index; index = find_index( nnc_geo, 0, 0, 541, 14507); - test_assert_double_equal(13.784438, ecl_nnc_data_iget_value( nnc_geo_data, index) ); + test_assert_double_equal(13.784438, ecl_nnc_data_iget_value( nnc_geo_data, index) ); index = find_index( nnc_geo, 0, 0, 48365, 118191); test_assert_double_equal(0.580284 , ecl_nnc_data_iget_value( nnc_geo_data, index) ); @@ -99,7 +99,7 @@ void test_alloc_file_flux(char * filename, int file_num) { ecl_file_type * restart_file = ecl_file_open( restart_file_name , 0 ); ecl_grid_type * grid = ecl_grid_alloc( grid_file_name ); ecl_nnc_geometry_type * nnc_geo = ecl_nnc_geometry_alloc( grid ); - { + { ecl_file_view_type * view_file = ecl_file_get_global_view( restart_file ); ecl_nnc_data_type * nnc_flux_data = ecl_nnc_data_alloc_wat_flux(grid, nnc_geo, view_file); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export.c b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export.cpp similarity index 85% rename from ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export.cpp index 6cafe9402e..556e2df7a0 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export.cpp @@ -19,16 +19,16 @@ #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include @@ -97,7 +97,7 @@ void test_nnc_export_missing_TRANX(const char * name ) { if (util_entry_exists(init_file_name)) { ecl_grid_type * grid = ecl_grid_alloc( grid_file_name ); ecl_file_type * init_file = ecl_file_open( init_file_name , 0); - ecl_nnc_type * nnc_data1 = util_calloc( ecl_nnc_export_get_size( grid ) , sizeof * nnc_data1 ); + ecl_nnc_type * nnc_data1 = (ecl_nnc_type *) util_calloc( ecl_nnc_export_get_size( grid ) , sizeof * nnc_data1 ); int count = ecl_nnc_export(grid, init_file, nnc_data1); int i; test_assert_int_equal( count , 0 ); @@ -113,8 +113,8 @@ void test_export(const char * name, bool have_tran_data) { ecl_grid_type * grid = ecl_grid_alloc( grid_file_name ); ecl_file_type * grid_file = ecl_file_open( grid_file_name , 0 ); ecl_file_type * init_file = ecl_file_open( init_file_name , 0); - ecl_nnc_type * nnc_data1 = util_calloc( ecl_nnc_export_get_size( grid ) , sizeof * nnc_data1 ); - ecl_nnc_type * nnc_data2 = util_calloc( ecl_nnc_export_get_size( grid ) , sizeof * nnc_data2 ); + ecl_nnc_type * nnc_data1 = (ecl_nnc_type *) util_calloc( ecl_nnc_export_get_size( grid ) , sizeof * nnc_data1 ); + ecl_nnc_type * nnc_data2 = (ecl_nnc_type *) util_calloc( ecl_nnc_export_get_size( grid ) , sizeof * nnc_data2 ); { @@ -237,7 +237,7 @@ void test_export(const char * name, bool have_tran_data) { ecl_nnc_geometry_type * nnc_geo = ecl_nnc_geometry_alloc( grid ); ecl_file_view_type * view_file = ecl_file_get_global_view( init_file ); ecl_nnc_data_type * nnc_geo_data = ecl_nnc_data_alloc_tran(grid, nnc_geo, view_file); - + test_assert_int_equal( ecl_nnc_export_get_size( grid ), ecl_nnc_geometry_size( nnc_geo )); for (int i=0; i < ecl_nnc_geometry_size( nnc_geo ); i++) { const ecl_nnc_pair_type *nnc_pair = ecl_nnc_geometry_iget( nnc_geo , i ); @@ -269,38 +269,12 @@ void test_export(const char * name, bool have_tran_data) { void test_cmp() { - ecl_nnc_type nnc1 = {.grid_nr1 = 1, - .grid_nr2 = 1, - .global_index1 = 1, - .global_index2 = 1}; - - ecl_nnc_type nnc2 = {.grid_nr1 = 1, // nnc1 == nnc2 - .grid_nr2 = 1, - .global_index1 = 1, - .global_index2 = 1 }; - - ecl_nnc_type nnc3 = {.grid_nr1 = 4, // nnc3 > nnc1 - .grid_nr2 = 1, - .global_index1 = 1, - .global_index2 = 1 }; - - - ecl_nnc_type nnc4 = {.grid_nr1 = 4, // nnc4 > nnc1 - .grid_nr2 = 2, // nnc4 > nnc2 - .global_index1 = 1, - .global_index2 = 1 }; - - ecl_nnc_type nnc5 = {.grid_nr1 = 4, // nnc5 > nnc4 - .grid_nr2 = 2, - .global_index1 = 3, - .global_index2 = 1 }; - - - ecl_nnc_type nnc6 = {.grid_nr1 = 4, // nnc6 > nnc5 - .grid_nr2 = 2, - .global_index1 = 3, - .global_index2 = 5 }; - + ecl_nnc_type nnc1 = {1,1,1,1}; + ecl_nnc_type nnc2 = {1,1,1,1}; + ecl_nnc_type nnc3 = {4,1,1,1}; + ecl_nnc_type nnc4 = {4,2,1,1}; + ecl_nnc_type nnc5 = {4,2,3,1}; + ecl_nnc_type nnc6 = {4,2,3,5}; test_assert_int_equal( 0 , ecl_nnc_sort_cmp( &nnc1 , &nnc2 )); test_assert_int_equal( 1 , ecl_nnc_sort_cmp( &nnc3 , &nnc1 )); @@ -313,13 +287,16 @@ void test_cmp() { void test_sort() { const int N = 1000; - ecl_nnc_type * nnc_list = util_calloc(N , sizeof * nnc_list ); + ecl_nnc_type * nnc_list = (ecl_nnc_type *) util_calloc(N , sizeof * nnc_list ); int i; for (i=0; i < N; i++) { - ecl_nnc_type nnc = {.grid_nr1 = (i % 19), - .grid_nr2 = (i % 3), - .global_index1 = (i % 7), - .global_index2 = (i % 13)}; + ecl_nnc_type nnc; + + nnc.grid_nr1 = (i % 19); + nnc.grid_nr2 = (i % 3); + nnc.global_index1 = (i % 7); + nnc.global_index2 = (i % 13); + nnc_list[i] = nnc; } ecl_nnc_sort( nnc_list , N ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_get_tran.c b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_get_tran.cpp similarity index 91% rename from ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_get_tran.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_get_tran.cpp index 881a4d3265..fb40436af0 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_get_tran.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_export_get_tran.cpp @@ -1,31 +1,31 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_nnc_export.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_nnc_export.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. ll - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include -#include -#include +#include +#include +#include void test_get_tran(const char * name) { char * grid_file_name = ecl_util_alloc_filename(NULL , name , ECL_EGRID_FILE , false , -1); @@ -51,7 +51,7 @@ void test_get_tran(const char * name) { ecl_kw_type * tran_kw = ecl_nnc_export_get_tran_kw( init_file , TRANNNC_KW , 48 ); test_assert_true( ecl_kw_is_instance( tran_kw )); test_assert_int_equal( 0 , ecl_kw_get_size( tran_kw )); - + tran_kw = ecl_nnc_export_get_tran_kw( init_file , TRANGL_KW , 48 ); test_assert_int_equal( 282 , ecl_kw_get_size( tran_kw )); test_assert_double_equal( 22.922695 , ecl_kw_iget_as_double( tran_kw , 0 )); @@ -63,7 +63,7 @@ void test_get_tran(const char * name) { ecl_kw_type * tran_kw = ecl_nnc_export_get_tran_kw( init_file , TRANNNC_KW , 99 ); test_assert_true( ecl_kw_is_instance( tran_kw )); test_assert_int_equal( 0 , ecl_kw_get_size( tran_kw )); - + tran_kw = ecl_nnc_export_get_tran_kw( init_file , TRANGL_KW , 99 ); test_assert_int_equal( 693 , ecl_kw_get_size( tran_kw )); test_assert_double_equal( 0.25534782 , ecl_kw_iget_as_double( tran_kw , 0 )); @@ -76,7 +76,7 @@ void test_get_tran(const char * name) { ecl_kw_type * tran_kw = ecl_nnc_export_get_tran_kw( init_file , TRANNNC_KW , 10 ); test_assert_true( ecl_kw_is_instance( tran_kw )); test_assert_int_equal( 0 , ecl_kw_get_size( tran_kw )); - + tran_kw = ecl_nnc_export_get_tran_kw( init_file , TRANGL_KW , 10 ); test_assert_int_equal( 260 , ecl_kw_get_size( tran_kw )); test_assert_double_equal( 0.87355447 , ecl_kw_iget_as_double( tran_kw , 0 )); @@ -89,13 +89,13 @@ void test_get_tran(const char * name) { ecl_kw_type * tran_kw = ecl_nnc_export_get_tran_kw( init_file , TRANNNC_KW , 110 ); test_assert_true( ecl_kw_is_instance( tran_kw )); test_assert_int_equal( 0 , ecl_kw_get_size( tran_kw )); - + tran_kw = ecl_nnc_export_get_tran_kw( init_file , TRANGL_KW , 110 ); test_assert_int_equal( 208 , ecl_kw_get_size( tran_kw )); test_assert_double_equal( 17.287283 , ecl_kw_iget_as_double( tran_kw , 0 )); test_assert_double_equal( 569.26312 , ecl_kw_iget_as_double( tran_kw , 207 )); } - + free( init_file_name ); free(grid_file_name); @@ -106,13 +106,13 @@ void test_get_tran(const char * name) { -void test_tranLL( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1 , int lgr_nr2, +void test_tranLL( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1 , int lgr_nr2, int size, - double first , + double first , double last) { - + ecl_kw_type * ecl_kw = ecl_nnc_export_get_tranll_kw(grid , init_file , lgr_nr1 , lgr_nr2 ); - + printf("lgr: %d -> %d \n",lgr_nr1 , lgr_nr2); test_assert_not_NULL(ecl_kw); test_assert_true(ecl_kw_is_instance( ecl_kw )); @@ -129,13 +129,13 @@ void test_get_tranLL(const char * name) { ecl_grid_type * grid = ecl_grid_alloc( grid_file_name ); ecl_file_type * grid_file = ecl_file_open( grid_file_name , 0 ); ecl_file_type * init_file = ecl_file_open( init_file_name , 0 ); - + test_tranLL( grid , init_file , ecl_grid_get_lgr_nr_from_name( grid , "LG003017" ), ecl_grid_get_lgr_nr_from_name( grid , "LG003018" ), 172 , 5.3957253 , 1.0099934); test_tranLL( grid , init_file , ecl_grid_get_lgr_nr_from_name( grid , "LG002016" ), ecl_grid_get_lgr_nr_from_name( grid , "LG002017" ), 93 , 1.4638059 , 0.36407200 ); - + test_tranLL( grid , init_file , ecl_grid_get_lgr_nr_from_name( grid , "LG002016" ), ecl_grid_get_lgr_nr_from_name( grid , "LG003016" ), 56 , 2.7360380 , 10.053267); @@ -144,7 +144,7 @@ void test_get_tranLL(const char * name) { test_tranLL( grid , init_file , ecl_grid_get_lgr_nr_from_name( grid , "LG009027" ), ecl_grid_get_lgr_nr_from_name( grid , "LG008027" ), 317 , 0.040260997 , 0.0066288318); - + free( init_file_name ); free(grid_file_name); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_geometry.c b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_geometry.cpp similarity index 89% rename from ThirdParty/Ert/lib/ecl/tests/ecl_nnc_geometry.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_geometry.cpp index 1b2d0af2d7..d457ee7b6b 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_geometry.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_geometry.cpp @@ -15,15 +15,15 @@ See the GNU General Public License at for more details. */ -#include -#include +#include +#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include void test_create_empty() { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list.c b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list.cpp similarity index 87% rename from ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list.cpp index 64c60819af..dd4f2e616a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list.cpp @@ -1,28 +1,28 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_nnc_index_list.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_nnc_index_list.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include +#include -#include +#include void test_create() { @@ -38,7 +38,7 @@ void test_create() { void test_content() { nnc_index_list_type * index_list = nnc_index_list_alloc(); - + nnc_index_list_add_index( index_list , 0 ); nnc_index_list_add_index( index_list , 1 ); nnc_index_list_add_index( index_list , 2 ); @@ -52,7 +52,7 @@ void test_content() { test_assert_int_equal( 1 , int_vector_iget( list , 1)); test_assert_int_equal( 2 , int_vector_iget( list , 2)); test_assert_int_equal( 3 , int_vector_iget( list , 3)); - + } nnc_index_list_free( index_list ); } @@ -60,7 +60,7 @@ void test_content() { void test_sort_unique() { nnc_index_list_type * index_list = nnc_index_list_alloc(); - + nnc_index_list_add_index( index_list , 3 ); nnc_index_list_add_index( index_list , 1 ); nnc_index_list_add_index( index_list , 2 ); @@ -74,7 +74,7 @@ void test_sort_unique() { test_assert_int_equal( 1 , int_vector_iget( list , 1)); test_assert_int_equal( 2 , int_vector_iget( list , 2)); test_assert_int_equal( 3 , int_vector_iget( list , 3)); - + } nnc_index_list_add_index( index_list , 3 ); nnc_index_list_add_index( index_list , 1 ); @@ -88,7 +88,7 @@ void test_sort_unique() { test_assert_int_equal( 1 , int_vector_iget( list , 1)); test_assert_int_equal( 2 , int_vector_iget( list , 2)); test_assert_int_equal( 3 , int_vector_iget( list , 3)); - + } nnc_index_list_free( index_list ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list_grid.c b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list_grid.cpp similarity index 75% rename from ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list_grid.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list_grid.cpp index 65645a5f2a..cfec278eaa 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list_grid.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_index_list_grid.cpp @@ -1,30 +1,30 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_nnc_index_list_grid.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_nnc_index_list_grid.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include +#include -#include -#include -#include +#include +#include +#include @@ -36,15 +36,15 @@ int main( int argc , char ** argv) { const ecl_kw_type * nnc1_kw = ecl_file_iget_named_kw( gfile , "NNC1" ,0 ); const ecl_kw_type * nnc2_kw = ecl_file_iget_named_kw( gfile , "NNC2" ,0 ); const int_vector_type * index_list = ecl_grid_get_nnc_index_list( grid ); - + { int_vector_type * nnc = int_vector_alloc(0,0); - + int_vector_set_many( nnc , 0 , ecl_kw_get_ptr( nnc1_kw ) , ecl_kw_get_size( nnc1_kw )); int_vector_append_many( nnc , ecl_kw_get_ptr( nnc2_kw ) , ecl_kw_get_size( nnc2_kw )); int_vector_select_unique( nnc ); test_assert_int_equal( int_vector_size( index_list ) , int_vector_size( nnc )); - + { int i; for (i=0; i < int_vector_size( nnc ); i++) @@ -52,7 +52,7 @@ int main( int argc , char ** argv) { } int_vector_free( nnc ); } - + ecl_file_close( gfile ); ecl_grid_free( grid ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_info_test.c b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_info_test.cpp similarity index 76% rename from ThirdParty/Ert/lib/ecl/tests/ecl_nnc_info_test.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_info_test.cpp index 70e5bd240b..dba5876244 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_info_test.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_info_test.cpp @@ -1,55 +1,55 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_nnc_info_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_nnc_info_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include void test_equal( ) { int lgr_nr = 1; - nnc_info_type * nnc_info1 = nnc_info_alloc(lgr_nr); - nnc_info_type * nnc_info2 = nnc_info_alloc(lgr_nr); + nnc_info_type * nnc_info1 = nnc_info_alloc(lgr_nr); + nnc_info_type * nnc_info2 = nnc_info_alloc(lgr_nr); test_assert_false( nnc_info_equal( NULL , nnc_info1 )); test_assert_false( nnc_info_equal( nnc_info1, NULL )); - + test_assert_true( nnc_info_equal( nnc_info1 , nnc_info2 )); - + nnc_info_add_nnc(nnc_info1, lgr_nr, 3 , 0); test_assert_false( nnc_info_equal( nnc_info1 , nnc_info2 )); nnc_info_add_nnc(nnc_info2, lgr_nr, 3 , 0); test_assert_true( nnc_info_equal( nnc_info1 , nnc_info2 )); - + nnc_info_add_nnc( nnc_info1 , lgr_nr + 1 , 10 , 10 ); nnc_info_add_nnc( nnc_info2 , lgr_nr + 2 , 11 , 11 ); test_assert_false( nnc_info_equal( nnc_info1 , nnc_info2 )); - + nnc_info_add_nnc( nnc_info1 , lgr_nr + 2 , 11 , 11 ); nnc_info_add_nnc( nnc_info2 , lgr_nr + 1 , 10 , 10 ); test_assert_true( nnc_info_equal( nnc_info1 , nnc_info2 )); @@ -59,7 +59,7 @@ void test_equal( ) { void test_copy( ) { int lgr_nr = 1; - nnc_info_type * nnc_info1 = nnc_info_alloc(lgr_nr); + nnc_info_type * nnc_info1 = nnc_info_alloc(lgr_nr); nnc_info_add_nnc( nnc_info1 , lgr_nr + 1 , 11 , 11 ); nnc_info_add_nnc( nnc_info1 , lgr_nr + 2 , 11 , 11 ); nnc_info_add_nnc( nnc_info1 , lgr_nr + 1 , 111 , 111 ); @@ -75,38 +75,38 @@ void test_copy( ) { void basic_test() { int lgr_nr = 77; - nnc_info_type * nnc_info = nnc_info_alloc(lgr_nr); + nnc_info_type * nnc_info = nnc_info_alloc(lgr_nr); test_assert_int_equal( 0 , nnc_info_get_total_size( nnc_info )); test_assert_int_equal( lgr_nr , nnc_info_get_lgr_nr( nnc_info )); test_assert_true(nnc_info_is_instance(nnc_info)); - test_assert_not_NULL(nnc_info); - + test_assert_not_NULL(nnc_info); + nnc_info_add_nnc(nnc_info, lgr_nr, 110 , 0); test_assert_int_equal( 1, nnc_info_get_total_size( nnc_info )); - + nnc_info_add_nnc(nnc_info, 1, 110 , 1); nnc_info_add_nnc(nnc_info, 1, 111 , 2); test_assert_int_equal( 3, nnc_info_get_total_size( nnc_info )); - + nnc_vector_type * nnc_vector = nnc_info_get_vector( nnc_info , 1); - const int_vector_type * nnc_cells = nnc_info_get_grid_index_list(nnc_info, 1); - test_assert_int_equal(int_vector_size(nnc_cells), 2); + const int_vector_type * nnc_cells = nnc_info_get_grid_index_list(nnc_info, 1); + test_assert_int_equal(int_vector_size(nnc_cells), 2); test_assert_ptr_equal( nnc_cells , nnc_vector_get_grid_index_list( nnc_vector )); nnc_vector_type * nnc_vector_null = nnc_info_get_vector( nnc_info , 2); - const int_vector_type * nnc_cells_null = nnc_info_get_grid_index_list(nnc_info, 2); - test_assert_NULL(nnc_cells_null); - test_assert_NULL(nnc_vector_null); - + const int_vector_type * nnc_cells_null = nnc_info_get_grid_index_list(nnc_info, 2); + test_assert_NULL(nnc_cells_null); + test_assert_NULL(nnc_vector_null); + nnc_vector_type * nnc_vector_self = nnc_info_get_self_vector( nnc_info ); const nnc_vector_type * nnc_vector_77 = nnc_info_get_vector( nnc_info , lgr_nr ); test_assert_ptr_equal( nnc_vector_77 , nnc_vector_self ); - const int_vector_type * nnc_cells_77 = nnc_info_get_grid_index_list(nnc_info, lgr_nr); - const int_vector_type * nnc_cells_self = nnc_info_get_self_grid_index_list(nnc_info); + const int_vector_type * nnc_cells_77 = nnc_info_get_grid_index_list(nnc_info, lgr_nr); + const int_vector_type * nnc_cells_self = nnc_info_get_self_grid_index_list(nnc_info); test_assert_ptr_equal( nnc_cells_77 , nnc_cells_self ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.c b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.cpp similarity index 72% rename from ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.cpp index 4de0c83190..2827077c4e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_pair.cpp @@ -18,19 +18,14 @@ #include #include -#include +#include #include -#include +#include void test_pair( int grid1_1 , int grid1_2 , int grid2_1, int grid2_2, bool expected) { - ecl_nnc_pair_type pair1 = {.grid_nr1 = grid1_1, .grid_nr2 = grid1_2, - .global_index1 = 0, - .global_index2 = 0}; - - ecl_nnc_pair_type pair2 = {.grid_nr1 = grid2_1, .grid_nr2 = grid2_2, - .global_index1 = 0, - .global_index2 = 0}; + ecl_nnc_pair_type pair1 = {grid1_1, grid1_2, 0, 0}; + ecl_nnc_pair_type pair2 = {grid2_1, grid2_2, 0, 0}; test_assert_bool_equal( ecl_nnc_geometry_same_kw( &pair1 , &pair2 ), expected); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.c b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.cpp similarity index 86% rename from ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.cpp index e547f14397..5a7d72d958 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_test.cpp @@ -1,32 +1,32 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_nnc_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_nnc_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include +#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include void test_scan( const char * grid_filename) { @@ -52,14 +52,14 @@ void test_scan( const char * grid_filename) { for (i=0; i < ecl_kw_get_size(nnc1_kw); i++) { const int g1 = ecl_kw_iget_int( nnc1_kw , i ) - 1; const int g2 = ecl_kw_iget_int( nnc2_kw , i ) - 1; - + if (g2 < ecl_grid_get_global_size( lgr )) { // Skipping matrix <-> fracture link in dual poro. const nnc_info_type * nnc_info = ecl_grid_get_cell_nnc_info1( lgr , g1 ); const int_vector_type * index_list = nnc_info_get_grid_index_list( nnc_info , lgr_nr); test_assert_not_NULL( nnc_info ); test_assert_int_not_equal( -1 , int_vector_index( index_list , g2 )); } - } + } } } } @@ -75,7 +75,7 @@ void test_scan( const char * grid_filename) { for (i=0; i < ecl_kw_get_size(nncg_kw); i++) { const int g = ecl_kw_iget_int( nncg_kw , i ) - 1; const int l = ecl_kw_iget_int( nncl_kw , i ) - 1; - + const nnc_info_type * nnc_info = ecl_grid_get_cell_nnc_info1( ecl_grid , g ); test_assert_not_NULL( nnc_info ); { @@ -83,29 +83,29 @@ void test_scan( const char * grid_filename) { test_assert_not_NULL( index_list ); test_assert_int_not_equal( -1 , int_vector_index( index_list , l )); } - } + } } } - + /* Amalgamated: LGR -> LGR */ { if (ecl_file_view_has_kw( nnc_view , NNCHEADA_KW)) { ecl_kw_type * nncheada_kw = ecl_file_view_iget_named_kw(nnc_view , NNCHEADA_KW , 0); ecl_kw_type * nnc1_kw = ecl_file_view_iget_named_kw(nnc_view , NNA1_KW , 0 ); ecl_kw_type * nnc2_kw = ecl_file_view_iget_named_kw(nnc_view , NNA2_KW , 0 ); - int lgr_nr1 = ecl_kw_iget_int( nncheada_kw , NNCHEADA_ILOC1_INDEX); + int lgr_nr1 = ecl_kw_iget_int( nncheada_kw , NNCHEADA_ILOC1_INDEX); int lgr_nr2 = ecl_kw_iget_int( nncheada_kw , NNCHEADA_ILOC2_INDEX); - + ecl_grid_type * lgr1 = ecl_grid_get_lgr_from_lgr_nr( ecl_grid , lgr_nr1); for (int i=0; i < ecl_kw_get_size(nnc1_kw); i++) { const int g1 = ecl_kw_iget_int( nnc1_kw , i ) - 1; const int g2 = ecl_kw_iget_int( nnc2_kw , i ) - 1; - + const nnc_info_type * nnc_info = ecl_grid_get_cell_nnc_info1( lgr1 , g1 ); const int_vector_type * index_list = nnc_info_get_grid_index_list( nnc_info , lgr_nr2); test_assert_not_NULL( nnc_info ); test_assert_int_not_equal( -1 , int_vector_index( index_list , g2 )); - } + } } } @@ -113,15 +113,15 @@ void test_scan( const char * grid_filename) { } } - -int main(int argc , char ** argv) { + +int main(int argc , char ** argv) { int iarg; for (iarg = 1; iarg < argc; iarg++) { printf("Checking file: %s \n",argv[iarg]); test_scan( argv[iarg] ); } - + exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_vector.c b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_vector.cpp similarity index 87% rename from ThirdParty/Ert/lib/ecl/tests/ecl_nnc_vector.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_nnc_vector.cpp index 240ff29bb4..e568531756 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_vector.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_nnc_vector.cpp @@ -1,32 +1,32 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_nnc_vector.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_nnc_vector.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include + +#include -#include - void test_basic() { int lgr_nr = 100; nnc_vector_type * vector = nnc_vector_alloc( lgr_nr ); - + test_assert_true( nnc_vector_is_instance( vector )); test_assert_int_equal( lgr_nr , nnc_vector_get_lgr_nr( vector )); @@ -53,7 +53,7 @@ void test_basic() { test_assert_int_equal( 200 , int_vector_iget( grid_index_list , 1 )); test_assert_int_equal( 300 , int_vector_iget( grid_index_list , 2 )); } - + nnc_vector_free( vector ); } @@ -62,7 +62,7 @@ void test_copy() { nnc_vector_type * vector1 = nnc_vector_alloc( lgr_nr ); nnc_vector_type * vector2 = nnc_vector_alloc( lgr_nr ); nnc_vector_type * vector3 = NULL; - + test_assert_true( nnc_vector_equal( vector1 , vector2 )); test_assert_false( nnc_vector_equal( vector1 , vector3 )); test_assert_false( nnc_vector_equal( vector3 , vector1 )); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_region.c b/ThirdParty/Ert/lib/ecl/tests/ecl_region.cpp similarity index 82% rename from ThirdParty/Ert/lib/ecl/tests/ecl_region.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_region.cpp index 2c0b339814..2ddf344fa3 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_region.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_region.cpp @@ -1,27 +1,27 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ecl_region.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ecl_region.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include -#include -#include +#include +#include void test_list( int volume , int nactive , ecl_region_type * region ) { const int_vector_type * active_list; @@ -47,14 +47,14 @@ void test_slice( const ecl_grid_type * grid ) { int nz = ecl_grid_get_nz( grid ); int nactive = ecl_grid_get_nactive( grid ); ecl_region_type * region = ecl_region_alloc( grid , false ); - + ecl_region_select_i1i2( region , 0 , nx - 1); test_list( nx*ny*nz , nactive , region ); ecl_region_select_j1j2( region , 0 , ny - 1); test_list( nx*ny*nz , nactive , region ); ecl_region_select_k1k2( region , 0 , nz - 1); test_list( nx*ny*nz , nactive , region ); - + ecl_region_free( region ); } @@ -64,7 +64,7 @@ int main(int argc , char ** argv) { ecl_grid_type * grid = ecl_grid_alloc( grid_file ); test_slice( grid ); - + ecl_grid_free( grid ); exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_region2region_test.c b/ThirdParty/Ert/lib/ecl/tests/ecl_region2region.cpp similarity index 68% rename from ThirdParty/Ert/lib/ecl/tests/ecl_region2region_test.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_region2region.cpp index 98694d278b..3402bf92fa 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_region2region_test.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_region2region.cpp @@ -1,70 +1,70 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ecl_region2region.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ecl_region2region.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include void has_r2r_key(const ecl_sum_type* ecl_sum) { test_assert_true(ecl_sum_has_key( ecl_sum , "RGF:393217" )); - test_assert_true(ecl_sum_has_key( ecl_sum , "RGF:1-2" )); - test_assert_true(ecl_sum_has_key( ecl_sum , "ROF:524291" )); - test_assert_true(ecl_sum_has_key( ecl_sum , "RWF:393222" )); - test_assert_true(ecl_sum_has_key( ecl_sum , "RWF:6-2" )); - test_assert_true(ecl_sum_has_key( ecl_sum , "ROF:3-6" )); - test_assert_true(ecl_sum_has_key( ecl_sum , "RNLF:458753" )); - test_assert_true(ecl_sum_has_key( ecl_sum , "RNLF:1-4" )); + test_assert_true(ecl_sum_has_key( ecl_sum , "RGF:1-2" )); + test_assert_true(ecl_sum_has_key( ecl_sum , "ROF:524291" )); + test_assert_true(ecl_sum_has_key( ecl_sum , "RWF:393222" )); + test_assert_true(ecl_sum_has_key( ecl_sum , "RWF:6-2" )); + test_assert_true(ecl_sum_has_key( ecl_sum , "ROF:3-6" )); + test_assert_true(ecl_sum_has_key( ecl_sum , "RNLF:458753" )); + test_assert_true(ecl_sum_has_key( ecl_sum , "RNLF:1-4" )); } void get_unit(const ecl_sum_type* ecl_sum) { - test_assert_string_equal(ecl_sum_get_unit( ecl_sum , "RGF:1-2" ), "GFLOW"); + test_assert_string_equal(ecl_sum_get_unit( ecl_sum , "RGF:1-2" ), "GFLOW"); test_assert_string_equal(ecl_sum_get_unit( ecl_sum , "ROF:3-6" ), "OFLOW"); test_assert_string_equal(ecl_sum_get_unit( ecl_sum , "RWF:6-2" ), "WFLOW"); - test_assert_string_equal(ecl_sum_get_unit( ecl_sum , "RNLF:1-4" ), "NLFLOW"); + test_assert_string_equal(ecl_sum_get_unit( ecl_sum , "RNLF:1-4" ), "NLFLOW"); } - + void get_var_params_index(const ecl_sum_type* ecl_sum) { test_assert_int_equal(ecl_sum_get_general_var_params_index( ecl_sum , "RGF:1-2"), 21917); test_assert_int_equal(ecl_sum_get_general_var_params_index( ecl_sum , "ROF:3-6"), 21918); test_assert_int_equal(ecl_sum_get_general_var_params_index( ecl_sum, "RWF:6-2"), 21919); test_assert_int_equal(ecl_sum_get_general_var_params_index( ecl_sum, "RNLF:1-4"), 21920); -} +} int main(int argc , char ** argv) { - + const char * headerfile = argv[1]; ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case( headerfile , ":"); - + if (ecl_sum) { has_r2r_key(ecl_sum); get_unit(ecl_sum); - get_var_params_index(ecl_sum); + get_var_params_index(ecl_sum); } - else - test_error_exit("ecl_region2region_test: Test file not read correctly"); - - - if (ecl_sum) + else + test_error_exit("ecl_region2region_test: Test file not read correctly"); + + + if (ecl_sum) ecl_sum_free( ecl_sum ); - + exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_restart_test.c b/ThirdParty/Ert/lib/ecl/tests/ecl_restart_test.cpp similarity index 80% rename from ThirdParty/Ert/lib/ecl/tests/ecl_restart_test.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_restart_test.cpp index 3ddd46822b..f36d0297ea 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_restart_test.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_restart_test.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ecl_restart_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ecl_restart_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include bool test_get( ecl_file_type * rst_file , int day , int month , int year , int expected_index) { @@ -41,18 +41,18 @@ int main(int argc , char ** argv) { const char * unrst_file = argv[1]; ecl_file_type * rst_file = ecl_file_open( unrst_file , 0); - + OK = OK && test_get( rst_file , 1 , 1 , 1998 , -1 ); OK = OK && test_get( rst_file , 17 , 9 , 2003 , -1 ); OK = OK && test_get( rst_file , 1 , 1 , 2008 , -1 ); - + OK = OK && test_get( rst_file , 1 , 1 , 2000 , 0 ); OK = OK && test_get( rst_file , 1 , 10 , 2000 , 10 ); OK = OK && test_get( rst_file , 1 , 3 , 2003 , 40 ); OK = OK && test_get( rst_file , 31 , 12 , 2004 , 62 ); - - - if (OK) + + + if (OK) exit(0); else exit(1); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_rft.c b/ThirdParty/Ert/lib/ecl/tests/ecl_rft.cpp similarity index 88% rename from ThirdParty/Ert/lib/ecl/tests/ecl_rft.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_rft.cpp index e4a6a9dcd5..fd7c698ae9 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_rft.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_rft.cpp @@ -1,32 +1,32 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_rft.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_rft.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include void test_rft_read_write(const char * rft_file){ @@ -41,7 +41,7 @@ void test_rft_read_write(const char * rft_file){ ecl_rft_node_type * new_node = ecl_rft_node_alloc_new("DUMMY", "R", ecl_rft_node_get_date(old_node), ecl_rft_node_get_days(old_node)); nodes[2]=new_node; test_work_area_type * work_area = test_work_area_alloc("RFT_RW"); - + ecl_rft_file_update("eclipse.rft", nodes,3, ECL_METRIC_UNITS); test_work_area_free(work_area); free(nodes); @@ -51,11 +51,11 @@ void test_rft_read_write(const char * rft_file){ void test_rft( const char * rft_file ) { ecl_rft_file_type * rft = ecl_rft_file_alloc( rft_file ); ecl_rft_node_type * rft_node = ecl_rft_file_iget_node( rft , 0 ); - + test_assert_true( ecl_rft_node_is_RFT( rft_node )); test_assert_int_equal( 14 , ecl_rft_node_get_size( rft_node )); test_assert_false( ecl_rft_node_is_MSW( rft_node )); - + test_assert_double_equal( 260.6111 , ecl_rft_node_iget_pressure( rft_node , 0 )); test_assert_double_equal( 0.0581993 , ecl_rft_node_iget_soil( rft_node , 0 )); test_assert_double_equal( 0.9405648 , ecl_rft_node_iget_swat( rft_node , 0 )); @@ -67,12 +67,12 @@ void test_rft( const char * rft_file ) { ecl_rft_node_iget_ijk( rft_node , 0 , &i , &j , &k ); test_assert_int_equal( 32 , i ); test_assert_int_equal( 53 , j ); - test_assert_int_equal( 0 , k ); + test_assert_int_equal( 0 , k ); ecl_rft_node_iget_ijk( rft_node , 13 , &i , &j , &k ); test_assert_int_equal( 32 , i ); test_assert_int_equal( 54 , j ); - test_assert_int_equal( 12 , k ); + test_assert_int_equal( 12 , k ); for (i=0; i < ecl_rft_node_get_size( rft_node ); i++) { const ecl_rft_cell_type * cell1 = ecl_rft_node_iget_cell( rft_node , i ); @@ -123,19 +123,19 @@ void test_plt( const char * plt_file ) { test_assert_double_equal( 167.473 , ecl_rft_node_iget_orat( plt_node , 0 )); test_assert_double_equal( 41682.2 , ecl_rft_node_iget_grat( plt_node , 0 )); test_assert_double_equal( 0.958927 , ecl_rft_node_iget_wrat( plt_node , 0 )); - + { int i,j,k; ecl_rft_node_iget_ijk( plt_node , 0 , &i , &j , &k ); test_assert_int_equal( 39 , i ); test_assert_int_equal( 33 , j ); - test_assert_int_equal( 16 , k ); - + test_assert_int_equal( 16 , k ); + ecl_rft_node_iget_ijk( plt_node , 21 , &i , &j , &k ); test_assert_int_equal( 44 , i ); test_assert_int_equal( 34 , j ); - test_assert_int_equal( 7 , k ); + test_assert_int_equal( 7 , k ); for (i=0; i < ecl_rft_node_get_size( plt_node ); i++) { const ecl_rft_cell_type * cell1 = ecl_rft_node_iget_cell( plt_node , i ); @@ -145,7 +145,7 @@ void test_plt( const char * plt_file ) { } ecl_rft_node_inplace_sort_cells( plt_node ); } - + ecl_rft_file_free( plt ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.c b/ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.cpp similarity index 90% rename from ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.cpp index 19328a7087..03e0be4bcc 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_rft_cell.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_rft_cell.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_rft_cell.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ @@ -24,12 +24,12 @@ #include #include -#include -#include +#include +#include #include -#include -#include +#include +#include @@ -42,9 +42,9 @@ void test_rft_cell() { const double pressure = 200; const double swat = 0.25; const double sgas = 0.35; - + ecl_rft_cell_type * cell = ecl_rft_cell_alloc_RFT(i,j,k,depth,pressure,swat,sgas); - + test_assert_int_equal( i , ecl_rft_cell_get_i( cell )); test_assert_int_equal( j , ecl_rft_cell_get_j( cell )); test_assert_int_equal( k , ecl_rft_cell_get_k( cell )); @@ -76,10 +76,10 @@ void test_rft_cell() { ecl_rft_cell_free( cell ); { ecl_rft_cell_type * cell = ecl_rft_cell_alloc_RFT(i,j,k,depth,pressure,swat,sgas); - + test_assert_true( ecl_rft_cell_ijk_equal( cell , i , j , k )); test_assert_false( ecl_rft_cell_ijk_equal( cell , i , j , k + 1 )); - + ecl_rft_cell_free__( cell ); } } @@ -98,13 +98,13 @@ void test_plt_cell() { const double wrat = 0.45; const double flowrate = 100.0; const double connection_start = 891; - const double connection_end = 979; + const double connection_end = 979; const double oil_flowrate = 0.891; const double gas_flowrate = 7771; const double water_flowrate = 77614; ecl_rft_cell_type * cell = ecl_rft_cell_alloc_PLT(i,j,k,depth,pressure,orat,grat,wrat,connection_start,connection_end, flowrate,oil_flowrate , gas_flowrate , water_flowrate); - + test_assert_int_equal( i , ecl_rft_cell_get_i( cell )); test_assert_int_equal( j , ecl_rft_cell_get_j( cell )); test_assert_int_equal( k , ecl_rft_cell_get_k( cell )); @@ -126,11 +126,11 @@ void test_plt_cell() { test_assert_double_equal( connection_start, ecl_rft_cell_get_connection_start( cell )); test_assert_double_equal( connection_end, ecl_rft_cell_get_connection_end( cell )); test_assert_double_equal(flowrate , ecl_rft_cell_get_flowrate( cell )); - + test_assert_double_equal(oil_flowrate , ecl_rft_cell_get_oil_flowrate( cell )); test_assert_double_equal(gas_flowrate , ecl_rft_cell_get_gas_flowrate( cell )); test_assert_double_equal(water_flowrate , ecl_rft_cell_get_water_flowrate( cell )); - + test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_swat( cell )); test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_sgas( cell )); test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_soil( cell )); @@ -143,7 +143,7 @@ void test_plt_cell() { int main( int argc , char ** argv) { - + test_rft_cell(); test_plt_cell(); exit(0); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.c b/ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.cpp similarity index 93% rename from ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.cpp index 7d9c149180..50d1bb6703 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_rst_file.cpp @@ -18,14 +18,14 @@ #include #include -#include -#include +#include +#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include @@ -58,7 +58,7 @@ void test_file( const char * src_file , const char * target_file , int report_st ecl_rst_file_type * rst_file = ecl_rst_file_open_write_seek( target_file , report_step ); test_assert_true( ecl_rst_file_ftell( rst_file ) == expected_offset ); ecl_rst_file_close( rst_file ); - test_assert_true( util_file_size( target_file ) == expected_offset ); + test_assert_true( util_file_size( target_file ) == (size_t) expected_offset ); } } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.c b/ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.c deleted file mode 100644 index 181d6b2957..0000000000 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_rst_header.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ -#include -#include - -#include - -#include -#include -#include -#include -#include - - -void test_file( const char * filename , int occurence , bool exists , const ecl_rsthead_type * true_header) { - int report_step = ecl_util_filename_report_nr( filename ); - ecl_file_type * rst_file = ecl_file_open( filename , 0); - ecl_file_enum file_type = ecl_util_get_file_type( filename , NULL , NULL ); - ecl_file_view_type * rst_view; - ecl_rsthead_type * rst_head; - - if (file_type == ECL_RESTART_FILE) - rst_view = ecl_file_get_global_view( rst_file ); - else - rst_view = ecl_file_get_restart_view( rst_file , occurence , -1 , -1 , -1 ); - - if (exists) { - test_assert_not_NULL( rst_view ); - rst_head = ecl_rsthead_alloc( rst_view , report_step); - test_assert_not_NULL( rst_head ); - - if (occurence == 0) { - ecl_rsthead_type * rst_head0 = ecl_rsthead_alloc( rst_view , report_step ); - - test_assert_true( ecl_rsthead_equal( rst_head , rst_head0 )); - ecl_rsthead_free( rst_head0 ); - } - test_assert_true( ecl_rsthead_equal( rst_head , true_header )); - - ecl_rsthead_free( rst_head ); - } else - test_assert_NULL( rst_view ); - -} - - -int main(int argc , char ** argv) { - ecl_rsthead_type true1 = {.report_step = 1, - .day = 1, - .year = 2000, - .month = 1, - .sim_time = (time_t) 946684800, - .version = 100, - .phase_sum = 7, - .nx = 40, - .ny = 64, - .nz = 14, - .nactive = 34770, - .nwells = 3, - .niwelz = 145, - .nzwelz = 3, - .niconz = 20, - .ncwmax = 120, - .nisegz = 18, - .nsegmx = 1, - .nswlmx = 1, - .nlbrmx = -1, - .nilbrz = -1, - .dualp = 0, - .sim_days = 0}; - - ecl_rsthead_type true2 = {.report_step = 5, - .day = 22, - .year = 1990, - .month = 1, - .sim_time = (time_t) 632966400, - .version = 100, - .phase_sum = 7, - .nx = 4, - .ny = 4, - .nz = 4, - .nactive = 64, - .nwells = 3, - .niwelz = 147, - .nzwelz = 3, - .niconz = 20, - .ncwmax = 13, - .nisegz = 18, - .nsegmx = 1, - .nswlmx = 1, - .nlbrmx = -1, - .nilbrz = -1, - .dualp = 1, - .sim_days = 21}; - - const char * unified_file = argv[1]; - const char * Xfile = argv[2]; - - test_file( unified_file , 0 , true , &true1 ); - test_file( unified_file , 100 , false , NULL ); - test_file( Xfile , 0 , true , &true2 ); - - exit(0); -} diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.cpp new file mode 100644 index 0000000000..c690d71535 --- /dev/null +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_rsthead.cpp @@ -0,0 +1,121 @@ +/* + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_rst_header.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ +#include +#include + +#include + +#include +#include +#include +#include +#include + + +void test_file( const char * filename , int occurence , bool exists , const ecl_rsthead_type * true_header) { + int report_step = ecl_util_filename_report_nr( filename ); + ecl_file_type * rst_file = ecl_file_open( filename , 0); + ecl_file_enum file_type = ecl_util_get_file_type( filename , NULL , NULL ); + ecl_file_view_type * rst_view; + ecl_rsthead_type * rst_head; + + if (file_type == ECL_RESTART_FILE) + rst_view = ecl_file_get_global_view( rst_file ); + else + rst_view = ecl_file_get_restart_view( rst_file , occurence , -1 , -1 , -1 ); + + if (exists) { + test_assert_not_NULL( rst_view ); + rst_head = ecl_rsthead_alloc( rst_view , report_step); + test_assert_not_NULL( rst_head ); + + if (occurence == 0) { + ecl_rsthead_type * rst_head0 = ecl_rsthead_alloc( rst_view , report_step ); + + test_assert_true( ecl_rsthead_equal( rst_head , rst_head0 )); + ecl_rsthead_free( rst_head0 ); + } + test_assert_true( ecl_rsthead_equal( rst_head , true_header )); + + ecl_rsthead_free( rst_head ); + } else + test_assert_NULL( rst_view ); + +} + + +int main(int argc , char ** argv) { + ecl_rsthead_type true1; + true1.report_step = 1; + true1.day = 1; + true1.year = 2000; + true1.month = 1; + true1.sim_time = (time_t) 946684800; + true1.version = 100; + true1.phase_sum = 7; + true1.nx = 40; + true1.ny = 64; + true1.nz = 14; + true1.nactive = 34770; + true1.nwells = 3; + true1.niwelz = 145; + true1.nzwelz = 3; + true1.niconz = 20; + true1.ncwmax = 120; + true1.nisegz = 18; + true1.nsegmx = 1; + true1.nswlmx = 1; + true1.nlbrmx = -1; + true1.nilbrz = -1; + true1.dualp = 0; + true1.sim_days = 0; + + ecl_rsthead_type true2; + true2.report_step = 5; + true2.day = 22; + true2.year = 1990; + true2.month = 1; + true2.sim_time = (time_t) 632966400; + true2.version = 100; + true2.phase_sum = 7; + true2.nx = 4; + true2.ny = 4; + true2.nz = 4; + true2.nactive = 64; + true2.nwells = 3; + true2.niwelz = 147; + true2.nzwelz = 3; + true2.niconz = 20; + true2.ncwmax = 13; + true2.nisegz = 18; + true2.nsegmx = 1; + true2.nswlmx = 1; + true2.nlbrmx = -1; + true2.nilbrz = -1; + true2.dualp = 1; + true2.sim_days = 21; + + const char * unified_file = argv[1]; + const char * Xfile = argv[2]; + + test_file( unified_file , 0 , true , &true1 ); + test_file( unified_file , 100 , false , NULL ); + test_file( Xfile , 0 , true , &true2 ); + + exit(0); +} diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_smspec.c b/ThirdParty/Ert/lib/ecl/tests/ecl_smspec.cpp similarity index 93% rename from ThirdParty/Ert/lib/ecl/tests/ecl_smspec.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_smspec.cpp index 961601dd2b..6ee378897e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_smspec.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_smspec.cpp @@ -19,9 +19,9 @@ #include #include -#include -#include -#include +#include +#include +#include void test_sort( ecl_smspec_type * smspec ) { @@ -41,7 +41,7 @@ void test_sort( ecl_smspec_type * smspec ) void test_copy(const ecl_smspec_type * smspec1) { ecl_sum_type * ecl_sum2 = ecl_sum_alloc_writer("CASE", false, true, ":", 0, true, 100, 100, 100); - ecl_smspec_type * smspec2 = ecl_sum_get_smspec(ecl_sum2); + const ecl_smspec_type * smspec2 = ecl_sum_get_smspec(ecl_sum2); for (int i=0; i < ecl_smspec_num_nodes(smspec1); i++) { const smspec_node_type * node = ecl_smspec_iget_node(smspec1, i); ecl_sum_add_smspec_node(ecl_sum2, node); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_smspec_node.c b/ThirdParty/Ert/lib/ecl/tests/ecl_smspec_node.cpp similarity index 90% rename from ThirdParty/Ert/lib/ecl/tests/ecl_smspec_node.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_smspec_node.cpp index 6ad046c49a..7806fc8dec 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_smspec_node.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_smspec_node.cpp @@ -20,9 +20,9 @@ #include #include -#include +#include -#include +#include void test_cmp_types() { @@ -57,10 +57,6 @@ void test_cmp_types() { test_assert_true( smspec_node_cmp( misc_node1, misc_node2) < 0 ); test_assert_true( smspec_node_cmp( misc_node2, misc_node1) > 0 ); - smspec_node_type * net1 = smspec_node_alloc(ECL_SMSPEC_NETWORK_VAR, "Net", "FOPT", "UNIT", ":", dims, 10 , 0, 0); - smspec_node_type * net2 = smspec_node_alloc(ECL_SMSPEC_NETWORK_VAR, "Net", "FOPT", "UNIT", ":", dims, 10 , 0, 0); - test_assert_true( smspec_node_cmp( net1, net2) == 0 ); - smspec_node_free( segment_node ); smspec_node_free( aquifer_node ); smspec_node_free( block_node ); @@ -70,8 +66,6 @@ void test_cmp_types() { smspec_node_free( field_node ); smspec_node_free( misc_node1 ); smspec_node_free( misc_node2 ); - smspec_node_free( net1 ); - smspec_node_free( net2 ); } void test_cmp_well() { @@ -82,6 +76,7 @@ void test_cmp_well() { smspec_node_type * well_node2_2 = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , "W2" , "WWWT" , "UNIT" , ":" , dims , 10 , 0 , 0 ); smspec_node_type * well_node_dummy = smspec_node_alloc( ECL_SMSPEC_WELL_VAR , DUMMY_WELL , "WOPR" , "UNIT" , ":" , dims , 10 , 0 , 0 ); + test_assert_NULL( well_node_dummy); test_assert_int_equal( smspec_node_cmp( well_node1_1 , well_node1_1 ), 0); test_assert_int_equal( smspec_node_cmp( well_node2_2 , well_node2_2 ), 0); @@ -92,15 +87,10 @@ void test_cmp_well() { test_assert_true( smspec_node_cmp( well_node1_2, well_node1_1) > 0 ); test_assert_true( smspec_node_cmp( well_node1_2, well_node2_1) < 0 ); - test_assert_true( smspec_node_cmp( well_node1_1, well_node_dummy) < 0 ); - test_assert_false( smspec_node_is_valid( well_node_dummy )); - test_assert_true( smspec_node_is_valid( well_node1_1 )); - smspec_node_free( well_node1_1 ); smspec_node_free( well_node2_1 ); smspec_node_free( well_node1_2 ); smspec_node_free( well_node2_2 ); - smspec_node_free( well_node_dummy ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_alloc_resampled_test.c b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp similarity index 97% rename from ThirdParty/Ert/lib/ecl/tests/ecl_sum_alloc_resampled_test.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp index 142e8073ae..3eb32c2f5a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_alloc_resampled_test.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_alloc_resampled_test.cpp @@ -1,8 +1,8 @@ -#include +#include -#include -#include +#include +#include ecl_sum_type * test_alloc_ecl_sum() { time_t start_time = util_make_date_utc( 1,1,2010 ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_case_exists.c b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_case_exists.cpp similarity index 73% rename from ThirdParty/Ert/lib/ecl/tests/ecl_sum_case_exists.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_sum_case_exists.cpp index 5d06dec664..ed43da456d 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_case_exists.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_case_exists.cpp @@ -1,33 +1,33 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_sum_case_exists.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_sum_case_exists.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include #include -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include void test_case( const char * sum_case , bool expected_exist) { @@ -40,14 +40,14 @@ void test_case_no_path( const char * sum_case , bool expected_exist) { path_stack_push_cwd( path_stack ); { char * basename , *path; - + util_alloc_file_components( sum_case , &path , &basename , NULL ); if (path) chdir( path ); test_assert_bool_equal(expected_exist , ecl_sum_case_exists( basename )); - - util_safe_free( path ); - util_safe_free( basename ); + + free( path ); + free( basename ); } path_stack_pop( path_stack ); path_stack_free( path_stack ); @@ -59,7 +59,7 @@ int main( int argc , char ** argv) { const char * missing_header = argv[2]; const char * missing_data = argv[3]; test_assert_false( ecl_sum_case_exists( "/does/not/exist" )); - + test_case( existing_case , true); test_case_no_path( existing_case , true); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_data_intermediate_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_data_intermediate_test.cpp new file mode 100644 index 0000000000..9a4e569894 --- /dev/null +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_data_intermediate_test.cpp @@ -0,0 +1,232 @@ +#include + +#include +#include +#include +#include + +#include + + +/* + +CASE1 +--------- +1 : BPR:1 100 200 300 400 +2 : BPR:2 110 210 310 410 +3 : BRP:3 120 220 320 430 + + + +CASE2 +--------- +1 : BRP:2 1100 2100 3100 4100 +2 : BPR:1 1000 2000 3000 4000 + + + +Total CASE2: +------------ +1 : BPR:2 110 210 310 1100 2100 3100 4100 +2 : BRP:1 100 200 300 1000 2000 3000 4000 + + + +CASE3 +----- +1 : BPR:3 12000 22000 32000 42000 +2 : BRP:2 11000 21000 31000 41000 +3 : BPR:1 10000 20000 30000 40000 + + +Total CASE3: +------------ +1 : BPR:3 120 220 320 0 0 12000 22000 32000 42000 +2 : BPR:2 110 210 310 1100 2100 11000 21000 31000 41000 +3 : BPR:1 100 200 300 1000 2000 10000 20000 30000 40000 + +*/ + + +#define ieq(d,i,v) test_assert_double_equal(double_vector_iget(d,(i)), v) + + +void verify_CASE1() { + ecl_sum_type * sum = ecl_sum_fread_alloc_case("CASE1", ":"); + + for (int i=1; i < 4; i++) { + double_vector_type * d = ecl_sum_alloc_data_vector(sum, i, false); + //test_assert_int_equal(4, double_vector_size(d)); + for (int j=0; j < 4; j++) { + test_assert_double_equal( double_vector_iget(d, j), (i - 1)*10 + (j + 1)*100); + } + double_vector_free(d); + } + ecl_sum_free(sum); +} + + + +void write_CASE1(bool unified) { + time_t start_time = util_make_date_utc( 1,1,2010 ); + ecl_sum_type * ecl_sum = ecl_sum_alloc_writer( "CASE1" , false , unified, ":" , start_time , true , 10 , 10 , 10 ); + double sim_seconds = 0; + + int num_dates = 4; + double ministep_length = 86400; // seconds in a day + + smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); + smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); + smspec_node_type * node3 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 3 , "BARS" , 0.0 ); + + for (int report_step = 0; report_step < num_dates; report_step++) { + { + ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 1 , sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , node1 , (1 + report_step) * 100 ); + ecl_sum_tstep_set_from_node( tstep , node2 , (1 + report_step) * 100 + 10.0 ); + ecl_sum_tstep_set_from_node( tstep , node3 , (1 + report_step) * 100 + 20.0 ); + } + sim_seconds += ministep_length * 3; + } + ecl_sum_fwrite( ecl_sum ); + ecl_sum_free(ecl_sum); + + verify_CASE1(); +} + + + +void verify_CASE2() { + ecl_sum_type * sum = ecl_sum_fread_alloc_case2__("CASE2", ":", false, true, 0); + + for (int i=0; i < 2; i++) { + double_vector_type * d = ecl_sum_alloc_data_vector(sum, i+1, false); + //test_assert_int_equal(4, double_vector_size(d)); + for (int j=1; j < 4; j++) + test_assert_double_equal( double_vector_iget(d, j-1), (1 - i)*100 + j*1000); + double_vector_free(d); + } + + ecl_sum_free(sum); + + + sum = ecl_sum_fread_alloc_case("CASE2", ":"); + for (int i=0; i < 2; i++) { + double_vector_type * d = ecl_sum_alloc_data_vector(sum, i+1, false); + //test_assert_int_equal(double_vector_size(d), 7); + ieq(d,0,(1 - i)*10 + 100); + ieq(d,1,(1 - i)*10 + 200); + ieq(d,2,(1 - i)*10 + 300); + ieq(d,3,(1 - i)*100 + 1000); + ieq(d,4,(1 - i)*100 + 2000); + ieq(d,5,(1 - i)*100 + 3000); + ieq(d,6,(1 - i)*100 + 4000); + double_vector_free(d); + } + + ecl_sum_free(sum); +} + + +void write_CASE2(bool unified) { + write_CASE1(unified); + { + time_t start_time = util_make_date_utc( 1,1,2010 ); + int num_dates = 4; + double ministep_length = 86400; // seconds in a day + double sim_seconds = ministep_length * 2.5 * 3; + ecl_sum_type * ecl_sum = ecl_sum_alloc_restart_writer( "CASE2" , "CASE1", false , true , ":" , start_time , true , 10 , 10 , 10 ); + + smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); + smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); + + for (int report_step = 1; report_step <= num_dates; report_step++) { + { + ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 3 , sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , node1 , report_step*1000); + ecl_sum_tstep_set_from_node( tstep , node2 , report_step*1000 + 100); + } + sim_seconds += ministep_length * 3; + } + ecl_sum_fwrite( ecl_sum ); + ecl_sum_free(ecl_sum); + verify_CASE2(); + } +} + +void verify_CASE3() { + ecl_sum_type * sum = ecl_sum_fread_alloc_case2__("CASE3", ":", false, true, 0); + + for (int i=0; i < 3; i++) { + double_vector_type * d = ecl_sum_alloc_data_vector(sum, i+1, false); + //test_assert_int_equal(4, double_vector_size(d)); + for (int j=0; j < 4; j++) { + test_assert_double_equal( double_vector_iget(d, j), (2 - i)*1000 + (j + 1)*10000); + } + double_vector_free(d); + } + ecl_sum_free(sum); + + sum = ecl_sum_fread_alloc_case("CASE3", ":"); + for (int i=0; i < 3; i++) { + double_vector_type * d = ecl_sum_alloc_data_vector(sum, i+1, false); + ieq(d,0,(2 - i)*10 + 100); + ieq(d,1,(2 - i)*10 + 200); + ieq(d,2,(2 - i)*10 + 300); + + if (i == 0) { + const smspec_node_type * node = ecl_smspec_iget_node(ecl_sum_get_smspec(sum), i); + double default_value = smspec_node_get_default(node); + ieq(d,3,default_value); + ieq(d,4,default_value); + } else { + ieq(d,3,(2 - i)*100 + 1000); + ieq(d,4,(2 - i)*100 + 2000); + } + ieq(d,5,(2 - i)*1000 + 10000); + ieq(d,6,(2 - i)*1000 + 20000); + ieq(d,7,(2 - i)*1000 + 30000); + ieq(d,8,(2 - i)*1000 + 40000); + double_vector_free(d); + } + + ecl_sum_free(sum); +} + + +void write_CASE3(bool unified) { + test_work_area_type * work_area = test_work_area_alloc("SMSPEC"); + write_CASE2(unified); + { + time_t start_time = util_make_date_utc( 1,1,2010 ); + int num_dates = 4; + double ministep_length = 86400; // seconds in a day + double sim_seconds = ministep_length * 4.0 * 3; + ecl_sum_type * ecl_sum = ecl_sum_alloc_restart_writer( "CASE3" , "CASE2", false , true , ":" , start_time , true , 10 , 10 , 10 ); + + smspec_node_type * node3 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 3 , "BARS" , 0.0 ); + smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 2 , "BARS" , 0.0 ); + smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 1 , "BARS" , 0.0 ); + + for (int report_step = 1; report_step <= num_dates; report_step++) { + { + ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 5 , sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , node1 , report_step*10000); + ecl_sum_tstep_set_from_node( tstep , node2 , report_step*10000 + 1000); + ecl_sum_tstep_set_from_node( tstep , node3 , report_step*10000 + 2000); + } + sim_seconds += ministep_length * 3; + } + ecl_sum_fwrite( ecl_sum ); + ecl_sum_free(ecl_sum); + verify_CASE3(); + } + test_work_area_free(work_area); +} + + +int main() { + write_CASE3(true); + write_CASE3(false); + return 0; +} diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_compatible.c b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_compatible.cpp similarity index 58% rename from ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_compatible.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_compatible.cpp index e76932c528..4cd4b1ece4 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_compatible.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_compatible.cpp @@ -1,28 +1,28 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_sum_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_sum_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include +#include @@ -30,19 +30,19 @@ int main( int argc , char ** argv) { const char * case1 = argv[1]; const char * case2 = argv[2]; const char * compatible_string = argv[3]; - bool compatible; ecl_sum_type * ecl_sum1 = ecl_sum_fread_alloc_case( case1 , ":"); ecl_sum_type * ecl_sum2 = ecl_sum_fread_alloc_case( case2 , ":"); - test_assert_true( ecl_sum_is_instance( ecl_sum1 )); + test_assert_true( ecl_sum_is_instance( ecl_sum1 )); test_assert_true( ecl_sum_is_instance( ecl_sum2 )); - test_assert_true( ecl_sum_report_step_compatible( ecl_sum1 , ecl_sum1) ); - test_assert_true( util_sscanf_bool( compatible_string , &compatible )); - test_assert_true( ecl_sum_report_step_compatible( ecl_sum1 , ecl_sum1) ); test_assert_true( ecl_sum_report_step_compatible( ecl_sum2 , ecl_sum2) ); - test_assert_bool_equal( compatible , ecl_sum_report_step_compatible( ecl_sum1 , ecl_sum2 )); - + + { + bool compatible; + test_assert_true( util_sscanf_bool( compatible_string , &compatible )); + test_assert_bool_equal( compatible , ecl_sum_report_step_compatible( ecl_sum1 , ecl_sum2 )); + } ecl_sum_free( ecl_sum1 ); ecl_sum_free( ecl_sum2 ); exit(0); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_equal.c b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_equal.cpp similarity index 76% rename from ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_equal.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_equal.cpp index 86465c7bf5..d9b30efa0e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_equal.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_report_step_equal.cpp @@ -1,28 +1,28 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_sum_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_sum_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include +#include @@ -38,11 +38,11 @@ int main( int argc , char ** argv) { test_assert_true( ecl_sum_is_instance( ecl_sum2 )); test_assert_true( ecl_sum_report_step_equal( ecl_sum1 , ecl_sum1) ); test_assert_true( util_sscanf_bool( equal_string , &equal )); - + test_assert_true( ecl_sum_report_step_equal( ecl_sum1 , ecl_sum1) ); test_assert_true( ecl_sum_report_step_equal( ecl_sum2 , ecl_sum2) ); test_assert_bool_equal( equal , ecl_sum_report_step_equal( ecl_sum1 , ecl_sum2 )); - + ecl_sum_free( ecl_sum1 ); ecl_sum_free( ecl_sum2 ); exit(0); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.c b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.cpp similarity index 95% rename from ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.cpp index d10a2142b3..9b049bdb79 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_test.cpp @@ -18,11 +18,11 @@ #include #include -#include -#include +#include +#include #include -#include +#include void test_time_range( const ecl_sum_type * ecl_sum ) { @@ -63,7 +63,7 @@ void test_is_oil_producer( const ecl_sum_type * ecl_sum) { int main( int argc , char ** argv) { const char * case1 = argv[1]; - + ecl_sum_type * ecl_sum1 = ecl_sum_fread_alloc_case( case1 , ":"); test_assert_true( ecl_sum_is_instance( ecl_sum1 )); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_writer.c b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_writer.cpp similarity index 93% rename from ThirdParty/Ert/lib/ecl/tests/ecl_sum_writer.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_sum_writer.cpp index f1691a943d..2fb3abb4c9 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_sum_writer.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_sum_writer.cpp @@ -18,15 +18,15 @@ #include #include -#include -#include +#include +#include #include -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include double write_summary( const char * name , time_t start_time , int nx , int ny , int nz , int num_dates, int num_ministep, double ministep_length) { @@ -95,7 +95,7 @@ void test_write_read( ) { int nz = 12; int num_dates = 5; int num_ministep = 10; - double ministep_length = 36000; // Seconds + double ministep_length = 86400; // Seconds - numerical value chosen to avoid rounding problems when converting between seconds and days. { test_work_area_type * work_area = test_work_area_alloc("sum/write"); ecl_sum_type * ecl_sum; @@ -159,8 +159,8 @@ void test_ecl_sum_alloc_restart_writer() { test_assert_true( ecl_file_view_has_kw(view_file, RESTART_KW)); ecl_kw_type * restart_kw = ecl_file_view_iget_named_kw(view_file, "RESTART", 0); test_assert_int_equal(8, ecl_kw_get_size(restart_kw)); - test_assert_string_equal( "CASE1 ", ecl_kw_iget_ptr( restart_kw , 0 ) ); - test_assert_string_equal( " ", ecl_kw_iget_ptr( restart_kw , 1 ) ); + test_assert_string_equal( "CASE1 ", (const char *) ecl_kw_iget_ptr( restart_kw , 0 ) ); + test_assert_string_equal( " ", (const char *) ecl_kw_iget_ptr( restart_kw , 1 ) ); for (int time_index=0; time_index < ecl_sum_get_data_length( case1 ); time_index++) test_assert_double_equal( ecl_sum_get_general_var( case1 , time_index , "FOPT"), ecl_sum_get_general_var( case2 , time_index , "FOPT")); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_unsmry_loader_test.cpp b/ThirdParty/Ert/lib/ecl/tests/ecl_unsmry_loader_test.cpp new file mode 100644 index 0000000000..55606a6ffa --- /dev/null +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_unsmry_loader_test.cpp @@ -0,0 +1,61 @@ +#include + +#include +#include + +#include + +#include "detail/ecl/ecl_unsmry_loader.hpp" + + + +ecl_sum_type * write_ecl_sum() { + time_t start_time = util_make_date_utc( 1,1,2010 ); + ecl_sum_type * ecl_sum = ecl_sum_alloc_writer( "CASE" , false , true , ":" , start_time , true , 10 , 10 , 10 ); + double sim_seconds = 0; + + int num_dates = 4; + double ministep_length = 86400; // seconds in a day + + smspec_node_type * node1 = ecl_sum_add_var( ecl_sum , "FOPT" , NULL , 0 , "Barrels" , 99.0 ); + smspec_node_type * node2 = ecl_sum_add_var( ecl_sum , "BPR" , NULL , 567 , "BARS" , 0.0 ); + smspec_node_type * node3 = ecl_sum_add_var( ecl_sum , "WWCT" , "OP-1" , 0 , "(1)" , 0.0 ); + + for (int report_step = 0; report_step < num_dates; report_step++) { + { + ecl_sum_tstep_type * tstep = ecl_sum_add_tstep( ecl_sum , report_step + 1 , sim_seconds ); + ecl_sum_tstep_set_from_node( tstep , node1 , report_step*2.0 ); + ecl_sum_tstep_set_from_node( tstep , node2 , report_step*4.0 + 2.0 ); + ecl_sum_tstep_set_from_node( tstep , node3 , report_step*6.0 + 4.0 ); + } + sim_seconds += ministep_length * 3; + + } + ecl_sum_fwrite( ecl_sum ); + return ecl_sum; +} + +void test_load() { + test_work_area_type * work_area = test_work_area_alloc("unsmry_loader"); + ecl_sum_type * ecl_sum = write_ecl_sum(); + test_assert_true( util_file_exists("CASE.SMSPEC") ); + test_assert_true( util_file_exists("CASE.UNSMRY") ); + ecl::unsmry_loader * loader = new ecl::unsmry_loader(ecl_sum_get_smspec(ecl_sum), "CASE.UNSMRY", 0); + + const std::vector FOPT_value = loader->get_vector(1); + const std::vector BPR_value = loader->get_vector(2); + const std::vector WWCT_value = loader->get_vector(3); + test_assert_int_equal( FOPT_value.size(), 4 ); + test_assert_double_equal( FOPT_value[3] , 6.0 ); + test_assert_double_equal( BPR_value[2] , 10.0 ); + test_assert_double_equal( WWCT_value[1] , 10.0 ); + + delete loader; + ecl_sum_free(ecl_sum); + test_work_area_free(work_area); +} + +int main() { + test_load(); + return 0; +} diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_util_filenames.c b/ThirdParty/Ert/lib/ecl/tests/ecl_util_filenames.cpp similarity index 96% rename from ThirdParty/Ert/lib/ecl/tests/ecl_util_filenames.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_util_filenames.cpp index 45b2256f85..65bc7d58fd 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_util_filenames.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_util_filenames.cpp @@ -18,12 +18,12 @@ #include #include -#include -#include -#include +#include +#include +#include #include -#include +#include void test_filename_report_nr() { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_no_shift.c b/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_no_shift.cpp similarity index 92% rename from ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_no_shift.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_no_shift.cpp index 594ec93f3f..b4d6cc1eaa 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_no_shift.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_no_shift.cpp @@ -18,11 +18,11 @@ #include #include -#include -#include +#include +#include #include -#include +#include void test_date(int mday, int month , int year) { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_shift.c b/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_shift.cpp similarity index 93% rename from ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_shift.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_shift.cpp index 54a0ebd6d9..73fa007994 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_shift.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_util_make_date_shift.cpp @@ -17,11 +17,11 @@ #include #include -#include -#include +#include +#include #include -#include +#include void test_date(int mday, int month , int year, int * year_offset) { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_util_month_range.c b/ThirdParty/Ert/lib/ecl/tests/ecl_util_month_range.cpp similarity index 89% rename from ThirdParty/Ert/lib/ecl/tests/ecl_util_month_range.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_util_month_range.cpp index c466d8490b..afd3d7af11 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_util_month_range.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_util_month_range.cpp @@ -1,28 +1,28 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_util_month_range.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_util_month_range.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include +#include @@ -37,7 +37,7 @@ void test_body( time_t_vector_type * date_list , int offset) { time_t prev_date = time_t_vector_iget( date_list , i - 1 ); int prev_month , prev_year; util_set_date_values_utc( prev_date , NULL , &prev_month , &prev_year); - + if (prev_year == year) test_assert_int_equal( month , prev_month + 1); else { @@ -53,8 +53,8 @@ void test_body( time_t_vector_type * date_list , int offset) { void test_append( const char * name , time_t_vector_type * date_list , time_t date1 , time_t date2, bool force_append_end) { int offset = time_t_vector_size( date_list ); - - printf("%s ...",name); + + printf("%s ...",name); fflush( stdout ); ecl_util_append_month_range( date_list , date1 , date2 , force_append_end); @@ -70,14 +70,14 @@ void test_append( const char * name , time_t_vector_type * date_list , time_t da test_assert_time_t_equal( time_t_vector_get_last( date_list ) , util_make_pure_date_utc(date2)); else test_assert_true( util_is_first_day_in_month_utc( time_t_vector_get_last( date_list ))); - + printf(" OK \n"); } void test_init( const char * name , time_t_vector_type * date_list , time_t start_date , time_t end_date) { - printf("%s ...",name); + printf("%s ...",name); fflush( stdout ); { ecl_util_init_month_range( date_list , start_date , end_date ); @@ -94,8 +94,8 @@ int main(int argc , char ** argv) { time_t date2 = util_make_datetime_utc(0,3,0,1,1,2005); time_t date3 = util_make_datetime_utc(0,4,0,10,1,2000); time_t date4 = util_make_datetime_utc(0,5,0,10,1,2005); - - + + { time_t_vector_type * date_list = time_t_vector_alloc(0 ,0 ); @@ -111,7 +111,7 @@ int main(int argc , char ** argv) { } { time_t_vector_type * date_list = time_t_vector_alloc(0 ,0 ); - + test_init( "Init Test1" , date_list , date1 , date2 ); test_init( "Init Test2" , date_list , date1 , date4 ); test_init( "Init Test3" , date_list , date3 , date2 ); diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_util_path_access.c b/ThirdParty/Ert/lib/ecl/tests/ecl_util_path_access.cpp similarity index 93% rename from ThirdParty/Ert/lib/ecl/tests/ecl_util_path_access.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_util_path_access.cpp index 1273184503..470acebe53 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_util_path_access.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_util_path_access.cpp @@ -20,10 +20,10 @@ #include #include -#include -#include +#include +#include -#include +#include void test_relative_access() { diff --git a/ThirdParty/Ert/lib/ecl/tests/ecl_valid_basename.c b/ThirdParty/Ert/lib/ecl/tests/ecl_valid_basename.cpp similarity index 96% rename from ThirdParty/Ert/lib/ecl/tests/ecl_valid_basename.c rename to ThirdParty/Ert/lib/ecl/tests/ecl_valid_basename.cpp index be484ddf18..b275c4300f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/ecl_valid_basename.c +++ b/ThirdParty/Ert/lib/ecl/tests/ecl_valid_basename.cpp @@ -22,8 +22,8 @@ for more details. */ -#include -#include +#include +#include diff --git a/ThirdParty/Ert/lib/ecl/tests/eclxx_filename.cpp b/ThirdParty/Ert/lib/ecl/tests/eclxx_filename.cpp index 5ad49e6776..1dd75bd20e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/eclxx_filename.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/eclxx_filename.cpp @@ -16,7 +16,7 @@ for more details. */ -#include +#include #include diff --git a/ThirdParty/Ert/lib/ecl/tests/eclxx_fortio.cpp b/ThirdParty/Ert/lib/ecl/tests/eclxx_fortio.cpp index cf492b019d..bbfab425cb 100644 --- a/ThirdParty/Ert/lib/ecl/tests/eclxx_fortio.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/eclxx_fortio.cpp @@ -21,14 +21,14 @@ #include -#include +#include #include #include #include void test_open() { - ERT::TestArea work_area("fortio"); + test_work_area_type * work_area = test_work_area_alloc("FORTIO"); ERT::FortIO fortio; fortio.open( "new_file" , std::fstream::out ); @@ -67,11 +67,12 @@ void test_open() { } test_assert_false( fortio.ftruncate( 0 )); fortio.close(); + test_work_area_free(work_area); } void test_fortio() { - ERT::TestArea ta("fortio"); + test_work_area_type * work_area = test_work_area_alloc("FORTIO"); ERT::FortIO fortio("new_file" , std::fstream::out ); { std::vector data; @@ -96,11 +97,12 @@ void test_fortio() { fortio.close(); test_assert_throw( ERT::FortIO fortio("file/does/not/exists" , std::fstream::in) , std::invalid_argument ); + test_work_area_free(work_area); } void test_fortio_kw() { - ERT::TestArea ta("fortio"); + test_work_area_type * work_area = test_work_area_alloc("FORTIO"); std::vector< int > vec( 1000 ); for (size_t i =0 ; i < vec.size(); i++) @@ -123,9 +125,10 @@ void test_fortio_kw() { fortio = ERT::FortIO("new_file" , std::fstream::in ); - test_assert_throw( ERT::EclKW::load(fortio) , std::invalid_argument ); + test_assert_throw( ERT::EclKW::load(fortio) , std::invalid_argument ); fortio.close(); } + test_work_area_free(work_area); } diff --git a/ThirdParty/Ert/lib/ecl/tests/eclxx_kw.cpp b/ThirdParty/Ert/lib/ecl/tests/eclxx_kw.cpp index 7c3e30215c..f348304c33 100644 --- a/ThirdParty/Ert/lib/ecl/tests/eclxx_kw.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/eclxx_kw.cpp @@ -22,11 +22,11 @@ #include -#include +#include #include #include -#include +#include void test_kw_name() { ERT::EclKW< int > kw1( "short", 1 ); @@ -170,7 +170,7 @@ void test_read_write() { std::vector s_data = {"S1", "S2", "S3"}; { - ERT::TestArea ta("test_fwrite"); + test_work_area_type * work_area = test_work_area_alloc("READ_WRITE"); { ERT::FortIO f("test_file", std::ios_base::out); ERT::write_kw(f, "DOUBLE", d_data); @@ -208,6 +208,7 @@ void test_read_write() { } ecl_file_close(f); + test_work_area_free(work_area); } } } diff --git a/ThirdParty/Ert/lib/ecl/tests/eclxx_smspec.cpp b/ThirdParty/Ert/lib/ecl/tests/eclxx_smspec.cpp index 0fd3e89a2f..ca134cf6f9 100644 --- a/ThirdParty/Ert/lib/ecl/tests/eclxx_smspec.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/eclxx_smspec.cpp @@ -17,8 +17,8 @@ along with OPM. If not, see . */ -#include -#include +#include +#include #include diff --git a/ThirdParty/Ert/lib/ecl/tests/eclxx_types.cpp b/ThirdParty/Ert/lib/ecl/tests/eclxx_types.cpp index 2ecd3add39..7b04d9414d 100644 --- a/ThirdParty/Ert/lib/ecl/tests/eclxx_types.cpp +++ b/ThirdParty/Ert/lib/ecl/tests/eclxx_types.cpp @@ -20,9 +20,8 @@ #include -#include #include -#include +#include #include diff --git a/ThirdParty/Ert/lib/ecl/tests/rft_test.c b/ThirdParty/Ert/lib/ecl/tests/rft_test.cpp similarity index 87% rename from ThirdParty/Ert/lib/ecl/tests/rft_test.c rename to ThirdParty/Ert/lib/ecl/tests/rft_test.cpp index dd80cc6411..4bd4b85f5f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/rft_test.c +++ b/ThirdParty/Ert/lib/ecl/tests/rft_test.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'rft_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'rft_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include @@ -27,9 +27,9 @@ int main (int argc , char ** argv) { util_exit("I want one RFT file - try again \n"); { const char * filename = argv[1]; - ecl_rft_file_type * rft_file = ecl_rft_file_alloc( filename ); + ecl_rft_file_type * rft_file = ecl_rft_file_alloc( filename ); stringlist_type * wells = ecl_rft_file_alloc_well_list( rft_file ); - + printf("\n"); { int iw; @@ -55,7 +55,7 @@ int main (int argc , char ** argv) { printf(" \n"); printf(" %g \n", ecl_rft_node_iget_pressure( node, icell)); printf(" %g \n" , ecl_rft_node_iget_depth( node , icell)); - printf(" %3d,%3d,%3d \n",i,j,k); + printf(" %3d,%3d,%3d \n",i,j,k); printf(" \n"); } } diff --git a/ThirdParty/Ert/lib/ecl/tests/test_ecl_file_index.c b/ThirdParty/Ert/lib/ecl/tests/test_ecl_file_index.cpp similarity index 89% rename from ThirdParty/Ert/lib/ecl/tests/test_ecl_file_index.c rename to ThirdParty/Ert/lib/ecl/tests/test_ecl_file_index.cpp index 7a241d7f49..59f59bb79e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/test_ecl_file_index.c +++ b/ThirdParty/Ert/lib/ecl/tests/test_ecl_file_index.cpp @@ -19,12 +19,12 @@ #include #include -#include +#include #include -#include +#include -#include -#include +#include +#include void test_load_nonexisting_file() { ecl_file_type * ecl_file = ecl_file_fast_open("base_file", "a_file_that_does_not_exist_2384623", 0); @@ -36,23 +36,23 @@ void test_create_and_load_index_file() { test_work_area_type * work_area = test_work_area_alloc("ecl_file_index_testing"); { - char * file_name = "initial_data_file"; - char * index_file_name = "index_file"; + const char * file_name = "initial_data_file"; + const char * index_file_name = "index_file"; //creating the data file - size_t data_size = 10; + int data_size = 10; ecl_kw_type * kw1 = ecl_kw_alloc("TEST1_KW", data_size, ECL_INT); for(int i = 0; i < data_size; ++i) ecl_kw_iset_int(kw1, i, 537 + i); fortio_type * fortio = fortio_open_writer(file_name, false, ECL_ENDIAN_FLIP); - ecl_kw_fwrite(kw1, fortio); - + ecl_kw_fwrite(kw1, fortio); + data_size = 5; ecl_kw_type * kw2 = ecl_kw_alloc("TEST2_KW", data_size, ECL_FLOAT); for(int i = 0; i < data_size; ++i) ecl_kw_iset_float(kw2, i, 0.15 * i); ecl_kw_fwrite(kw2, fortio); - fortio_fclose(fortio); + fortio_fclose(fortio); //finished creating data file //creating ecl_file @@ -60,7 +60,7 @@ void test_create_and_load_index_file() { test_assert_true( ecl_file_has_kw( ecl_file , "TEST1_KW" ) ); ecl_file_write_index( ecl_file , index_file_name); int ecl_file_size = ecl_file_get_size( ecl_file ); - ecl_file_close( ecl_file ); + ecl_file_close( ecl_file ); //finished using ecl_file test_assert_false( ecl_file_index_valid(file_name, "nofile")); @@ -79,12 +79,12 @@ void test_create_and_load_index_file() { test_assert_true( ecl_file_is_instance(ecl_file_index) ); test_assert_true( ecl_file_get_global_view(ecl_file_index) ); - test_assert_int_equal(ecl_file_size, ecl_file_get_size(ecl_file_index) ); - + test_assert_int_equal(ecl_file_size, ecl_file_get_size(ecl_file_index) ); + test_assert_true( ecl_file_has_kw( ecl_file_index, "TEST1_KW" ) ); test_assert_true( ecl_file_has_kw( ecl_file_index, "TEST2_KW" ) ); - ecl_kw_type * kwi1 = ecl_file_iget_kw( ecl_file_index , 0 ); + ecl_kw_type * kwi1 = ecl_file_iget_kw( ecl_file_index , 0 ); test_assert_true (ecl_kw_equal(kw1, kwi1)); test_assert_double_equal( 537.0, ecl_kw_iget_as_double(kwi1, 0) ); test_assert_double_equal( 546.0, ecl_kw_iget_as_double(kwi1, 9) ); @@ -92,7 +92,7 @@ void test_create_and_load_index_file() { ecl_kw_type * kwi2 = ecl_file_iget_kw( ecl_file_index , 1 ); test_assert_true (ecl_kw_equal(kw2, kwi2)); test_assert_double_equal( 0.15, ecl_kw_iget_as_double(kwi2, 1) ); - test_assert_double_equal( 0.60, ecl_kw_iget_as_double(kwi2, 4) ); + test_assert_double_equal( 0.60, ecl_kw_iget_as_double(kwi2, 4) ); ecl_kw_free(kw1); ecl_kw_free(kw2); diff --git a/ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data.c b/ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data.cpp similarity index 88% rename from ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data.c rename to ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data.cpp index 38d1dff474..a68185e61f 100644 --- a/ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data.c +++ b/ThirdParty/Ert/lib/ecl/tests/test_ecl_nnc_data.cpp @@ -16,18 +16,18 @@ for more details. */ -#include -#include -#include +#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include #include -#include -#include +#include +#include @@ -46,7 +46,7 @@ void test_alloc_global_only(bool data_in_file) { ecl_grid_add_self_nnc(grid0, 2 ,nx*ny + 2, 2 ); { ecl_nnc_geometry_type * nnc_geo = ecl_nnc_geometry_alloc( grid0 ); - test_assert_int_equal( ecl_nnc_geometry_size( nnc_geo ) , 3 ); + test_assert_int_equal( ecl_nnc_geometry_size( nnc_geo ) , 3 ); /* Create a dummy INIT file which *ony* contains a TRANNC keyword with the correct size. */ @@ -63,15 +63,15 @@ void test_alloc_global_only(bool data_in_file) { fortio_fclose( f ); ecl_kw_free( trann_nnc ); } - + ecl_file_type * init_file = ecl_file_open( "TEST.INIT" , 0 ); - ecl_file_view_type * view_file = ecl_file_get_global_view( init_file ); - + ecl_file_view_type * view_file = ecl_file_get_global_view( init_file ); + ecl_nnc_data_type * nnc_geo_data = ecl_nnc_data_alloc_tran(grid0, nnc_geo, view_file); - + if (data_in_file) { - + int nnc_data_size = ecl_nnc_data_get_size( nnc_geo_data ); test_assert_true( ecl_file_view_has_kw( view_file, TRANNNC_KW) ); test_assert_true(nnc_data_size == 3); @@ -82,7 +82,7 @@ void test_alloc_global_only(bool data_in_file) { } else test_assert_NULL(nnc_geo_data); - + if (data_in_file) ecl_nnc_data_free( nnc_geo_data ); ecl_nnc_geometry_free( nnc_geo ); @@ -98,7 +98,7 @@ void test_alloc_global_only(bool data_in_file) { int main(int argc , char ** argv) { - + test_alloc_global_only(true); test_alloc_global_only(false); diff --git a/ThirdParty/Ert/lib/ecl/tests/test_transactions.c b/ThirdParty/Ert/lib/ecl/tests/test_transactions.cpp similarity index 90% rename from ThirdParty/Ert/lib/ecl/tests/test_transactions.c rename to ThirdParty/Ert/lib/ecl/tests/test_transactions.cpp index 166c3ca725..1d6f9933ad 100644 --- a/ThirdParty/Ert/lib/ecl/tests/test_transactions.c +++ b/ThirdParty/Ert/lib/ecl/tests/test_transactions.cpp @@ -20,16 +20,16 @@ #include #include -#include +#include #include -#include +#include -#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include /* @@ -40,16 +40,16 @@ void test_transaction() { test_work_area_type * work_area = test_work_area_alloc("ecl_file_index_testing"); { - char * file_name = "data_file"; + const char * file_name = "data_file"; fortio_type * fortio = fortio_open_writer(file_name, false, ECL_ENDIAN_FLIP); //creating the data file - size_t data_size = 10; + int data_size = 10; ecl_kw_type * kw1 = ecl_kw_alloc("TEST1_KW", data_size, ECL_INT); for(int i = 0; i < data_size; ++i) ecl_kw_iset_int(kw1, i, 537 + i); - ecl_kw_fwrite(kw1, fortio); - + ecl_kw_fwrite(kw1, fortio); + data_size = 5; ecl_kw_type * kw2 = ecl_kw_alloc("TEST2_KW", data_size, ECL_FLOAT); for(int i = 0; i < data_size; ++i) @@ -62,9 +62,9 @@ void test_transaction() { ecl_kw_iset_float(kw3, i, 0.45 * i); ecl_kw_fwrite(kw3, fortio); - fortio_fclose(fortio); + fortio_fclose(fortio); //finished creating data file - + ecl_file_type * file = ecl_file_open(file_name, 0); ecl_file_view_type * file_view = ecl_file_get_global_view(file); ecl_file_kw_type * file_kw0 = ecl_file_view_iget_file_kw( file_view , 0); @@ -80,7 +80,7 @@ void test_transaction() { ecl_file_view_iget_kw(file_view, 0); ecl_file_view_iget_kw(file_view, 1); ecl_file_transaction_type * t2 = ecl_file_view_start_transaction( file_view ); - + ecl_file_view_iget_kw(file_view, 0); ecl_file_view_iget_kw(file_view, 1); ecl_file_view_iget_kw(file_view, 1); diff --git a/ThirdParty/Ert/lib/ecl/tests/well_branch_collection.c b/ThirdParty/Ert/lib/ecl/tests/well_branch_collection.cpp similarity index 75% rename from ThirdParty/Ert/lib/ecl/tests/well_branch_collection.c rename to ThirdParty/Ert/lib/ecl/tests/well_branch_collection.cpp index 39daebd45e..df88ed73af 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_branch_collection.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_branch_collection.cpp @@ -1,49 +1,49 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_branch_collection.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_branch_collection.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include +#include -#include -#include -#include +#include +#include +#include int main(int argc , char ** argv) { test_install_SIGNALS(); - + well_branch_collection_type * branches = well_branch_collection_alloc(); - double * rseg_data = util_calloc( 100 , sizeof * rseg_data ); + double * rseg_data = (double *) util_calloc( 100 , sizeof * rseg_data ); const double depth = 100; const double length = 20; const double total_length = 200; const double diameter = 10; - rseg_data[ RSEG_DEPTH_INDEX ] = depth; + rseg_data[ RSEG_DEPTH_INDEX ] = depth; rseg_data[ RSEG_LENGTH_INDEX ] = length; rseg_data[ RSEG_TOTAL_LENGTH_INDEX ] = total_length; - rseg_data[ RSEG_DIAMETER_INDEX ] = diameter; - + rseg_data[ RSEG_DIAMETER_INDEX ] = diameter; + test_assert_true( well_branch_collection_is_instance( branches )); test_assert_int_equal( well_branch_collection_get_size( branches ) , 0 ); test_assert_NULL( well_branch_collection_iget_start_segment( branches , 0 )); @@ -52,12 +52,12 @@ int main(int argc , char ** argv) { { well_segment_type * segment1 = well_segment_alloc(189 , 99 , 78 , rseg_data); well_segment_type * segment2 = well_segment_alloc(200 , 189 , 78 , rseg_data); - + test_assert_false( well_branch_collection_add_start_segment( branches , segment1 )); - + test_assert_true( well_segment_link( segment2 , segment1 )); test_assert_true( well_branch_collection_add_start_segment( branches , segment2 )); - + test_assert_int_equal( well_branch_collection_get_size( branches ) , 1 ); test_assert_true( well_segment_is_instance( well_branch_collection_iget_start_segment( branches , 0 ))); test_assert_true( well_segment_is_instance( well_branch_collection_get_start_segment( branches , 78 ))); @@ -65,7 +65,7 @@ int main(int argc , char ** argv) { well_segment_free( segment2 ); well_segment_free( segment1 ); - + } free( rseg_data ); well_branch_collection_free( branches ); diff --git a/ThirdParty/Ert/lib/ecl/tests/well_conn.c b/ThirdParty/Ert/lib/ecl/tests/well_conn.cpp similarity index 91% rename from ThirdParty/Ert/lib/ecl/tests/well_conn.c rename to ThirdParty/Ert/lib/ecl/tests/well_conn.cpp index a1c8583eb3..c81907c0bc 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_conn.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_conn.cpp @@ -1,32 +1,32 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_conn.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_conn.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include +#include -#include -#include +#include +#include void test_conn_rate(){ int i = 10; diff --git a/ThirdParty/Ert/lib/ecl/tests/well_conn_CF.c b/ThirdParty/Ert/lib/ecl/tests/well_conn_CF.cpp similarity index 75% rename from ThirdParty/Ert/lib/ecl/tests/well_conn_CF.c rename to ThirdParty/Ert/lib/ecl/tests/well_conn_CF.cpp index 8ff2c0411c..27de6631d5 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_conn_CF.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_conn_CF.cpp @@ -1,38 +1,38 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include -#include -#include -#include +#include +#include +#include -void well_conn_test_CF( const ecl_kw_type * iwel_kw , const ecl_kw_type * icon_kw , const ecl_kw_type * scon_kw, const ecl_kw_type * xcon_kw , const const ecl_rsthead_type * rst_head , int iwell , int iconn, double CF) { +void well_conn_test_CF( const ecl_kw_type * iwel_kw , const ecl_kw_type * icon_kw , const ecl_kw_type * scon_kw, const ecl_kw_type * xcon_kw , const ecl_rsthead_type * rst_head , int iwell , int iconn, double CF) { well_conn_type * conn = well_conn_alloc_from_kw( icon_kw , scon_kw, xcon_kw , rst_head , iwell , iconn ); test_assert_double_equal( CF , well_conn_get_connection_factor(conn)); well_conn_free( conn ); diff --git a/ThirdParty/Ert/lib/ecl/tests/well_conn_collection.c b/ThirdParty/Ert/lib/ecl/tests/well_conn_collection.cpp similarity index 68% rename from ThirdParty/Ert/lib/ecl/tests/well_conn_collection.c rename to ThirdParty/Ert/lib/ecl/tests/well_conn_collection.cpp index 41b4fa4cfe..d988c1b1e6 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_conn_collection.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_conn_collection.cpp @@ -1,39 +1,39 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_conn_collection.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_conn_collection.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include +#include -#include -#include +#include +#include void test_empty() { well_conn_collection_type * wellcc = well_conn_collection_alloc( ); test_assert_not_NULL( wellcc ); test_assert_true( well_conn_collection_is_instance( wellcc )); - + test_assert_int_equal( 0 , well_conn_collection_get_size( wellcc )); { well_conn_type * conn = well_conn_collection_iget( wellcc , 0 ); @@ -43,7 +43,7 @@ void test_empty() { const well_conn_type * conn = well_conn_collection_iget_const( wellcc , 10 ); test_assert_NULL( conn ); } - + well_conn_collection_free( wellcc ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/well_conn_load.c b/ThirdParty/Ert/lib/ecl/tests/well_conn_load.cpp similarity index 83% rename from ThirdParty/Ert/lib/ecl/tests/well_conn_load.c rename to ThirdParty/Ert/lib/ecl/tests/well_conn_load.cpp index ec4a8f3d70..02fd157415 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_conn_load.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_conn_load.cpp @@ -1,35 +1,35 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include -#include -#include -#include +#include +#include +#include @@ -38,12 +38,12 @@ int main(int argc , char ** argv) { bool MSW; ecl_file_type * rst_file = ecl_file_open( Xfile , 0 ); ecl_rsthead_type * rst_head = ecl_rsthead_alloc( ecl_file_get_global_view(rst_file) , ecl_util_filename_report_nr( Xfile )); - + test_install_SIGNALS(); test_assert_true( util_sscanf_bool( argv[2] , &MSW )); test_assert_not_NULL( rst_file ); test_assert_not_NULL( rst_head ); - + { int iwell; const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0 ); @@ -62,14 +62,14 @@ int main(int argc , char ** argv) { for (iconn = 0; iconn < num_connections; iconn++) { well_conn_type * conn = well_conn_alloc_from_kw( icon_kw , scon_kw , xcon_kw, rst_head , iwell , iconn ); - + test_assert_true( well_conn_is_instance( conn )); test_assert_not_NULL( conn ); if (!MSW) test_assert_bool_equal( well_conn_MSW( conn ) , MSW); else caseMSW |= well_conn_MSW( conn ); - + well_conn_collection_add( wellcc , conn ); well_conn_collection_add_ref( wellcc_ref , conn ); test_assert_int_equal( iconn + 1 , well_conn_collection_get_size( wellcc )); @@ -82,15 +82,15 @@ int main(int argc , char ** argv) { int i; for (i=0; i < well_conn_collection_get_size( wellcc ); i++) test_assert_true( well_conn_is_instance( well_conn_collection_iget_const( wellcc , i ))); - + } { well_conn_collection_type * wellcc2 = well_conn_collection_alloc(); int i; - - test_assert_int_equal( well_conn_collection_get_size( wellcc ) , + + test_assert_int_equal( well_conn_collection_get_size( wellcc ) , well_conn_collection_load_from_kw( wellcc2 , iwel_kw , icon_kw , scon_kw, xcon_kw, iwell , rst_head)); - + for (i=0; i < well_conn_collection_get_size( wellcc2 ); i++) { test_assert_true( well_conn_is_instance( well_conn_collection_iget_const( wellcc2 , i ))); test_assert_true( well_conn_equal( well_conn_collection_iget_const( wellcc2 , i ) , well_conn_collection_iget_const( wellcc , i ))); @@ -101,7 +101,7 @@ int main(int argc , char ** argv) { } test_assert_bool_equal( caseMSW , MSW); } - + exit( 0 ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/well_dualp.c b/ThirdParty/Ert/lib/ecl/tests/well_dualp.cpp similarity index 74% rename from ThirdParty/Ert/lib/ecl/tests/well_dualp.c rename to ThirdParty/Ert/lib/ecl/tests/well_dualp.cpp index cffd40455c..30315df48e 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_dualp.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_dualp.cpp @@ -1,43 +1,43 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_dualp.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_dualp.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include -#include +#include void test_rstfile( const char * filename , bool fracture_connection) { ecl_file_type * rst_file = ecl_file_open( filename , 0); const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0); ecl_rsthead_type * header = ecl_rsthead_alloc( ecl_file_get_global_view( rst_file ), ecl_util_filename_report_nr(filename)); - + well_conn_type * wellhead = well_conn_alloc_wellhead( iwel_kw , header , 0 ); - + if (fracture_connection) { test_assert_true( well_conn_fracture_connection( wellhead )); test_assert_false( well_conn_matrix_connection( wellhead )); @@ -45,9 +45,9 @@ void test_rstfile( const char * filename , bool fracture_connection) { test_assert_false( well_conn_fracture_connection( wellhead )); test_assert_true( well_conn_matrix_connection( wellhead )); } - + test_assert_true( well_conn_get_k( wellhead ) < header->nz ); - + ecl_rsthead_free( header ); well_conn_free( wellhead ); ecl_file_close( rst_file ); @@ -60,6 +60,6 @@ int main(int argc , char ** argv) { test_rstfile( fracture_rstfile , true); test_rstfile( matrix_rstfile , false ); - + exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/well_info.c b/ThirdParty/Ert/lib/ecl/tests/well_info.cpp similarity index 63% rename from ThirdParty/Ert/lib/ecl/tests/well_info.c rename to ThirdParty/Ert/lib/ecl/tests/well_info.cpp index 8a8dcb5424..2daf549175 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_info.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_info.cpp @@ -1,37 +1,37 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_conn.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_conn.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include -#include +#include +#include -#include +#include int main(int argc , char ** argv) { const char * grid_file = argv[1]; - + ecl_grid_type * grid = ecl_grid_alloc( grid_file ); test_assert_not_NULL( grid ); { diff --git a/ThirdParty/Ert/lib/ecl/tests/well_lgr_load.c b/ThirdParty/Ert/lib/ecl/tests/well_lgr_load.cpp similarity index 82% rename from ThirdParty/Ert/lib/ecl/tests/well_lgr_load.c rename to ThirdParty/Ert/lib/ecl/tests/well_lgr_load.cpp index e00b55709c..4e060c1772 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_lgr_load.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_lgr_load.cpp @@ -21,17 +21,18 @@ #include #include -#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include @@ -54,6 +55,7 @@ int main( int argc , char ** argv) { for (int iwell = 0; iwell < well_info_get_num_wells( well_info ); iwell++) { well_ts_type * well_ts = well_info_get_ts( well_info , well_info_iget_well_name( well_info , iwell)); well_state_type * well_state = well_ts_get_last_state( well_ts ); + test_assert_not_NULL(well_state); } well_info_free( well_info ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment.c b/ThirdParty/Ert/lib/ecl/tests/well_segment.cpp similarity index 85% rename from ThirdParty/Ert/lib/ecl/tests/well_segment.c rename to ThirdParty/Ert/lib/ecl/tests/well_segment.cpp index 79426e62fd..fd3062716a 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment.cpp @@ -1,45 +1,45 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_segment.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_segment.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include +#include -#include -#include +#include +#include int main(int argc , char ** argv) { test_install_SIGNALS(); - double * rseg_data = util_calloc( 100 , sizeof * rseg_data ); + double * rseg_data = (double *) util_calloc( 100 , sizeof * rseg_data ); const double depth = 100; const double length = 20; const double total_length = 200; const double diameter = 10; - rseg_data[ RSEG_DEPTH_INDEX ] = depth; + rseg_data[ RSEG_DEPTH_INDEX ] = depth; rseg_data[ RSEG_LENGTH_INDEX ] = length; rseg_data[ RSEG_TOTAL_LENGTH_INDEX ] = total_length; - rseg_data[ RSEG_DIAMETER_INDEX ] = diameter; + rseg_data[ RSEG_DIAMETER_INDEX ] = diameter; { int segment_id = 78; int outlet_segment_id = 100; @@ -69,7 +69,7 @@ int main(int argc , char ** argv) { int outlet_segment_id = WELL_SEGMENT_OUTLET_END_VALUE; int branch_nr = 100; well_segment_type * ws = well_segment_alloc(12 , outlet_segment_id , branch_nr, rseg_data); - + test_assert_true( well_segment_nearest_wellhead( ws )); test_assert_false( well_segment_main_stem( ws )); well_segment_free( ws ); @@ -80,7 +80,7 @@ int main(int argc , char ** argv) { int outlet_segment_id = WELL_SEGMENT_OUTLET_END_VALUE; int branch_nr = WELL_SEGMENT_BRANCH_INACTIVE_VALUE; well_segment_type * ws = well_segment_alloc(89 , outlet_segment_id , branch_nr, rseg_data); - + test_assert_false( well_segment_active( ws )); well_segment_free( ws ); } @@ -90,7 +90,7 @@ int main(int argc , char ** argv) { int outlet_id = 0; well_segment_type * outlet = well_segment_alloc(outlet_id , WELL_SEGMENT_OUTLET_END_VALUE , branch_nr, rseg_data); well_segment_type * ws = well_segment_alloc(100 , outlet_id , branch_nr, rseg_data); - + test_assert_true( well_segment_link( ws , outlet )); test_assert_ptr_equal( well_segment_get_outlet( ws ) , outlet ); test_assert_int_equal( well_segment_get_link_count( outlet ) , 1 ); @@ -106,11 +106,11 @@ int main(int argc , char ** argv) { int outlet_id = 0; well_segment_type * outlet = well_segment_alloc(outlet_id , WELL_SEGMENT_OUTLET_END_VALUE , branch_nr , rseg_data); well_segment_type * ws = well_segment_alloc(100 , outlet_id + 1, branch_nr, rseg_data); - + test_assert_false( well_segment_link( ws , outlet )); test_assert_NULL( well_segment_get_outlet( ws ) ); test_assert_int_equal( well_segment_get_link_count( outlet ) , 0 ); - + well_segment_free( ws ); well_segment_free( outlet ); } diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment_branch_conn_load.c b/ThirdParty/Ert/lib/ecl/tests/well_segment_branch_conn_load.cpp similarity index 80% rename from ThirdParty/Ert/lib/ecl/tests/well_segment_branch_conn_load.c rename to ThirdParty/Ert/lib/ecl/tests/well_segment_branch_conn_load.cpp index 05e71495d3..55761b2448 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment_branch_conn_load.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment_branch_conn_load.cpp @@ -1,39 +1,39 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_segment_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_segment_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include int main(int argc , char ** argv) { @@ -51,7 +51,7 @@ int main(int argc , char ** argv) { test_install_SIGNALS(); test_assert_not_NULL( rst_file ); test_assert_not_NULL( rst_head ); - { + { int well_nr; for (well_nr = 0; well_nr < rst_head->nwells; well_nr++) { well_conn_collection_type * connections = well_conn_collection_alloc(); @@ -60,18 +60,18 @@ int main(int argc , char ** argv) { well_segment_collection_type * segments = well_segment_collection_alloc(); bool load_segment_information = true; bool is_MSW_well = false; - + if (well_segment_collection_load_from_kw( segments , well_nr , iwel_kw , iseg_kw , rseg_loader , rst_head , load_segment_information , &is_MSW_well)) { well_branch_collection_type * branches = well_branch_collection_alloc(); - + test_assert_true( well_segment_well_is_MSW( well_nr , iwel_kw , rst_head)); well_segment_collection_link( segments ); { int is; for (is=0; is < well_segment_collection_get_size( segments ); is++) { well_segment_type * segment = well_segment_collection_iget( segments , is ); - - if (well_segment_nearest_wellhead( segment )) + + if (well_segment_nearest_wellhead( segment )) test_assert_NULL( well_segment_get_outlet( segment )); else test_assert_not_NULL( well_segment_get_outlet( segment )); @@ -86,16 +86,16 @@ int main(int argc , char ** argv) { for (ib = 0; ib < well_branch_collection_get_size( branches ); ib++) { const well_segment_type * start_segment = well_branch_collection_iget_start_segment( branches , ib ); const well_segment_type * segment = start_segment; - + printf("Branch %d " , ib ); while (segment) { printf("%d -> ",well_segment_get_id( segment )); segment = well_segment_get_outlet( segment ); } printf(" X \n"); - } + } } - well_segment_collection_add_connections( segments , ECL_GRID_GLOBAL_GRID , connections ); + well_segment_collection_add_connections( segments , ECL_GRID_GLOBAL_GRID , connections ); well_branch_collection_free( branches ); } else test_assert_false( well_segment_well_is_MSW( well_nr , iwel_kw , rst_head )); diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment_collection.c b/ThirdParty/Ert/lib/ecl/tests/well_segment_collection.cpp similarity index 82% rename from ThirdParty/Ert/lib/ecl/tests/well_segment_collection.c rename to ThirdParty/Ert/lib/ecl/tests/well_segment_collection.cpp index 8ade17c741..8c28653adc 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment_collection.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment_collection.cpp @@ -1,37 +1,37 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_segment_collection.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_segment_collection.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include +#include -#include -#include +#include +#include int main(int argc , char ** argv) { test_install_SIGNALS(); - double * rseg_data = util_calloc( 100 , sizeof * rseg_data ); + double * rseg_data = (double *) util_calloc( 100 , sizeof * rseg_data ); well_segment_collection_type * sc = well_segment_collection_alloc(); test_assert_not_NULL( sc ); test_assert_int_equal( well_segment_collection_get_size( sc ) , 0 ); @@ -40,11 +40,11 @@ int main(int argc , char ** argv) { int outlet_segment_id = WELL_SEGMENT_OUTLET_END_VALUE; int branch_nr = WELL_SEGMENT_BRANCH_INACTIVE_VALUE; well_segment_type * ws = well_segment_alloc(89 , outlet_segment_id , branch_nr, rseg_data); - + well_segment_collection_add( sc , ws ); test_assert_int_equal( well_segment_collection_get_size( sc ) , 1); test_assert_ptr_equal( well_segment_collection_iget( sc , 0 ) , ws ); - + test_assert_false( well_segment_collection_has_segment( sc , 451 )); test_assert_true( well_segment_collection_has_segment( sc , 89 )); test_assert_ptr_equal( well_segment_collection_get( sc , 89 ) , ws ); @@ -54,11 +54,11 @@ int main(int argc , char ** argv) { int outlet_segment_id = WELL_SEGMENT_OUTLET_END_VALUE; int branch_nr = WELL_SEGMENT_BRANCH_INACTIVE_VALUE; well_segment_type * ws = well_segment_alloc(90 , outlet_segment_id , branch_nr , rseg_data); - + well_segment_collection_add( sc , ws ); test_assert_int_equal( well_segment_collection_get_size( sc ) , 2); test_assert_ptr_equal( well_segment_collection_iget( sc , 1 ) , ws ); - + test_assert_false( well_segment_collection_has_segment( sc , 451 )); test_assert_true( well_segment_collection_has_segment( sc , 89 )); test_assert_true( well_segment_collection_has_segment( sc , 90 )); @@ -70,18 +70,18 @@ int main(int argc , char ** argv) { int outlet_segment_id = WELL_SEGMENT_OUTLET_END_VALUE; int branch_nr = WELL_SEGMENT_BRANCH_INACTIVE_VALUE; well_segment_type * ws = well_segment_alloc(89 , outlet_segment_id , branch_nr, rseg_data); - + well_segment_collection_add( sc , ws ); test_assert_int_equal( well_segment_collection_get_size( sc ) , 2); test_assert_ptr_equal( well_segment_collection_iget( sc , 0 ) , ws ); - + test_assert_false( well_segment_collection_has_segment( sc , 451 )); test_assert_true( well_segment_collection_has_segment( sc , 89 )); test_assert_ptr_equal( well_segment_collection_get( sc , 89 ) , ws ); } - + free( rseg_data ); well_segment_collection_free( sc ); - + exit(0); } diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment_conn.c b/ThirdParty/Ert/lib/ecl/tests/well_segment_conn.cpp similarity index 66% rename from ThirdParty/Ert/lib/ecl/tests/well_segment_conn.c rename to ThirdParty/Ert/lib/ecl/tests/well_segment_conn.cpp index b3886e604c..9b53f16eaa 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment_conn.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment_conn.cpp @@ -1,48 +1,48 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_segment_conn.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_segment_conn.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include -#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include int main(int argc , char ** argv) { test_install_SIGNALS(); - double * rseg_data = util_calloc( 100 , sizeof * rseg_data ); + double * rseg_data = (double *) util_calloc( 100 , sizeof * rseg_data ); { double CF = 88; int segment_id = 78; int outlet_segment_id = 100; int branch_nr = WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE; well_segment_type * ws = well_segment_alloc(segment_id , outlet_segment_id , branch_nr, rseg_data); - well_conn_type * conn1 = well_conn_alloc_MSW(1,1,1,CF,true,well_conn_dirX,segment_id); - well_conn_type * conn2 = well_conn_alloc_MSW(1,1,1,CF,true,well_conn_dirX,segment_id + 1); - + well_conn_type * conn1 = well_conn_alloc_MSW(1,1,1,CF,well_conn_dirX,true,segment_id); + well_conn_type * conn2 = well_conn_alloc_MSW(1,1,1,CF,well_conn_dirX,true,segment_id + 1); + test_assert_false( well_segment_has_global_grid_connections( ws )); test_assert_true( well_segment_add_connection( ws , ECL_GRID_GLOBAL_GRID , conn1 )); diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment_conn_load.c b/ThirdParty/Ert/lib/ecl/tests/well_segment_conn_load.cpp similarity index 79% rename from ThirdParty/Ert/lib/ecl/tests/well_segment_conn_load.c rename to ThirdParty/Ert/lib/ecl/tests/well_segment_conn_load.cpp index 6fbdb46eb6..92b213fbfd 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment_conn_load.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment_conn_load.cpp @@ -1,38 +1,38 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_segment_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_segment_conn_load.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include int main(int argc , char ** argv) { @@ -47,29 +47,29 @@ int main(int argc , char ** argv) { test_install_SIGNALS(); test_assert_not_NULL( rst_file ); test_assert_not_NULL( rst_head ); - { + { int well_nr; for (well_nr = 0; well_nr < rst_head->nwells; well_nr++) { well_conn_collection_type * connections = well_conn_collection_alloc(); well_conn_collection_load_from_kw( connections , iwel_kw , icon_kw , well_nr , rst_head); { well_segment_collection_type * segments = well_segment_collection_alloc(); - + if (well_segment_collection_load_from_kw( segments , well_nr , iwel_kw , iseg_kw , rseg_kw , rst_head )) { well_branch_collection_type * branches = well_branch_collection_alloc(); - + test_assert_true( well_segment_well_is_MSW( well_nr , iwel_kw , rst_head)); well_segment_collection_link( segments ); { int is; for (is=0; is < well_segment_collection_get_size( segments ); is++) { well_segment_type * segment = well_segment_collection_iget( segments , is ); - - if (well_segment_nearest_wellhead( segment )) + + if (well_segment_nearest_wellhead( segment )) test_assert_NULL( well_segment_get_outlet( segment )); else test_assert_not_NULL( well_segment_get_outlet( segment )); - + test_assert_ptr_not_equal( segment , well_segment_get_outlet( segment )); } } @@ -80,7 +80,7 @@ int main(int argc , char ** argv) { for (ib = 0; ib < well_branch_collection_get_size( branches ); ib++) { const well_segment_type * start_segment = well_branch_collection_iget_start_segment( branches , ib ); const well_segment_type * segment = start_segment; - + printf("Branch %d/%d " , ib , well_branch_collection_get_size( branches ) ); while (segment) { printf("[%p]%d -> \n",segment , well_segment_get_id( segment )); @@ -88,9 +88,9 @@ int main(int argc , char ** argv) { } printf("\n"); sleep(1); - } + } } - well_segment_collection_add_connections( segments , ECL_GRID_GLOBAL_GRID , connections ); + well_segment_collection_add_connections( segments , ECL_GRID_GLOBAL_GRID , connections ); well_branch_collection_free( branches ); } else test_assert_false( well_segment_well_is_MSW( well_nr , iwel_kw , rst_head )); diff --git a/ThirdParty/Ert/lib/ecl/tests/well_segment_load.c b/ThirdParty/Ert/lib/ecl/tests/well_segment_load.cpp similarity index 81% rename from ThirdParty/Ert/lib/ecl/tests/well_segment_load.c rename to ThirdParty/Ert/lib/ecl/tests/well_segment_load.cpp index 633646a306..6ca651d811 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_segment_load.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_segment_load.cpp @@ -1,36 +1,36 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_segment_load.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_segment_load.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include int main(int argc , char ** argv) { @@ -45,10 +45,10 @@ int main(int argc , char ** argv) { test_install_SIGNALS(); test_assert_not_NULL( rst_file ); test_assert_not_NULL( rst_head ); - + { int well_nr; - + for (well_nr = 0; well_nr < rst_head->nwells; well_nr++) { int iwel_offset = rst_head->niwelz * well_nr; well_segment_collection_type * segments = well_segment_collection_alloc(); @@ -56,13 +56,13 @@ int main(int argc , char ** argv) { if (seg_well_nr >= 0) { int segment_index; int segment_count = 0; - + for (segment_index = 0; segment_index < rst_head->nsegmx; segment_index++) { int segment_id = segment_index + WELL_SEGMENT_OFFSET; well_segment_type * segment = well_segment_alloc_from_kw( iseg_kw , rseg_loader , rst_head , seg_well_nr , segment_index , segment_id ); - + test_assert_true( well_segment_is_instance( segment )); - + if (well_segment_active( segment )) { well_segment_collection_add( segments , segment ); test_assert_int_equal( well_segment_collection_get_size( segments ) , segment_count + 1); @@ -71,7 +71,7 @@ int main(int argc , char ** argv) { } else well_segment_free( segment ); } - } + } { well_segment_collection_type * segments2 = well_segment_collection_alloc(); @@ -84,7 +84,7 @@ int main(int argc , char ** argv) { test_assert_true( is_MSW_well ); else test_assert_false( is_MSW_well ); - + well_segment_collection_link( segments ); well_segment_collection_link( segments2 ); diff --git a/ThirdParty/Ert/lib/ecl/tests/well_state.c b/ThirdParty/Ert/lib/ecl/tests/well_state.cpp similarity index 86% rename from ThirdParty/Ert/lib/ecl/tests/well_state.c rename to ThirdParty/Ert/lib/ecl/tests/well_state.cpp index 111e858a06..436aad1cd0 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_state.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_state.cpp @@ -1,30 +1,30 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_state.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_state.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include +#include -#include +#include int main(int argc , char ** argv) { diff --git a/ThirdParty/Ert/lib/ecl/tests/well_state_load.c b/ThirdParty/Ert/lib/ecl/tests/well_state_load.cpp similarity index 92% rename from ThirdParty/Ert/lib/ecl/tests/well_state_load.c rename to ThirdParty/Ert/lib/ecl/tests/well_state_load.cpp index 9957e3a19d..e78acdfcd5 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_state_load.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_state_load.cpp @@ -18,16 +18,16 @@ #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include -#include +#include int main(int argc , char ** argv) { diff --git a/ThirdParty/Ert/lib/ecl/tests/well_state_load_missing_RSEG.c b/ThirdParty/Ert/lib/ecl/tests/well_state_load_missing_RSEG.cpp similarity index 77% rename from ThirdParty/Ert/lib/ecl/tests/well_state_load_missing_RSEG.c rename to ThirdParty/Ert/lib/ecl/tests/well_state_load_missing_RSEG.cpp index 503526232d..d20955352b 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_state_load_missing_RSEG.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_state_load_missing_RSEG.cpp @@ -1,33 +1,33 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_state_load_missing_RSEG.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_state_load_missing_RSEG.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include -#include +#include int main(int argc , char ** argv) { @@ -47,7 +47,7 @@ int main(int argc , char ** argv) { well_type_enum type = ECL_WELL_GAS_INJECTOR; int global_well_nr = 0; bool load_segment_information = false; - + for (global_well_nr = 0; global_well_nr < header->nwells; global_well_nr++) { well_state_type * well_state = well_state_alloc(well_name , global_well_nr , open , type , report_nr , valid_from); test_assert_true( well_state_is_instance( well_state) ); diff --git a/ThirdParty/Ert/lib/ecl/tests/well_ts.c b/ThirdParty/Ert/lib/ecl/tests/well_ts.cpp similarity index 92% rename from ThirdParty/Ert/lib/ecl/tests/well_ts.c rename to ThirdParty/Ert/lib/ecl/tests/well_ts.cpp index 6de48ad200..7a4dba9dc9 100644 --- a/ThirdParty/Ert/lib/ecl/tests/well_ts.c +++ b/ThirdParty/Ert/lib/ecl/tests/well_ts.cpp @@ -18,14 +18,14 @@ #include #include -#include -#include +#include +#include #include -#include -#include +#include +#include -#include +#include int main(int argc , char ** argv) { diff --git a/ThirdParty/Ert/lib/ecl/well_branch_collection.cpp b/ThirdParty/Ert/lib/ecl/well_branch_collection.cpp index dfc43b96b3..005419decf 100644 --- a/ThirdParty/Ert/lib/ecl/well_branch_collection.cpp +++ b/ThirdParty/Ert/lib/ecl/well_branch_collection.cpp @@ -1,24 +1,24 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_branch_collection.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_branch_collection.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include -#include +#include #include #include #include @@ -102,14 +102,14 @@ bool well_branch_collection_add_start_segment( well_branch_collection_type * bra if ((well_segment_get_link_count( start_segment ) == 0) && (well_segment_get_outlet(start_segment))) { int branch_id = well_segment_get_branch_id( start_segment ); int current_index = int_vector_safe_iget( branches->index_map , branch_id); - if (current_index >= 0) + if (current_index >= 0) vector_iset_ref( branches->__start_segments , current_index , start_segment); else { int new_index = vector_get_size( branches->__start_segments ); vector_append_ref( branches->__start_segments , start_segment); int_vector_iset( branches->index_map , branch_id , new_index); } - + return true; } else return false; @@ -117,4 +117,4 @@ bool well_branch_collection_add_start_segment( well_branch_collection_type * bra - + diff --git a/ThirdParty/Ert/lib/ecl/well_conn.cpp b/ThirdParty/Ert/lib/ecl/well_conn.cpp index aaa394901c..eaa8a90ac4 100644 --- a/ThirdParty/Ert/lib/ecl/well_conn.cpp +++ b/ThirdParty/Ert/lib/ecl/well_conn.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include diff --git a/ThirdParty/Ert/lib/ecl/well_conn_collection.cpp b/ThirdParty/Ert/lib/ecl/well_conn_collection.cpp index 2e77fd61a3..788d25440a 100644 --- a/ThirdParty/Ert/lib/ecl/well_conn_collection.cpp +++ b/ThirdParty/Ert/lib/ecl/well_conn_collection.cpp @@ -18,7 +18,7 @@ #include -#include +#include #include #include diff --git a/ThirdParty/Ert/lib/ecl/well_info.cpp b/ThirdParty/Ert/lib/ecl/well_info.cpp index d2e00429b4..b838955ff9 100644 --- a/ThirdParty/Ert/lib/ecl/well_info.cpp +++ b/ThirdParty/Ert/lib/ecl/well_info.cpp @@ -19,10 +19,12 @@ #include #include -#include +#include +#include + +#include #include #include -#include #include #include @@ -180,9 +182,9 @@ struct well_info_struct { - hash_type * wells; /* Hash table of well_ts_type instances; indexed by well name. */ - stringlist_type * well_names; /* A list of all the well names. */ - const ecl_grid_type * grid; + hash_type * wells; /* Hash table of well_ts_type instances; indexed by well name. */ + std::vector well_names; /* A list of all the well names. */ + const ecl_grid_type * grid; }; @@ -192,9 +194,8 @@ struct well_info_struct { */ well_info_type * well_info_alloc( const ecl_grid_type * grid) { - well_info_type * well_info = (well_info_type*)util_malloc( sizeof * well_info ); + well_info_type * well_info = new well_info_type(); well_info->wells = hash_alloc(); - well_info->well_names = stringlist_alloc_new(); well_info->grid = grid; return well_info; } @@ -211,7 +212,7 @@ well_ts_type * well_info_get_ts( const well_info_type * well_info , const char * static void well_info_add_new_ts( well_info_type * well_info , const char * well_name) { well_ts_type * well_ts = well_ts_alloc( well_name ) ; hash_insert_hash_owned_ref( well_info->wells , well_name , well_ts , well_ts_free__); - stringlist_append_copy( well_info->well_names , well_name ); + well_info->well_names.push_back( well_name ); } static void well_info_add_state( well_info_type * well_info , well_state_type * well_state) { @@ -353,8 +354,7 @@ void well_info_load_rst_eclfile( well_info_type * well_info , ecl_file_type * ec void well_info_free( well_info_type * well_info ) { hash_free( well_info->wells ); - stringlist_free( well_info->well_names ); - free( well_info ); + delete well_info; } int well_info_get_well_size( const well_info_type * well_info , const char * well_name ) { @@ -381,16 +381,17 @@ well_state_type * well_info_iget_state( const well_info_type * well_info , const } well_state_type * well_info_iiget_state( const well_info_type * well_info , int well_index , int time_index) { - const char * well_name = stringlist_iget( well_info->well_names , well_index ); - return well_info_iget_state( well_info , well_name , time_index ); + const std::string& well_name = well_info->well_names[well_index]; + return well_info_iget_state( well_info , well_name.c_str() , time_index ); } /*****************************************************************/ int well_info_get_num_wells( const well_info_type * well_info ) { - return stringlist_get_size( well_info->well_names ); + return well_info->well_names.size(); } const char * well_info_iget_well_name( const well_info_type * well_info, int well_index) { - return stringlist_iget( well_info->well_names , well_index); + const std::string& well_name = well_info->well_names[well_index]; + return well_name.c_str(); } diff --git a/ThirdParty/Ert/lib/ecl/well_rseg_loader.cpp b/ThirdParty/Ert/lib/ecl/well_rseg_loader.cpp index 29e507409b..c0bc317cc2 100644 --- a/ThirdParty/Ert/lib/ecl/well_rseg_loader.cpp +++ b/ThirdParty/Ert/lib/ecl/well_rseg_loader.cpp @@ -18,7 +18,7 @@ #include -#include +#include #include #include @@ -36,7 +36,7 @@ struct well_rseg_loader_struct { int_vector_type * relative_index_map; int_vector_type * absolute_index_map; char * buffer; - char * kw; + const char * kw; }; diff --git a/ThirdParty/Ert/lib/ecl/well_segment.cpp b/ThirdParty/Ert/lib/ecl/well_segment.cpp index 8209506788..8d3717847e 100644 --- a/ThirdParty/Ert/lib/ecl/well_segment.cpp +++ b/ThirdParty/Ert/lib/ecl/well_segment.cpp @@ -1,24 +1,24 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_segment.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_segment.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include -#include +#include #include #include @@ -30,13 +30,13 @@ #include #include -#define WELL_SEGMENT_TYPE_ID 2209166 +#define WELL_SEGMENT_TYPE_ID 2209166 struct well_segment_struct { UTIL_TYPE_ID_DECLARATION; int link_count; - int segment_id; - int branch_id; + int segment_id; + int branch_id; int outlet_segment_id; // This is in the global index space given by the ISEG keyword. well_segment_type * outlet_segment; hash_type * connections; // hash_type; @@ -55,7 +55,7 @@ static UTIL_SAFE_CAST_FUNCTION( well_segment , WELL_SEGMENT_TYPE_ID ) well_segment_type * well_segment_alloc(int segment_id , int outlet_segment_id , int branch_id , const double * rseg_data) { well_segment_type * segment = (well_segment_type*)util_malloc( sizeof * segment ); UTIL_TYPE_ID_INIT( segment , WELL_SEGMENT_TYPE_ID ); - + segment->link_count = 0; segment->segment_id = segment_id; segment->outlet_segment_id = outlet_segment_id; @@ -74,7 +74,7 @@ well_segment_type * well_segment_alloc(int segment_id , int outlet_segment_id , segment->total_length = rseg_data[ RSEG_TOTAL_LENGTH_INDEX ]; segment->diameter = rseg_data[ RSEG_DIAMETER_INDEX ]; } - + return segment; } @@ -103,7 +103,7 @@ well_segment_type * well_segment_alloc_from_kw( const ecl_kw_type * iseg_kw , co /* if (iseg_kw != NULL) { if (conn->segment != WELL_CONN_NORMAL_WELL_SEGMENT_ID) { - + } else { conn->branch = 0; conn->outlet_segment = 0; @@ -148,7 +148,7 @@ bool well_segment_nearest_wellhead( const well_segment_type * segment ) { else return false; } - + int well_segment_get_link_count( const well_segment_type * segment ) { return segment->link_count; @@ -170,7 +170,7 @@ int well_segment_get_id( const well_segment_type * segment ) { well_segment_type * well_segment_get_outlet( const well_segment_type * segment ) { return segment->outlet_segment; } - + bool well_segment_link( well_segment_type * segment , well_segment_type * outlet_segment ) { if (segment->outlet_segment_id == outlet_segment->segment_id) { @@ -179,8 +179,8 @@ bool well_segment_link( well_segment_type * segment , well_segment_type * outlet outlet_segment->link_count++; } return true; - } else - /* + } else + /* This is a quite fatal topological error - and aborting is probaly the wisest thing to do. I.e. the function well_segment_link_strict() is recommended. */ @@ -210,14 +210,14 @@ bool well_segment_add_connection( well_segment_type * segment , const char * gri if (conn_segment_id == segment->segment_id) { if (!well_segment_has_grid_connections( segment , grid_name )) hash_insert_hash_owned_ref( segment->connections , grid_name , well_conn_collection_alloc() , well_conn_collection_free__ ); - + { well_conn_collection_type * connections = (well_conn_collection_type*)hash_get( segment->connections , grid_name ); well_conn_collection_add_ref( connections , conn ); } return true; } else - return false; + return false; } @@ -236,9 +236,9 @@ const well_conn_collection_type * well_segment_get_global_connections(const well bool well_segment_well_is_MSW(int well_nr , const ecl_kw_type * iwel_kw , const ecl_rsthead_type * rst_head) { int iwel_offset = rst_head->niwelz * well_nr; - int segment_well_nr = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_SEGMENTED_WELL_NR_INDEX) - 1; - - if (segment_well_nr == IWEL_SEGMENTED_WELL_NR_NORMAL_VALUE) + int segment_well_nr = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_SEGMENTED_WELL_NR_INDEX) - 1; + + if (segment_well_nr == IWEL_SEGMENTED_WELL_NR_NORMAL_VALUE) return false; else return true; diff --git a/ThirdParty/Ert/lib/ecl/well_segment_collection.cpp b/ThirdParty/Ert/lib/ecl/well_segment_collection.cpp index dadfe69449..841ee7d394 100644 --- a/ThirdParty/Ert/lib/ecl/well_segment_collection.cpp +++ b/ThirdParty/Ert/lib/ecl/well_segment_collection.cpp @@ -1,24 +1,24 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_segment_collection.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_segment_collection.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include -#include +#include #include #include @@ -100,17 +100,17 @@ bool well_segment_collection_has_segment( const well_segment_collection_type * -int well_segment_collection_load_from_kw( well_segment_collection_type * segment_collection , int well_nr , - const ecl_kw_type * iwel_kw , - const ecl_kw_type * iseg_kw , +int well_segment_collection_load_from_kw( well_segment_collection_type * segment_collection , int well_nr , + const ecl_kw_type * iwel_kw , + const ecl_kw_type * iseg_kw , const well_rseg_loader_type * rseg_loader , - const ecl_rsthead_type * rst_head , + const ecl_rsthead_type * rst_head , bool load_segments , bool * is_MSW_well) { - + int iwel_offset = rst_head->niwelz * well_nr; - int segment_well_nr = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_SEGMENTED_WELL_NR_INDEX) - 1; + int segment_well_nr = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_SEGMENTED_WELL_NR_INDEX) - 1; int segments_added = 0; - + if (segment_well_nr != IWEL_SEGMENTED_WELL_NR_NORMAL_VALUE) { int segment_index; *is_MSW_well = true; @@ -119,7 +119,7 @@ int well_segment_collection_load_from_kw( well_segment_collection_type * segment for (segment_index = 0; segment_index < rst_head->nsegmx; segment_index++) { int segment_id = segment_index + WELL_SEGMENT_OFFSET; well_segment_type * segment = well_segment_alloc_from_kw( iseg_kw , rseg_loader , rst_head , segment_well_nr , segment_index , segment_id ); - + if (well_segment_active( segment )) { well_segment_collection_add( segment_collection , segment ); segments_added++; @@ -146,8 +146,8 @@ void well_segment_collection_link(const well_segment_collection_type * segment_ -void well_segment_collection_add_connections(well_segment_collection_type * segment_collection , - const char * grid_name , +void well_segment_collection_add_connections(well_segment_collection_type * segment_collection , + const char * grid_name , const well_conn_collection_type * connections) { int iconn; for (iconn = 0; iconn < well_conn_collection_get_size( connections ); iconn++) { @@ -162,7 +162,7 @@ void well_segment_collection_add_connections(well_segment_collection_type * segm -void well_segment_collection_add_branches( const well_segment_collection_type * segment_collection , +void well_segment_collection_add_branches( const well_segment_collection_type * segment_collection , well_branch_collection_type * branches ) { int iseg; for (iseg =0; iseg < well_segment_collection_get_size( segment_collection ); iseg++) { diff --git a/ThirdParty/Ert/lib/ecl/well_state.cpp b/ThirdParty/Ert/lib/ecl/well_state.cpp index 7ee3129efe..d0dc6c0273 100644 --- a/ThirdParty/Ert/lib/ecl/well_state.cpp +++ b/ThirdParty/Ert/lib/ecl/well_state.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include diff --git a/ThirdParty/Ert/lib/ecl/well_ts.cpp b/ThirdParty/Ert/lib/ecl/well_ts.cpp index 2a51809e72..6aa42d4c16 100644 --- a/ThirdParty/Ert/lib/ecl/well_ts.cpp +++ b/ThirdParty/Ert/lib/ecl/well_ts.cpp @@ -62,7 +62,7 @@ #include #include -#include +#include #include #include diff --git a/ThirdParty/Ert/lib/geometry/geo_pointset.cpp b/ThirdParty/Ert/lib/geometry/geo_pointset.cpp index 970b2fd2cb..0aa2777753 100644 --- a/ThirdParty/Ert/lib/geometry/geo_pointset.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_pointset.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include @@ -98,7 +98,7 @@ void geo_pointset_add_xyz( geo_pointset_type * pointset , double x , double y, d void geo_pointset_free( geo_pointset_type * pointset ) { free( pointset->xcoord ); free( pointset->ycoord ); - util_safe_free( pointset->zcoord ); + free( pointset->zcoord ); free( pointset ); } diff --git a/ThirdParty/Ert/lib/geometry/geo_polygon.cpp b/ThirdParty/Ert/lib/geometry/geo_polygon.cpp index 516d90de04..e375bb07e5 100644 --- a/ThirdParty/Ert/lib/geometry/geo_polygon.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_polygon.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include @@ -57,7 +57,7 @@ geo_polygon_type * geo_polygon_alloc(const char * name) { void geo_polygon_free( geo_polygon_type * polygon ) { double_vector_free( polygon->xcoord ); double_vector_free( polygon->ycoord ); - util_safe_free( polygon->name ); + free( polygon->name ); free( polygon ); } diff --git a/ThirdParty/Ert/lib/geometry/geo_polygon_collection.cpp b/ThirdParty/Ert/lib/geometry/geo_polygon_collection.cpp index f02ddb1374..043bffcb83 100644 --- a/ThirdParty/Ert/lib/geometry/geo_polygon_collection.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_polygon_collection.cpp @@ -1,32 +1,32 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'geo_polygon_collection.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'geo_polygon_collection.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include #include #include -#include -#include +#include +#include @@ -68,7 +68,7 @@ geo_polygon_type * geo_polygon_collection_create_polygon( geo_polygon_collection } return polygon; -} +} bool geo_polygon_collection_add_polygon( geo_polygon_collection_type * polygons , geo_polygon_type * polygon , bool polygon_owner ) { @@ -80,10 +80,10 @@ bool geo_polygon_collection_add_polygon( geo_polygon_collection_type * polygons vector_append_owned_ref( polygons->polygon_list , polygon , geo_polygon_free__); else vector_append_ref( polygons->polygon_list , polygon ); - + if (name) hash_insert_ref( polygons->polygon_map , name , polygon ); - + return true; } } diff --git a/ThirdParty/Ert/lib/geometry/geo_region.cpp b/ThirdParty/Ert/lib/geometry/geo_region.cpp index 76a1a1f11a..5ce2a6f382 100644 --- a/ThirdParty/Ert/lib/geometry/geo_region.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_region.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'geo_region.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'geo_region.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include #include #include @@ -36,10 +36,10 @@ struct geo_region_struct { UTIL_TYPE_ID_DECLARATION; bool preselect; bool index_valid; - bool * active_mask; + bool * active_mask; int_vector_type * index_list; const geo_pointset_type * pointset; - int pointset_size; + int pointset_size; }; @@ -100,19 +100,19 @@ void geo_region_free__( void * arg ) { /*****************************************************************/ -static void geo_region_polygon_select__( geo_region_type * region , - const geo_polygon_type * polygon , +static void geo_region_polygon_select__( geo_region_type * region , + const geo_polygon_type * polygon , bool select_inside , bool select) { - + int index; for (index = 0; index < region->pointset_size; index++) { double x , y; bool is_inside; geo_pointset_iget_xy( region->pointset , index , &x , &y); - + is_inside = geo_polygon_contains_point( polygon , x , y ); - if (is_inside == select_inside) + if (is_inside == select_inside) region->active_mask[index] = select; } @@ -139,7 +139,7 @@ void geo_region_deselect_outside_polygon( geo_region_type * region , const geo_p /*****************************************************************/ static void geo_region_select_line__( geo_region_type * region, const double xcoords[2] , const double ycoords[2], bool select_above , bool select){ - double vx = xcoords[1] - xcoords[0]; // Vector from point 1 to point 2 + double vx = xcoords[1] - xcoords[0]; // Vector from point 1 to point 2 double vy = ycoords[1] - ycoords[0]; int index; @@ -161,8 +161,8 @@ static void geo_region_select_line__( geo_region_type * region, const double xco else above = false; } - - if (above == select_above) + + if (above == select_above) region->active_mask[index] = select; } geo_region_invalidate_index_list( region ); diff --git a/ThirdParty/Ert/lib/geometry/geo_surface.cpp b/ThirdParty/Ert/lib/geometry/geo_surface.cpp index c3b25e25e4..773da26113 100644 --- a/ThirdParty/Ert/lib/geometry/geo_surface.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_surface.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include @@ -248,7 +248,7 @@ static bool geo_surface_fload_irap( geo_surface_type * surface , const char * fi if (read_ok) geo_surface_init_regular( surface , zcoord ); - util_safe_free( zcoord ); + free( zcoord ); } fclose( stream ); } diff --git a/ThirdParty/Ert/lib/geometry/geo_util.cpp b/ThirdParty/Ert/lib/geometry/geo_util.cpp index 2dda526704..e8d0b1cbb1 100644 --- a/ThirdParty/Ert/lib/geometry/geo_util.cpp +++ b/ThirdParty/Ert/lib/geometry/geo_util.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include diff --git a/ThirdParty/Ert/lib/geometry/tests/geo_polygon.c b/ThirdParty/Ert/lib/geometry/tests/geo_polygon.cpp similarity index 80% rename from ThirdParty/Ert/lib/geometry/tests/geo_polygon.c rename to ThirdParty/Ert/lib/geometry/tests/geo_polygon.cpp index d6c9110f56..f3f46e6f60 100644 --- a/ThirdParty/Ert/lib/geometry/tests/geo_polygon.c +++ b/ThirdParty/Ert/lib/geometry/tests/geo_polygon.cpp @@ -1,30 +1,30 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'geo_surface.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'geo_surface.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include #include -#include +#include #include -#include +#include -#include +#include @@ -38,9 +38,9 @@ void test_create() { void test_contains__( double x , double y , int length , const double * data, bool expected) { - geo_polygon_type * polygon = geo_polygon_alloc( NULL ); + geo_polygon_type * polygon = (geo_polygon_type *) geo_polygon_alloc( NULL ); int i; - for (i=0; i < length; i++) + for (i=0; i < length; i++) geo_polygon_add_point( polygon , data[2*i] , data[2*i + 1]); test_assert_bool_equal( expected , geo_polygon_contains_point( polygon ,x , y)); @@ -71,14 +71,14 @@ void test_contains_polygon3( int length , const double * data) { void test_contains() { - test_contains_polygon1( 4 , (const double[8]) {0,0,1,0,1,1,0,1}); - test_contains_polygon2( 5 , (const double[10]) {0,0,1,0,1,1,0,1,0,0}); - test_contains_polygon3( 6 , (const double[12]) {0,0 , 0,1 , 0.6,0.5 , 0.4,0.5 , 1,1 , 1,0}); + test_contains_polygon1( 4 , (const double[8]) {0,0,1,0,1,1,0,1}); + test_contains_polygon2( 5 , (const double[10]) {0,0,1,0,1,1,0,1,0,0}); + test_contains_polygon3( 6 , (const double[12]) {0,0 , 0,1 , 0.6,0.5 , 0.4,0.5 , 1,1 , 1,0}); } void test_prepend() { - geo_polygon_type * polygon = geo_polygon_alloc( NULL ); + geo_polygon_type * polygon = (geo_polygon_type *) geo_polygon_alloc( NULL ); geo_polygon_add_point(polygon , 1 , 1); geo_polygon_add_point_front( polygon , 0,0); test_assert_int_equal( 2 , geo_polygon_get_size( polygon )); @@ -88,7 +88,7 @@ void test_prepend() { geo_polygon_iget_xy(polygon , 0 , &x , &y); test_assert_double_equal( x , 0 ); test_assert_double_equal( x , 0 ); - + geo_polygon_iget_xy(polygon , 1 , &x , &y); test_assert_double_equal( x , 1 ); test_assert_double_equal( x , 1 ); diff --git a/ThirdParty/Ert/lib/geometry/tests/geo_polygon_collection.c b/ThirdParty/Ert/lib/geometry/tests/geo_polygon_collection.cpp similarity index 66% rename from ThirdParty/Ert/lib/geometry/tests/geo_polygon_collection.c rename to ThirdParty/Ert/lib/geometry/tests/geo_polygon_collection.cpp index 1c803aeb66..7023a82446 100644 --- a/ThirdParty/Ert/lib/geometry/tests/geo_polygon_collection.c +++ b/ThirdParty/Ert/lib/geometry/tests/geo_polygon_collection.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'geo_polygon_collection.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'geo_polygon_collection.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include @@ -21,11 +21,11 @@ #include #include -#include +#include #include -#include -#include +#include +#include diff --git a/ThirdParty/Ert/lib/geometry/tests/geo_surface.c b/ThirdParty/Ert/lib/geometry/tests/geo_surface.cpp similarity index 92% rename from ThirdParty/Ert/lib/geometry/tests/geo_surface.c rename to ThirdParty/Ert/lib/geometry/tests/geo_surface.cpp index 2d8e53e9de..c9fd440b54 100644 --- a/ThirdParty/Ert/lib/geometry/tests/geo_surface.c +++ b/ThirdParty/Ert/lib/geometry/tests/geo_surface.cpp @@ -20,16 +20,16 @@ #include #include -#include +#include #include -#include +#include -#include +#include void test_load(const char * input_file , const char * broken_file) { geo_surface_type * surface = geo_surface_fload_alloc_irap( input_file , false ); - double * data = util_calloc( geo_surface_get_size( surface ) , sizeof * data ); + double * data = (double *) util_calloc( geo_surface_get_size( surface ) , sizeof * data ); test_assert_true( geo_surface_fload_irap_zcoord( surface , input_file , data )); test_assert_false( geo_surface_fload_irap_zcoord( surface , "/does/not/exist" , data )); diff --git a/ThirdParty/Ert/lib/geometry/tests/geo_util_xlines.c b/ThirdParty/Ert/lib/geometry/tests/geo_util_xlines.cpp similarity index 96% rename from ThirdParty/Ert/lib/geometry/tests/geo_util_xlines.c rename to ThirdParty/Ert/lib/geometry/tests/geo_util_xlines.cpp index 388ec16740..6c926632c0 100644 --- a/ThirdParty/Ert/lib/geometry/tests/geo_util_xlines.c +++ b/ThirdParty/Ert/lib/geometry/tests/geo_util_xlines.cpp @@ -20,10 +20,10 @@ #include #include -#include +#include #include -#include +#include @@ -233,10 +233,10 @@ void test_degenerate_line(double ** points) { int main( int argc , char ** argv) { - double ** points = util_malloc( 4 * sizeof * points); + double ** points = (double **) util_malloc( 4 * sizeof * points); int i; for (i = 0; i < 4; i++) - points[i] = util_malloc( 2 * sizeof * points[i]); + points[i] = (double *) util_malloc( 2 * sizeof * points[i]); { test_parallell_lines(points); test_crossing_lines(points); diff --git a/ThirdParty/Ert/lib/include/ert/ecl/EclFilename.hpp b/ThirdParty/Ert/lib/include/ert/ecl/EclFilename.hpp index dafe8176b9..858fccfb59 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/EclFilename.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/EclFilename.hpp @@ -20,7 +20,7 @@ #define ERT_ECL_FILEMAME_HPP #include -#include +#include namespace ERT { std::string EclFilename( const std::string& base, ecl_file_enum file_type , int report_step, bool fmt_file = false); diff --git a/ThirdParty/Ert/lib/include/ert/ecl/EclKW.hpp b/ThirdParty/Ert/lib/include/ert/ecl/EclKW.hpp index 68f834428d..9a07836bf8 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/EclKW.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/EclKW.hpp @@ -27,8 +27,8 @@ #include #include -#include -#include +#include +#include #include namespace ERT { diff --git a/ThirdParty/Ert/lib/include/ert/ecl/FortIO.hpp b/ThirdParty/Ert/lib/include/ert/ecl/FortIO.hpp index f79e2aaf22..2f7d69fa09 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/FortIO.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/FortIO.hpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include diff --git a/ThirdParty/Ert/lib/include/ert/ecl/Smspec.hpp b/ThirdParty/Ert/lib/include/ert/ecl/Smspec.hpp index c86ff6f9d6..b16c4ced38 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/Smspec.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/Smspec.hpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include namespace ERT { diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.h deleted file mode 100644 index 3c84b55279..0000000000 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_box.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ERT_ECL_BOX_H -#define ERT_ECL_BOX_H -#ifdef __cplusplus -extern "C" { -#endif - -#include - - -typedef struct ecl_box_struct ecl_box_type; - - -void ecl_box_set_size (ecl_box_type * , int , int , int , int , int , int ); -ecl_box_type * ecl_box_alloc(const ecl_grid_type * ecl_grid , int i1,int i2 , int j1 , int j2 , int k1, int k2); -void ecl_box_free (ecl_box_type * ); -void ecl_box_set_values(const ecl_box_type * , char * , const char * , int ); -int ecl_box_get_total_size(const ecl_box_type * ); -int ecl_box_get_active_size( const ecl_box_type * ecl_box ); -const int * ecl_box_get_active_list( const ecl_box_type * ecl_box ); -int ecl_box_get_global_size( const ecl_box_type * ecl_box ); -const int * ecl_box_get_global_list( const ecl_box_type * ecl_box ); -bool ecl_box_contains(const ecl_box_type * box , int i , int j , int k); - -UTIL_IS_INSTANCE_HEADER( ecl_box ); -UTIL_SAFE_CAST_HEADER( ecl_box ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.hpp index 4b1a822b03..e88098554a 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_box.hpp @@ -1,19 +1,41 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_box.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_BOX_H +#define ERT_ECL_BOX_H + +#include +#include + + +namespace ecl { + + class ecl_box { + public: + ecl_box(const ecl_grid_type * grid, int i1, int i2, int j1, int j2, int k1, int k2); + const std::vector& active_list() const; + private: + const ecl_grid_type * grid; + + int i1,i2,j1,j2,k1,k2; + std::vector active_index_list; + std::vector global_index_list; + }; + +} +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.h index 6b04ac1523..520777aa9e 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.h @@ -1,72 +1,9 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_COARSE_CELL_H -#define ERT_ECL_COARSE_CELL_H - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ecl_coarse_cell_struct ecl_coarse_cell_type; - -bool ecl_coarse_cell_equal(const ecl_coarse_cell_type * coarse_cell1, - const ecl_coarse_cell_type * coarse_cell2); -ecl_coarse_cell_type * ecl_coarse_cell_alloc(void); -void ecl_coarse_cell_update(ecl_coarse_cell_type * coarse_cell, - int i, - int j, - int k, - int global_index); -void ecl_coarse_cell_free(ecl_coarse_cell_type * coarse_cell); -void ecl_coarse_cell_free__(void * arg); - -int ecl_coarse_cell_get_i1(const ecl_coarse_cell_type * coarse_cell); -int ecl_coarse_cell_get_j1(const ecl_coarse_cell_type * coarse_cell); -int ecl_coarse_cell_get_k1(const ecl_coarse_cell_type * coarse_cell); -int ecl_coarse_cell_get_i2(const ecl_coarse_cell_type * coarse_cell); -int ecl_coarse_cell_get_j2(const ecl_coarse_cell_type * coarse_cell); -int ecl_coarse_cell_get_k2(const ecl_coarse_cell_type * coarse_cell); -const int * ecl_coarse_cell_get_box_ptr(const ecl_coarse_cell_type * coarse_cell); - -int ecl_coarse_cell_get_size(const ecl_coarse_cell_type * coarse_cell); -int ecl_coarse_cell_iget_cell_index(ecl_coarse_cell_type * coarse_cell, - int group_index); -const int * ecl_coarse_cell_get_index_ptr(ecl_coarse_cell_type * coarse_cell); -const int_vector_type * ecl_coarse_cell_get_index_vector(ecl_coarse_cell_type * coarse_cell); +#include -void ecl_coarse_cell_update_index(ecl_coarse_cell_type * coarse_cell, - int global_index, - int * active_index, - int * active_fracture_index, - int active_value); -int ecl_coarse_cell_get_active_index(const ecl_coarse_cell_type * coarse_cell); -int ecl_coarse_cell_get_active_fracture_index(const ecl_coarse_cell_type * coarse_cell); -int ecl_coarse_cell_iget_active_cell_index(const ecl_coarse_cell_type * coarse_cell, - int index); -int ecl_coarse_cell_iget_active_value(const ecl_coarse_cell_type * coarse_cell, - int index); -int ecl_coarse_cell_get_num_active(const ecl_coarse_cell_type * coarse_cell); -void ecl_coarse_cell_fprintf(const ecl_coarse_cell_type * coarse_cell, - FILE * stream); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.hpp index 289c1dd7c4..6b04ac1523 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_coarse_cell.hpp @@ -1,19 +1,72 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + This file is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_COARSE_CELL_H +#define ERT_ECL_COARSE_CELL_H + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ecl_coarse_cell_struct ecl_coarse_cell_type; + +bool ecl_coarse_cell_equal(const ecl_coarse_cell_type * coarse_cell1, + const ecl_coarse_cell_type * coarse_cell2); +ecl_coarse_cell_type * ecl_coarse_cell_alloc(void); +void ecl_coarse_cell_update(ecl_coarse_cell_type * coarse_cell, + int i, + int j, + int k, + int global_index); +void ecl_coarse_cell_free(ecl_coarse_cell_type * coarse_cell); +void ecl_coarse_cell_free__(void * arg); + +int ecl_coarse_cell_get_i1(const ecl_coarse_cell_type * coarse_cell); +int ecl_coarse_cell_get_j1(const ecl_coarse_cell_type * coarse_cell); +int ecl_coarse_cell_get_k1(const ecl_coarse_cell_type * coarse_cell); +int ecl_coarse_cell_get_i2(const ecl_coarse_cell_type * coarse_cell); +int ecl_coarse_cell_get_j2(const ecl_coarse_cell_type * coarse_cell); +int ecl_coarse_cell_get_k2(const ecl_coarse_cell_type * coarse_cell); +const int * ecl_coarse_cell_get_box_ptr(const ecl_coarse_cell_type * coarse_cell); + +int ecl_coarse_cell_get_size(const ecl_coarse_cell_type * coarse_cell); +int ecl_coarse_cell_iget_cell_index(ecl_coarse_cell_type * coarse_cell, + int group_index); +const int * ecl_coarse_cell_get_index_ptr(ecl_coarse_cell_type * coarse_cell); +const int_vector_type * ecl_coarse_cell_get_index_vector(ecl_coarse_cell_type * coarse_cell); + +void ecl_coarse_cell_update_index(ecl_coarse_cell_type * coarse_cell, + int global_index, + int * active_index, + int * active_fracture_index, + int active_value); +int ecl_coarse_cell_get_active_index(const ecl_coarse_cell_type * coarse_cell); +int ecl_coarse_cell_get_active_fracture_index(const ecl_coarse_cell_type * coarse_cell); +int ecl_coarse_cell_iget_active_cell_index(const ecl_coarse_cell_type * coarse_cell, + int index); +int ecl_coarse_cell_iget_active_value(const ecl_coarse_cell_type * coarse_cell, + int index); +int ecl_coarse_cell_get_num_active(const ecl_coarse_cell_type * coarse_cell); +void ecl_coarse_cell_fprintf(const ecl_coarse_cell_type * coarse_cell, + FILE * stream); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.h index 54f0abbb2e..724a2f6880 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.h @@ -1,60 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_endian_flip.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_ENDIAN_FLIP_H -#define ERT_ECL_ENDIAN_FLIP_H -#ifdef __cplusplus -extern "C" { -#endif +#include -#include -/** - This header file checks if the ECLIPSE endianness and the hardware - endianness are equal, and defines the macro ECL_ENDIAN_FLIP - accordingly. - - All the ecl_xxx functions will use the ECL_ENDIAN_FLIP macro to - determine whether the endian flip should be performed. When opening - a fortio instance explicitly you can use the ECL_ENDIAN_FLIP macro - to get the endianness correct (for ECLIPSE usage that is). -*/ - -#define ECLIPSE_BYTE_ORDER __BIG_ENDIAN // Alternatively: __LITTLE_ENDIAN - -#ifdef BYTE_ORDER - #if BYTE_ORDER == ECLIPSE_BYTE_ORDER - #define ECL_ENDIAN_FLIP false - #else - #define ECL_ENDIAN_FLIP true - #endif -#else - #ifdef WIN32 - #define ECL_ENDIAN_FLIP true // Unconditional byte flip on Windows. - #else - #error: The macro BYTE_ORDER is not defined? - #endif -#endif - -#undef ECLIPSE_BYTE_ORDER - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.hpp index a0b3ac55e9..9876aaf0ef 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_endian_flip.hpp @@ -1,19 +1,60 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_endian_flip.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_ENDIAN_FLIP_H +#define ERT_ECL_ENDIAN_FLIP_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + This header file checks if the ECLIPSE endianness and the hardware + endianness are equal, and defines the macro ECL_ENDIAN_FLIP + accordingly. + + All the ecl_xxx functions will use the ECL_ENDIAN_FLIP macro to + determine whether the endian flip should be performed. When opening + a fortio instance explicitly you can use the ECL_ENDIAN_FLIP macro + to get the endianness correct (for ECLIPSE usage that is). +*/ + +#define ECLIPSE_BYTE_ORDER __BIG_ENDIAN // Alternatively: __LITTLE_ENDIAN + +#ifdef BYTE_ORDER + #if BYTE_ORDER == ECLIPSE_BYTE_ORDER + #define ECL_ENDIAN_FLIP false + #else + #define ECL_ENDIAN_FLIP true + #endif +#else + #ifdef WIN32 + #define ECL_ENDIAN_FLIP true // Unconditional byte flip on Windows. + #else + #error: The macro BYTE_ORDER is not defined? + #endif +#endif + +#undef ECLIPSE_BYTE_ORDER + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.h index d51ba41d0a..34ca6dab16 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.h @@ -1,137 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_file.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_FILE_H -#define ERT_ECL_FILE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - - -#include -#include -#include -#include -#include -#include - - - -#define ECL_FILE_FLAGS_ENUM_DEFS \ - {.value = 1 , .name="ECL_FILE_CLOSE_STREAM"}, \ - {.value = 2 , .name="ECL_FILE_WRITABLE"} -#define ECL_FILE_FLAGS_ENUM_SIZE 2 - - - - - typedef struct ecl_file_struct ecl_file_type; - bool ecl_file_load_all( ecl_file_type * ecl_file ); - ecl_file_type * ecl_file_open( const char * filename , int flags); - ecl_file_type * ecl_file_fast_open( const char * filename , const char * index_filename , int flags); - bool ecl_file_write_index( const ecl_file_type * ecl_file , const char * index_filename); - bool ecl_file_index_valid(const char * file_name, const char * index_file_name); - void ecl_file_close( ecl_file_type * ecl_file ); - void ecl_file_fortio_detach( ecl_file_type * ecl_file ); - void ecl_file_free__(void * arg); - ecl_kw_type * ecl_file_icopy_named_kw( const ecl_file_type * ecl_file , const char * kw, int ith); - ecl_kw_type * ecl_file_icopy_kw( const ecl_file_type * ecl_file , int index); - bool ecl_file_has_kw( const ecl_file_type * ecl_file , const char * kw); - int ecl_file_get_num_named_kw(const ecl_file_type * ecl_file , const char * kw); - int ecl_file_get_size( const ecl_file_type * ecl_file ); - int ecl_file_get_num_distinct_kw(const ecl_file_type * ecl_file); - const char * ecl_file_iget_distinct_kw(const ecl_file_type * ecl_file , int index); - const char * ecl_file_get_src_file( const ecl_file_type * ecl_file ); - int ecl_file_iget_occurence( const ecl_file_type * ecl_file , int index); - ecl_version_enum ecl_file_get_ecl_version( const ecl_file_type * file ); - void ecl_file_fwrite_fortio(const ecl_file_type * ec_file , fortio_type * fortio , int offset); - void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * , bool fmt_file ); - - void ecl_file_replace_kw( ecl_file_type * ecl_file , ecl_kw_type * old_kw , ecl_kw_type * new_kw , bool insert_copy); - int ecl_file_get_phases( const ecl_file_type * init_file ); - void ecl_file_fprintf_kw_list( const ecl_file_type * ecl_file , FILE * stream ); - - bool ecl_file_writable( const ecl_file_type * ecl_file ); - int ecl_file_get_flags( const ecl_file_type * ecl_file ); - void ecl_file_set_flags( ecl_file_type * ecl_file, int new_flags ); - bool ecl_file_flags_set( const ecl_file_type * ecl_file , int flags); - - - - ecl_file_kw_type * ecl_file_iget_file_kw( const ecl_file_type * file , int global_index); - ecl_file_kw_type * ecl_file_iget_named_file_kw( const ecl_file_type * file , const char * kw, int ith); - ecl_kw_type * ecl_file_iget_kw( const ecl_file_type * file , int global_index); - ecl_data_type ecl_file_iget_data_type( const ecl_file_type * file , int global_index); - int ecl_file_iget_size( const ecl_file_type * file , int global_index); - const char * ecl_file_iget_header( const ecl_file_type * file , int global_index); - ecl_kw_type * ecl_file_iget_named_kw( const ecl_file_type * file , const char * kw, int ith); - ecl_data_type ecl_file_iget_named_data_type( const ecl_file_type * file , const char * kw , int ith); - int ecl_file_iget_named_size( const ecl_file_type * file , const char * kw , int ith); - void ecl_file_indexed_read(const ecl_file_type * file , const char * kw, int index, const int_vector_type * index_map, char* buffer); - - ecl_file_view_type * ecl_file_get_global_blockview( ecl_file_type * ecl_file , const char * kw , int occurence); - ecl_file_view_type * ecl_file_alloc_global_blockview( ecl_file_type * ecl_file , const char * kw , int occurence); - ecl_file_view_type * ecl_file_get_global_view( ecl_file_type * ecl_file ); - ecl_file_view_type * ecl_file_get_active_view( ecl_file_type * ecl_file ); - //bool ecl_file_writable( const ecl_file_type * ecl_file ); - bool ecl_file_save_kw( const ecl_file_type * ecl_file , const ecl_kw_type * ecl_kw); - bool ecl_file_has_kw_ptr( const ecl_file_type * ecl_file , const ecl_kw_type * ecl_kw); - -/*****************************************************************/ -/* R E S T A R T F I L E S */ - - double ecl_file_iget_restart_sim_days( const ecl_file_type * restart_file , int index ); - time_t ecl_file_iget_restart_sim_date( const ecl_file_type * restart_file , int occurence ); - int ecl_file_get_restart_index( const ecl_file_type * restart_file , time_t sim_time); - bool ecl_file_has_report_step( const ecl_file_type * ecl_file , int report_step); - bool ecl_file_has_sim_time( const ecl_file_type * ecl_file , time_t sim_time); - - - void ecl_file_close_fortio_stream(ecl_file_type * ecl_file); - - ecl_file_view_type * ecl_file_get_restart_view( ecl_file_type * ecl_file , int input_index, int report_step , time_t sim_time, double sim_days); - ecl_file_view_type * ecl_file_get_summary_view( ecl_file_type * ecl_file , int report_step ); - -/*****************************************************************/ -/* SUMMARY FILES */ - - UTIL_IS_INSTANCE_HEADER( ecl_file ); - - //Deprecated: - - void ecl_file_push_block( ecl_file_type * ecl_file ); - void ecl_file_pop_block( ecl_file_type * ecl_file ); - bool ecl_file_subselect_block( ecl_file_type * ecl_file , const char * kw , int occurence); - bool ecl_file_select_block( ecl_file_type * ecl_file , const char * kw , int occurence); - - bool ecl_file_select_rstblock_sim_time( ecl_file_type * ecl_file , time_t sim_time); - bool ecl_file_select_rstblock_report_step( ecl_file_type * ecl_file , int report_step); - bool ecl_file_iselect_rstblock( ecl_file_type * ecl_file , int seqnum_index ); - ecl_file_type * ecl_file_open_rstblock_report_step( const char * filename , int report_step , int flags); - ecl_file_type * ecl_file_open_rstblock_sim_time( const char * filename , time_t sim_time , int flags); - ecl_file_type * ecl_file_iopen_rstblock( const char * filename , int seqnum_index , int flags); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.hpp index 6fade2adb9..8ddae75c74 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file.hpp @@ -1,19 +1,137 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_file.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_FILE_H +#define ERT_ECL_FILE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +#include +#include +#include +#include +#include +#include + + + +#define ECL_FILE_FLAGS_ENUM_DEFS \ + {.value = 1 , .name="ECL_FILE_CLOSE_STREAM"}, \ + {.value = 2 , .name="ECL_FILE_WRITABLE"} +#define ECL_FILE_FLAGS_ENUM_SIZE 2 + + + + + typedef struct ecl_file_struct ecl_file_type; + bool ecl_file_load_all( ecl_file_type * ecl_file ); + ecl_file_type * ecl_file_open( const char * filename , int flags); + ecl_file_type * ecl_file_fast_open( const char * filename , const char * index_filename , int flags); + bool ecl_file_write_index( const ecl_file_type * ecl_file , const char * index_filename); + bool ecl_file_index_valid(const char * file_name, const char * index_file_name); + void ecl_file_close( ecl_file_type * ecl_file ); + void ecl_file_fortio_detach( ecl_file_type * ecl_file ); + void ecl_file_free__(void * arg); + ecl_kw_type * ecl_file_icopy_named_kw( const ecl_file_type * ecl_file , const char * kw, int ith); + ecl_kw_type * ecl_file_icopy_kw( const ecl_file_type * ecl_file , int index); + bool ecl_file_has_kw( const ecl_file_type * ecl_file , const char * kw); + int ecl_file_get_num_named_kw(const ecl_file_type * ecl_file , const char * kw); + int ecl_file_get_size( const ecl_file_type * ecl_file ); + int ecl_file_get_num_distinct_kw(const ecl_file_type * ecl_file); + const char * ecl_file_iget_distinct_kw(const ecl_file_type * ecl_file , int index); + const char * ecl_file_get_src_file( const ecl_file_type * ecl_file ); + int ecl_file_iget_occurence( const ecl_file_type * ecl_file , int index); + ecl_version_enum ecl_file_get_ecl_version( const ecl_file_type * file ); + void ecl_file_fwrite_fortio(const ecl_file_type * ec_file , fortio_type * fortio , int offset); + void ecl_file_fwrite(const ecl_file_type * ecl_file , const char * , bool fmt_file ); + + void ecl_file_replace_kw( ecl_file_type * ecl_file , ecl_kw_type * old_kw , ecl_kw_type * new_kw , bool insert_copy); + int ecl_file_get_phases( const ecl_file_type * init_file ); + void ecl_file_fprintf_kw_list( const ecl_file_type * ecl_file , FILE * stream ); + + bool ecl_file_writable( const ecl_file_type * ecl_file ); + int ecl_file_get_flags( const ecl_file_type * ecl_file ); + void ecl_file_set_flags( ecl_file_type * ecl_file, int new_flags ); + bool ecl_file_flags_set( const ecl_file_type * ecl_file , int flags); + + + + ecl_file_kw_type * ecl_file_iget_file_kw( const ecl_file_type * file , int global_index); + ecl_file_kw_type * ecl_file_iget_named_file_kw( const ecl_file_type * file , const char * kw, int ith); + ecl_kw_type * ecl_file_iget_kw( const ecl_file_type * file , int global_index); + ecl_data_type ecl_file_iget_data_type( const ecl_file_type * file , int global_index); + int ecl_file_iget_size( const ecl_file_type * file , int global_index); + const char * ecl_file_iget_header( const ecl_file_type * file , int global_index); + ecl_kw_type * ecl_file_iget_named_kw( const ecl_file_type * file , const char * kw, int ith); + ecl_data_type ecl_file_iget_named_data_type( const ecl_file_type * file , const char * kw , int ith); + int ecl_file_iget_named_size( const ecl_file_type * file , const char * kw , int ith); + void ecl_file_indexed_read(const ecl_file_type * file , const char * kw, int index, const int_vector_type * index_map, char* buffer); + + ecl_file_view_type * ecl_file_get_global_blockview( ecl_file_type * ecl_file , const char * kw , int occurence); + ecl_file_view_type * ecl_file_alloc_global_blockview( ecl_file_type * ecl_file , const char * kw , int occurence); + ecl_file_view_type * ecl_file_get_global_view( ecl_file_type * ecl_file ); + ecl_file_view_type * ecl_file_get_active_view( ecl_file_type * ecl_file ); + //bool ecl_file_writable( const ecl_file_type * ecl_file ); + bool ecl_file_save_kw( const ecl_file_type * ecl_file , const ecl_kw_type * ecl_kw); + bool ecl_file_has_kw_ptr( const ecl_file_type * ecl_file , const ecl_kw_type * ecl_kw); + +/*****************************************************************/ +/* R E S T A R T F I L E S */ + + double ecl_file_iget_restart_sim_days( const ecl_file_type * restart_file , int index ); + time_t ecl_file_iget_restart_sim_date( const ecl_file_type * restart_file , int occurence ); + int ecl_file_get_restart_index( const ecl_file_type * restart_file , time_t sim_time); + bool ecl_file_has_report_step( const ecl_file_type * ecl_file , int report_step); + bool ecl_file_has_sim_time( const ecl_file_type * ecl_file , time_t sim_time); + + + void ecl_file_close_fortio_stream(ecl_file_type * ecl_file); + + ecl_file_view_type * ecl_file_get_restart_view( ecl_file_type * ecl_file , int input_index, int report_step , time_t sim_time, double sim_days); + ecl_file_view_type * ecl_file_get_summary_view( ecl_file_type * ecl_file , int report_step ); + +/*****************************************************************/ +/* SUMMARY FILES */ + + UTIL_IS_INSTANCE_HEADER( ecl_file ); + + //Deprecated: + + void ecl_file_push_block( ecl_file_type * ecl_file ); + void ecl_file_pop_block( ecl_file_type * ecl_file ); + bool ecl_file_subselect_block( ecl_file_type * ecl_file , const char * kw , int occurence); + bool ecl_file_select_block( ecl_file_type * ecl_file , const char * kw , int occurence); + + bool ecl_file_select_rstblock_sim_time( ecl_file_type * ecl_file , time_t sim_time); + bool ecl_file_select_rstblock_report_step( ecl_file_type * ecl_file , int report_step); + bool ecl_file_iselect_rstblock( ecl_file_type * ecl_file , int seqnum_index ); + ecl_file_type * ecl_file_open_rstblock_report_step( const char * filename , int report_step , int flags); + ecl_file_type * ecl_file_open_rstblock_sim_time( const char * filename , time_t sim_time , int flags); + ecl_file_type * ecl_file_iopen_rstblock( const char * filename , int seqnum_index , int flags); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.h index a50cf87aa9..1197dddf82 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.h @@ -1,67 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_file_kw.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_FILE_KW_H -#define ERT_ECL_FILE_KW_H +#include -#ifdef __cplusplus -extern "C" { -#endif -#include - -#include - -#include -#include - -typedef struct ecl_file_kw_struct ecl_file_kw_type; -typedef struct inv_map_struct inv_map_type; - - inv_map_type * inv_map_alloc(void); - ecl_file_kw_type * inv_map_get_file_kw( inv_map_type * inv_map , const ecl_kw_type * ecl_kw ); - void inv_map_free( inv_map_type * map ); - bool ecl_file_kw_equal( const ecl_file_kw_type * kw1 , const ecl_file_kw_type * kw2); - ecl_file_kw_type * ecl_file_kw_alloc( const ecl_kw_type * ecl_kw , offset_type offset); - ecl_file_kw_type * ecl_file_kw_alloc0( const char * header , ecl_data_type data_type , int size , offset_type offset); - void ecl_file_kw_free( ecl_file_kw_type * file_kw ); - void ecl_file_kw_free__( void * arg ); - ecl_kw_type * ecl_file_kw_get_kw( ecl_file_kw_type * file_kw , fortio_type * fortio, inv_map_type * inv_map); - ecl_kw_type * ecl_file_kw_get_kw_ptr( ecl_file_kw_type * file_kw ); - ecl_file_kw_type * ecl_file_kw_alloc_copy( const ecl_file_kw_type * src ); - const char * ecl_file_kw_get_header( const ecl_file_kw_type * file_kw ); - int ecl_file_kw_get_size( const ecl_file_kw_type * file_kw ); - ecl_data_type ecl_file_kw_get_data_type(const ecl_file_kw_type *); - offset_type ecl_file_kw_get_offset(const ecl_file_kw_type * file_kw); - bool ecl_file_kw_ptr_eq( const ecl_file_kw_type * file_kw , const ecl_kw_type * ecl_kw); - void ecl_file_kw_replace_kw( ecl_file_kw_type * file_kw , fortio_type * target , ecl_kw_type * new_kw ); - bool ecl_file_kw_fskip_data( const ecl_file_kw_type * file_kw , fortio_type * fortio); - void ecl_file_kw_inplace_fwrite( ecl_file_kw_type * file_kw , fortio_type * fortio); - - void ecl_file_kw_fwrite( const ecl_file_kw_type * file_kw , FILE * stream ); - ecl_file_kw_type ** ecl_file_kw_fread_alloc_multiple( FILE * stream , int num); - ecl_file_kw_type * ecl_file_kw_fread_alloc( FILE * stream ); - - void ecl_file_kw_start_transaction(const ecl_file_kw_type * file_kw, int * ref_count); - void ecl_file_kw_end_transaction(ecl_file_kw_type * file_kw, int ref_count); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.hpp index 35352ecfd1..f066fd1b5d 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_kw.hpp @@ -1,19 +1,67 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_file_kw.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_FILE_KW_H +#define ERT_ECL_FILE_KW_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +#include +#include + +typedef struct ecl_file_kw_struct ecl_file_kw_type; +typedef struct inv_map_struct inv_map_type; + + inv_map_type * inv_map_alloc(void); + ecl_file_kw_type * inv_map_get_file_kw( inv_map_type * inv_map , const ecl_kw_type * ecl_kw ); + void inv_map_free( inv_map_type * map ); + bool ecl_file_kw_equal( const ecl_file_kw_type * kw1 , const ecl_file_kw_type * kw2); + ecl_file_kw_type * ecl_file_kw_alloc( const ecl_kw_type * ecl_kw , offset_type offset); + ecl_file_kw_type * ecl_file_kw_alloc0( const char * header , ecl_data_type data_type , int size , offset_type offset); + void ecl_file_kw_free( ecl_file_kw_type * file_kw ); + void ecl_file_kw_free__( void * arg ); + ecl_kw_type * ecl_file_kw_get_kw( ecl_file_kw_type * file_kw , fortio_type * fortio, inv_map_type * inv_map); + ecl_kw_type * ecl_file_kw_get_kw_ptr( ecl_file_kw_type * file_kw ); + ecl_file_kw_type * ecl_file_kw_alloc_copy( const ecl_file_kw_type * src ); + const char * ecl_file_kw_get_header( const ecl_file_kw_type * file_kw ); + int ecl_file_kw_get_size( const ecl_file_kw_type * file_kw ); + ecl_data_type ecl_file_kw_get_data_type(const ecl_file_kw_type *); + offset_type ecl_file_kw_get_offset(const ecl_file_kw_type * file_kw); + bool ecl_file_kw_ptr_eq( const ecl_file_kw_type * file_kw , const ecl_kw_type * ecl_kw); + void ecl_file_kw_replace_kw( ecl_file_kw_type * file_kw , fortio_type * target , ecl_kw_type * new_kw ); + bool ecl_file_kw_fskip_data( const ecl_file_kw_type * file_kw , fortio_type * fortio); + void ecl_file_kw_inplace_fwrite( ecl_file_kw_type * file_kw , fortio_type * fortio); + + void ecl_file_kw_fwrite( const ecl_file_kw_type * file_kw , FILE * stream ); + ecl_file_kw_type ** ecl_file_kw_fread_alloc_multiple( FILE * stream , int num); + ecl_file_kw_type * ecl_file_kw_fread_alloc( FILE * stream ); + + void ecl_file_kw_start_transaction(const ecl_file_kw_type * file_kw, int * ref_count); + void ecl_file_kw_end_transaction(ecl_file_kw_type * file_kw, int ref_count); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.h index d5b28a2647..30cb80005e 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.h @@ -1,115 +1,9 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_ECL_FILE_VIEW_H -#define ERT_ECL_FILE_VIEW_H - -#include -#include - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - ECL_FILE_CLOSE_STREAM = 1 , /* - This flag will close the underlying FILE object between each access; this is - mainly to save filedescriptors in cases where many ecl_file instances are open at - the same time. */ - // - ECL_FILE_WRITABLE = 2 /* - This flag opens the file in a mode where it can be updated and modified, but it - must still exist and be readable. I.e. this should not compared with the normal: - fopen(filename , "w") where an existing file is truncated to zero upon successfull - open. - */ -} ecl_file_flag_type; - - -typedef struct ecl_file_view_struct ecl_file_view_type; -typedef struct ecl_file_transaction_struct ecl_file_transaction_type; - - - bool ecl_file_view_flags_set( const ecl_file_view_type * file_view, int query_flags); - bool ecl_file_view_check_flags( int state_flags , int query_flags); - - ecl_file_view_type * ecl_file_view_alloc( fortio_type * fortio , int * flags , inv_map_type * inv_map , bool owner ); - int ecl_file_view_get_global_index( const ecl_file_view_type * ecl_file_view , const char * kw , int ith); - void ecl_file_view_make_index( ecl_file_view_type * ecl_file_view ); - bool ecl_file_view_has_kw( const ecl_file_view_type * ecl_file_view, const char * kw); - ecl_file_kw_type * ecl_file_view_iget_file_kw( const ecl_file_view_type * ecl_file_view , int global_index); - ecl_file_kw_type * ecl_file_view_iget_named_file_kw( const ecl_file_view_type * ecl_file_view , const char * kw, int ith); - ecl_kw_type * ecl_file_view_iget_kw( const ecl_file_view_type * ecl_file_view , int index); - void ecl_file_view_index_fload_kw(const ecl_file_view_type * ecl_file_view, const char* kw, int index, const int_vector_type * index_map, char* buffer); - int ecl_file_view_find_kw_value( const ecl_file_view_type * ecl_file_view , const char * kw , const void * value); - const char * ecl_file_view_iget_distinct_kw( const ecl_file_view_type * ecl_file_view , int index); - int ecl_file_view_get_num_distinct_kw( const ecl_file_view_type * ecl_file_view ); - int ecl_file_view_get_size( const ecl_file_view_type * ecl_file_view ); - ecl_data_type ecl_file_view_iget_data_type( const ecl_file_view_type * ecl_file_view , int index); - int ecl_file_view_iget_size( const ecl_file_view_type * ecl_file_view , int index); - const char * ecl_file_view_iget_header( const ecl_file_view_type * ecl_file_view , int index); - ecl_kw_type * ecl_file_view_iget_named_kw( const ecl_file_view_type * ecl_file_view , const char * kw, int ith); - ecl_data_type ecl_file_view_iget_named_data_type( const ecl_file_view_type * ecl_file_view , const char * kw , int ith); - int ecl_file_view_iget_named_size( const ecl_file_view_type * ecl_file_view , const char * kw , int ith); - void ecl_file_view_replace_kw( ecl_file_view_type * ecl_file_view , ecl_kw_type * old_kw , ecl_kw_type * new_kw , bool insert_copy); - bool ecl_file_view_load_all( ecl_file_view_type * ecl_file_view ); - void ecl_file_view_add_kw( ecl_file_view_type * ecl_file_view , ecl_file_kw_type * file_kw); - void ecl_file_view_free( ecl_file_view_type * ecl_file_view ); - void ecl_file_view_free__( void * arg ); - int ecl_file_view_get_num_named_kw(const ecl_file_view_type * ecl_file_view , const char * kw); - void ecl_file_view_fwrite( const ecl_file_view_type * ecl_file_view , fortio_type * target , int offset); - int ecl_file_view_iget_occurence( const ecl_file_view_type * ecl_file_view , int global_index); - void ecl_file_view_fprintf_kw_list(const ecl_file_view_type * ecl_file_view , FILE * stream); - ecl_file_view_type * ecl_file_view_add_blockview(const ecl_file_view_type * ecl_file_view , const char * header, int occurence); - ecl_file_view_type * ecl_file_view_add_blockview2(const ecl_file_view_type * ecl_file_view , const char * start_kw, const char * end_kw, int occurence); - ecl_file_view_type * ecl_file_view_add_restart_view(ecl_file_view_type * file_view , int seqnum_index, int report_step , time_t sim_time, double sim_days); - ecl_file_view_type * ecl_file_view_alloc_blockview(const ecl_file_view_type * ecl_file_view , const char * header, int occurence); - ecl_file_view_type * ecl_file_view_alloc_blockview2(const ecl_file_view_type * ecl_file_view , const char * start_kw, const char * end_kw, int occurence); - - void ecl_file_view_add_child( ecl_file_view_type * parent , ecl_file_view_type * child); - bool ecl_file_view_drop_flag( ecl_file_view_type * file_view , int flag); - void ecl_file_view_add_flag( ecl_file_view_type * file_view , int flag); - - int ecl_file_view_seqnum_index_from_sim_time( ecl_file_view_type * parent_map , time_t sim_time); - bool ecl_file_view_has_sim_time( const ecl_file_view_type * ecl_file_view , time_t sim_time); - int ecl_file_view_find_sim_time(const ecl_file_view_type * ecl_file_view , time_t sim_time); - double ecl_file_view_iget_restart_sim_days(const ecl_file_view_type * ecl_file_view , int seqnum_index); - time_t ecl_file_view_iget_restart_sim_date(const ecl_file_view_type * ecl_file_view , int seqnum_index); - bool ecl_file_view_has_report_step( const ecl_file_view_type * ecl_file_view , int report_step); - - ecl_file_view_type * ecl_file_view_add_summary_view( ecl_file_view_type * file_view , int report_step ); - const char * ecl_file_view_get_src_file( const ecl_file_view_type * file_view ); - void ecl_file_view_fclose_stream( ecl_file_view_type * file_view ); - - void ecl_file_view_write_index(const ecl_file_view_type * file_view, FILE * ostream); - ecl_file_view_type * ecl_file_view_fread_alloc( fortio_type * fortio , int * flags , inv_map_type * inv_map, FILE * istream ); - - ecl_file_transaction_type * ecl_file_view_start_transaction(ecl_file_view_type * file_view); - void ecl_file_view_end_transaction( ecl_file_view_type * file_view, ecl_file_transaction_type * transaction); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.hpp index 4fbb391a83..20ab40af07 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_file_view.hpp @@ -1,19 +1,115 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - + Copyright (C) 2016 Statoil ASA, Norway. + This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include + +#ifndef ERT_ECL_FILE_VIEW_H +#define ERT_ECL_FILE_VIEW_H + +#include +#include + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ECL_FILE_CLOSE_STREAM = 1 , /* + This flag will close the underlying FILE object between each access; this is + mainly to save filedescriptors in cases where many ecl_file instances are open at + the same time. */ + // + ECL_FILE_WRITABLE = 2 /* + This flag opens the file in a mode where it can be updated and modified, but it + must still exist and be readable. I.e. this should not compared with the normal: + fopen(filename , "w") where an existing file is truncated to zero upon successfull + open. + */ +} ecl_file_flag_type; + + +typedef struct ecl_file_view_struct ecl_file_view_type; +typedef struct ecl_file_transaction_struct ecl_file_transaction_type; + + + bool ecl_file_view_flags_set( const ecl_file_view_type * file_view, int query_flags); + bool ecl_file_view_check_flags( int state_flags , int query_flags); + + ecl_file_view_type * ecl_file_view_alloc( fortio_type * fortio , int * flags , inv_map_type * inv_map , bool owner ); + int ecl_file_view_get_global_index( const ecl_file_view_type * ecl_file_view , const char * kw , int ith); + void ecl_file_view_make_index( ecl_file_view_type * ecl_file_view ); + bool ecl_file_view_has_kw( const ecl_file_view_type * ecl_file_view, const char * kw); + ecl_file_kw_type * ecl_file_view_iget_file_kw( const ecl_file_view_type * ecl_file_view , int global_index); + ecl_file_kw_type * ecl_file_view_iget_named_file_kw( const ecl_file_view_type * ecl_file_view , const char * kw, int ith); + ecl_kw_type * ecl_file_view_iget_kw( const ecl_file_view_type * ecl_file_view , int index); + void ecl_file_view_index_fload_kw(const ecl_file_view_type * ecl_file_view, const char* kw, int index, const int_vector_type * index_map, char* buffer); + int ecl_file_view_find_kw_value( const ecl_file_view_type * ecl_file_view , const char * kw , const void * value); + const char * ecl_file_view_iget_distinct_kw( const ecl_file_view_type * ecl_file_view , int index); + int ecl_file_view_get_num_distinct_kw( const ecl_file_view_type * ecl_file_view ); + int ecl_file_view_get_size( const ecl_file_view_type * ecl_file_view ); + ecl_data_type ecl_file_view_iget_data_type( const ecl_file_view_type * ecl_file_view , int index); + int ecl_file_view_iget_size( const ecl_file_view_type * ecl_file_view , int index); + const char * ecl_file_view_iget_header( const ecl_file_view_type * ecl_file_view , int index); + ecl_kw_type * ecl_file_view_iget_named_kw( const ecl_file_view_type * ecl_file_view , const char * kw, int ith); + ecl_data_type ecl_file_view_iget_named_data_type( const ecl_file_view_type * ecl_file_view , const char * kw , int ith); + int ecl_file_view_iget_named_size( const ecl_file_view_type * ecl_file_view , const char * kw , int ith); + void ecl_file_view_replace_kw( ecl_file_view_type * ecl_file_view , ecl_kw_type * old_kw , ecl_kw_type * new_kw , bool insert_copy); + bool ecl_file_view_load_all( ecl_file_view_type * ecl_file_view ); + void ecl_file_view_add_kw( ecl_file_view_type * ecl_file_view , ecl_file_kw_type * file_kw); + void ecl_file_view_free( ecl_file_view_type * ecl_file_view ); + void ecl_file_view_free__( void * arg ); + int ecl_file_view_get_num_named_kw(const ecl_file_view_type * ecl_file_view , const char * kw); + void ecl_file_view_fwrite( const ecl_file_view_type * ecl_file_view , fortio_type * target , int offset); + int ecl_file_view_iget_occurence( const ecl_file_view_type * ecl_file_view , int global_index); + void ecl_file_view_fprintf_kw_list(const ecl_file_view_type * ecl_file_view , FILE * stream); + ecl_file_view_type * ecl_file_view_add_blockview(const ecl_file_view_type * ecl_file_view , const char * header, int occurence); + ecl_file_view_type * ecl_file_view_add_blockview2(const ecl_file_view_type * ecl_file_view , const char * start_kw, const char * end_kw, int occurence); + ecl_file_view_type * ecl_file_view_add_restart_view(ecl_file_view_type * file_view , int seqnum_index, int report_step , time_t sim_time, double sim_days); + ecl_file_view_type * ecl_file_view_alloc_blockview(const ecl_file_view_type * ecl_file_view , const char * header, int occurence); + ecl_file_view_type * ecl_file_view_alloc_blockview2(const ecl_file_view_type * ecl_file_view , const char * start_kw, const char * end_kw, int occurence); + + void ecl_file_view_add_child( ecl_file_view_type * parent , ecl_file_view_type * child); + bool ecl_file_view_drop_flag( ecl_file_view_type * file_view , int flag); + void ecl_file_view_add_flag( ecl_file_view_type * file_view , int flag); + + int ecl_file_view_seqnum_index_from_sim_time( ecl_file_view_type * parent_map , time_t sim_time); + bool ecl_file_view_has_sim_time( const ecl_file_view_type * ecl_file_view , time_t sim_time); + int ecl_file_view_find_sim_time(const ecl_file_view_type * ecl_file_view , time_t sim_time); + double ecl_file_view_iget_restart_sim_days(const ecl_file_view_type * ecl_file_view , int seqnum_index); + time_t ecl_file_view_iget_restart_sim_date(const ecl_file_view_type * ecl_file_view , int seqnum_index); + bool ecl_file_view_has_report_step( const ecl_file_view_type * ecl_file_view , int report_step); + + ecl_file_view_type * ecl_file_view_add_summary_view( ecl_file_view_type * file_view , int report_step ); + const char * ecl_file_view_get_src_file( const ecl_file_view_type * file_view ); + void ecl_file_view_fclose_stream( ecl_file_view_type * file_view ); + + void ecl_file_view_write_index(const ecl_file_view_type * file_view, FILE * ostream); + ecl_file_view_type * ecl_file_view_fread_alloc( fortio_type * fortio , int * flags , inv_map_type * inv_map, FILE * istream ); + + ecl_file_transaction_type * ecl_file_view_start_transaction(ecl_file_view_type * file_view); + void ecl_file_view_end_transaction( ecl_file_view_type * file_view, ecl_file_transaction_type * transaction); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.h index 67c44b9bfb..c58f33b2e0 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.h @@ -1,47 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_GRAV_H -#define ERT_ECL_GRAV_H -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include - -typedef struct ecl_grav_struct ecl_grav_type; -typedef struct ecl_grav_survey_struct ecl_grav_survey_type; - +#include -void ecl_grav_free( ecl_grav_type * ecl_grav_config ); -ecl_grav_type * ecl_grav_alloc( const ecl_grid_type * ecl_grid, const ecl_file_type * init_file ); -ecl_grav_survey_type * ecl_grav_add_survey_FIP( ecl_grav_type * grav , const char * name , const ecl_file_view_type * restart_file ); -ecl_grav_survey_type * ecl_grav_add_survey_PORMOD( ecl_grav_type * grav , const char * name , const ecl_file_view_type * restart_file ); -ecl_grav_survey_type * ecl_grav_add_survey_RPORV( ecl_grav_type * grav , const char * name , const ecl_file_view_type * restart_file ); -ecl_grav_survey_type * ecl_grav_add_survey_RFIP( ecl_grav_type * grav , const char * name , const ecl_file_view_type * restart_file ); -double ecl_grav_eval( const ecl_grav_type * grav , const char * base, const char * monitor , ecl_region_type * region , double utm_x, double utm_y , double depth, int phase_mask); -void ecl_grav_new_std_density( ecl_grav_type * grav , ecl_phase_enum phase , double default_density); -void ecl_grav_add_std_density( ecl_grav_type * grav , ecl_phase_enum phase , int pvtnum , double density); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.hpp index 9dbd0ae404..41e09f34cd 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav.hpp @@ -1,19 +1,47 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - + Copyright (C) 2011 Statoil ASA, Norway. + This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_GRAV_H +#define ERT_ECL_GRAV_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct ecl_grav_struct ecl_grav_type; +typedef struct ecl_grav_survey_struct ecl_grav_survey_type; + + +void ecl_grav_free( ecl_grav_type * ecl_grav_config ); +ecl_grav_type * ecl_grav_alloc( const ecl_grid_type * ecl_grid, const ecl_file_type * init_file ); +ecl_grav_survey_type * ecl_grav_add_survey_FIP( ecl_grav_type * grav , const char * name , const ecl_file_view_type * restart_file ); +ecl_grav_survey_type * ecl_grav_add_survey_PORMOD( ecl_grav_type * grav , const char * name , const ecl_file_view_type * restart_file ); +ecl_grav_survey_type * ecl_grav_add_survey_RPORV( ecl_grav_type * grav , const char * name , const ecl_file_view_type * restart_file ); +ecl_grav_survey_type * ecl_grav_add_survey_RFIP( ecl_grav_type * grav , const char * name , const ecl_file_view_type * restart_file ); +double ecl_grav_eval( const ecl_grav_type * grav , const char * base, const char * monitor , ecl_region_type * region , double utm_x, double utm_y , double depth, int phase_mask); +void ecl_grav_new_std_density( ecl_grav_type * grav , ecl_phase_enum phase , double default_density); +void ecl_grav_add_std_density( ecl_grav_type * grav , ecl_phase_enum phase , int pvtnum , double density); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.h index 62a1b84ed1..0964567ae2 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.h @@ -1,47 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_grav.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_GRAV_CALC_H -#define ERT_ECL_GRAV_CALC_H -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -double ecl_grav_phase_deltag( double utm_x , - double utm_y , - double tvd, - const ecl_grid_type * grid, - const ecl_file_type * init_file , - const ecl_kw_type * sat_kw1, - const ecl_kw_type * rho_kw1, - const ecl_kw_type * porv_kw1, - const ecl_kw_type * sat_kw2, - const ecl_kw_type * rho_kw2, - const ecl_kw_type * porv_kw2); - - +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.hpp index df878a9337..62a1b84ed1 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_calc.hpp @@ -1,19 +1,47 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_grav.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_GRAV_CALC_H +#define ERT_ECL_GRAV_CALC_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +double ecl_grav_phase_deltag( double utm_x , + double utm_y , + double tvd, + const ecl_grid_type * grid, + const ecl_file_type * init_file , + const ecl_kw_type * sat_kw1, + const ecl_kw_type * rho_kw1, + const ecl_kw_type * porv_kw1, + const ecl_kw_type * sat_kw2, + const ecl_kw_type * rho_kw2, + const ecl_kw_type * porv_kw2); + + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.h index 35c2a0ae51..a2c0232808 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.h @@ -1,56 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_grav_common.h' is part of ERT - Ensemble based - Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_GRAV_COMMON_H -#define ERT_ECL_GRAV_COMMON_H - -#ifdef __cplusplus -extern "C" { -#endif -#include - -#include -#include - -bool * ecl_grav_common_alloc_aquifer_cell(const ecl_grid_cache_type * grid_cache, - const ecl_file_type * init_file); - -double ecl_grav_common_eval_biot_savart(const ecl_grid_cache_type * grid_cache, - ecl_region_type * region, - const bool * aquifer, - const double * weight, - double utm_x, - double utm_y, - double depth); - -double ecl_grav_common_eval_geertsma(const ecl_grid_cache_type * grid_cache, - ecl_region_type * region, - const bool * aquifer, - const double * weight, - double utm_x, - double utm_y, - double depth, - double poisson_ratio, - double seabed); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.hpp index 555ef8dc1c..925508cf17 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grav_common.hpp @@ -1,19 +1,57 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_grav_common.h' is part of ERT - Ensemble based + Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_GRAV_COMMON_H +#define ERT_ECL_GRAV_COMMON_H + +#include + +#include +#include "detail/ecl/ecl_grid_cache.hpp" + +#ifdef __cplusplus +extern "C" { +#endif + + bool * ecl_grav_common_alloc_aquifer_cell(const ecl::ecl_grid_cache& grid_cache, + const ecl_file_type * init_file); + + double ecl_grav_common_eval_biot_savart(const ecl::ecl_grid_cache& grid_cache, + ecl_region_type * region, + const bool * aquifer, + const double * weight, + double utm_x, + double utm_y, + double depth); + + double ecl_grav_common_eval_geertsma(const ecl::ecl_grid_cache& grid_cache, + ecl_region_type * region, + const bool * aquifer, + const double * weight, + double utm_x, + double utm_y, + double depth, + double poisson_ratio, + double seabed); + +#ifdef __cplusplus +} + +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.h index 5ae7b115db..3aa37be372 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.h @@ -1,269 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_grid.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_GRID_H -#define ERT_ECL_GRID_H -#ifdef __cplusplus -extern "C" { -#endif -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define ECL_GRID_COORD_SIZE(nx,ny) (((nx) + 1) * ((ny) + 1) * 6) -#define ECL_GRID_ZCORN_SIZE(nx,ny,nz) (((nx) * (ny) * (nz) * 8)) - -#define ECL_GRID_GLOBAL_GRID "Global" // used as key in hash tables over grids. -#define ECL_GRID_MAINGRID_LGR_NR 0 - - typedef double (block_function_ftype) ( const double_vector_type *); - typedef struct ecl_grid_struct ecl_grid_type; - - bool ecl_grid_have_coarse_cells( const ecl_grid_type * main_grid ); - bool ecl_grid_cell_in_coarse_group1( const ecl_grid_type * main_grid , int global_index ); - bool ecl_grid_cell_in_coarse_group3( const ecl_grid_type * main_grid , int i , int j , int k); - int ecl_grid_get_num_coarse_groups( const ecl_grid_type * main_grid ); - ecl_coarse_cell_type * ecl_grid_iget_coarse_group( const ecl_grid_type * ecl_grid , int coarse_nr ); - ecl_coarse_cell_type * ecl_grid_get_cell_coarse_group1( const ecl_grid_type * ecl_grid , int global_index); - ecl_coarse_cell_type * ecl_grid_get_cell_coarse_group3( const ecl_grid_type * ecl_grid , int i , int j , int k); - - int ecl_grid_get_cell_twist1( const ecl_grid_type * ecl_grid, int global_index ); - int ecl_grid_get_cell_twist3( const ecl_grid_type * ecl_grid, int i , int j , int k); - - void ecl_grid_get_column_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j, double_vector_type * column); - int ecl_grid_get_global_index_from_xy_top( const ecl_grid_type * ecl_grid , double x , double y); - int ecl_grid_get_global_index_from_xy_bottom( const ecl_grid_type * ecl_grid , double x , double y); - ecl_grid_type * ecl_grid_alloc_dx_dy_dz_tops( int nx, int ny , int nz , const double * dx , const double * dy , const double * dz , const double * tops , const int * actnum); - - void ecl_grid_get_cell_corner_xyz3(const ecl_grid_type * grid , int i , int j , int k, int corner_nr , double * xpos , double * ypos , double * zpos ); - void ecl_grid_get_cell_corner_xyz1(const ecl_grid_type * grid , int global_index , int corner_nr , double * xpos , double * ypos , double * zpos ); - void ecl_grid_get_corner_xyz(const ecl_grid_type * grid , int i , int j , int k, double * xpos , double * ypos , double * zpos ); - - double ecl_grid_get_cell_dx1A( const ecl_grid_type * grid , int active_index); - double ecl_grid_get_cell_dy1A( const ecl_grid_type * grid , int active_index); - double ecl_grid_get_cell_dz1A( const ecl_grid_type * grid , int active_index ); - double ecl_grid_get_cell_thickness1A( const ecl_grid_type * grid , int active_index ); - - double ecl_grid_get_cell_dx1( const ecl_grid_type * grid , int global_index ); - double ecl_grid_get_cell_dy1( const ecl_grid_type * grid , int global_index ); - double ecl_grid_get_cell_dz1( const ecl_grid_type * grid , int global_index ); - double ecl_grid_get_cell_thickness1( const ecl_grid_type * grid , int global_index ); - - double ecl_grid_get_cell_dx3( const ecl_grid_type * grid , int i , int j , int k); - double ecl_grid_get_cell_dy3( const ecl_grid_type * grid , int i , int j , int k); - double ecl_grid_get_cell_dz3( const ecl_grid_type * grid , int i , int j , int k); - double ecl_grid_get_cell_thickness3( const ecl_grid_type * grid , int i , int j , int k); - - void ecl_grid_get_distance(const ecl_grid_type * grid , int global_index1, int global_index2 , double *dx , double *dy , double *dz); - double ecl_grid_get_cdepth1A(const ecl_grid_type * grid , int active_index); - double ecl_grid_get_cdepth1(const ecl_grid_type * grid , int global_index); - double ecl_grid_get_cdepth3(const ecl_grid_type * grid , int i, int j , int k); - int ecl_grid_get_global_index_from_xy( const ecl_grid_type * ecl_grid , int k , bool lower_layer , double x , double y); - bool ecl_grid_cell_contains_xyz1( const ecl_grid_type * ecl_grid , int global_index , double x , double y , double z); - bool ecl_grid_cell_contains_xyz3( const ecl_grid_type * ecl_grid , int i , int j , int k, double x , double y , double z ); - double ecl_grid_get_cell_volume1( const ecl_grid_type * ecl_grid, int global_index ); - double ecl_grid_get_cell_volume1_tskille( const ecl_grid_type * ecl_grid, int global_index ); - double ecl_grid_get_cell_volume3( const ecl_grid_type * ecl_grid, int i , int j , int k); - double ecl_grid_get_cell_volume1A( const ecl_grid_type * ecl_grid, int active_index ); - bool ecl_grid_cell_contains1(const ecl_grid_type * grid , int global_index , double x , double y , double z); - bool ecl_grid_cell_contains3(const ecl_grid_type * grid , int i , int j ,int k , double x , double y , double z); - int ecl_grid_get_global_index_from_xyz(ecl_grid_type * grid , double x , double y , double z , int start_index); - bool ecl_grid_get_ijk_from_xyz(ecl_grid_type * grid , double x , double y , double z , int start_index, int *i, int *j, int *k ); - bool ecl_grid_get_ij_from_xy( const ecl_grid_type * grid , double x , double y , int k , int* i, int* j); - const char * ecl_grid_get_name( const ecl_grid_type * ); - int ecl_grid_get_active_index3(const ecl_grid_type * ecl_grid , int i , int j , int k); - int ecl_grid_get_active_index1(const ecl_grid_type * ecl_grid , int global_index); - int ecl_grid_get_active_fracture_index3(const ecl_grid_type * ecl_grid , int i , int j , int k); - int ecl_grid_get_active_fracture_index1(const ecl_grid_type * ecl_grid , int global_index); - bool ecl_grid_cell_active3(const ecl_grid_type * , int , int , int ); - bool ecl_grid_cell_active1(const ecl_grid_type * , int); - bool ecl_grid_ijk_valid(const ecl_grid_type * , int , int , int ); - int ecl_grid_get_global_index3(const ecl_grid_type * , int , int , int ); - int ecl_grid_get_global_index1A(const ecl_grid_type * ecl_grid , int active_index); - int ecl_grid_get_global_index1F(const ecl_grid_type * ecl_grid , int active_fracture_index); - - const nnc_info_type * ecl_grid_get_cell_nnc_info3( const ecl_grid_type * grid , int i , int j , int k); - const nnc_info_type * ecl_grid_get_cell_nnc_info1( const ecl_grid_type * grid , int global_index); - void ecl_grid_add_self_nnc( ecl_grid_type * grid1, int g1, int g2, int nnc_index); - void ecl_grid_add_self_nnc_list( ecl_grid_type * grid, const int * g1_list , const int * g2_list , int num_nnc ); - - ecl_grid_type * ecl_grid_alloc_GRDECL_kw( int nx, int ny , int nz , const ecl_kw_type * zcorn_kw , const ecl_kw_type * coord_kw , const ecl_kw_type * actnum_kw , const ecl_kw_type * mapaxes_kw ); - ecl_grid_type * ecl_grid_alloc_GRDECL_data(int , int , int , const float * , const float * , const int * , bool apply_mapaxes , const float * mapaxes); - ecl_grid_type * ecl_grid_alloc_GRID_data(int num_coords , int nx, int ny , int nz , int coords_size , int ** coords , float ** corners , bool apply_mapaxes, const float * mapaxes); - ecl_grid_type * ecl_grid_alloc(const char * ); - ecl_grid_type * ecl_grid_load_case( const char * case_input ); - ecl_grid_type * ecl_grid_load_case__( const char * case_input , bool apply_mapaxes); - ecl_grid_type * ecl_grid_alloc_rectangular( int nx , int ny , int nz , double dx , double dy , double dz , const int * actnum); - ecl_grid_type * ecl_grid_alloc_regular( int nx, int ny , int nz , const double * ivec, const double * jvec , const double * kvec , const int * actnum); - ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv( int nx, int ny , int nz , const double * dxv , const double * dyv , const double * dzv , const int * actnum); - ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv_depthz( int nx, int ny , int nz , const double * dxv , const double * dyv , const double * dzv , const double * depthz , const int * actnum); - ecl_kw_type * ecl_grid_alloc_volume_kw( const ecl_grid_type * grid , bool active_size); - ecl_kw_type * ecl_grid_alloc_mapaxes_kw( const ecl_grid_type * grid ); - ecl_kw_type * ecl_grid_alloc_coord_kw( const ecl_grid_type * grid); - - bool ecl_grid_exists( const char * case_input ); - char * ecl_grid_alloc_case_filename( const char * case_input ); - - void ecl_grid_free(ecl_grid_type * ); - void ecl_grid_free__( void * arg ); - grid_dims_type ecl_grid_iget_dims( const ecl_grid_type * grid , int grid_nr); - void ecl_grid_get_dims(const ecl_grid_type * , int *, int * , int * , int *); - int ecl_grid_get_nz( const ecl_grid_type * grid ); - int ecl_grid_get_nx( const ecl_grid_type * grid ); - int ecl_grid_get_ny( const ecl_grid_type * grid ); - int ecl_grid_get_nactive( const ecl_grid_type * grid ); - int ecl_grid_get_nactive_fracture( const ecl_grid_type * grid ); - int ecl_grid_get_active_index(const ecl_grid_type * , int , int , int ); - void ecl_grid_summarize(const ecl_grid_type * ); - void ecl_grid_get_ijk1(const ecl_grid_type * , int global_index , int *, int * , int *); - void ecl_grid_get_ijk1A(const ecl_grid_type * , int active_index, int *, int * , int *); - void ecl_grid_get_ijk_from_active_index(const ecl_grid_type *, int , int *, int * , int * ); - - void ecl_grid_get_xyz3(const ecl_grid_type * , int , int , int , double * , double * , double *); - void ecl_grid_get_xyz1(const ecl_grid_type * grid , int global_index , double *xpos , double *ypos , double *zpos); - void ecl_grid_get_xyz1A(const ecl_grid_type * grid , int active_index , double *xpos , double *ypos , double *zpos); - - bool ecl_grid_get_xyz_inside1(const ecl_grid_type * grid , int global_index , double *xpos , double *ypos , double *zpos); - bool ecl_grid_get_xyz_inside3(const ecl_grid_type * grid , int i , int j , int k , double *xpos , double *ypos , double *zpos); - - int ecl_grid_get_global_size( const ecl_grid_type * ecl_grid ); - bool ecl_grid_compare(const ecl_grid_type * g1 , const ecl_grid_type * g2 , bool include_lgr, bool include_nnc , bool verbose); - int ecl_grid_get_active_size( const ecl_grid_type * ecl_grid ); - - double ecl_grid_get_bottom1(const ecl_grid_type * grid , int global_index); - double ecl_grid_get_bottom3(const ecl_grid_type * grid , int i, int j , int k); - double ecl_grid_get_bottom1A(const ecl_grid_type * grid , int active_index); - double ecl_grid_get_top1(const ecl_grid_type * grid , int global_index); - double ecl_grid_get_top3(const ecl_grid_type * grid , int i, int j , int k); - double ecl_grid_get_top1A(const ecl_grid_type * grid , int active_index); - double ecl_grid_get_top2(const ecl_grid_type * grid , int i, int j); - double ecl_grid_get_bottom2(const ecl_grid_type * grid , int i, int j); - int ecl_grid_locate_depth( const ecl_grid_type * grid , double depth , int i , int j ); - - void ecl_grid_alloc_blocking_variables(ecl_grid_type * , int ); - void ecl_grid_init_blocking(ecl_grid_type * ); - double ecl_grid_block_eval3d(ecl_grid_type * grid , int i, int j , int k ,block_function_ftype * blockf ); - int ecl_grid_get_block_count3d(const ecl_grid_type * ecl_grid , int i , int j, int k); - bool ecl_grid_block_value_3d(ecl_grid_type * , double , double ,double , double); - - bool ecl_grid_cell_invalid1(const ecl_grid_type * ecl_grid , int global_index); - bool ecl_grid_cell_invalid3(const ecl_grid_type * ecl_grid , int i , int j , int k); - double ecl_grid_cell_invalid1A(const ecl_grid_type * grid , int active_index); - - bool ecl_grid_cell_valid1(const ecl_grid_type * ecl_grid , int global_index); - bool ecl_grid_cell_valid3(const ecl_grid_type * ecl_grid , int i , int j , int k); - double ecl_grid_cell_valid1A(const ecl_grid_type * grid , int active_index); - - void ecl_grid_dump(const ecl_grid_type * grid , FILE * stream); - void ecl_grid_dump_ascii(ecl_grid_type * grid , bool active_only , FILE * stream); - void ecl_grid_dump_ascii_cell1(ecl_grid_type * grid , int global_index , FILE * stream, const double * offset); - void ecl_grid_dump_ascii_cell3(ecl_grid_type * grid , int i , int j , int k , FILE * stream , const double * offset); - - /* lgr related functions */ - const ecl_grid_type * ecl_grid_get_cell_lgr3(const ecl_grid_type * grid , int i, int j , int k); - const ecl_grid_type * ecl_grid_get_cell_lgr1A(const ecl_grid_type * grid , int active_index); - const ecl_grid_type * ecl_grid_get_cell_lgr1(const ecl_grid_type * grid , int global_index ); - int ecl_grid_get_num_lgr(const ecl_grid_type * main_grid ); - int ecl_grid_get_lgr_nr( const ecl_grid_type * ecl_grid ); - int ecl_grid_get_lgr_nr_from_name( const ecl_grid_type * grid , const char * name); - ecl_grid_type * ecl_grid_iget_lgr(const ecl_grid_type * main_grid , int lgr_index); - ecl_grid_type * ecl_grid_get_lgr_from_lgr_nr(const ecl_grid_type * main_grid, int lgr_nr); - ecl_grid_type * ecl_grid_get_lgr(const ecl_grid_type * main_grid, const char * __lgr_name); - bool ecl_grid_has_lgr(const ecl_grid_type * main_grid, const char * __lgr_name); - bool ecl_grid_has_lgr_nr(const ecl_grid_type * main_grid, int lgr_nr); - const char * ecl_grid_iget_lgr_name( const ecl_grid_type * ecl_grid , int lgr_index); - const char * ecl_grid_get_lgr_name( const ecl_grid_type * ecl_grid , int lgr_nr); - stringlist_type * ecl_grid_alloc_lgr_name_list(const ecl_grid_type * ecl_grid); - int ecl_grid_get_parent_cell1( const ecl_grid_type * grid , int global_index); - int ecl_grid_get_parent_cell3( const ecl_grid_type * grid , int i , int j , int k); - const ecl_grid_type * ecl_grid_get_global_grid( const ecl_grid_type * grid ); - bool ecl_grid_is_lgr( const ecl_grid_type * ecl_grid ); - - double ecl_grid_get_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k); - float ecl_grid_get_float_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k); - double ecl_grid_get_double_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k); - int ecl_grid_get_int_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k); - - void ecl_grid_grdecl_fprintf_kw( const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream , double double_default); - bool ecl_grid_test_lgr_consistency( const ecl_grid_type * ecl_grid ); - - void ecl_grid_fwrite_dims( const ecl_grid_type * grid , fortio_type * init_file, ert_ecl_unit_enum output_unit); - void ecl_grid_fwrite_depth( const ecl_grid_type * grid , fortio_type * init_file , ert_ecl_unit_enum ouput_unit); - - void ecl_grid_fwrite_EGRID( ecl_grid_type * grid , const char * filename, bool metric_output); - void ecl_grid_fwrite_EGRID2( ecl_grid_type * grid , const char * filename, ert_ecl_unit_enum output_unit); - - void ecl_grid_fwrite_GRID( const ecl_grid_type * grid , const char * filename); - void ecl_grid_fwrite_GRID2( const ecl_grid_type * grid , const char * filename, ert_ecl_unit_enum output_unit); - - void ecl_grid_fprintf_grdecl( ecl_grid_type * grid , FILE * stream ); - void ecl_grid_fprintf_grdecl2( ecl_grid_type * grid , FILE * stream , ert_ecl_unit_enum output_unit); - - int ecl_grid_zcorn_index__(int nx, int ny , int i, int j , int k , int c); - int ecl_grid_zcorn_index(const ecl_grid_type * grid , int i, int j , int k , int c); - ecl_grid_type * ecl_grid_alloc_EGRID(const char * grid_file, bool apply_mapaxes ); - ecl_grid_type * ecl_grid_alloc_GRID(const char * grid_file, bool apply_mapaxes ); - - float * ecl_grid_alloc_zcorn_data( const ecl_grid_type * grid ); - ecl_kw_type * ecl_grid_alloc_zcorn_kw( const ecl_grid_type * grid ); - int * ecl_grid_alloc_actnum_data( const ecl_grid_type * grid ); - ecl_kw_type * ecl_grid_alloc_actnum_kw( const ecl_grid_type * grid ); - ecl_kw_type * ecl_grid_alloc_hostnum_kw( const ecl_grid_type * grid ); - ecl_kw_type * ecl_grid_alloc_gridhead_kw( int nx, int ny , int nz , int grid_nr); - ecl_grid_type * ecl_grid_alloc_copy( const ecl_grid_type * src_grid ); - ecl_grid_type * ecl_grid_alloc_processed_copy( const ecl_grid_type * src_grid , const double * zcorn , const int * actnum); - - void ecl_grid_ri_export( const ecl_grid_type * ecl_grid , double * ri_points); - void ecl_grid_cell_ri_export( const ecl_grid_type * ecl_grid , int global_index , double * ri_points); - - bool ecl_grid_dual_grid( const ecl_grid_type * ecl_grid ); - int ecl_grid_get_num_nnc( const ecl_grid_type * grid ); - - bool ecl_grid_cell_regular3( const ecl_grid_type * ecl_grid, int i,int j,int k); - bool ecl_grid_cell_regular1( const ecl_grid_type * ecl_grid, int global_index); - - void ecl_grid_init_zcorn_data( const ecl_grid_type * grid , float * zcorn ); - void ecl_grid_init_zcorn_data_double( const ecl_grid_type * grid , double * zcorn ); - int ecl_grid_get_zcorn_size( const ecl_grid_type * grid ); - - void ecl_grid_init_coord_data( const ecl_grid_type * grid , float * coord ); - void ecl_grid_init_coord_data_double( const ecl_grid_type * grid , double * coord ); - int ecl_grid_get_coord_size( const ecl_grid_type * ecl_grid); - - void ecl_grid_init_actnum_data( const ecl_grid_type * grid , int * actnum ); - bool ecl_grid_use_mapaxes( const ecl_grid_type * grid ); - void ecl_grid_init_mapaxes_data_double( const ecl_grid_type * grid , double * mapaxes); - void ecl_grid_reset_actnum( ecl_grid_type * grid , const int * actnum ); - void ecl_grid_compressed_kw_copy( const ecl_grid_type * grid , ecl_kw_type * target_kw , const ecl_kw_type * src_kw); - void ecl_grid_global_kw_copy( const ecl_grid_type * grid , ecl_kw_type * target_kw , const ecl_kw_type * src_kw); - void ecl_grid_export_cell_corners1(const ecl_grid_type * grid, int global_index, double *x, double *y, double *z); +#include - UTIL_IS_INSTANCE_HEADER( ecl_grid ); - UTIL_SAFE_CAST_HEADER( ecl_grid ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.hpp index a27e4887ee..4efac56885 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid.hpp @@ -1,19 +1,293 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_grid.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_GRID_H +#define ERT_ECL_GRID_H +#ifdef __cplusplus +extern "C" { +#endif +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define ECL_GRID_COORD_SIZE(nx,ny) (((nx) + 1) * ((ny) + 1) * 6) +#define ECL_GRID_ZCORN_SIZE(nx,ny,nz) (((nx) * (ny) * (nz) * 8)) + +#define ECL_GRID_GLOBAL_GRID "Global" // used as key in hash tables over grids. +#define ECL_GRID_MAINGRID_LGR_NR 0 + + typedef double (block_function_ftype) ( const double_vector_type *); + typedef struct ecl_grid_struct ecl_grid_type; + + bool ecl_grid_have_coarse_cells( const ecl_grid_type * main_grid ); + bool ecl_grid_cell_in_coarse_group1( const ecl_grid_type * main_grid , int global_index ); + bool ecl_grid_cell_in_coarse_group3( const ecl_grid_type * main_grid , int i , int j , int k); + int ecl_grid_get_num_coarse_groups( const ecl_grid_type * main_grid ); + ecl_coarse_cell_type * ecl_grid_iget_coarse_group( const ecl_grid_type * ecl_grid , int coarse_nr ); + ecl_coarse_cell_type * ecl_grid_get_cell_coarse_group1( const ecl_grid_type * ecl_grid , int global_index); + ecl_coarse_cell_type * ecl_grid_get_cell_coarse_group3( const ecl_grid_type * ecl_grid , int i , int j , int k); + + int ecl_grid_get_cell_twist1( const ecl_grid_type * ecl_grid, int global_index ); + int ecl_grid_get_cell_twist3( const ecl_grid_type * ecl_grid, int i , int j , int k); + + void ecl_grid_get_column_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j, double_vector_type * column); + int ecl_grid_get_global_index_from_xy_top( const ecl_grid_type * ecl_grid , double x , double y); + int ecl_grid_get_global_index_from_xy_bottom( const ecl_grid_type * ecl_grid , double x , double y); + ecl_grid_type * ecl_grid_alloc_dx_dy_dz_tops( int nx, int ny , int nz , const double * dx , const double * dy , const double * dz , const double * tops , const int * actnum); + + void ecl_grid_get_cell_corner_xyz3(const ecl_grid_type * grid , int i , int j , int k, int corner_nr , double * xpos , double * ypos , double * zpos ); + void ecl_grid_get_cell_corner_xyz1(const ecl_grid_type * grid , int global_index , int corner_nr , double * xpos , double * ypos , double * zpos ); + void ecl_grid_get_corner_xyz(const ecl_grid_type * grid , int i , int j , int k, double * xpos , double * ypos , double * zpos ); + + double ecl_grid_get_cell_dx1A( const ecl_grid_type * grid , int active_index); + double ecl_grid_get_cell_dy1A( const ecl_grid_type * grid , int active_index); + double ecl_grid_get_cell_dz1A( const ecl_grid_type * grid , int active_index ); + double ecl_grid_get_cell_thickness1A( const ecl_grid_type * grid , int active_index ); + + double ecl_grid_get_cell_dx1( const ecl_grid_type * grid , int global_index ); + double ecl_grid_get_cell_dy1( const ecl_grid_type * grid , int global_index ); + double ecl_grid_get_cell_dz1( const ecl_grid_type * grid , int global_index ); + double ecl_grid_get_cell_thickness1( const ecl_grid_type * grid , int global_index ); + + double ecl_grid_get_cell_dx3( const ecl_grid_type * grid , int i , int j , int k); + double ecl_grid_get_cell_dy3( const ecl_grid_type * grid , int i , int j , int k); + double ecl_grid_get_cell_dz3( const ecl_grid_type * grid , int i , int j , int k); + double ecl_grid_get_cell_thickness3( const ecl_grid_type * grid , int i , int j , int k); + + void ecl_grid_get_distance(const ecl_grid_type * grid , int global_index1, int global_index2 , double *dx , double *dy , double *dz); + double ecl_grid_get_cdepth1A(const ecl_grid_type * grid , int active_index); + double ecl_grid_get_cdepth1(const ecl_grid_type * grid , int global_index); + double ecl_grid_get_cdepth3(const ecl_grid_type * grid , int i, int j , int k); + int ecl_grid_get_global_index_from_xy( const ecl_grid_type * ecl_grid , int k , bool lower_layer , double x , double y); + bool ecl_grid_cell_contains_xyz1( const ecl_grid_type * ecl_grid , int global_index , double x , double y , double z); + bool ecl_grid_cell_contains_xyz3( const ecl_grid_type * ecl_grid , int i , int j , int k, double x , double y , double z ); + double ecl_grid_get_cell_volume1( const ecl_grid_type * ecl_grid, int global_index ); + double ecl_grid_get_cell_volume3( const ecl_grid_type * ecl_grid, int i , int j , int k); + double ecl_grid_get_cell_volume1A( const ecl_grid_type * ecl_grid, int active_index ); + bool ecl_grid_cell_contains1(const ecl_grid_type * grid , int global_index , double x , double y , double z); + bool ecl_grid_cell_contains3(const ecl_grid_type * grid , int i , int j ,int k , double x , double y , double z); + int ecl_grid_get_global_index_from_xyz(ecl_grid_type * grid , double x , double y , double z , int start_index); + bool ecl_grid_get_ijk_from_xyz(ecl_grid_type * grid , double x , double y , double z , int start_index, int *i, int *j, int *k ); + bool ecl_grid_get_ij_from_xy( const ecl_grid_type * grid , double x , double y , int k , int* i, int* j); + const char * ecl_grid_get_name( const ecl_grid_type * ); + int ecl_grid_get_active_index3(const ecl_grid_type * ecl_grid , int i , int j , int k); + int ecl_grid_get_active_index1(const ecl_grid_type * ecl_grid , int global_index); + int ecl_grid_get_active_fracture_index3(const ecl_grid_type * ecl_grid , int i , int j , int k); + int ecl_grid_get_active_fracture_index1(const ecl_grid_type * ecl_grid , int global_index); + bool ecl_grid_cell_active3(const ecl_grid_type * , int , int , int ); + bool ecl_grid_cell_active1(const ecl_grid_type * , int); + bool ecl_grid_ijk_valid(const ecl_grid_type * , int , int , int ); + int ecl_grid_get_global_index3(const ecl_grid_type * , int , int , int ); + int ecl_grid_get_global_index1A(const ecl_grid_type * ecl_grid , int active_index); + int ecl_grid_get_global_index1F(const ecl_grid_type * ecl_grid , int active_fracture_index); + + const nnc_info_type * ecl_grid_get_cell_nnc_info3( const ecl_grid_type * grid , int i , int j , int k); + const nnc_info_type * ecl_grid_get_cell_nnc_info1( const ecl_grid_type * grid , int global_index); + void ecl_grid_add_self_nnc( ecl_grid_type * grid1, int g1, int g2, int nnc_index); + void ecl_grid_add_self_nnc_list( ecl_grid_type * grid, const int * g1_list , const int * g2_list , int num_nnc ); + + ecl_grid_type * ecl_grid_alloc_GRDECL_kw( int nx, int ny , int nz , const ecl_kw_type * zcorn_kw , const ecl_kw_type * coord_kw , const ecl_kw_type * actnum_kw , const ecl_kw_type * mapaxes_kw ); + ecl_grid_type * ecl_grid_alloc_GRDECL_data(int , int , int , const float * , const float * , const int * , bool apply_mapaxes , const float * mapaxes); + ecl_grid_type * ecl_grid_alloc_GRID_data(int num_coords , int nx, int ny , int nz , int coords_size , int ** coords , float ** corners , bool apply_mapaxes, const float * mapaxes); + ecl_grid_type * ecl_grid_alloc(const char * ); + ecl_grid_type * ecl_grid_alloc_ext_actnum(const char * , const int * ext_actnum); + ecl_grid_type * ecl_grid_load_case( const char * case_input ); + ecl_grid_type * ecl_grid_load_case__( const char * case_input , bool apply_mapaxes); + ecl_grid_type * ecl_grid_alloc_rectangular( int nx , int ny , int nz , double dx , double dy , double dz , const int * actnum); + ecl_grid_type * ecl_grid_alloc_regular( int nx, int ny , int nz , const double * ivec, const double * jvec , const double * kvec , const int * actnum); + ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv( int nx, int ny , int nz , const double * dxv , const double * dyv , const double * dzv , const int * actnum); + ecl_grid_type * ecl_grid_alloc_dxv_dyv_dzv_depthz( int nx, int ny , int nz , const double * dxv , const double * dyv , const double * dzv , const double * depthz , const int * actnum); + ecl_kw_type * ecl_grid_alloc_volume_kw( const ecl_grid_type * grid , bool active_size); + ecl_kw_type * ecl_grid_alloc_mapaxes_kw( const ecl_grid_type * grid ); + ecl_kw_type * ecl_grid_alloc_coord_kw( const ecl_grid_type * grid); + + bool ecl_grid_exists( const char * case_input ); + char * ecl_grid_alloc_case_filename( const char * case_input ); + + void ecl_grid_free(ecl_grid_type * ); + void ecl_grid_free__( void * arg ); + grid_dims_type ecl_grid_iget_dims( const ecl_grid_type * grid , int grid_nr); + void ecl_grid_get_dims(const ecl_grid_type * , int *, int * , int * , int *); + int ecl_grid_get_nz( const ecl_grid_type * grid ); + int ecl_grid_get_nx( const ecl_grid_type * grid ); + int ecl_grid_get_ny( const ecl_grid_type * grid ); + int ecl_grid_get_nactive( const ecl_grid_type * grid ); + int ecl_grid_get_nactive_fracture( const ecl_grid_type * grid ); + int ecl_grid_get_active_index(const ecl_grid_type * , int , int , int ); + void ecl_grid_summarize(const ecl_grid_type * ); + void ecl_grid_get_ijk1(const ecl_grid_type * , int global_index , int *, int * , int *); + void ecl_grid_get_ijk1A(const ecl_grid_type * , int active_index, int *, int * , int *); + void ecl_grid_get_ijk_from_active_index(const ecl_grid_type *, int , int *, int * , int * ); + + void ecl_grid_get_xyz3(const ecl_grid_type * , int , int , int , double * , double * , double *); + void ecl_grid_get_xyz1(const ecl_grid_type * grid , int global_index , double *xpos , double *ypos , double *zpos); + void ecl_grid_get_xyz1A(const ecl_grid_type * grid , int active_index , double *xpos , double *ypos , double *zpos); + + bool ecl_grid_get_xyz_inside1(const ecl_grid_type * grid , int global_index , double *xpos , double *ypos , double *zpos); + bool ecl_grid_get_xyz_inside3(const ecl_grid_type * grid , int i , int j , int k , double *xpos , double *ypos , double *zpos); + + int ecl_grid_get_global_size( const ecl_grid_type * ecl_grid ); + bool ecl_grid_compare(const ecl_grid_type * g1 , const ecl_grid_type * g2 , bool include_lgr, bool include_nnc , bool verbose); + int ecl_grid_get_active_size( const ecl_grid_type * ecl_grid ); + + double ecl_grid_get_bottom1(const ecl_grid_type * grid , int global_index); + double ecl_grid_get_bottom3(const ecl_grid_type * grid , int i, int j , int k); + double ecl_grid_get_bottom1A(const ecl_grid_type * grid , int active_index); + double ecl_grid_get_top1(const ecl_grid_type * grid , int global_index); + double ecl_grid_get_top3(const ecl_grid_type * grid , int i, int j , int k); + double ecl_grid_get_top1A(const ecl_grid_type * grid , int active_index); + double ecl_grid_get_top2(const ecl_grid_type * grid , int i, int j); + double ecl_grid_get_bottom2(const ecl_grid_type * grid , int i, int j); + int ecl_grid_locate_depth( const ecl_grid_type * grid , double depth , int i , int j ); + + void ecl_grid_alloc_blocking_variables(ecl_grid_type * , int ); + void ecl_grid_init_blocking(ecl_grid_type * ); + double ecl_grid_block_eval3d(ecl_grid_type * grid , int i, int j , int k ,block_function_ftype * blockf ); + int ecl_grid_get_block_count3d(const ecl_grid_type * ecl_grid , int i , int j, int k); + bool ecl_grid_block_value_3d(ecl_grid_type * , double , double ,double , double); + + bool ecl_grid_cell_invalid1(const ecl_grid_type * ecl_grid , int global_index); + bool ecl_grid_cell_invalid3(const ecl_grid_type * ecl_grid , int i , int j , int k); + double ecl_grid_cell_invalid1A(const ecl_grid_type * grid , int active_index); + + bool ecl_grid_cell_valid1(const ecl_grid_type * ecl_grid , int global_index); + bool ecl_grid_cell_valid3(const ecl_grid_type * ecl_grid , int i , int j , int k); + double ecl_grid_cell_valid1A(const ecl_grid_type * grid , int active_index); + + void ecl_grid_dump(const ecl_grid_type * grid , FILE * stream); + void ecl_grid_dump_ascii(ecl_grid_type * grid , bool active_only , FILE * stream); + void ecl_grid_dump_ascii_cell1(ecl_grid_type * grid , int global_index , FILE * stream, const double * offset); + void ecl_grid_dump_ascii_cell3(ecl_grid_type * grid , int i , int j , int k , FILE * stream , const double * offset); + + /* lgr related functions */ + const ecl_grid_type * ecl_grid_get_cell_lgr3(const ecl_grid_type * grid , int i, int j , int k); + const ecl_grid_type * ecl_grid_get_cell_lgr1A(const ecl_grid_type * grid , int active_index); + const ecl_grid_type * ecl_grid_get_cell_lgr1(const ecl_grid_type * grid , int global_index ); + int ecl_grid_get_num_lgr(const ecl_grid_type * main_grid ); + int ecl_grid_get_lgr_nr( const ecl_grid_type * ecl_grid ); + int ecl_grid_get_lgr_nr_from_name( const ecl_grid_type * grid , const char * name); + ecl_grid_type * ecl_grid_iget_lgr(const ecl_grid_type * main_grid , int lgr_index); + ecl_grid_type * ecl_grid_get_lgr_from_lgr_nr(const ecl_grid_type * main_grid, int lgr_nr); + ecl_grid_type * ecl_grid_get_lgr(const ecl_grid_type * main_grid, const char * __lgr_name); + bool ecl_grid_has_lgr(const ecl_grid_type * main_grid, const char * __lgr_name); + bool ecl_grid_has_lgr_nr(const ecl_grid_type * main_grid, int lgr_nr); + const char * ecl_grid_iget_lgr_name( const ecl_grid_type * ecl_grid , int lgr_index); + const char * ecl_grid_get_lgr_name( const ecl_grid_type * ecl_grid , int lgr_nr); + stringlist_type * ecl_grid_alloc_lgr_name_list(const ecl_grid_type * ecl_grid); + int ecl_grid_get_parent_cell1( const ecl_grid_type * grid , int global_index); + int ecl_grid_get_parent_cell3( const ecl_grid_type * grid , int i , int j , int k); + const ecl_grid_type * ecl_grid_get_global_grid( const ecl_grid_type * grid ); + bool ecl_grid_is_lgr( const ecl_grid_type * ecl_grid ); + + double ecl_grid_get_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k); + float ecl_grid_get_float_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k); + double ecl_grid_get_double_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k); + int ecl_grid_get_int_property(const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , int i , int j , int k); + + void ecl_grid_grdecl_fprintf_kw( const ecl_grid_type * ecl_grid , const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream , double double_default); + bool ecl_grid_test_lgr_consistency( const ecl_grid_type * ecl_grid ); + + void ecl_grid_fwrite_dims( const ecl_grid_type * grid , fortio_type * init_file, ert_ecl_unit_enum output_unit); + void ecl_grid_fwrite_depth( const ecl_grid_type * grid , fortio_type * init_file , ert_ecl_unit_enum ouput_unit); + + void ecl_grid_fwrite_EGRID( ecl_grid_type * grid , const char * filename, bool metric_output); + void ecl_grid_fwrite_EGRID2( ecl_grid_type * grid , const char * filename, ert_ecl_unit_enum output_unit); + + void ecl_grid_fwrite_GRID( const ecl_grid_type * grid , const char * filename); + void ecl_grid_fwrite_GRID2( const ecl_grid_type * grid , const char * filename, ert_ecl_unit_enum output_unit); + + void ecl_grid_fprintf_grdecl( ecl_grid_type * grid , FILE * stream ); + void ecl_grid_fprintf_grdecl2( ecl_grid_type * grid , FILE * stream , ert_ecl_unit_enum output_unit); + + int ecl_grid_zcorn_index__(int nx, int ny , int i, int j , int k , int c); + int ecl_grid_zcorn_index(const ecl_grid_type * grid , int i, int j , int k , int c); + ecl_grid_type * ecl_grid_alloc_EGRID(const char * grid_file, bool apply_mapaxes ); + ecl_grid_type * ecl_grid_alloc_GRID(const char * grid_file, bool apply_mapaxes ); + + float * ecl_grid_alloc_zcorn_data( const ecl_grid_type * grid ); + ecl_kw_type * ecl_grid_alloc_zcorn_kw( const ecl_grid_type * grid ); + int * ecl_grid_alloc_actnum_data( const ecl_grid_type * grid ); + ecl_kw_type * ecl_grid_alloc_actnum_kw( const ecl_grid_type * grid ); + ecl_kw_type * ecl_grid_alloc_hostnum_kw( const ecl_grid_type * grid ); + ecl_kw_type * ecl_grid_alloc_gridhead_kw( int nx, int ny , int nz , int grid_nr); + ecl_grid_type * ecl_grid_alloc_copy( const ecl_grid_type * src_grid ); + ecl_grid_type * ecl_grid_alloc_processed_copy( const ecl_grid_type * src_grid , const double * zcorn , const int * actnum); + + void ecl_grid_ri_export( const ecl_grid_type * ecl_grid , double * ri_points); + void ecl_grid_cell_ri_export( const ecl_grid_type * ecl_grid , int global_index , double * ri_points); + + bool ecl_grid_dual_grid( const ecl_grid_type * ecl_grid ); + int ecl_grid_get_num_nnc( const ecl_grid_type * grid ); + + bool ecl_grid_cell_regular3( const ecl_grid_type * ecl_grid, int i,int j,int k); + bool ecl_grid_cell_regular1( const ecl_grid_type * ecl_grid, int global_index); + + void ecl_grid_init_zcorn_data( const ecl_grid_type * grid , float * zcorn ); + void ecl_grid_init_zcorn_data_double( const ecl_grid_type * grid , double * zcorn ); + int ecl_grid_get_zcorn_size( const ecl_grid_type * grid ); + + void ecl_grid_init_coord_data( const ecl_grid_type * grid , float * coord ); + void ecl_grid_init_coord_data_double( const ecl_grid_type * grid , double * coord ); + int ecl_grid_get_coord_size( const ecl_grid_type * ecl_grid); + + void ecl_grid_init_actnum_data( const ecl_grid_type * grid , int * actnum ); + bool ecl_grid_use_mapaxes( const ecl_grid_type * grid ); + void ecl_grid_init_mapaxes_data_double( const ecl_grid_type * grid , double * mapaxes); + void ecl_grid_reset_actnum( ecl_grid_type * grid , const int * actnum ); + void ecl_grid_compressed_kw_copy( const ecl_grid_type * grid , ecl_kw_type * target_kw , const ecl_kw_type * src_kw); + void ecl_grid_global_kw_copy( const ecl_grid_type * grid , ecl_kw_type * target_kw , const ecl_kw_type * src_kw); + void ecl_grid_export_cell_corners1(const ecl_grid_type * grid, int global_index, double *x, double *y, double *z); + + ert_ecl_unit_enum ecl_grid_get_unit_system(const ecl_grid_type * grid); + void ecl_grid_export_index(const ecl_grid_type * grid, int * global_index, int * index_data , bool active_only); + void ecl_grid_export_data_as_int( int index_size, const int * global_index, const ecl_kw_type * kw, int * output); + void ecl_grid_export_data_as_double( int index_size, const int * data_index, const ecl_kw_type * kw, double * output); + void ecl_grid_export_volume( const ecl_grid_type * grid, int index_size, const int * global_index, double * output ); + void ecl_grid_export_position( const ecl_grid_type * grid, int index_size, const int * global_index, double * output); + void export_corners( const ecl_grid_type * grid, int index_size, const int * global_index, double * output); + + UTIL_IS_INSTANCE_HEADER( ecl_grid ); + UTIL_SAFE_CAST_HEADER( ecl_grid ); + +#ifdef __cplusplus +} +namespace ecl { + + ecl_grid_type * ecl_grid_alloc_GRDECL_data(int nx, + int ny, + int nz, + const double * zcorn, + const double * coord, + const int * actnum, + bool apply_mapaxes, + const float * mapaxes); + +} + +#ifdef __cplusplus +#endif + +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_cache.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_cache.h deleted file mode 100644 index 2aecabe56a..0000000000 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_cache.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_grid_cache.h' is part of ERT - Ensemble based - Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ERT_ECL_GRID_CACHE_H -#define ERT_ECL_GRID_CACHE_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - typedef struct ecl_grid_cache_struct ecl_grid_cache_type; - - - ecl_grid_cache_type * ecl_grid_cache_alloc( const ecl_grid_type * grid ); - int ecl_grid_cache_get_size( const ecl_grid_cache_type * grid_cache ); - int ecl_grid_cache_iget_global_index( const ecl_grid_cache_type * grid_cache , int active_index); - const int * ecl_grid_cache_get_global_index( const ecl_grid_cache_type * grid_cache ); - const double * ecl_grid_cache_get_xpos( const ecl_grid_cache_type * grid_cache ); - const double * ecl_grid_cache_get_ypos( const ecl_grid_cache_type * grid_cache ); - const double * ecl_grid_cache_get_zpos( const ecl_grid_cache_type * grid_cache ); - const double * ecl_grid_cache_get_volume( const ecl_grid_cache_type * grid_cache ); - void ecl_grid_cache_free( ecl_grid_cache_type * grid_cache ); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_cache.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_cache.hpp deleted file mode 100644 index 32ca2236ef..0000000000 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_cache.hpp +++ /dev/null @@ -1,19 +0,0 @@ -/* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#include diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.h index af173f58ef..7380cf820e 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.h @@ -1,37 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_grid_dims.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_GRID_DIMS_H -#define ERT_ECL_GRID_DIMS_H -#ifdef __cplusplus -extern "C" { -#endif +#include -#include - typedef struct ecl_grid_dims_struct ecl_grid_dims_type; - - ecl_grid_dims_type * ecl_grid_dims_alloc( const char * grid_file , const char * data_file); - void ecl_grid_dims_free( ecl_grid_dims_type * grid_dims ); - int ecl_grid_dims_get_num_grids( const ecl_grid_dims_type * grid_dims); - const grid_dims_type * ecl_grid_dims_iget_dims( const ecl_grid_dims_type * grid_dims , int grid_nr ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.hpp index d32e7d5d77..f67179badd 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_grid_dims.hpp @@ -1,19 +1,37 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_grid_dims.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_GRID_DIMS_H +#define ERT_ECL_GRID_DIMS_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + + typedef struct ecl_grid_dims_struct ecl_grid_dims_type; + + ecl_grid_dims_type * ecl_grid_dims_alloc( const char * grid_file , const char * data_file); + void ecl_grid_dims_free( ecl_grid_dims_type * grid_dims ); + int ecl_grid_dims_get_num_grids( const ecl_grid_dims_type * grid_dims); + const grid_dims_type * ecl_grid_dims_iget_dims( const ecl_grid_dims_type * grid_dims , int grid_nr ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.h index 771b0f7c91..f1f643f518 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.h @@ -1,39 +1,9 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ecl_init_file.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_INIT_FILE_H -#define ERT_ECL_INIT_FILE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include -#include -#include - - void ecl_init_file_fwrite_header( fortio_type * fortio , const ecl_grid_type * grid , const ecl_kw_type * poro , ert_ecl_unit_enum unit_system, int phases , time_t start_date); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.hpp index ef37a89689..8870ffe54a 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_init_file.hpp @@ -1,19 +1,39 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ecl_init_file.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_INIT_FILE_H +#define ERT_ECL_INIT_FILE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include + + void ecl_init_file_fwrite_header( fortio_type * fortio , const ecl_grid_type * grid , const ecl_kw_type * poro , ert_ecl_unit_enum unit_system, int phases , time_t start_date); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.h index c33f01274b..dcd2cba1e2 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.h @@ -1,47 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_io_config.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_IO_CONFIG_H -#define ERT_ECL_IO_CONFIG_H -#ifdef __cplusplus -extern "C" { -#endif +#include -typedef struct ecl_io_config_struct ecl_io_config_type; - -/* Modifiers */ -void ecl_io_config_set_formatted(ecl_io_config_type *, bool ); -void ecl_io_config_set_unified_restart(ecl_io_config_type *, bool ); -void ecl_io_config_set_unified_summary(ecl_io_config_type *, bool ); - - -/* Accesors */ -bool ecl_io_config_get_formatted(ecl_io_config_type *); -bool ecl_io_config_get_unified_restart(ecl_io_config_type *); -bool ecl_io_config_get_unified_summary(ecl_io_config_type *); - - -/* Allocater & destructor */ -ecl_io_config_type * ecl_io_config_alloc(bool ,bool ,bool); -void ecl_io_config_free(ecl_io_config_type * ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.hpp index fdbe583b39..d198d47ca6 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_io_config.hpp @@ -1,19 +1,47 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_io_config.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_IO_CONFIG_H +#define ERT_ECL_IO_CONFIG_H +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct ecl_io_config_struct ecl_io_config_type; + +/* Modifiers */ +void ecl_io_config_set_formatted(ecl_io_config_type *, bool ); +void ecl_io_config_set_unified_restart(ecl_io_config_type *, bool ); +void ecl_io_config_set_unified_summary(ecl_io_config_type *, bool ); + + +/* Accesors */ +bool ecl_io_config_get_formatted(ecl_io_config_type *); +bool ecl_io_config_get_unified_restart(ecl_io_config_type *); +bool ecl_io_config_get_unified_summary(ecl_io_config_type *); + + +/* Allocater & destructor */ +ecl_io_config_type * ecl_io_config_alloc(bool ,bool ,bool); +void ecl_io_config_free(ecl_io_config_type * ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.h index 21b22bd385..0dabfef752 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.h @@ -1,277 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_kw.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ERT_ECL_KW_H -#define ERT_ECL_KW_H -#ifdef __cplusplus -extern "C" { -#endif -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - - UTIL_IS_INSTANCE_HEADER(ecl_kw); - - - typedef struct ecl_kw_struct ecl_kw_type; - - typedef enum { - ECL_KW_READ_OK = 0, - ECL_KW_READ_FAIL = 1 - } ecl_read_status_enum; - -/* - The size of an ecl_kw instance is denoted with an integer. The - choice of int to store the size obviously limits the maximum size to - INT_MAX elements. This choice is an historical mistake - it should - probably have been size_t; however the ecl_kw datastructure is - tightly bound to the on-disk binary format supplied by Eclipse, and - there the number of elements is stored as a signed(?) 32 bit - integer - so using int for size does make some sense- + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#define ECL_KW_MAX_SIZE INT_MAX - -/* - Character data in ECLIPSE files comes as an array of fixed-length - string. Each of these strings is 8 characters long. The type name, - i.e. 'REAL', 'INTE', ... , come as 4 character strings. -*/ -#define ECL_KW_HEADER_DATA_SIZE ECL_STRING8_LENGTH + ECL_TYPE_LENGTH + 4 -#define ECL_KW_HEADER_FORTIO_SIZE ECL_KW_HEADER_DATA_SIZE + 8 - - - - int ecl_kw_first_different( const ecl_kw_type * kw1 , const ecl_kw_type * kw2 , int offset, double abs_epsilon , double rel_epsilon); - size_t ecl_kw_fortio_size( const ecl_kw_type * ecl_kw ); - void * ecl_kw_get_ptr(const ecl_kw_type *ecl_kw); - void ecl_kw_set_data_ptr(ecl_kw_type * ecl_kw , void * data); - void ecl_kw_fwrite_data(const ecl_kw_type *_ecl_kw , fortio_type *fortio); - bool ecl_kw_fread_realloc_data(ecl_kw_type *ecl_kw, fortio_type *fortio); - ecl_data_type ecl_kw_get_data_type(const ecl_kw_type *); - const char * ecl_kw_get_header8(const ecl_kw_type *); - const char * ecl_kw_get_header(const ecl_kw_type * ecl_kw ); - ecl_kw_type * ecl_kw_alloc_empty(void); - ecl_read_status_enum ecl_kw_fread_header(ecl_kw_type *, fortio_type *); - void ecl_kw_set_header_name(ecl_kw_type * , const char * ); - bool ecl_kw_fseek_kw(const char * , bool , bool , fortio_type *); - bool ecl_kw_fseek_last_kw(const char * , bool , fortio_type *); - void ecl_kw_inplace_update_file(const ecl_kw_type * , const char * , int ) ; - void ecl_kw_fskip(fortio_type *); - void ecl_kw_alloc_data(ecl_kw_type *); - void ecl_kw_alloc_double_data(ecl_kw_type * ecl_kw , double * values); - void ecl_kw_alloc_float_data(ecl_kw_type * ecl_kw , float * values); - bool ecl_kw_fread_realloc(ecl_kw_type *, fortio_type *); - void ecl_kw_fread(ecl_kw_type * , fortio_type * ); - ecl_kw_type * ecl_kw_fread_alloc(fortio_type *); - ecl_kw_type * ecl_kw_alloc_actnum(const ecl_kw_type * porv_kw, float porv_limit); - void ecl_kw_free_data(ecl_kw_type *); - void ecl_kw_fread_indexed_data(fortio_type * fortio, offset_type data_offset, ecl_data_type, int element_count, const int_vector_type* index_map, char* buffer); - void ecl_kw_free(ecl_kw_type *); - void ecl_kw_free__(void *); - ecl_kw_type * ecl_kw_alloc_copy (const ecl_kw_type *); - ecl_kw_type * ecl_kw_alloc_sub_copy( const ecl_kw_type * src, const char * new_kw , int offset , int count); - const void * ecl_kw_copyc__(const void *); - ecl_kw_type * ecl_kw_alloc_slice_copy( const ecl_kw_type * src, int index1, int index2, int stride); - void ecl_kw_resize( ecl_kw_type * ecl_kw, int new_size); - //void * ecl_kw_get_data_ref(const ecl_kw_type *); - void * ecl_kw_alloc_data_copy(const ecl_kw_type * ); - void ecl_kw_memcpy(ecl_kw_type *, const ecl_kw_type *); - void ecl_kw_get_memcpy_data(const ecl_kw_type *, void *); - void ecl_kw_get_memcpy_float_data(const ecl_kw_type *ecl_kw , float *target); - void ecl_kw_get_memcpy_double_data(const ecl_kw_type *ecl_kw , double *target); - void ecl_kw_get_memcpy_int_data(const ecl_kw_type *ecl_kw , int *target); - void ecl_kw_set_memcpy_data(ecl_kw_type * , const void *); - bool ecl_kw_fwrite(const ecl_kw_type *, fortio_type *); - void ecl_kw_iget(const ecl_kw_type *, int , void *); - void ecl_kw_iset(ecl_kw_type *ecl_kw , int i , const void *iptr); - void ecl_kw_iset_char_ptr( ecl_kw_type * ecl_kw , int index, const char * s); - void ecl_kw_iset_string8(ecl_kw_type * ecl_kw , int index , const char *s8); - void ecl_kw_iset_string_ptr(ecl_kw_type*, int, const char*); - const char * ecl_kw_iget_string_ptr(const ecl_kw_type *, int); - const char * ecl_kw_iget_char_ptr( const ecl_kw_type * ecl_kw , int i); - void * ecl_kw_iget_ptr(const ecl_kw_type *, int); - int ecl_kw_get_size(const ecl_kw_type *); - bool ecl_kw_ichar_eq(const ecl_kw_type *, int , const char *); - ecl_kw_type * ecl_kw_alloc( const char * header , int size , ecl_data_type ); - ecl_kw_type * ecl_kw_alloc_new(const char * , int , ecl_data_type , const void * ); - ecl_kw_type * ecl_kw_alloc_new_shared(const char * , int , ecl_data_type , void * ); - ecl_kw_type * ecl_kw_alloc_global_copy(const ecl_kw_type * src, const ecl_kw_type * actnum); - void ecl_kw_fwrite_param(const char * , bool , const char * , ecl_data_type , int , void * ); - void ecl_kw_fwrite_param_fortio(fortio_type *, const char * , ecl_data_type , int , void * ); - void ecl_kw_summarize(const ecl_kw_type * ecl_kw); - void ecl_kw_fread_double_param(const char * , bool , double *); - float ecl_kw_iget_as_float(const ecl_kw_type * ecl_kw , int i); - double ecl_kw_iget_as_double(const ecl_kw_type * ecl_kw , int i); - void ecl_kw_get_data_as_double(const ecl_kw_type *, double *); - void ecl_kw_get_data_as_float(const ecl_kw_type * ecl_kw , float * float_data); - bool ecl_kw_name_equal( const ecl_kw_type * ecl_kw , const char * name); - bool ecl_kw_header_eq(const ecl_kw_type *ecl_kw1 , const ecl_kw_type * ecl_kw2); - bool ecl_kw_equal(const ecl_kw_type *ecl_kw1, const ecl_kw_type *ecl_kw2); - bool ecl_kw_size_and_type_equal( const ecl_kw_type *ecl_kw1 , const ecl_kw_type * ecl_kw2 ); - bool ecl_kw_icmp_string( const ecl_kw_type * ecl_kw , int index, const char * other_string); - bool ecl_kw_numeric_equal(const ecl_kw_type *ecl_kw1, const ecl_kw_type *ecl_kw2 , double abs_diff , double rel_diff); - bool ecl_kw_block_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2 , int cmp_elements); - bool ecl_kw_data_equal( const ecl_kw_type * ecl_kw , const void * data); - bool ecl_kw_content_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2); - bool ecl_kw_fskip_data__( ecl_data_type, int, fortio_type *); - bool ecl_kw_fskip_data(ecl_kw_type *ecl_kw, fortio_type *fortio); - bool ecl_kw_fread_data(ecl_kw_type *ecl_kw, fortio_type *fortio); - void ecl_kw_fskip_header( fortio_type * fortio); - bool ecl_kw_size_and_numeric_type_equal( const ecl_kw_type * kw1, const ecl_kw_type * kw2); - bool ecl_kw_inplace_safe_div(ecl_kw_type * target_kw, const ecl_kw_type * divisor); - void ecl_kw_inplace_sqrt( ecl_kw_type * kw ); - - - bool ecl_kw_is_kw_file(fortio_type * fortio); - - int ecl_kw_element_sum_int( const ecl_kw_type * ecl_kw ); - double ecl_kw_element_sum_float( const ecl_kw_type * ecl_kw ); - void ecl_kw_inplace_inv(ecl_kw_type * my_kw); - void ecl_kw_element_sum(const ecl_kw_type * , void * ); - void ecl_kw_element_sum_indexed(const ecl_kw_type * ecl_kw , const int_vector_type * index_list, void * _sum); - void ecl_kw_max_min(const ecl_kw_type * , void * , void *); - void * ecl_kw_get_void_ptr(const ecl_kw_type * ecl_kw); - - ecl_kw_type * ecl_kw_buffer_alloc(buffer_type * buffer); - void ecl_kw_buffer_store(const ecl_kw_type * ecl_kw , buffer_type * buffer); - - void ecl_kw_fprintf_data( const ecl_kw_type * ecl_kw , const char * fmt , FILE * stream); - void ecl_kw_memcpy_data( ecl_kw_type * target , const ecl_kw_type * src); - - bool ecl_kw_assert_numeric( const ecl_kw_type * kw ); - bool ecl_kw_assert_binary( const ecl_kw_type * kw1, const ecl_kw_type * kw2); - - void ecl_kw_scalar_set_bool( ecl_kw_type * ecl_kw , bool bool_value); - void ecl_kw_scalar_set__(ecl_kw_type * ecl_kw , const void * value); - void ecl_kw_scalar_set_float_or_double( ecl_kw_type * ecl_kw , double value ); - - -#define ECL_KW_SCALAR_SET_TYPED_HEADER( ctype ) void ecl_kw_scalar_set_ ## ctype( ecl_kw_type * ecl_kw , ctype value); - ECL_KW_SCALAR_SET_TYPED_HEADER( int ) - ECL_KW_SCALAR_SET_TYPED_HEADER( float ) - ECL_KW_SCALAR_SET_TYPED_HEADER( double ) -#undef ECL_KW_SCALAR_SET_TYPED_HEADER - - ecl_kw_type * ecl_kw_alloc_scatter_copy( const ecl_kw_type * src_kw , int target_size , const int * mapping, void * def_value); - - void ecl_kw_inplace_add_squared(ecl_kw_type * target_kw, const ecl_kw_type * add_kw); - void ecl_kw_inplace_add( ecl_kw_type * target_kw , const ecl_kw_type * add_kw); - void ecl_kw_inplace_sub( ecl_kw_type * target_kw , const ecl_kw_type * sub_kw); - void ecl_kw_inplace_div( ecl_kw_type * target_kw , const ecl_kw_type * div_kw); - void ecl_kw_inplace_mul( ecl_kw_type * target_kw , const ecl_kw_type * mul_kw); - void ecl_kw_inplace_abs( ecl_kw_type * kw ); - - void ecl_kw_inplace_add_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * add_kw); - void ecl_kw_inplace_sub_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * sub_kw); - void ecl_kw_inplace_mul_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * mul_kw); - void ecl_kw_inplace_div_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * div_kw); - void ecl_kw_copy_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * src_kw); - - bool ecl_kw_assert_binary_numeric( const ecl_kw_type * kw1, const ecl_kw_type * kw2); -#define ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( ctype ) bool ecl_kw_assert_binary_ ## ctype( const ecl_kw_type * kw1 , const ecl_kw_type * kw2) - ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( int ); - ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( float ); - ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( double ); -#undef ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER - -#define ECL_KW_SCALE_TYPED_HEADER( ctype ) void ecl_kw_scale_ ## ctype (ecl_kw_type * ecl_kw , ctype scale_factor) - ECL_KW_SCALE_TYPED_HEADER( int ); - ECL_KW_SCALE_TYPED_HEADER( float ); - ECL_KW_SCALE_TYPED_HEADER( double ); -#undef ECL_KW_SCALE_TYPED_HEADER - void ecl_kw_scale_float_or_double( ecl_kw_type * ecl_kw , double scale_factor ); - - -#define ECL_KW_SHIFT_TYPED_HEADER( ctype ) void ecl_kw_shift_ ## ctype (ecl_kw_type * ecl_kw , ctype shift_factor) - ECL_KW_SHIFT_TYPED_HEADER( int ); - ECL_KW_SHIFT_TYPED_HEADER( float ); - ECL_KW_SHIFT_TYPED_HEADER( double ); -#undef ECL_KW_SHIFT_TYPED_HEADER - void ecl_kw_shift_float_or_double( ecl_kw_type * ecl_kw , double shift_value ); - - -#define ECL_KW_IGET_TYPED_HEADER(type) type ecl_kw_iget_ ## type(const ecl_kw_type * , int) - ECL_KW_IGET_TYPED_HEADER(double); - ECL_KW_IGET_TYPED_HEADER(float); - ECL_KW_IGET_TYPED_HEADER(int); -#undef ECL_KW_IGET_TYPED_HEADER - bool ecl_kw_iget_bool( const ecl_kw_type * ecl_kw , int i ); - - -#define ECL_KW_ISET_TYPED_HEADER(type) void ecl_kw_iset_ ## type(ecl_kw_type * , int , type ) - ECL_KW_ISET_TYPED_HEADER(double); - ECL_KW_ISET_TYPED_HEADER(float); - ECL_KW_ISET_TYPED_HEADER(int); -#undef ECL_KW_ISET_TYPED_HEADER - void ecl_kw_iset_bool( ecl_kw_type * ecl_kw , int i , bool bool_value); - - -#define ECL_KW_GET_TYPED_PTR_HEADER(type) type * ecl_kw_get_ ## type ## _ptr(const ecl_kw_type *) - ECL_KW_GET_TYPED_PTR_HEADER(double); - ECL_KW_GET_TYPED_PTR_HEADER(float); - ECL_KW_GET_TYPED_PTR_HEADER(int); - ECL_KW_GET_TYPED_PTR_HEADER(bool); -#undef ECL_KW_GET_TYPED_PTR_HEADER - - -#define ECL_KW_SET_INDEXED_HEADER(ctype ) void ecl_kw_set_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype value) - ECL_KW_SET_INDEXED_HEADER( double ); - ECL_KW_SET_INDEXED_HEADER( float ); - ECL_KW_SET_INDEXED_HEADER( int ); -#undef ECL_KW_SET_INDEXED_HEADER - - -#define ECL_KW_SHIFT_INDEXED_HEADER(ctype) void ecl_kw_shift_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype shift) - ECL_KW_SHIFT_INDEXED_HEADER( int ); - ECL_KW_SHIFT_INDEXED_HEADER( float ); - ECL_KW_SHIFT_INDEXED_HEADER( double ); -#undef ECL_KW_SHIFT_INDEXED_HEADER - - -#define ECL_KW_SCALE_INDEXED_HEADER(ctype) void ecl_kw_scale_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype scale) - ECL_KW_SCALE_INDEXED_HEADER( int ); - ECL_KW_SCALE_INDEXED_HEADER( float ); - ECL_KW_SCALE_INDEXED_HEADER( double ); -#undef ECL_KW_SCALE_INDEXED_HEADER - - -#define ECL_KW_MAX_MIN_HEADER( ctype ) void ecl_kw_max_min_ ## ctype( const ecl_kw_type * ecl_kw , ctype * _max , ctype * _min) - ECL_KW_MAX_MIN_HEADER( int ); - ECL_KW_MAX_MIN_HEADER( float ); - ECL_KW_MAX_MIN_HEADER( double ); -#undef ECL_KW_MAX_MIN_HEADER - - void ecl_kw_fix_uninitialized(ecl_kw_type * ecl_kw , int nx , int ny , int nz, const int * actnum); - - ecl_type_enum ecl_kw_get_type(const ecl_kw_type *); +#include -#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.hpp index f4ed8bfb4a..607c638af3 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw.hpp @@ -1,19 +1,277 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_kw.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ + +#ifndef ERT_ECL_KW_H +#define ERT_ECL_KW_H +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + + UTIL_IS_INSTANCE_HEADER(ecl_kw); + + + typedef struct ecl_kw_struct ecl_kw_type; + + typedef enum { + ECL_KW_READ_OK = 0, + ECL_KW_READ_FAIL = 1 + } ecl_read_status_enum; + +/* + The size of an ecl_kw instance is denoted with an integer. The + choice of int to store the size obviously limits the maximum size to + INT_MAX elements. This choice is an historical mistake - it should + probably have been size_t; however the ecl_kw datastructure is + tightly bound to the on-disk binary format supplied by Eclipse, and + there the number of elements is stored as a signed(?) 32 bit + integer - so using int for size does make some sense- */ -#include +#define ECL_KW_MAX_SIZE INT_MAX + +/* + Character data in ECLIPSE files comes as an array of fixed-length + string. Each of these strings is 8 characters long. The type name, + i.e. 'REAL', 'INTE', ... , come as 4 character strings. +*/ +#define ECL_KW_HEADER_DATA_SIZE ECL_STRING8_LENGTH + ECL_TYPE_LENGTH + 4 +#define ECL_KW_HEADER_FORTIO_SIZE ECL_KW_HEADER_DATA_SIZE + 8 + + + + int ecl_kw_first_different( const ecl_kw_type * kw1 , const ecl_kw_type * kw2 , int offset, double abs_epsilon , double rel_epsilon); + size_t ecl_kw_fortio_size( const ecl_kw_type * ecl_kw ); + void * ecl_kw_get_ptr(const ecl_kw_type *ecl_kw); + void ecl_kw_set_data_ptr(ecl_kw_type * ecl_kw , void * data); + void ecl_kw_fwrite_data(const ecl_kw_type *_ecl_kw , fortio_type *fortio); + bool ecl_kw_fread_realloc_data(ecl_kw_type *ecl_kw, fortio_type *fortio); + ecl_data_type ecl_kw_get_data_type(const ecl_kw_type *); + const char * ecl_kw_get_header8(const ecl_kw_type *); + const char * ecl_kw_get_header(const ecl_kw_type * ecl_kw ); + ecl_kw_type * ecl_kw_alloc_empty(void); + ecl_read_status_enum ecl_kw_fread_header(ecl_kw_type *, fortio_type *); + void ecl_kw_set_header_name(ecl_kw_type * , const char * ); + bool ecl_kw_fseek_kw(const char * , bool , bool , fortio_type *); + bool ecl_kw_fseek_last_kw(const char * , bool , fortio_type *); + void ecl_kw_inplace_update_file(const ecl_kw_type * , const char * , int ) ; + void ecl_kw_fskip(fortio_type *); + void ecl_kw_alloc_data(ecl_kw_type *); + void ecl_kw_alloc_double_data(ecl_kw_type * ecl_kw , double * values); + void ecl_kw_alloc_float_data(ecl_kw_type * ecl_kw , float * values); + bool ecl_kw_fread_realloc(ecl_kw_type *, fortio_type *); + void ecl_kw_fread(ecl_kw_type * , fortio_type * ); + ecl_kw_type * ecl_kw_fread_alloc(fortio_type *); + ecl_kw_type * ecl_kw_alloc_actnum(const ecl_kw_type * porv_kw, float porv_limit); + void ecl_kw_free_data(ecl_kw_type *); + void ecl_kw_fread_indexed_data(fortio_type * fortio, offset_type data_offset, ecl_data_type, int element_count, const int_vector_type* index_map, char* buffer); + void ecl_kw_free(ecl_kw_type *); + void ecl_kw_free__(void *); + ecl_kw_type * ecl_kw_alloc_copy (const ecl_kw_type *); + ecl_kw_type * ecl_kw_alloc_sub_copy( const ecl_kw_type * src, const char * new_kw , int offset , int count); + const void * ecl_kw_copyc__(const void *); + ecl_kw_type * ecl_kw_alloc_slice_copy( const ecl_kw_type * src, int index1, int index2, int stride); + void ecl_kw_resize( ecl_kw_type * ecl_kw, int new_size); + //void * ecl_kw_get_data_ref(const ecl_kw_type *); + void * ecl_kw_alloc_data_copy(const ecl_kw_type * ); + void ecl_kw_memcpy(ecl_kw_type *, const ecl_kw_type *); + void ecl_kw_get_memcpy_data(const ecl_kw_type *, void *); + void ecl_kw_get_memcpy_float_data(const ecl_kw_type *ecl_kw , float *target); + void ecl_kw_get_memcpy_double_data(const ecl_kw_type *ecl_kw , double *target); + void ecl_kw_get_memcpy_int_data(const ecl_kw_type *ecl_kw , int *target); + void ecl_kw_set_memcpy_data(ecl_kw_type * , const void *); + bool ecl_kw_fwrite(const ecl_kw_type *, fortio_type *); + void ecl_kw_iget(const ecl_kw_type *, int , void *); + void ecl_kw_iset(ecl_kw_type *ecl_kw , int i , const void *iptr); + void ecl_kw_iset_char_ptr( ecl_kw_type * ecl_kw , int index, const char * s); + void ecl_kw_iset_string8(ecl_kw_type * ecl_kw , int index , const char *s8); + void ecl_kw_iset_string_ptr(ecl_kw_type*, int, const char*); + const char * ecl_kw_iget_string_ptr(const ecl_kw_type *, int); + const char * ecl_kw_iget_char_ptr( const ecl_kw_type * ecl_kw , int i); + void * ecl_kw_iget_ptr(const ecl_kw_type *, int); + int ecl_kw_get_size(const ecl_kw_type *); + bool ecl_kw_ichar_eq(const ecl_kw_type *, int , const char *); + ecl_kw_type * ecl_kw_alloc( const char * header , int size , ecl_data_type ); + ecl_kw_type * ecl_kw_alloc_new(const char * , int , ecl_data_type , const void * ); + ecl_kw_type * ecl_kw_alloc_new_shared(const char * , int , ecl_data_type , void * ); + ecl_kw_type * ecl_kw_alloc_global_copy(const ecl_kw_type * src, const ecl_kw_type * actnum); + void ecl_kw_fwrite_param(const char * , bool , const char * , ecl_data_type , int , void * ); + void ecl_kw_fwrite_param_fortio(fortio_type *, const char * , ecl_data_type , int , void * ); + void ecl_kw_summarize(const ecl_kw_type * ecl_kw); + void ecl_kw_fread_double_param(const char * , bool , double *); + float ecl_kw_iget_as_float(const ecl_kw_type * ecl_kw , int i); + double ecl_kw_iget_as_double(const ecl_kw_type * ecl_kw , int i); + void ecl_kw_get_data_as_double(const ecl_kw_type *, double *); + void ecl_kw_get_data_as_float(const ecl_kw_type * ecl_kw , float * float_data); + bool ecl_kw_name_equal( const ecl_kw_type * ecl_kw , const char * name); + bool ecl_kw_header_eq(const ecl_kw_type *ecl_kw1 , const ecl_kw_type * ecl_kw2); + bool ecl_kw_equal(const ecl_kw_type *ecl_kw1, const ecl_kw_type *ecl_kw2); + bool ecl_kw_size_and_type_equal( const ecl_kw_type *ecl_kw1 , const ecl_kw_type * ecl_kw2 ); + bool ecl_kw_icmp_string( const ecl_kw_type * ecl_kw , int index, const char * other_string); + bool ecl_kw_numeric_equal(const ecl_kw_type *ecl_kw1, const ecl_kw_type *ecl_kw2 , double abs_diff , double rel_diff); + bool ecl_kw_block_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2 , int cmp_elements); + bool ecl_kw_data_equal( const ecl_kw_type * ecl_kw , const void * data); + bool ecl_kw_content_equal( const ecl_kw_type * ecl_kw1 , const ecl_kw_type * ecl_kw2); + bool ecl_kw_fskip_data__( ecl_data_type, int, fortio_type *); + bool ecl_kw_fskip_data(ecl_kw_type *ecl_kw, fortio_type *fortio); + bool ecl_kw_fread_data(ecl_kw_type *ecl_kw, fortio_type *fortio); + void ecl_kw_fskip_header( fortio_type * fortio); + bool ecl_kw_size_and_numeric_type_equal( const ecl_kw_type * kw1, const ecl_kw_type * kw2); + bool ecl_kw_inplace_safe_div(ecl_kw_type * target_kw, const ecl_kw_type * divisor); + void ecl_kw_inplace_sqrt( ecl_kw_type * kw ); + + + bool ecl_kw_is_kw_file(fortio_type * fortio); + + int ecl_kw_element_sum_int( const ecl_kw_type * ecl_kw ); + double ecl_kw_element_sum_float( const ecl_kw_type * ecl_kw ); + void ecl_kw_inplace_inv(ecl_kw_type * my_kw); + void ecl_kw_element_sum(const ecl_kw_type * , void * ); + void ecl_kw_element_sum_indexed(const ecl_kw_type * ecl_kw , const int_vector_type * index_list, void * _sum); + void ecl_kw_max_min(const ecl_kw_type * , void * , void *); + void * ecl_kw_get_void_ptr(const ecl_kw_type * ecl_kw); + + ecl_kw_type * ecl_kw_buffer_alloc(buffer_type * buffer); + void ecl_kw_buffer_store(const ecl_kw_type * ecl_kw , buffer_type * buffer); + + void ecl_kw_fprintf_data( const ecl_kw_type * ecl_kw , const char * fmt , FILE * stream); + void ecl_kw_memcpy_data( ecl_kw_type * target , const ecl_kw_type * src); + + bool ecl_kw_assert_numeric( const ecl_kw_type * kw ); + bool ecl_kw_assert_binary( const ecl_kw_type * kw1, const ecl_kw_type * kw2); + + void ecl_kw_scalar_set_bool( ecl_kw_type * ecl_kw , bool bool_value); + void ecl_kw_scalar_set__(ecl_kw_type * ecl_kw , const void * value); + void ecl_kw_scalar_set_float_or_double( ecl_kw_type * ecl_kw , double value ); + + +#define ECL_KW_SCALAR_SET_TYPED_HEADER( ctype ) void ecl_kw_scalar_set_ ## ctype( ecl_kw_type * ecl_kw , ctype value); + ECL_KW_SCALAR_SET_TYPED_HEADER( int ) + ECL_KW_SCALAR_SET_TYPED_HEADER( float ) + ECL_KW_SCALAR_SET_TYPED_HEADER( double ) +#undef ECL_KW_SCALAR_SET_TYPED_HEADER + + ecl_kw_type * ecl_kw_alloc_scatter_copy( const ecl_kw_type * src_kw , int target_size , const int * mapping, void * def_value); + + void ecl_kw_inplace_add_squared(ecl_kw_type * target_kw, const ecl_kw_type * add_kw); + void ecl_kw_inplace_add( ecl_kw_type * target_kw , const ecl_kw_type * add_kw); + void ecl_kw_inplace_sub( ecl_kw_type * target_kw , const ecl_kw_type * sub_kw); + void ecl_kw_inplace_div( ecl_kw_type * target_kw , const ecl_kw_type * div_kw); + void ecl_kw_inplace_mul( ecl_kw_type * target_kw , const ecl_kw_type * mul_kw); + void ecl_kw_inplace_abs( ecl_kw_type * kw ); + + void ecl_kw_inplace_add_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * add_kw); + void ecl_kw_inplace_sub_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * sub_kw); + void ecl_kw_inplace_mul_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * mul_kw); + void ecl_kw_inplace_div_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * div_kw); + void ecl_kw_copy_indexed( ecl_kw_type * target_kw , const int_vector_type * index_set , const ecl_kw_type * src_kw); + + bool ecl_kw_assert_binary_numeric( const ecl_kw_type * kw1, const ecl_kw_type * kw2); +#define ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( ctype ) bool ecl_kw_assert_binary_ ## ctype( const ecl_kw_type * kw1 , const ecl_kw_type * kw2) + ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( int ); + ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( float ); + ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER( double ); +#undef ECL_KW_ASSERT_TYPED_BINARY_OP_HEADER + +#define ECL_KW_SCALE_TYPED_HEADER( ctype ) void ecl_kw_scale_ ## ctype (ecl_kw_type * ecl_kw , ctype scale_factor) + ECL_KW_SCALE_TYPED_HEADER( int ); + ECL_KW_SCALE_TYPED_HEADER( float ); + ECL_KW_SCALE_TYPED_HEADER( double ); +#undef ECL_KW_SCALE_TYPED_HEADER + void ecl_kw_scale_float_or_double( ecl_kw_type * ecl_kw , double scale_factor ); + + +#define ECL_KW_SHIFT_TYPED_HEADER( ctype ) void ecl_kw_shift_ ## ctype (ecl_kw_type * ecl_kw , ctype shift_factor) + ECL_KW_SHIFT_TYPED_HEADER( int ); + ECL_KW_SHIFT_TYPED_HEADER( float ); + ECL_KW_SHIFT_TYPED_HEADER( double ); +#undef ECL_KW_SHIFT_TYPED_HEADER + void ecl_kw_shift_float_or_double( ecl_kw_type * ecl_kw , double shift_value ); + + +#define ECL_KW_IGET_TYPED_HEADER(type) type ecl_kw_iget_ ## type(const ecl_kw_type * , int) + ECL_KW_IGET_TYPED_HEADER(double); + ECL_KW_IGET_TYPED_HEADER(float); + ECL_KW_IGET_TYPED_HEADER(int); +#undef ECL_KW_IGET_TYPED_HEADER + bool ecl_kw_iget_bool( const ecl_kw_type * ecl_kw , int i ); + + +#define ECL_KW_ISET_TYPED_HEADER(type) void ecl_kw_iset_ ## type(ecl_kw_type * , int , type ) + ECL_KW_ISET_TYPED_HEADER(double); + ECL_KW_ISET_TYPED_HEADER(float); + ECL_KW_ISET_TYPED_HEADER(int); +#undef ECL_KW_ISET_TYPED_HEADER + void ecl_kw_iset_bool( ecl_kw_type * ecl_kw , int i , bool bool_value); + + +#define ECL_KW_GET_TYPED_PTR_HEADER(type) type * ecl_kw_get_ ## type ## _ptr(const ecl_kw_type *) + ECL_KW_GET_TYPED_PTR_HEADER(double); + ECL_KW_GET_TYPED_PTR_HEADER(float); + ECL_KW_GET_TYPED_PTR_HEADER(int); + ECL_KW_GET_TYPED_PTR_HEADER(bool); +#undef ECL_KW_GET_TYPED_PTR_HEADER + + +#define ECL_KW_SET_INDEXED_HEADER(ctype ) void ecl_kw_set_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype value) + ECL_KW_SET_INDEXED_HEADER( double ); + ECL_KW_SET_INDEXED_HEADER( float ); + ECL_KW_SET_INDEXED_HEADER( int ); +#undef ECL_KW_SET_INDEXED_HEADER + + +#define ECL_KW_SHIFT_INDEXED_HEADER(ctype) void ecl_kw_shift_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype shift) + ECL_KW_SHIFT_INDEXED_HEADER( int ); + ECL_KW_SHIFT_INDEXED_HEADER( float ); + ECL_KW_SHIFT_INDEXED_HEADER( double ); +#undef ECL_KW_SHIFT_INDEXED_HEADER + + +#define ECL_KW_SCALE_INDEXED_HEADER(ctype) void ecl_kw_scale_indexed_ ## ctype( ecl_kw_type * ecl_kw, const int_vector_type * index_list , ctype scale) + ECL_KW_SCALE_INDEXED_HEADER( int ); + ECL_KW_SCALE_INDEXED_HEADER( float ); + ECL_KW_SCALE_INDEXED_HEADER( double ); +#undef ECL_KW_SCALE_INDEXED_HEADER + + +#define ECL_KW_MAX_MIN_HEADER( ctype ) void ecl_kw_max_min_ ## ctype( const ecl_kw_type * ecl_kw , ctype * _max , ctype * _min) + ECL_KW_MAX_MIN_HEADER( int ); + ECL_KW_MAX_MIN_HEADER( float ); + ECL_KW_MAX_MIN_HEADER( double ); +#undef ECL_KW_MAX_MIN_HEADER + + void ecl_kw_fix_uninitialized(ecl_kw_type * ecl_kw , int nx , int ny , int nz, const int * actnum); + + ecl_type_enum ecl_kw_get_type(const ecl_kw_type *); + +#include + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.h index 6c5afabcb1..b1ebc75737 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.h @@ -1,57 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_kw_grdecl.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -/* - This header does not define datatypes; just a couple of functions. It should - be included from the ecl_kw.h header, so applications do not need to include this - header explicitly. -*/ - -#ifndef ERT_ECL_KW_GRDECL_H -#define ERT_ECL_KW_GRDECL_H -#ifdef __cplusplus -extern "C" { -#endif - - - - bool ecl_kw_grdecl_fseek_kw(const char * , bool , FILE * ); - - ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_dynamic__( FILE * stream , const char * kw , bool strict , ecl_data_type ); - ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_dynamic( FILE * stream , const char * kw , ecl_data_type); - - ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_data__(FILE * stream , bool strict , int size, ecl_data_type data_type ); - ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_data( FILE * stream , int size , ecl_data_type data_type); - - ecl_kw_type * ecl_kw_fscanf_alloc_grdecl__(FILE * stream, const char * kw , bool strict , int size, ecl_data_type data_type); - ecl_kw_type * ecl_kw_fscanf_alloc_grdecl(FILE * stream , const char * kw, int size, ecl_data_type data_type); - - ecl_kw_type * ecl_kw_fscanf_alloc_current_grdecl__( FILE * stream , bool strict , ecl_data_type data_type); - ecl_kw_type * ecl_kw_fscanf_alloc_current_grdecl( FILE * stream , ecl_data_type data_type); - - bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ); - char * ecl_kw_grdecl_alloc_next_header( FILE * stream ); - - void ecl_kw_fprintf_grdecl(const ecl_kw_type * ecl_kw , FILE * stream); - void ecl_kw_fprintf_grdecl__(const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.hpp index eb27171f48..2113c18cd9 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_grdecl.hpp @@ -1,20 +1,57 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_kw_grdecl.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ +/* + This header does not define datatypes; just a couple of functions. It should + be included from the ecl_kw.h header, so applications do not need to include this + header explicitly. +*/ + +#ifndef ERT_ECL_KW_GRDECL_H +#define ERT_ECL_KW_GRDECL_H +#ifdef __cplusplus +extern "C" { +#endif + + + + bool ecl_kw_grdecl_fseek_kw(const char * , bool , FILE * ); + + ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_dynamic__( FILE * stream , const char * kw , bool strict , ecl_data_type ); + ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_dynamic( FILE * stream , const char * kw , ecl_data_type); + + ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_data__(FILE * stream , bool strict , int size, ecl_data_type data_type ); + ecl_kw_type * ecl_kw_fscanf_alloc_grdecl_data( FILE * stream , int size , ecl_data_type data_type); + + ecl_kw_type * ecl_kw_fscanf_alloc_grdecl__(FILE * stream, const char * kw , bool strict , int size, ecl_data_type data_type); + ecl_kw_type * ecl_kw_fscanf_alloc_grdecl(FILE * stream , const char * kw, int size, ecl_data_type data_type); + + ecl_kw_type * ecl_kw_fscanf_alloc_current_grdecl__( FILE * stream , bool strict , ecl_data_type data_type); + ecl_kw_type * ecl_kw_fscanf_alloc_current_grdecl( FILE * stream , ecl_data_type data_type); + + bool ecl_kw_grdecl_fseek_next_kw( FILE * stream ); + char * ecl_kw_grdecl_alloc_next_header( FILE * stream ); + + void ecl_kw_fprintf_grdecl(const ecl_kw_type * ecl_kw , FILE * stream); + void ecl_kw_fprintf_grdecl__(const ecl_kw_type * ecl_kw , const char * special_header , FILE * stream); + +#ifdef __cplusplus +} +#endif +#endif -#include diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_magic.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_magic.h index 8c0f50db65..4197a5c318 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_magic.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_magic.h @@ -1,645 +1,9 @@ -#ifndef ERT_ECL_KW_MAGIC_H -#define ERT_ECL_KW_MAGIC_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - This header file contains names and indices of ECLIPSE keywords - which have special significance in various files. Observe that many - of the keywords like e.g. INTEHEAD occur in many different file - types, with partly overlapping layout and values. - */ - -/*****************************************************************/ -/* INIT files: */ -/*****************************************************************/ - -#define PORO_KW "PORO" -#define PORV_KW "PORV" -#define AQUIFER_KW "AQUIFERN" -#define INTEHEAD_KW "INTEHEAD" -#define LOGIHEAD_KW "LOGIHEAD" -#define DOUBHEAD_KW "DOUBHEAD" -#define RPORV_KW "RPORV" -#define PORV_KW "PORV" -#define PORMOD_KW "PORV_MOD" - -#define PVTNUM_KW "PVTNUM" -#define LGRHEADI_KW "LGRHEADI" -#define LGRHEADI_LGR_NR_INDEX 0 -#define LGRJOIN_KW "LGRJOIN" - - -/* - The table in the INIT file are organized with one large data keyword - 'TAB' and one keyword 'TABDIMS' which describe the layout of the - data in the TAB keyword. - - For each of the tables there 'TABDIMS_xxx_OFFSET_ITEM' which points - to an element in the 'TABDIMS' vector which contains the starting - address of table 'xxx' in the 'TAB' keyword, then there are one or - several integer values describing how many values/tables there - are. In addition there is an assumed number of columns which is not - explicitly stored in the TABDIMS keyword. - - The input format is quite flexible with respect to the size of the - individual tables and subtables, but the representation in the INIT - file is based on fixed length columns and equal sized tables, where - all inactive elements have the default value 2e20. - - Assume the following PVTO input: - - - PVTO - 1.55203 1.00000 1.15907572 0.64345 - 25.00000 1.15319788 0.67619 - 50.00000 1.14759314 0.70959 / - - 28.04570 25.00000 1.17415042 0.63294 - 50.00000 1.16792401 0.66638 - 75.00000 1.16222385 0.69918 - 100.00000 1.15212320 0.76297 / - - 35.62113 50.00000 1.19208190 0.61538 - 75.00000 1.18568689 0.64790 - 100.00000 1.17982339 0.67985 - 125.00000 1.17441865 0.71127 - 150.00000 1.16941365 0.74217 / - - / - 20.66588 1.00000 1.15642614 0.57010 - 25.00000 1.15051027 0.59831 - 50.00000 1.14487540 0.62703 / - - 27.65815 25.00000 1.17402576 0.56928 - 50.00000 1.16771923 0.59875 - 75.00000 1.16195281 0.62760 - 100.00000 1.15665041 0.65588 - / - -This is the PVTO table, and it is described by the constants -TABDIMS_IBPVTO_OFFSET_ITEM, TABDIMS_JBPVTO_OFFSET_ITEM, -TABDIMS_NRPVTO_ITEM, TABDIMS_NPPVTO_ITEM and TABDIMS_NTPVTO_ITEM. Observe the following: - - 1. There are 3 GOR values in the first table and 2 in the second, - this is the number of composition nodes - - TABDIMS_NRPVTO_ITEM. Since there are 3 in the first table and 2 in - the second the value of TABDIMS[ TABDIMS_NRPVTO_ITEM ] >= 3. - - 2. The GOR node values (1.55203, 28.04570, 35.62113) and (20.66588, - 27.65815) are stored separately at offset - TABDIMS[ TABDIMS_JBPVTO_OFFSET_ITEM ] in the TAB array. - - 3. The length of the longest column is 5 elements so the value of - TABDIMS[ TABDIMS_NPPVTO_ITEM ] >= 5. - - 4. The actual table data starts at offset TABDIMS[ - TABDIMS_IBPVTO_ITEM] in the TAB table. - -When packing the actual data into the TAB array the indices are -running as row,GOR,table,column - with row fastest. All in all the -linear vector for this PVTO table will look like: - - 1.00000 \ \ \ \ - 25.00000 | | | | - 50.00000 | NPPVTO = 5 | | | - * | | | | - * | | | | ------------/ | | | - 25.00000 | | | - 50.00000 | | | - 75.00000 | NRPVTO = 3 | | -100.00000 | | | - * | | | ------------ | | | - 50.00000 | | | - 75.00000 | | | -100.00000 | | | -125.00000 | | | -150.00000 | | | -=========== / | NTPVTO = 2 | - 1.00000 | | - 25.00000 | | - 50.00000 | | - * | | - * | | Three columns - ------------ | | (not in TABDIMS) - 25.00000 | | - 50.00000 | | - 75.00000 | | -100.00000 | | - * | | ------------ | | -* | | -* | | -* | | -* | | -* | | -@@@@@@@@@@@ / | -1.15907572 | -1.15319788 | -1.14759314 | - * | - * | ------------ | -1.17415042 | -1.16792401 | -1.16222385 | -1.15212320 | - * | ------------ | -1.19208190 | -1.18568689 | -1.17982339 | -1.17441865 | -1.16941365 | -=========== | -1.15642614 | -1.15051027 | -1.14487540 | - * | - * | ------------ | -1.17402576 | -1.16771923 | -1.16195281 | -1.15665041 | - * | ------------ | -* | -* | -* | -* | -* | -@@@@@@@@@@@ | -0.64345 | -0.67619 | -0.70959 | - * | - * | ------------ | -0.63294 | -0.66638 | -0.69918 | -0.76297 | - * | ------------ | -0.61538 | -0.64790 | -0.67985 | -0.71127 | -0.74217 | -=========== | -0.57010 | -0.59831 | -0.62703 | - * | - * | ------------ | -0.56928 | -0.59875 | -0.62760 | -0.65588 | - * | ------------ | -* | -* | -* | -* | -* | - / - -In this vector representation the different composition subtable -columns are separated by '----', the different main tables are -separated by '======' and the columns are separated by '@@@@'. Default -values (2e20) are denoted with '*'. - -*/ -#define TABDIMS_SIZE 100 - -#define TABDIMS_TAB_SIZE_ITEM 0 - -#define TABDIMS_IBROCK_OFFSET_ITEM 1 -#define TABDIMS_NTROCK_ITEM 2 - -#define TABDIMS_IBROCC_OFFSET_ITEM 3 -#define TABDIMS_NPROCC_ITEM 4 - -#define TABDIMS_IBPVTO_OFFSET_ITEM 6 -#define TABDIMS_JBPVTO_OFFSET_ITEM 7 -#define TABDIMS_NRPVTO_ITEM 8 -#define TABDIMS_NPPVTO_ITEM 9 -#define TABDIMS_NTPVTO_ITEM 10 - -#define TABDIMS_IBPVTW_OFFSET_ITEM 11 -#define TABDIMS_NTPVTW_ITEM 12 - -#define TABDIMS_IBPVTG_OFFSET_ITEM 13 -#define TABDIMS_JBPVTG_OFFSET_ITEM 14 -#define TABDIMS_NRPVTG_ITEM 15 -#define TABDIMS_NPPVTG_ITEM 16 -#define TABDIMS_NTPVTG_ITEM 17 - -#define TABDIMS_IBDENS_OFFSET_ITEM 18 -#define TABDIMS_NTDENS_ITEM 19 - -#define TABDIMS_IBSWFN_OFFSET_ITEM 20 -#define TABDIMS_NSSWFN_ITEM 21 -#define TABDIMS_NTSWFN_ITEM 22 - -#define TABDIMS_IBSGFN_OFFSET_ITEM 23 -#define TABDIMS_NSSGFN_ITEM 24 -#define TABDIMS_NTSGFN_ITEM 25 - -#define TABDIMS_IBSOFN_OFFSET_ITEM 26 -#define TABDIMS_IBSWCO_OFFSET_ITEM 27 -#define TABDIMS_NSSOFN_ITEM 28 -#define TABDIMS_NTSOFN_ITEM 29 - -#define TABDIMS_IBVETB_OFFSET_ITEM 40 -#define TABDIMS_NSVETB_ITEM 41 -#define TABDIMS_NTVETB_ITEM 42 - -#define TABDIMS_IBTHPR_OFFSET_ITEM 43 -#define TABDIMS_IBSLIM_ITEM 44 -#define TABDIMS_NSENDP_ITEM 45 -#define TABDIMS_NTENDP_ITEM 46 - -#define TABDIMS_IBRTEM_OFFSET_ITEM 47 -#define TABDIMS_IBCTOL_ITEM 48 - -#define TABDIMS_IBLANG_OFFSET_ITEM 50 // LANGMUIR Table -#define TABDIMS_NCLANG_ITEM 51 // LANGMUIR Table -#define TABDIMS_NSLANG_ITEM 52 // LANGMUIR Table -#define TABDIMS_NTLANG_ITEM 53 // LANGMUIR Table - -#define TABDIMS_IBLNG2_OFFSET_ITEM 54 // LANGSOLV Table -#define TABDIMS_IBCADP_OFFSET_ITEM 55 // COALPP Table -#define TABDIMS_IBCADS_OFFSET_ITEM 56 // COALADS Table -#define TABDIMS_IBROCP_OFFSET_ITEM 57 // ROCKPAMA Table -#define TABDIMS_NTRPMA_ITEM 58 // ROCKPAMA Table - - /* - Observe that many of the elements in the INTEHEAD keyword is shared - between the restart and init files. The ones listed below here are - in both the INIT and the restart files. In addition the restart - files have many well related items which are only in the restart - files. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ - -#define INTEHEAD_UNIT_INDEX 2 -#define INTEHEAD_NX_INDEX 8 -#define INTEHEAD_NY_INDEX 9 -#define INTEHEAD_NZ_INDEX 10 -#define INTEHEAD_NACTIVE_INDEX 11 -#define INTEHEAD_PHASE_INDEX 14 -#define INTEHEAD_DAY_INDEX 64 -#define INTEHEAD_MONTH_INDEX 65 -#define INTEHEAD_YEAR_INDEX 66 -#define INTEHEAD_TIMESTEP_INDEX 67 -#define INTEHEAD_REPORT_STEP 68 -#define INTEHEAD_IPROG_INDEX 94 - -// The value seems to be: report_step - 1; might be previous? -#define INTEHEAD_REPORT_INDEX 219 - - -#define INTEHEAD_METRIC_VALUE 1 -#define INTEHEAD_ECLIPSE100_VALUE 100 -#define INTEHEAD_ECLIPSE300_VALUE 300 -#define INTEHEAD_ECLIPSE300THERMAL_VALUE 500 -#define INTEHEAD_INTERSECT_VALUE 700 -#define INTEHEAD_FRONTSIM_VALUE 800 - -#define INTEHEAD_INIT_SIZE 95 -#define INTEHEAD_RESTART_SIZE 180 - -#define LOGIHEAD_ECLIPSE300_RADIAL_INDEX 3 -#define LOGIHEAD_ECLIPSE100_RADIAL_INDEX 4 -#define LOGIHEAD_DUALP_INDEX 14 -#define LOGIHEAD_INIT_SIZE 80 -#define LOGIHEAD_RESTART_SIZE 15 - - -#define LOGIHEAD_RS_INDEX 0 -#define LOGIHEAD_RV_INDEX 1 -#define LOGIHEAD_DIR_RELPERM_INDEX 2 -/*-----------------------------------------------------------------*/ -#define LOGIHEAD_REV_RELPERM100_INDEX 3 /* The indices for reversible relperm and */ -#define LOGIHEAD_RADIAL100_INDEX 4 /* use of radial grids is interchanged between */ -#define LOGIHEAD_REV_RELPERM300_INDEX 4 /* ECLIPSE100 and ECLIPSE300. */ -#define LOGIHEAD_RADIAL300_INDEX 3 -/*-----------------------------------------------------------------*/ -#define LOGIHEAD_HYSTERISIS_INDEX 6 -#define LOGIHEAD_DUALP_INDEX 14 -#define LOGIHEAD_ENDPOINT_SCALING_INDEX 16 -#define LOGIHEAD_DIR_ENDPOINT_SCALING_INDEX 17 -#define LOGIHEAD_REV_ENDPOINT_SCALING_INDEX 18 -#define LOGIHEAD_ALT_ENDPOINT_SCALING_INDEX 19 -#define LOGIHEAD_MISC_DISPLACEMENT_INDEX 35 -#define LOGIHEAD_CONSTANT_OILCOMPR_INDEX (39-1) /* Constant oil compressibility (PVCDO)? */ -#define LOGIHEAD_SCALE_WATER_PC_AT_MAX_SAT_INDEX 55 -#define LOGIHEAD_SCALE_GAS_PC_AT_MAX_SAT_INDEX 56 - - - - -#define DOUBHEAD_INIT_SIZE 1 -#define DOUBHEAD_RESTART_SIZE 1 - - -/*****************************************************************/ -/* RESTART files: */ -/*****************************************************************/ - -#define SEQNUM_KW "SEQNUM" /* Contains the report step as the only data; not - present in non-unified files, where the report - step must be inferred from the filename. */ -#define STARTSOL_KW "STARTSOL" -#define ENDSOL_KW "ENDSOL" - -#define XWEL_KW "XWEL" -#define IWEL_KW "IWEL" -#define ZWEL_KW "ZWEL" -#define ICON_KW "ICON" -#define SCON_KW "SCON" -#define XCON_KW "XCON" -#define ISEG_KW "ISEG" -#define RSEG_KW "RSEG" - -#define ECLIPSE100_OIL_DEN_KW "OIL_DEN" -#define ECLIPSE100_GAS_DEN_KW "GAS_DEN" -#define ECLIPSE100_WATER_DEN_KW "WAT_DEN" - -#define ECLIPSE300_OIL_DEN_KW "DENO" -#define ECLIPSE300_GAS_DEN_KW "DENG" -#define ECLIPSE300_WATER_DEN_KW "DENW" - -#define FIPGAS_KW "FIPGAS" -#define FIPWAT_KW "FIPWAT" -#define FIPOIL_KW "FIPOIL" -#define RFIPGAS_KW "RFIPGAS" -#define RFIPWAT_KW "RFIPWAT" -#define RFIPOIL_KW "RFIPOIL" - -#define FLRWATNNC_KW "FLRWATN+" //nnc wtr flux, grid1 == grid2 -#define FLROILNNC_KW "FLROILN+" //nnc oil flux, grid1 == grid2 -#define FLRGASNNC_KW "FLRGASN+" //nnc gas flux, grid1 == grid2 - -#define FLRWATLG_KW "FLRWATL+" //nnc wtr flux, grid1 == 0, grid != 0 -#define FLROILLG_KW "FLROILL+" //nnc oil flux, grid1 == 0, grid != 0 -#define FLRGASLG_KW "FLRGASL+" //nnc gas flux, grid1 == 0, grid != 0 - -#define FLRWATLL_KW "FLRWATA+" //nnc wtr flux, grid1 != 0, grid2 != 0, grid1 != grid2 -#define FLROILLL_KW "FLROILA+" //nnc oil flux, grid1 != 0, grid2 != 0, grid1 != grid2 -#define FLRGASLL_KW "FLRGASA+" //nnc gas flux, grid1 != 0, grid2 != 0, grid1 != grid2 - -#define INTEHEAD_NWELLS_INDEX 16 // Number of wells -#define INTEHEAD_NIWELZ_INDEX 24 // Number of elements pr. well in the IWEL array. -#define INTEHEAD_NXWELZ_INDEX 26 // Number of elements pr. well in the XWEL array. -#define INTEHEAD_NZWELZ_INDEX 27 // Number of 8 character words pr. well - -#define INTEHEAD_NCWMAX_INDEX 17 // Maximum number of completions per well -#define INTEHEAD_NWGMAX_INDEX 19 // Maximum number of wells in any group -#define INTEHEAD_NGMAXZ_INDEX 20 // Maximum number of groups in field -#define INTEHEAD_NSWELZ_INDEX 25 - -#define INTEHEAD_NICONZ_INDEX 32 // Number of elements pr completion in the ICON array. -#define INTEHEAD_NSCONZ_INDEX 33 // Number of elements pr completion in the SCON array -#define INTEHEAD_NXCONZ_INDEX 34 // Number of elements pr completion in the XCON array -#define INTEHEAD_NIGRPZ_INDEX 36 // Number of elements pr group in the IGRP array. - - -#define INTEHEAD_NSWLMX_INDEX 175 -#define INTEHEAD_NSEGMX_INDEX 176 -#define INTEHEAD_NLBRMX_INDEX 177 -#define INTEHEAD_NISEGZ_INDEX 178 -#define INTEHEAD_NRSEGZ_INDEX 179 -#define INTEHEAD_NILBRZ_INDEX 180 - -#define DOUBHEAD_DAYS_INDEX 0 - -/*****************************************************************/ -/* Summary files */ -/*****************************************************************/ - -/* Summary header file */ -#define MINISTEP_KW "MINISTEP" -#define STARTDAT_KW "STARTDAT" /* Intgere keyword containing day,month,year. */ -#define WGNAMES_KW "WGNAMES" /* The names of wells/groups for the summary vectors. */ -#define NAMES_KW "NAMES" /* Alias for WGNAMES_KW. */ -#define KEYWORDS_KW "KEYWORDS" /* The variable type for the various summary vectors. */ -#define UNITS_KW "UNITS" /* The units, i.e SM^3/DAY the summary vectors. */ -#define DIMENS_KW "DIMENS" /* The dimensions of the grid - also used in the GRID files. */ -#define NUMS_KW "NUMS" /* Extra numeric qualifiers for the summary variables, like cell number. */ -#define LGRS_KW "LGRS" /* The lgr name for a vector originating from an lgr. */ -#define NUMLX_KW "NUMLX" /* For block variables defined in a an lgr this is i coordinate in the lgr. */ -#define NUMLY_KW "NUMLY" /* ... j coordinate in the lgr. */ -#define NUMLZ_KW "NUMLZ" /* ... k coordinate in the lgr. */ - - -/* Magic indices used to locate day,month,year from the STARTDAT keyword. */ -#define STARTDAT_DAY_INDEX 0 -#define STARTDAT_MONTH_INDEX 1 -#define STARTDAT_YEAR_INDEX 2 -#define STARTDAT_SIZE 3 - - -/* Magic indices uset to locate the grid dimensions from the DIMENS - keyword in the SMSPEC files. Observe that these magic indices - differ from the magic indices used to look up grid dimensions from - the DIMENS keyword in GRID files. */ -#define DIMENS_SMSPEC_SIZE_INDEX 0 -#define DIMENS_SMSPEC_NX_INDEX 1 -#define DIMENS_SMSPEC_NY_INDEX 2 -#define DIMENS_SMSPEC_NZ_INDEX 3 -#define DIMENS_SMSPEC_RESTART_STEP_INDEX 5 -#define DIMENS_SIZE 6 - -#define INTEHEAD_SMSPEC_SIZE 2 -#define INTEHEAD_SMSPEC_UNIT_INDEX 0 -#define INTEHEAD_SMSPEC_IPROG_INDEX 1 - - -/* Summary data files: */ -#define SEQHDR_KW "SEQHDR" // Contains a single 'magic' integer - not used in libecl. -#define PARAMS_KW "PARAMS" // Contains the actual summary data for one timestep. -#define MINISTEP_KW "MINISTEP" // Scalar integer - contains the timestep number. - -#define SEQHDR_SIZE 1 - -#define RESTART_KW "RESTART" -#define SUMMARY_RESTART_SIZE 8 - -/* - There are no magic indices in the summary data files, for all - interesting data the table created from the ecl_smspec file must be - consulted. -*/ - - -/*****************************************************************/ -/* RFT Files */ -/*****************************************************************/ -/* The files with extension .RFT can contain three quite different - types of information: RFT / PLT / SEGMENT, this is indicated by an - element of the WELLETC keyword. The keywords below are organized in - common keywords, keywords for RFTs and keywords for PLTs. The - special information for SEGMENT data is not internalized at all, - and there are also several additional keywords for the PLTs which - are not internalized. */ - - -/* Common keywords */ -#define TIME_KW "TIME" /* The days since simulation start when - an RFT is performed, also used as - block header when splitting an RFT - file into different wells and timesteps. */ -#define DATE_KW "DATE" /* The date of an RFT as integers: (day,month,year). */ -#define WELLETC_KW "WELLETC" /* The type of date RFT|PLT|SEGMENT and well name are - extracted from this keyword. */ -#define CONIPOS_KW "CONIPOS" /* The i-index of the connections in the well. */ -#define CONJPOS_KW "CONJPOS" /* The j-index ... */ -#define CONKPOS_KW "CONKPOS" /* The k-index ... */ -#define HOSTGRID_KW "HOSTGRID" - -/* RFT keywords */ -#define SWAT_KW "SWAT" /* The kewyord containing SWAT. */ -#define SGAS_KW "SGAS" /* The kewyord containing SGAS. */ -#define PRESSURE_KW "PRESSURE" /* The kewyord containing PRESSURE. */ -#define DEPTH_KW "DEPTH" /* The depth of the connection. */ - -/* PLT keywords */ -#define CONDEPTH_KW "CONDEPTH" /* The depth of the connection. */ -#define CONWRAT_KW "CONWRAT" /* Water rate in a connection. */ -#define CONGRAT_KW "CONGRAT" /* Gas ... */ -#define CONORAT_KW "CONORAT" /* Oil ... */ -#define CONPRES_KW "CONPRES" /* Pressure ... */ -#define CONLENST_KW "CONLENST" /* Length along MSW well */ -#define CONLENEN_KW "CONLENEN" /* Length to connection end for MSW well */ -#define CONVTUB_KW "CONVTUB" /* Volumetric flow at tubing head conditions. */ -#define CONOTUB_KW "CONOTUB" /* Volumetric oil flow at tubing head conditions. */ -#define CONGTUB_KW "CONGTUB" /* Volumetric gas flow at tubing head conditions. */ -#define CONWTUB_KW "CONWTUB" /* Volumetric water flow at tubing head conditions. */ - - -#define WELLETC_TYPE_INDEX 5 /* At this keyword the WELLETC keyword contains a string - containing 'R', 'P' , or 'S' for RFT, PLT or SEGMENT data - respectively.*/ -#define WELLETC_NAME_INDEX 1 /* The name of well being investigated is on this index of - the WELLETC keyword. */ - -/* Magic indices used to get day,month,year from the DATE - keyword. */ -#define DATE_DAY_INDEX 0 -#define DATE_MONTH_INDEX 1 -#define DATE_YEAR_INDEX 2 - - -/*****************************************************************/ -/* GRID and EGRID files. */ -/*****************************************************************/ -/* GRID and EGRID files have very different structure, and only a few - keywords are shared. */ - - -/* Common keywords */ -#define SPECGRID_KW "SPECGRID" -#define SPECGRID_NX_INDEX 0 -#define SPECGRID_NY_INDEX 1 -#define SPECGRID_NZ_INDEX 2 -#define MAPAXES_KW "MAPAXES" /* Keyword used to transform from grid coordinates to - world coordinates. */ -#define LGR_KW "LGR" /* Name of LGR; for GRID files it can contain two elements, - the second element will be the name of the parent. */ -#define MAPUNITS_KW "MAPUNITS" -#define GRIDUNIT_KW "GRIDUNIT" - -#define NNC1_KW "NNC1" /*Upstream cell numbers for non-neighbour connections*/ -#define NNC2_KW "NNC2" /*Downstream cell numbers for non-neighbour connections*/ -#define NNCL_KW "NNCL" /*Cell numbers for LGR cells that are connected to global grid cells*/ -#define NNCG_KW "NNCG" /*Cell numbers for global cells connected to LGR cells*/ - -#define NNCHEAD_KW "NNCHEAD" /*Non-neighbour connection header*/ -#define NNCHEAD_SIZE 10 -#define NNCHEAD_NUMNNC_INDEX 0 /*Item 1 in non-neighbour connection header: number of NNCs. Only present for main grid*/ -#define NNCHEAD_LGR_INDEX 1 /*Item 2 in non-neighbour connection header: LGR number (0 for global grid)*/ - -#define NNCHEADA_KW "NNCHEADA" /*Header for NNC's between two amalgamated LGRs*/ -#define NNA1_KW "NNA1" /*Cell numbers in connecting local grid ILOC1*/ -#define NNA2_KW "NNA2" /*Cell numbers in connecting local grid ILOC2*/ -#define NNCHEADA_ILOC1_INDEX 0 /*ILOC1: Index of first LGR*/ -#define NNCHEADA_ILOC2_INDEX 1 /*ILOC2: Index of second LGR*/ -#define NNA_NUMNNC_INDEX 0 /*Item 1 in NNA1 or NNA2 is number of NNCs*/ - -#define TRANNNC_KW "TRANNNC" -#define TRANGL_KW "TRANGL" -#define TRANLL_KW "TRANLL" - -/* EGRID keywords */ -#define LGR_PARENT_KW "LGRPARNT" /* The name of the parent for an LGR. */ -#define COORDS_KW "COORDS" /* The (x,y) coordinates of the top and bottom of the pillars constituting the grid. */ -#define ZCORN_KW "ZCORN" /* Z coordinate where pillars cross planes. */ -#define ACTNUM_KW "ACTNUM" /* Integer flag of with active=0,1. */ -#define HOSTNUM_KW "HOSTNUM" /* For cells in LGR - pointing back to cell nr in - parent grid. */ -#define FILEHEAD_KW "FILEHEAD" -#define ENDGRID_KW "ENDGRID" -#define ENDLGR_KW "ENDLGR" -#define CORSNUM_KW "CORSNUM" - -/* GRID keywords */ -#define GRIDHEAD_KW "GRIDHEAD" /* Header information for GRID files. */ -#define COORD_KW "COORD" /* Header information for one cell in GRID file. */ -#define CORNERS_KW "CORNERS" /* Vector containing (x,y,z) x 8 elements - all corners in a cell. */ -#define DIMENS_KW "DIMENS" /* The dimensions of the grid. */ -#define RADIAL_KW "RADIAL" - -#define GLOBAL_STRING "GLOBAL" - -#define GRIDHEAD_TYPE_INDEX 0 -#define GRIDHEAD_NX_INDEX 1 -#define GRIDHEAD_NY_INDEX 2 -#define GRIDHEAD_NZ_INDEX 3 -#define GRIDHEAD_LGR_INDEX 4 -#define GRIDHEAD_NUMRES_INDEX 24 -#define GRIDHEAD_SIZE 100 - -/* Observe that these indices are one value lower than the values used - in the ecl_smspec file. */ -#define DIMENS_NX_INDEX 0 -#define DIMENS_NY_INDEX 1 -#define DIMENS_NZ_INDEX 2 - -#define FILEHEAD_VERSION_INDEX 0 -#define FILEHEAD_YEAR_INDEX 1 -#define FILEHEAD_COMPAT_INDEX 3 -#define FILEHEAD_TYPE_INDEX 4 -#define FILEHEAD_DUALP_INDEX 5 -#define FILEHEAD_ORGFORMAT_INDEX 6 - -#define GRIDHEAD_GRIDTYPE_CORNERPOINT 1 /* <----\ */ - /* | Fucking hysterical! */ -#define FILEHEAD_GRIDTYPE_CORNERPOINT 0 /* <----/ */ - -#define FILEHEAD_ORGTYPE_CORNERPOINT 1 -#define FILEHEAD_SINGLE_POROSITY 0 -#define FILEHEAD_DUAL_POROSITY 1 -#define FILEHEAD_DUAL_PERMEABILITY 2 - - -#define CELL_NOT_ACTIVE 0 -#define CELL_ACTIVE_MATRIX 1 -#define CELL_ACTIVE CELL_ACTIVE_MATRIX -#define CELL_ACTIVE_FRACTURE 2 - +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_magic.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_magic.hpp index d7cfba7c96..02dab28681 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_magic.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_kw_magic.hpp @@ -1,20 +1,645 @@ +#ifndef ERT_ECL_KW_MAGIC_H +#define ERT_ECL_KW_MAGIC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + This header file contains names and indices of ECLIPSE keywords + which have special significance in various files. Observe that many + of the keywords like e.g. INTEHEAD occur in many different file + types, with partly overlapping layout and values. + */ + +/*****************************************************************/ +/* INIT files: */ +/*****************************************************************/ + +#define PORO_KW "PORO" +#define PORV_KW "PORV" +#define AQUIFER_KW "AQUIFERN" +#define INTEHEAD_KW "INTEHEAD" +#define LOGIHEAD_KW "LOGIHEAD" +#define DOUBHEAD_KW "DOUBHEAD" +#define RPORV_KW "RPORV" +#define PORV_KW "PORV" +#define PORMOD_KW "PORV_MOD" + +#define PVTNUM_KW "PVTNUM" +#define LGRHEADI_KW "LGRHEADI" +#define LGRHEADI_LGR_NR_INDEX 0 +#define LGRJOIN_KW "LGRJOIN" + + +/* + The table in the INIT file are organized with one large data keyword + 'TAB' and one keyword 'TABDIMS' which describe the layout of the + data in the TAB keyword. + + For each of the tables there 'TABDIMS_xxx_OFFSET_ITEM' which points + to an element in the 'TABDIMS' vector which contains the starting + address of table 'xxx' in the 'TAB' keyword, then there are one or + several integer values describing how many values/tables there + are. In addition there is an assumed number of columns which is not + explicitly stored in the TABDIMS keyword. + + The input format is quite flexible with respect to the size of the + individual tables and subtables, but the representation in the INIT + file is based on fixed length columns and equal sized tables, where + all inactive elements have the default value 2e20. + + Assume the following PVTO input: + + + PVTO + 1.55203 1.00000 1.15907572 0.64345 + 25.00000 1.15319788 0.67619 + 50.00000 1.14759314 0.70959 / + + 28.04570 25.00000 1.17415042 0.63294 + 50.00000 1.16792401 0.66638 + 75.00000 1.16222385 0.69918 + 100.00000 1.15212320 0.76297 / + + 35.62113 50.00000 1.19208190 0.61538 + 75.00000 1.18568689 0.64790 + 100.00000 1.17982339 0.67985 + 125.00000 1.17441865 0.71127 + 150.00000 1.16941365 0.74217 / + + / + 20.66588 1.00000 1.15642614 0.57010 + 25.00000 1.15051027 0.59831 + 50.00000 1.14487540 0.62703 / + + 27.65815 25.00000 1.17402576 0.56928 + 50.00000 1.16771923 0.59875 + 75.00000 1.16195281 0.62760 + 100.00000 1.15665041 0.65588 + / + +This is the PVTO table, and it is described by the constants +TABDIMS_IBPVTO_OFFSET_ITEM, TABDIMS_JBPVTO_OFFSET_ITEM, +TABDIMS_NRPVTO_ITEM, TABDIMS_NPPVTO_ITEM and TABDIMS_NTPVTO_ITEM. Observe the following: + + 1. There are 3 GOR values in the first table and 2 in the second, + this is the number of composition nodes - + TABDIMS_NRPVTO_ITEM. Since there are 3 in the first table and 2 in + the second the value of TABDIMS[ TABDIMS_NRPVTO_ITEM ] >= 3. + + 2. The GOR node values (1.55203, 28.04570, 35.62113) and (20.66588, + 27.65815) are stored separately at offset + TABDIMS[ TABDIMS_JBPVTO_OFFSET_ITEM ] in the TAB array. + + 3. The length of the longest column is 5 elements so the value of + TABDIMS[ TABDIMS_NPPVTO_ITEM ] >= 5. + + 4. The actual table data starts at offset TABDIMS[ + TABDIMS_IBPVTO_ITEM] in the TAB table. + +When packing the actual data into the TAB array the indices are +running as row,GOR,table,column - with row fastest. All in all the +linear vector for this PVTO table will look like: + + 1.00000 \ \ \ \ + 25.00000 | | | | + 50.00000 | NPPVTO = 5 | | | + * | | | | + * | | | | +-----------/ | | | + 25.00000 | | | + 50.00000 | | | + 75.00000 | NRPVTO = 3 | | +100.00000 | | | + * | | | +----------- | | | + 50.00000 | | | + 75.00000 | | | +100.00000 | | | +125.00000 | | | +150.00000 | | | +=========== / | NTPVTO = 2 | + 1.00000 | | + 25.00000 | | + 50.00000 | | + * | | + * | | Three columns - +----------- | | (not in TABDIMS) + 25.00000 | | + 50.00000 | | + 75.00000 | | +100.00000 | | + * | | +----------- | | +* | | +* | | +* | | +* | | +* | | +@@@@@@@@@@@ / | +1.15907572 | +1.15319788 | +1.14759314 | + * | + * | +----------- | +1.17415042 | +1.16792401 | +1.16222385 | +1.15212320 | + * | +----------- | +1.19208190 | +1.18568689 | +1.17982339 | +1.17441865 | +1.16941365 | +=========== | +1.15642614 | +1.15051027 | +1.14487540 | + * | + * | +----------- | +1.17402576 | +1.16771923 | +1.16195281 | +1.15665041 | + * | +----------- | +* | +* | +* | +* | +* | +@@@@@@@@@@@ | +0.64345 | +0.67619 | +0.70959 | + * | + * | +----------- | +0.63294 | +0.66638 | +0.69918 | +0.76297 | + * | +----------- | +0.61538 | +0.64790 | +0.67985 | +0.71127 | +0.74217 | +=========== | +0.57010 | +0.59831 | +0.62703 | + * | + * | +----------- | +0.56928 | +0.59875 | +0.62760 | +0.65588 | + * | +----------- | +* | +* | +* | +* | +* | + / + +In this vector representation the different composition subtable +columns are separated by '----', the different main tables are +separated by '======' and the columns are separated by '@@@@'. Default +values (2e20) are denoted with '*'. + +*/ +#define TABDIMS_SIZE 100 + +#define TABDIMS_TAB_SIZE_ITEM 0 + +#define TABDIMS_IBROCK_OFFSET_ITEM 1 +#define TABDIMS_NTROCK_ITEM 2 + +#define TABDIMS_IBROCC_OFFSET_ITEM 3 +#define TABDIMS_NPROCC_ITEM 4 + +#define TABDIMS_IBPVTO_OFFSET_ITEM 6 +#define TABDIMS_JBPVTO_OFFSET_ITEM 7 +#define TABDIMS_NRPVTO_ITEM 8 +#define TABDIMS_NPPVTO_ITEM 9 +#define TABDIMS_NTPVTO_ITEM 10 + +#define TABDIMS_IBPVTW_OFFSET_ITEM 11 +#define TABDIMS_NTPVTW_ITEM 12 + +#define TABDIMS_IBPVTG_OFFSET_ITEM 13 +#define TABDIMS_JBPVTG_OFFSET_ITEM 14 +#define TABDIMS_NRPVTG_ITEM 15 +#define TABDIMS_NPPVTG_ITEM 16 +#define TABDIMS_NTPVTG_ITEM 17 + +#define TABDIMS_IBDENS_OFFSET_ITEM 18 +#define TABDIMS_NTDENS_ITEM 19 + +#define TABDIMS_IBSWFN_OFFSET_ITEM 20 +#define TABDIMS_NSSWFN_ITEM 21 +#define TABDIMS_NTSWFN_ITEM 22 + +#define TABDIMS_IBSGFN_OFFSET_ITEM 23 +#define TABDIMS_NSSGFN_ITEM 24 +#define TABDIMS_NTSGFN_ITEM 25 + +#define TABDIMS_IBSOFN_OFFSET_ITEM 26 +#define TABDIMS_IBSWCO_OFFSET_ITEM 27 +#define TABDIMS_NSSOFN_ITEM 28 +#define TABDIMS_NTSOFN_ITEM 29 + +#define TABDIMS_IBVETB_OFFSET_ITEM 40 +#define TABDIMS_NSVETB_ITEM 41 +#define TABDIMS_NTVETB_ITEM 42 + +#define TABDIMS_IBTHPR_OFFSET_ITEM 43 +#define TABDIMS_IBSLIM_ITEM 44 +#define TABDIMS_NSENDP_ITEM 45 +#define TABDIMS_NTENDP_ITEM 46 + +#define TABDIMS_IBRTEM_OFFSET_ITEM 47 +#define TABDIMS_IBCTOL_ITEM 48 + +#define TABDIMS_IBLANG_OFFSET_ITEM 50 // LANGMUIR Table +#define TABDIMS_NCLANG_ITEM 51 // LANGMUIR Table +#define TABDIMS_NSLANG_ITEM 52 // LANGMUIR Table +#define TABDIMS_NTLANG_ITEM 53 // LANGMUIR Table + +#define TABDIMS_IBLNG2_OFFSET_ITEM 54 // LANGSOLV Table +#define TABDIMS_IBCADP_OFFSET_ITEM 55 // COALPP Table +#define TABDIMS_IBCADS_OFFSET_ITEM 56 // COALADS Table +#define TABDIMS_IBROCP_OFFSET_ITEM 57 // ROCKPAMA Table +#define TABDIMS_NTRPMA_ITEM 58 // ROCKPAMA Table + + +/* + Observe that many of the elements in the INTEHEAD keyword is shared + between the restart and init files. The ones listed below here are + in both the INIT and the restart files. In addition the restart + files have many well related items which are only in the restart + files. +*/ + + +#define INTEHEAD_UNIT_INDEX 2 +#define INTEHEAD_NX_INDEX 8 +#define INTEHEAD_NY_INDEX 9 +#define INTEHEAD_NZ_INDEX 10 +#define INTEHEAD_NACTIVE_INDEX 11 +#define INTEHEAD_PHASE_INDEX 14 +#define INTEHEAD_DAY_INDEX 64 +#define INTEHEAD_MONTH_INDEX 65 +#define INTEHEAD_YEAR_INDEX 66 +#define INTEHEAD_TIMESTEP_INDEX 67 +#define INTEHEAD_REPORT_STEP 68 +#define INTEHEAD_IPROG_INDEX 94 + +// The value seems to be: report_step - 1; might be previous? +#define INTEHEAD_REPORT_INDEX 219 + + +#define INTEHEAD_METRIC_VALUE 1 +#define INTEHEAD_ECLIPSE100_VALUE 100 +#define INTEHEAD_ECLIPSE300_VALUE 300 +#define INTEHEAD_ECLIPSE300THERMAL_VALUE 500 +#define INTEHEAD_INTERSECT_VALUE 700 +#define INTEHEAD_FRONTSIM_VALUE 800 + +#define INTEHEAD_INIT_SIZE 95 +#define INTEHEAD_RESTART_SIZE 180 + +#define LOGIHEAD_ECLIPSE300_RADIAL_INDEX 3 +#define LOGIHEAD_ECLIPSE100_RADIAL_INDEX 4 +#define LOGIHEAD_DUALP_INDEX 14 +#define LOGIHEAD_INIT_SIZE 80 +#define LOGIHEAD_RESTART_SIZE 15 + + +#define LOGIHEAD_RS_INDEX 0 +#define LOGIHEAD_RV_INDEX 1 +#define LOGIHEAD_DIR_RELPERM_INDEX 2 +/*-----------------------------------------------------------------*/ +#define LOGIHEAD_REV_RELPERM100_INDEX 3 /* The indices for reversible relperm and */ +#define LOGIHEAD_RADIAL100_INDEX 4 /* use of radial grids is interchanged between */ +#define LOGIHEAD_REV_RELPERM300_INDEX 4 /* ECLIPSE100 and ECLIPSE300. */ +#define LOGIHEAD_RADIAL300_INDEX 3 +/*-----------------------------------------------------------------*/ +#define LOGIHEAD_HYSTERISIS_INDEX 6 +#define LOGIHEAD_DUALP_INDEX 14 +#define LOGIHEAD_ENDPOINT_SCALING_INDEX 16 +#define LOGIHEAD_DIR_ENDPOINT_SCALING_INDEX 17 +#define LOGIHEAD_REV_ENDPOINT_SCALING_INDEX 18 +#define LOGIHEAD_ALT_ENDPOINT_SCALING_INDEX 19 +#define LOGIHEAD_MISC_DISPLACEMENT_INDEX 35 +#define LOGIHEAD_CONSTANT_OILCOMPR_INDEX (39-1) /* Constant oil compressibility (PVCDO)? */ +#define LOGIHEAD_SCALE_WATER_PC_AT_MAX_SAT_INDEX 55 +#define LOGIHEAD_SCALE_GAS_PC_AT_MAX_SAT_INDEX 56 + + + + +#define DOUBHEAD_INIT_SIZE 1 +#define DOUBHEAD_RESTART_SIZE 1 + + +/*****************************************************************/ +/* RESTART files: */ +/*****************************************************************/ + +#define SEQNUM_KW "SEQNUM" /* Contains the report step as the only data; not + present in non-unified files, where the report + step must be inferred from the filename. */ +#define STARTSOL_KW "STARTSOL" +#define ENDSOL_KW "ENDSOL" + +#define XWEL_KW "XWEL" +#define IWEL_KW "IWEL" +#define ZWEL_KW "ZWEL" +#define ICON_KW "ICON" +#define SCON_KW "SCON" +#define XCON_KW "XCON" +#define ISEG_KW "ISEG" +#define RSEG_KW "RSEG" + +#define ECLIPSE100_OIL_DEN_KW "OIL_DEN" +#define ECLIPSE100_GAS_DEN_KW "GAS_DEN" +#define ECLIPSE100_WATER_DEN_KW "WAT_DEN" + +#define ECLIPSE300_OIL_DEN_KW "DENO" +#define ECLIPSE300_GAS_DEN_KW "DENG" +#define ECLIPSE300_WATER_DEN_KW "DENW" + +#define FIPGAS_KW "FIPGAS" +#define FIPWAT_KW "FIPWAT" +#define FIPOIL_KW "FIPOIL" +#define RFIPGAS_KW "RFIPGAS" +#define RFIPWAT_KW "RFIPWAT" +#define RFIPOIL_KW "RFIPOIL" + +#define FLRWATNNC_KW "FLRWATN+" //nnc wtr flux, grid1 == grid2 +#define FLROILNNC_KW "FLROILN+" //nnc oil flux, grid1 == grid2 +#define FLRGASNNC_KW "FLRGASN+" //nnc gas flux, grid1 == grid2 + +#define FLRWATLG_KW "FLRWATL+" //nnc wtr flux, grid1 == 0, grid != 0 +#define FLROILLG_KW "FLROILL+" //nnc oil flux, grid1 == 0, grid != 0 +#define FLRGASLG_KW "FLRGASL+" //nnc gas flux, grid1 == 0, grid != 0 + +#define FLRWATLL_KW "FLRWATA+" //nnc wtr flux, grid1 != 0, grid2 != 0, grid1 != grid2 +#define FLROILLL_KW "FLROILA+" //nnc oil flux, grid1 != 0, grid2 != 0, grid1 != grid2 +#define FLRGASLL_KW "FLRGASA+" //nnc gas flux, grid1 != 0, grid2 != 0, grid1 != grid2 + +#define INTEHEAD_NWELLS_INDEX 16 // Number of wells +#define INTEHEAD_NIWELZ_INDEX 24 // Number of elements pr. well in the IWEL array. +#define INTEHEAD_NXWELZ_INDEX 26 // Number of elements pr. well in the XWEL array. +#define INTEHEAD_NZWELZ_INDEX 27 // Number of 8 character words pr. well + +#define INTEHEAD_NCWMAX_INDEX 17 // Maximum number of completions per well +#define INTEHEAD_NWGMAX_INDEX 19 // Maximum number of wells in any group +#define INTEHEAD_NGMAXZ_INDEX 20 // Maximum number of groups in field +#define INTEHEAD_NSWELZ_INDEX 25 + +#define INTEHEAD_NICONZ_INDEX 32 // Number of elements pr completion in the ICON array. +#define INTEHEAD_NSCONZ_INDEX 33 // Number of elements pr completion in the SCON array +#define INTEHEAD_NXCONZ_INDEX 34 // Number of elements pr completion in the XCON array +#define INTEHEAD_NIGRPZ_INDEX 36 // Number of elements pr group in the IGRP array. + + +#define INTEHEAD_NSWLMX_INDEX 175 +#define INTEHEAD_NSEGMX_INDEX 176 +#define INTEHEAD_NLBRMX_INDEX 177 +#define INTEHEAD_NISEGZ_INDEX 178 +#define INTEHEAD_NRSEGZ_INDEX 179 +#define INTEHEAD_NILBRZ_INDEX 180 + +#define DOUBHEAD_DAYS_INDEX 0 + +/*****************************************************************/ +/* Summary files */ +/*****************************************************************/ + +/* Summary header file */ +#define MINISTEP_KW "MINISTEP" +#define STARTDAT_KW "STARTDAT" /* Intgere keyword containing day,month,year. */ +#define WGNAMES_KW "WGNAMES" /* The names of wells/groups for the summary vectors. */ +#define NAMES_KW "NAMES" /* Alias for WGNAMES_KW. */ +#define KEYWORDS_KW "KEYWORDS" /* The variable type for the various summary vectors. */ +#define UNITS_KW "UNITS" /* The units, i.e SM^3/DAY the summary vectors. */ +#define DIMENS_KW "DIMENS" /* The dimensions of the grid - also used in the GRID files. */ +#define NUMS_KW "NUMS" /* Extra numeric qualifiers for the summary variables, like cell number. */ +#define LGRS_KW "LGRS" /* The lgr name for a vector originating from an lgr. */ +#define NUMLX_KW "NUMLX" /* For block variables defined in a an lgr this is i coordinate in the lgr. */ +#define NUMLY_KW "NUMLY" /* ... j coordinate in the lgr. */ +#define NUMLZ_KW "NUMLZ" /* ... k coordinate in the lgr. */ + + +/* Magic indices used to locate day,month,year from the STARTDAT keyword. */ +#define STARTDAT_DAY_INDEX 0 +#define STARTDAT_MONTH_INDEX 1 +#define STARTDAT_YEAR_INDEX 2 +#define STARTDAT_SIZE 3 + + +/* Magic indices uset to locate the grid dimensions from the DIMENS + keyword in the SMSPEC files. Observe that these magic indices + differ from the magic indices used to look up grid dimensions from + the DIMENS keyword in GRID files. */ +#define DIMENS_SMSPEC_SIZE_INDEX 0 +#define DIMENS_SMSPEC_NX_INDEX 1 +#define DIMENS_SMSPEC_NY_INDEX 2 +#define DIMENS_SMSPEC_NZ_INDEX 3 +#define DIMENS_SMSPEC_RESTART_STEP_INDEX 5 +#define DIMENS_SIZE 6 + +#define INTEHEAD_SMSPEC_SIZE 2 +#define INTEHEAD_SMSPEC_UNIT_INDEX 0 +#define INTEHEAD_SMSPEC_IPROG_INDEX 1 + + +/* Summary data files: */ +#define SEQHDR_KW "SEQHDR" // Contains a single 'magic' integer - not used in libecl. +#define PARAMS_KW "PARAMS" // Contains the actual summary data for one timestep. +#define MINISTEP_KW "MINISTEP" // Scalar integer - contains the timestep number. + +#define SEQHDR_SIZE 1 + +#define RESTART_KW "RESTART" +#define SUMMARY_RESTART_SIZE 8 + /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + There are no magic indices in the summary data files, for all + interesting data the table created from the ecl_smspec file must be + consulted. */ -#include +/*****************************************************************/ +/* RFT Files */ +/*****************************************************************/ +/* The files with extension .RFT can contain three quite different + types of information: RFT / PLT / SEGMENT, this is indicated by an + element of the WELLETC keyword. The keywords below are organized in + common keywords, keywords for RFTs and keywords for PLTs. The + special information for SEGMENT data is not internalized at all, + and there are also several additional keywords for the PLTs which + are not internalized. */ + + +/* Common keywords */ +#define TIME_KW "TIME" /* The days since simulation start when + an RFT is performed, also used as + block header when splitting an RFT + file into different wells and timesteps. */ +#define DATE_KW "DATE" /* The date of an RFT as integers: (day,month,year). */ +#define WELLETC_KW "WELLETC" /* The type of date RFT|PLT|SEGMENT and well name are + extracted from this keyword. */ +#define CONIPOS_KW "CONIPOS" /* The i-index of the connections in the well. */ +#define CONJPOS_KW "CONJPOS" /* The j-index ... */ +#define CONKPOS_KW "CONKPOS" /* The k-index ... */ +#define HOSTGRID_KW "HOSTGRID" + +/* RFT keywords */ +#define SWAT_KW "SWAT" /* The kewyord containing SWAT. */ +#define SGAS_KW "SGAS" /* The kewyord containing SGAS. */ +#define PRESSURE_KW "PRESSURE" /* The kewyord containing PRESSURE. */ +#define DEPTH_KW "DEPTH" /* The depth of the connection. */ + +/* PLT keywords */ +#define CONDEPTH_KW "CONDEPTH" /* The depth of the connection. */ +#define CONWRAT_KW "CONWRAT" /* Water rate in a connection. */ +#define CONGRAT_KW "CONGRAT" /* Gas ... */ +#define CONORAT_KW "CONORAT" /* Oil ... */ +#define CONPRES_KW "CONPRES" /* Pressure ... */ +#define CONLENST_KW "CONLENST" /* Length along MSW well */ +#define CONLENEN_KW "CONLENEN" /* Length to connection end for MSW well */ +#define CONVTUB_KW "CONVTUB" /* Volumetric flow at tubing head conditions. */ +#define CONOTUB_KW "CONOTUB" /* Volumetric oil flow at tubing head conditions. */ +#define CONGTUB_KW "CONGTUB" /* Volumetric gas flow at tubing head conditions. */ +#define CONWTUB_KW "CONWTUB" /* Volumetric water flow at tubing head conditions. */ + + +#define WELLETC_TYPE_INDEX 5 /* At this keyword the WELLETC keyword contains a string + containing 'R', 'P' , or 'S' for RFT, PLT or SEGMENT data + respectively.*/ +#define WELLETC_NAME_INDEX 1 /* The name of well being investigated is on this index of + the WELLETC keyword. */ + +/* Magic indices used to get day,month,year from the DATE + keyword. */ +#define DATE_DAY_INDEX 0 +#define DATE_MONTH_INDEX 1 +#define DATE_YEAR_INDEX 2 + + +/*****************************************************************/ +/* GRID and EGRID files. */ +/*****************************************************************/ +/* GRID and EGRID files have very different structure, and only a few + keywords are shared. */ + + +/* Common keywords */ +#define SPECGRID_KW "SPECGRID" +#define SPECGRID_NX_INDEX 0 +#define SPECGRID_NY_INDEX 1 +#define SPECGRID_NZ_INDEX 2 +#define MAPAXES_KW "MAPAXES" /* Keyword used to transform from grid coordinates to + world coordinates. */ +#define LGR_KW "LGR" /* Name of LGR; for GRID files it can contain two elements, + the second element will be the name of the parent. */ +#define MAPUNITS_KW "MAPUNITS" +#define GRIDUNIT_KW "GRIDUNIT" + +#define NNC1_KW "NNC1" /*Upstream cell numbers for non-neighbour connections*/ +#define NNC2_KW "NNC2" /*Downstream cell numbers for non-neighbour connections*/ +#define NNCL_KW "NNCL" /*Cell numbers for LGR cells that are connected to global grid cells*/ +#define NNCG_KW "NNCG" /*Cell numbers for global cells connected to LGR cells*/ + +#define NNCHEAD_KW "NNCHEAD" /*Non-neighbour connection header*/ +#define NNCHEAD_SIZE 10 +#define NNCHEAD_NUMNNC_INDEX 0 /*Item 1 in non-neighbour connection header: number of NNCs. Only present for main grid*/ +#define NNCHEAD_LGR_INDEX 1 /*Item 2 in non-neighbour connection header: LGR number (0 for global grid)*/ + +#define NNCHEADA_KW "NNCHEADA" /*Header for NNC's between two amalgamated LGRs*/ +#define NNA1_KW "NNA1" /*Cell numbers in connecting local grid ILOC1*/ +#define NNA2_KW "NNA2" /*Cell numbers in connecting local grid ILOC2*/ +#define NNCHEADA_ILOC1_INDEX 0 /*ILOC1: Index of first LGR*/ +#define NNCHEADA_ILOC2_INDEX 1 /*ILOC2: Index of second LGR*/ +#define NNA_NUMNNC_INDEX 0 /*Item 1 in NNA1 or NNA2 is number of NNCs*/ + +#define TRANNNC_KW "TRANNNC" +#define TRANGL_KW "TRANGL" +#define TRANLL_KW "TRANLL" + +/* EGRID keywords */ +#define LGR_PARENT_KW "LGRPARNT" /* The name of the parent for an LGR. */ +#define COORDS_KW "COORDS" /* The (x,y) coordinates of the top and bottom of the pillars constituting the grid. */ +#define ZCORN_KW "ZCORN" /* Z coordinate where pillars cross planes. */ +#define ACTNUM_KW "ACTNUM" /* Integer flag of with active=0,1. */ +#define HOSTNUM_KW "HOSTNUM" /* For cells in LGR - pointing back to cell nr in + parent grid. */ +#define FILEHEAD_KW "FILEHEAD" +#define ENDGRID_KW "ENDGRID" +#define ENDLGR_KW "ENDLGR" +#define CORSNUM_KW "CORSNUM" + +/* GRID keywords */ +#define GRIDHEAD_KW "GRIDHEAD" /* Header information for GRID files. */ +#define COORD_KW "COORD" /* Header information for one cell in GRID file. */ +#define CORNERS_KW "CORNERS" /* Vector containing (x,y,z) x 8 elements - all corners in a cell. */ +#define DIMENS_KW "DIMENS" /* The dimensions of the grid. */ +#define RADIAL_KW "RADIAL" + +#define GLOBAL_STRING "GLOBAL" + +#define GRIDHEAD_TYPE_INDEX 0 +#define GRIDHEAD_NX_INDEX 1 +#define GRIDHEAD_NY_INDEX 2 +#define GRIDHEAD_NZ_INDEX 3 +#define GRIDHEAD_LGR_INDEX 4 +#define GRIDHEAD_NUMRES_INDEX 24 +#define GRIDHEAD_SIZE 100 + +/* Observe that these indices are one value lower than the values used + in the ecl_smspec file. */ +#define DIMENS_NX_INDEX 0 +#define DIMENS_NY_INDEX 1 +#define DIMENS_NZ_INDEX 2 + +#define FILEHEAD_VERSION_INDEX 0 +#define FILEHEAD_YEAR_INDEX 1 +#define FILEHEAD_COMPAT_INDEX 3 +#define FILEHEAD_TYPE_INDEX 4 +#define FILEHEAD_DUALP_INDEX 5 +#define FILEHEAD_ORGFORMAT_INDEX 6 + +#define GRIDHEAD_GRIDTYPE_CORNERPOINT 1 /* <----\ */ + /* | Fucking hysterical! */ +#define FILEHEAD_GRIDTYPE_CORNERPOINT 0 /* <----/ */ + +#define FILEHEAD_ORGTYPE_CORNERPOINT 1 +#define FILEHEAD_SINGLE_POROSITY 0 +#define FILEHEAD_DUAL_POROSITY 1 +#define FILEHEAD_DUAL_PERMEABILITY 2 + + +#define CELL_NOT_ACTIVE 0 +#define CELL_ACTIVE_MATRIX 1 +#define CELL_ACTIVE CELL_ACTIVE_MATRIX +#define CELL_ACTIVE_FRACTURE 2 + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.h index ffc7493bdf..16d0fe4a48 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.h @@ -1,46 +1,9 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. - - The file 'ecl_nnc_geometry.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ECL_NNC_DATA_H -#define ECL_NNC_DATA_H -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include - -typedef struct ecl_nnc_data_struct ecl_nnc_data_type; - -ecl_nnc_data_type * ecl_nnc_data_alloc_tran(const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file); -ecl_nnc_data_type * ecl_nnc_data_alloc_wat_flux(const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file); -ecl_nnc_data_type * ecl_nnc_data_alloc_oil_flux(const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file); -ecl_nnc_data_type * ecl_nnc_data_alloc_gas_flux(const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file); -void ecl_nnc_data_free(ecl_nnc_data_type * data); - -int ecl_nnc_data_get_size(ecl_nnc_data_type * data); -const double * ecl_nnc_data_get_values( const ecl_nnc_data_type * data ); +#include -double ecl_nnc_data_iget_value(const ecl_nnc_data_type * data, int index); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.hpp index 5cca194e38..8ed4c594e7 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_data.hpp @@ -1,19 +1,47 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2017 Statoil ASA, Norway. + + The file 'ecl_nnc_geometry.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ECL_NNC_DATA_H +#define ECL_NNC_DATA_H + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ecl_nnc_data_struct ecl_nnc_data_type; + +ecl_nnc_data_type * ecl_nnc_data_alloc_tran(const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file); +ecl_nnc_data_type * ecl_nnc_data_alloc_wat_flux(const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file); +ecl_nnc_data_type * ecl_nnc_data_alloc_oil_flux(const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file); +ecl_nnc_data_type * ecl_nnc_data_alloc_gas_flux(const ecl_grid_type * grid, const ecl_nnc_geometry_type * nnc_geo, const ecl_file_view_type * init_file); +void ecl_nnc_data_free(ecl_nnc_data_type * data); + +int ecl_nnc_data_get_size(ecl_nnc_data_type * data); +const double * ecl_nnc_data_get_values( const ecl_nnc_data_type * data ); + +double ecl_nnc_data_iget_value(const ecl_nnc_data_type * data, int index); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.h index cf0fcc69be..bd15b73903 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.h @@ -1,61 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ecl_nnc_export.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_ECL_NNC_EXPORT -#define ERT_ECL_NNC_EXPORT - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include -#include - -#define ERT_ECL_DEFAULT_NNC_TRANS HUGE_VAL - -typedef struct { - int grid_nr1; - int global_index1; - int grid_nr2; - int global_index2; - - int input_index; /* corresponds to the input ordering of this nnc */ - - double trans; -} ecl_nnc_type; - - - int ecl_nnc_export_get_size( const ecl_grid_type * grid ); - int ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data); - - ecl_kw_type * ecl_nnc_export_get_tranx_kw( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1, int lgr_nr2 ); - ecl_kw_type * ecl_nnc_export_get_tranll_kw( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1, int lgr_nr2 ); - ecl_kw_type * ecl_nnc_export_get_tran_kw( const ecl_file_type * init_file , const char * kw , int lgr_nr ); - - bool ecl_nnc_equal( const ecl_nnc_type * nnc1 , const ecl_nnc_type * nnc2); - int ecl_nnc_sort_cmp( const ecl_nnc_type * nnc1 , const ecl_nnc_type * nnc2); - void ecl_nnc_sort( ecl_nnc_type * nnc_list , int size); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.hpp index e2d16c2eb3..68ca00d61a 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_export.hpp @@ -1,20 +1,62 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ecl_nnc_export.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_NNC_EXPORT +#define ERT_ECL_NNC_EXPORT + + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ERT_ECL_DEFAULT_NNC_TRANS HUGE_VAL + +typedef struct { + int grid_nr1; + int global_index1; + int grid_nr2; + int global_index2; + + int input_index; /* corresponds to the input ordering of this nnc */ + + double trans; +} ecl_nnc_type; + + + int ecl_nnc_export_get_size( const ecl_grid_type * grid ); + int ecl_nnc_export( const ecl_grid_type * grid , const ecl_file_type * init_file , ecl_nnc_type * nnc_data); + + ecl_kw_type * ecl_nnc_export_get_tranx_kw( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1, int lgr_nr2 ); + ecl_kw_type * ecl_nnc_export_get_tranll_kw( const ecl_grid_type * grid , const ecl_file_type * init_file , int lgr_nr1, int lgr_nr2 ); + ecl_kw_type * ecl_nnc_export_get_tran_kw( const ecl_file_type * init_file , const char * kw , int lgr_nr ); + + bool ecl_nnc_equal( const ecl_nnc_type * nnc1 , const ecl_nnc_type * nnc2); + int ecl_nnc_sort_cmp( const ecl_nnc_type * nnc1 , const ecl_nnc_type * nnc2); + void ecl_nnc_sort( ecl_nnc_type * nnc_list , int size); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.h index fdd002077c..b9c56a12c9 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.h @@ -1,51 +1,9 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. - - The file 'ecl_nnc_geometry.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_NNC_GEOMETRY_H -#define ERT_NNC_GEOMETRY_H -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - -typedef struct ecl_nnc_geometry_struct ecl_nnc_geometry_type; -typedef struct ecl_nnc_pair_struct ecl_nnc_pair_type; - -struct ecl_nnc_pair_struct { - int grid_nr1; - int global_index1; - int grid_nr2; - int global_index2; - - int input_index; /* corresponds to the input ordering of this nnc */ -}; +#include -UTIL_IS_INSTANCE_HEADER( ecl_nnc_geometry); -void ecl_nnc_geometry_free( ecl_nnc_geometry_type * nnc_geo); -ecl_nnc_geometry_type * ecl_nnc_geometry_alloc( const ecl_grid_type * grid ); -int ecl_nnc_geometry_size( const ecl_nnc_geometry_type * nnc_geo ); -const ecl_nnc_pair_type * ecl_nnc_geometry_iget( const ecl_nnc_geometry_type * nnc_geo , int index); -bool ecl_nnc_geometry_same_kw( const ecl_nnc_pair_type * nnc1 , const ecl_nnc_pair_type * nnc2); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.hpp index 8c9f3c9ab7..66c5742ede 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_nnc_geometry.hpp @@ -1,19 +1,52 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2017 Statoil ASA, Norway. + + The file 'ecl_nnc_geometry.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_NNC_GEOMETRY_H +#define ERT_NNC_GEOMETRY_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ecl_nnc_geometry_struct ecl_nnc_geometry_type; +typedef struct ecl_nnc_pair_struct ecl_nnc_pair_type; + +struct ecl_nnc_pair_struct { + int grid_nr1; + int global_index1; + int grid_nr2; + int global_index2; + + int input_index; /* corresponds to the input ordering of this nnc */ +}; + +UTIL_IS_INSTANCE_HEADER( ecl_nnc_geometry); +void ecl_nnc_geometry_free( ecl_nnc_geometry_type * nnc_geo); +ecl_nnc_geometry_type * ecl_nnc_geometry_alloc( const ecl_grid_type * grid ); +int ecl_nnc_geometry_size( const ecl_nnc_geometry_type * nnc_geo ); +const ecl_nnc_pair_type * ecl_nnc_geometry_iget( const ecl_nnc_geometry_type * nnc_geo , int index); +bool ecl_nnc_geometry_same_kw( const ecl_nnc_pair_type * nnc1 , const ecl_nnc_pair_type * nnc2); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.h index 9ad8e40310..507801257b 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.h @@ -1,215 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_region.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_REGION_H -#define ERT_ECL_REGION_H -#ifdef __cplusplus -extern "C" { -#endif -#include - -#include - -#include - -#include -#include -#include - - -typedef enum { - SELECT_ALL = 0, - DESELECT_ALL = 1, - SELECT_FROM_IJK = 2, - DESELECT_FROM_IJK = 3, - SELECT_FROM_I = 4, - DSELECT_FROM_I = 5, - SELECT_FROM_J = 6, - DSELECT_FROM_J = 7, - SELECT_FROM_K = 8, - DSELECT_FROM_K = 9, - SELECT_EQUAL = 10, - DESELECT_EQUAL = 11, - SELECT_IN_INTERVAL = 12, - DESELECT_IN_INTERVAL = 13, - INVERT_SELECTION = 14 -} ecl_region_select_cmd; - - - -typedef struct ecl_region_struct ecl_region_type; - - void ecl_region_unlock( ecl_region_type * region ); - void ecl_region_lock( ecl_region_type * region ); - void ecl_region_reset( ecl_region_type * ecl_region ); - ecl_region_type * ecl_region_alloc_copy( const ecl_region_type * ecl_region ); - ecl_region_type * ecl_region_alloc( const ecl_grid_type * ecl_grid , bool preselect); - void ecl_region_free( ecl_region_type * region ); - void ecl_region_free__( void * __region ); - - const int_vector_type * ecl_region_get_active_list( ecl_region_type * region ); - const int_vector_type * ecl_region_get_global_list( ecl_region_type * region ); - const int_vector_type * ecl_region_get_global_active_list( ecl_region_type * region ); - - bool ecl_region_contains_ijk( const ecl_region_type * ecl_region , int i , int j , int k); - bool ecl_region_contains_global( const ecl_region_type * ecl_region , int global_index); - bool ecl_region_contains_active( const ecl_region_type * ecl_region , int active_index); - - void ecl_region_select_true( ecl_region_type * region , const ecl_kw_type * ecl_kw); - - void ecl_region_invert_selection( ecl_region_type * region ); - void ecl_region_select_all( ecl_region_type * region); - void ecl_region_deselect_all( ecl_region_type * region ); - void ecl_region_deselect_true( ecl_region_type * region , const ecl_kw_type * ecl_kw); - void ecl_region_select_false( ecl_region_type * region , const ecl_kw_type * ecl_kw); - - void ecl_region_select_in_interval( ecl_region_type * region , const ecl_kw_type * ecl_kw, float min_value , float max_value); - void ecl_region_deselect_in_interval( ecl_region_type * region , const ecl_kw_type * ecl_kw, float min_value , float max_value); - - void ecl_region_select_equal( ecl_region_type * region , const ecl_kw_type * ecl_kw, int value); - void ecl_region_deselect_equal( ecl_region_type * region , const ecl_kw_type * ecl_kw, int value); - - void ecl_region_select_inactive_cells( ecl_region_type * region ); - void ecl_region_deselect_inactive_cells( ecl_region_type * region ); - void ecl_region_select_active_cells( ecl_region_type * region ); - void ecl_region_deselect_active_cells( ecl_region_type * region ); - - void ecl_region_select_from_box( ecl_region_type * region , const ecl_box_type * ecl_box ); - void ecl_region_deselect_from_box( ecl_region_type * region , const ecl_box_type * ecl_box ); - - void ecl_region_select_from_ijkbox( ecl_region_type * region , int i1 , int i2 , int j1 , int j2 , int k1 , int k2); - void ecl_region_deselect_from_ijkbox( ecl_region_type * region , int i1 , int i2 , int j1 , int j2 , int k1 , int k2); - - void ecl_region_select_i1i2( ecl_region_type * region , int i1 , int i2); - void ecl_region_deselect_i1i2( ecl_region_type * region , int i1 , int i2); - void ecl_region_select_j1j2( ecl_region_type * region , int j1 , int j2); - void ecl_region_deselect_j1j2( ecl_region_type * region , int j1 , int i2); - void ecl_region_select_k1k2( ecl_region_type * region , int k1 , int k2); - void ecl_region_deselect_k1k2( ecl_region_type * region , int k1 , int i2); - - void ecl_region_select_shallow_cells( ecl_region_type * region , double depth_limit ); - void ecl_region_deselect_shallow_cells( ecl_region_type * region , double depth_limit ); - void ecl_region_select_deep_cells( ecl_region_type * region , double depth_limit ); - void ecl_region_deselect_deep_cells( ecl_region_type * region , double depth_limit ); - - void ecl_region_select_thin_cells( ecl_region_type * ecl_region , double dz_limit ); - void ecl_region_deselect_thin_cells( ecl_region_type * ecl_region , double dz_limit ); - void ecl_region_select_thick_cells( ecl_region_type * ecl_region , double dz_limit ); - void ecl_region_deselect_thick_cells( ecl_region_type * ecl_region , double dz_limit ); - - void ecl_region_select_small_cells( ecl_region_type * ecl_region , double volum_limit ); - void ecl_region_deselect_small_cells( ecl_region_type * ecl_region , double volum_limit ); - void ecl_region_select_large_cells( ecl_region_type * ecl_region , double volum_limit ); - void ecl_region_deselect_large_cells( ecl_region_type * ecl_region , double volum_limit ); - - void ecl_region_select_global_index( ecl_region_type * ecl_region , int global_index); - void ecl_region_deselect_global_index( ecl_region_type * ecl_region , int global_index); - - void ecl_region_select_active_index( ecl_region_type * ecl_region , int active_index); - void ecl_region_deselect_active_index( ecl_region_type * ecl_region , int active_index); - - void ecl_region_intersection( ecl_region_type * region , const ecl_region_type * new_region ); - void ecl_region_union( ecl_region_type * region , const ecl_region_type * new_region ); - void ecl_region_subtract( ecl_region_type * region , const ecl_region_type * new_region); - void ecl_region_xor( ecl_region_type * region , const ecl_region_type * new_region); - - void ecl_region_select_smaller( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , float limit); - void ecl_region_deselect_smaller( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , float limit); - void ecl_region_select_larger( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , float limit); - void ecl_region_deselect_larger( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , float limit); - - void ecl_region_cmp_select_less( ecl_region_type * ecl_region , const ecl_kw_type * kw1 , const ecl_kw_type * kw2); - void ecl_region_cmp_deselect_less( ecl_region_type * ecl_region , const ecl_kw_type * kw1 , const ecl_kw_type * kw2); - void ecl_region_cmp_select_more( ecl_region_type * ecl_region , const ecl_kw_type * kw1 , const ecl_kw_type * kw2); - void ecl_region_cmp_deselect_more( ecl_region_type * ecl_region , const ecl_kw_type * kw1 , const ecl_kw_type * kw2); - - void ecl_region_select_in_cylinder( ecl_region_type * region , double x0 , double y0, double R); - void ecl_region_deselect_in_cylinder( ecl_region_type * region , double x0 , double y0, double R); - void ecl_region_select_in_zcylinder( ecl_region_type * region , double x0 , double y0, double R , double z1 , double z2); - void ecl_region_deselect_in_zcylinder( ecl_region_type * region , double x0 , double y0, double R, double z1 , double z2); - - void ecl_region_select_above_plane( ecl_region_type * region, const double n[3] , const double p[3]); - void ecl_region_select_below_plane( ecl_region_type * region, const double n[3] , const double p[3]); - void ecl_region_deselect_above_plane( ecl_region_type * region, const double n[3] , const double p[3]); - void ecl_region_deselect_below_plane( ecl_region_type * region, const double n[3] , const double p[3]); - - void ecl_region_select_inside_polygon( ecl_region_type * region , const geo_polygon_type * polygon); - void ecl_region_deselect_inside_polygon( ecl_region_type * region , const geo_polygon_type * polygon); - void ecl_region_select_outside_polygon( ecl_region_type * region , const geo_polygon_type * polygon); - void ecl_region_deselect_outside_polygon( ecl_region_type * region , const geo_polygon_type * polygon); - - void ecl_region_select_from_layer( ecl_region_type * region , const layer_type * layer , int k , int layer_value); - void ecl_region_deselect_from_layer( ecl_region_type * region , const layer_type * layer , int k , int layer_value); - void ecl_region_deselect_false( ecl_region_type * region , const ecl_kw_type * ecl_kw); - - -/*****************************************************************/ -/* Functions to manipulate ecl_kw instances . */ - - void ecl_region_set_kw_int( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , int value, bool force_active); - void ecl_region_set_kw_float( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , float value , bool force_active); - void ecl_region_set_kw_double( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , double value , bool force_active); - void ecl_region_kw_copy( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * src_kw , bool force_active); - int ecl_region_get_kw_size( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); - - void ecl_region_kw_iadd( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * delta_kw , bool force_active); - void ecl_region_kw_idiv( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * div_kw , bool force_active); - void ecl_region_kw_imul( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * mul_kw , bool force_active); - void ecl_region_kw_isub( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * delta_kw , bool force_active); - - bool ecl_region_equal( const ecl_region_type * region1 , const ecl_region_type * region2); - - void ecl_region_scale_kw_float( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , float value , bool force_active); - void ecl_region_scale_kw_double( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , double value , bool force_active); - void ecl_region_scale_kw_int( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , int value , bool force_active); - void ecl_region_shift_kw_int( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , int value , bool force_active); - void ecl_region_shift_kw_double( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , double value , bool force_active); - void ecl_region_shift_kw_float( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , float value , bool force_active); - - const int_vector_type * ecl_region_get_kw_index_list( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); - - -/*****************************************************************/ -/* set/get the name */ - void ecl_region_set_name( ecl_region_type * region , const char * name ); - const char * ecl_region_get_name( const ecl_region_type * region ); - -/*****************************************************************/ -/* Stupid cpp compat/legacy/cruft functions. */ - int ecl_region_get_active_size_cpp( ecl_region_type * region ); - int ecl_region_get_global_size_cpp( ecl_region_type * region ); - const int * ecl_region_get_active_list_cpp( ecl_region_type * region ); - const int * ecl_region_get_global_list_cpp( ecl_region_type * region ); - - -/*****************************************************************/ - - double ecl_region_sum_kw_double( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); - int ecl_region_sum_kw_int( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); - float ecl_region_sum_kw_float( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); - int ecl_region_sum_kw_bool( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); - - +#include -UTIL_IS_INSTANCE_HEADER( ecl_region ); -UTIL_SAFE_CAST_HEADER( ecl_region ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.hpp index d51112ae82..321b1f68d5 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_region.hpp @@ -1,19 +1,211 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_region.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_REGION_H +#define ERT_ECL_REGION_H +#include + +#include + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + SELECT_ALL = 0, + DESELECT_ALL = 1, + SELECT_FROM_IJK = 2, + DESELECT_FROM_IJK = 3, + SELECT_FROM_I = 4, + DSELECT_FROM_I = 5, + SELECT_FROM_J = 6, + DSELECT_FROM_J = 7, + SELECT_FROM_K = 8, + DSELECT_FROM_K = 9, + SELECT_EQUAL = 10, + DESELECT_EQUAL = 11, + SELECT_IN_INTERVAL = 12, + DESELECT_IN_INTERVAL = 13, + INVERT_SELECTION = 14 +} ecl_region_select_cmd; + + + +typedef struct ecl_region_struct ecl_region_type; + + void ecl_region_unlock( ecl_region_type * region ); + void ecl_region_lock( ecl_region_type * region ); + void ecl_region_reset( ecl_region_type * ecl_region ); + ecl_region_type * ecl_region_alloc_copy( const ecl_region_type * ecl_region ); + ecl_region_type * ecl_region_alloc( const ecl_grid_type * ecl_grid , bool preselect); + void ecl_region_free( ecl_region_type * region ); + void ecl_region_free__( void * __region ); + + const int_vector_type * ecl_region_get_active_list( ecl_region_type * region ); + const int_vector_type * ecl_region_get_global_list( ecl_region_type * region ); + const int_vector_type * ecl_region_get_global_active_list( ecl_region_type * region ); + + bool ecl_region_contains_ijk( const ecl_region_type * ecl_region , int i , int j , int k); + bool ecl_region_contains_global( const ecl_region_type * ecl_region , int global_index); + bool ecl_region_contains_active( const ecl_region_type * ecl_region , int active_index); + + void ecl_region_select_true( ecl_region_type * region , const ecl_kw_type * ecl_kw); + + void ecl_region_invert_selection( ecl_region_type * region ); + void ecl_region_select_all( ecl_region_type * region); + void ecl_region_deselect_all( ecl_region_type * region ); + void ecl_region_deselect_true( ecl_region_type * region , const ecl_kw_type * ecl_kw); + void ecl_region_select_false( ecl_region_type * region , const ecl_kw_type * ecl_kw); + + void ecl_region_select_in_interval( ecl_region_type * region , const ecl_kw_type * ecl_kw, float min_value , float max_value); + void ecl_region_deselect_in_interval( ecl_region_type * region , const ecl_kw_type * ecl_kw, float min_value , float max_value); + + void ecl_region_select_equal( ecl_region_type * region , const ecl_kw_type * ecl_kw, int value); + void ecl_region_deselect_equal( ecl_region_type * region , const ecl_kw_type * ecl_kw, int value); + + void ecl_region_select_inactive_cells( ecl_region_type * region ); + void ecl_region_deselect_inactive_cells( ecl_region_type * region ); + void ecl_region_select_active_cells( ecl_region_type * region ); + void ecl_region_deselect_active_cells( ecl_region_type * region ); + + void ecl_region_select_from_ijkbox( ecl_region_type * region , int i1 , int i2 , int j1 , int j2 , int k1 , int k2); + void ecl_region_deselect_from_ijkbox( ecl_region_type * region , int i1 , int i2 , int j1 , int j2 , int k1 , int k2); + + void ecl_region_select_i1i2( ecl_region_type * region , int i1 , int i2); + void ecl_region_deselect_i1i2( ecl_region_type * region , int i1 , int i2); + void ecl_region_select_j1j2( ecl_region_type * region , int j1 , int j2); + void ecl_region_deselect_j1j2( ecl_region_type * region , int j1 , int i2); + void ecl_region_select_k1k2( ecl_region_type * region , int k1 , int k2); + void ecl_region_deselect_k1k2( ecl_region_type * region , int k1 , int i2); + + void ecl_region_select_shallow_cells( ecl_region_type * region , double depth_limit ); + void ecl_region_deselect_shallow_cells( ecl_region_type * region , double depth_limit ); + void ecl_region_select_deep_cells( ecl_region_type * region , double depth_limit ); + void ecl_region_deselect_deep_cells( ecl_region_type * region , double depth_limit ); + + void ecl_region_select_thin_cells( ecl_region_type * ecl_region , double dz_limit ); + void ecl_region_deselect_thin_cells( ecl_region_type * ecl_region , double dz_limit ); + void ecl_region_select_thick_cells( ecl_region_type * ecl_region , double dz_limit ); + void ecl_region_deselect_thick_cells( ecl_region_type * ecl_region , double dz_limit ); + + void ecl_region_select_small_cells( ecl_region_type * ecl_region , double volum_limit ); + void ecl_region_deselect_small_cells( ecl_region_type * ecl_region , double volum_limit ); + void ecl_region_select_large_cells( ecl_region_type * ecl_region , double volum_limit ); + void ecl_region_deselect_large_cells( ecl_region_type * ecl_region , double volum_limit ); + + void ecl_region_select_global_index( ecl_region_type * ecl_region , int global_index); + void ecl_region_deselect_global_index( ecl_region_type * ecl_region , int global_index); + + void ecl_region_select_active_index( ecl_region_type * ecl_region , int active_index); + void ecl_region_deselect_active_index( ecl_region_type * ecl_region , int active_index); + + void ecl_region_intersection( ecl_region_type * region , const ecl_region_type * new_region ); + void ecl_region_union( ecl_region_type * region , const ecl_region_type * new_region ); + void ecl_region_subtract( ecl_region_type * region , const ecl_region_type * new_region); + void ecl_region_xor( ecl_region_type * region , const ecl_region_type * new_region); + + void ecl_region_select_smaller( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , float limit); + void ecl_region_deselect_smaller( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , float limit); + void ecl_region_select_larger( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , float limit); + void ecl_region_deselect_larger( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , float limit); + + void ecl_region_cmp_select_less( ecl_region_type * ecl_region , const ecl_kw_type * kw1 , const ecl_kw_type * kw2); + void ecl_region_cmp_deselect_less( ecl_region_type * ecl_region , const ecl_kw_type * kw1 , const ecl_kw_type * kw2); + void ecl_region_cmp_select_more( ecl_region_type * ecl_region , const ecl_kw_type * kw1 , const ecl_kw_type * kw2); + void ecl_region_cmp_deselect_more( ecl_region_type * ecl_region , const ecl_kw_type * kw1 , const ecl_kw_type * kw2); + + void ecl_region_select_in_cylinder( ecl_region_type * region , double x0 , double y0, double R); + void ecl_region_deselect_in_cylinder( ecl_region_type * region , double x0 , double y0, double R); + void ecl_region_select_in_zcylinder( ecl_region_type * region , double x0 , double y0, double R , double z1 , double z2); + void ecl_region_deselect_in_zcylinder( ecl_region_type * region , double x0 , double y0, double R, double z1 , double z2); + + void ecl_region_select_above_plane( ecl_region_type * region, const double n[3] , const double p[3]); + void ecl_region_select_below_plane( ecl_region_type * region, const double n[3] , const double p[3]); + void ecl_region_deselect_above_plane( ecl_region_type * region, const double n[3] , const double p[3]); + void ecl_region_deselect_below_plane( ecl_region_type * region, const double n[3] , const double p[3]); + + void ecl_region_select_inside_polygon( ecl_region_type * region , const geo_polygon_type * polygon); + void ecl_region_deselect_inside_polygon( ecl_region_type * region , const geo_polygon_type * polygon); + void ecl_region_select_outside_polygon( ecl_region_type * region , const geo_polygon_type * polygon); + void ecl_region_deselect_outside_polygon( ecl_region_type * region , const geo_polygon_type * polygon); + + void ecl_region_select_from_layer( ecl_region_type * region , const layer_type * layer , int k , int layer_value); + void ecl_region_deselect_from_layer( ecl_region_type * region , const layer_type * layer , int k , int layer_value); + void ecl_region_deselect_false( ecl_region_type * region , const ecl_kw_type * ecl_kw); + + +/*****************************************************************/ +/* Functions to manipulate ecl_kw instances . */ + + void ecl_region_set_kw_int( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , int value, bool force_active); + void ecl_region_set_kw_float( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , float value , bool force_active); + void ecl_region_set_kw_double( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , double value , bool force_active); + void ecl_region_kw_copy( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * src_kw , bool force_active); + int ecl_region_get_kw_size( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); + + void ecl_region_kw_iadd( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * delta_kw , bool force_active); + void ecl_region_kw_idiv( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * div_kw , bool force_active); + void ecl_region_kw_imul( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * mul_kw , bool force_active); + void ecl_region_kw_isub( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , const ecl_kw_type * delta_kw , bool force_active); + + bool ecl_region_equal( const ecl_region_type * region1 , const ecl_region_type * region2); + + void ecl_region_scale_kw_float( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , float value , bool force_active); + void ecl_region_scale_kw_double( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , double value , bool force_active); + void ecl_region_scale_kw_int( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , int value , bool force_active); + void ecl_region_shift_kw_int( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , int value , bool force_active); + void ecl_region_shift_kw_double( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , double value , bool force_active); + void ecl_region_shift_kw_float( ecl_region_type * ecl_region , ecl_kw_type * ecl_kw , float value , bool force_active); + + const int_vector_type * ecl_region_get_kw_index_list( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); + + +/*****************************************************************/ +/* set/get the name */ + void ecl_region_set_name( ecl_region_type * region , const char * name ); + const char * ecl_region_get_name( const ecl_region_type * region ); + +/*****************************************************************/ +/* Stupid cpp compat/legacy/cruft functions. */ + int ecl_region_get_active_size_cpp( ecl_region_type * region ); + int ecl_region_get_global_size_cpp( ecl_region_type * region ); + const int * ecl_region_get_active_list_cpp( ecl_region_type * region ); + const int * ecl_region_get_global_list_cpp( ecl_region_type * region ); + + +/*****************************************************************/ + + double ecl_region_sum_kw_double( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); + int ecl_region_sum_kw_int( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); + float ecl_region_sum_kw_float( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); + int ecl_region_sum_kw_bool( ecl_region_type * ecl_region , const ecl_kw_type * ecl_kw , bool force_active); + + + +UTIL_IS_INSTANCE_HEADER( ecl_region ); +UTIL_SAFE_CAST_HEADER( ecl_region ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.h index cf23fa5585..0b13aef8db 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.h @@ -1,85 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_rft_cell.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_RFT_CELL_H -#define ERT_ECL_RFT_CELL_H -#ifdef __cplusplus -extern "C" { -#endif +#include -#include - -#define ECL_RFT_CELL_INVALID_VALUE -1 - -typedef struct ecl_rft_cell_struct ecl_rft_cell_type; - - - - -UTIL_IS_INSTANCE_HEADER( ecl_rft_cell ); - - ecl_rft_cell_type * ecl_rft_cell_alloc_PLT( int i , - int j , - int k , - double depth , - double pressure , - double orat , - double grat , - double wrat , - double connection_start, - double connection_end, - double flowrate, - double oil_flowrate, - double gas_flowrate, - double water_flowrate); - - ecl_rft_cell_type * ecl_rft_cell_alloc_RFT( int i , int j , int k , double depth , double pressure , double swat , double sgas); - void ecl_rft_cell_free( ecl_rft_cell_type * cell ); - void ecl_rft_cell_free__( void * arg); - - bool ecl_rft_cell_ijk_equal( const ecl_rft_cell_type * cell , int i , int j , int k); - void ecl_rft_cell_get_ijk( const ecl_rft_cell_type * cell , int * i , int * j , int * k); - int ecl_rft_cell_get_i( const ecl_rft_cell_type * cell ); - int ecl_rft_cell_get_j( const ecl_rft_cell_type * cell ); - int ecl_rft_cell_get_k( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_depth( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_pressure( const ecl_rft_cell_type * cell ); - - double ecl_rft_cell_get_swat( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_sgas( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_soil( const ecl_rft_cell_type * cell ); - - double ecl_rft_cell_get_wrat( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_grat( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_orat( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_connection_start( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_connection_end( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_flowrate( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_oil_flowrate( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_gas_flowrate( const ecl_rft_cell_type * cell ); - double ecl_rft_cell_get_water_flowrate( const ecl_rft_cell_type * cell ); - - int ecl_rft_cell_cmp__( const void * arg1 , const void * arg2); - int ecl_rft_cell_cmp( const ecl_rft_cell_type * cell1 , const ecl_rft_cell_type * cell2); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.hpp index 65ba3f48fc..96ba37abd6 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_cell.hpp @@ -1,19 +1,85 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_rft_cell.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_RFT_CELL_H +#define ERT_ECL_RFT_CELL_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define ECL_RFT_CELL_INVALID_VALUE -1 + +typedef struct ecl_rft_cell_struct ecl_rft_cell_type; + + + + +UTIL_IS_INSTANCE_HEADER( ecl_rft_cell ); + + ecl_rft_cell_type * ecl_rft_cell_alloc_PLT( int i , + int j , + int k , + double depth , + double pressure , + double orat , + double grat , + double wrat , + double connection_start, + double connection_end, + double flowrate, + double oil_flowrate, + double gas_flowrate, + double water_flowrate); + + ecl_rft_cell_type * ecl_rft_cell_alloc_RFT( int i , int j , int k , double depth , double pressure , double swat , double sgas); + void ecl_rft_cell_free( ecl_rft_cell_type * cell ); + void ecl_rft_cell_free__( void * arg); + + bool ecl_rft_cell_ijk_equal( const ecl_rft_cell_type * cell , int i , int j , int k); + void ecl_rft_cell_get_ijk( const ecl_rft_cell_type * cell , int * i , int * j , int * k); + int ecl_rft_cell_get_i( const ecl_rft_cell_type * cell ); + int ecl_rft_cell_get_j( const ecl_rft_cell_type * cell ); + int ecl_rft_cell_get_k( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_depth( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_pressure( const ecl_rft_cell_type * cell ); + + double ecl_rft_cell_get_swat( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_sgas( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_soil( const ecl_rft_cell_type * cell ); + + double ecl_rft_cell_get_wrat( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_grat( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_orat( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_connection_start( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_connection_end( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_flowrate( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_oil_flowrate( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_gas_flowrate( const ecl_rft_cell_type * cell ); + double ecl_rft_cell_get_water_flowrate( const ecl_rft_cell_type * cell ); + + int ecl_rft_cell_cmp__( const void * arg1 , const void * arg2); + int ecl_rft_cell_cmp( const ecl_rft_cell_type * cell1 , const ecl_rft_cell_type * cell2); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.h index 5bf5443849..87f7e2b510 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.h @@ -1,60 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_rft_file.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_RFT_FILE_H -#define ERT_ECL_RFT_FILE_H -#ifdef __cplusplus -extern "C" { -#endif -#include - -#include - -#include -#include -#include - -typedef struct ecl_rft_file_struct ecl_rft_file_type; - -char * ecl_rft_file_alloc_case_filename(const char * case_input ); -const char * ecl_rft_file_get_filename( const ecl_rft_file_type * rft_file ); -ecl_rft_file_type * ecl_rft_file_alloc_case(const char * case_input ); -bool ecl_rft_file_case_has_rft( const char * case_input ); -ecl_rft_file_type * ecl_rft_file_alloc(const char * ); -void ecl_rft_file_free(ecl_rft_file_type * ); -void ecl_rft_file_block(const ecl_rft_file_type * , double , const char * , int , const double * , int * , int * , int *); -void ecl_rft_file_fprintf_rft_obs(const ecl_rft_file_type * , double , const char * , const char *, const char * , double); -ecl_rft_node_type * ecl_rft_file_get_node(const ecl_rft_file_type * , const char * ); - +#include -int ecl_rft_file_get_size__( const ecl_rft_file_type * rft_file, const char * well_pattern , time_t recording_time); -int ecl_rft_file_get_size( const ecl_rft_file_type * rft_file); -ecl_rft_node_type * ecl_rft_file_get_well_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time); -ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_file , int index); -ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_file , const char * well, int index); -bool ecl_rft_file_has_well( const ecl_rft_file_type * rft_file , const char * well); -int ecl_rft_file_get_well_occurences( const ecl_rft_file_type * rft_file , const char * well); -stringlist_type * ecl_rft_file_alloc_well_list(const ecl_rft_file_type * rft_file ); -int ecl_rft_file_get_num_wells( const ecl_rft_file_type * rft_file ); -void ecl_rft_file_free__( void * arg); -void ecl_rft_file_update(const char * rft_file_name, ecl_rft_node_type ** nodes,int num_nodes, ert_ecl_unit_enum unit_set); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.hpp index 3545ee0d42..02f23cb048 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_file.hpp @@ -1,19 +1,60 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_rft_file.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_RFT_FILE_H +#define ERT_ECL_RFT_FILE_H +#ifdef __cplusplus +extern "C" { +#endif +#include + +#include + +#include +#include +#include + +typedef struct ecl_rft_file_struct ecl_rft_file_type; + +char * ecl_rft_file_alloc_case_filename(const char * case_input ); +const char * ecl_rft_file_get_filename( const ecl_rft_file_type * rft_file ); +ecl_rft_file_type * ecl_rft_file_alloc_case(const char * case_input ); +bool ecl_rft_file_case_has_rft( const char * case_input ); +ecl_rft_file_type * ecl_rft_file_alloc(const char * ); +void ecl_rft_file_free(ecl_rft_file_type * ); +void ecl_rft_file_block(const ecl_rft_file_type * , double , const char * , int , const double * , int * , int * , int *); +void ecl_rft_file_fprintf_rft_obs(const ecl_rft_file_type * , double , const char * , const char *, const char * , double); +ecl_rft_node_type * ecl_rft_file_get_node(const ecl_rft_file_type * , const char * ); + + +int ecl_rft_file_get_size__( const ecl_rft_file_type * rft_file, const char * well_pattern , time_t recording_time); +int ecl_rft_file_get_size( const ecl_rft_file_type * rft_file); +ecl_rft_node_type * ecl_rft_file_get_well_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time); +ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_file , int index); +ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_file , const char * well, int index); +bool ecl_rft_file_has_well( const ecl_rft_file_type * rft_file , const char * well); +int ecl_rft_file_get_well_occurences( const ecl_rft_file_type * rft_file , const char * well); +stringlist_type * ecl_rft_file_alloc_well_list(const ecl_rft_file_type * rft_file ); +int ecl_rft_file_get_num_wells( const ecl_rft_file_type * rft_file ); +void ecl_rft_file_free__( void * arg); +void ecl_rft_file_update(const char * rft_file_name, ecl_rft_node_type ** nodes,int num_nodes, ert_ecl_unit_enum unit_set); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.h index b7f6418cbd..a7c5dcf9c4 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.h @@ -1,76 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_rft_node.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_RFT_NODE_H -#define ERT_ECL_RFT_NODE_H -#ifdef __cplusplus -extern "C" { -#endif -#include - -#include -#include -#include - -typedef enum { RFT = 1 , - PLT = 2 , - SEGMENT = 3 /* Not really implemented */ } ecl_rft_enum; - -typedef struct ecl_rft_node_struct ecl_rft_node_type; - -void ecl_rft_node_inplace_sort_cells( ecl_rft_node_type * rft_node ); -const ecl_rft_cell_type * ecl_rft_node_iget_cell_sorted( ecl_rft_node_type * rft_node , int index); -const ecl_rft_cell_type * ecl_rft_node_iget_cell( const ecl_rft_node_type * rft_node , int index); -const ecl_rft_cell_type * ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k); -void ecl_rft_node_fprintf_rft_obs(const ecl_rft_node_type * , double , const char * , const char * , double ); -ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_view_type * rft_view ); -void ecl_rft_node_free(ecl_rft_node_type * ); -void ecl_rft_node_free__(void * ); -time_t ecl_rft_node_get_date(const ecl_rft_node_type * ); -int ecl_rft_node_get_size(const ecl_rft_node_type * ); -const char * ecl_rft_node_get_well_name( const ecl_rft_node_type * rft_node ); -void ecl_rft_node_iget_ijk( const ecl_rft_node_type * rft_node , int index , int *i , int *j , int *k); - -bool ecl_rft_node_is_RFT( const ecl_rft_node_type * rft_node ); -bool ecl_rft_node_is_PLT( const ecl_rft_node_type * rft_node ); -bool ecl_rft_node_is_SEGMENT( const ecl_rft_node_type * rft_node ); -bool ecl_rft_node_is_MSW( const ecl_rft_node_type * rft_node ); - -double ecl_rft_node_iget_pressure( const ecl_rft_node_type * rft_node , int index); -double ecl_rft_node_iget_depth( const ecl_rft_node_type * rft_node , int index); -double ecl_rft_node_iget_wrat( const ecl_rft_node_type * rft_node , int index); -double ecl_rft_node_iget_grat( const ecl_rft_node_type * rft_node , int index); -double ecl_rft_node_iget_orat( const ecl_rft_node_type * rft_node , int index); - -double ecl_rft_node_iget_swat( const ecl_rft_node_type * rft_node , int index); -double ecl_rft_node_iget_sgas( const ecl_rft_node_type * rft_node , int index); -double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index); -void ecl_rft_node_fwrite(const ecl_rft_node_type * rft_node, fortio_type * fortio, ert_ecl_unit_enum unit_set); -double ecl_rft_node_get_days(const ecl_rft_node_type * rft_node ); -int ecl_rft_node_cmp( const ecl_rft_node_type * n1 , const ecl_rft_node_type * n2); - -void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell); -ecl_rft_node_type * ecl_rft_node_alloc_new(const char * well_name, const char * data_type_string, const time_t recording_date, const double days); - -ecl_rft_enum ecl_rft_node_get_type(const ecl_rft_node_type * rft_node); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.hpp index 623405e7d0..ab6dcd46c6 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rft_node.hpp @@ -1,20 +1,76 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_rft_node.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ +#ifndef ERT_ECL_RFT_NODE_H +#define ERT_ECL_RFT_NODE_H +#ifdef __cplusplus +extern "C" { +#endif +#include + +#include +#include +#include + +typedef enum { RFT = 1 , + PLT = 2 , + SEGMENT = 3 /* Not really implemented */ } ecl_rft_enum; + +typedef struct ecl_rft_node_struct ecl_rft_node_type; + +void ecl_rft_node_inplace_sort_cells( ecl_rft_node_type * rft_node ); +const ecl_rft_cell_type * ecl_rft_node_iget_cell_sorted( ecl_rft_node_type * rft_node , int index); +const ecl_rft_cell_type * ecl_rft_node_iget_cell( const ecl_rft_node_type * rft_node , int index); +const ecl_rft_cell_type * ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k); +void ecl_rft_node_fprintf_rft_obs(const ecl_rft_node_type * , double , const char * , const char * , double ); +ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_view_type * rft_view ); +void ecl_rft_node_free(ecl_rft_node_type * ); +void ecl_rft_node_free__(void * ); +time_t ecl_rft_node_get_date(const ecl_rft_node_type * ); +int ecl_rft_node_get_size(const ecl_rft_node_type * ); +const char * ecl_rft_node_get_well_name( const ecl_rft_node_type * rft_node ); +void ecl_rft_node_iget_ijk( const ecl_rft_node_type * rft_node , int index , int *i , int *j , int *k); + +bool ecl_rft_node_is_RFT( const ecl_rft_node_type * rft_node ); +bool ecl_rft_node_is_PLT( const ecl_rft_node_type * rft_node ); +bool ecl_rft_node_is_SEGMENT( const ecl_rft_node_type * rft_node ); +bool ecl_rft_node_is_MSW( const ecl_rft_node_type * rft_node ); + +double ecl_rft_node_iget_pressure( const ecl_rft_node_type * rft_node , int index); +double ecl_rft_node_iget_depth( const ecl_rft_node_type * rft_node , int index); +double ecl_rft_node_iget_wrat( const ecl_rft_node_type * rft_node , int index); +double ecl_rft_node_iget_grat( const ecl_rft_node_type * rft_node , int index); +double ecl_rft_node_iget_orat( const ecl_rft_node_type * rft_node , int index); + +double ecl_rft_node_iget_swat( const ecl_rft_node_type * rft_node , int index); +double ecl_rft_node_iget_sgas( const ecl_rft_node_type * rft_node , int index); +double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index); +void ecl_rft_node_fwrite(const ecl_rft_node_type * rft_node, fortio_type * fortio, ert_ecl_unit_enum unit_set); +double ecl_rft_node_get_days(const ecl_rft_node_type * rft_node ); +int ecl_rft_node_cmp( const ecl_rft_node_type * n1 , const ecl_rft_node_type * n2); + +void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell); +ecl_rft_node_type * ecl_rft_node_alloc_new(const char * well_name, const char * data_type_string, const time_t recording_date, const double days); + +ecl_rft_enum ecl_rft_node_get_type(const ecl_rft_node_type * rft_node); + +#ifdef __cplusplus +} +#endif +#endif -#include diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.h index d558eac333..a52d84d348 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.h @@ -1,49 +1,9 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ecl_rst_file.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_ECL_RST_FILE_H -#define ERT_ECL_RST_FILE_H -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct ecl_rst_file_struct ecl_rst_file_type; - - - ecl_rst_file_type * ecl_rst_file_open_read( const char * filename ); - ecl_rst_file_type * ecl_rst_file_open_write( const char * filename ); - ecl_rst_file_type * ecl_rst_file_open_append( const char * filename ); - ecl_rst_file_type * ecl_rst_file_open_write_seek( const char * filename , int report_step); - void ecl_rst_file_close( ecl_rst_file_type * rst_file ); - - void ecl_rst_file_start_solution( ecl_rst_file_type * rst_file ); - void ecl_rst_file_end_solution( ecl_rst_file_type * rst_file ); - void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file , int seqnum, ecl_rsthead_type * rsthead_data ); - void ecl_rst_file_add_kw(ecl_rst_file_type * rst_file , const ecl_kw_type * ecl_kw ); - offset_type ecl_rst_file_ftell(const ecl_rst_file_type * rst_file ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.hpp index 9ecc8a91e1..f4d6e5d4a8 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rst_file.hpp @@ -1,20 +1,49 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ecl_rst_file.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_RST_FILE_H +#define ERT_ECL_RST_FILE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct ecl_rst_file_struct ecl_rst_file_type; + + + ecl_rst_file_type * ecl_rst_file_open_read( const char * filename ); + ecl_rst_file_type * ecl_rst_file_open_write( const char * filename ); + ecl_rst_file_type * ecl_rst_file_open_append( const char * filename ); + ecl_rst_file_type * ecl_rst_file_open_write_seek( const char * filename , int report_step); + void ecl_rst_file_close( ecl_rst_file_type * rst_file ); + + void ecl_rst_file_start_solution( ecl_rst_file_type * rst_file ); + void ecl_rst_file_end_solution( ecl_rst_file_type * rst_file ); + void ecl_rst_file_fwrite_header( ecl_rst_file_type * rst_file , int seqnum, ecl_rsthead_type * rsthead_data ); + void ecl_rst_file_add_kw(ecl_rst_file_type * rst_file , const ecl_kw_type * ecl_kw ); + offset_type ecl_rst_file_ftell(const ecl_rst_file_type * rst_file ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.h index cf58ec3e53..f6e79cfb5c 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.h @@ -1,104 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_RSTHEAD.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_RSTHEAD_H -#define ERT_ECL_RSTHEAD_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include -#include - - - typedef struct { - // The report step is from the SEQNUM keyword for unified files, - // and inferred from the filename for non unified files. - int report_step; - int day; - int year; - int month; - time_t sim_time; - int version; // 100, 300, 500 (Eclipse300-Thermal) - int phase_sum; // Oil = 1 Gas = 2 Water = 4 - - ert_ecl_unit_enum unit_system; - - int nx; - int ny; - int nz; - int nactive; - /*-----------------------------------------------------------------*/ - /* All fields below the line are taken literally (apart from - lowercasing) from the section about restart files in the - ECLIPSE File Formats Reference Manual. The elements typically - serve as dimensions in the ?WEL, ?SEG and ?CON arrays. - */ - - // Pure well properties - int nwells; // Number of wells - int niwelz; // Number of elements pr well in IWEL array - int nzwelz; // Number of 8 character words pr well in ZWEL array - int nxwelz; // Number of elements pr well in XWEL array. - - // Connection properties - int niconz; // Number of elements per completion in ICON array - int ncwmax; // Maximum number of completions per well - int nsconz; // Number of elements per completion in SCON array - int nxconz; // Number of elements per completion in XCON array - - // Segment properties - int nisegz; // Number of entries pr segment in the ISEG array - int nsegmx; // The maximum number of segments pr well - int nswlmx; // The maximum number of segmented wells - int nlbrmx; // The maximum number of lateral branches pr well - int nilbrz; // The number of entries pr segment in ILBR array - int nrsegz; // The number of entries pr segment in RSEG array - - // Properteies from the LOGIHEAD keyword: - bool dualp; - - - // Properties from the DOUBHEAD keyword: - double sim_days; - } ecl_rsthead_type; - - +#include - void ecl_rsthead_free( ecl_rsthead_type * rsthead ); - ecl_rsthead_type * ecl_rsthead_alloc_from_kw( int report_step , const ecl_kw_type * intehead_kw , const ecl_kw_type * doubhead_kw , const ecl_kw_type * logihead_kw ); - ecl_rsthead_type * ecl_rsthead_alloc( const ecl_file_view_type * rst_file , int report_step); - ecl_rsthead_type * ecl_rsthead_alloc_empty(void); - time_t ecl_rsthead_date( const ecl_kw_type * intehead_kw ); - void ecl_rsthead_fprintf( const ecl_rsthead_type * header , FILE * stream); - void ecl_rsthead_fprintf_struct( const ecl_rsthead_type * header , FILE * stream); - bool ecl_rsthead_equal( const ecl_rsthead_type * header1 , const ecl_rsthead_type * header2); - double ecl_rsthead_get_sim_days( const ecl_rsthead_type * header ); - int ecl_rsthead_get_report_step( const ecl_rsthead_type * header ); - time_t ecl_rsthead_get_sim_time( const ecl_rsthead_type * header ); - int ecl_rsthead_get_nxconz( const ecl_rsthead_type * rsthead ); - int ecl_rsthead_get_ncwmax( const ecl_rsthead_type * rsthead ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.hpp index 44550950a1..8c91a65e16 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_rsthead.hpp @@ -1,19 +1,104 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_RSTHEAD.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_RSTHEAD_H +#define ERT_ECL_RSTHEAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include + + + typedef struct { + // The report step is from the SEQNUM keyword for unified files, + // and inferred from the filename for non unified files. + int report_step; + int day; + int year; + int month; + time_t sim_time; + int version; // 100, 300, 500 (Eclipse300-Thermal) + int phase_sum; // Oil = 1 Gas = 2 Water = 4 + + ert_ecl_unit_enum unit_system; + + int nx; + int ny; + int nz; + int nactive; + /*-----------------------------------------------------------------*/ + /* All fields below the line are taken literally (apart from + lowercasing) from the section about restart files in the + ECLIPSE File Formats Reference Manual. The elements typically + serve as dimensions in the ?WEL, ?SEG and ?CON arrays. + */ + + // Pure well properties + int nwells; // Number of wells + int niwelz; // Number of elements pr well in IWEL array + int nzwelz; // Number of 8 character words pr well in ZWEL array + int nxwelz; // Number of elements pr well in XWEL array. + + // Connection properties + int niconz; // Number of elements per completion in ICON array + int ncwmax; // Maximum number of completions per well + int nsconz; // Number of elements per completion in SCON array + int nxconz; // Number of elements per completion in XCON array + + // Segment properties + int nisegz; // Number of entries pr segment in the ISEG array + int nsegmx; // The maximum number of segments pr well + int nswlmx; // The maximum number of segmented wells + int nlbrmx; // The maximum number of lateral branches pr well + int nilbrz; // The number of entries pr segment in ILBR array + int nrsegz; // The number of entries pr segment in RSEG array + + // Properteies from the LOGIHEAD keyword: + bool dualp; + + + // Properties from the DOUBHEAD keyword: + double sim_days; + } ecl_rsthead_type; + + + + void ecl_rsthead_free( ecl_rsthead_type * rsthead ); + ecl_rsthead_type * ecl_rsthead_alloc_from_kw( int report_step , const ecl_kw_type * intehead_kw , const ecl_kw_type * doubhead_kw , const ecl_kw_type * logihead_kw ); + ecl_rsthead_type * ecl_rsthead_alloc( const ecl_file_view_type * rst_file , int report_step); + ecl_rsthead_type * ecl_rsthead_alloc_empty(void); + time_t ecl_rsthead_date( const ecl_kw_type * intehead_kw ); + void ecl_rsthead_fprintf( const ecl_rsthead_type * header , FILE * stream); + void ecl_rsthead_fprintf_struct( const ecl_rsthead_type * header , FILE * stream); + bool ecl_rsthead_equal( const ecl_rsthead_type * header1 , const ecl_rsthead_type * header2); + double ecl_rsthead_get_sim_days( const ecl_rsthead_type * header ); + int ecl_rsthead_get_report_step( const ecl_rsthead_type * header ); + time_t ecl_rsthead_get_sim_time( const ecl_rsthead_type * header ); + int ecl_rsthead_get_nxconz( const ecl_rsthead_type * rsthead ); + int ecl_rsthead_get_ncwmax( const ecl_rsthead_type * rsthead ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.h index f42e5c338b..797a587f96 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.h @@ -1,158 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_smspec.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_SMSPEC -#define ERT_ECL_SMSPEC - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#include -#include - -#include -#include - -typedef struct ecl_smspec_struct ecl_smspec_type; - - -/** - These are the different variable types, see table 3.4 in the - ECLIPFE file format docuemntation for naming conventions. - - Only the variable types marked with "X" below are supported in the - remaining implementation. To add support for a new variable type - the functions smspec_node_alloc(), ecl_smsepec_fread_header() and - ecl_smspec_install_gen_key() must be updated. -*/ - - int * ecl_smspec_alloc_mapping( const ecl_smspec_type * self, const ecl_smspec_type * other); - const int_vector_type * ecl_smspec_get_index_map( const ecl_smspec_type * smspec ); - void ecl_smspec_index_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node); - void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node); - void ecl_smspec_add_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node ); - ecl_smspec_var_type ecl_smspec_iget_var_type( const ecl_smspec_type * smspec , int index ); - bool ecl_smspec_needs_num( ecl_smspec_var_type var_type ); - bool ecl_smspec_needs_wgname( ecl_smspec_var_type var_type ); - const char * ecl_smspec_get_var_type_name( ecl_smspec_var_type var_type ); - ecl_smspec_var_type ecl_smspec_identify_var_type(const char * var); - ecl_smspec_type * ecl_smspec_alloc_empty(bool write_mode , const char * key_join_string); - - ecl_smspec_type * ecl_smspec_alloc_restart_writer( const char * key_join_string , const char * restart_case, int restart_step, time_t sim_start , bool time_in_days , int nx , int ny , int nz); - - ecl_smspec_type * ecl_smspec_alloc_writer( const char * key_join_string , time_t sim_start , bool time_in_days , int nx , int ny , int nz); - void ecl_smspec_fwrite( const ecl_smspec_type * smspec , const char * ecl_case , bool fmt_file ); - - ecl_smspec_type * ecl_smspec_fread_alloc(const char *header_file, const char * key_join_string , bool include_restart); - void ecl_smspec_free( ecl_smspec_type *); - - int ecl_smspec_get_date_day_index( const ecl_smspec_type * smspec ); - int ecl_smspec_get_date_month_index( const ecl_smspec_type * smspec ); - int ecl_smspec_get_date_year_index( const ecl_smspec_type * smspec ); - - - const smspec_node_type * ecl_smspec_get_well_var_node( const ecl_smspec_type * smspec , const char * well , const char * var); - int ecl_smspec_get_well_var_params_index(const ecl_smspec_type * ecl_smspec , const char * well , const char *var); - bool ecl_smspec_has_well_var(const ecl_smspec_type * ecl_smspec , const char * well , const char *var); - - const smspec_node_type * ecl_smspec_get_group_var_node( const ecl_smspec_type * smspec , const char * group , const char * var); - int ecl_smspec_get_group_var_params_index(const ecl_smspec_type * ecl_smspec , const char * group , const char *var); - bool ecl_smspec_has_group_var(const ecl_smspec_type * ecl_smspec , const char * group , const char *var); - - const smspec_node_type * ecl_smspec_get_field_var_node( const ecl_smspec_type * smspec , const char * var); - int ecl_smspec_get_field_var_params_index(const ecl_smspec_type * ecl_smspec , const char *var); - bool ecl_smspec_has_field_var(const ecl_smspec_type * ecl_smspec , const char *var); - - const smspec_node_type * ecl_smspec_get_region_var_node(const ecl_smspec_type * ecl_smspec , const char *region_var , int region_nr); - int ecl_smspec_get_region_var_params_index(const ecl_smspec_type * ecl_smspec , const char * region_var , int region_nr); - bool ecl_smspec_has_region_var(const ecl_smspec_type * ecl_smspec , const char * region_var , int region_nr); - - const smspec_node_type * ecl_smspec_get_misc_var_node(const ecl_smspec_type * ecl_smspec , const char *var); - int ecl_smspec_get_misc_var_params_index(const ecl_smspec_type * ecl_smspec , const char *var); - bool ecl_smspec_has_misc_var(const ecl_smspec_type * ecl_smspec , const char *var); - - const smspec_node_type * ecl_smspec_get_block_var_node(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr); - int ecl_smspec_get_block_var_params_index(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr); - bool ecl_smspec_has_block_var(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr); - - const smspec_node_type * ecl_smspec_get_block_var_node_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k); - int ecl_smspec_get_block_var_params_index_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k); - bool ecl_smspec_has_block_var_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k); - - const smspec_node_type * ecl_smspec_get_well_completion_var_node(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr); - int ecl_smspec_get_well_completion_var_params_index(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr); - bool ecl_smspec_has_well_completion_var(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr); - - const smspec_node_type * ecl_smspec_get_general_var_node( const ecl_smspec_type * smspec , const char * lookup_kw ); - int ecl_smspec_get_general_var_params_index(const ecl_smspec_type * ecl_smspec , const char * lookup_kw); - bool ecl_smspec_has_general_var(const ecl_smspec_type * ecl_smspec , const char * lookup_kw); - const char * ecl_smspec_get_general_var_unit( const ecl_smspec_type * ecl_smspec , const char * lookup_kw); - - - //bool ecl_smspec_general_is_total(const ecl_smspec_type * ecl_smspec , const char * gen_key); - //bool ecl_smspec_is_rate(const ecl_smspec_type * smspec , int kw_index); - //ecl_smspec_var_type ecl_smspec_iget_var_type( const ecl_smspec_type * smspec , int index ); - //const char * ecl_smspec_iget_unit( const ecl_smspec_type * smspec , int index ); - //int ecl_smspec_iget_num( const ecl_smspec_type * smspec , int index ); - //const char * ecl_smspec_iget_wgname( const ecl_smspec_type * smspec , int index ); - //const char * ecl_smspec_iget_keyword( const ecl_smspec_type * smspec , int index ); - - - - - void ecl_smspec_init_var( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node , const char * keyword , const char * wgname , int num, const char * unit ); - void ecl_smspec_select_matching_general_var_list( const ecl_smspec_type * smspec , const char * pattern , stringlist_type * keys); - stringlist_type * ecl_smspec_alloc_matching_general_var_list(const ecl_smspec_type * smspec , const char * pattern); - - int ecl_smspec_get_time_seconds( const ecl_smspec_type * ecl_smspec ); - int ecl_smspec_get_time_index( const ecl_smspec_type * ecl_smspec ); - time_t ecl_smspec_get_start_time(const ecl_smspec_type * ); - /*****************************************************************/ - bool ecl_smspec_get_formatted( const ecl_smspec_type * ecl_smspec); - const char * ecl_smspec_get_header_file( const ecl_smspec_type * ecl_smspec ); - stringlist_type * ecl_smspec_alloc_well_list( const ecl_smspec_type * smspec , const char * pattern); - stringlist_type * ecl_smspec_alloc_group_list( const ecl_smspec_type * smspec , const char * pattern); - stringlist_type * ecl_smspec_alloc_well_var_list( const ecl_smspec_type * smspec ); - const char * ecl_smspec_get_simulation_path(const ecl_smspec_type * ecl_smspec); - int ecl_smspec_get_restart_step(const ecl_smspec_type * ecl_smspec); - const char * ecl_smspec_get_restart_case( const ecl_smspec_type * ecl_smspec); - const char * ecl_smspec_get_join_string( const ecl_smspec_type * smspec); - const float_vector_type * ecl_smspec_get_params_default( const ecl_smspec_type * ecl_smspec ); - void ecl_smspec_update_wgname( ecl_smspec_type * smspec , smspec_node_type * node , const char * wgname ); - - const int * ecl_smspec_get_grid_dims( const ecl_smspec_type * smspec ); - int ecl_smspec_get_params_size( const ecl_smspec_type * smspec ); - int ecl_smspec_num_nodes( const ecl_smspec_type * smspec); - const smspec_node_type * ecl_smspec_iget_node( const ecl_smspec_type * smspec , int index ); - void ecl_smspec_lock( ecl_smspec_type * smspec ); - - - char * ecl_smspec_alloc_well_key( const ecl_smspec_type * smspec , const char * keyword , const char * wgname); - bool ecl_smspec_equal( const ecl_smspec_type * self , const ecl_smspec_type * other); +#include - void ecl_smspec_sort( ecl_smspec_type * smspec ); - ert_ecl_unit_enum ecl_smspec_get_unit_system(const ecl_smspec_type * smspec); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.hpp index 7f59f6a7fe..5bfef485f8 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_smspec.hpp @@ -1,19 +1,158 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_smspec.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_SMSPEC +#define ERT_ECL_SMSPEC + + +#include +#include + +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ecl_smspec_struct ecl_smspec_type; + + +/** + These are the different variable types, see table 3.4 in the + ECLIPFE file format docuemntation for naming conventions. + + Only the variable types marked with "X" below are supported in the + remaining implementation. To add support for a new variable type + the functions smspec_node_alloc(), ecl_smsepec_fread_header() and + ecl_smspec_install_gen_key() must be updated. +*/ + + int * ecl_smspec_alloc_mapping( const ecl_smspec_type * self, const ecl_smspec_type * other); + const int_vector_type * ecl_smspec_get_index_map( const ecl_smspec_type * smspec ); + void ecl_smspec_index_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node); + void ecl_smspec_insert_node(ecl_smspec_type * ecl_smspec, smspec_node_type * smspec_node); + void ecl_smspec_add_node( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node ); + ecl_smspec_var_type ecl_smspec_iget_var_type( const ecl_smspec_type * smspec , int index ); + bool ecl_smspec_needs_num( ecl_smspec_var_type var_type ); + bool ecl_smspec_needs_wgname( ecl_smspec_var_type var_type ); + const char * ecl_smspec_get_var_type_name( ecl_smspec_var_type var_type ); + ecl_smspec_var_type ecl_smspec_identify_var_type(const char * var); + ecl_smspec_type * ecl_smspec_alloc_empty(bool write_mode , const char * key_join_string); + + ecl_smspec_type * ecl_smspec_alloc_restart_writer( const char * key_join_string , const char * restart_case, int restart_step, time_t sim_start , bool time_in_days , int nx , int ny , int nz); + + ecl_smspec_type * ecl_smspec_alloc_writer( const char * key_join_string , time_t sim_start , bool time_in_days , int nx , int ny , int nz); + void ecl_smspec_fwrite( const ecl_smspec_type * smspec , const char * ecl_case , bool fmt_file ); + + ecl_smspec_type * ecl_smspec_fread_alloc(const char *header_file, const char * key_join_string , bool include_restart); + void ecl_smspec_free( ecl_smspec_type *); + + int ecl_smspec_get_date_day_index( const ecl_smspec_type * smspec ); + int ecl_smspec_get_date_month_index( const ecl_smspec_type * smspec ); + int ecl_smspec_get_date_year_index( const ecl_smspec_type * smspec ); + + + const smspec_node_type * ecl_smspec_get_well_var_node( const ecl_smspec_type * smspec , const char * well , const char * var); + int ecl_smspec_get_well_var_params_index(const ecl_smspec_type * ecl_smspec , const char * well , const char *var); + bool ecl_smspec_has_well_var(const ecl_smspec_type * ecl_smspec , const char * well , const char *var); + + const smspec_node_type * ecl_smspec_get_group_var_node( const ecl_smspec_type * smspec , const char * group , const char * var); + int ecl_smspec_get_group_var_params_index(const ecl_smspec_type * ecl_smspec , const char * group , const char *var); + bool ecl_smspec_has_group_var(const ecl_smspec_type * ecl_smspec , const char * group , const char *var); + + const smspec_node_type * ecl_smspec_get_field_var_node( const ecl_smspec_type * smspec , const char * var); + int ecl_smspec_get_field_var_params_index(const ecl_smspec_type * ecl_smspec , const char *var); + bool ecl_smspec_has_field_var(const ecl_smspec_type * ecl_smspec , const char *var); + + const smspec_node_type * ecl_smspec_get_region_var_node(const ecl_smspec_type * ecl_smspec , const char *region_var , int region_nr); + int ecl_smspec_get_region_var_params_index(const ecl_smspec_type * ecl_smspec , const char * region_var , int region_nr); + bool ecl_smspec_has_region_var(const ecl_smspec_type * ecl_smspec , const char * region_var , int region_nr); + + const smspec_node_type * ecl_smspec_get_misc_var_node(const ecl_smspec_type * ecl_smspec , const char *var); + int ecl_smspec_get_misc_var_params_index(const ecl_smspec_type * ecl_smspec , const char *var); + bool ecl_smspec_has_misc_var(const ecl_smspec_type * ecl_smspec , const char *var); + + const smspec_node_type * ecl_smspec_get_block_var_node(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr); + int ecl_smspec_get_block_var_params_index(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr); + bool ecl_smspec_has_block_var(const ecl_smspec_type * ecl_smspec , const char * block_var , int block_nr); + + const smspec_node_type * ecl_smspec_get_block_var_node_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k); + int ecl_smspec_get_block_var_params_index_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k); + bool ecl_smspec_has_block_var_ijk(const ecl_smspec_type * ecl_smspec , const char * block_var , int i , int j , int k); + + const smspec_node_type * ecl_smspec_get_well_completion_var_node(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr); + int ecl_smspec_get_well_completion_var_params_index(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr); + bool ecl_smspec_has_well_completion_var(const ecl_smspec_type * ecl_smspec , const char * well , const char *var, int cell_nr); + + const smspec_node_type * ecl_smspec_get_general_var_node( const ecl_smspec_type * smspec , const char * lookup_kw ); + int ecl_smspec_get_general_var_params_index(const ecl_smspec_type * ecl_smspec , const char * lookup_kw); + bool ecl_smspec_has_general_var(const ecl_smspec_type * ecl_smspec , const char * lookup_kw); + const char * ecl_smspec_get_general_var_unit( const ecl_smspec_type * ecl_smspec , const char * lookup_kw); + + + //bool ecl_smspec_general_is_total(const ecl_smspec_type * ecl_smspec , const char * gen_key); + //bool ecl_smspec_is_rate(const ecl_smspec_type * smspec , int kw_index); + //ecl_smspec_var_type ecl_smspec_iget_var_type( const ecl_smspec_type * smspec , int index ); + //const char * ecl_smspec_iget_unit( const ecl_smspec_type * smspec , int index ); + //int ecl_smspec_iget_num( const ecl_smspec_type * smspec , int index ); + //const char * ecl_smspec_iget_wgname( const ecl_smspec_type * smspec , int index ); + //const char * ecl_smspec_iget_keyword( const ecl_smspec_type * smspec , int index ); + + + + + void ecl_smspec_init_var( ecl_smspec_type * ecl_smspec , smspec_node_type * smspec_node , const char * keyword , const char * wgname , int num, const char * unit ); + void ecl_smspec_select_matching_general_var_list( const ecl_smspec_type * smspec , const char * pattern , stringlist_type * keys); + stringlist_type * ecl_smspec_alloc_matching_general_var_list(const ecl_smspec_type * smspec , const char * pattern); + + int ecl_smspec_get_time_seconds( const ecl_smspec_type * ecl_smspec ); + int ecl_smspec_get_time_index( const ecl_smspec_type * ecl_smspec ); + time_t ecl_smspec_get_start_time(const ecl_smspec_type * ); + /*****************************************************************/ + bool ecl_smspec_get_formatted( const ecl_smspec_type * ecl_smspec); + const char * ecl_smspec_get_header_file( const ecl_smspec_type * ecl_smspec ); + stringlist_type * ecl_smspec_alloc_well_list( const ecl_smspec_type * smspec , const char * pattern); + stringlist_type * ecl_smspec_alloc_group_list( const ecl_smspec_type * smspec , const char * pattern); + stringlist_type * ecl_smspec_alloc_well_var_list( const ecl_smspec_type * smspec ); + const char * ecl_smspec_get_simulation_path(const ecl_smspec_type * ecl_smspec); + int ecl_smspec_get_first_step(const ecl_smspec_type * ecl_smspec); + int ecl_smspec_get_restart_step(const ecl_smspec_type * ecl_smspec); + const char * ecl_smspec_get_restart_case( const ecl_smspec_type * ecl_smspec); + const char * ecl_smspec_get_join_string( const ecl_smspec_type * smspec); + const float_vector_type * ecl_smspec_get_params_default( const ecl_smspec_type * ecl_smspec ); + + const int * ecl_smspec_get_grid_dims( const ecl_smspec_type * smspec ); + int ecl_smspec_get_params_size( const ecl_smspec_type * smspec ); + int ecl_smspec_num_nodes( const ecl_smspec_type * smspec); + const smspec_node_type * ecl_smspec_iget_node( const ecl_smspec_type * smspec , int index ); + + + char * ecl_smspec_alloc_well_key( const ecl_smspec_type * smspec , const char * keyword , const char * wgname); + bool ecl_smspec_equal( const ecl_smspec_type * self , const ecl_smspec_type * other); + + void ecl_smspec_sort( ecl_smspec_type * smspec ); + ert_ecl_unit_enum ecl_smspec_get_unit_system(const ecl_smspec_type * smspec); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.h index 71d0747a1f..aa51918375 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.h @@ -1,54 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_subsidence.h' is part of ERT - Ensemble based - Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_SUBSIDENCE_H -#define ERT_ECL_SUBSIDENCE_H -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include - - typedef struct ecl_subsidence_struct ecl_subsidence_type; - typedef struct ecl_subsidence_survey_struct ecl_subsidence_survey_type; - - - void ecl_subsidence_free( ecl_subsidence_type * ecl_subsidence_config ); - ecl_subsidence_type * ecl_subsidence_alloc( const ecl_grid_type * ecl_grid, const ecl_file_type * init_file ); - ecl_subsidence_survey_type * ecl_subsidence_add_survey_PRESSURE( ecl_subsidence_type * subsidence , - const char * name , const ecl_file_view_type * restart_view ); - - bool ecl_subsidence_has_survey( const ecl_subsidence_type * subsidence , const char * name); - double ecl_subsidence_eval( const ecl_subsidence_type * subsidence , - const char * base, const char * monitor , - ecl_region_type * region , - double utm_x, double utm_y , double depth, double compressibility, double poisson_ratio); - - double ecl_subsidence_eval_geertsma( const ecl_subsidence_type * subsidence , const char * base, const char * monitor , ecl_region_type * region , - double utm_x, double utm_y , double depth, - double youngs_modulus, double poisson_ratio, double seabed); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.hpp index a8b535ef8a..84f8977fbb 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_subsidence.hpp @@ -1,19 +1,54 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_subsidence.h' is part of ERT - Ensemble based + Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_SUBSIDENCE_H +#define ERT_ECL_SUBSIDENCE_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + + typedef struct ecl_subsidence_struct ecl_subsidence_type; + typedef struct ecl_subsidence_survey_struct ecl_subsidence_survey_type; + + + void ecl_subsidence_free( ecl_subsidence_type * ecl_subsidence_config ); + ecl_subsidence_type * ecl_subsidence_alloc( const ecl_grid_type * ecl_grid, const ecl_file_type * init_file ); + ecl_subsidence_survey_type * ecl_subsidence_add_survey_PRESSURE( ecl_subsidence_type * subsidence , + const char * name , const ecl_file_view_type * restart_view ); + + bool ecl_subsidence_has_survey( const ecl_subsidence_type * subsidence , const char * name); + double ecl_subsidence_eval( const ecl_subsidence_type * subsidence , + const char * base, const char * monitor , + ecl_region_type * region , + double utm_x, double utm_y , double depth, double compressibility, double poisson_ratio); + + double ecl_subsidence_eval_geertsma( const ecl_subsidence_type * subsidence , const char * base, const char * monitor , ecl_region_type * region , + double utm_x, double utm_y , double depth, + double youngs_modulus, double poisson_ratio, double seabed); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.h index 780add6010..8487b7b1e7 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.h @@ -1,289 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_sum.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_SUM_H -#define ERT_ECL_SUM_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - - typedef struct { - char * locale; - const char * sep; - char * newline; - char * value_fmt; - const char * date_fmt; - char * days_fmt; - char * header_fmt; - bool print_header; - bool print_dash; - const char * date_header; - char * date_dash; - char * value_dash; - } ecl_sum_fmt_type; - - - /*****************************************************************/ - /* This is a forward declaration. */ -typedef struct ecl_sum_vector_struct ecl_sum_vector_type; - -typedef struct ecl_sum_struct ecl_sum_type; - - void ecl_sum_fmt_init_summary_x( const ecl_sum_type * ecl_sum , ecl_sum_fmt_type * fmt ); - double ecl_sum_get_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const smspec_node_type * node); - double ecl_sum_get_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const smspec_node_type * node); - double ecl_sum_time2days( const ecl_sum_type * ecl_sum , time_t sim_time); - - void ecl_sum_set_unified( ecl_sum_type * ecl_sum , bool unified ); - void ecl_sum_set_fmt_case( ecl_sum_type * ecl_sum , bool fmt_case ); - - int ecl_sum_get_report_step_from_time( const ecl_sum_type * sum , time_t sim_time); - int ecl_sum_get_report_step_from_days( const ecl_sum_type * sum , double sim_days); - bool ecl_sum_check_sim_time( const ecl_sum_type * sum , time_t sim_time); - bool ecl_sum_check_sim_days( const ecl_sum_type * sum , double sim_days); - const char * ecl_sum_get_keyword( const ecl_sum_type * sum , const char * gen_key ); - const char * ecl_sum_get_wgname( const ecl_sum_type * sum , const char * gen_key ); - const char * ecl_sum_get_unit( const ecl_sum_type * sum , const char * gen_key ); - int ecl_sum_get_num( const ecl_sum_type * sum , const char * gen_key ); - - double ecl_sum_iget( const ecl_sum_type * ecl_sum , int time_index , int param_index); - int ecl_sum_iget_num( const ecl_sum_type * sum , int param_index ); - const char * ecl_sum_iget_wgname( const ecl_sum_type * sum , int param_index ); - const char * ecl_sum_iget_keyword( const ecl_sum_type * sum , int param_index ); - int ecl_sum_get_data_length( const ecl_sum_type * ecl_sum ); - void ecl_sum_scale_vector( ecl_sum_type * ecl_sum, int index, double scalar ); - void ecl_sum_shift_vector( ecl_sum_type * ecl_sum, int index, double addend ); - double ecl_sum_iget_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , int param_index); - double ecl_sum_iget_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , int param_index ); - - - - void ecl_sum_summarize( const ecl_sum_type * ecl_sum , FILE * stream ); - bool ecl_sum_general_is_total(const ecl_sum_type * ecl_sum , const char * gen_key); - void ecl_sum_free_data(ecl_sum_type * ); - void ecl_sum_free__(void * ); - void ecl_sum_free(ecl_sum_type * ); - ecl_sum_type * ecl_sum_fread_alloc(const char * , const stringlist_type * data_files, const char * key_join_string, bool include_restart); - ecl_sum_type * ecl_sum_fread_alloc_case(const char * , const char * key_join_string); - ecl_sum_type * ecl_sum_fread_alloc_case__(const char * , const char * key_join_string , bool include_restart); - ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times); - bool ecl_sum_case_exists( const char * input_file ); - - /* Accessor functions : */ - double ecl_sum_get_well_var(const ecl_sum_type * ecl_sum , int time_index , const char * well , const char *var); - bool ecl_sum_has_well_var(const ecl_sum_type * ecl_sum , const char * well , const char *var); - double ecl_sum_get_well_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * well , const char * var); - double ecl_sum_get_well_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * well , const char * var); - - double ecl_sum_get_group_var(const ecl_sum_type * ecl_sum , int time_index , const char * group , const char *var); - bool ecl_sum_has_group_var(const ecl_sum_type * ecl_sum , const char * group , const char *var); - - double ecl_sum_get_field_var(const ecl_sum_type * ecl_sum , int time_index , const char *var); - bool ecl_sum_has_field_var(const ecl_sum_type * ecl_sum , const char *var); - double ecl_sum_get_field_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * var); - double ecl_sum_get_field_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * var); - - double ecl_sum_get_block_var(const ecl_sum_type * ecl_sum , int time_index , const char * block_var , int block_nr); - int ecl_sum_get_block_var_index(const ecl_sum_type * ecl_sum , const char * block_var , int block_nr); - bool ecl_sum_has_block_var(const ecl_sum_type * ecl_sum , const char * block_var , int block_nr); - double ecl_sum_get_block_var_ijk(const ecl_sum_type * ecl_sum , int time_index , const char * block_var , int i , int j , int k); - int ecl_sum_get_block_var_index_ijk(const ecl_sum_type * ecl_sum , const char * block_var , int i , int j , int k); - bool ecl_sum_has_block_var_ijk(const ecl_sum_type * ecl_sum , const char * block_var , int i , int j , int k); - - double ecl_sum_get_region_var(const ecl_sum_type * ecl_sum , int time_index , const char *var , int region_nr); - bool ecl_sum_has_region_var(const ecl_sum_type * ecl_sum , const char *var , int region_nr); - - double ecl_sum_get_misc_var(const ecl_sum_type * ecl_sum , int time_index , const char *var); - int ecl_sum_get_misc_var_index(const ecl_sum_type * ecl_sum , const char *var); - bool ecl_sum_has_misc_var(const ecl_sum_type * ecl_sum , const char *var); - - double ecl_sum_get_well_completion_var(const ecl_sum_type * ecl_sum , int time_index , const char * well , const char *var, int cell_nr); - int ecl_sum_get_well_completion_var_index(const ecl_sum_type * ecl_sum , const char * well , const char *var, int cell_nr); - bool ecl_sum_has_well_completion_var(const ecl_sum_type * ecl_sum , const char * well , const char *var, int cell_nr); - - double ecl_sum_get_general_var(const ecl_sum_type * ecl_sum , int time_index , const char * lookup_kw); - int ecl_sum_get_general_var_params_index(const ecl_sum_type * ecl_sum , const char * lookup_kw); - const smspec_node_type * ecl_sum_get_general_var_node(const ecl_sum_type * ecl_sum , const char * lookup_kw); - bool ecl_sum_has_general_var(const ecl_sum_type * ecl_sum , const char * lookup_kw); - bool ecl_sum_has_key(const ecl_sum_type * ecl_sum , const char * lookup_kw); - double ecl_sum_get_general_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * var); - double ecl_sum_get_general_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * var); - const char * ecl_sum_get_general_var_unit( const ecl_sum_type * ecl_sum , const char * var); - ert_ecl_unit_enum ecl_sum_get_unit_system(const ecl_sum_type * ecl_sum); - - /***************/ - void ecl_sum_fprintf(const ecl_sum_type * , FILE * , const stringlist_type * , bool report_only , const ecl_sum_fmt_type * fmt); - - - - - /* Time related functions */ - int ecl_sum_get_restart_step(const ecl_sum_type * ecl_sum); - int ecl_sum_get_first_gt( const ecl_sum_type * ecl_sum , int param_index , double limit); - int ecl_sum_get_first_lt( const ecl_sum_type * ecl_sum , int param_index , double limit); - int ecl_sum_get_last_report_step( const ecl_sum_type * ecl_sum ); - int ecl_sum_get_first_report_step( const ecl_sum_type * ecl_sum ); - bool ecl_sum_has_report_step(const ecl_sum_type * ecl_sum , int report_step ); - time_t ecl_sum_get_report_time( const ecl_sum_type * ecl_sum , int report_step ); - time_t ecl_sum_iget_sim_time( const ecl_sum_type * ecl_sum , int index ); - double ecl_sum_iget_sim_days( const ecl_sum_type * ecl_sum , int time_index); - int ecl_sum_iget_report_step( const ecl_sum_type * ecl_sum , int internal_index ); - int ecl_sum_iget_mini_step( const ecl_sum_type * ecl_sum , int internal_index ); - double ecl_sum_iget_general_var(const ecl_sum_type * ecl_sum , int internal_index , const char * lookup_kw); - - - void ecl_sum_init_data_vector(const ecl_sum_type * ecl_sum , - double_vector_type * data_vector , - int data_index , - bool report_only ); - double_vector_type * ecl_sum_alloc_data_vector( const ecl_sum_type * ecl_sum , int data_index , bool report_only); - time_t_vector_type * ecl_sum_alloc_time_vector( const ecl_sum_type * ecl_sum , bool report_only); - time_t ecl_sum_get_data_start( const ecl_sum_type * ecl_sum ); - time_t ecl_sum_get_end_time( const ecl_sum_type * ecl_sum); - time_t ecl_sum_get_start_time(const ecl_sum_type * ); - - const char * ecl_sum_get_base(const ecl_sum_type * ecl_sum ); - const char * ecl_sum_get_path(const ecl_sum_type * ecl_sum ); - const char * ecl_sum_get_abs_path(const ecl_sum_type * ecl_sum ); - const ecl_sum_type * ecl_sum_get_restart_case(const ecl_sum_type * ecl_sum); - const char * ecl_sum_get_case(const ecl_sum_type * ); - bool ecl_sum_same_case( const ecl_sum_type * ecl_sum , const char * input_file ); - - void ecl_sum_resample_from_sim_days(const ecl_sum_type * ecl_sum , - const double_vector_type * sim_days , - double_vector_type * value , - const char * gen_key); - void ecl_sum_resample_from_sim_time(const ecl_sum_type * ecl_sum , - const time_t_vector_type * sim_time , - double_vector_type * value , - const char * gen_key); - time_t ecl_sum_time_from_days( const ecl_sum_type * ecl_sum , double sim_days ); - double ecl_sum_days_from_time( const ecl_sum_type * ecl_sum , time_t sim_time ); - double ecl_sum_get_sim_length( const ecl_sum_type * ecl_sum ) ; - double ecl_sum_get_first_day( const ecl_sum_type * ecl_sum ); - - /*****************************************************************/ - stringlist_type * ecl_sum_alloc_well_list( const ecl_sum_type * ecl_sum , const char * pattern); - stringlist_type * ecl_sum_alloc_group_list( const ecl_sum_type * ecl_sum , const char * pattern); - stringlist_type * ecl_sum_alloc_well_var_list( const ecl_sum_type * ecl_sum ); - stringlist_type * ecl_sum_alloc_matching_general_var_list(const ecl_sum_type * ecl_sum , const char * pattern); - void ecl_sum_select_matching_general_var_list( const ecl_sum_type * ecl_sum , const char * pattern , stringlist_type * keys); - const ecl_smspec_type * ecl_sum_get_smspec( const ecl_sum_type * ecl_sum ); - ecl_smspec_var_type ecl_sum_identify_var_type(const char * var); - ecl_smspec_var_type ecl_sum_get_var_type( const ecl_sum_type * ecl_sum , const char * gen_key); - bool ecl_sum_var_is_rate( const ecl_sum_type * ecl_sum , const char * gen_key); - bool ecl_sum_var_is_total( const ecl_sum_type * ecl_sum , const char * gen_key); - - int ecl_sum_iget_report_end( const ecl_sum_type * ecl_sum , int report_step ); - int ecl_sum_iget_report_start( const ecl_sum_type * ecl_sum , int report_step ); - ecl_sum_type * ecl_sum_alloc_restart_writer2( const char * ecl_case, - const char * restart_case, - int restart_step, - bool fmt_output, - bool unified, - const char * key_join_string, - time_t sim_start, - bool time_in_days, - int nx, - int ny, - int nz); - void ecl_sum_set_case( ecl_sum_type * ecl_sum , const char * input_arg); - - ecl_sum_type * ecl_sum_alloc_restart_writer(const char * ecl_case , - const char * restart_case , - bool fmt_output , - bool unified , - const char * key_join_string , - time_t sim_start , - bool time_in_days , - int nx , - int ny , - int nz); - ecl_sum_type * ecl_sum_alloc_writer(const char * ecl_case , - bool fmt_output , - bool unified , - const char * key_join_string , - time_t sim_start , - bool time_in_days , - int nx , int ny , int nz); - void ecl_sum_fwrite( const ecl_sum_type * ecl_sum ); - void ecl_sum_fwrite_smspec( const ecl_sum_type * ecl_sum ); - smspec_node_type * ecl_sum_add_smspec_node(ecl_sum_type * ecl_sum, const smspec_node_type * node); - smspec_node_type * ecl_sum_add_var(ecl_sum_type * ecl_sum , - const char * keyword , - const char * wgname , - int num , - const char * unit , - float default_value); - smspec_node_type * ecl_sum_add_blank_var(ecl_sum_type * ecl_sum , - float default_value); - void ecl_sum_init_var(ecl_sum_type * ecl_sum , - smspec_node_type * smspec_node , - const char * keyword , - const char * wgname , - int num , - const char * unit); - ecl_sum_tstep_type * ecl_sum_add_tstep( ecl_sum_type * ecl_sum , int report_step , double sim_seconds); - void ecl_sum_update_wgname( ecl_sum_type * ecl_sum , smspec_node_type * node , const char * wgname ); - - bool ecl_sum_is_oil_producer( const ecl_sum_type * ecl_sum , const char * well); - char * ecl_sum_alloc_well_key( const ecl_sum_type * ecl_sum , const char * keyword , const char * wgname); - bool ecl_sum_report_step_equal( const ecl_sum_type * ecl_sum1 , const ecl_sum_type * ecl_sum2); - bool ecl_sum_report_step_compatible( const ecl_sum_type * ecl_sum1 , const ecl_sum_type * ecl_sum2); - void ecl_sum_export_csv(const ecl_sum_type * ecl_sum , - const char * filename , - const stringlist_type * var_list , - const char * date_format , - const char * sep); - - - double_vector_type * ecl_sum_alloc_seconds_solution( const ecl_sum_type * ecl_sum , const char * gen_key , double cmp_value , bool rates_clamp_lower); - double_vector_type * ecl_sum_alloc_days_solution( const ecl_sum_type * ecl_sum , const char * gen_key , double cmp_value , bool rates_clamp_lower); - time_t_vector_type * ecl_sum_alloc_time_solution( const ecl_sum_type * ecl_sum , const char * gen_key , double cmp_value , bool rates_clamp_lower); - - double ecl_sum_iget_last_value(const ecl_sum_type * ecl_sum, int param_index); - double ecl_sum_get_last_value_gen_key(const ecl_sum_type * ecl_sum, const char * gen_key); - double ecl_sum_get_last_value_node(const ecl_sum_type * ecl_sum, const smspec_node_type *node); - double ecl_sum_iget_first_value(const ecl_sum_type * ecl_sum, int param_index); - double ecl_sum_get_first_value_gen_key(const ecl_sum_type * ecl_sum, const char * gen_key); - double ecl_sum_get_first_value_node(const ecl_sum_type * ecl_sum, const smspec_node_type *node); +#include - void ecl_sum_init_datetime64_vector(const ecl_sum_type * ecl_sum, int64_t * data, int multiplier); - void ecl_sum_init_double_vector_interp(const ecl_sum_type * ecl_sum, const char * gen_key, const time_t_vector_type * time_points, double * data); - void ecl_sum_init_double_vector(const ecl_sum_type * ecl_sum, const char * gen_key, double * data); - void ecl_sum_init_double_frame(const ecl_sum_type * ecl_sum, const ecl_sum_vector_type * keywords, double * data); - void ecl_sum_init_double_frame_interp(const ecl_sum_type * ecl_sum, const ecl_sum_vector_type * keywords, const time_t_vector_type * time_points, double * data); - UTIL_IS_INSTANCE_HEADER( ecl_sum ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.hpp index 7370f32e97..a66529fb45 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum.hpp @@ -1,19 +1,274 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_sum.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_SUM_H +#define ERT_ECL_SUM_H + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct { + char * locale; + const char * sep; + const char * newline; + const char * value_fmt; + const char * date_fmt; + const char * days_fmt; + const char * header_fmt; + bool print_header; + bool print_dash; + const char * date_header; + const char * date_dash; + const char * value_dash; + } ecl_sum_fmt_type; + + + /*****************************************************************/ + /* This is a forward declaration. */ +typedef struct ecl_sum_vector_struct ecl_sum_vector_type; + +typedef struct ecl_sum_struct ecl_sum_type; + + void ecl_sum_fmt_init_summary_x( const ecl_sum_type * ecl_sum , ecl_sum_fmt_type * fmt ); + double ecl_sum_get_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const smspec_node_type * node); + double ecl_sum_get_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const smspec_node_type * node); + double ecl_sum_time2days( const ecl_sum_type * ecl_sum , time_t sim_time); + + void ecl_sum_set_unified( ecl_sum_type * ecl_sum , bool unified ); + void ecl_sum_set_fmt_case( ecl_sum_type * ecl_sum , bool fmt_case ); + + int ecl_sum_get_report_step_from_time( const ecl_sum_type * sum , time_t sim_time); + int ecl_sum_get_report_step_from_days( const ecl_sum_type * sum , double sim_days); + bool ecl_sum_check_sim_time( const ecl_sum_type * sum , time_t sim_time); + bool ecl_sum_check_sim_days( const ecl_sum_type * sum , double sim_days); + const char * ecl_sum_get_keyword( const ecl_sum_type * sum , const char * gen_key ); + const char * ecl_sum_get_wgname( const ecl_sum_type * sum , const char * gen_key ); + const char * ecl_sum_get_unit( const ecl_sum_type * sum , const char * gen_key ); + int ecl_sum_get_num( const ecl_sum_type * sum , const char * gen_key ); + + double ecl_sum_iget( const ecl_sum_type * ecl_sum , int time_index , int param_index); + int ecl_sum_iget_num( const ecl_sum_type * sum , int param_index ); + const char * ecl_sum_iget_wgname( const ecl_sum_type * sum , int param_index ); + const char * ecl_sum_iget_keyword( const ecl_sum_type * sum , int param_index ); + int ecl_sum_get_data_length( const ecl_sum_type * ecl_sum ); + double ecl_sum_iget_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , int param_index); + double ecl_sum_iget_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , int param_index ); + + + + void ecl_sum_summarize( const ecl_sum_type * ecl_sum , FILE * stream ); + bool ecl_sum_general_is_total(const ecl_sum_type * ecl_sum , const char * gen_key); + void ecl_sum_free_data(ecl_sum_type * ); + void ecl_sum_free__(void * ); + void ecl_sum_free(ecl_sum_type * ); + ecl_sum_type * ecl_sum_fread_alloc(const char * , const stringlist_type * data_files, const char * key_join_string, bool include_restart, bool lazy_load, int file_options); + ecl_sum_type * ecl_sum_fread_alloc_case(const char * , const char * key_join_string); + ecl_sum_type * ecl_sum_fread_alloc_case__(const char * input_file , const char * key_join_string , bool include_restart); + ecl_sum_type * ecl_sum_fread_alloc_case2__(const char * , const char * key_join_string , bool include_restart, bool lazy_load, int file_options); + ecl_sum_type * ecl_sum_alloc_resample(const ecl_sum_type * ecl_sum, const char * ecl_case, const time_t_vector_type * times); + bool ecl_sum_case_exists( const char * input_file ); + + /* Accessor functions : */ + double ecl_sum_get_well_var(const ecl_sum_type * ecl_sum , int time_index , const char * well , const char *var); + bool ecl_sum_has_well_var(const ecl_sum_type * ecl_sum , const char * well , const char *var); + double ecl_sum_get_well_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * well , const char * var); + double ecl_sum_get_well_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * well , const char * var); + + double ecl_sum_get_group_var(const ecl_sum_type * ecl_sum , int time_index , const char * group , const char *var); + bool ecl_sum_has_group_var(const ecl_sum_type * ecl_sum , const char * group , const char *var); + + double ecl_sum_get_field_var(const ecl_sum_type * ecl_sum , int time_index , const char *var); + bool ecl_sum_has_field_var(const ecl_sum_type * ecl_sum , const char *var); + double ecl_sum_get_field_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * var); + double ecl_sum_get_field_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * var); + + double ecl_sum_get_block_var(const ecl_sum_type * ecl_sum , int time_index , const char * block_var , int block_nr); + int ecl_sum_get_block_var_index(const ecl_sum_type * ecl_sum , const char * block_var , int block_nr); + bool ecl_sum_has_block_var(const ecl_sum_type * ecl_sum , const char * block_var , int block_nr); + double ecl_sum_get_block_var_ijk(const ecl_sum_type * ecl_sum , int time_index , const char * block_var , int i , int j , int k); + int ecl_sum_get_block_var_index_ijk(const ecl_sum_type * ecl_sum , const char * block_var , int i , int j , int k); + bool ecl_sum_has_block_var_ijk(const ecl_sum_type * ecl_sum , const char * block_var , int i , int j , int k); + + double ecl_sum_get_region_var(const ecl_sum_type * ecl_sum , int time_index , const char *var , int region_nr); + bool ecl_sum_has_region_var(const ecl_sum_type * ecl_sum , const char *var , int region_nr); + + double ecl_sum_get_misc_var(const ecl_sum_type * ecl_sum , int time_index , const char *var); + int ecl_sum_get_misc_var_index(const ecl_sum_type * ecl_sum , const char *var); + bool ecl_sum_has_misc_var(const ecl_sum_type * ecl_sum , const char *var); + + double ecl_sum_get_well_completion_var(const ecl_sum_type * ecl_sum , int time_index , const char * well , const char *var, int cell_nr); + int ecl_sum_get_well_completion_var_index(const ecl_sum_type * ecl_sum , const char * well , const char *var, int cell_nr); + bool ecl_sum_has_well_completion_var(const ecl_sum_type * ecl_sum , const char * well , const char *var, int cell_nr); + + double ecl_sum_get_general_var(const ecl_sum_type * ecl_sum , int time_index , const char * lookup_kw); + int ecl_sum_get_general_var_params_index(const ecl_sum_type * ecl_sum , const char * lookup_kw); + const smspec_node_type * ecl_sum_get_general_var_node(const ecl_sum_type * ecl_sum , const char * lookup_kw); + bool ecl_sum_has_general_var(const ecl_sum_type * ecl_sum , const char * lookup_kw); + bool ecl_sum_has_key(const ecl_sum_type * ecl_sum , const char * lookup_kw); + double ecl_sum_get_general_var_from_sim_days( const ecl_sum_type * ecl_sum , double sim_days , const char * var); + double ecl_sum_get_general_var_from_sim_time( const ecl_sum_type * ecl_sum , time_t sim_time , const char * var); + const char * ecl_sum_get_general_var_unit( const ecl_sum_type * ecl_sum , const char * var); + ert_ecl_unit_enum ecl_sum_get_unit_system(const ecl_sum_type * ecl_sum); + + /***************/ + void ecl_sum_fprintf(const ecl_sum_type * , FILE * , const stringlist_type * , bool report_only , const ecl_sum_fmt_type * fmt); + + + + + /* Time related functions */ + int ecl_sum_get_restart_step(const ecl_sum_type * ecl_sum); + int ecl_sum_get_first_gt( const ecl_sum_type * ecl_sum , int param_index , double limit); + int ecl_sum_get_first_lt( const ecl_sum_type * ecl_sum , int param_index , double limit); + int ecl_sum_get_last_report_step( const ecl_sum_type * ecl_sum ); + int ecl_sum_get_first_report_step( const ecl_sum_type * ecl_sum ); + bool ecl_sum_has_report_step(const ecl_sum_type * ecl_sum , int report_step ); + time_t ecl_sum_get_report_time( const ecl_sum_type * ecl_sum , int report_step ); + time_t ecl_sum_iget_sim_time( const ecl_sum_type * ecl_sum , int index ); + double ecl_sum_iget_sim_days( const ecl_sum_type * ecl_sum , int time_index); + int ecl_sum_iget_report_step( const ecl_sum_type * ecl_sum , int internal_index ); + double ecl_sum_iget_general_var(const ecl_sum_type * ecl_sum , int internal_index , const char * lookup_kw); + + + double_vector_type * ecl_sum_alloc_data_vector( const ecl_sum_type * ecl_sum , int data_index , bool report_only); + time_t_vector_type * ecl_sum_alloc_time_vector( const ecl_sum_type * ecl_sum , bool report_only); + time_t ecl_sum_get_data_start( const ecl_sum_type * ecl_sum ); + time_t ecl_sum_get_end_time( const ecl_sum_type * ecl_sum); + time_t ecl_sum_get_start_time(const ecl_sum_type * ); + + const char * ecl_sum_get_base(const ecl_sum_type * ecl_sum ); + const char * ecl_sum_get_path(const ecl_sum_type * ecl_sum ); + const char * ecl_sum_get_abs_path(const ecl_sum_type * ecl_sum ); + const ecl_sum_type * ecl_sum_get_restart_case(const ecl_sum_type * ecl_sum); + const char * ecl_sum_get_case(const ecl_sum_type * ); + bool ecl_sum_same_case( const ecl_sum_type * ecl_sum , const char * input_file ); + + void ecl_sum_resample_from_sim_days(const ecl_sum_type * ecl_sum , + const double_vector_type * sim_days , + double_vector_type * value , + const char * gen_key); + void ecl_sum_resample_from_sim_time(const ecl_sum_type * ecl_sum , + const time_t_vector_type * sim_time , + double_vector_type * value , + const char * gen_key); + time_t ecl_sum_time_from_days( const ecl_sum_type * ecl_sum , double sim_days ); + double ecl_sum_days_from_time( const ecl_sum_type * ecl_sum , time_t sim_time ); + double ecl_sum_get_sim_length( const ecl_sum_type * ecl_sum ) ; + double ecl_sum_get_first_day( const ecl_sum_type * ecl_sum ); + + /*****************************************************************/ + stringlist_type * ecl_sum_alloc_well_list( const ecl_sum_type * ecl_sum , const char * pattern); + stringlist_type * ecl_sum_alloc_group_list( const ecl_sum_type * ecl_sum , const char * pattern); + stringlist_type * ecl_sum_alloc_well_var_list( const ecl_sum_type * ecl_sum ); + stringlist_type * ecl_sum_alloc_matching_general_var_list(const ecl_sum_type * ecl_sum , const char * pattern); + void ecl_sum_select_matching_general_var_list( const ecl_sum_type * ecl_sum , const char * pattern , stringlist_type * keys); + const ecl_smspec_type * ecl_sum_get_smspec( const ecl_sum_type * ecl_sum ); + ecl_smspec_var_type ecl_sum_identify_var_type(const char * var); + ecl_smspec_var_type ecl_sum_get_var_type( const ecl_sum_type * ecl_sum , const char * gen_key); + bool ecl_sum_var_is_rate( const ecl_sum_type * ecl_sum , const char * gen_key); + bool ecl_sum_var_is_total( const ecl_sum_type * ecl_sum , const char * gen_key); + + int ecl_sum_iget_report_end( const ecl_sum_type * ecl_sum , int report_step ); + ecl_sum_type * ecl_sum_alloc_restart_writer2( const char * ecl_case, + const char * restart_case, + int restart_step, + bool fmt_output, + bool unified, + const char * key_join_string, + time_t sim_start, + bool time_in_days, + int nx, + int ny, + int nz); + void ecl_sum_set_case( ecl_sum_type * ecl_sum , const char * input_arg); + + ecl_sum_type * ecl_sum_alloc_restart_writer(const char * ecl_case , + const char * restart_case , + bool fmt_output , + bool unified , + const char * key_join_string , + time_t sim_start , + bool time_in_days , + int nx , + int ny , + int nz); + ecl_sum_type * ecl_sum_alloc_writer(const char * ecl_case , + bool fmt_output , + bool unified , + const char * key_join_string , + time_t sim_start , + bool time_in_days , + int nx , int ny , int nz); + void ecl_sum_fwrite( const ecl_sum_type * ecl_sum ); + bool ecl_sum_can_write( const ecl_sum_type * ecl_sum ); + void ecl_sum_fwrite_smspec( const ecl_sum_type * ecl_sum ); + smspec_node_type * ecl_sum_add_smspec_node(ecl_sum_type * ecl_sum, const smspec_node_type * node); + smspec_node_type * ecl_sum_add_var(ecl_sum_type * ecl_sum , + const char * keyword , + const char * wgname , + int num , + const char * unit , + float default_value); + ecl_sum_tstep_type * ecl_sum_add_tstep( ecl_sum_type * ecl_sum , int report_step , double sim_seconds); + + bool ecl_sum_is_oil_producer( const ecl_sum_type * ecl_sum , const char * well); + char * ecl_sum_alloc_well_key( const ecl_sum_type * ecl_sum , const char * keyword , const char * wgname); + bool ecl_sum_report_step_equal( const ecl_sum_type * ecl_sum1 , const ecl_sum_type * ecl_sum2); + bool ecl_sum_report_step_compatible( const ecl_sum_type * ecl_sum1 , const ecl_sum_type * ecl_sum2); + void ecl_sum_export_csv(const ecl_sum_type * ecl_sum , + const char * filename , + const stringlist_type * var_list , + const char * date_format , + const char * sep); + + + double_vector_type * ecl_sum_alloc_seconds_solution( const ecl_sum_type * ecl_sum , const char * gen_key , double cmp_value , bool rates_clamp_lower); + double_vector_type * ecl_sum_alloc_days_solution( const ecl_sum_type * ecl_sum , const char * gen_key , double cmp_value , bool rates_clamp_lower); + time_t_vector_type * ecl_sum_alloc_time_solution( const ecl_sum_type * ecl_sum , const char * gen_key , double cmp_value , bool rates_clamp_lower); + + double ecl_sum_iget_last_value(const ecl_sum_type * ecl_sum, int param_index); + double ecl_sum_get_last_value_gen_key(const ecl_sum_type * ecl_sum, const char * gen_key); + double ecl_sum_get_last_value_node(const ecl_sum_type * ecl_sum, const smspec_node_type *node); + double ecl_sum_iget_first_value(const ecl_sum_type * ecl_sum, int param_index); + double ecl_sum_get_first_value_gen_key(const ecl_sum_type * ecl_sum, const char * gen_key); + double ecl_sum_get_first_value_node(const ecl_sum_type * ecl_sum, const smspec_node_type *node); + + void ecl_sum_init_datetime64_vector(const ecl_sum_type * ecl_sum, int64_t * data, int multiplier); + void ecl_sum_init_double_vector_interp(const ecl_sum_type * ecl_sum, const char * gen_key, const time_t_vector_type * time_points, double * data); + void ecl_sum_init_double_vector(const ecl_sum_type * ecl_sum, const char * gen_key, double * data); + void ecl_sum_init_double_frame(const ecl_sum_type * ecl_sum, const ecl_sum_vector_type * keywords, double * data); + void ecl_sum_init_double_frame_interp(const ecl_sum_type * ecl_sum, const ecl_sum_vector_type * keywords, const time_t_vector_type * time_points, double * data); + UTIL_IS_INSTANCE_HEADER( ecl_sum ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.h index 929c1114a6..ca34e6519f 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.h @@ -1,112 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_sum_data.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_SUM_DATA_H -#define ERT_ECL_SUM_DATA_H - - -#ifdef __cplusplus -extern "C" { -#endif -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -typedef struct ecl_sum_data_struct ecl_sum_data_type ; - - void ecl_sum_data_add_case(ecl_sum_data_type * self, const ecl_sum_data_type * other); - void ecl_sum_data_fwrite_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , bool unified, int report_step); - void ecl_sum_data_fwrite( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , bool unified); - bool ecl_sum_data_fread( ecl_sum_data_type * data , const stringlist_type * filelist); - ecl_sum_data_type * ecl_sum_data_alloc_writer( ecl_smspec_type * smspec ); - ecl_sum_data_type * ecl_sum_data_alloc( ecl_smspec_type * smspec); - double ecl_sum_data_time2days( const ecl_sum_data_type * data , time_t sim_time); - int ecl_sum_data_get_report_step_from_time(const ecl_sum_data_type * data , time_t sim_time); - int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , double days); - bool ecl_sum_data_check_sim_time( const ecl_sum_data_type * data , time_t sim_time); - bool ecl_sum_data_check_sim_days( const ecl_sum_data_type * data , double sim_days); - int ecl_sum_data_get_num_ministep( const ecl_sum_data_type * data ); - double_vector_type * ecl_sum_data_alloc_data_vector( const ecl_sum_data_type * data , int data_index , bool report_only); - void ecl_sum_data_init_data_vector( const ecl_sum_data_type * data , double_vector_type * data_vector , int data_index , bool report_only); - void ecl_sum_data_init_time_vector( const ecl_sum_data_type * data , time_t_vector_type * time_vector , bool report_only); - time_t_vector_type * ecl_sum_data_alloc_time_vector( const ecl_sum_data_type * data , bool report_only); - time_t ecl_sum_data_get_data_start( const ecl_sum_data_type * data ); - time_t ecl_sum_data_get_report_time( const ecl_sum_data_type * data , int report_step); - double ecl_sum_data_get_first_day( const ecl_sum_data_type * data); - time_t ecl_sum_data_get_sim_start ( const ecl_sum_data_type * data ); - time_t ecl_sum_data_get_sim_end ( const ecl_sum_data_type * data ); - double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ); - void ecl_sum_data_summarize(const ecl_sum_data_type * data , FILE * stream); - double ecl_sum_data_iget( const ecl_sum_data_type * data , int internal_index , int params_index ); - - double ecl_sum_data_iget_sim_days( const ecl_sum_data_type * , int ); - time_t ecl_sum_data_iget_sim_time( const ecl_sum_data_type * , int ); - void ecl_sum_data_get_interp_vector( const ecl_sum_data_type * data , time_t sim_time, const ecl_sum_vector_type * keylist, double_vector_type * results); - - bool ecl_sum_data_has_report_step(const ecl_sum_data_type * , int ); - - ecl_sum_data_type * ecl_sum_data_fread_alloc( ecl_smspec_type * , const stringlist_type * filelist , bool include_restart); - void ecl_sum_data_free( ecl_sum_data_type * ); - int ecl_sum_data_get_last_report_step( const ecl_sum_data_type * data ); - int ecl_sum_data_get_first_report_step( const ecl_sum_data_type * data ); - - double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t sim_time , const smspec_node_type * smspec_node); - double ecl_sum_data_get_from_sim_days( const ecl_sum_data_type * data , double sim_days , const smspec_node_type * smspec_node); - - int ecl_sum_data_get_length( const ecl_sum_data_type * data ); - void ecl_sum_data_scale_vector( ecl_sum_data_type * data , int index, double scalar ); - void ecl_sum_data_shift_vector( ecl_sum_data_type * data , int index, double addend ); - int ecl_sum_data_iget_report_step(const ecl_sum_data_type * data , int internal_index); - int ecl_sum_data_iget_mini_step(const ecl_sum_data_type * data , int internal_index); - int ecl_sum_data_iget_report_end( const ecl_sum_data_type * data , int report_step ); - int ecl_sum_data_iget_report_start( const ecl_sum_data_type * data , int report_step ); - ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int report_step , double sim_seconds); - bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2); - bool ecl_sum_data_report_step_compatible( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2); - void ecl_sum_data_fwrite_interp_csv_line(const ecl_sum_data_type * data , time_t sim_time, const ecl_sum_vector_type * keylist, FILE *fp); - double ecl_sum_data_get_last_value(const ecl_sum_data_type * data, int param_index); - double ecl_sum_data_iget_last_value(const ecl_sum_data_type * data, int param_index); - double ecl_sum_data_iget_first_value(const ecl_sum_data_type * data, int param_index); - void ecl_sum_data_init_double_vector(const ecl_sum_data_type * data, int params_index, double * output_data); - void ecl_sum_data_init_datetime64_vector(const ecl_sum_data_type * data, int64_t * output_data, int multiplier); - - void ecl_sum_data_init_double_frame(const ecl_sum_data_type * data, const ecl_sum_vector_type * keywords, double *output_data); - double_vector_type * ecl_sum_data_alloc_seconds_solution( const ecl_sum_data_type * data , const smspec_node_type * node , double value, bool rates_clamp_lower); - void ecl_sum_data_init_double_frame_interp(const ecl_sum_data_type * data, - const ecl_sum_vector_type * keywords, - const time_t_vector_type * time_points, - double * output_data); - - void ecl_sum_data_init_double_vector_interp(const ecl_sum_data_type * data, - const smspec_node_type * smspec_node, - const time_t_vector_type * time_points, - double * output_data); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.hpp index 9d54a02f6c..0c6fdbc0b1 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_data.hpp @@ -1,19 +1,110 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_sum_data.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_SUM_DATA_H +#define ERT_ECL_SUM_DATA_H + + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ecl_sum_data_struct ecl_sum_data_type ; + + void ecl_sum_data_reset_self_map( ecl_sum_data_type * data ); + void ecl_sum_data_add_case(ecl_sum_data_type * self, const ecl_sum_data_type * other); + void ecl_sum_data_fwrite_step( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , bool unified, int report_step); + void ecl_sum_data_fwrite( const ecl_sum_data_type * data , const char * ecl_case , bool fmt_case , bool unified); + bool ecl_sum_data_can_write(const ecl_sum_data_type * data); + bool ecl_sum_data_fread( ecl_sum_data_type * data , const stringlist_type * filelist, bool lazy_load, int file_options); + ecl_sum_data_type * ecl_sum_data_alloc_writer( ecl_smspec_type * smspec ); + ecl_sum_data_type * ecl_sum_data_alloc( ecl_smspec_type * smspec); + double ecl_sum_data_time2days( const ecl_sum_data_type * data , time_t sim_time); + int ecl_sum_data_get_report_step_from_time(const ecl_sum_data_type * data , time_t sim_time); + int ecl_sum_data_get_report_step_from_days(const ecl_sum_data_type * data , double days); + bool ecl_sum_data_check_sim_time( const ecl_sum_data_type * data , time_t sim_time); + bool ecl_sum_data_check_sim_days( const ecl_sum_data_type * data , double sim_days); + int ecl_sum_data_get_num_ministep( const ecl_sum_data_type * data ); + double_vector_type * ecl_sum_data_alloc_data_vector( const ecl_sum_data_type * data , int data_index , bool report_only); + void ecl_sum_data_init_time_vector( const ecl_sum_data_type * data , time_t_vector_type * time_vector , bool report_only); + time_t_vector_type * ecl_sum_data_alloc_time_vector( const ecl_sum_data_type * data , bool report_only); + time_t ecl_sum_data_get_data_start( const ecl_sum_data_type * data ); + time_t ecl_sum_data_get_report_time( const ecl_sum_data_type * data , int report_step); + double ecl_sum_data_get_first_day( const ecl_sum_data_type * data); + time_t ecl_sum_data_get_sim_start ( const ecl_sum_data_type * data ); + time_t ecl_sum_data_get_sim_end ( const ecl_sum_data_type * data ); + double ecl_sum_data_get_sim_length( const ecl_sum_data_type * data ); + void ecl_sum_data_summarize(const ecl_sum_data_type * data , FILE * stream); + double ecl_sum_data_iget( const ecl_sum_data_type * data , int internal_index , int params_index ); + + double ecl_sum_data_iget_sim_days( const ecl_sum_data_type * , int ); + time_t ecl_sum_data_iget_sim_time( const ecl_sum_data_type * , int ); + void ecl_sum_data_get_interp_vector( const ecl_sum_data_type * data , time_t sim_time, const ecl_sum_vector_type * keylist, double_vector_type * results); + + bool ecl_sum_data_has_report_step(const ecl_sum_data_type * , int ); + + ecl_sum_data_type * ecl_sum_data_fread_alloc( ecl_smspec_type * , const stringlist_type * filelist , bool include_restart, bool lazy_load); + void ecl_sum_data_free( ecl_sum_data_type * ); + int ecl_sum_data_get_last_report_step( const ecl_sum_data_type * data ); + int ecl_sum_data_get_first_report_step( const ecl_sum_data_type * data ); + + double ecl_sum_data_get_from_sim_time( const ecl_sum_data_type * data , time_t sim_time , const smspec_node_type * smspec_node); + double ecl_sum_data_get_from_sim_days( const ecl_sum_data_type * data , double sim_days , const smspec_node_type * smspec_node); + + int ecl_sum_data_get_length( const ecl_sum_data_type * data ); + int ecl_sum_data_iget_report_step(const ecl_sum_data_type * data , int internal_index); + int ecl_sum_data_iget_report_end( const ecl_sum_data_type * data , int report_step ); + ecl_sum_tstep_type * ecl_sum_data_add_new_tstep( ecl_sum_data_type * data , int report_step , double sim_seconds); + bool ecl_sum_data_report_step_equal( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2); + bool ecl_sum_data_report_step_compatible( const ecl_sum_data_type * data1 , const ecl_sum_data_type * data2); + void ecl_sum_data_fwrite_interp_csv_line(const ecl_sum_data_type * data , time_t sim_time, const ecl_sum_vector_type * keylist, FILE *fp); + double ecl_sum_data_get_last_value(const ecl_sum_data_type * data, int param_index); + double ecl_sum_data_iget_last_value(const ecl_sum_data_type * data, int param_index); + double ecl_sum_data_iget_first_value(const ecl_sum_data_type * data, int param_index); + void ecl_sum_data_init_double_vector(const ecl_sum_data_type * data, int params_index, double * output_data); + void ecl_sum_data_init_datetime64_vector(const ecl_sum_data_type * data, int64_t * output_data, int multiplier); + + void ecl_sum_data_init_double_frame(const ecl_sum_data_type * data, const ecl_sum_vector_type * keywords, double *output_data); + double_vector_type * ecl_sum_data_alloc_seconds_solution( const ecl_sum_data_type * data , const smspec_node_type * node , double value, bool rates_clamp_lower); + void ecl_sum_data_init_double_frame_interp(const ecl_sum_data_type * data, + const ecl_sum_vector_type * keywords, + const time_t_vector_type * time_points, + double * output_data); + + void ecl_sum_data_init_double_vector_interp(const ecl_sum_data_type * data, + const smspec_node_type * smspec_node, + const time_t_vector_type * time_points, + double * output_data); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.h index 3c7d54fb53..aa1ca99029 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.h @@ -1,31 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_sum_index.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_SUM_INDEX_H -#define ERT_ECL_SUM_INDEX_H +#include -#ifdef __cplusplus -extern "C" { -#endif -typedef struct ecl_sum_index_struct ecl_sum_index_type; - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.hpp index 1317fbf5a4..d68088f976 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_index.hpp @@ -1,20 +1,31 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_sum_index.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ +#ifndef ERT_ECL_SUM_INDEX_H +#define ERT_ECL_SUM_INDEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ecl_sum_index_struct ecl_sum_index_type; -#include +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.h index e5e92471e5..6d8ca74027 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.h @@ -1,79 +1,9 @@ - /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ecl_sum_tstep.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. +/* + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_SUM_TSTEP_H -#define ERT_ECL_SUM_TSTEP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include - -typedef struct ecl_sum_tstep_struct ecl_sum_tstep_type; - - ecl_sum_tstep_type * ecl_sum_tstep_alloc_remap_copy( const ecl_sum_tstep_type * src , const ecl_smspec_type * new_smspec, float default_value , const int * params_map); - ecl_sum_tstep_type * ecl_sum_tstep_alloc_copy( const ecl_sum_tstep_type * src ); - void ecl_sum_tstep_free( ecl_sum_tstep_type * ministep ); - void ecl_sum_tstep_free__( void * __ministep); - ecl_sum_tstep_type * ecl_sum_tstep_alloc_from_file(int report_step , - int ministep_nr , - const ecl_kw_type * params_kw , - const char * src_file , - const ecl_smspec_type * smspec); - - ecl_sum_tstep_type * ecl_sum_tstep_alloc_new( int report_step , int ministep , float sim_seconds , const ecl_smspec_type * smspec ); - - double ecl_sum_tstep_iget(const ecl_sum_tstep_type * ministep , int index); - time_t ecl_sum_tstep_get_sim_time(const ecl_sum_tstep_type * ministep); - double ecl_sum_tstep_get_sim_days(const ecl_sum_tstep_type * ministep); - double ecl_sum_tstep_get_sim_seconds(const ecl_sum_tstep_type * ministep); - - int ecl_sum_tstep_get_report(const ecl_sum_tstep_type * ministep); - int ecl_sum_tstep_get_ministep(const ecl_sum_tstep_type * ministep); - - void ecl_sum_tstep_fwrite( const ecl_sum_tstep_type * ministep , const int_vector_type * index_map , fortio_type * fortio); - void ecl_sum_tstep_iset( ecl_sum_tstep_type * tstep , int index , float value); - - /// scales with value; equivalent to iset( iget() * scalar) - void ecl_sum_tstep_iscale(ecl_sum_tstep_type * tstep, int index, float scalar); - - /// adds addend to tstep[index]; equivalent to iset( iget() + addend) - void ecl_sum_tstep_ishift(ecl_sum_tstep_type * tstep, int index, float addend); - - void ecl_sum_tstep_set_from_node( ecl_sum_tstep_type * tstep , const smspec_node_type * smspec_node , float value); - double ecl_sum_tstep_get_from_node( const ecl_sum_tstep_type * tstep , const smspec_node_type * smspec_node); - - void ecl_sum_tstep_set_from_key( ecl_sum_tstep_type * tstep , const char * gen_key , float value); - double ecl_sum_tstep_get_from_key( const ecl_sum_tstep_type * tstep , const char * gen_key); - bool ecl_sum_tstep_has_key(const ecl_sum_tstep_type * tstep , const char * gen_key); - - bool ecl_sum_tstep_sim_time_equal( const ecl_sum_tstep_type * tstep1 , const ecl_sum_tstep_type * tstep2 ); - - UTIL_SAFE_CAST_HEADER( ecl_sum_tstep ); - UTIL_SAFE_CAST_HEADER_CONST( ecl_sum_tstep ); - +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.hpp index 5350247752..4fc332ea00 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_tstep.hpp @@ -1,19 +1,79 @@ -/* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + /* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ecl_sum_tstep.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_SUM_TSTEP_H +#define ERT_ECL_SUM_TSTEP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include + +typedef struct ecl_sum_tstep_struct ecl_sum_tstep_type; + + ecl_sum_tstep_type * ecl_sum_tstep_alloc_remap_copy( const ecl_sum_tstep_type * src , const ecl_smspec_type * new_smspec, float default_value , const int * params_map); + ecl_sum_tstep_type * ecl_sum_tstep_alloc_copy( const ecl_sum_tstep_type * src ); + void ecl_sum_tstep_free( ecl_sum_tstep_type * ministep ); + void ecl_sum_tstep_free__( void * __ministep); + ecl_sum_tstep_type * ecl_sum_tstep_alloc_from_file(int report_step , + int ministep_nr , + const ecl_kw_type * params_kw , + const char * src_file , + const ecl_smspec_type * smspec); + + ecl_sum_tstep_type * ecl_sum_tstep_alloc_new( int report_step , int ministep , float sim_seconds , const ecl_smspec_type * smspec ); + + double ecl_sum_tstep_iget(const ecl_sum_tstep_type * ministep , int index); + time_t ecl_sum_tstep_get_sim_time(const ecl_sum_tstep_type * ministep); + double ecl_sum_tstep_get_sim_days(const ecl_sum_tstep_type * ministep); + double ecl_sum_tstep_get_sim_seconds(const ecl_sum_tstep_type * ministep); + + int ecl_sum_tstep_get_report(const ecl_sum_tstep_type * ministep); + int ecl_sum_tstep_get_ministep(const ecl_sum_tstep_type * ministep); + + void ecl_sum_tstep_fwrite( const ecl_sum_tstep_type * ministep , const int_vector_type * index_map , fortio_type * fortio); + void ecl_sum_tstep_iset( ecl_sum_tstep_type * tstep , int index , float value); + + /// scales with value; equivalent to iset( iget() * scalar) + void ecl_sum_tstep_iscale(ecl_sum_tstep_type * tstep, int index, float scalar); + + /// adds addend to tstep[index]; equivalent to iset( iget() + addend) + void ecl_sum_tstep_ishift(ecl_sum_tstep_type * tstep, int index, float addend); + + void ecl_sum_tstep_set_from_node( ecl_sum_tstep_type * tstep , const smspec_node_type * smspec_node , float value); + double ecl_sum_tstep_get_from_node( const ecl_sum_tstep_type * tstep , const smspec_node_type * smspec_node); + + void ecl_sum_tstep_set_from_key( ecl_sum_tstep_type * tstep , const char * gen_key , float value); + double ecl_sum_tstep_get_from_key( const ecl_sum_tstep_type * tstep , const char * gen_key); + bool ecl_sum_tstep_has_key(const ecl_sum_tstep_type * tstep , const char * gen_key); + + bool ecl_sum_tstep_sim_time_equal( const ecl_sum_tstep_type * tstep1 , const ecl_sum_tstep_type * tstep2 ); + + UTIL_SAFE_CAST_HEADER( ecl_sum_tstep ); + UTIL_SAFE_CAST_HEADER_CONST( ecl_sum_tstep ); + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.h index 6994160437..549093c1bd 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.h @@ -1,53 +1,9 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ecl_sum_vector.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_SUM_VECTOR_H -#define ERT_ECL_SUM_VECTOR_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - -typedef struct ecl_sum_vector_struct ecl_sum_vector_type; - - void ecl_sum_vector_free( ecl_sum_vector_type * keylist ); - ecl_sum_vector_type * ecl_sum_vector_alloc(const ecl_sum_type * ecl_sum, bool add_keywords); - - bool ecl_sum_vector_add_key( ecl_sum_vector_type * keylist, const char * key); - void ecl_sum_vector_add_keys( ecl_sum_vector_type * keylist, const char * pattern); - - const char* ecl_sum_vector_iget_key(const ecl_sum_vector_type * ecl_sum_vector, int index); - bool ecl_sum_vector_iget_is_rate(const ecl_sum_vector_type * ecl_sum_vector, int index); - int ecl_sum_vector_iget_param_index(const ecl_sum_vector_type * ecl_sum_vector, int index); - int ecl_sum_vector_get_size(const ecl_sum_vector_type * ecl_sum_vector); - bool ecl_sum_vector_iget_valid(const ecl_sum_vector_type * ecl_sum_vector, int index); - - ecl_sum_vector_type * ecl_sum_vector_alloc_layout_copy(const ecl_sum_vector_type * src_vector, const ecl_sum_type * ecl_sum); - - - UTIL_IS_INSTANCE_HEADER( ecl_sum_vector); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.hpp index 8b06dae566..c9e4ed9c42 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_sum_vector.hpp @@ -1,19 +1,53 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'ecl_sum_vector.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_SUM_VECTOR_H +#define ERT_ECL_SUM_VECTOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +typedef struct ecl_sum_vector_struct ecl_sum_vector_type; + + void ecl_sum_vector_free( ecl_sum_vector_type * keylist ); + ecl_sum_vector_type * ecl_sum_vector_alloc(const ecl_sum_type * ecl_sum, bool add_keywords); + + bool ecl_sum_vector_add_key( ecl_sum_vector_type * keylist, const char * key); + void ecl_sum_vector_add_keys( ecl_sum_vector_type * keylist, const char * pattern); + + const char* ecl_sum_vector_iget_key(const ecl_sum_vector_type * ecl_sum_vector, int index); + bool ecl_sum_vector_iget_is_rate(const ecl_sum_vector_type * ecl_sum_vector, int index); + int ecl_sum_vector_iget_param_index(const ecl_sum_vector_type * ecl_sum_vector, int index); + int ecl_sum_vector_get_size(const ecl_sum_vector_type * ecl_sum_vector); + bool ecl_sum_vector_iget_valid(const ecl_sum_vector_type * ecl_sum_vector, int index); + + ecl_sum_vector_type * ecl_sum_vector_alloc_layout_copy(const ecl_sum_vector_type * src_vector, const ecl_sum_type * ecl_sum); + + + UTIL_IS_INSTANCE_HEADER( ecl_sum_vector); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.h index a218330974..5f39630a44 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.h @@ -1,137 +1,9 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. - - The file 'ecl_type.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ERT_ECL_TYPE_H -#define ERT_ECL_TYPE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/* - The type of an eclipse keyword is carried by a struct - ecl_type_struct which contains a type enum, and the size in bytes of - one such element. These structs are for the most part handled with - value semantics, and created with macros ECL_INT, ECL_FLOAT and so - on. - - The macros in C use designated initializers, whereas the C++ macros - use a constructor, for this reason this file has two slightly - different code paths for C and C++. -*/ - -#define ECL_STRING8_LENGTH 8 -#define ECL_TYPE_LENGTH 4 - -typedef enum { - ECL_CHAR_TYPE = 0, - ECL_FLOAT_TYPE = 1, - ECL_DOUBLE_TYPE = 2, - ECL_INT_TYPE = 3, - ECL_BOOL_TYPE = 4, - ECL_MESS_TYPE = 5, - ECL_STRING_TYPE = 7 -} ecl_type_enum; - -#define ECL_TYPE_ENUM_DEFS {.value = 0 , .name = "ECL_CHAR_TYPE"}, \ -{.value = 1 , .name = "ECL_FLOAT_TYPE"} , \ -{.value = 2 , .name = "ECL_DOUBLE_TYPE"}, \ -{.value = 3 , .name = "ECL_INT_TYPE"}, \ -{.value = 4 , .name = "ECL_BOOL_TYPE"}, \ -{.value = 5 , .name = "ECL_MESS_TYPE"}, \ -{.value = 7 , .name = "ECL_STRING_TYPE"} - - -/* - Character data in ECLIPSE files comes as an array of fixed-length - string. Each of these strings is 8 characters long. The type name, - i.e. 'REAL', 'INTE', ... , come as 4 character strings. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#define ECL_STRING8_LENGTH 8 // 'Normal' 8 characters 'CHAR' type. -#define ECL_TYPE_LENGTH 4 - -struct ecl_type_struct { - const ecl_type_enum type; - const size_t element_size; -}; - -#ifdef __cplusplus - -#define ECL_INT ecl_data_type{ ECL_INT_TYPE, sizeof(int)} -#define ECL_FLOAT ecl_data_type{ ECL_FLOAT_TYPE, sizeof(float)} -#define ECL_DOUBLE ecl_data_type{ ECL_DOUBLE_TYPE, sizeof(double)} -#define ECL_BOOL ecl_data_type{ ECL_BOOL_TYPE, sizeof(bool)} -#define ECL_CHAR ecl_data_type{ ECL_CHAR_TYPE, ECL_STRING8_LENGTH + 1} -#define ECL_MESS ecl_data_type{ ECL_MESS_TYPE, 0} -#define ECL_STRING(size) ecl_data_type{ECL_STRING_TYPE, (size) + 1} - -} - -#else - -#define ECL_CHAR (ecl_data_type) {.type = ECL_CHAR_TYPE, .element_size = ECL_STRING8_LENGTH + 1} -#define ECL_INT (ecl_data_type) {.type = ECL_INT_TYPE, .element_size = sizeof(int)} -#define ECL_FLOAT (ecl_data_type) {.type = ECL_FLOAT_TYPE, .element_size = sizeof(float)} -#define ECL_DOUBLE (ecl_data_type) {.type = ECL_DOUBLE_TYPE, .element_size = sizeof(double)} -#define ECL_BOOL (ecl_data_type) {.type = ECL_BOOL_TYPE, .element_size = sizeof(bool)} -#define ECL_MESS (ecl_data_type) {.type = ECL_MESS_TYPE, .element_size = 0} -#define ECL_STRING(size) (ecl_data_type) {.type = ECL_STRING_TYPE, .element_size = (size) + 1} - -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ecl_type_struct ecl_data_type; - -ecl_data_type ecl_type_create_from_name(const char *); -ecl_data_type ecl_type_create(const ecl_type_enum, const size_t); -ecl_data_type ecl_type_create_from_type(const ecl_type_enum); - -ecl_type_enum ecl_type_get_type(const ecl_data_type); -char * ecl_type_alloc_name(const ecl_data_type); - -int ecl_type_get_sizeof_ctype(const ecl_data_type); -int ecl_type_get_sizeof_iotype(const ecl_data_type); - -bool ecl_type_is_equal(const ecl_data_type, const ecl_data_type); - -bool ecl_type_is_numeric(const ecl_data_type); -bool ecl_type_is_alpha(const ecl_data_type); -bool ecl_type_is_char(const ecl_data_type); -bool ecl_type_is_int(const ecl_data_type); -bool ecl_type_is_float(const ecl_data_type); -bool ecl_type_is_double(const ecl_data_type); -bool ecl_type_is_mess(const ecl_data_type); -bool ecl_type_is_bool(const ecl_data_type); -bool ecl_type_is_string(const ecl_data_type); - -// Temporary fixup for OPM. -char * ecl_type_get_name(const ecl_data_type); - -#ifdef __cplusplus -} -#endif +#include -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.hpp index 982417c0ea..a218330974 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_type.hpp @@ -1,19 +1,137 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2017 Statoil ASA, Norway. + + The file 'ecl_type.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ + +#ifndef ERT_ECL_TYPE_H +#define ERT_ECL_TYPE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + The type of an eclipse keyword is carried by a struct + ecl_type_struct which contains a type enum, and the size in bytes of + one such element. These structs are for the most part handled with + value semantics, and created with macros ECL_INT, ECL_FLOAT and so + on. + + The macros in C use designated initializers, whereas the C++ macros + use a constructor, for this reason this file has two slightly + different code paths for C and C++. +*/ + +#define ECL_STRING8_LENGTH 8 +#define ECL_TYPE_LENGTH 4 + +typedef enum { + ECL_CHAR_TYPE = 0, + ECL_FLOAT_TYPE = 1, + ECL_DOUBLE_TYPE = 2, + ECL_INT_TYPE = 3, + ECL_BOOL_TYPE = 4, + ECL_MESS_TYPE = 5, + ECL_STRING_TYPE = 7 +} ecl_type_enum; + +#define ECL_TYPE_ENUM_DEFS {.value = 0 , .name = "ECL_CHAR_TYPE"}, \ +{.value = 1 , .name = "ECL_FLOAT_TYPE"} , \ +{.value = 2 , .name = "ECL_DOUBLE_TYPE"}, \ +{.value = 3 , .name = "ECL_INT_TYPE"}, \ +{.value = 4 , .name = "ECL_BOOL_TYPE"}, \ +{.value = 5 , .name = "ECL_MESS_TYPE"}, \ +{.value = 7 , .name = "ECL_STRING_TYPE"} + + +/* + Character data in ECLIPSE files comes as an array of fixed-length + string. Each of these strings is 8 characters long. The type name, + i.e. 'REAL', 'INTE', ... , come as 4 character strings. */ -#include +#define ECL_STRING8_LENGTH 8 // 'Normal' 8 characters 'CHAR' type. +#define ECL_TYPE_LENGTH 4 + +struct ecl_type_struct { + const ecl_type_enum type; + const size_t element_size; +}; + +#ifdef __cplusplus + +#define ECL_INT ecl_data_type{ ECL_INT_TYPE, sizeof(int)} +#define ECL_FLOAT ecl_data_type{ ECL_FLOAT_TYPE, sizeof(float)} +#define ECL_DOUBLE ecl_data_type{ ECL_DOUBLE_TYPE, sizeof(double)} +#define ECL_BOOL ecl_data_type{ ECL_BOOL_TYPE, sizeof(bool)} +#define ECL_CHAR ecl_data_type{ ECL_CHAR_TYPE, ECL_STRING8_LENGTH + 1} +#define ECL_MESS ecl_data_type{ ECL_MESS_TYPE, 0} +#define ECL_STRING(size) ecl_data_type{ECL_STRING_TYPE, (size) + 1} + +} + +#else + +#define ECL_CHAR (ecl_data_type) {.type = ECL_CHAR_TYPE, .element_size = ECL_STRING8_LENGTH + 1} +#define ECL_INT (ecl_data_type) {.type = ECL_INT_TYPE, .element_size = sizeof(int)} +#define ECL_FLOAT (ecl_data_type) {.type = ECL_FLOAT_TYPE, .element_size = sizeof(float)} +#define ECL_DOUBLE (ecl_data_type) {.type = ECL_DOUBLE_TYPE, .element_size = sizeof(double)} +#define ECL_BOOL (ecl_data_type) {.type = ECL_BOOL_TYPE, .element_size = sizeof(bool)} +#define ECL_MESS (ecl_data_type) {.type = ECL_MESS_TYPE, .element_size = 0} +#define ECL_STRING(size) (ecl_data_type) {.type = ECL_STRING_TYPE, .element_size = (size) + 1} + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ecl_type_struct ecl_data_type; + +ecl_data_type ecl_type_create_from_name(const char *); +ecl_data_type ecl_type_create(const ecl_type_enum, const size_t); +ecl_data_type ecl_type_create_from_type(const ecl_type_enum); + +ecl_type_enum ecl_type_get_type(const ecl_data_type); +char * ecl_type_alloc_name(const ecl_data_type); + +int ecl_type_get_sizeof_ctype(const ecl_data_type); +int ecl_type_get_sizeof_iotype(const ecl_data_type); + +bool ecl_type_is_equal(const ecl_data_type, const ecl_data_type); + +bool ecl_type_is_numeric(const ecl_data_type); +bool ecl_type_is_alpha(const ecl_data_type); +bool ecl_type_is_char(const ecl_data_type); +bool ecl_type_is_int(const ecl_data_type); +bool ecl_type_is_float(const ecl_data_type); +bool ecl_type_is_double(const ecl_data_type); +bool ecl_type_is_mess(const ecl_data_type); +bool ecl_type_is_bool(const ecl_data_type); +bool ecl_type_is_string(const ecl_data_type); + +// Temporary fixup for OPM. +char * ecl_type_get_name(const ecl_data_type); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.h index ecee98a662..b6de71dbae 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.h @@ -1,46 +1,9 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. - - The file 'ecl_units.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ECL_UNITS_H -#define ECL_UNITS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define ECL_UNITS_CUBIC(x) ((x)*(x)*(x)) -#define ECL_UNITS_MILLI(x) ((x)*0.001) -#define ECL_UNITS_MEGA(x) ((x)*1000000) - -#define ECL_UNITS_LENGTH_INCH 0.0254 -#define ECL_UNITS_LENGTH_FEET 12 * ECL_UNITS_LENGTH_INCH - -#define ECL_UNITS_VOLUME_GALLON 231 * ECL_UNITS_CUBIC( ECL_UNITS_LENGTH_INCH ) -#define ECL_UNITS_VOLUME_BARREL ECL_UNITS_VOLUME_GALLON * 42 -#define ECL_UNITS_VOLUME_LITER 0.001 -#define ECL_UNITS_VOLUME_MILLI_LITER ECL_UNITS_MILLI( ECL_UNITS_VOLUME_LITER ) -#define ECL_UNITS_VOLUME_GAS_FIELD ECL_UNITS_MEGA( ECL_UNITS_CUBIC( ECL_UNITS_LENGTH_FEET ) ) - -#define ECL_UNITS_TIME_HOUR 3600 -#define ECL_UNITS_TIME_DAY 24 * ECL_UNITS_TIME_HOUR +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.hpp index 09fd7dbafa..ecee98a662 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_units.hpp @@ -1,19 +1,46 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2017 Statoil ASA, Norway. + + The file 'ecl_units.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ECL_UNITS_H +#define ECL_UNITS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define ECL_UNITS_CUBIC(x) ((x)*(x)*(x)) +#define ECL_UNITS_MILLI(x) ((x)*0.001) +#define ECL_UNITS_MEGA(x) ((x)*1000000) + +#define ECL_UNITS_LENGTH_INCH 0.0254 +#define ECL_UNITS_LENGTH_FEET 12 * ECL_UNITS_LENGTH_INCH + +#define ECL_UNITS_VOLUME_GALLON 231 * ECL_UNITS_CUBIC( ECL_UNITS_LENGTH_INCH ) +#define ECL_UNITS_VOLUME_BARREL ECL_UNITS_VOLUME_GALLON * 42 +#define ECL_UNITS_VOLUME_LITER 0.001 +#define ECL_UNITS_VOLUME_MILLI_LITER ECL_UNITS_MILLI( ECL_UNITS_VOLUME_LITER ) +#define ECL_UNITS_VOLUME_GAS_FIELD ECL_UNITS_MEGA( ECL_UNITS_CUBIC( ECL_UNITS_LENGTH_FEET ) ) + +#define ECL_UNITS_TIME_HOUR 3600 +#define ECL_UNITS_TIME_DAY 24 * ECL_UNITS_TIME_HOUR + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.h b/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.h index 7dea54f480..416cf8c536 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.h @@ -1,151 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ecl_util.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_ECL_UTIL_H -#define ERT_ECL_UTIL_H -#ifdef __cplusplus -extern "C" { -#endif -#include -#include - -#include -#include -#include -#include - - -typedef enum { ECL_OTHER_FILE = 0 , - ECL_RESTART_FILE = 1 , - ECL_UNIFIED_RESTART_FILE = 2 , - ECL_SUMMARY_FILE = 4 , - ECL_UNIFIED_SUMMARY_FILE = 8 , - ECL_SUMMARY_HEADER_FILE = 16 , - ECL_GRID_FILE = 32 , - ECL_EGRID_FILE = 64 , - ECL_INIT_FILE = 128 , - ECL_RFT_FILE = 256 , - ECL_DATA_FILE = 512 } ecl_file_enum; - - - - /* - This enum enumerates the four different ways summary and restart information - can be stored. - */ - - - typedef enum { ECL_INVALID_STORAGE = 0, - ECL_BINARY_UNIFIED = 1, - ECL_FORMATTED_UNIFIED = 2, - ECL_BINARY_NON_UNIFIED = 4, - ECL_FORMATTED_NON_UNIFIED = 8} ecl_storage_enum; - -/* - The libecl library has been built and tested 99.5% with ECLIPSE100 - as context, but in thye gravity code there is some very limited - functionality related to ECLIPSE100 versus ECLIPSE300 functionality. - - Observe that numerical values found as part of the INTEHAD keyword - differ from these values, and are found in the ecl_kw_magic.h - header. -*/ - -typedef enum { - ECLIPSE_UNDEFINED = 0, - ECLIPSE100 = 1, - ECLIPSE300 = 2, - ECLIPSE300_THERMAL = 3, - INTERSECT = 4, - FRONTSIM = 5 -} ecl_version_enum; - -/* - Observe that the numerical enum VALUES matches those found in item - 14 in the INTEHEAD keyword in the ECLIPSE INIT files; i.e. the - distribution of numerical values 1,2,4 can NOT BE CHANGED. - - The function ecl_util_get_phase_name() can be used to lookup a - string name from an enum value. - - The phases in a simulation will typically be a sum of these - fundamental phases, and represented as an integer. -*/ - -typedef enum { - ECL_OIL_PHASE = 1, - ECL_GAS_PHASE = 2, - ECL_WATER_PHASE = 4 -} ecl_phase_enum; - -#define ECL_PHASE_ENUM_DEFS {.value = 1 , .name = "ECL_OIL_PHASE"}, {.value = 2 , .name = "ECL_GAS_PHASE"} , {.value = 4 , .name = "ECL_WATER_PHASE"} -#define ECL_PHASE_ENUM_SIZE 3 - -typedef enum { - ECL_METRIC_UNITS = 1, - ECL_FIELD_UNITS = 2, - ECL_LAB_UNITS = 3, - ECL_PVT_M_UNITS = 4 -} ert_ecl_unit_enum; - - -// For unformatted files: -#define ECL_BOOL_TRUE_INT -1 // Binary representation: 11111111 11111111 11111111 1111111 -#define ECL_BOOL_FALSE_INT 0 // Binary representation: 00000000 00000000 00000000 0000000 -#define ECL_COMMENT_STRING "--" -#define ECL_COMMENT_CHAR '-' // Need to consecutive to make an ECLIPSE comment -#define ECL_DATA_TERMINATION "/" - - -/*****************************************************************/ -bool ecl_util_unified_file(const char *filename); -const char * ecl_util_file_type_name( ecl_file_enum file_type ); -char * ecl_util_alloc_base_guess(const char *); -int ecl_util_filename_report_nr(const char *); -ecl_file_enum ecl_util_inspect_extension(const char * ext , bool *_fmt_file, int * _report_nr); -ecl_file_enum ecl_util_get_file_type(const char * filename, bool * fmt_file, int * report_nr); -char * ecl_util_alloc_filename(const char * /* path */, const char * /* base */, ecl_file_enum , bool /* fmt_file */ , int /*report_nr*/); -char * ecl_util_alloc_exfilename(const char * /* path */, const char * /* base */, ecl_file_enum , bool /* fmt_file */ , int /*report_nr*/); -void ecl_util_memcpy_typed_data(void *, const void * , ecl_data_type , ecl_data_type , int ); -void ecl_util_escape_kw(char * kw); -bool ecl_util_alloc_summary_files(const char * , const char * , const char * , char ** , stringlist_type * ); -void ecl_util_alloc_summary_data_files(const char * path , const char * base , bool fmt_file , stringlist_type * filelist); -void ecl_util_alloc_restart_files(const char * , const char * , char *** , int * , bool * , bool *); -time_t ecl_util_get_start_date(const char * ); -int ecl_util_get_num_cpu(const char * data_file); -bool ecl_util_fmt_file(const char * filename , bool * __fmt_file); -char * ecl_util_alloc_exfilename_anyfmt(const char * path, const char * base , ecl_file_enum file_type , bool start_fmt , int report_nr); -int ecl_util_get_month_nr(const char * month_name); -int ecl_util_fname_report_cmp(const void *f1, const void *f2); -time_t ecl_util_make_date(int mday , int month , int year); -time_t ecl_util_make_date__(int mday , int month , int year, int * year_offset); -ert_ecl_unit_enum ecl_util_get_unit_set(const char * data_file); +#include -bool ecl_util_valid_basename_fmt( const char * basename_fmt ); -bool ecl_util_valid_basename( const char * basename ); -const char * ecl_util_get_phase_name( ecl_phase_enum phase ); -int ecl_util_select_filelist( const char * path , const char * base , ecl_file_enum file_type , bool fmt_file , stringlist_type * filelist); -void ecl_util_append_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date , bool force_append_end); -void ecl_util_init_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date); -void ecl_util_set_date_values(time_t t , int * mday , int * month , int * year); -bool ecl_util_path_access(const char * ecl_case); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.hpp b/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.hpp index 6118488a7e..0cf1ada4b7 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/ecl_util.hpp @@ -1,19 +1,151 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_util.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_ECL_UTIL_H +#define ERT_ECL_UTIL_H +#ifdef __cplusplus +extern "C" { +#endif +#include +#include + +#include +#include +#include +#include + + +typedef enum { ECL_OTHER_FILE = 0 , + ECL_RESTART_FILE = 1 , + ECL_UNIFIED_RESTART_FILE = 2 , + ECL_SUMMARY_FILE = 4 , + ECL_UNIFIED_SUMMARY_FILE = 8 , + ECL_SUMMARY_HEADER_FILE = 16 , + ECL_GRID_FILE = 32 , + ECL_EGRID_FILE = 64 , + ECL_INIT_FILE = 128 , + ECL_RFT_FILE = 256 , + ECL_DATA_FILE = 512 } ecl_file_enum; + + + + /* + This enum enumerates the four different ways summary and restart information + can be stored. + */ + + + typedef enum { ECL_INVALID_STORAGE = 0, + ECL_BINARY_UNIFIED = 1, + ECL_FORMATTED_UNIFIED = 2, + ECL_BINARY_NON_UNIFIED = 4, + ECL_FORMATTED_NON_UNIFIED = 8} ecl_storage_enum; + +/* + The libecl library has been built and tested 99.5% with ECLIPSE100 + as context, but in thye gravity code there is some very limited + functionality related to ECLIPSE100 versus ECLIPSE300 functionality. + + Observe that numerical values found as part of the INTEHAD keyword + differ from these values, and are found in the ecl_kw_magic.h + header. +*/ + +typedef enum { + ECLIPSE_UNDEFINED = 0, + ECLIPSE100 = 1, + ECLIPSE300 = 2, + ECLIPSE300_THERMAL = 3, + INTERSECT = 4, + FRONTSIM = 5 +} ecl_version_enum; + +/* + Observe that the numerical enum VALUES matches those found in item + 14 in the INTEHEAD keyword in the ECLIPSE INIT files; i.e. the + distribution of numerical values 1,2,4 can NOT BE CHANGED. + + The function ecl_util_get_phase_name() can be used to lookup a + string name from an enum value. + + The phases in a simulation will typically be a sum of these + fundamental phases, and represented as an integer. +*/ + +typedef enum { + ECL_OIL_PHASE = 1, + ECL_GAS_PHASE = 2, + ECL_WATER_PHASE = 4 +} ecl_phase_enum; + +#define ECL_PHASE_ENUM_DEFS {.value = 1 , .name = "ECL_OIL_PHASE"}, {.value = 2 , .name = "ECL_GAS_PHASE"} , {.value = 4 , .name = "ECL_WATER_PHASE"} +#define ECL_PHASE_ENUM_SIZE 3 + +typedef enum { + ECL_METRIC_UNITS = 1, + ECL_FIELD_UNITS = 2, + ECL_LAB_UNITS = 3, + ECL_PVT_M_UNITS = 4 +} ert_ecl_unit_enum; + + +// For unformatted files: +#define ECL_BOOL_TRUE_INT -1 // Binary representation: 11111111 11111111 11111111 1111111 +#define ECL_BOOL_FALSE_INT 0 // Binary representation: 00000000 00000000 00000000 0000000 +#define ECL_COMMENT_STRING "--" +#define ECL_COMMENT_CHAR '-' // Need to consecutive to make an ECLIPSE comment +#define ECL_DATA_TERMINATION "/" + + +/*****************************************************************/ +bool ecl_util_unified_file(const char *filename); +const char * ecl_util_file_type_name( ecl_file_enum file_type ); +char * ecl_util_alloc_base_guess(const char *); +int ecl_util_filename_report_nr(const char *); +ecl_file_enum ecl_util_inspect_extension(const char * ext , bool *_fmt_file, int * _report_nr); +ecl_file_enum ecl_util_get_file_type(const char * filename, bool * fmt_file, int * report_nr); +char * ecl_util_alloc_filename(const char * /* path */, const char * /* base */, ecl_file_enum , bool /* fmt_file */ , int /*report_nr*/); +char * ecl_util_alloc_exfilename(const char * /* path */, const char * /* base */, ecl_file_enum , bool /* fmt_file */ , int /*report_nr*/); +void ecl_util_memcpy_typed_data(void *, const void * , ecl_data_type , ecl_data_type , int ); +void ecl_util_escape_kw(char * kw); +bool ecl_util_alloc_summary_files(const char * , const char * , const char * , char ** , stringlist_type * ); +void ecl_util_alloc_summary_data_files(const char * path , const char * base , bool fmt_file , stringlist_type * filelist); +void ecl_util_alloc_restart_files(const char * , const char * , char *** , int * , bool * , bool *); +time_t ecl_util_get_start_date(const char * ); +int ecl_util_get_num_cpu(const char * data_file); +bool ecl_util_fmt_file(const char * filename , bool * __fmt_file); +char * ecl_util_alloc_exfilename_anyfmt(const char * path, const char * base , ecl_file_enum file_type , bool start_fmt , int report_nr); +int ecl_util_get_month_nr(const char * month_name); +int ecl_util_fname_report_cmp(const void *f1, const void *f2); +time_t ecl_util_make_date(int mday , int month , int year); +time_t ecl_util_make_date__(int mday , int month , int year, int * year_offset); +ert_ecl_unit_enum ecl_util_get_unit_set(const char * data_file); + +bool ecl_util_valid_basename_fmt( const char * basename_fmt ); +bool ecl_util_valid_basename( const char * basename ); +const char * ecl_util_get_phase_name( ecl_phase_enum phase ); + +int ecl_util_select_filelist( const char * path , const char * base , ecl_file_enum file_type , bool fmt_file , stringlist_type * filelist); +void ecl_util_append_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date , bool force_append_end); +void ecl_util_init_month_range( time_t_vector_type * date_list , time_t start_date , time_t end_date); +void ecl_util_set_date_values(time_t t , int * mday , int * month , int * year); +bool ecl_util_path_access(const char * ecl_case); +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/fault_block.h b/ThirdParty/Ert/lib/include/ert/ecl/fault_block.h index e91c8e6e7b..30d072c663 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/fault_block.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/fault_block.h @@ -1,61 +1,9 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'fault_block.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_FAULT_BLOCK_H -#define ERT_FAULT_BLOCK_H -#ifdef __cplusplus -extern "C" { -#endif +#include -#include -#include -#include -#include - -#include -#include - - - - - typedef struct fault_block_struct fault_block_type; - - void fault_block_free__( void * arg); - int fault_block_get_size( const fault_block_type * block ); - double fault_block_get_xc( fault_block_type * fault_block ); - double fault_block_get_yc( fault_block_type * fault_block ); - int fault_block_get_id( const fault_block_type * block ); - int fault_block_get_size( const fault_block_type * fault_block ); - void fault_block_export_cell(const fault_block_type * fault_block , int index , int * i , int * j , int * k , double * x, double * y, double * z); - void fault_block_assign_to_region( fault_block_type * fault_block , int region_id ); - const int_vector_type * fault_block_get_region_list( const fault_block_type * fault_block ); - int fault_block_iget_j(const fault_block_type * fault_block , int index); - int fault_block_iget_i(const fault_block_type * fault_block , int index); - void fault_block_add_cell( fault_block_type * fault_block , int i , int j); - bool fault_block_trace_edge( const fault_block_type * block , double_vector_type * x_list , double_vector_type * y_list, int_vector_type * cell_list); - const int_vector_type * fault_block_get_global_index_list( const fault_block_type * fault_block); - void fault_block_copy_content(fault_block_type * target_block , const fault_block_type * src_block ); - void fault_block_list_neighbours( const fault_block_type * block , bool connected_only , const geo_polygon_collection_type * polylines , int_vector_type * neighbour_list); - - UTIL_IS_INSTANCE_HEADER(fault_block); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/fault_block.hpp b/ThirdParty/Ert/lib/include/ert/ecl/fault_block.hpp index 901d2167b2..5d9ebbc27a 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/fault_block.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/fault_block.hpp @@ -1,20 +1,61 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'fault_block.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ +#ifndef ERT_FAULT_BLOCK_H +#define ERT_FAULT_BLOCK_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#include + +#include +#include + + + + + typedef struct fault_block_struct fault_block_type; + + void fault_block_free__( void * arg); + int fault_block_get_size( const fault_block_type * block ); + double fault_block_get_xc( fault_block_type * fault_block ); + double fault_block_get_yc( fault_block_type * fault_block ); + int fault_block_get_id( const fault_block_type * block ); + int fault_block_get_size( const fault_block_type * fault_block ); + void fault_block_export_cell(const fault_block_type * fault_block , int index , int * i , int * j , int * k , double * x, double * y, double * z); + void fault_block_assign_to_region( fault_block_type * fault_block , int region_id ); + const int_vector_type * fault_block_get_region_list( const fault_block_type * fault_block ); + int fault_block_iget_j(const fault_block_type * fault_block , int index); + int fault_block_iget_i(const fault_block_type * fault_block , int index); + void fault_block_add_cell( fault_block_type * fault_block , int i , int j); + bool fault_block_trace_edge( const fault_block_type * block , double_vector_type * x_list , double_vector_type * y_list, int_vector_type * cell_list); + const int_vector_type * fault_block_get_global_index_list( const fault_block_type * fault_block); + void fault_block_copy_content(fault_block_type * target_block , const fault_block_type * src_block ); + void fault_block_list_neighbours( const fault_block_type * block , bool connected_only , const geo_polygon_collection_type * polylines , int_vector_type * neighbour_list); + + UTIL_IS_INSTANCE_HEADER(fault_block); -#include +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.h b/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.h index e95a3ea5ae..0d0bcd59a8 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.h @@ -1,61 +1,9 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'fault_block_layer.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_FAULT_BLOCK_LAYER_H -#define ERT_FAULT_BLOCK_LAYER_H -#ifdef __cplusplus -extern "C" { -#endif +#include -#include -#include -#include -#include -#include - - UTIL_IS_INSTANCE_HEADER(fault_block_layer); - - typedef struct fault_block_layer_struct fault_block_layer_type; - - fault_block_layer_type * fault_block_layer_alloc( const ecl_grid_type * grid , int k); - void fault_block_layer_free( fault_block_layer_type * layer ); - void fault_block_layer_free__( void * arg ); - bool fault_block_layer_has_block( const fault_block_layer_type * layer , int block_id); - void fault_block_layer_del_block( fault_block_layer_type * layer , int block_id); - fault_block_type * fault_block_layer_add_block( fault_block_layer_type * layer , int block_id); - fault_block_type * fault_block_layer_get_block( const fault_block_layer_type * layer , int block_id); - fault_block_type * fault_block_layer_iget_block( const fault_block_layer_type * layer , int storage_index); - fault_block_type * fault_block_layer_safe_get_block( fault_block_layer_type * layer , int block_id); - int fault_block_layer_get_max_id( const fault_block_layer_type * layer ); - int fault_block_layer_get_next_id( const fault_block_layer_type * layer ); - int fault_block_layer_get_size( const fault_block_layer_type * layer); - bool fault_block_layer_scan_kw( fault_block_layer_type * layer , const ecl_kw_type * fault_block_kw); - bool fault_block_layer_load_kw( fault_block_layer_type * layer , const ecl_kw_type * fault_block_kw); - int fault_block_layer_get_k( const fault_block_layer_type * layer ); - void fault_block_layer_scan_layer( fault_block_layer_type * fault_layer , layer_type * layer); - void fault_block_layer_insert_block_content( fault_block_layer_type * layer , const fault_block_type * src_block); - bool fault_block_layer_export( const fault_block_layer_type * layer , ecl_kw_type * faultblock_kw); - const ecl_grid_type * fault_block_layer_get_grid( const fault_block_layer_type * layer ); - layer_type * fault_block_layer_get_layer( const fault_block_layer_type * layer ); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.hpp b/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.hpp index d2266cd641..745fa509d9 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/fault_block_layer.hpp @@ -1,19 +1,61 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'fault_block_layer.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_FAULT_BLOCK_LAYER_H +#define ERT_FAULT_BLOCK_LAYER_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include +#include +#include + + UTIL_IS_INSTANCE_HEADER(fault_block_layer); + + typedef struct fault_block_layer_struct fault_block_layer_type; + + fault_block_layer_type * fault_block_layer_alloc( const ecl_grid_type * grid , int k); + void fault_block_layer_free( fault_block_layer_type * layer ); + void fault_block_layer_free__( void * arg ); + bool fault_block_layer_has_block( const fault_block_layer_type * layer , int block_id); + void fault_block_layer_del_block( fault_block_layer_type * layer , int block_id); + fault_block_type * fault_block_layer_add_block( fault_block_layer_type * layer , int block_id); + fault_block_type * fault_block_layer_get_block( const fault_block_layer_type * layer , int block_id); + fault_block_type * fault_block_layer_iget_block( const fault_block_layer_type * layer , int storage_index); + fault_block_type * fault_block_layer_safe_get_block( fault_block_layer_type * layer , int block_id); + int fault_block_layer_get_max_id( const fault_block_layer_type * layer ); + int fault_block_layer_get_next_id( const fault_block_layer_type * layer ); + int fault_block_layer_get_size( const fault_block_layer_type * layer); + bool fault_block_layer_scan_kw( fault_block_layer_type * layer , const ecl_kw_type * fault_block_kw); + bool fault_block_layer_load_kw( fault_block_layer_type * layer , const ecl_kw_type * fault_block_kw); + int fault_block_layer_get_k( const fault_block_layer_type * layer ); + void fault_block_layer_scan_layer( fault_block_layer_type * fault_layer , layer_type * layer); + void fault_block_layer_insert_block_content( fault_block_layer_type * layer , const fault_block_type * src_block); + bool fault_block_layer_export( const fault_block_layer_type * layer , ecl_kw_type * faultblock_kw); + const ecl_grid_type * fault_block_layer_get_grid( const fault_block_layer_type * layer ); + layer_type * fault_block_layer_get_layer( const fault_block_layer_type * layer ); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/fortio.h b/ThirdParty/Ert/lib/include/ert/ecl/fortio.h index 55d253af06..93a56eb827 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/fortio.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/fortio.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'fortio.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'fortio.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #ifndef ERT_FORTIO_H @@ -27,13 +27,13 @@ extern "C" { #include #include -#include +#include typedef enum { FORTIO_NOENTRY = 0, /* File does not exists at all - application error. */ FORTIO_EOF = 1, /* The file / record is empty */ FORTIO_OK = 2, /* The file / record is OK with: [32 bit header | data | 32 bit footer] */ - FORTIO_MISSING_DATA = 3, + FORTIO_MISSING_DATA = 3, FORTIO_MISSING_TAIL = 4, FORTIO_HEADER_MISMATCH = 5 } fortio_status_type; diff --git a/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.h b/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.h index 46d59abbf6..0b5d7dc84a 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.h @@ -1,37 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'grid_dims.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_GRID_DIMS_H -#define ERT_GRID_DIMS_H -#ifdef __cplusplus -extern "C" { -#endif +#include -typedef struct { - int nx,ny,nz,nactive; -} grid_dims_type; - void grid_dims_init( grid_dims_type * dims , int nx, int ny , int nz , int nactive); - grid_dims_type * grid_dims_alloc( int nx, int ny , int nz , int nactive); - void grid_dims_free( grid_dims_type * dims ); - void grid_dims_free__( void * arg); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.hpp b/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.hpp index 215e1daf11..b7955cf404 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/grid_dims.hpp @@ -1,20 +1,37 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'grid_dims.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ +#ifndef ERT_GRID_DIMS_H +#define ERT_GRID_DIMS_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int nx,ny,nz,nactive; +} grid_dims_type; + + void grid_dims_init( grid_dims_type * dims , int nx, int ny , int nz , int nactive); + grid_dims_type * grid_dims_alloc( int nx, int ny , int nz , int nactive); + void grid_dims_free( grid_dims_type * dims ); + void grid_dims_free__( void * arg); -#include +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/layer.h b/ThirdParty/Ert/lib/include/ert/ecl/layer.h index f1aacf1135..6fe3c63dc6 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/layer.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/layer.h @@ -1,93 +1,9 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'layer.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ERT_LAYER_H -#define ERT_LAYER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -#include - -/* - The elements in this enum are (ab)used as indexes into a int[] vector; - i.e. the must span the values 0..3. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ - typedef enum { - RIGHT_EDGE = 0, - LEFT_EDGE = 1, - TOP_EDGE = 2, - BOTTOM_EDGE = 3 - } edge_dir_enum; - - typedef struct { - int i; - int j; - } int_point2d_type; - - - - typedef struct layer_struct layer_type; - - bool layer_iget_left_barrier( const layer_type * layer, int i , int j); - bool layer_iget_bottom_barrier( const layer_type * layer, int i , int j); - int layer_get_nx( const layer_type * layer ); - int layer_get_ny( const layer_type * layer ); - void layer_fprintf_cell( const layer_type * layer , int i , int j , FILE * stream); - void layer_fprintf( const layer_type * layer , FILE * stream); - void layer_fprintf_box( const layer_type * layer , FILE * stream , int i1 , int i2 , int j1 , int j2); - layer_type * layer_alloc(int nx , int ny); - void layer_free( layer_type * layer ); - int layer_replace_cell_values( layer_type * layer , int old_value , int new_value); - bool layer_iget_active( const layer_type * layer, int i , int j); - int layer_iget_cell_value( const layer_type * layer, int i , int j); - void layer_iset_cell_value( layer_type * layer , int i , int j , int value); - int layer_iget_edge_value( const layer_type * layer , int i , int j , edge_dir_enum dir); - bool layer_cell_on_edge( const layer_type * layer , int i , int j); - int layer_get_ny( const layer_type * layer); - int layer_get_nx( const layer_type * layer); - int layer_get_cell_sum( const layer_type * layer ); - bool layer_trace_block_content( layer_type * layer , bool erase , int start_i , int start_j , int value , int_vector_type * i_list , int_vector_type * j_list); - bool layer_trace_block_edge( const layer_type * layer , int i , int j , int value , struct_vector_type * corner_list , int_vector_type * cell_list); - bool layer_cell_contact( const layer_type * layer , int i1 , int j1 , int i2 , int j2); - void layer_add_interp_barrier( layer_type * layer , int c1 , int c2); - void layer_add_ijbarrier( layer_type * layer , int i1 , int j1 , int i2 , int j2 ); - void layer_add_barrier( layer_type * layer , int c1 , int c2); - void layer_memcpy(layer_type * target_layer , const layer_type * src_layer); - void layer_update_active( layer_type * layer , const ecl_grid_type * grid , int k); - void layer_clear_cells( layer_type * layer); - void layer_update_connected_cells( layer_type * layer , int i , int j , int org_value , int new_value); - void layer_assign( layer_type * layer, int value); - - void layer_cells_equal( const layer_type * layer , int value , int_vector_type * i_list , int_vector_type * j_list); - int layer_count_equal( const layer_type * layer , int value ); - -UTIL_IS_INSTANCE_HEADER( layer ); -UTIL_SAFE_CAST_HEADER( layer ); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/layer.hpp b/ThirdParty/Ert/lib/include/ert/ecl/layer.hpp index 97de3b6bcc..450ee240d3 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/layer.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/layer.hpp @@ -1,19 +1,92 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'layer.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_LAYER_H +#define ERT_LAYER_H + + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + The elements in this enum are (ab)used as indexes into a int[] vector; + i.e. the must span the values 0..3. +*/ + + typedef enum { + RIGHT_EDGE = 0, + LEFT_EDGE = 1, + TOP_EDGE = 2, + BOTTOM_EDGE = 3 + } edge_dir_enum; + + typedef struct { + int i; + int j; + } int_point2d_type; + + + + typedef struct layer_struct layer_type; + + bool layer_iget_left_barrier( const layer_type * layer, int i , int j); + bool layer_iget_bottom_barrier( const layer_type * layer, int i , int j); + int layer_get_nx( const layer_type * layer ); + int layer_get_ny( const layer_type * layer ); + void layer_fprintf_cell( const layer_type * layer , int i , int j , FILE * stream); + void layer_fprintf( const layer_type * layer , FILE * stream); + void layer_fprintf_box( const layer_type * layer , FILE * stream , int i1 , int i2 , int j1 , int j2); + layer_type * layer_alloc(int nx , int ny); + void layer_free( layer_type * layer ); + int layer_replace_cell_values( layer_type * layer , int old_value , int new_value); + bool layer_iget_active( const layer_type * layer, int i , int j); + int layer_iget_cell_value( const layer_type * layer, int i , int j); + void layer_iset_cell_value( layer_type * layer , int i , int j , int value); + int layer_iget_edge_value( const layer_type * layer , int i , int j , edge_dir_enum dir); + bool layer_cell_on_edge( const layer_type * layer , int i , int j); + int layer_get_ny( const layer_type * layer); + int layer_get_nx( const layer_type * layer); + int layer_get_cell_sum( const layer_type * layer ); + bool layer_trace_block_content( layer_type * layer , bool erase , int start_i , int start_j , int value , int_vector_type * i_list , int_vector_type * j_list); + bool layer_cell_contact( const layer_type * layer , int i1 , int j1 , int i2 , int j2); + void layer_add_interp_barrier( layer_type * layer , int c1 , int c2); + void layer_add_ijbarrier( layer_type * layer , int i1 , int j1 , int i2 , int j2 ); + void layer_add_barrier( layer_type * layer , int c1 , int c2); + void layer_memcpy(layer_type * target_layer , const layer_type * src_layer); + void layer_update_active( layer_type * layer , const ecl_grid_type * grid , int k); + void layer_clear_cells( layer_type * layer); + void layer_update_connected_cells( layer_type * layer , int i , int j , int org_value , int new_value); + void layer_assign( layer_type * layer, int value); + + void layer_cells_equal( const layer_type * layer , int value , int_vector_type * i_list , int_vector_type * j_list); + int layer_count_equal( const layer_type * layer , int value ); + +UTIL_IS_INSTANCE_HEADER( layer ); +UTIL_SAFE_CAST_HEADER( layer ); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.h b/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.h index 396a74d556..ac62f32dc4 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.h @@ -1,60 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'nnc_info.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_NNC_INFO_H -#define ERT_NNC_INFO_H -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#include - - typedef struct nnc_info_struct nnc_info_type; - - UTIL_IS_INSTANCE_HEADER(nnc_info); - - nnc_info_type * nnc_info_alloc(int lgr_nr); - void nnc_info_free( nnc_info_type * nnc_info ); - void nnc_info_add_nnc(nnc_info_type * nnc_info, int lgr_nr, int global_cell_number, int nnc_index); - - const int_vector_type * nnc_info_iget_grid_index_list(const nnc_info_type * nnc_info, int lgr_index); - nnc_vector_type * nnc_info_iget_vector( const nnc_info_type * nnc_info , int lgr_index); - - const int_vector_type * nnc_info_get_grid_index_list(const nnc_info_type * nnc_info, int lgr_nr); - nnc_vector_type * nnc_info_get_vector( const nnc_info_type * nnc_info , int lgr_nr); - - const int_vector_type * nnc_info_get_self_grid_index_list(const nnc_info_type * nnc_info); - nnc_vector_type * nnc_info_get_self_vector( const nnc_info_type * nnc_info ); - - int nnc_info_get_lgr_nr(const nnc_info_type * nnc_info ); - int nnc_info_get_size( const nnc_info_type * nnc_info ); - int nnc_info_get_total_size( const nnc_info_type * nnc_info ); - void nnc_info_fprintf(const nnc_info_type * nnc_info , FILE * stream); - - bool nnc_info_equal( const nnc_info_type * nnc_info1 , const nnc_info_type * nnc_info2 ); - nnc_info_type * nnc_info_alloc_copy( const nnc_info_type * src_info ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.hpp b/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.hpp index 93b5b155e1..91858cefbf 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/nnc_info.hpp @@ -1,19 +1,60 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'nnc_info.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include + +#ifndef ERT_NNC_INFO_H +#define ERT_NNC_INFO_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include + + typedef struct nnc_info_struct nnc_info_type; + + UTIL_IS_INSTANCE_HEADER(nnc_info); + + nnc_info_type * nnc_info_alloc(int lgr_nr); + void nnc_info_free( nnc_info_type * nnc_info ); + void nnc_info_add_nnc(nnc_info_type * nnc_info, int lgr_nr, int global_cell_number, int nnc_index); + + const int_vector_type * nnc_info_iget_grid_index_list(const nnc_info_type * nnc_info, int lgr_index); + nnc_vector_type * nnc_info_iget_vector( const nnc_info_type * nnc_info , int lgr_index); + + const int_vector_type * nnc_info_get_grid_index_list(const nnc_info_type * nnc_info, int lgr_nr); + nnc_vector_type * nnc_info_get_vector( const nnc_info_type * nnc_info , int lgr_nr); + + const int_vector_type * nnc_info_get_self_grid_index_list(const nnc_info_type * nnc_info); + nnc_vector_type * nnc_info_get_self_vector( const nnc_info_type * nnc_info ); + + int nnc_info_get_lgr_nr(const nnc_info_type * nnc_info ); + int nnc_info_get_size( const nnc_info_type * nnc_info ); + int nnc_info_get_total_size( const nnc_info_type * nnc_info ); + void nnc_info_fprintf(const nnc_info_type * nnc_info , FILE * stream); + + bool nnc_info_equal( const nnc_info_type * nnc_info1 , const nnc_info_type * nnc_info2 ); + nnc_info_type * nnc_info_alloc_copy( const nnc_info_type * src_info ); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.h b/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.h index dca90b0e80..2c1813e34a 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.h @@ -1,50 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'nnc_vector.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_NNC_VECTOR_H -#define ERT_NNC_VECTOR_H -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - - typedef struct nnc_vector_struct nnc_vector_type; - - UTIL_IS_INSTANCE_HEADER(nnc_vector); - - int nnc_vector_iget_nnc_index( const nnc_vector_type * nnc_vector , int index ); - int nnc_vector_iget_grid_index( const nnc_vector_type * nnc_vector , int index ); - nnc_vector_type * nnc_vector_alloc(int lgr_nr); - nnc_vector_type * nnc_vector_alloc_copy(const nnc_vector_type * src_vector); - void nnc_vector_free( nnc_vector_type * nnc_vector ); - void nnc_vector_add_nnc(nnc_vector_type * nnc_vector, int global_cell_number, int nnc_index); - const int_vector_type * nnc_vector_get_grid_index_list(const nnc_vector_type * nnc_vector); - const int_vector_type * nnc_vector_get_nnc_index_list(const nnc_vector_type * nnc_vector); - int nnc_vector_get_lgr_nr(const nnc_vector_type * nnc_vector ); - void nnc_vector_free__(void * arg); - int nnc_vector_get_size( const nnc_vector_type * nnc_vector ); - bool nnc_vector_equal( const nnc_vector_type * nnc_vector1 , const nnc_vector_type * nnc_vector2); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.hpp b/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.hpp index c2194dcd82..3c5f6c304c 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/nnc_vector.hpp @@ -1,19 +1,50 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'nnc_vector.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include + +#ifndef ERT_NNC_VECTOR_H +#define ERT_NNC_VECTOR_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + typedef struct nnc_vector_struct nnc_vector_type; + + UTIL_IS_INSTANCE_HEADER(nnc_vector); + + int nnc_vector_iget_nnc_index( const nnc_vector_type * nnc_vector , int index ); + int nnc_vector_iget_grid_index( const nnc_vector_type * nnc_vector , int index ); + nnc_vector_type * nnc_vector_alloc(int lgr_nr); + nnc_vector_type * nnc_vector_alloc_copy(const nnc_vector_type * src_vector); + void nnc_vector_free( nnc_vector_type * nnc_vector ); + void nnc_vector_add_nnc(nnc_vector_type * nnc_vector, int global_cell_number, int nnc_index); + const int_vector_type * nnc_vector_get_grid_index_list(const nnc_vector_type * nnc_vector); + const int_vector_type * nnc_vector_get_nnc_index_list(const nnc_vector_type * nnc_vector); + int nnc_vector_get_lgr_nr(const nnc_vector_type * nnc_vector ); + void nnc_vector_free__(void * arg); + int nnc_vector_get_size( const nnc_vector_type * nnc_vector ); + bool nnc_vector_equal( const nnc_vector_type * nnc_vector1 , const nnc_vector_type * nnc_vector2); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.h b/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.h index 5f2e13b1ba..e0e4b77ccd 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.h +++ b/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.h @@ -1,148 +1,9 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'smspec_node.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_SMSPEC_NODE_H -#define ERT_SMSPEC_NODE_H -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define DUMMY_WELL ":+:+:+:+" -#define IS_DUMMY_WELL(well) (strcmp((well) , DUMMY_WELL) == 0) -#define SMSPEC_PARAMS_INDEX_INVALID -77 - - -#define SMSPEC_TIME_KEYWORD "TIME" -#define SMSPEC_TIME_NUMS_VALUE -32676 - -#define SMSPEC_YEARS_KEYWORD "YEARS" -#define SMSPEC_YEARS_NUMS_VALUE -32676 - - -typedef enum {ECL_SMSPEC_INVALID_VAR = 0 , - ECL_SMSPEC_FIELD_VAR = 1 , /* X */ - ECL_SMSPEC_REGION_VAR = 2 , /* X */ - ECL_SMSPEC_GROUP_VAR = 3 , /* X */ - ECL_SMSPEC_WELL_VAR = 4 , /* X */ - ECL_SMSPEC_SEGMENT_VAR = 5 , /* X */ - ECL_SMSPEC_BLOCK_VAR = 6 , /* X */ - ECL_SMSPEC_AQUIFER_VAR = 7 , - ECL_SMSPEC_COMPLETION_VAR = 8 , /* X */ - ECL_SMSPEC_NETWORK_VAR = 9 , - ECL_SMSPEC_REGION_2_REGION_VAR = 10 , - ECL_SMSPEC_LOCAL_BLOCK_VAR = 11 , /* X */ - ECL_SMSPEC_LOCAL_COMPLETION_VAR = 12 , /* X */ - ECL_SMSPEC_LOCAL_WELL_VAR = 13 , /* X */ - ECL_SMSPEC_MISC_VAR = 14 /* X */} ecl_smspec_var_type; - - -#define SMSPEC_NUMS_INVALID -991199 -#define SMSPEC_NUMS_WELL 1 -#define SMSPEC_NUMS_GROUP 2 -#define SMSPEC_NUMS_FIELD 0 - - typedef struct smspec_node_struct smspec_node_type; - - char * smspec_alloc_block_ijk_key( const char * join_string , const char * keyword , int i , int j , int k); - char * smspec_alloc_completion_ijk_key( const char * join_string , const char * keyword, const char * wgname , int i , int j , int k); - char * smspec_alloc_completion_num_key( const char * join_string , const char * keyword, const char * wgname , int num); - char * smspec_alloc_group_key( const char * join_string , const char * keyword , const char * wgname); - char * smspec_alloc_well_key( const char * join_string , const char * keyword , const char * wgname); - char * smspec_alloc_region_key( const char * join_string , const char * keyword , int num); - char * smspec_alloc_region_2_region_r1r2_key( const char * join_string , const char * keyword , int r1, int r2); - char * smspec_alloc_region_2_region_num_key( const char * join_string , const char * keyword , int num); - char * smspec_alloc_segment_key( const char * join_string , const char * keyword , const char * wgname , int num); - char * smspec_alloc_block_num_key( const char * join_string , const char * keyword , int num); - char * smspec_alloc_local_well_key( const char * join_string , const char * keyword , const char * lgr_name , const char * wgname); - char * smspec_alloc_local_block_key( const char * join_string , const char * keyword , const char * lgr_name , int i , int j , int k); - char * smspec_alloc_local_completion_key( const char * join_string, const char * keyword , const char * lgr_name , const char * wgname , int i , int j , int k); - - bool smspec_node_equal( const smspec_node_type * node1, const smspec_node_type * node2); - - void smspec_node_init( smspec_node_type * smspec_node, - ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * key_join_string , - const int grid_dims[3] , - int num); - - smspec_node_type * smspec_node_alloc( ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * key_join_string , - const int grid_dims[3] , - int num , int param_index, float default_value); - - smspec_node_type * smspec_node_alloc_lgr( ecl_smspec_var_type var_type , - const char * wgname , - const char * keyword , - const char * unit , - const char * lgr , - const char * key_join_string , - int lgr_i, int lgr_j , int lgr_k, - int param_index, - float default_value); - - smspec_node_type * smspec_node_alloc_new(int params_index, float default_value); - smspec_node_type * smspec_node_alloc_copy( const smspec_node_type* ); - - void smspec_node_free( smspec_node_type * index ); - void smspec_node_free__(void * arg); - void smspec_node_set_params_index( smspec_node_type * smspec_node , int params_index); - int smspec_node_get_params_index( const smspec_node_type * smspec_node ); - const char * smspec_node_get_gen_key1( const smspec_node_type * smspec_node); - const char * smspec_node_get_gen_key2( const smspec_node_type * smspec_node); - ecl_smspec_var_type smspec_node_get_var_type( const smspec_node_type * smspec_node); - int smspec_node_get_num( const smspec_node_type * smspec_node); - const char * smspec_node_get_wgname( const smspec_node_type * smspec_node); - void smspec_node_update_wgname( smspec_node_type * index , const char * wgname , const char * key_join_string); - const char * smspec_node_get_keyword( const smspec_node_type * smspec_node); - const char * smspec_node_get_unit( const smspec_node_type * smspec_node); - void smspec_node_set_unit( smspec_node_type * smspec_node , const char * unit ); - bool smspec_node_is_rate( const smspec_node_type * smspec_node ); - bool smspec_node_is_total( const smspec_node_type * smspec_node ); - bool smspec_node_is_historical( const smspec_node_type * smspec_node ); - bool smspec_node_is_valid( const smspec_node_type * smspec_node ); - bool smspec_node_need_nums( const smspec_node_type * smspec_node ); - void smspec_node_fprintf( const smspec_node_type * smspec_node , FILE * stream); - - void smspec_node_set_default( smspec_node_type * smspec_node , float default_value); - float smspec_node_get_default( const smspec_node_type * smspec_node); - - const int* smspec_node_get_ijk( const smspec_node_type * smpsec_node ); - const char* smspec_node_get_lgr_name( const smspec_node_type * smpsec_node ); - const int* smspec_node_get_lgr_ijk( const smspec_node_type * smpsec_node ); - - int smspec_node_get_R1( const smspec_node_type * smpsec_node ); - int smspec_node_get_R2( const smspec_node_type * smpsec_node ); - - int smspec_node_cmp( const smspec_node_type * node1, const smspec_node_type * node2); - int smspec_node_cmp__( const void * node1, const void * node2); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.hpp b/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.hpp index 0a6f2f7f18..a8dfc0dba2 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl/smspec_node.hpp @@ -1,20 +1,148 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'smspec_node.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_SMSPEC_NODE_H +#define ERT_SMSPEC_NODE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DUMMY_WELL ":+:+:+:+" +#define IS_DUMMY_WELL(well) (strcmp((well) , DUMMY_WELL) == 0) +#define SMSPEC_PARAMS_INDEX_INVALID -77 + + +#define SMSPEC_TIME_KEYWORD "TIME" +#define SMSPEC_TIME_NUMS_VALUE -32676 + +#define SMSPEC_YEARS_KEYWORD "YEARS" +#define SMSPEC_YEARS_NUMS_VALUE -32676 + + +typedef enum {ECL_SMSPEC_INVALID_VAR = 0 , + ECL_SMSPEC_FIELD_VAR = 1 , /* X */ + ECL_SMSPEC_REGION_VAR = 2 , /* X */ + ECL_SMSPEC_GROUP_VAR = 3 , /* X */ + ECL_SMSPEC_WELL_VAR = 4 , /* X */ + ECL_SMSPEC_SEGMENT_VAR = 5 , /* X */ + ECL_SMSPEC_BLOCK_VAR = 6 , /* X */ + ECL_SMSPEC_AQUIFER_VAR = 7 , + ECL_SMSPEC_COMPLETION_VAR = 8 , /* X */ + ECL_SMSPEC_NETWORK_VAR = 9 , + ECL_SMSPEC_REGION_2_REGION_VAR = 10 , + ECL_SMSPEC_LOCAL_BLOCK_VAR = 11 , /* X */ + ECL_SMSPEC_LOCAL_COMPLETION_VAR = 12 , /* X */ + ECL_SMSPEC_LOCAL_WELL_VAR = 13 , /* X */ + ECL_SMSPEC_MISC_VAR = 14 /* X */} ecl_smspec_var_type; + + +#define SMSPEC_NUMS_INVALID -991199 +#define SMSPEC_NUMS_WELL 1 +#define SMSPEC_NUMS_GROUP 2 +#define SMSPEC_NUMS_FIELD 0 + + typedef struct smspec_node_struct smspec_node_type; + + char * smspec_alloc_block_ijk_key( const char * join_string , const char * keyword , int i , int j , int k); + char * smspec_alloc_completion_ijk_key( const char * join_string , const char * keyword, const char * wgname , int i , int j , int k); + char * smspec_alloc_completion_num_key( const char * join_string , const char * keyword, const char * wgname , int num); + char * smspec_alloc_group_key( const char * join_string , const char * keyword , const char * wgname); + char * smspec_alloc_well_key( const char * join_string , const char * keyword , const char * wgname); + char * smspec_alloc_region_key( const char * join_string , const char * keyword , int num); + char * smspec_alloc_region_2_region_r1r2_key( const char * join_string , const char * keyword , int r1, int r2); + char * smspec_alloc_region_2_region_num_key( const char * join_string , const char * keyword , int num); + char * smspec_alloc_segment_key( const char * join_string , const char * keyword , const char * wgname , int num); + char * smspec_alloc_block_num_key( const char * join_string , const char * keyword , int num); + char * smspec_alloc_local_well_key( const char * join_string , const char * keyword , const char * lgr_name , const char * wgname); + char * smspec_alloc_local_block_key( const char * join_string , const char * keyword , const char * lgr_name , int i , int j , int k); + char * smspec_alloc_local_completion_key( const char * join_string, const char * keyword , const char * lgr_name , const char * wgname , int i , int j , int k); + + bool smspec_node_equal( const smspec_node_type * node1, const smspec_node_type * node2); + + void smspec_node_init( smspec_node_type * smspec_node, + ecl_smspec_var_type var_type , + const char * wgname , + const char * keyword , + const char * unit , + const char * key_join_string , + const int grid_dims[3] , + int num); + + smspec_node_type * smspec_node_alloc( ecl_smspec_var_type var_type , + const char * wgname , + const char * keyword , + const char * unit , + const char * key_join_string , + const int grid_dims[3] , + int num , int param_index, float default_value); + + smspec_node_type * smspec_node_alloc_lgr( ecl_smspec_var_type var_type , + const char * wgname , + const char * keyword , + const char * unit , + const char * lgr , + const char * key_join_string , + int lgr_i, int lgr_j , int lgr_k, + int param_index, + float default_value); + + smspec_node_type * smspec_node_alloc_new(int params_index, float default_value); + smspec_node_type * smspec_node_alloc_copy( const smspec_node_type* ); + + void smspec_node_free( smspec_node_type * index ); + void smspec_node_free__(void * arg); + void smspec_node_set_params_index( smspec_node_type * smspec_node , int params_index); + int smspec_node_get_params_index( const smspec_node_type * smspec_node ); + const char * smspec_node_get_gen_key1( const smspec_node_type * smspec_node); + const char * smspec_node_get_gen_key2( const smspec_node_type * smspec_node); + ecl_smspec_var_type smspec_node_get_var_type( const smspec_node_type * smspec_node); + int smspec_node_get_num( const smspec_node_type * smspec_node); + const char * smspec_node_get_wgname( const smspec_node_type * smspec_node); + const char * smspec_node_get_keyword( const smspec_node_type * smspec_node); + const char * smspec_node_get_unit( const smspec_node_type * smspec_node); + void smspec_node_set_unit( smspec_node_type * smspec_node , const char * unit ); + bool smspec_node_is_rate( const smspec_node_type * smspec_node ); + bool smspec_node_is_total( const smspec_node_type * smspec_node ); + bool smspec_node_is_historical( const smspec_node_type * smspec_node ); + bool smspec_node_need_nums( const smspec_node_type * smspec_node ); + void smspec_node_fprintf( const smspec_node_type * smspec_node , FILE * stream); + + void smspec_node_set_default( smspec_node_type * smspec_node , float default_value); + float smspec_node_get_default( const smspec_node_type * smspec_node); + + const int* smspec_node_get_ijk( const smspec_node_type * smpsec_node ); + const char* smspec_node_get_lgr_name( const smspec_node_type * smpsec_node ); + const int* smspec_node_get_lgr_ijk( const smspec_node_type * smpsec_node ); + + int smspec_node_get_R1( const smspec_node_type * smpsec_node ); + int smspec_node_get_R2( const smspec_node_type * smpsec_node ); + + int smspec_node_cmp( const smspec_node_type * node1, const smspec_node_type * node2); + int smspec_node_cmp__( const void * node1, const void * node2); + bool smspec_node_identify_total(const char * keyword, ecl_smspec_var_type var_type); + bool smspec_node_identify_rate(const char * keyword); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.h b/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.h index 850e9166f2..720951c7c5 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.h +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.h @@ -1,50 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_branch_collection.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_WELL_BRANCH_COLLECTION_H -#define ERT_WELL_BRANCH_COLLECTION_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - -#include - - typedef struct well_branch_collection_struct well_branch_collection_type; - - well_branch_collection_type * well_branch_collection_alloc(void); - void well_branch_collection_free( well_branch_collection_type * branches ); - void well_branch_collection_free__( void * arg ); - bool well_branch_collection_has_branch( const well_branch_collection_type * branches , int branch_id); - int well_branch_collection_get_size( const well_branch_collection_type * branches ); - const well_segment_type * well_branch_collection_iget_start_segment( const well_branch_collection_type * branches , int index ); - const well_segment_type * well_branch_collection_get_start_segment( const well_branch_collection_type * branches , int branch_id); - bool well_branch_collection_add_start_segment( well_branch_collection_type * branches , const well_segment_type * start_segment); - - UTIL_IS_INSTANCE_HEADER( well_branch_collection ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.hpp index 3815a62422..d7aca7a963 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_branch_collection.hpp @@ -1,20 +1,50 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_branch_collection.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_WELL_BRANCH_COLLECTION_H +#define ERT_WELL_BRANCH_COLLECTION_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +#include + + typedef struct well_branch_collection_struct well_branch_collection_type; + + well_branch_collection_type * well_branch_collection_alloc(void); + void well_branch_collection_free( well_branch_collection_type * branches ); + void well_branch_collection_free__( void * arg ); + bool well_branch_collection_has_branch( const well_branch_collection_type * branches , int branch_id); + int well_branch_collection_get_size( const well_branch_collection_type * branches ); + const well_segment_type * well_branch_collection_iget_start_segment( const well_branch_collection_type * branches , int index ); + const well_segment_type * well_branch_collection_get_start_segment( const well_branch_collection_type * branches , int branch_id); + bool well_branch_collection_add_start_segment( well_branch_collection_type * branches , const well_segment_type * start_segment); + + UTIL_IS_INSTANCE_HEADER( well_branch_collection ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.h b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.h index 5ae4b1e20c..813a599d40 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.h +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.h @@ -1,88 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'well_conn.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_WELL_CONN_H -#define ERT_WELL_CONN_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - -#include - - typedef enum { - well_conn_dirX = 1, - well_conn_dirY = 2, - well_conn_dirZ = 3, - well_conn_fracX = 4, - well_conn_fracY = 5 - } well_conn_dir_enum; - - - typedef struct well_conn_struct well_conn_type; - - - void well_conn_free( well_conn_type * conn); - void well_conn_free__( void * arg ); - - well_conn_type * well_conn_alloc( int i , int j , int k , double connection_factor , well_conn_dir_enum dir, bool open); - well_conn_type * well_conn_alloc_MSW( int i , int j , int k , double connection_factor , well_conn_dir_enum dir, bool open, int segment); - well_conn_type * well_conn_alloc_fracture( int i , int j , int k , double connection_factor , well_conn_dir_enum dir, bool open); - well_conn_type * well_conn_alloc_fracture_MSW( int i , int j , int k , double connection_factor , well_conn_dir_enum dir, bool open, int segment); - - bool well_conn_MSW(const well_conn_type * conn); - - well_conn_type * well_conn_alloc_from_kw( const ecl_kw_type * icon_kw , const ecl_kw_type * scon_kw , const ecl_kw_type* xcon_kw, const ecl_rsthead_type * header , int well_nr , int conn_nr); - well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const ecl_rsthead_type * header , int well_nr); - - int well_conn_get_i(const well_conn_type * conn); - int well_conn_get_j(const well_conn_type * conn); - int well_conn_get_k(const well_conn_type * conn); - well_conn_dir_enum well_conn_get_dir(const well_conn_type * conn); - bool well_conn_open( const well_conn_type * conn ); - int well_conn_get_segment_id( const well_conn_type * conn ); - bool well_conn_fracture_connection( const well_conn_type * conn); - bool well_conn_matrix_connection( const well_conn_type * conn); - bool well_conn_equal( const well_conn_type *conn1 , const well_conn_type * conn2); - double well_conn_get_connection_factor( const well_conn_type * conn ); - - double well_conn_get_oil_rate(const well_conn_type *conn); - double well_conn_get_gas_rate(const well_conn_type *conn); - double well_conn_get_water_rate(const well_conn_type *conn); - double well_conn_get_volume_rate(const well_conn_type *conn); - - double well_conn_get_oil_rate_si(const well_conn_type *conn); - double well_conn_get_gas_rate_si(const well_conn_type *conn); - double well_conn_get_water_rate_si(const well_conn_type *conn); - double well_conn_get_volume_rate_si(const well_conn_type *conn); - - -UTIL_IS_INSTANCE_HEADER( well_conn ); - UTIL_SAFE_CAST_HEADER( well_conn ); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.hpp index 98459f44e6..610779ab5d 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn.hpp @@ -1,20 +1,89 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'well_conn.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_WELL_CONN_H +#define ERT_WELL_CONN_H + + + +#include + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef enum { + well_conn_dirX = 1, + well_conn_dirY = 2, + well_conn_dirZ = 3, + well_conn_fracX = 4, + well_conn_fracY = 5 + } well_conn_dir_enum; + + + typedef struct well_conn_struct well_conn_type; + + + void well_conn_free( well_conn_type * conn); + void well_conn_free__( void * arg ); + + well_conn_type * well_conn_alloc( int i , int j , int k , double connection_factor , well_conn_dir_enum dir, bool open); + well_conn_type * well_conn_alloc_MSW( int i , int j , int k , double connection_factor , well_conn_dir_enum dir, bool open, int segment); + well_conn_type * well_conn_alloc_fracture( int i , int j , int k , double connection_factor , well_conn_dir_enum dir, bool open); + well_conn_type * well_conn_alloc_fracture_MSW( int i , int j , int k , double connection_factor , well_conn_dir_enum dir, bool open, int segment); + + bool well_conn_MSW(const well_conn_type * conn); + + well_conn_type * well_conn_alloc_from_kw( const ecl_kw_type * icon_kw , const ecl_kw_type * scon_kw , const ecl_kw_type* xcon_kw, const ecl_rsthead_type * header , int well_nr , int conn_nr); + well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const ecl_rsthead_type * header , int well_nr); + + int well_conn_get_i(const well_conn_type * conn); + int well_conn_get_j(const well_conn_type * conn); + int well_conn_get_k(const well_conn_type * conn); + well_conn_dir_enum well_conn_get_dir(const well_conn_type * conn); + bool well_conn_open( const well_conn_type * conn ); + int well_conn_get_segment_id( const well_conn_type * conn ); + bool well_conn_fracture_connection( const well_conn_type * conn); + bool well_conn_matrix_connection( const well_conn_type * conn); + bool well_conn_equal( const well_conn_type *conn1 , const well_conn_type * conn2); + double well_conn_get_connection_factor( const well_conn_type * conn ); + + double well_conn_get_oil_rate(const well_conn_type *conn); + double well_conn_get_gas_rate(const well_conn_type *conn); + double well_conn_get_water_rate(const well_conn_type *conn); + double well_conn_get_volume_rate(const well_conn_type *conn); + + double well_conn_get_oil_rate_si(const well_conn_type *conn); + double well_conn_get_gas_rate_si(const well_conn_type *conn); + double well_conn_get_water_rate_si(const well_conn_type *conn); + double well_conn_get_volume_rate_si(const well_conn_type *conn); + + +UTIL_IS_INSTANCE_HEADER( well_conn ); + UTIL_SAFE_CAST_HEADER( well_conn ); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.h b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.h index 36f9526fc4..9a22aad1b5 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.h +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.h @@ -1,61 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_conn_collection.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_WELL_CONN_COLLECTION_H -#define ERT_WELL_CONN_COLLECTION_H - - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - -#include - -typedef struct well_conn_collection_struct well_conn_collection_type; - -well_conn_collection_type * well_conn_collection_alloc(void); -void well_conn_collection_free(well_conn_collection_type * wellcc); -void well_conn_collection_free__(void * arg); -int well_conn_collection_get_size(const well_conn_collection_type * wellcc); -const well_conn_type * well_conn_collection_iget_const(const well_conn_collection_type * wellcc, - int index); -well_conn_type * well_conn_collection_iget(const well_conn_collection_type * wellcc, - int index); -void well_conn_collection_add(well_conn_collection_type * wellcc, - well_conn_type * conn); -void well_conn_collection_add_ref(well_conn_collection_type * wellcc, - well_conn_type * conn); -int well_conn_collection_load_from_kw(well_conn_collection_type * wellcc, - const ecl_kw_type * iwel_kw, - const ecl_kw_type * icon_kw, - const ecl_kw_type * scon_kw, - const ecl_kw_type * xcon_kw, - int iwell, - const ecl_rsthead_type * rst_head); - -UTIL_IS_INSTANCE_HEADER(well_conn_collection); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.hpp index bbbecd3e6e..3cc9a178c8 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_conn_collection.hpp @@ -1,20 +1,61 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_conn_collection.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_WELL_CONN_COLLECTION_H +#define ERT_WELL_CONN_COLLECTION_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +#include + +typedef struct well_conn_collection_struct well_conn_collection_type; + +well_conn_collection_type * well_conn_collection_alloc(void); +void well_conn_collection_free(well_conn_collection_type * wellcc); +void well_conn_collection_free__(void * arg); +int well_conn_collection_get_size(const well_conn_collection_type * wellcc); +const well_conn_type * well_conn_collection_iget_const(const well_conn_collection_type * wellcc, + int index); +well_conn_type * well_conn_collection_iget(const well_conn_collection_type * wellcc, + int index); +void well_conn_collection_add(well_conn_collection_type * wellcc, + well_conn_type * conn); +void well_conn_collection_add_ref(well_conn_collection_type * wellcc, + well_conn_type * conn); +int well_conn_collection_load_from_kw(well_conn_collection_type * wellcc, + const ecl_kw_type * iwel_kw, + const ecl_kw_type * icon_kw, + const ecl_kw_type * scon_kw, + const ecl_kw_type * xcon_kw, + int iwell, + const ecl_rsthead_type * rst_head); + +UTIL_IS_INSTANCE_HEADER(well_conn_collection); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.h b/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.h index 41a2ade9f2..8998130c3f 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.h +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.h @@ -1,154 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'well_const.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - - -#ifndef ERT_WELL_CONST_H -#define ERT_WELL_CONST_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define WELL_SEGMENT_OFFSET 1 -#define WELL_BRANCH_OFFSET 1 - -#define ECLIPSE_WELL_SEGMENT_OFFSET 1 -#define ECLIPSE_WELL_BRANCH_OFFSET 1 - -/* These values are taken from the ISEG description in table 6.1 in ECLIPSE file formats reference. */ -#define ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE 0 -#define ECLIPSE_WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE 1 -#define ECLIPSE_WELL_SEGMENT_INACTIVE_VALUE 0 -#define ECLIPSE_CONN_NORMAL_WELL_SEGMENT_VALUE 0 - -#define WELL_SEGMENT_OUTLET_END_VALUE (WELL_SEGMENT_OFFSET + ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE - ECLIPSE_WELL_SEGMENT_OFFSET) // -1 -#define WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE (WELL_BRANCH_OFFSET + ECLIPSE_WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE - ECLIPSE_WELL_BRANCH_OFFSET) // 0 -#define WELL_SEGMENT_BRANCH_INACTIVE_VALUE (WELL_BRANCH_OFFSET + ECLIPSE_WELL_SEGMENT_INACTIVE_VALUE - ECLIPSE_WELL_BRANCH_OFFSET) // -1 -#define CONN_NORMAL_WELL_SEGMENT_VALUE (WELL_SEGMENT_OFFSET + ECLIPSE_CONN_NORMAL_WELL_SEGMENT_VALUE - ECLIPSE_WELL_SEGMENT_OFFSET) - - - -/* - Observe that the values given as _ITEM are not indices which can - be directly used in the IWEL or ICON keywords; an offset must be - added. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#define IWEL_HEADI_INDEX 0 -#define IWEL_HEADJ_INDEX 1 -#define IWEL_HEADK_INDEX 2 -#define IWEL_CONNECTIONS_INDEX 4 -#define IWEL_GROUP_INDEX 5 -#define IWEL_TYPE_INDEX 6 -#define IWEL_STATUS_INDEX 10 -#define IWEL_LGR_INDEX 42 -#define IWEL_SEGMENTED_WELL_NR_INDEX 70 - -#define IWEL_HEADI_ITEM 0 -#define IWEL_HEADJ_ITEM 1 -#define IWEL_HEADK_ITEM 2 -#define IWEL_CONNECTIONS_ITEM 4 -#define IWEL_GROUP_ITEM 5 -#define IWEL_TYPE_ITEM 6 -#define IWEL_STATUS_ITEM 10 -#define IWEL_LGR_ITEM 42 -#define IWEL_SEGMENTED_WELL_NR_ITEM 70 - -#define IWEL_SEGMENTED_WELL_NR_NORMAL_VALUE -1 -#define ISEG_OUTLET_INDEX 1 -#define ISEG_BRANCH_INDEX 3 - -#define XWEL_RES_WRAT_ITEM 1 -#define XWEL_RES_GRAT_ITEM 2 -#define XWEL_RES_ORAT_ITEM 3 -#define XWEL_RESV_ITEM 4 - - -#define ICON_IC_INDEX 0 -#define ICON_I_INDEX 1 -#define ICON_J_INDEX 2 -#define ICON_K_INDEX 3 -#define ICON_STATUS_INDEX 5 -#define ICON_DIRECTION_INDEX 13 -#define ICON_SEGMENT_INDEX 14 - -#define ICON_IC_ITEM 0 -#define ICON_I_ITEM 1 -#define ICON_J_ITEM 2 -#define ICON_K_ITEM 3 -#define ICON_STATUS_ITEM 5 -#define ICON_DIRECTION_ITEM 13 -#define ICON_SEGMENT_ITEM 14 - -#define ICON_DIRX 1 -#define ICON_DIRY 2 -#define ICON_DIRZ 3 -#define ICON_FRACX 4 -#define ICON_FRACY 5 -#define ICON_DEFAULT_DIR_VALUE 0 -#define ICON_DEFAULT_DIR_TARGET ICON_DIRZ - -#define SCON_CF_INDEX 0 - -#define XCON_ORAT_INDEX 0 -#define XCON_WRAT_INDEX 1 -#define XCON_GRAT_INDEX 2 -#define XCON_QR_INDEX 49 - -#define RSEG_LENGTH_INDEX 0 -#define RSEG_DIAMETER_INDEX 2 -#define RSEG_TOTAL_LENGTH_INDEX 6 -#define RSEG_DEPTH_INDEX 7 - -/* - The ECLIPSE documentation says that a certain item in the IWEL array - should indicate the type of the well, the available types are the - ones given in the enum below. Unfortunately it turns out that when - the well is closed the integer value in the IWEL array can be 0, if - the well is indeed closed we accept this zero - otherwise we fail - hard. Theese hoops are in the well_state_alloc() routine. -*/ - -#define IWEL_UNDOCUMENTED_ZERO 0 -#define IWEL_PRODUCER 1 -#define IWEL_OIL_INJECTOR 2 -#define IWEL_WATER_INJECTOR 3 -#define IWEL_GAS_INJECTOR 4 - - typedef enum { - ERT_UNDOCUMENTED_ZERO = 0, // Deprecated - retained for Resinsight compatibility - ECL_WELL_ZERO = 0, - - ERT_PRODUCER = 1, // Deprecated - ECL_WELL_PRODUCER = 1, - - ERT_OIL_INJECTOR = 2, // Deprecated - ECL_WELL_OIL_INJECTOR = 2, - - ERT_WATER_INJECTOR = 3, // Deprecated - ECL_WELL_WATER_INJECTOR = 3, - - ERT_GAS_INJECTOR = 4, // Deprecated - ECL_WELL_GAS_INJECTOR = 4, - } well_type_enum; +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.hpp index 9daefcf46f..41a2ade9f2 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_const.hpp @@ -1,20 +1,154 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'well_const.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ + + +#ifndef ERT_WELL_CONST_H +#define ERT_WELL_CONST_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define WELL_SEGMENT_OFFSET 1 +#define WELL_BRANCH_OFFSET 1 + +#define ECLIPSE_WELL_SEGMENT_OFFSET 1 +#define ECLIPSE_WELL_BRANCH_OFFSET 1 + +/* These values are taken from the ISEG description in table 6.1 in ECLIPSE file formats reference. */ +#define ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE 0 +#define ECLIPSE_WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE 1 +#define ECLIPSE_WELL_SEGMENT_INACTIVE_VALUE 0 +#define ECLIPSE_CONN_NORMAL_WELL_SEGMENT_VALUE 0 + +#define WELL_SEGMENT_OUTLET_END_VALUE (WELL_SEGMENT_OFFSET + ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE - ECLIPSE_WELL_SEGMENT_OFFSET) // -1 +#define WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE (WELL_BRANCH_OFFSET + ECLIPSE_WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE - ECLIPSE_WELL_BRANCH_OFFSET) // 0 +#define WELL_SEGMENT_BRANCH_INACTIVE_VALUE (WELL_BRANCH_OFFSET + ECLIPSE_WELL_SEGMENT_INACTIVE_VALUE - ECLIPSE_WELL_BRANCH_OFFSET) // -1 +#define CONN_NORMAL_WELL_SEGMENT_VALUE (WELL_SEGMENT_OFFSET + ECLIPSE_CONN_NORMAL_WELL_SEGMENT_VALUE - ECLIPSE_WELL_SEGMENT_OFFSET) + + + +/* + Observe that the values given as _ITEM are not indices which can + be directly used in the IWEL or ICON keywords; an offset must be + added. +*/ + +#define IWEL_HEADI_INDEX 0 +#define IWEL_HEADJ_INDEX 1 +#define IWEL_HEADK_INDEX 2 +#define IWEL_CONNECTIONS_INDEX 4 +#define IWEL_GROUP_INDEX 5 +#define IWEL_TYPE_INDEX 6 +#define IWEL_STATUS_INDEX 10 +#define IWEL_LGR_INDEX 42 +#define IWEL_SEGMENTED_WELL_NR_INDEX 70 + +#define IWEL_HEADI_ITEM 0 +#define IWEL_HEADJ_ITEM 1 +#define IWEL_HEADK_ITEM 2 +#define IWEL_CONNECTIONS_ITEM 4 +#define IWEL_GROUP_ITEM 5 +#define IWEL_TYPE_ITEM 6 +#define IWEL_STATUS_ITEM 10 +#define IWEL_LGR_ITEM 42 +#define IWEL_SEGMENTED_WELL_NR_ITEM 70 + +#define IWEL_SEGMENTED_WELL_NR_NORMAL_VALUE -1 +#define ISEG_OUTLET_INDEX 1 +#define ISEG_BRANCH_INDEX 3 + +#define XWEL_RES_WRAT_ITEM 1 +#define XWEL_RES_GRAT_ITEM 2 +#define XWEL_RES_ORAT_ITEM 3 +#define XWEL_RESV_ITEM 4 + + +#define ICON_IC_INDEX 0 +#define ICON_I_INDEX 1 +#define ICON_J_INDEX 2 +#define ICON_K_INDEX 3 +#define ICON_STATUS_INDEX 5 +#define ICON_DIRECTION_INDEX 13 +#define ICON_SEGMENT_INDEX 14 + +#define ICON_IC_ITEM 0 +#define ICON_I_ITEM 1 +#define ICON_J_ITEM 2 +#define ICON_K_ITEM 3 +#define ICON_STATUS_ITEM 5 +#define ICON_DIRECTION_ITEM 13 +#define ICON_SEGMENT_ITEM 14 + +#define ICON_DIRX 1 +#define ICON_DIRY 2 +#define ICON_DIRZ 3 +#define ICON_FRACX 4 +#define ICON_FRACY 5 +#define ICON_DEFAULT_DIR_VALUE 0 +#define ICON_DEFAULT_DIR_TARGET ICON_DIRZ + +#define SCON_CF_INDEX 0 + +#define XCON_ORAT_INDEX 0 +#define XCON_WRAT_INDEX 1 +#define XCON_GRAT_INDEX 2 +#define XCON_QR_INDEX 49 + +#define RSEG_LENGTH_INDEX 0 +#define RSEG_DIAMETER_INDEX 2 +#define RSEG_TOTAL_LENGTH_INDEX 6 +#define RSEG_DEPTH_INDEX 7 + +/* + The ECLIPSE documentation says that a certain item in the IWEL array + should indicate the type of the well, the available types are the + ones given in the enum below. Unfortunately it turns out that when + the well is closed the integer value in the IWEL array can be 0, if + the well is indeed closed we accept this zero - otherwise we fail + hard. Theese hoops are in the well_state_alloc() routine. */ +#define IWEL_UNDOCUMENTED_ZERO 0 +#define IWEL_PRODUCER 1 +#define IWEL_OIL_INJECTOR 2 +#define IWEL_WATER_INJECTOR 3 +#define IWEL_GAS_INJECTOR 4 + + typedef enum { + ERT_UNDOCUMENTED_ZERO = 0, // Deprecated - retained for Resinsight compatibility + ECL_WELL_ZERO = 0, + + ERT_PRODUCER = 1, // Deprecated + ECL_WELL_PRODUCER = 1, + + ERT_OIL_INJECTOR = 2, // Deprecated + ECL_WELL_OIL_INJECTOR = 2, + + ERT_WATER_INJECTOR = 3, // Deprecated + ECL_WELL_WATER_INJECTOR = 3, + + ERT_GAS_INJECTOR = 4, // Deprecated + ECL_WELL_GAS_INJECTOR = 4, + } well_type_enum; + +#ifdef __cplusplus +} +#endif -#include +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.h b/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.h index 36b332b856..48fcb82ca9 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.h +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.h @@ -1,57 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'well_info.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_WELL_INFO_H -#define ERT_WELL_INFO_H +#include -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -#include - - typedef struct well_info_struct well_info_type; - - well_info_type * well_info_alloc(const ecl_grid_type * grid); - void well_info_add_UNRST_wells2( well_info_type * well_info , ecl_file_view_type * rst_view, bool load_segment_information); - void well_info_add_UNRST_wells( well_info_type * well_info , ecl_file_type * rst_file, bool load_segment_information); - void well_info_add_wells( well_info_type * well_info , ecl_file_type * rst_file , int report_nr , bool load_segment_information); - void well_info_add_wells2( well_info_type * well_info , ecl_file_view_type * rst_view , int report_nr, bool load_segment_information); - void well_info_load_rstfile( well_info_type * well_info , const char * filename, bool load_segment_information); - void well_info_load_rst_eclfile( well_info_type * well_info , ecl_file_type * rst_file , bool load_segment_information); - void well_info_free( well_info_type * well_info ); - - well_ts_type * well_info_get_ts( const well_info_type * well_info , const char *well_name); - int well_info_get_num_wells( const well_info_type * well_info ); - const char * well_info_iget_well_name( const well_info_type * well_info, int well_index); - bool well_info_has_well( well_info_type * well_info , const char * well_name ); - - well_state_type * well_info_get_state_from_time( const well_info_type * well_info , const char * well_name , time_t sim_time); - well_state_type * well_info_get_state_from_report( const well_info_type * well_info , const char * well_name , int report_step ); - well_state_type * well_info_iget_state( const well_info_type * well_info , const char * well_name , int time_index); - well_state_type * well_info_iiget_state( const well_info_type * well_info , int well_index , int time_index); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.hpp index df5625079d..b7bad41564 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_info.hpp @@ -1,20 +1,58 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'well_info.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ +#ifndef ERT_WELL_INFO_H +#define ERT_WELL_INFO_H + + + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct well_info_struct well_info_type; + + well_info_type * well_info_alloc(const ecl_grid_type * grid); + void well_info_add_UNRST_wells2( well_info_type * well_info , ecl_file_view_type * rst_view, bool load_segment_information); + void well_info_add_UNRST_wells( well_info_type * well_info , ecl_file_type * rst_file, bool load_segment_information); + void well_info_add_wells( well_info_type * well_info , ecl_file_type * rst_file , int report_nr , bool load_segment_information); + void well_info_add_wells2( well_info_type * well_info , ecl_file_view_type * rst_view , int report_nr, bool load_segment_information); + void well_info_load_rstfile( well_info_type * well_info , const char * filename, bool load_segment_information); + void well_info_load_rst_eclfile( well_info_type * well_info , ecl_file_type * rst_file , bool load_segment_information); + void well_info_free( well_info_type * well_info ); + + well_ts_type * well_info_get_ts( const well_info_type * well_info , const char *well_name); + int well_info_get_num_wells( const well_info_type * well_info ); + const char * well_info_iget_well_name( const well_info_type * well_info, int well_index); + bool well_info_has_well( well_info_type * well_info , const char * well_name ); + + well_state_type * well_info_get_state_from_time( const well_info_type * well_info , const char * well_name , time_t sim_time); + well_state_type * well_info_get_state_from_report( const well_info_type * well_info , const char * well_name , int report_step ); + well_state_type * well_info_iget_state( const well_info_type * well_info , const char * well_name , int time_index); + well_state_type * well_info_iiget_state( const well_info_type * well_info , int well_index , int time_index); + +#ifdef __cplusplus +} +#endif -#include +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.h b/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.h index 9886907582..d78184f5de 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.h +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.h @@ -1,42 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'well_info.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_WELL_RSEG_LOADER_H -#define ERT_WELL_RSEG_LOADER_H - - -#ifdef __cplusplus -extern "C" { -#endif - -#include - - - typedef struct well_rseg_loader_struct well_rseg_loader_type; - - well_rseg_loader_type * well_rseg_loader_alloc(ecl_file_view_type * rst_view); - void well_rseg_loader_free(well_rseg_loader_type * well_rseg_loader); - - int well_rseg_loader_element_count(const well_rseg_loader_type * well_rseg_loader); - double * well_rseg_loader_load_values(const well_rseg_loader_type * well_rseg_loader, int rseg_offset); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.hpp index 3fbdb9a8e3..1270fba0d8 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_rseg_loader.hpp @@ -1,20 +1,42 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'well_info.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ +#ifndef ERT_WELL_RSEG_LOADER_H +#define ERT_WELL_RSEG_LOADER_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + + typedef struct well_rseg_loader_struct well_rseg_loader_type; + + well_rseg_loader_type * well_rseg_loader_alloc(ecl_file_view_type * rst_view); + void well_rseg_loader_free(well_rseg_loader_type * well_rseg_loader); + + int well_rseg_loader_element_count(const well_rseg_loader_type * well_rseg_loader); + double * well_rseg_loader_load_values(const well_rseg_loader_type * well_rseg_loader, int rseg_offset); + +#ifdef __cplusplus +} +#endif -#include +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.h b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.h index c566de27f0..d5a0c34924 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.h +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.h @@ -1,75 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_segment.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_WELL_SEGMENT_H -#define ERT_WELL_SEGMENT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include - -#include -#include -#include - - - - - typedef struct well_segment_struct well_segment_type; - - well_segment_type * well_segment_alloc_from_kw( const ecl_kw_type * iseg_kw , const well_rseg_loader_type * rseg_loader , const ecl_rsthead_type * header , int well_nr, int segment_index , int segment_id); - well_segment_type * well_segment_alloc(int segment_id , int outlet_segment_id , int branch_id , const double * rseg_data); - void well_segment_free(well_segment_type * segment ); - void well_segment_free__(void * arg); - - bool well_segment_active( const well_segment_type * segment ); - bool well_segment_main_stem( const well_segment_type * segment ); - bool well_segment_nearest_wellhead( const well_segment_type * segment ); - - int well_segment_get_link_count( const well_segment_type * segment ); - int well_segment_get_branch_id( const well_segment_type * segment ); - int well_segment_get_outlet_id( const well_segment_type * segment ); - int well_segment_get_id( const well_segment_type * segment ); - well_segment_type * well_segment_get_outlet( const well_segment_type * segment ); - bool well_segment_link( well_segment_type * segment , well_segment_type * outlet_segment ); - void well_segment_link_strict( well_segment_type * segment , well_segment_type * outlet_segment ); - bool well_segment_has_grid_connections( const well_segment_type * segment , const char * grid_name); - bool well_segment_has_global_grid_connections( const well_segment_type * segment); - bool well_segment_add_connection( well_segment_type * segment , const char * grid_name , well_conn_type * conn); - const well_conn_collection_type * well_segment_get_connections(const well_segment_type * segment , const char * grid_name ); - const well_conn_collection_type * well_segment_get_global_connections(const well_segment_type * segment ); - bool well_segment_well_is_MSW(int well_nr , const ecl_kw_type * iwel_kw , const ecl_rsthead_type * rst_head); - - double well_segment_get_depth( const well_segment_type * segment ); - double well_segment_get_length( const well_segment_type * segment ); - double well_segment_get_total_length( const well_segment_type * segment ); - double well_segment_get_diameter( const well_segment_type * segment ); - - UTIL_IS_INSTANCE_HEADER( well_segment ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.hpp index 1a423cf493..084cfea8da 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment.hpp @@ -1,20 +1,75 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_segment.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_WELL_SEGMENT_H +#define ERT_WELL_SEGMENT_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include + +#include +#include +#include + + + + + typedef struct well_segment_struct well_segment_type; + + well_segment_type * well_segment_alloc_from_kw( const ecl_kw_type * iseg_kw , const well_rseg_loader_type * rseg_loader , const ecl_rsthead_type * header , int well_nr, int segment_index , int segment_id); + well_segment_type * well_segment_alloc(int segment_id , int outlet_segment_id , int branch_id , const double * rseg_data); + void well_segment_free(well_segment_type * segment ); + void well_segment_free__(void * arg); + + bool well_segment_active( const well_segment_type * segment ); + bool well_segment_main_stem( const well_segment_type * segment ); + bool well_segment_nearest_wellhead( const well_segment_type * segment ); + + int well_segment_get_link_count( const well_segment_type * segment ); + int well_segment_get_branch_id( const well_segment_type * segment ); + int well_segment_get_outlet_id( const well_segment_type * segment ); + int well_segment_get_id( const well_segment_type * segment ); + well_segment_type * well_segment_get_outlet( const well_segment_type * segment ); + bool well_segment_link( well_segment_type * segment , well_segment_type * outlet_segment ); + void well_segment_link_strict( well_segment_type * segment , well_segment_type * outlet_segment ); + bool well_segment_has_grid_connections( const well_segment_type * segment , const char * grid_name); + bool well_segment_has_global_grid_connections( const well_segment_type * segment); + bool well_segment_add_connection( well_segment_type * segment , const char * grid_name , well_conn_type * conn); + const well_conn_collection_type * well_segment_get_connections(const well_segment_type * segment , const char * grid_name ); + const well_conn_collection_type * well_segment_get_global_connections(const well_segment_type * segment ); + bool well_segment_well_is_MSW(int well_nr , const ecl_kw_type * iwel_kw , const ecl_rsthead_type * rst_head); + + double well_segment_get_depth( const well_segment_type * segment ); + double well_segment_get_length( const well_segment_type * segment ); + double well_segment_get_total_length( const well_segment_type * segment ); + double well_segment_get_diameter( const well_segment_type * segment ); + + UTIL_IS_INSTANCE_HEADER( well_segment ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.h b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.h index fd5dafceb7..301ad31bc2 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.h +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.h @@ -1,63 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'well_segment_collection.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_WELL_SEGMENT_COLLECTION_H -#define ERT_WELL_SEGMENT_COLLECTION_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - -#include -#include -#include -#include - - typedef struct well_segment_collection_struct well_segment_collection_type; - - well_segment_collection_type * well_segment_collection_alloc(void); - void well_segment_collection_free(well_segment_collection_type * segment_collection ); - int well_segment_collection_get_size( const well_segment_collection_type * segment_collection ); - void well_segment_collection_add( well_segment_collection_type * segment_collection , well_segment_type * segment); - bool well_segment_collection_has_segment( const well_segment_collection_type * segment_collection , int segment_id); - well_segment_type * well_segment_collection_get( const well_segment_collection_type * segment_collection , int segment_id); - well_segment_type * well_segment_collection_iget( const well_segment_collection_type * segment_collection , int index); - int well_segment_collection_load_from_kw( well_segment_collection_type * segment_collection , int well_nr , - const ecl_kw_type * iwel_kw , - const ecl_kw_type * iseg_kw , - const well_rseg_loader_type * rseg_loader , - const ecl_rsthead_type * rst_head, - bool load_segment_information , bool * is_MSW_well); - - void well_segment_collection_link(const well_segment_collection_type * segment_collection); - void well_segment_collection_add_connections(well_segment_collection_type * segment_collection , - const char * grid_name , - const well_conn_collection_type * connections); - void well_segment_collection_add_branches( const well_segment_collection_type * segment_collection , - well_branch_collection_type * branches ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.hpp index f15cf65a7e..fc4dd95d45 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_segment_collection.hpp @@ -1,20 +1,63 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'well_segment_collection.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_WELL_SEGMENT_COLLECTION_H +#define ERT_WELL_SEGMENT_COLLECTION_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +#include +#include +#include +#include + + typedef struct well_segment_collection_struct well_segment_collection_type; + + well_segment_collection_type * well_segment_collection_alloc(void); + void well_segment_collection_free(well_segment_collection_type * segment_collection ); + int well_segment_collection_get_size( const well_segment_collection_type * segment_collection ); + void well_segment_collection_add( well_segment_collection_type * segment_collection , well_segment_type * segment); + bool well_segment_collection_has_segment( const well_segment_collection_type * segment_collection , int segment_id); + well_segment_type * well_segment_collection_get( const well_segment_collection_type * segment_collection , int segment_id); + well_segment_type * well_segment_collection_iget( const well_segment_collection_type * segment_collection , int index); + int well_segment_collection_load_from_kw( well_segment_collection_type * segment_collection , int well_nr , + const ecl_kw_type * iwel_kw , + const ecl_kw_type * iseg_kw , + const well_rseg_loader_type * rseg_loader , + const ecl_rsthead_type * rst_head, + bool load_segment_information , bool * is_MSW_well); + + void well_segment_collection_link(const well_segment_collection_type * segment_collection); + void well_segment_collection_add_connections(well_segment_collection_type * segment_collection , + const char * grid_name , + const well_conn_collection_type * connections); + void well_segment_collection_add_branches( const well_segment_collection_type * segment_collection , + well_branch_collection_type * branches ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.h b/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.h index aa9427c858..9223bb9498 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.h +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.h @@ -1,112 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'well_state.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_WELL_STATE_H -#define ERT_WELL_STATE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include -#include - -#include -#include -#include -#include -#include - - -#define GLOBAL_GRID_NAME "GLOBAL" // The name assigned to the global grid for name based lookup. - - typedef struct well_state_struct well_state_type; - - well_state_type * well_state_alloc(const char * well_name , int global_well_nr , bool open, well_type_enum type , int report_nr, time_t valid_from); - well_state_type * well_state_alloc_from_file( ecl_file_type * ecl_file , const ecl_grid_type * grid , int report_step , int well_nr , bool load_segment_information); - well_state_type * well_state_alloc_from_file2( ecl_file_view_type * file_view , const ecl_grid_type * grid , int report_nr , int global_well_nr ,bool load_segment_information); - - void well_state_add_connections2( well_state_type * well_state , - const ecl_grid_type * grid , - ecl_file_view_type * rst_view , - int well_nr); - - void well_state_add_connections( well_state_type * well_state , - const ecl_grid_type * grid , - ecl_file_type * rst_file , - int well_nr); - - bool well_state_add_MSW( well_state_type * well_state , - ecl_file_type * rst_file , - int well_nr, - bool load_segment_information); - - - bool well_state_add_MSW2( well_state_type * well_state , - ecl_file_view_type * rst_view, - int well_nr, - bool load_segment_information); - - - bool well_state_is_MSW( const well_state_type * well_state); - - bool well_state_has_segment_data(const well_state_type * well_state); - - well_segment_collection_type * well_state_get_segments( const well_state_type * well_state ); - well_branch_collection_type * well_state_get_branches( const well_state_type * well_state ); - - - void well_state_free( well_state_type * well ); - const char * well_state_get_name( const well_state_type * well ); - int well_state_get_report_nr( const well_state_type * well_state ); - time_t well_state_get_sim_time( const well_state_type * well_state ); - well_type_enum well_state_get_type( const well_state_type * well_state); - bool well_state_is_open( const well_state_type * well_state ); - int well_state_get_well_nr( const well_state_type * well_state ); - - const well_conn_type * well_state_get_global_wellhead( const well_state_type * well_state ); - const well_conn_type * well_state_iget_wellhead( const well_state_type * well_state , int grid_nr); - const well_conn_type * well_state_get_wellhead( const well_state_type * well_state , const char * grid_name); - - well_type_enum well_state_translate_ecl_type_int(int int_type); - - const well_conn_collection_type * well_state_get_grid_connections( const well_state_type * well_state , const char * grid_name); - const well_conn_collection_type * well_state_get_global_connections( const well_state_type * well_state ); - bool well_state_has_grid_connections( const well_state_type * well_state , const char * grid_name); - bool well_state_has_global_connections( const well_state_type * well_state ); - - double well_state_get_oil_rate( const well_state_type * well_state ); - double well_state_get_gas_rate( const well_state_type * well_state ); - double well_state_get_water_rate( const well_state_type * well_state); - double well_state_get_volume_rate( const well_state_type * well_state); - double well_state_get_water_rate_si( const well_state_type * well_state); - double well_state_get_oil_rate_si( const well_state_type * well_state ); - double well_state_get_volume_rate_si( const well_state_type * well_state); - double well_state_get_gas_rate_si( const well_state_type * well_state ); - - - UTIL_IS_INSTANCE_HEADER( well_state ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.hpp index 4166742c82..c41e215685 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_state.hpp @@ -1,20 +1,112 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'well_state.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_WELL_STATE_H +#define ERT_WELL_STATE_H + + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GLOBAL_GRID_NAME "GLOBAL" // The name assigned to the global grid for name based lookup. + + typedef struct well_state_struct well_state_type; + + well_state_type * well_state_alloc(const char * well_name , int global_well_nr , bool open, well_type_enum type , int report_nr, time_t valid_from); + well_state_type * well_state_alloc_from_file( ecl_file_type * ecl_file , const ecl_grid_type * grid , int report_step , int well_nr , bool load_segment_information); + well_state_type * well_state_alloc_from_file2( ecl_file_view_type * file_view , const ecl_grid_type * grid , int report_nr , int global_well_nr ,bool load_segment_information); + + void well_state_add_connections2( well_state_type * well_state , + const ecl_grid_type * grid , + ecl_file_view_type * rst_view , + int well_nr); + + void well_state_add_connections( well_state_type * well_state , + const ecl_grid_type * grid , + ecl_file_type * rst_file , + int well_nr); + + bool well_state_add_MSW( well_state_type * well_state , + ecl_file_type * rst_file , + int well_nr, + bool load_segment_information); + + + bool well_state_add_MSW2( well_state_type * well_state , + ecl_file_view_type * rst_view, + int well_nr, + bool load_segment_information); + + + bool well_state_is_MSW( const well_state_type * well_state); + + bool well_state_has_segment_data(const well_state_type * well_state); + + well_segment_collection_type * well_state_get_segments( const well_state_type * well_state ); + well_branch_collection_type * well_state_get_branches( const well_state_type * well_state ); + + + void well_state_free( well_state_type * well ); + const char * well_state_get_name( const well_state_type * well ); + int well_state_get_report_nr( const well_state_type * well_state ); + time_t well_state_get_sim_time( const well_state_type * well_state ); + well_type_enum well_state_get_type( const well_state_type * well_state); + bool well_state_is_open( const well_state_type * well_state ); + int well_state_get_well_nr( const well_state_type * well_state ); + + const well_conn_type * well_state_get_global_wellhead( const well_state_type * well_state ); + const well_conn_type * well_state_iget_wellhead( const well_state_type * well_state , int grid_nr); + const well_conn_type * well_state_get_wellhead( const well_state_type * well_state , const char * grid_name); + + well_type_enum well_state_translate_ecl_type_int(int int_type); + + const well_conn_collection_type * well_state_get_grid_connections( const well_state_type * well_state , const char * grid_name); + const well_conn_collection_type * well_state_get_global_connections( const well_state_type * well_state ); + bool well_state_has_grid_connections( const well_state_type * well_state , const char * grid_name); + bool well_state_has_global_connections( const well_state_type * well_state ); + + double well_state_get_oil_rate( const well_state_type * well_state ); + double well_state_get_gas_rate( const well_state_type * well_state ); + double well_state_get_water_rate( const well_state_type * well_state); + double well_state_get_volume_rate( const well_state_type * well_state); + double well_state_get_water_rate_si( const well_state_type * well_state); + double well_state_get_oil_rate_si( const well_state_type * well_state ); + double well_state_get_volume_rate_si( const well_state_type * well_state); + double well_state_get_gas_rate_si( const well_state_type * well_state ); + + + UTIL_IS_INSTANCE_HEADER( well_state ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.h b/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.h index 4b4f0473b7..6e6ca84e6f 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.h +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.h @@ -1,48 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'well_ts.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_WELL_TS_H -#define ERT_WELL_TS_H -#ifdef __cplusplus -extern "C" { -#endif - -#include - - - typedef struct well_ts_struct well_ts_type; - - void well_ts_free( well_ts_type * well_ts ); - void well_ts_add_well( well_ts_type * well_ts , well_state_type * well_state ); - well_ts_type * well_ts_alloc( const char * well_name ); - void well_ts_free__( void * arg ); - well_state_type * well_ts_get_state_from_sim_time( const well_ts_type * well_ts , time_t sim_time); - well_state_type * well_ts_get_state_from_report( const well_ts_type * well_ts , int report_nr); - well_state_type * well_ts_iget_state( const well_ts_type * well_ts , int index); - int well_ts_get_size( const well_ts_type * well_ts); - char * well_ts_get_name( const well_ts_type * well_ts); - well_state_type * well_ts_get_first_state( const well_ts_type * well_ts); - well_state_type * well_ts_get_last_state( const well_ts_type * well_ts); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.hpp b/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.hpp index 9f4463d1c7..5044b685b0 100644 --- a/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.hpp +++ b/ThirdParty/Ert/lib/include/ert/ecl_well/well_ts.hpp @@ -1,20 +1,48 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'well_ts.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_WELL_TS_H +#define ERT_WELL_TS_H + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct well_ts_struct well_ts_type; + + void well_ts_free( well_ts_type * well_ts ); + void well_ts_add_well( well_ts_type * well_ts , well_state_type * well_state ); + well_ts_type * well_ts_alloc( const char * well_name ); + void well_ts_free__( void * arg ); + well_state_type * well_ts_get_state_from_sim_time( const well_ts_type * well_ts , time_t sim_time); + well_state_type * well_ts_get_state_from_report( const well_ts_type * well_ts , int report_nr); + well_state_type * well_ts_iget_state( const well_ts_type * well_ts , int index); + int well_ts_get_size( const well_ts_type * well_ts); + char * well_ts_get_name( const well_ts_type * well_ts); + well_state_type * well_ts_get_first_state( const well_ts_type * well_ts); + well_state_type * well_ts_get_last_state( const well_ts_type * well_ts); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.h b/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.h index 7e549e6852..eac74fb762 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.h +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.h @@ -1,52 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'geo_pointset.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_GEO_POINTSET_H -#define ERT_GEO_POINTSET_H - - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct geo_pointset_struct geo_pointset_type; - +#include - geo_pointset_type * geo_pointset_alloc( bool external_z ); - void geo_pointset_free( geo_pointset_type * pointset ); - void geo_pointset_add_xyz( geo_pointset_type * pointset , double x , double y, double z); - int geo_pointset_get_size( const geo_pointset_type * pointset ); - void geo_pointset_iget_xy( const geo_pointset_type * pointset , int index , double * x , double * y); - const double * geo_pointset_get_zcoord( const geo_pointset_type * pointset ); - bool geo_pointset_equal( const geo_pointset_type * pointset1 , const geo_pointset_type * pointset2); - double geo_pointset_iget_z( const geo_pointset_type * pointset , int index ); - void geo_pointset_iset_z( geo_pointset_type * pointset , int index , double value); - void geo_pointset_memcpy( const geo_pointset_type * src, geo_pointset_type * target , bool copy_zdata); - void geo_pointset_shift_z( geo_pointset_type * pointset , double value ); - void geo_pointset_assign_z( geo_pointset_type * pointset , double value ); - void geo_pointset_scale_z( geo_pointset_type * pointset , double value ); - void geo_pointset_imul( geo_pointset_type * pointset , const geo_pointset_type * other ); - void geo_pointset_iadd( geo_pointset_type * pointset , const geo_pointset_type * other ); - void geo_pointset_isub( geo_pointset_type * self , const geo_pointset_type * other ); - void geo_pointset_isqrt( geo_pointset_type * pointset ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.hpp index a1f54f309d..7e549e6852 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_pointset.hpp @@ -1,19 +1,52 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'geo_pointset.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_GEO_POINTSET_H +#define ERT_GEO_POINTSET_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct geo_pointset_struct geo_pointset_type; + + + geo_pointset_type * geo_pointset_alloc( bool external_z ); + void geo_pointset_free( geo_pointset_type * pointset ); + void geo_pointset_add_xyz( geo_pointset_type * pointset , double x , double y, double z); + int geo_pointset_get_size( const geo_pointset_type * pointset ); + void geo_pointset_iget_xy( const geo_pointset_type * pointset , int index , double * x , double * y); + const double * geo_pointset_get_zcoord( const geo_pointset_type * pointset ); + bool geo_pointset_equal( const geo_pointset_type * pointset1 , const geo_pointset_type * pointset2); + double geo_pointset_iget_z( const geo_pointset_type * pointset , int index ); + void geo_pointset_iset_z( geo_pointset_type * pointset , int index , double value); + void geo_pointset_memcpy( const geo_pointset_type * src, geo_pointset_type * target , bool copy_zdata); + void geo_pointset_shift_z( geo_pointset_type * pointset , double value ); + void geo_pointset_assign_z( geo_pointset_type * pointset , double value ); + void geo_pointset_scale_z( geo_pointset_type * pointset , double value ); + void geo_pointset_imul( geo_pointset_type * pointset , const geo_pointset_type * other ); + void geo_pointset_iadd( geo_pointset_type * pointset , const geo_pointset_type * other ); + void geo_pointset_isub( geo_pointset_type * self , const geo_pointset_type * other ); + void geo_pointset_isqrt( geo_pointset_type * pointset ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.h b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.h index 7964f870fe..ccc7ea2d32 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.h +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.h @@ -1,57 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'geo_polygon.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_GEO_POLYGON_H -#define ERT_GEO_POLYGON_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - - typedef struct geo_polygon_struct geo_polygon_type; - - geo_polygon_type * geo_polygon_alloc( const char * name ); - void geo_polygon_free( geo_polygon_type * polygon ); - void geo_polygon_free__( void * arg ); - void geo_polygon_add_point( geo_polygon_type * polygon , double x , double y ); - void geo_polygon_add_point_front( geo_polygon_type * polygon , double x , double y); - geo_polygon_type * geo_polygon_fload_alloc_irap( const char * filename ); - bool geo_polygon_contains_point( const geo_polygon_type * polygon , double x , double y); - bool geo_polygon_contains_point__( const geo_polygon_type * polygon , double x , double y, bool force_edge_inside); - void geo_polygon_reset(geo_polygon_type * polygon ); - void geo_polygon_fprintf(const geo_polygon_type * polygon , FILE * stream); - void geo_polygon_shift(geo_polygon_type * polygon , double x0 , double y0); - void geo_polygon_close( geo_polygon_type * polygoon); - int geo_polygon_get_size(const geo_polygon_type * polygon ); - void geo_polygon_iget_xy(const geo_polygon_type * polygon , int index , double *x , double *y); - bool geo_polygon_segment_intersects(const geo_polygon_type * polygon , double x1 , double y1 , double x2 , double y2); - const char * geo_polygon_get_name( const geo_polygon_type * polygon ); - void geo_polygon_set_name( geo_polygon_type * polygon , const char * name); - double geo_polygon_get_length( geo_polygon_type * polygon ); - bool geo_polygon_equal( const geo_polygon_type * polygon1 , const geo_polygon_type * polygon2 ); +#include - UTIL_IS_INSTANCE_HEADER( geo_polygon ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.hpp index 47a0198653..b7287644b8 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon.hpp @@ -1,19 +1,57 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'geo_polygon.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_GEO_POLYGON_H +#define ERT_GEO_POLYGON_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + + typedef struct geo_polygon_struct geo_polygon_type; + + geo_polygon_type * geo_polygon_alloc( const char * name ); + void geo_polygon_free( geo_polygon_type * polygon ); + void geo_polygon_free__( void * arg ); + void geo_polygon_add_point( geo_polygon_type * polygon , double x , double y ); + void geo_polygon_add_point_front( geo_polygon_type * polygon , double x , double y); + geo_polygon_type * geo_polygon_fload_alloc_irap( const char * filename ); + bool geo_polygon_contains_point( const geo_polygon_type * polygon , double x , double y); + bool geo_polygon_contains_point__( const geo_polygon_type * polygon , double x , double y, bool force_edge_inside); + void geo_polygon_reset(geo_polygon_type * polygon ); + void geo_polygon_fprintf(const geo_polygon_type * polygon , FILE * stream); + void geo_polygon_shift(geo_polygon_type * polygon , double x0 , double y0); + void geo_polygon_close( geo_polygon_type * polygoon); + int geo_polygon_get_size(const geo_polygon_type * polygon ); + void geo_polygon_iget_xy(const geo_polygon_type * polygon , int index , double *x , double *y); + bool geo_polygon_segment_intersects(const geo_polygon_type * polygon , double x1 , double y1 , double x2 , double y2); + const char * geo_polygon_get_name( const geo_polygon_type * polygon ); + void geo_polygon_set_name( geo_polygon_type * polygon , const char * name); + double geo_polygon_get_length( geo_polygon_type * polygon ); + bool geo_polygon_equal( const geo_polygon_type * polygon1 , const geo_polygon_type * polygon2 ); + + UTIL_IS_INSTANCE_HEADER( geo_polygon ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.h b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.h index 07283ecc00..750f328ead 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.h +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.h @@ -1,50 +1,9 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'geo_polygon_collection.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_GEO_POLYGON_COLLECTION_H -#define ERT_GEO_POLYGON_COLLECTION_H +#include -#ifdef __cplusplus -extern "C" { -#endif -#include - -#include - -#include - - - - typedef struct geo_polygon_collection_struct geo_polygon_collection_type; - - geo_polygon_collection_type * geo_polygon_collection_alloc( ); - void geo_polygon_collection_free( geo_polygon_collection_type * polygons ); - int geo_polygon_collection_size( const geo_polygon_collection_type * polygons ); - geo_polygon_type * geo_polygon_collection_create_polygon( geo_polygon_collection_type * polygons , const char * name ); - bool geo_polygon_collection_has_polygon( const geo_polygon_collection_type * polygons , const char * name); - bool geo_polygon_collection_add_polygon( geo_polygon_collection_type * polygons , geo_polygon_type * polygon , bool polygon_owner ); - geo_polygon_type * geo_polygon_collection_iget_polygon(const geo_polygon_collection_type * polygons , int index); - geo_polygon_type * geo_polygon_collection_get_polygon(const geo_polygon_collection_type * polygons , const char * polygon_name); - - UTIL_IS_INSTANCE_HEADER( geo_polygon_collection ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.hpp index 0b956ad4b8..1ee312ee10 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_polygon_collection.hpp @@ -1,19 +1,50 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2014 Statoil ASA, Norway. + + The file 'geo_polygon_collection.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_GEO_POLYGON_COLLECTION_H +#define ERT_GEO_POLYGON_COLLECTION_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +#include + + + + typedef struct geo_polygon_collection_struct geo_polygon_collection_type; + + geo_polygon_collection_type * geo_polygon_collection_alloc( ); + void geo_polygon_collection_free( geo_polygon_collection_type * polygons ); + int geo_polygon_collection_size( const geo_polygon_collection_type * polygons ); + geo_polygon_type * geo_polygon_collection_create_polygon( geo_polygon_collection_type * polygons , const char * name ); + bool geo_polygon_collection_has_polygon( const geo_polygon_collection_type * polygons , const char * name); + bool geo_polygon_collection_add_polygon( geo_polygon_collection_type * polygons , geo_polygon_type * polygon , bool polygon_owner ); + geo_polygon_type * geo_polygon_collection_iget_polygon(const geo_polygon_collection_type * polygons , int index); + geo_polygon_type * geo_polygon_collection_get_polygon(const geo_polygon_collection_type * polygons , const char * polygon_name); + + UTIL_IS_INSTANCE_HEADER( geo_polygon_collection ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_region.h b/ThirdParty/Ert/lib/include/ert/geometry/geo_region.h index 5f0311e199..6f8603c14d 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_region.h +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_region.h @@ -1,60 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'geo_region.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#include -#include -#include -#include - -#include -#include - -#ifndef ERT_GEO_REGION_H -#define ERT_GEO_REGION_H - - -#ifdef __cplusplus -extern "C" { -#endif - - - - typedef struct geo_region_struct geo_region_type; - - geo_region_type * geo_region_alloc( const geo_pointset_type * pointset , bool preselect); - void geo_region_free( geo_region_type * region ); - void geo_region_free__( void * arg ); - void geo_region_reset( geo_region_type * region ); - const int_vector_type * geo_region_get_index_list( geo_region_type * region ); - - void geo_region_select_inside_polygon( geo_region_type * region , const geo_polygon_type * polygon); - void geo_region_select_outside_polygon( geo_region_type * region , const geo_polygon_type * polygon); - void geo_region_deselect_inside_polygon( geo_region_type * region , const geo_polygon_type * polygon); - void geo_region_deselect_outside_polygon( geo_region_type * region , const geo_polygon_type * polygon); - - void geo_region_select_above_line( geo_region_type * region, const double xcoords[2] , const double ycoords[2]); - void geo_region_select_below_line( geo_region_type * region, const double xcoords[2] , const double ycoords[2]); - void geo_region_deselect_above_line( geo_region_type * region, const double xcoords[2] , const double ycoords[2]); - void geo_region_deselect_below_line( geo_region_type * region, const double xcoords[2] , const double ycoords[2]); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_region.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_region.hpp index aca4548a42..e719112d2c 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_region.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_region.hpp @@ -1,19 +1,60 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'geo_region.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include + +#include +#include + +#include +#include + +#include +#include + +#ifndef ERT_GEO_REGION_H +#define ERT_GEO_REGION_H + + +#ifdef __cplusplus +extern "C" { +#endif + + + + typedef struct geo_region_struct geo_region_type; + + geo_region_type * geo_region_alloc( const geo_pointset_type * pointset , bool preselect); + void geo_region_free( geo_region_type * region ); + void geo_region_free__( void * arg ); + void geo_region_reset( geo_region_type * region ); + const int_vector_type * geo_region_get_index_list( geo_region_type * region ); + + void geo_region_select_inside_polygon( geo_region_type * region , const geo_polygon_type * polygon); + void geo_region_select_outside_polygon( geo_region_type * region , const geo_polygon_type * polygon); + void geo_region_deselect_inside_polygon( geo_region_type * region , const geo_polygon_type * polygon); + void geo_region_deselect_outside_polygon( geo_region_type * region , const geo_polygon_type * polygon); + + void geo_region_select_above_line( geo_region_type * region, const double xcoords[2] , const double ycoords[2]); + void geo_region_select_below_line( geo_region_type * region, const double xcoords[2] , const double ycoords[2]); + void geo_region_deselect_above_line( geo_region_type * region, const double xcoords[2] , const double ycoords[2]); + void geo_region_deselect_below_line( geo_region_type * region, const double xcoords[2] , const double ycoords[2]); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.h b/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.h index 0e6dd12801..831b89bbef 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.h +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.h @@ -1,62 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'geo_surface.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_GEO_SURFACE_H -#define ERT_GEO_SURFACE_H - -#ifdef __cplusplus -extern "C" { -#endif - - -#include - - - typedef struct geo_surface_struct geo_surface_type; - - bool geo_surface_equal_header( const geo_surface_type * surface1 , const geo_surface_type * surface2 ); - bool geo_surface_equal( const geo_surface_type * surface1 , const geo_surface_type * surface2); - void geo_surface_free( geo_surface_type * geo_surface ); - void geo_surface_free__( void * arg); - geo_pointset_type * geo_surface_get_pointset( const geo_surface_type * surface ); - geo_surface_type * geo_surface_fload_alloc_irap( const char * filename , bool loadz); - geo_surface_type * geo_surface_alloc_new( int nx, int ny, double xinc, double yinc, double xstart, double ystart, double angle ); - bool geo_surface_fload_irap_zcoord( const geo_surface_type * surface, const char * filename, double *zlist); - double geo_surface_iget_zvalue(const geo_surface_type * surface, int index); - int geo_surface_get_size( const geo_surface_type * surface ); - void geo_surface_fprintf_irap( const geo_surface_type * surface, const char * filename ); - void geo_surface_fprintf_irap_external_zcoord( const geo_surface_type * surface, const char * filename , const double * zcoord); - int geo_surface_get_nx( const geo_surface_type * surface ); - int geo_surface_get_ny( const geo_surface_type * surface ); - void geo_surface_iget_xy( const geo_surface_type* surface, int index, double* x, double* y); - - void geo_surface_shift( const geo_surface_type * src , double value); - void geo_surface_scale( const geo_surface_type * src , double value); - void geo_surface_isub( geo_surface_type * self , const geo_surface_type * other); - void geo_surface_iset_zvalue(geo_surface_type * surface, int index , double value); - void geo_surface_assign_value( const geo_surface_type * src , double value); - geo_surface_type * geo_surface_alloc_copy( const geo_surface_type * src , bool copy_zdata); - void geo_surface_iadd( geo_surface_type * self , const geo_surface_type * other); - void geo_surface_imul( geo_surface_type * self , const geo_surface_type * other); - void geo_surface_isqrt( geo_surface_type * surface ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.hpp index f4030b6ca1..8a827b5b88 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_surface.hpp @@ -1,19 +1,62 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'geo_surface.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include + +#ifndef ERT_GEO_SURFACE_H +#define ERT_GEO_SURFACE_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + + + typedef struct geo_surface_struct geo_surface_type; + + bool geo_surface_equal_header( const geo_surface_type * surface1 , const geo_surface_type * surface2 ); + bool geo_surface_equal( const geo_surface_type * surface1 , const geo_surface_type * surface2); + void geo_surface_free( geo_surface_type * geo_surface ); + void geo_surface_free__( void * arg); + geo_pointset_type * geo_surface_get_pointset( const geo_surface_type * surface ); + geo_surface_type * geo_surface_fload_alloc_irap( const char * filename , bool loadz); + geo_surface_type * geo_surface_alloc_new( int nx, int ny, double xinc, double yinc, double xstart, double ystart, double angle ); + bool geo_surface_fload_irap_zcoord( const geo_surface_type * surface, const char * filename, double *zlist); + double geo_surface_iget_zvalue(const geo_surface_type * surface, int index); + int geo_surface_get_size( const geo_surface_type * surface ); + void geo_surface_fprintf_irap( const geo_surface_type * surface, const char * filename ); + void geo_surface_fprintf_irap_external_zcoord( const geo_surface_type * surface, const char * filename , const double * zcoord); + int geo_surface_get_nx( const geo_surface_type * surface ); + int geo_surface_get_ny( const geo_surface_type * surface ); + void geo_surface_iget_xy( const geo_surface_type* surface, int index, double* x, double* y); + + void geo_surface_shift( const geo_surface_type * src , double value); + void geo_surface_scale( const geo_surface_type * src , double value); + void geo_surface_isub( geo_surface_type * self , const geo_surface_type * other); + void geo_surface_iset_zvalue(geo_surface_type * surface, int index , double value); + void geo_surface_assign_value( const geo_surface_type * src , double value); + geo_surface_type * geo_surface_alloc_copy( const geo_surface_type * src , bool copy_zdata); + void geo_surface_iadd( geo_surface_type * self , const geo_surface_type * other); + void geo_surface_imul( geo_surface_type * self , const geo_surface_type * other); + void geo_surface_isqrt( geo_surface_type * surface ); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_util.h b/ThirdParty/Ert/lib/include/ert/geometry/geo_util.h index a988963dbc..ab351d623e 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_util.h +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_util.h @@ -1,46 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'geo_util.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_GEO_UTIL_H -#define ERT_GEO_UTIL_H - - -#ifdef __cplusplus -extern "C" { -#endif -#include - - typedef enum { - GEO_UTIL_LINES_CROSSING = 0, - GEO_UTIL_LINES_PARALLELL = 1, - GEO_UTIL_LINES_OVERLAPPING = 2, - GEO_UTIL_LINES_DEGENERATE = 3, - GEO_UTIL_NOT_CROSSING = 4 - } geo_util_xlines_status_enum; - - bool geo_util_inside_polygon__(const double * xlist , const double * ylist , int num_points , double x0 , double y0 , bool force_edge_inside); - bool geo_util_inside_polygon(const double * xlist , const double * ylist , int num_points , double x0 , double y0); - geo_util_xlines_status_enum geo_util_xlines( const double ** points , double * x0, double * y0 ); - geo_util_xlines_status_enum geo_util_xsegments( const double ** points , double * x0, double * y0 ); - +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/geometry/geo_util.hpp b/ThirdParty/Ert/lib/include/ert/geometry/geo_util.hpp index b0b3bf1e52..a988963dbc 100644 --- a/ThirdParty/Ert/lib/include/ert/geometry/geo_util.hpp +++ b/ThirdParty/Ert/lib/include/ert/geometry/geo_util.hpp @@ -1,19 +1,46 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. - - This file is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'geo_util.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -#include +#ifndef ERT_GEO_UTIL_H +#define ERT_GEO_UTIL_H + + +#ifdef __cplusplus +extern "C" { +#endif +#include + + typedef enum { + GEO_UTIL_LINES_CROSSING = 0, + GEO_UTIL_LINES_PARALLELL = 1, + GEO_UTIL_LINES_OVERLAPPING = 2, + GEO_UTIL_LINES_DEGENERATE = 3, + GEO_UTIL_NOT_CROSSING = 4 + } geo_util_xlines_status_enum; + + bool geo_util_inside_polygon__(const double * xlist , const double * ylist , int num_points , double x0 , double y0 , bool force_edge_inside); + bool geo_util_inside_polygon(const double * xlist , const double * ylist , int num_points , double x0 , double y0); + geo_util_xlines_status_enum geo_util_xlines( const double ** points , double * x0, double * y0 ); + geo_util_xlines_status_enum geo_util_xsegments( const double ** points , double * x0, double * y0 ); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/TestArea.hpp b/ThirdParty/Ert/lib/include/ert/util/TestArea.hpp deleted file mode 100644 index 4700ca64cc..0000000000 --- a/ThirdParty/Ert/lib/include/ert/util/TestArea.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (C) 2016 Statoil ASA, Norway. - - This is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ERT_TEST_AREA_CXX -#define ERT_TEST_AREA_CXX - -#include - -#include - -#include - -/* - The TestArea class will create a random temporary and call chdir() - into this directory. When the TestArea instance goes out of scope - the directory will be removed. - - In addition to the cleanup the main feature of the TestArea - implementation are in the copyXXX() methods, these methods all - interpret the input argument relative to the original cwd. This is - quite convenient when you need to copy input files to the test - directory. -*/ - - -namespace ERT { - - class TestArea { - public: - TestArea( ); - TestArea( const std::string& name ); - void enter(const std::string& name ); - - /* Will copy one file into work area. */ - void copyFile( const std::string& filename) const; - - /* Will copy a directory with all content recursively into the - work area. */ - void copyDirectory( const std::string& directory) const; - - /* - Will copy all the content of a directory into the work area, i.e. - if your directory looks like: - - path0/file1.txt - path0/file2.txt - path0/subdir/file3.txt - - copyDirectoryContet( "path0" ) will copy the files file1.txt, - file2.txt and the directory subdir into work area. - */ - void copyDirectoryContent( const std::string& directory) const; - - /* - Will determine the directory holding the input entry, and copy - the content of that directory, i.e. the following are - equivalent: - - copyDirectoryContent("path0") <=> copyParentContent("path0/file1.txt") - - */ - void copyParentContent( const std::string& entry ) const; - - /* - Will call copyDircetory( ) with the directory holding this - entry: - - copyDirectory("path0") <=> copyParentDirectory("path0/file1.txt") - */ - void copyParentDirectory( const std::string& entry ) const; - - std::string getCwd() const; - std::string getOriginalCwd() const; - void setStore(bool store); - - private: - std::string inputPath( const std::string& path) const; - void assertOpen( ) const; - void assertFileExists( const std::string& ) const; - void assertDirectoryExists( const std::string& ) const; - void assertEntryExists( const std::string& ) const; - ert_unique_ptr c_ptr; - }; -} - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/arg_pack.h b/ThirdParty/Ert/lib/include/ert/util/arg_pack.h deleted file mode 100644 index af4487d034..0000000000 --- a/ThirdParty/Ert/lib/include/ert/util/arg_pack.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'arg_pack.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ERT_ARG_PACK_H -#define ERT_ARG_PACK_H -#ifdef __cplusplus -extern "C" { -#endif -#include -#include - -#include -#include - -typedef struct arg_pack_struct arg_pack_type; -typedef void (arg_node_free_ftype) (void *); -typedef void * (arg_node_copyc_ftype) (const void *); - - arg_pack_type * arg_pack_alloc(); - UTIL_SAFE_CAST_HEADER( arg_pack ); - UTIL_SAFE_CAST_HEADER_CONST( arg_pack ); - UTIL_IS_INSTANCE_HEADER( arg_pack ); - - void arg_pack_free(arg_pack_type * ); - void arg_pack_free__(void *); - void arg_pack_clear(arg_pack_type *); - void arg_pack_lock(arg_pack_type *); - void arg_pack_fscanf(arg_pack_type * arg , FILE * stream, const char * filename); - void arg_pack_fprintf(const arg_pack_type * , FILE * ); - - void arg_pack_append_ptr(arg_pack_type * , void *); - void arg_pack_append_const_ptr(arg_pack_type * , const void *); - void arg_pack_append_owned_ptr(arg_pack_type * , void * , arg_node_free_ftype *); - void arg_pack_append_copy(arg_pack_type * , void * , arg_node_copyc_ftype * , arg_node_free_ftype *); - - /* - void arg_pack_iset_copy(arg_pack_type * arg_pack , int index , void * ptr, arg_node_copyc_ftype * copyc , arg_node_free_ftype * freef); - void arg_pack_iset_ptr(arg_pack_type * arg_pack, int index , void * ptr); - void arg_pack_iset_owned_ptr(arg_pack_type * arg_pack, int index , void * ptr, arg_node_free_ftype * freef); - */ - const void * arg_pack_iget_const_ptr( const arg_pack_type * arg_pack , int index); - void * arg_pack_iget_ptr(const arg_pack_type * , int); - void * arg_pack_iget_adress(const arg_pack_type * , int); - node_ctype arg_pack_iget_ctype(const arg_pack_type * arg_pack ,int index); - - int arg_pack_size( const arg_pack_type * arg_pack ); - - /*****************************************************************/ - -#define APPEND_TYPED_HEADER(type) void arg_pack_append_ ## type (arg_pack_type * , type); -#define IGET_TYPED_HEADER(type) type arg_pack_iget_ ## type( const arg_pack_type * , int ); -#define ISET_TYPED_HEADER(type) void arg_pack_iset_ ## type( arg_pack_type * , int , type value); - -APPEND_TYPED_HEADER(int) -APPEND_TYPED_HEADER(bool) -APPEND_TYPED_HEADER(char) -APPEND_TYPED_HEADER(float) -APPEND_TYPED_HEADER(double) -APPEND_TYPED_HEADER(size_t) - -IGET_TYPED_HEADER(int) -IGET_TYPED_HEADER(bool) -IGET_TYPED_HEADER(char) -IGET_TYPED_HEADER(float) -IGET_TYPED_HEADER(double) -IGET_TYPED_HEADER(size_t) - -ISET_TYPED_HEADER(int) -ISET_TYPED_HEADER(bool) -ISET_TYPED_HEADER(char) -ISET_TYPED_HEADER(float) -ISET_TYPED_HEADER(double) -ISET_TYPED_HEADER(size_t) - -#undef APPEND_TYPED_HEADER -#undef GET_TYPED_HEADER - - -#ifdef __cplusplus -} -#endif -#endif - diff --git a/ThirdParty/Ert/lib/include/ert/util/arg_pack.hpp b/ThirdParty/Ert/lib/include/ert/util/arg_pack.hpp deleted file mode 100644 index 94c71385e1..0000000000 --- a/ThirdParty/Ert/lib/include/ert/util/arg_pack.hpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (C) 2018 Statoil ASA, Norway. - - This is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ARG_PACK_CXX -#define ARG_PACK_CXX - -#include - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/atomic.h b/ThirdParty/Ert/lib/include/ert/util/atomic.h index 852432c7a8..08aae0110e 100644 --- a/ThirdParty/Ert/lib/include/ert/util/atomic.h +++ b/ThirdParty/Ert/lib/include/ert/util/atomic.h @@ -1,27 +1,27 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'atomic.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'atomic.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ -/* +/* This whole file was something I found on the internet - it was posted as beeing in the public domain. The essential functions __sync_add_and_fetch() and do on are (as I understand it) built in gcc functions. Only available in reasonably new gcc versions - (4.1???). + (4.1???). */ #ifndef _ATOMIC_H diff --git a/ThirdParty/Ert/lib/include/ert/util/buffer.h b/ThirdParty/Ert/lib/include/ert/util/buffer.h index e828ae7146..05ec18d6af 100644 --- a/ThirdParty/Ert/lib/include/ert/util/buffer.h +++ b/ThirdParty/Ert/lib/include/ert/util/buffer.h @@ -1,111 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'buffer.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_BUFFER_H -#define ERT_BUFFER_H - -#ifdef __cplusplus -extern "C" { -#endif -#include -#include -#include -#include -#include - -#include -#include -#include - - - - typedef struct buffer_struct buffer_type; - - buffer_type * buffer_alloc( size_t buffer_size ); - buffer_type * buffer_alloc_private_wrapper(void * data , size_t buffer_size ); - bool buffer_search_replace( buffer_type * buffer , const char * old_string , const char * new_string); - void buffer_shrink_to_fit( buffer_type * buffer ); - void buffer_memshift(buffer_type * buffer , size_t offset, ssize_t shift); - bool buffer_strstr( buffer_type * buffer , const char * expr ); - bool buffer_strchr( buffer_type * buffer , int c); - void buffer_replace_string( buffer_type * buffer , size_t offset , size_t old_size , const char * new_string); - void buffer_replace_data(buffer_type * buffer , size_t offset , size_t old_size , const void * new_data , size_t new_size); - - void buffer_free_container( buffer_type * buffer ); - void buffer_free( buffer_type * buffer); - size_t buffer_fread(buffer_type * buffer , void * target_ptr , size_t item_size , size_t items); - size_t buffer_fwrite(buffer_type * buffer , const void * src_ptr , size_t item_size , size_t items); - void buffer_summarize(const buffer_type * buffer , const char *); - - void buffer_fwrite_char_ptr(buffer_type * buffer , const char * string_ptr ); - void buffer_strcat(buffer_type * buffer , const char * string); - void buffer_fwrite_char(buffer_type * buffer , char value); - void buffer_fwrite_int(buffer_type * buffer , int value); - void buffer_fskip_bool(buffer_type * buffer); - void buffer_fwrite_bool(buffer_type * buffer , bool value); - int buffer_fread_int(buffer_type * buffer ); - bool buffer_fread_bool(buffer_type * buffer); - long int buffer_fread_long(buffer_type * buffer); - void buffer_fskip_long(buffer_type * buffer); - void buffer_store(const buffer_type * buffer , const char * filename); - size_t buffer_get_offset(const buffer_type * buffer); - size_t buffer_get_alloc_size(const buffer_type * buffer); - size_t buffer_get_size(const buffer_type * buffer); - size_t buffer_get_string_size( const buffer_type * buffer ); - size_t buffer_get_remaining_size(const buffer_type * buffer); - void * buffer_get_data(const buffer_type * buffer); - void * buffer_alloc_data_copy(const buffer_type * buffer); - void * buffer_iget_data(const buffer_type * buffer, size_t offset); - void buffer_stream_fwrite( const buffer_type * buffer , FILE * stream ); - int buffer_fgetc( buffer_type * buffer ); - void buffer_fseek(buffer_type * buffer , ssize_t offset , int whence); - void buffer_fskip(buffer_type * buffer, ssize_t offset); - void buffer_clear( buffer_type * buffer ); - - void buffer_fskip_int(buffer_type * buffer); - void buffer_fskip_time_t(buffer_type * buffer); - time_t buffer_fread_time_t(buffer_type * buffer); - void buffer_fwrite_time_t(buffer_type * buffer , time_t value); - void buffer_rewind(buffer_type * buffer ); - - double buffer_fread_double(buffer_type * buffer); - void buffer_fwrite_double(buffer_type * buffer , double value); - - size_t buffer_stream_fwrite_n( const buffer_type * buffer , size_t offset , ssize_t write_size , FILE * stream ); - void buffer_stream_fprintf( const buffer_type * buffer , FILE * stream ); - void buffer_stream_fread( buffer_type * buffer , size_t byte_size , FILE * stream); - buffer_type * buffer_fread_alloc(const char * filename); - void buffer_fread_realloc(buffer_type * buffer , const char * filename); - void buffer_fprintf(const buffer_type * buffer, const char * fmt, FILE * stream); - -#ifdef ERT_HAVE_ZLIB - size_t buffer_fwrite_compressed(buffer_type * buffer, const void * ptr , size_t byte_size); - size_t buffer_fread_compressed(buffer_type * buffer , size_t compressed_size , void * target_ptr , size_t target_size); -#endif - - -#include "buffer_string.h" - - UTIL_IS_INSTANCE_HEADER( buffer ); - UTIL_SAFE_CAST_HEADER( buffer ); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/buffer.hpp b/ThirdParty/Ert/lib/include/ert/util/buffer.hpp index b002e8981e..167028a46b 100644 --- a/ThirdParty/Ert/lib/include/ert/util/buffer.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/buffer.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'buffer.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,103 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef BUFFER_CXX -#define BUFFER_CXX +#ifndef ERT_BUFFER_H +#define ERT_BUFFER_H -#include +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include +#include +#include + +#include +#include +#include + + + + typedef struct buffer_struct buffer_type; + + buffer_type * buffer_alloc( size_t buffer_size ); + buffer_type * buffer_alloc_private_wrapper(void * data , size_t buffer_size ); + bool buffer_search_replace( buffer_type * buffer , const char * old_string , const char * new_string); + void buffer_shrink_to_fit( buffer_type * buffer ); + void buffer_memshift(buffer_type * buffer , size_t offset, ssize_t shift); + bool buffer_strstr( buffer_type * buffer , const char * expr ); + bool buffer_strchr( buffer_type * buffer , int c); + void buffer_replace_string( buffer_type * buffer , size_t offset , size_t old_size , const char * new_string); + void buffer_replace_data(buffer_type * buffer , size_t offset , size_t old_size , const void * new_data , size_t new_size); + + void buffer_free_container( buffer_type * buffer ); + void buffer_free( buffer_type * buffer); + size_t buffer_fread(buffer_type * buffer , void * target_ptr , size_t item_size , size_t items); + size_t buffer_fwrite(buffer_type * buffer , const void * src_ptr , size_t item_size , size_t items); + void buffer_summarize(const buffer_type * buffer , const char *); + + void buffer_fwrite_char_ptr(buffer_type * buffer , const char * string_ptr ); + void buffer_strcat(buffer_type * buffer , const char * string); + void buffer_fwrite_char(buffer_type * buffer , char value); + void buffer_fwrite_int(buffer_type * buffer , int value); + void buffer_fskip_bool(buffer_type * buffer); + void buffer_fwrite_bool(buffer_type * buffer , bool value); + int buffer_fread_int(buffer_type * buffer ); + bool buffer_fread_bool(buffer_type * buffer); + long int buffer_fread_long(buffer_type * buffer); + void buffer_fskip_long(buffer_type * buffer); + void buffer_store(const buffer_type * buffer , const char * filename); + size_t buffer_get_offset(const buffer_type * buffer); + size_t buffer_get_alloc_size(const buffer_type * buffer); + size_t buffer_get_size(const buffer_type * buffer); + size_t buffer_get_string_size( const buffer_type * buffer ); + size_t buffer_get_remaining_size(const buffer_type * buffer); + void * buffer_get_data(const buffer_type * buffer); + void * buffer_alloc_data_copy(const buffer_type * buffer); + void * buffer_iget_data(const buffer_type * buffer, size_t offset); + void buffer_stream_fwrite( const buffer_type * buffer , FILE * stream ); + int buffer_fgetc( buffer_type * buffer ); + void buffer_fseek(buffer_type * buffer , ssize_t offset , int whence); + void buffer_fskip(buffer_type * buffer, ssize_t offset); + void buffer_clear( buffer_type * buffer ); + + void buffer_fskip_int(buffer_type * buffer); + void buffer_fskip_time_t(buffer_type * buffer); + time_t buffer_fread_time_t(buffer_type * buffer); + void buffer_fwrite_time_t(buffer_type * buffer , time_t value); + void buffer_rewind(buffer_type * buffer ); + + double buffer_fread_double(buffer_type * buffer); + void buffer_fwrite_double(buffer_type * buffer , double value); + + size_t buffer_stream_fwrite_n( const buffer_type * buffer , size_t offset , ssize_t write_size , FILE * stream ); + void buffer_stream_fprintf( const buffer_type * buffer , FILE * stream ); + void buffer_stream_fread( buffer_type * buffer , size_t byte_size , FILE * stream); + buffer_type * buffer_fread_alloc(const char * filename); + void buffer_fread_realloc(buffer_type * buffer , const char * filename); + void buffer_fprintf(const buffer_type * buffer, const char * fmt, FILE * stream); + +#ifdef ERT_HAVE_ZLIB + size_t buffer_fwrite_compressed(buffer_type * buffer, const void * ptr , size_t byte_size); + size_t buffer_fread_compressed(buffer_type * buffer , size_t compressed_size , void * target_ptr , size_t target_size); +#endif + + +#include "buffer_string.h" + + UTIL_IS_INSTANCE_HEADER( buffer ); + UTIL_SAFE_CAST_HEADER( buffer ); + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/ecl_version.h b/ThirdParty/Ert/lib/include/ert/util/ecl_version.h index 83c39ae8b2..53e08bb078 100644 --- a/ThirdParty/Ert/lib/include/ert/util/ecl_version.h +++ b/ThirdParty/Ert/lib/include/ert/util/ecl_version.h @@ -1,40 +1,9 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. - - The file 'ecl_version.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ECL_VERSION -#define ECL_VERSION - -#include - -#ifdef __cplusplus -extern"C" { -#endif - -const char * ecl_version_get_git_commit(); -const char * ecl_version_get_git_commit_short(); -const char * ecl_version_get_build_time(); -int ecl_version_get_major_version(); -int ecl_version_get_minor_version(); -const char * ecl_version_get_micro_version(); -bool ecl_version_is_ert_devel_version(); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/ecl_version.hpp b/ThirdParty/Ert/lib/include/ert/util/ecl_version.hpp index 3af2a9706b..83c39ae8b2 100644 --- a/ThirdParty/Ert/lib/include/ert/util/ecl_version.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/ecl_version.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2016 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'ecl_version.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,32 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef ECL_VERSION_CXX -#define ECL_VERSION_CXX +#ifndef ECL_VERSION +#define ECL_VERSION -#include +#include + +#ifdef __cplusplus +extern"C" { +#endif + +const char * ecl_version_get_git_commit(); +const char * ecl_version_get_git_commit_short(); +const char * ecl_version_get_build_time(); +int ecl_version_get_major_version(); +int ecl_version_get_minor_version(); +const char * ecl_version_get_micro_version(); +bool ecl_version_is_ert_devel_version(); + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/hash.h b/ThirdParty/Ert/lib/include/ert/util/hash.h index cc7dfbb200..52aece2574 100644 --- a/ThirdParty/Ert/lib/include/ert/util/hash.h +++ b/ThirdParty/Ert/lib/include/ert/util/hash.h @@ -1,87 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'hash.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_HASH_H -#define ERT_HASH_H -#ifdef __cplusplus -extern"C" { -#endif - -#include - -#include -#include -#include - -typedef struct hash_struct hash_type; -typedef struct hash_iter_struct hash_iter_type; -typedef void (hash_apply_ftype) (void * ); - -UTIL_SAFE_CAST_HEADER(hash); -UTIL_SAFE_CAST_HEADER_CONST(hash); - -hash_type * hash_alloc(void); -void hash_iter_complete(hash_type * ); -void hash_free(hash_type *); -void hash_free__(void *); -void hash_insert_ref(hash_type * , const char * , const void *); -void hash_insert_copy(hash_type *, const char * , const void *, copyc_ftype *, free_ftype *); -void hash_insert_string(hash_type *, const char *, const char *); -bool hash_has_key(const hash_type *, const char *); -void * hash_pop( hash_type * hash , const char * key); -void * hash_safe_get( const hash_type * hash , const char * key ); -void * hash_get(const hash_type *, const char *); -char * hash_get_string(const hash_type * , const char *); -void hash_del(hash_type *, const char *); -void hash_safe_del(hash_type * , const char * ); -void hash_clear(hash_type *); -int hash_get_size(const hash_type *); -void hash_set_keylist(const hash_type * , char **); -char ** hash_alloc_keylist(const hash_type *); -stringlist_type * hash_alloc_stringlist(const hash_type * ); - -char ** hash_alloc_sorted_keylist (const hash_type *hash , int ( hash_get_cmp_value ) (const void *)); -char ** hash_alloc_key_sorted_list(const hash_type *hash, int (*cmp)(const void *, const void *)); -bool hash_key_list_compare(const hash_type * hash1, const hash_type * hash2); -void hash_insert_hash_owned_ref(hash_type *, const char * , const void *, free_ftype *); -void hash_resize(hash_type *hash, int new_size); - -hash_iter_type * hash_iter_alloc(const hash_type *); -void hash_iter_free(hash_iter_type *); -bool hash_iter_is_complete(const hash_iter_type *); -const char * hash_iter_get_next_key(hash_iter_type *); -void * hash_iter_get_next_value(hash_iter_type *); -void hash_iter_restart( hash_iter_type * iter ); - -hash_type * hash_alloc_from_options(const stringlist_type *); -bool hash_add_option( hash_type * hash, const char * key_value); - -int hash_inc_counter(hash_type * hash , const char * counter_key); -int hash_get_counter(const hash_type * hash , const char * key); -void hash_insert_int(hash_type * , const char * , int); -int hash_get_int(const hash_type * , const char *); -void hash_insert_double(hash_type * , const char * , double); -double hash_get_double(const hash_type * , const char *); -void hash_apply( hash_type * hash , hash_apply_ftype * func); +#include -UTIL_IS_INSTANCE_HEADER(hash); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/hash.hpp b/ThirdParty/Ert/lib/include/ert/util/hash.hpp index 1a2758952a..deae544285 100644 --- a/ThirdParty/Ert/lib/include/ert/util/hash.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/hash.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'hash.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,79 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef HASH_CXX -#define HASH_CXX +#ifndef ERT_HASH_H +#define ERT_HASH_H +#ifdef __cplusplus +extern"C" { +#endif + +#include + +#include +#include +#include + +typedef struct hash_struct hash_type; +typedef struct hash_iter_struct hash_iter_type; +typedef void (hash_apply_ftype) (void * ); + +UTIL_SAFE_CAST_HEADER(hash); +UTIL_SAFE_CAST_HEADER_CONST(hash); + +hash_type * hash_alloc(void); +void hash_iter_complete(hash_type * ); +void hash_free(hash_type *); +void hash_free__(void *); +void hash_insert_ref(hash_type * , const char * , const void *); +void hash_insert_copy(hash_type *, const char * , const void *, copyc_ftype *, free_ftype *); +void hash_insert_string(hash_type *, const char *, const char *); +bool hash_has_key(const hash_type *, const char *); +void * hash_pop( hash_type * hash , const char * key); +void * hash_safe_get( const hash_type * hash , const char * key ); +void * hash_get(const hash_type *, const char *); +char * hash_get_string(const hash_type * , const char *); +void hash_del(hash_type *, const char *); +void hash_safe_del(hash_type * , const char * ); +void hash_clear(hash_type *); +int hash_get_size(const hash_type *); +void hash_set_keylist(const hash_type * , char **); +char ** hash_alloc_keylist(const hash_type *); +stringlist_type * hash_alloc_stringlist(const hash_type * ); -#include +char ** hash_alloc_sorted_keylist (const hash_type *hash , int ( hash_get_cmp_value ) (const void *)); +char ** hash_alloc_key_sorted_list(const hash_type *hash, int (*cmp)(const void *, const void *)); +bool hash_key_list_compare(const hash_type * hash1, const hash_type * hash2); +void hash_insert_hash_owned_ref(hash_type *, const char * , const void *, free_ftype *); +void hash_resize(hash_type *hash, int new_size); +hash_iter_type * hash_iter_alloc(const hash_type *); +void hash_iter_free(hash_iter_type *); +bool hash_iter_is_complete(const hash_iter_type *); +const char * hash_iter_get_next_key(hash_iter_type *); +void * hash_iter_get_next_value(hash_iter_type *); +void hash_iter_restart( hash_iter_type * iter ); + +hash_type * hash_alloc_from_options(const stringlist_type *); +bool hash_add_option( hash_type * hash, const char * key_value); + +int hash_inc_counter(hash_type * hash , const char * counter_key); +int hash_get_counter(const hash_type * hash , const char * key); +void hash_insert_int(hash_type * , const char * , int); +int hash_get_int(const hash_type * , const char *); +void hash_insert_double(hash_type * , const char * , double); +double hash_get_double(const hash_type * , const char *); +void hash_apply( hash_type * hash , hash_apply_ftype * func); + +UTIL_IS_INSTANCE_HEADER(hash); + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/hash_node.h b/ThirdParty/Ert/lib/include/ert/util/hash_node.h index e587177004..e0a03b228f 100644 --- a/ThirdParty/Ert/lib/include/ert/util/hash_node.h +++ b/ThirdParty/Ert/lib/include/ert/util/hash_node.h @@ -1,49 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'hash_node.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_HASH_NODE_H -#define ERT_HASH_NODE_H -#ifdef __cplusplus -extern "C" { -#endif -#include -#include +#include -#include -typedef struct hash_node_struct hash_node_type; -typedef uint32_t (hashf_type) (const char *key, size_t len); -typedef enum {hash_ref_data , hash_int_data , hash_double_data , hash_string_data} hash_data_type; - - -bool hash_node_key_eq(const hash_node_type * , uint32_t , const char *); -hash_node_type * hash_node_get_next(const hash_node_type * ); -uint32_t hash_node_get_insert_nr(const hash_node_type * ); -void hash_node_set_next(hash_node_type * , const hash_node_type * ); -hash_node_type * hash_node_alloc_new(const char *, node_data_type * , hashf_type *, uint32_t); -void hash_node_set_insert_nr(hash_node_type *, uint32_t ); -uint32_t hash_node_get_table_index(const hash_node_type * ); -uint32_t hash_node_get_global_index(const hash_node_type * ); -const char * hash_node_get_key(const hash_node_type * ); -node_data_type * hash_node_get_data(const hash_node_type *); -void hash_node_free(hash_node_type *); -uint32_t hash_node_set_table_index(hash_node_type *, uint32_t ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/hash_node.hpp b/ThirdParty/Ert/lib/include/ert/util/hash_node.hpp index 2d6176c592..8579068ebb 100644 --- a/ThirdParty/Ert/lib/include/ert/util/hash_node.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/hash_node.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'hash_node.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,41 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef HASH_NODE_CXX -#define HASH_NODE_CXX +#ifndef ERT_HASH_NODE_H +#define ERT_HASH_NODE_H +#ifdef __cplusplus +extern "C" { +#endif +#include +#include + +#include -#include +typedef struct hash_node_struct hash_node_type; +typedef uint32_t (hashf_type) (const char *key, size_t len); +typedef enum {hash_ref_data , hash_int_data , hash_double_data , hash_string_data} hash_data_type; + +bool hash_node_key_eq(const hash_node_type * , uint32_t , const char *); +hash_node_type * hash_node_get_next(const hash_node_type * ); +uint32_t hash_node_get_insert_nr(const hash_node_type * ); +void hash_node_set_next(hash_node_type * , const hash_node_type * ); +hash_node_type * hash_node_alloc_new(const char *, node_data_type * , hashf_type *, uint32_t); +void hash_node_set_insert_nr(hash_node_type *, uint32_t ); +uint32_t hash_node_get_table_index(const hash_node_type * ); +uint32_t hash_node_get_global_index(const hash_node_type * ); +const char * hash_node_get_key(const hash_node_type * ); +node_data_type * hash_node_get_data(const hash_node_type *); +void hash_node_free(hash_node_type *); +uint32_t hash_node_set_table_index(hash_node_type *, uint32_t ); +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/hash_sll.h b/ThirdParty/Ert/lib/include/ert/util/hash_sll.h index 3fc57d1e6b..81add8960d 100644 --- a/ThirdParty/Ert/lib/include/ert/util/hash_sll.h +++ b/ThirdParty/Ert/lib/include/ert/util/hash_sll.h @@ -1,41 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'hash_sll.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_HASH_SLL_H -#define ERT_HASH_SLL_H -#ifdef __cplusplus -extern "C" { -#endif +#include -#include -typedef struct hash_sll_struct hash_sll_type; - -hash_sll_type **hash_sll_alloc_table(int ); -/*hash_sll_type * hash_sll_alloc(void);*/ -void hash_sll_del_node(hash_sll_type * , hash_node_type *); -void hash_sll_add_node(hash_sll_type *, hash_node_type *); -void hash_sll_free(hash_sll_type *); -bool hash_sll_has_key(const hash_sll_type *, uint32_t , const char *); -bool hash_sll_empty(const hash_sll_type * hash_sll); -hash_node_type * hash_sll_get(const hash_sll_type *, uint32_t , const char *); -hash_node_type * hash_sll_get_head(const hash_sll_type *); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/hash_sll.hpp b/ThirdParty/Ert/lib/include/ert/util/hash_sll.hpp index 70c64a0b03..2af6319e41 100644 --- a/ThirdParty/Ert/lib/include/ert/util/hash_sll.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/hash_sll.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'hash_sll.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,33 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef HASH_SLL_CXX -#define HASH_SLL_CXX +#ifndef ERT_HASH_SLL_H +#define ERT_HASH_SLL_H +#ifdef __cplusplus +extern "C" { +#endif + +#include -#include +typedef struct hash_sll_struct hash_sll_type; +hash_sll_type **hash_sll_alloc_table(int ); +/*hash_sll_type * hash_sll_alloc(void);*/ +void hash_sll_del_node(hash_sll_type * , hash_node_type *); +void hash_sll_add_node(hash_sll_type *, hash_node_type *); +void hash_sll_free(hash_sll_type *); +bool hash_sll_has_key(const hash_sll_type *, uint32_t , const char *); +bool hash_sll_empty(const hash_sll_type * hash_sll); +hash_node_type * hash_sll_get(const hash_sll_type *, uint32_t , const char *); +hash_node_type * hash_sll_get_head(const hash_sll_type *); +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/lookup_table.h b/ThirdParty/Ert/lib/include/ert/util/lookup_table.h index a2ebb1d32e..261d75b170 100644 --- a/ThirdParty/Ert/lib/include/ert/util/lookup_table.h +++ b/ThirdParty/Ert/lib/include/ert/util/lookup_table.h @@ -1,52 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'lookup_table.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_LOOKUP_TABLE_H -#define ERT_LOOKUP_TABLE_H +#include -#ifdef __cplusplus -extern "C" { -#endif -#include - -typedef struct lookup_table_struct lookup_table_type; - - - void lookup_table_set_data( lookup_table_type * lt , double_vector_type * x , double_vector_type * y , bool data_owner ); - lookup_table_type * lookup_table_alloc( double_vector_type * x , double_vector_type * y , bool data_owner); - lookup_table_type * lookup_table_alloc_empty(); - void lookup_table_append( lookup_table_type * lt , double x , double y); - void lookup_table_free( lookup_table_type * lt ); - double lookup_table_interp( lookup_table_type * lt , double x); - double lookup_table_get_max_value( lookup_table_type * lookup_table ); - double lookup_table_get_min_value( lookup_table_type * lookup_table ); - double lookup_table_get_max_arg( lookup_table_type * lookup_table ); - double lookup_table_get_min_arg( lookup_table_type * lookup_table ); - int lookup_table_get_size( const lookup_table_type * lt ); - void lookup_table_set_low_limit( lookup_table_type * lt , double limit); - bool lookup_table_has_low_limit(const lookup_table_type * lt ); - void lookup_table_set_high_limit( lookup_table_type * lt , double limit); - bool lookup_table_has_high_limit(const lookup_table_type * lt ); - - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/lookup_table.hpp b/ThirdParty/Ert/lib/include/ert/util/lookup_table.hpp index a3fcd045ac..9658cd411b 100644 --- a/ThirdParty/Ert/lib/include/ert/util/lookup_table.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/lookup_table.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'lookup_table.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,44 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef LOOKUP_TABLE_CXX -#define LOOKUP_TABLE_CXX +#ifndef ERT_LOOKUP_TABLE_H +#define ERT_LOOKUP_TABLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef struct lookup_table_struct lookup_table_type; -#include + void lookup_table_set_data( lookup_table_type * lt , double_vector_type * x , double_vector_type * y , bool data_owner ); + lookup_table_type * lookup_table_alloc( double_vector_type * x , double_vector_type * y , bool data_owner); + lookup_table_type * lookup_table_alloc_empty(); + void lookup_table_append( lookup_table_type * lt , double x , double y); + void lookup_table_free( lookup_table_type * lt ); + double lookup_table_interp( lookup_table_type * lt , double x); + double lookup_table_get_max_value( lookup_table_type * lookup_table ); + double lookup_table_get_min_value( lookup_table_type * lookup_table ); + double lookup_table_get_max_arg( lookup_table_type * lookup_table ); + double lookup_table_get_min_arg( lookup_table_type * lookup_table ); + int lookup_table_get_size( const lookup_table_type * lt ); + void lookup_table_set_low_limit( lookup_table_type * lt , double limit); + bool lookup_table_has_low_limit(const lookup_table_type * lt ); + void lookup_table_set_high_limit( lookup_table_type * lt , double limit); + bool lookup_table_has_high_limit(const lookup_table_type * lt ); + + + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/mzran.h b/ThirdParty/Ert/lib/include/ert/util/mzran.h index 506fa99887..d60a9a969b 100644 --- a/ThirdParty/Ert/lib/include/ert/util/mzran.h +++ b/ThirdParty/Ert/lib/include/ert/util/mzran.h @@ -1,47 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'mzran.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_MZRAN_H -#define ERT_MZRAN_H +#include -#ifdef __cplusplus -extern "C" { -#endif -#include -#include -typedef struct mzran_struct mzran_type; - -#define MZRAN_MAX_VALUE 4294967296 -#define MZRAN_STATE_SIZE 16 /* Size of the seed buffer - in bytes. */ - - -void mzran_fscanf_state( void * __rng , FILE * stream ); -unsigned int mzran_forward(void * __rng); -void * mzran_alloc( void ); -void mzran_set_state(void * __rng , const char * seed_buffer); -void mzran_get_state(void * __rng , char * state_buffer); -double mzran_get_double(mzran_type * rng); -int mzran_get_int( mzran_type * rng, int max); -void mzran_fprintf_state( const void * __rng , FILE * stream); -void mzran_free( void * __rng ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/mzran.hpp b/ThirdParty/Ert/lib/include/ert/util/mzran.hpp index 512eb56ad9..06315a06ce 100644 --- a/ThirdParty/Ert/lib/include/ert/util/mzran.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/mzran.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'mzran.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,39 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef MZRAN_CXX -#define MZRAN_CXX +#ifndef ERT_MZRAN_H +#define ERT_MZRAN_H -#include +#ifdef __cplusplus +extern "C" { +#endif +#include +#include + +typedef struct mzran_struct mzran_type; + +#define MZRAN_MAX_VALUE 4294967296 +#define MZRAN_STATE_SIZE 16 /* Size of the seed buffer - in bytes. */ + +void mzran_fscanf_state( void * __rng , FILE * stream ); +unsigned int mzran_forward(void * __rng); +void * mzran_alloc( void ); +void mzran_set_state(void * __rng , const char * seed_buffer); +void mzran_get_state(void * __rng , char * state_buffer); +double mzran_get_double(mzran_type * rng); +int mzran_get_int( mzran_type * rng, int max); +void mzran_fprintf_state( const void * __rng , FILE * stream); +void mzran_free( void * __rng ); + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/node_ctype.h b/ThirdParty/Ert/lib/include/ert/util/node_ctype.h index 314522277a..0a86ac67be 100644 --- a/ThirdParty/Ert/lib/include/ert/util/node_ctype.h +++ b/ThirdParty/Ert/lib/include/ert/util/node_ctype.h @@ -1,50 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'node_ctype.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_NODE_CTYPE_H -#define ERT_NODE_CTYPE_H -#ifdef __cplusplus -extern "C" { -#endif +#include -/* - value : means a scalar which has been packed into the container - object. - - pointer: means a (typed) pointer which points to a memory location - outside the container object (however the container can own - the memory). - -*/ - -typedef enum {CTYPE_VOID_POINTER = 1, - CTYPE_INT_VALUE = 2, - CTYPE_DOUBLE_VALUE = 3, - CTYPE_FLOAT_VALUE = 4 , - CTYPE_CHAR_VALUE = 5 , - CTYPE_BOOL_VALUE = 6 , - CTYPE_SIZE_T_VALUE = 7 , - CTYPE_INVALID = 100} node_ctype; - - -const char * node_ctype_name(node_ctype ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/node_ctype.hpp b/ThirdParty/Ert/lib/include/ert/util/node_ctype.hpp index 6618717f82..344a3aa0f3 100644 --- a/ThirdParty/Ert/lib/include/ert/util/node_ctype.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/node_ctype.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'node_ctype.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,42 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef NODE_CTYPE_CXX -#define NODE_CTYPE_CXX +#ifndef ERT_NODE_CTYPE_H +#define ERT_NODE_CTYPE_H +#ifdef __cplusplus +extern "C" { +#endif + -#include +/* + value : means a scalar which has been packed into the container + object. + pointer: means a (typed) pointer which points to a memory location + outside the container object (however the container can own + the memory). + +*/ + +typedef enum {CTYPE_VOID_POINTER = 1, + CTYPE_INT_VALUE = 2, + CTYPE_DOUBLE_VALUE = 3, + CTYPE_FLOAT_VALUE = 4 , + CTYPE_CHAR_VALUE = 5 , + CTYPE_BOOL_VALUE = 6 , + CTYPE_SIZE_T_VALUE = 7 , + CTYPE_INVALID = 100} node_ctype; + + +const char * node_ctype_name(node_ctype ); +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/node_data.h b/ThirdParty/Ert/lib/include/ert/util/node_data.h index a4ae13cbfe..03e1add257 100644 --- a/ThirdParty/Ert/lib/include/ert/util/node_data.h +++ b/ThirdParty/Ert/lib/include/ert/util/node_data.h @@ -1,59 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'node_data.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_NODE_DATA_H -#define ERT_NODE_DATA_H +#include -#include -#ifdef __cplusplus -extern "C" { -#endif - -typedef void * ( copyc_ftype ) (const void *); -typedef void ( free_ftype ) (void *); - - - -typedef struct node_data_struct node_data_type; - - -void node_data_free(node_data_type *); -void node_data_free_container(node_data_type * ); -node_data_type * node_data_alloc_deep_copy(const node_data_type * ); -node_data_type * node_data_alloc_shallow_copy(const node_data_type * ); -node_data_type * node_data_alloc_copy(const node_data_type * node , bool deep_copy); -void * node_data_get_ptr(const node_data_type *); -const void * node_data_get_const_ptr(const node_data_type *); -node_data_type * node_data_alloc_buffer(const void *, int ); -node_data_type * node_data_alloc_ptr(const void * , copyc_ftype * , free_ftype *); - -node_data_type * node_data_alloc_int(int ); -int node_data_get_int( const node_data_type * ); -int node_data_fetch_and_inc_int( node_data_type * node_data ); -node_data_type * node_data_alloc_double(double ); -double node_data_get_double( const node_data_type * ); -node_data_type * node_data_alloc_string(const char *); -char * node_data_get_string( const node_data_type * ); - - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/node_data.hpp b/ThirdParty/Ert/lib/include/ert/util/node_data.hpp index 91f5d8c634..4e572f1836 100644 --- a/ThirdParty/Ert/lib/include/ert/util/node_data.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/node_data.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'node_data.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,51 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef NODE_DATA_CXX -#define NODE_DATA_CXX +#ifndef ERT_NODE_DATA_H +#define ERT_NODE_DATA_H -#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef void * ( copyc_ftype ) (const void *); +typedef void ( free_ftype ) (void *); + + + +typedef struct node_data_struct node_data_type; + + +void node_data_free(node_data_type *); +void node_data_free_container(node_data_type * ); +node_data_type * node_data_alloc_deep_copy(const node_data_type * ); +node_data_type * node_data_alloc_shallow_copy(const node_data_type * ); +node_data_type * node_data_alloc_copy(const node_data_type * node , bool deep_copy); +void * node_data_get_ptr(const node_data_type *); +const void * node_data_get_const_ptr(const node_data_type *); +node_data_type * node_data_alloc_buffer(const void *, int ); +node_data_type * node_data_alloc_ptr(const void * , copyc_ftype * , free_ftype *); + +node_data_type * node_data_alloc_int(int ); +int node_data_get_int( const node_data_type * ); +int node_data_fetch_and_inc_int( node_data_type * node_data ); +node_data_type * node_data_alloc_double(double ); +double node_data_get_double( const node_data_type * ); +node_data_type * node_data_alloc_string(const char *); +char * node_data_get_string( const node_data_type * ); + + + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/parser.h b/ThirdParty/Ert/lib/include/ert/util/parser.h index 944f2a39ce..b81fc7ce9a 100644 --- a/ThirdParty/Ert/lib/include/ert/util/parser.h +++ b/ThirdParty/Ert/lib/include/ert/util/parser.h @@ -1,168 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'parser.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_PARSER_H -#define ERT_PARSER_H -#include +#include -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -typedef struct basic_parser_struct basic_parser_type; - - -/** - GENERAL OVERVIEW - - The parser_type is used to create a series of "tokens" - from a file or string buffer. In it's simplest form, - we define a token as a subset of a string separated by - by some split characters. - - For example, if we define the normal space (i.e. " ") as - the only split character, "tokenizing" the string - "I like beer " would give the following result: - - Token number 0 is "I" - Token number 1 is "like" - Token number 2 is "beer" - - Note that all the white space (i.e. split characters) have been - removed. - - - - COMMENTS - - The parser can ignore comments when tokenzing - a file or buffer. To enable this feature, allocate - the parser_type with comment_start and comment_end - different from NULL. For example if we set both - comment_start and comment_end to "##", tokenizing - "I ## really ## like beer" would give: - - Token number 0 is "I" - Token number 1 is "like" - Token number 2 is "beer" - - - - SPECIAL CHARACTERS - - Some times it can be useful to define a set of characters which - behave like white space in the sense that they separate tokens in - the source, but they do not get dropped. For example, letting "=" be - a special character, tokenzing "key=value" would give: - - Token number 0 is "key" - Token number 1 is "=" - Token number 2 is "value" - - The special characters are given in the "specials" string when - allocating the parser. - - - - QUOTERS - - When parsing user input, the user often wants to provide e.g. a - filename with a white-space character in it. To support this, the - parser can be given a set of quoters. For example, letting " " be - white space and adding "'" to the quoters, tokenizing - - "my_file = 'my documents with space in.txt'" - - would give: - - Token number 0 is "my_file" - Token number 1 is "=" - Token number 2 is "'my documents with space in.txt'" - - If wanted, the quoting characters can be removed - using the strip_quote_marks options when running - the parser on the buffer. The last token - in the example above would then be: - - Token number 2 is "my documents with space in.txt" - - To use one of the quoter characters in a string, - place a "\" in front of it. Building on our previous - example, let the string be "my_file = 'my \'doc.txt'" - Tokenzing this with strip_quote_marks set to true - would give: - - Token number 0 is "my_file" - Token number 1 is "=" - Token number 2 is "my 'doc.txt" - - Note that the "\" in front of"'" has been removed. - If strip_quote_marks is set to false, the result is: - - - Token number 0 is "my_file" - Token number 1 is "=" - Token number 2 is "'my \'doc.txt'" - -*/ - - -basic_parser_type * basic_parser_alloc( - const char * whitespace, /** Set to NULL if not interessting. */ - const char * quoters, /** Set to NULL if not interessting. */ - const char * specials, /** Set to NULL if not interessting. */ - const char * delete_set, - const char * comment_start, /** Set to NULL if not interessting. */ - const char * comment_end); /** Set to NULL if not interessting. */ - - -void basic_parser_set_splitters( basic_parser_type * parser , const char * splitters ); -void basic_parser_set_quoters( basic_parser_type * parser , const char * quoters ); -void basic_parser_set_specials( basic_parser_type * parser , const char * specials ); -void basic_parser_set_delete_set( basic_parser_type * parser , const char * delete_set ); -void basic_parser_set_comment_start( basic_parser_type * parser , const char * comment_start ); -void basic_parser_set_comment_end( basic_parser_type * parser , const char * comment_end ); - - -void basic_parser_free( - basic_parser_type * parser); - - -stringlist_type * basic_parser_tokenize_buffer( - const basic_parser_type * parser, - const char * buffer, - bool strip_quote_marks); - - -stringlist_type * basic_parser_tokenize_file( - const basic_parser_type * parser, - const char * filename, - bool strip_quote_marks); - - -/* Pollution by Joakim: */ - -void basic_parser_strip_buffer(const basic_parser_type * parser , char ** __buffer); -bool basic_parser_fseek_string(const basic_parser_type * parser , FILE * stream , const char * string , bool skip_string , bool case_sensitive); -char * basic_parser_fread_alloc_file_content(const char * filename , const char * quote_set , const char * delete_set , const char * comment_start , const char * comment_end); -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/parser.hpp b/ThirdParty/Ert/lib/include/ert/util/parser.hpp index 72e400d2d1..d00e311f0f 100644 --- a/ThirdParty/Ert/lib/include/ert/util/parser.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/parser.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'parser.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,160 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef PARSER_CXX -#define PARSER_CXX +#ifndef ERT_PARSER_H +#define ERT_PARSER_H +#include -#include +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +typedef struct basic_parser_struct basic_parser_type; + + +/** + GENERAL OVERVIEW + + The parser_type is used to create a series of "tokens" + from a file or string buffer. In it's simplest form, + we define a token as a subset of a string separated by + by some split characters. + + For example, if we define the normal space (i.e. " ") as + the only split character, "tokenizing" the string + "I like beer " would give the following result: + + Token number 0 is "I" + Token number 1 is "like" + Token number 2 is "beer" + + Note that all the white space (i.e. split characters) have been + removed. + + + + COMMENTS + + The parser can ignore comments when tokenzing + a file or buffer. To enable this feature, allocate + the parser_type with comment_start and comment_end + different from NULL. For example if we set both + comment_start and comment_end to "##", tokenizing + "I ## really ## like beer" would give: + + Token number 0 is "I" + Token number 1 is "like" + Token number 2 is "beer" + + + + SPECIAL CHARACTERS + + Some times it can be useful to define a set of characters which + behave like white space in the sense that they separate tokens in + the source, but they do not get dropped. For example, letting "=" be + a special character, tokenzing "key=value" would give: + + Token number 0 is "key" + Token number 1 is "=" + Token number 2 is "value" + + The special characters are given in the "specials" string when + allocating the parser. + + + + QUOTERS + + When parsing user input, the user often wants to provide e.g. a + filename with a white-space character in it. To support this, the + parser can be given a set of quoters. For example, letting " " be + white space and adding "'" to the quoters, tokenizing + + "my_file = 'my documents with space in.txt'" + + would give: + + Token number 0 is "my_file" + Token number 1 is "=" + Token number 2 is "'my documents with space in.txt'" + + If wanted, the quoting characters can be removed + using the strip_quote_marks options when running + the parser on the buffer. The last token + in the example above would then be: + + Token number 2 is "my documents with space in.txt" + + To use one of the quoter characters in a string, + place a "\" in front of it. Building on our previous + example, let the string be "my_file = 'my \'doc.txt'" + Tokenzing this with strip_quote_marks set to true + would give: + + Token number 0 is "my_file" + Token number 1 is "=" + Token number 2 is "my 'doc.txt" + + Note that the "\" in front of"'" has been removed. + If strip_quote_marks is set to false, the result is: + + + Token number 0 is "my_file" + Token number 1 is "=" + Token number 2 is "'my \'doc.txt'" + +*/ + + +basic_parser_type * basic_parser_alloc( + const char * whitespace, /** Set to NULL if not interessting. */ + const char * quoters, /** Set to NULL if not interessting. */ + const char * specials, /** Set to NULL if not interessting. */ + const char * delete_set, + const char * comment_start, /** Set to NULL if not interessting. */ + const char * comment_end); /** Set to NULL if not interessting. */ + + +void basic_parser_set_splitters( basic_parser_type * parser , const char * splitters ); +void basic_parser_set_quoters( basic_parser_type * parser , const char * quoters ); +void basic_parser_set_specials( basic_parser_type * parser , const char * specials ); +void basic_parser_set_delete_set( basic_parser_type * parser , const char * delete_set ); +void basic_parser_set_comment_start( basic_parser_type * parser , const char * comment_start ); +void basic_parser_set_comment_end( basic_parser_type * parser , const char * comment_end ); + + +void basic_parser_free( + basic_parser_type * parser); + + +stringlist_type * basic_parser_tokenize_buffer( + const basic_parser_type * parser, + const char * buffer, + bool strip_quote_marks); + + +stringlist_type * basic_parser_tokenize_file( + const basic_parser_type * parser, + const char * filename, + bool strip_quote_marks); + + +/* Pollution by Joakim: */ + +void basic_parser_strip_buffer(const basic_parser_type * parser , char ** __buffer); +bool basic_parser_fseek_string(const basic_parser_type * parser , FILE * stream , const char * string , bool skip_string , bool case_sensitive); +char * basic_parser_fread_alloc_file_content(const char * filename , const char * quote_set , const char * delete_set , const char * comment_start , const char * comment_end); +#ifdef __cplusplus +} +#endif // __cplusplus #endif + diff --git a/ThirdParty/Ert/lib/include/ert/util/path_stack.h b/ThirdParty/Ert/lib/include/ert/util/path_stack.h index a5e964ec66..05b9f5cb96 100644 --- a/ThirdParty/Ert/lib/include/ert/util/path_stack.h +++ b/ThirdParty/Ert/lib/include/ert/util/path_stack.h @@ -1,42 +1,9 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'path_stack.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_PATH_STACK_H -#define ERT_PATH_STACK_H -#ifdef __cplusplus -extern "C" { -#endif - - typedef struct path_stack_struct path_stack_type; - - path_stack_type * path_stack_alloc(); - const char * path_stack_pop( path_stack_type * path_stack ); - void path_stack_push_cwd( path_stack_type * path_stack ); - bool path_stack_push( path_stack_type * path_stack , const char * path ); - void path_stack_free( path_stack_type * path_stack ); - int path_stack_size( const path_stack_type * path_stack ); - const char * path_stack_peek( const path_stack_type * path_stack ); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/path_stack.hpp b/ThirdParty/Ert/lib/include/ert/util/path_stack.hpp index 2dbea35ffd..7da9f9fc27 100644 --- a/ThirdParty/Ert/lib/include/ert/util/path_stack.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/path_stack.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2012 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'path_stack.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,33 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef PATH_STACK_CXX -#define PATH_STACK_CXX -#include +#ifndef ERT_PATH_STACK_H +#define ERT_PATH_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct path_stack_struct path_stack_type; + + path_stack_type * path_stack_alloc(); + void path_stack_pop( path_stack_type * path_stack ); + void path_stack_push_cwd( path_stack_type * path_stack ); + bool path_stack_push( path_stack_type * path_stack , const char * path ); + void path_stack_free( path_stack_type * path_stack ); + int path_stack_size( const path_stack_type * path_stack ); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/perm_vector.h b/ThirdParty/Ert/lib/include/ert/util/perm_vector.h index 87dab4ddd4..00ed33ccbc 100644 --- a/ThirdParty/Ert/lib/include/ert/util/perm_vector.h +++ b/ThirdParty/Ert/lib/include/ert/util/perm_vector.h @@ -1,40 +1,9 @@ /* - Copyright (C) 2016 Statoil ASA, Norway. - - The file 'perm_vector.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef PERM_VECTOR_H -#define PERM_VECTOR_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -typedef struct perm_vector_struct perm_vector_type; - -perm_vector_type * perm_vector_alloc( int * perm_input , int size ); -void perm_vector_free( perm_vector_type * perm_vector ); -int perm_vector_get_size( const perm_vector_type * perm); -int perm_vector_iget( const perm_vector_type * perm, int index); - -#ifdef __cplusplus -} -#endif //__cplusplus +#include -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/perm_vector.hpp b/ThirdParty/Ert/lib/include/ert/util/perm_vector.hpp index 53758b9ea9..60662c2e9b 100644 --- a/ThirdParty/Ert/lib/include/ert/util/perm_vector.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/perm_vector.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2016 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'perm_vector.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,32 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef PERM_VECTOR_CXX -#define PERM_VECTOR_CXX +#ifndef PERM_VECTOR_H +#define PERM_VECTOR_H -#include +#include + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +typedef struct perm_vector_struct perm_vector_type; + +perm_vector_type * perm_vector_alloc( int * perm_input , int size ); +void perm_vector_free( perm_vector_type * perm_vector ); +int perm_vector_get_size( const perm_vector_type * perm); +int perm_vector_iget( const perm_vector_type * perm, int index); + +#ifdef __cplusplus +} +#endif //__cplusplus #endif + diff --git a/ThirdParty/Ert/lib/include/ert/util/rng.h b/ThirdParty/Ert/lib/include/ert/util/rng.h index 8d5a73b2c4..e6044ffe8c 100644 --- a/ThirdParty/Ert/lib/include/ert/util/rng.h +++ b/ThirdParty/Ert/lib/include/ert/util/rng.h @@ -1,85 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'rng.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_RNG_H -#define ERT_RNG_H - -#ifdef __cplusplus -extern "C" { -#endif -#include - -#include - - -typedef enum { - INIT_DEFAULT = 0, /* The rng is initialized with the default seed values. */ - INIT_CLOCK = 1, /* Four random seeds are calculated with the util_clock_seed() function. */ - INIT_DEV_RANDOM = 2, /* Random content is read with the function util_fread_dev_random(). */ - INIT_DEV_URANDOM = 3 /* Random content is read with the function util_fread_dev_urandom(). */ -} rng_init_mode; - - -typedef enum { - MZRAN = 1 -} rng_alg_type; - - - typedef unsigned int ( rng_forward_ftype ) ( void * ); - typedef void ( rng_set_state_ftype ) ( void * , const char * ); - typedef void ( rng_get_state_ftype ) ( void * , char * ); - typedef void * ( rng_alloc_ftype ) ( void ); - typedef void ( rng_free_ftype ) ( void * ); - typedef void ( rng_fscanf_ftype ) ( void * , FILE * ); - typedef void ( rng_fprintf_ftype ) ( const void * , FILE * ); - - typedef struct rng_struct rng_type; - - rng_type * rng_alloc( rng_alg_type type , rng_init_mode init_mode ); - void rng_free( rng_type * rng); - void rng_free( rng_type * rng); - unsigned int rng_forward( rng_type * rng ); - double rng_get_double( rng_type * rng); - void rng_rng_init( rng_type * rng , rng_type * seed_src); - void rng_init( rng_type * rng , rng_init_mode init_mode ); - rng_alg_type rng_get_type( const rng_type * rng ); - void rng_fprintf_state( rng_type * rng , FILE * stream ); - void rng_fscanf_state( rng_type * rng , FILE * stream ); - int rng_state_size( const rng_type * rng ); - void rng_save_state( rng_type * rng , const char * filename); - void rng_load_state( rng_type * rng , const char * filename); - - void rng_set_state( rng_type * rng , const char * state); - void rng_get_state( const rng_type * rng , char * state); - - unsigned int rng_forward( rng_type * rng ); - double rng_get_double( rng_type * rng ); - int rng_get_int( rng_type * rng , int max_value ); - unsigned int rng_get_max_int(const rng_type * rng); - - double rng_std_normal( rng_type * rng ); - void rng_shuffle_int( rng_type * rng , int * data , size_t num_elements); - void rng_shuffle( rng_type * rng , char * data , size_t element_size , size_t num_elements); - void rng_free__( void * arg); +#include - UTIL_SAFE_CAST_HEADER( rng ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/rng.hpp b/ThirdParty/Ert/lib/include/ert/util/rng.hpp index d75be17013..2964296877 100644 --- a/ThirdParty/Ert/lib/include/ert/util/rng.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/rng.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'rng.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,77 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef RNG_CXX -#define RNG_CXX +#ifndef ERT_RNG_H +#define ERT_RNG_H -#include +#ifdef __cplusplus +extern "C" { +#endif +#include + +#include + + +typedef enum { + INIT_DEFAULT = 0, /* The rng is initialized with the default seed values. */ + INIT_CLOCK = 1, /* Four random seeds are calculated with the util_clock_seed() function. */ + INIT_DEV_RANDOM = 2, /* Random content is read with the function util_fread_dev_random(). */ + INIT_DEV_URANDOM = 3 /* Random content is read with the function util_fread_dev_urandom(). */ +} rng_init_mode; + + +typedef enum { + MZRAN = 1 +} rng_alg_type; + + + typedef unsigned int ( rng_forward_ftype ) ( void * ); + typedef void ( rng_set_state_ftype ) ( void * , const char * ); + typedef void ( rng_get_state_ftype ) ( void * , char * ); + typedef void * ( rng_alloc_ftype ) ( void ); + typedef void ( rng_free_ftype ) ( void * ); + typedef void ( rng_fscanf_ftype ) ( void * , FILE * ); + typedef void ( rng_fprintf_ftype ) ( const void * , FILE * ); + typedef struct rng_struct rng_type; + + rng_type * rng_alloc( rng_alg_type type , rng_init_mode init_mode ); + void rng_free( rng_type * rng); + void rng_free( rng_type * rng); + unsigned int rng_forward( rng_type * rng ); + double rng_get_double( rng_type * rng); + void rng_rng_init( rng_type * rng , rng_type * seed_src); + void rng_init( rng_type * rng , rng_init_mode init_mode ); + rng_alg_type rng_get_type( const rng_type * rng ); + void rng_fprintf_state( rng_type * rng , FILE * stream ); + void rng_fscanf_state( rng_type * rng , FILE * stream ); + int rng_state_size( const rng_type * rng ); + void rng_save_state( rng_type * rng , const char * filename); + void rng_load_state( rng_type * rng , const char * filename); + + void rng_set_state( rng_type * rng , const char * state); + void rng_get_state( const rng_type * rng , char * state); + + unsigned int rng_forward( rng_type * rng ); + double rng_get_double( rng_type * rng ); + int rng_get_int( rng_type * rng , int max_value ); + unsigned int rng_get_max_int(const rng_type * rng); + + double rng_std_normal( rng_type * rng ); + void rng_shuffle_int( rng_type * rng , int * data , size_t num_elements); + void rng_shuffle( rng_type * rng , char * data , size_t element_size , size_t num_elements); + void rng_free__( void * arg); + + UTIL_SAFE_CAST_HEADER( rng ); + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/set.h b/ThirdParty/Ert/lib/include/ert/util/set.h deleted file mode 100644 index 6c2a7a4abb..0000000000 --- a/ThirdParty/Ert/lib/include/ert/util/set.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'set.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ERT_SET_H -#define ERT_SET_H -#ifdef __cplusplus -extern "C" { -#endif -#include -#include -#include - - -typedef struct set_struct set_type; -typedef struct set_iter_struct set_iter_type; - -void set_clear( set_type * set ); -void set_remove_key(set_type * , const char * ); -set_type * set_alloc(int , const char ** ); -set_type * set_alloc_empty(); -bool set_add_key(set_type * , const char * ); -bool set_has_key(const set_type * set, const char * ); -void set_free(set_type * ); -void set_free__(void * ); -int set_get_size(const set_type *); -char ** set_alloc_keylist(const set_type * ); -void set_fwrite(const set_type * , FILE * ); -void set_fread(set_type * , FILE * ); -set_type * set_fread_alloc(FILE *); -void set_fprintf(const set_type * , const char * sep , FILE * ); -void set_intersect(set_type * , const set_type * ); -void set_union(set_type * , const set_type * ); -void set_minus(set_type * , const set_type * ); -set_type * set_copyc(const set_type *); - - -set_iter_type * set_iter_alloc(const set_type * set); -void set_iter_free(set_iter_type * set_iter); -bool set_iter_is_complete(const set_iter_type * set_iter); -const char * set_iter_get_next_key(set_iter_type * set_iter); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/set.hpp b/ThirdParty/Ert/lib/include/ert/util/set.hpp deleted file mode 100644 index 4a5936ab31..0000000000 --- a/ThirdParty/Ert/lib/include/ert/util/set.hpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (C) 2018 Statoil ASA, Norway. - - This is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef SET_CXX -#define SET_CXX - -#include - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/ssize_t.h b/ThirdParty/Ert/lib/include/ert/util/ssize_t.h index 3a1d524555..4aff372c76 100644 --- a/ThirdParty/Ert/lib/include/ert/util/ssize_t.h +++ b/ThirdParty/Ert/lib/include/ert/util/ssize_t.h @@ -1,34 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'ssize_t.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_SSIZE_T_H -#define ERT_SSIZE_T_H +#include -#ifdef _MSC_VER -/* maximum number of bytes addressable */ -#ifdef _WIN64 -typedef __int64 ssize_t; -#else -typedef long ssize_t; -#endif -#else -/* POSIX 2008 states that it should be defined here */ -#include -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/ssize_t.hpp b/ThirdParty/Ert/lib/include/ert/util/ssize_t.hpp index df855a99cc..10507fa5d9 100644 --- a/ThirdParty/Ert/lib/include/ert/util/ssize_t.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/ssize_t.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'ssize_t.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,26 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef SSIZE_T_CXX -#define SSIZE_T_CXX +#ifndef ERT_SSIZE_T_H +#define ERT_SSIZE_T_H -#include +#ifdef _MSC_VER +/* maximum number of bytes addressable */ +#ifdef _WIN64 +typedef __int64 ssize_t; +#else +typedef long ssize_t; +#endif +#else +/* POSIX 2008 states that it should be defined here */ +#include +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/statistics.h b/ThirdParty/Ert/lib/include/ert/util/statistics.h index b910e31fb3..3b0e33a8d9 100644 --- a/ThirdParty/Ert/lib/include/ert/util/statistics.h +++ b/ThirdParty/Ert/lib/include/ert/util/statistics.h @@ -1,35 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'statistics.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_STATISTICS_H -#define ERT_STATISTICS_H +#include -#ifdef __cplusplus -extern "C" { -#endif -#include -double statistics_std( const double_vector_type * data_vector ); -double statistics_mean( const double_vector_type * data_vector ); -double statistics_empirical_quantile( double_vector_type * data , double quantile ); -double statistics_empirical_quantile__( const double_vector_type * data , double quantile ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/statistics.hpp b/ThirdParty/Ert/lib/include/ert/util/statistics.hpp index 2d1fe6f10a..5a14bb390a 100644 --- a/ThirdParty/Ert/lib/include/ert/util/statistics.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/statistics.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'statistics.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,27 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef STATISTICS_CXX -#define STATISTICS_CXX +#ifndef ERT_STATISTICS_H +#define ERT_STATISTICS_H -#include +#ifdef __cplusplus +extern "C" { +#endif +#include + +double statistics_std( const double_vector_type * data_vector ); +double statistics_mean( const double_vector_type * data_vector ); +double statistics_empirical_quantile( double_vector_type * data , double quantile ); +double statistics_empirical_quantile__( const double_vector_type * data , double quantile ); +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/string_util.h b/ThirdParty/Ert/lib/include/ert/util/string_util.h index 6d5a7c26d4..52c76ea478 100644 --- a/ThirdParty/Ert/lib/include/ert/util/string_util.h +++ b/ThirdParty/Ert/lib/include/ert/util/string_util.h @@ -1,43 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'string_util.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_STRING_UTIL_H -#define ERT_STRING_UTIL_H -#include -#include +#include -#ifdef __cplusplus -extern "C" { -#endif - bool string_util_init_active_list( const char * range_string , int_vector_type * active_list ); - bool string_util_update_active_list( const char * range_string , int_vector_type * active_list ); - int_vector_type * string_util_alloc_active_list( const char * range_string ); - - bool string_util_init_active_mask( const char * range_string , bool_vector_type * active_mask); - bool string_util_update_active_mask( const char * range_string , bool_vector_type * active_mask); - bool_vector_type * string_util_alloc_active_mask( const char * range_string ); - - bool string_util_update_value_list( const char * range_string , int_vector_type * value_list); - bool string_util_init_value_list( const char * range_string , int_vector_type * value_list ); - int_vector_type * string_util_alloc_value_list(const char * range_string); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/string_util.hpp b/ThirdParty/Ert/lib/include/ert/util/string_util.hpp index 4cfb76138f..dc43464a76 100644 --- a/ThirdParty/Ert/lib/include/ert/util/string_util.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/string_util.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2013 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'string_util.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,35 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ +#ifndef ERT_STRING_UTIL_H +#define ERT_STRING_UTIL_H -#ifndef STRING_UTIL_CXX -#define STRING_UTIL_CXX +#include +#include -#include +#ifdef __cplusplus +extern "C" { +#endif + + bool string_util_init_active_list( const char * range_string , int_vector_type * active_list ); + bool string_util_update_active_list( const char * range_string , int_vector_type * active_list ); + int_vector_type * string_util_alloc_active_list( const char * range_string ); + + bool string_util_init_active_mask( const char * range_string , bool_vector_type * active_mask); + bool string_util_update_active_mask( const char * range_string , bool_vector_type * active_mask); + bool_vector_type * string_util_alloc_active_mask( const char * range_string ); + bool string_util_update_value_list( const char * range_string , int_vector_type * value_list); + bool string_util_init_value_list( const char * range_string , int_vector_type * value_list ); + int_vector_type * string_util_alloc_value_list(const char * range_string); + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/stringlist.h b/ThirdParty/Ert/lib/include/ert/util/stringlist.h index 85f6e130cf..0a423ae834 100644 --- a/ThirdParty/Ert/lib/include/ert/util/stringlist.h +++ b/ThirdParty/Ert/lib/include/ert/util/stringlist.h @@ -1,123 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'stringlist.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_STRINGLIST_H -#define ERT_STRINGLIST_H - -#include -#include - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct stringlist_struct stringlist_type; -typedef int ( string_cmp_ftype) (const void * , const void *); -typedef bool ( file_pred_ftype) (const char *, const void *); - - int stringlist_select_files(stringlist_type * names, const char * path, file_pred_ftype * predicate, const void * pred_arg); - - const char * stringlist_get_last( const stringlist_type * stringlist ); - char * stringlist_pop( stringlist_type * stringlist); - void stringlist_deep_copy( stringlist_type * target , const stringlist_type * src); - stringlist_type * stringlist_alloc_deep_copy_with_limits(const stringlist_type * src , int offset, int num_strings); - stringlist_type * stringlist_alloc_deep_copy_with_offset(const stringlist_type * src , int offset); - stringlist_type * stringlist_alloc_deep_copy( const stringlist_type * src ); - - stringlist_type * stringlist_alloc_new(void); - void stringlist_free__(void * ); - void stringlist_free(stringlist_type *); - void stringlist_clear(stringlist_type * ); - - void stringlist_append_copy(stringlist_type * , const char *); - void stringlist_append_ref(stringlist_type * , const char *); - void stringlist_append_owned_ref(stringlist_type * , const char *); - - const char * stringlist_safe_iget( const stringlist_type * stringlist , int index); - bool stringlist_unique(const stringlist_type * stringlist ); - bool stringlist_iequal( const stringlist_type * stringlist , int index, const char * s ); - const char * stringlist_iget(const stringlist_type * , int); - int stringlist_iget_as_int( const stringlist_type * stringlist , int index , bool * valid); - double stringlist_iget_as_double( const stringlist_type * stringlist , int index , bool * valid); - bool stringlist_iget_as_bool( const stringlist_type * stringlist, int index, bool * valid); - char * stringlist_iget_copy(const stringlist_type * stringlist , int ); - char * stringlist_alloc_joined_string(const stringlist_type * , const char * ); - char * stringlist_alloc_joined_substring( const stringlist_type * s , int start_index , int end_index , const char * sep ); - const char * stringlist_front(const stringlist_type * stringlist); - const char * stringlist_back(const stringlist_type * stringlist); - - - - void stringlist_iset_copy(stringlist_type *, int index , const char *); - void stringlist_iset_ref(stringlist_type *, int index , const char *); - void stringlist_iset_owned_ref(stringlist_type *, int index , const char *); - - void stringlist_insert_copy(stringlist_type *, int index , const char *); - void stringlist_insert_ref(stringlist_type *, int index , const char *); - void stringlist_insert_owned_ref(stringlist_type *, int index , const char *); - - void stringlist_idel(stringlist_type * stringlist , int index); - - int stringlist_get_size(const stringlist_type * ); - void stringlist_fprintf(const stringlist_type * , const char * , FILE *); - void stringlist_fprintf_fmt(const stringlist_type * stringlist, const stringlist_type * fmt_list , FILE * stream); - - - stringlist_type * stringlist_alloc_argv_copy(const char ** , int ); - stringlist_type * stringlist_alloc_argv_ref (const char ** , int ); - stringlist_type * stringlist_alloc_argv_owned_ref(const char ** argv , int argc); - stringlist_type * stringlist_alloc_shallow_copy(const stringlist_type *); - stringlist_type * stringlist_alloc_shallow_copy_with_offset(const stringlist_type * stringlist, int offset); - stringlist_type * stringlist_alloc_shallow_copy_with_limits(const stringlist_type * stringlist, int offset , int num_strings); - stringlist_type * stringlist_alloc_from_split( const char * input_string , const char * sep ); - stringlist_type * stringlist_fread_alloc(FILE * ); - - void stringlist_append_stringlist_copy(stringlist_type * , const stringlist_type * ); - void stringlist_append_stringlist_ref(stringlist_type * , const stringlist_type * ); - void stringlist_insert_stringlist_copy(stringlist_type * , const stringlist_type *, int); - - bool stringlist_equal(const stringlist_type * , const stringlist_type *); - bool stringlist_contains(const stringlist_type * , const char * ); - int_vector_type * stringlist_find(const stringlist_type *, const char *); - int stringlist_find_first(const stringlist_type * , const char * ); - int stringlist_get_argc(const stringlist_type * ); - char ** stringlist_alloc_char_copy(const stringlist_type * ); - char ** stringlist_alloc_char_ref(const stringlist_type * stringlist); - void stringlist_fread(stringlist_type * , FILE * ); - void stringlist_fwrite(const stringlist_type * , FILE * ); - void stringlist_sort(stringlist_type * , string_cmp_ftype * string_cmp); - void stringlist_reverse( stringlist_type * s ); - void stringlist_python_sort( stringlist_type * s , int cmp_flag); +#include -#ifdef ERT_HAVE_GLOB - int stringlist_select_matching(stringlist_type * names , const char * pattern); -#endif - int stringlist_select_matching_files(stringlist_type * names , const char * path , const char * file_pattern); - int stringlist_select_matching_elements(stringlist_type * target , const stringlist_type * src , const char * pattern); - int stringlist_append_matching_elements(stringlist_type * target , const stringlist_type * src , const char * pattern); - UTIL_IS_INSTANCE_HEADER(stringlist); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/stringlist.hpp b/ThirdParty/Ert/lib/include/ert/util/stringlist.hpp index ea149225dc..8e8176739d 100644 --- a/ThirdParty/Ert/lib/include/ert/util/stringlist.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/stringlist.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'stringlist.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,109 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef STRINGLIST_CXX -#define STRINGLIST_CXX +#ifndef ERT_STRINGLIST_H +#define ERT_STRINGLIST_H -#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct stringlist_struct stringlist_type; +typedef int ( string_cmp_ftype) (const void * , const void *); +typedef bool ( file_pred_ftype) (const char *, const void *); + + int stringlist_select_files(stringlist_type * names, const char * path, file_pred_ftype * predicate, const void * pred_arg); + + const char * stringlist_get_last( const stringlist_type * stringlist ); + char * stringlist_pop( stringlist_type * stringlist); + void stringlist_deep_copy( stringlist_type * target , const stringlist_type * src); + stringlist_type * stringlist_alloc_deep_copy_with_limits(const stringlist_type * src , int offset, int num_strings); + stringlist_type * stringlist_alloc_deep_copy_with_offset(const stringlist_type * src , int offset); + stringlist_type * stringlist_alloc_deep_copy( const stringlist_type * src ); + + stringlist_type * stringlist_alloc_new(void); + void stringlist_free__(void * ); + void stringlist_free(stringlist_type *); + void stringlist_clear(stringlist_type * ); + + void stringlist_append_copy(stringlist_type * , const char *); + + const char * stringlist_safe_iget( const stringlist_type * stringlist , int index); + bool stringlist_unique(const stringlist_type * stringlist ); + bool stringlist_iequal( const stringlist_type * stringlist , int index, const char * s ); + const char * stringlist_iget(const stringlist_type * , int); + int stringlist_iget_as_int( const stringlist_type * stringlist , int index , bool * valid); + double stringlist_iget_as_double( const stringlist_type * stringlist , int index , bool * valid); + bool stringlist_iget_as_bool( const stringlist_type * stringlist, int index, bool * valid); + char * stringlist_iget_copy(const stringlist_type * stringlist , int ); + char * stringlist_alloc_joined_string(const stringlist_type * , const char * ); + char * stringlist_alloc_joined_substring( const stringlist_type * s , int start_index , int end_index , const char * sep ); + const char * stringlist_front(const stringlist_type * stringlist); + const char * stringlist_back(const stringlist_type * stringlist); + + + + void stringlist_iset_copy(stringlist_type *, int index , const char *); + void stringlist_iset_ref(stringlist_type *, int index , const char *); + void stringlist_iset_owned_ref(stringlist_type *, int index , const char *); + + void stringlist_insert_copy(stringlist_type *, int index , const char *); + void stringlist_insert_ref(stringlist_type *, int index , const char *); + void stringlist_insert_owned_ref(stringlist_type *, int index , const char *); + + void stringlist_idel(stringlist_type * stringlist , int index); + + int stringlist_get_size(const stringlist_type * ); + void stringlist_fprintf(const stringlist_type * , const char * , FILE *); + void stringlist_fprintf_fmt(const stringlist_type * stringlist, const stringlist_type * fmt_list , FILE * stream); + + + stringlist_type * stringlist_alloc_argv_copy(const char ** , int ); + stringlist_type * stringlist_alloc_argv_ref (const char ** , int ); + stringlist_type * stringlist_alloc_argv_owned_ref(const char ** argv , int argc); + stringlist_type * stringlist_alloc_from_split( const char * input_string , const char * sep ); + stringlist_type * stringlist_fread_alloc(FILE * ); + + void stringlist_append_stringlist_copy(stringlist_type * , const stringlist_type * ); + void stringlist_insert_stringlist_copy(stringlist_type * , const stringlist_type *, int); + + bool stringlist_equal(const stringlist_type * , const stringlist_type *); + bool stringlist_contains(const stringlist_type * , const char * ); + int_vector_type * stringlist_find(const stringlist_type *, const char *); + int stringlist_find_first(const stringlist_type * , const char * ); + int stringlist_get_argc(const stringlist_type * ); + char ** stringlist_alloc_char_copy(const stringlist_type * ); + char ** stringlist_alloc_char_ref(const stringlist_type * stringlist); + void stringlist_fread(stringlist_type * , FILE * ); + void stringlist_fwrite(const stringlist_type * , FILE * ); + void stringlist_sort(stringlist_type * , string_cmp_ftype * string_cmp); + void stringlist_reverse( stringlist_type * s ); + void stringlist_python_sort( stringlist_type * s , int cmp_flag); + +#ifdef ERT_HAVE_GLOB + int stringlist_select_matching(stringlist_type * names , const char * pattern); +#endif + int stringlist_select_matching_files(stringlist_type * names , const char * path , const char * file_pattern); + int stringlist_select_matching_elements(stringlist_type * target , const stringlist_type * src , const char * pattern); + int stringlist_append_matching_elements(stringlist_type * target , const stringlist_type * src , const char * pattern); + UTIL_IS_INSTANCE_HEADER(stringlist); + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/struct_vector.h b/ThirdParty/Ert/lib/include/ert/util/struct_vector.h deleted file mode 100644 index 79f56ffe18..0000000000 --- a/ThirdParty/Ert/lib/include/ert/util/struct_vector.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'struct_vector.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef ERT_STRUCT_VECTOR_H -#define ERT_STRUCT_VECTOR_H - -#ifdef __cplusplus -extern "C" { -#endif -#include - - -typedef struct struct_vector_struct struct_vector_type; -typedef int ( struct_vector_cmp_ftype ) (const void * , const void *); - - struct_vector_type * struct_vector_alloc( int element_size ); - void struct_vector_free( struct_vector_type * struct_vector ); - int struct_vector_get_size( const struct_vector_type * struct_vector ); - void struct_vector_append( struct_vector_type * struct_vector , void * value); - void struct_vector_iget( const struct_vector_type * struct_vector , int index , void * value); - void * struct_vector_iget_ptr( const struct_vector_type * struct_vector , int index); - void struct_vector_reset( struct_vector_type * struct_vector ); - void struct_vector_reserve( struct_vector_type * struct_vector , int reserve_size); - void * struct_vector_get_data( const struct_vector_type * struct_vector ); - void struct_vector_sort( struct_vector_type * struct_vector , struct_vector_cmp_ftype * cmp); - - UTIL_IS_INSTANCE_HEADER( struct_vector ); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/struct_vector.hpp b/ThirdParty/Ert/lib/include/ert/util/struct_vector.hpp deleted file mode 100644 index d91ac14230..0000000000 --- a/ThirdParty/Ert/lib/include/ert/util/struct_vector.hpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - Copyright (C) 2018 Statoil ASA, Norway. - - This is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#ifndef STRUCT_VECTOR_CXX -#define STRUCT_VECTOR_CXX - -#include - -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/test_util.h b/ThirdParty/Ert/lib/include/ert/util/test_util.h index b1326deeef..29fc1315ec 100644 --- a/ThirdParty/Ert/lib/include/ert/util/test_util.h +++ b/ThirdParty/Ert/lib/include/ert/util/test_util.h @@ -1,137 +1,9 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'test_util.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ - -#ifndef ERT_TEST_UTIL_H -#define ERT_TEST_UTIL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include - -#if defined(__APPLE__) -#include -#include -#endif - - - void test_error_exit( const char * fmt , ...); - void * test_argpack_is_stringlist( void * arg ); - void * thread_pool_test_func1( void * arg ); - -#define test_exit( fmt, ...) test_exit__( __FILE__ , __LINE__ , fmt , __VA_ARGS__); - void test_exit__(const char * file , int line , const char * fmt , ...); - -#define test_assert_string_equal( s1 , s2 ) test_assert_string_equal__(s1 , s2 , __FILE__ , __LINE__) - void test_assert_string_equal__( const char * s1 , const char * s2 , const char * file , int line); -#define test_assert_string_not_equal( s1 , s2 ) test_assert_string_not_equal__(s1 , s2 , __FILE__ , __LINE__) - void test_assert_string_not_equal__( const char * s1 , const char * s2 , const char * file , int line); - - bool test_check_string_equal( const char *s1 , const char * s2); - -#define test_assert_int_equal( i1 , i2 ) test_assert_int_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) - void test_assert_int_equal__( int i1 , int i2 , const char * file , int line ); - -#define test_assert_int_not_equal( i1 , i2 ) test_assert_int_not_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) - void test_assert_int_not_equal__( int i1 , int i2 , const char * file , int line ); - -#define test_assert_long_equal( i1 , i2 ) test_assert_long_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) - void test_assert_long_equal__( long i1 , long i2 , const char * file , long line ); - -#define test_assert_long_not_equal( i1 , i2 ) test_assert_long_not_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) - void test_assert_long_not_equal__( long i1 , long i2 , const char * file , long line ); - -#define test_assert_uint_equal( i1 , i2 ) test_assert_uint_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) - void test_assert_uint_equal__( unsigned int i1 , unsigned int i2 , const char * file , int line ); - -#define test_assert_uint_not_equal( i1 , i2 ) test_assert_uint_not_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) - void test_assert_uint_not_equal__( unsigned int i1 , unsigned int i2 , const char * file , int line ); - -#define test_assert_size_t_equal( s1 , s2 ) test_assert_size_t_equal__( (s1) , (s2) , __FILE__ , __LINE__ ) - void test_assert_size_t_equal__( size_t s1 , size_t s2 , const char * file , int line ); - -#define test_assert_size_t_not_equal( s1 , s2 ) test_assert_size_t_not_equal__( (s1) , (s2) , __FILE__ , __LINE__ ) - void test_assert_size_t_not_equal__( size_t s1 , size_t s2 , const char * file , int line ); - - -#define test_assert_double_equal( d1 , d2 ) test_assert_double_equal__( (d1) , (d2) , __FILE__ , __LINE__ ) - void test_assert_double_equal__( double d1 , double d2 , const char * file , int line ); - bool test_check_double_equal( double d1 , double d2); - -#define test_assert_float_equal( d1 , d2 ) test_assert_float_equal__( (d1) , (d2) , __FILE__ , __LINE__ ) - void test_assert_float_equal__( float d1 , float d2 , const char * file , int line ); - bool test_check_float_equal( float d1 , float d2); - -#define test_assert_double_not_equal( d1 , d2 ) test_assert_double_not_equal__( (d1) , (d2) , __FILE__ , __LINE__ ) - void test_assert_double_not_equal__( double d1 , double d2 , const char * file , int line ); - -#define test_assert_bool_equal( b1 , b2 ) test_assert_bool_equal__( (b1) , (b2) , __FILE__ , __LINE__ ) - void test_assert_bool_equal__( bool b1 , bool b2 , const char * file , int line); - -#define test_assert_bool_not_equal( b1 , b2 ) test_assert_bool_not_equal__( (b1) , (b2) , __FILE__ , __LINE__ ) - void test_assert_bool_not_equal__( bool b1 , bool b2 , const char * file , int line); - -#define test_assert_true( value ) test_assert_true__( (value) , __FILE__ , __LINE__) - void test_assert_true__( bool value, const char * file , int line); - -#define test_assert_false( value ) test_assert_false__( (value) , __FILE__ , __LINE__) - void test_assert_false__( bool value, const char * file , int line); - -#define test_assert_time_t_equal( t1 , t2) test_assert_time_t_equal__((t1) , (t2) , __FILE__ , __LINE__) - void test_assert_time_t_equal__( time_t t1 , time_t t2 , const char * file , int line); - -#define test_assert_time_t_not_equal( t1 , t2) test_assert_time_t_not_equal__((t1) , (t2) , __FILE__ , __LINE__) - void test_assert_time_t_not_equal__( time_t t1 , time_t t2 , const char * file , int line); - -#define test_assert_ptr_equal( p1 , p2 ) test_assert_ptr_equal__( (p1) , (p2) , __FILE__ , __LINE__) - void test_assert_ptr_equal__( const void * p1 , const void * p2 , const char * file , int line); - -#define test_assert_ptr_not_equal(p1 , p2) test_assert_ptr_not_equal__( (p1) , (p2) , __FILE__ , __LINE__) - void test_assert_ptr_not_equal__( const void * p1 , const void * p2 , const char * file , int line); - -#define test_assert_NULL( p ) test_assert_NULL__( (p) , __FILE__ , __LINE__) - void test_assert_NULL__( const void * p , const char * file , int line); - -#define test_assert_not_NULL( p ) test_assert_not_NULL__( (p) , __FILE__ , __LINE__) - void test_assert_not_NULL__( const void * p , const char * file , int line); - -#define test_assert_mem_equal( p1 , p2 , byte_size ) test_assert_mem_equal__( (p1) , (p2) , (byte_size), __FILE__ , __LINE__) - void test_assert_mem_equal__( const void * p1 , const void * p2 , size_t byte_size , const char * file , int line); - -#define test_assert_mem_not_equal( p1 , p2 , byte_size ) test_assert_mem_not_equal__( (p1) , (p2) , (byte_size), __FILE__ , __LINE__) - void test_assert_mem_not_equal__( const void * p1 , const void * p2 , size_t byte_size , const char * file , int line); - -#define test_assert_file_content( input_file , expected) test_assert_file_content__( input_file , expected , __FILE__ , __LINE__) - void test_assert_file_content__( const char * input_file , const char * expected, const char * src_file , int line); - - void test_install_SIGNALS(void); - - jmp_buf * util_abort_test_jump_buffer(); - void test_util_addr2line(); - void test_assert_util_abort(const char * function_name , void call_func (void *) , void * arg); +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/test_util.hpp b/ThirdParty/Ert/lib/include/ert/util/test_util.hpp index 0800221ee7..0e3087681d 100644 --- a/ThirdParty/Ert/lib/include/ert/util/test_util.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/test_util.hpp @@ -17,31 +17,149 @@ */ -#ifndef __TEST_UTIL_HPP__ -#define __TEST_UTIL_HPP__ - -#include - -#define test_assert_throw(expr , exception_type ) \ -{ \ - bool throw_ok = false; \ - try { \ - expr; \ - } \ - catch (std::exception &e) { \ - if (dynamic_cast(&e)) \ - throw_ok = true; \ - } \ - if (!throw_ok) \ - test_error_exit("Correct exception not thrown at %s:%d\n",__FILE__ , __LINE__); \ -} +#ifndef ERT_TEST_UTIL_H +#define ERT_TEST_UTIL_H + +#include +#include +#include +#include + +#if defined(__APPLE__) +#include +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + + void test_error_exit( const char * fmt , ...); + void * test_argpack_is_stringlist( void * arg ); + void * thread_pool_test_func1( void * arg ); + +#define test_exit( fmt, ...) test_exit__( __FILE__ , __LINE__ , fmt , __VA_ARGS__); + void test_exit__(const char * file , int line , const char * fmt , ...); + +#define test_assert_string_equal( s1 , s2 ) test_assert_string_equal__(s1 , s2 , __FILE__ , __LINE__) + void test_assert_string_equal__( const char * s1 , const char * s2 , const char * file , int line); +#define test_assert_string_not_equal( s1 , s2 ) test_assert_string_not_equal__(s1 , s2 , __FILE__ , __LINE__) + void test_assert_string_not_equal__( const char * s1 , const char * s2 , const char * file , int line); + + bool test_check_string_equal( const char *s1 , const char * s2); + +#define test_assert_int_equal( i1 , i2 ) test_assert_int_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) + void test_assert_int_equal__( int i1 , int i2 , const char * file , int line ); + +#define test_assert_int_not_equal( i1 , i2 ) test_assert_int_not_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) + void test_assert_int_not_equal__( int i1 , int i2 , const char * file , int line ); + +#define test_assert_long_equal( i1 , i2 ) test_assert_long_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) + void test_assert_long_equal__( long i1 , long i2 , const char * file , long line ); + +#define test_assert_long_not_equal( i1 , i2 ) test_assert_long_not_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) + void test_assert_long_not_equal__( long i1 , long i2 , const char * file , long line ); + +#define test_assert_uint_equal( i1 , i2 ) test_assert_uint_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) + void test_assert_uint_equal__( unsigned int i1 , unsigned int i2 , const char * file , int line ); + +#define test_assert_uint_not_equal( i1 , i2 ) test_assert_uint_not_equal__( (i1) , (i2) , __FILE__ , __LINE__ ) + void test_assert_uint_not_equal__( unsigned int i1 , unsigned int i2 , const char * file , int line ); + +#define test_assert_size_t_equal( s1 , s2 ) test_assert_size_t_equal__( (s1) , (s2) , __FILE__ , __LINE__ ) + void test_assert_size_t_equal__( size_t s1 , size_t s2 , const char * file , int line ); + +#define test_assert_size_t_not_equal( s1 , s2 ) test_assert_size_t_not_equal__( (s1) , (s2) , __FILE__ , __LINE__ ) + void test_assert_size_t_not_equal__( size_t s1 , size_t s2 , const char * file , int line ); + + +#define test_assert_double_equal( d1 , d2 ) test_assert_double_equal__( (d1) , (d2) , __FILE__ , __LINE__ ) + void test_assert_double_equal__( double d1 , double d2 , const char * file , int line ); + bool test_check_double_equal( double d1 , double d2); + +#define test_assert_float_equal( d1 , d2 ) test_assert_float_equal__( (d1) , (d2) , __FILE__ , __LINE__ ) + void test_assert_float_equal__( float d1 , float d2 , const char * file , int line ); + bool test_check_float_equal( float d1 , float d2); + +#define test_assert_double_not_equal( d1 , d2 ) test_assert_double_not_equal__( (d1) , (d2) , __FILE__ , __LINE__ ) + void test_assert_double_not_equal__( double d1 , double d2 , const char * file , int line ); -#define test_assert_std_string_equal(s0, s1) \ -{ \ - if (s0.compare(s1) != 0) \ - test_error_exit("Strings not equal at%s:%d (%s != %s)\n", \ - __FILE__ , __LINE__, s0.c_str(), s1.c_str()); \ +#define test_assert_bool_equal( b1 , b2 ) test_assert_bool_equal__( (b1) , (b2) , __FILE__ , __LINE__ ) + void test_assert_bool_equal__( bool b1 , bool b2 , const char * file , int line); + +#define test_assert_bool_not_equal( b1 , b2 ) test_assert_bool_not_equal__( (b1) , (b2) , __FILE__ , __LINE__ ) + void test_assert_bool_not_equal__( bool b1 , bool b2 , const char * file , int line); + +#define test_assert_true( value ) test_assert_true__( (value) , __FILE__ , __LINE__) + void test_assert_true__( bool value, const char * file , int line); + +#define test_assert_false( value ) test_assert_false__( (value) , __FILE__ , __LINE__) + void test_assert_false__( bool value, const char * file , int line); + +#define test_assert_time_t_equal( t1 , t2) test_assert_time_t_equal__((t1) , (t2) , __FILE__ , __LINE__) + void test_assert_time_t_equal__( time_t t1 , time_t t2 , const char * file , int line); + +#define test_assert_time_t_not_equal( t1 , t2) test_assert_time_t_not_equal__((t1) , (t2) , __FILE__ , __LINE__) + void test_assert_time_t_not_equal__( time_t t1 , time_t t2 , const char * file , int line); + +#define test_assert_ptr_equal( p1 , p2 ) test_assert_ptr_equal__( (p1) , (p2) , __FILE__ , __LINE__) + void test_assert_ptr_equal__( const void * p1 , const void * p2 , const char * file , int line); + +#define test_assert_ptr_not_equal(p1 , p2) test_assert_ptr_not_equal__( (p1) , (p2) , __FILE__ , __LINE__) + void test_assert_ptr_not_equal__( const void * p1 , const void * p2 , const char * file , int line); + +#define test_assert_NULL( p ) test_assert_NULL__( (p) , __FILE__ , __LINE__) + void test_assert_NULL__( const void * p , const char * file , int line); + +#define test_assert_not_NULL( p ) test_assert_not_NULL__( (p) , __FILE__ , __LINE__) + void test_assert_not_NULL__( const void * p , const char * file , int line); + +#define test_assert_mem_equal( p1 , p2 , byte_size ) test_assert_mem_equal__( (p1) , (p2) , (byte_size), __FILE__ , __LINE__) + void test_assert_mem_equal__( const void * p1 , const void * p2 , size_t byte_size , const char * file , int line); + +#define test_assert_mem_not_equal( p1 , p2 , byte_size ) test_assert_mem_not_equal__( (p1) , (p2) , (byte_size), __FILE__ , __LINE__) + void test_assert_mem_not_equal__( const void * p1 , const void * p2 , size_t byte_size , const char * file , int line); + +#define test_assert_file_content( input_file , expected) test_assert_file_content__( input_file , expected , __FILE__ , __LINE__) + void test_assert_file_content__( const char * input_file , const char * expected, const char * src_file , int line); + + void test_install_SIGNALS(void); + + jmp_buf * util_abort_test_jump_buffer(); + void test_util_addr2line(); + void test_assert_util_abort(const char * function_name , void call_func (void *) , void * arg); + + +#ifdef __cplusplus } +#endif + +#ifdef __cplusplus + +#define test_assert_throw(expr , exception_type ) \ + { \ + bool throw_ok = false; \ + try { \ + expr; \ + } \ + catch (std::exception &e) { \ + if (dynamic_cast(&e)) \ + throw_ok = true; \ + } \ + if (!throw_ok) \ + test_error_exit("Correct exception not thrown at %s:%d\n",__FILE__ , __LINE__); \ + } + +#define test_assert_std_string_equal(s0, s1) \ + { \ + if (s0.compare(s1) != 0) \ + test_error_exit("Strings not equal at%s:%d (%s != %s)\n", \ + __FILE__ , __LINE__, s0.c_str(), s1.c_str()); \ + } + + +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/test_work_area.h b/ThirdParty/Ert/lib/include/ert/util/test_work_area.h index 443d31fab7..ddf936af5d 100644 --- a/ThirdParty/Ert/lib/include/ert/util/test_work_area.h +++ b/ThirdParty/Ert/lib/include/ert/util/test_work_area.h @@ -1,57 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'test_work_area.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ +#include -#ifndef ERT_TEST_WORK_AREA_H -#define ERT_TEST_WORK_AREA_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#include - - typedef struct test_work_area_struct test_work_area_type; - - char * test_work_area_alloc_input_path( const test_work_area_type * work_area , const char * input_path ); - test_work_area_type * test_work_area_alloc(const char * test_name ); - test_work_area_type * test_work_area_alloc_relative(const char * prefix , const char * test_path); - void test_work_area_set_store( test_work_area_type * work_area , bool store); - - void test_work_area_free(test_work_area_type * work_area); - const char * test_work_area_get_cwd( const test_work_area_type * work_area ); - const char * test_work_area_get_original_cwd( const test_work_area_type * work_area ); - void test_work_area_install_file( test_work_area_type * work_area , const char * input_src_file ); - void test_work_area_copy_directory( test_work_area_type * work_area , const char * input_directory); - void test_work_area_copy_directory_content( test_work_area_type * work_area , const char * input_directory); - void test_work_area_copy_file( test_work_area_type * work_area , const char * input_file); - bool test_work_area_copy_parent_directory( test_work_area_type * work_area , const char * input_path); - bool test_work_area_copy_parent_content( test_work_area_type * work_area , const char * input_path); - void test_work_area_sync( test_work_area_type * work_area); - - test_work_area_type * temp_area_alloc_relative(const char * prefix , const char * test_path); - test_work_area_type * temp_area_alloc(const char * test_path); - - UTIL_IS_INSTANCE_HEADER( test_work_area ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/test_work_area.hpp b/ThirdParty/Ert/lib/include/ert/util/test_work_area.hpp index 5d9fbc90bd..e988012536 100644 --- a/ThirdParty/Ert/lib/include/ert/util/test_work_area.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/test_work_area.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2013 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'test_work_area.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,49 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef TEST_WORK_AREA_CXX -#define TEST_WORK_AREA_CXX -#include +#ifndef ERT_TEST_WORK_AREA_H +#define ERT_TEST_WORK_AREA_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + + typedef struct test_work_area_struct test_work_area_type; + + char * test_work_area_alloc_input_path( const test_work_area_type * work_area , const char * input_path ); + test_work_area_type * test_work_area_alloc(const char * test_name ); + test_work_area_type * test_work_area_alloc_relative(const char * prefix , const char * test_path); + void test_work_area_set_store( test_work_area_type * work_area , bool store); + + void test_work_area_free(test_work_area_type * work_area); + const char * test_work_area_get_cwd( const test_work_area_type * work_area ); + const char * test_work_area_get_original_cwd( const test_work_area_type * work_area ); + void test_work_area_install_file( test_work_area_type * work_area , const char * input_src_file ); + void test_work_area_copy_directory( test_work_area_type * work_area , const char * input_directory); + void test_work_area_copy_directory_content( test_work_area_type * work_area , const char * input_directory); + void test_work_area_copy_file( test_work_area_type * work_area , const char * input_file); + bool test_work_area_copy_parent_directory( test_work_area_type * work_area , const char * input_path); + bool test_work_area_copy_parent_content( test_work_area_type * work_area , const char * input_path); + void test_work_area_sync( test_work_area_type * work_area); + + test_work_area_type * temp_area_alloc_relative(const char * prefix , const char * test_path); + test_work_area_type * temp_area_alloc(const char * test_path); + + UTIL_IS_INSTANCE_HEADER( test_work_area ); + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/thread_pool1.h b/ThirdParty/Ert/lib/include/ert/util/thread_pool1.h index 14c2871468..be605c0ba3 100644 --- a/ThirdParty/Ert/lib/include/ert/util/thread_pool1.h +++ b/ThirdParty/Ert/lib/include/ert/util/thread_pool1.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'thread_pool1.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'thread_pool1.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #ifndef ERT_THREAD_POOL_H diff --git a/ThirdParty/Ert/lib/include/ert/util/time_interval.hpp b/ThirdParty/Ert/lib/include/ert/util/time_interval.hpp index 26073dbf06..939a2748e4 100644 --- a/ThirdParty/Ert/lib/include/ert/util/time_interval.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/time_interval.hpp @@ -19,6 +19,6 @@ #ifndef TIME_INTERVAL_CXX #define TIME_INTERVAL_CXX -#include +#include #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/timer.h b/ThirdParty/Ert/lib/include/ert/util/timer.h index 73c80e7236..a95bf08efd 100644 --- a/ThirdParty/Ert/lib/include/ert/util/timer.h +++ b/ThirdParty/Ert/lib/include/ert/util/timer.h @@ -1,48 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'timer.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_TIMER_H -#define ERT_TIMER_H +#include -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - - -typedef struct timer_struct timer_type; - - timer_type * timer_alloc( bool ); - void timer_free(timer_type *); - void timer_start(timer_type *); - double timer_stop(timer_type *); - void timer_reset(timer_type *); - - double timer_get_total_time(const timer_type *timer); - double timer_get_max_time(const timer_type *timer); - double timer_get_min_time(const timer_type *timer); - double timer_get_avg_time(const timer_type *timer); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/timer.hpp b/ThirdParty/Ert/lib/include/ert/util/timer.hpp index 14a83dd14f..8830222065 100644 --- a/ThirdParty/Ert/lib/include/ert/util/timer.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/timer.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'timer.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,40 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef TIMER_CXX -#define TIMER_CXX +#ifndef ERT_TIMER_H +#define ERT_TIMER_H -#include +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +typedef struct timer_struct timer_type; + + timer_type * timer_alloc( bool ); + void timer_free(timer_type *); + void timer_start(timer_type *); + double timer_stop(timer_type *); + void timer_reset(timer_type *); + double timer_get_total_time(const timer_type *timer); + double timer_get_max_time(const timer_type *timer); + double timer_get_min_time(const timer_type *timer); + double timer_get_avg_time(const timer_type *timer); + + +#ifdef __cplusplus +} #endif +#endif + diff --git a/ThirdParty/Ert/lib/include/ert/util/type_macros.h b/ThirdParty/Ert/lib/include/ert/util/type_macros.h index 21b680eab3..dda741245a 100644 --- a/ThirdParty/Ert/lib/include/ert/util/type_macros.h +++ b/ThirdParty/Ert/lib/include/ert/util/type_macros.h @@ -1,144 +1,9 @@ -#ifndef ERT_TYPE_MACROS_H -#define ERT_TYPE_MACROS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - - -/*****************************************************************/ -/** - - The four macros UTIL_IS_INSTANCE_FUNCTION, UTIL_SAFE_CAST_FUNTION, - UTIL_TYPE_ID_DECLARATION and UTIL_TYPE_ID_INIT can be used to - implement a simple system for type checking (void *) at - runtime. The system is based on a unique integer for each class, - this must be provided by the user. - - The motivation for these functions is to be able to to type-check - the arguments to callback functions like pthread_create. - - UTIL_TYPE_ID_DECLARATION: Adds a field "int __type_id;" to the - struct defintion. - - UTIL_TYPE_ID_INIT: Should be added to the allocation routine, - inserts a "->__type_id = magic_int;" code line in the alloc - routine. - - UTIL_IS_INSTANCE_FUNCTION: This macro will generate a function - _is_instance(void *) which will cast the (void *) input to - (type *), and check the value of __type_id. If this is the - correct value true is returned, otherwise the function will - return false. Observe that the function will accept NULL as - input; in which case it will return false. - - UTIL_SAFE_CAST_FUNCTION: This is similar to - UTIL_IS_INSTANCE_FUNCTION, but it will return (type *) if the - cast succeeds, and fail hard if it fails. There is also a _CONST - variety of this function. - +/* + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ - - - -#define UTIL_IS_INSTANCE_FUNCTION(type , TYPE_ID) \ -bool type ## _is_instance( const void * __arg ) { \ - if (__arg == NULL) \ - return false; \ - else { \ - const type ## _type * arg = (const type ## _type * ) __arg; \ - if ( arg->__type_id == TYPE_ID) \ - return true; \ - else \ - return false; \ - } \ -} - - -#define UTIL_IS_INSTANCE_HEADER(type) bool type ## _is_instance( const void * __arg ) - - -#define UTIL_SAFE_CAST_FUNCTION(type , TYPE_ID) \ -type ## _type * type ## _safe_cast( void * __arg ) { \ - if (__arg == NULL) { \ - util_abort("%s: runtime cast failed - tried to dereference NULL\n",__func__); \ - return NULL; \ - } \ - { \ - type ## _type * arg = (type ## _type *) __arg; \ - if ( arg->__type_id == TYPE_ID) \ - return arg; \ - else { \ - util_abort("%s: runtime cast failed: Got ID:%d Expected ID:%d \n", __func__ , arg->__type_id , TYPE_ID); \ - return NULL; \ - } \ - } \ -} -#define UTIL_SAFE_CAST_HEADER( type ) type ## _type * type ## _safe_cast( void * __arg ) - - -#define UTIL_SAFE_CAST_FUNCTION_CONST(type , TYPE_ID) \ -const type ## _type * type ## _safe_cast_const( const void * __arg ) { \ - if (__arg == NULL) { \ - util_abort("%s: runtime cast failed - tried to dereference NULL\n",__func__); \ - return NULL; \ - } \ - { \ - const type ## _type * arg = (const type ## _type *) __arg; \ - if ( arg->__type_id == TYPE_ID) \ - return arg; \ - else { \ - util_abort("%s: runtime cast failed: Got ID:%d Expected ID:%d \n", __func__ , arg->__type_id , TYPE_ID); \ - return NULL; \ - } \ - } \ -} -#define UTIL_SAFE_CAST_HEADER_CONST( type ) const type ## _type * type ## _safe_cast_const( const void * __arg ) - - - - -#define UTIL_TRY_CAST_FUNCTION(type , TYPE_ID) \ -type ## _type * type ## _try_cast( void * __arg ) { \ - if (__arg == NULL) \ - return NULL; \ - { \ - type ## _type * arg = (type ## _type *) __arg; \ - if ( arg->__type_id == TYPE_ID) \ - return arg; \ - else \ - return NULL; \ - } \ -} -#define UTIL_TRY_CAST_HEADER( type ) type ## _type * type ## _try_cast( void * __arg ) - - -#define UTIL_TRY_CAST_FUNCTION_CONST(type , TYPE_ID) \ -const type ## _type * type ## _try_cast_const( const void * __arg ) { \ - if (__arg == NULL) \ - return NULL; \ - { \ - const type ## _type * arg = (type ## _type *) __arg; \ - if ( arg->__type_id == TYPE_ID) \ - return arg; \ - else \ - return NULL; \ - } \ -} -#define UTIL_TRY_CAST_HEADER_CONST( type ) const type ## _type * type ## _try_cast_const( const void * __arg ) - - - - -#define UTIL_TYPE_ID_DECLARATION int __type_id -#define UTIL_TYPE_ID_INIT(var , TYPE_ID) var->__type_id = TYPE_ID; - +#include -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/type_macros.hpp b/ThirdParty/Ert/lib/include/ert/util/type_macros.hpp index 704643272e..e3dba00617 100644 --- a/ThirdParty/Ert/lib/include/ert/util/type_macros.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/type_macros.hpp @@ -1,24 +1,144 @@ -/* - Copyright (C) 2018 Statoil ASA, Norway. +#ifndef ERT_TYPE_MACROS_H +#define ERT_TYPE_MACROS_H - This is part of ERT - Ensemble based Reservoir Tool. +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +/*****************************************************************/ +/** + + The four macros UTIL_IS_INSTANCE_FUNCTION, UTIL_SAFE_CAST_FUNTION, + UTIL_TYPE_ID_DECLARATION and UTIL_TYPE_ID_INIT can be used to + implement a simple system for type checking (void *) at + runtime. The system is based on a unique integer for each class, + this must be provided by the user. + + The motivation for these functions is to be able to to type-check + the arguments to callback functions like pthread_create. + + UTIL_TYPE_ID_DECLARATION: Adds a field "int __type_id;" to the + struct defintion. + + UTIL_TYPE_ID_INIT: Should be added to the allocation routine, + inserts a "->__type_id = magic_int;" code line in the alloc + routine. - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + UTIL_IS_INSTANCE_FUNCTION: This macro will generate a function + _is_instance(void *) which will cast the (void *) input to + (type *), and check the value of __type_id. If this is the + correct value true is returned, otherwise the function will + return false. Observe that the function will accept NULL as + input; in which case it will return false. - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 - FITNESS FOR A PARTICULAR PURPOSE. + UTIL_SAFE_CAST_FUNCTION: This is similar to + UTIL_IS_INSTANCE_FUNCTION, but it will return (type *) if the + cast succeeds, and fail hard if it fails. There is also a _CONST + variety of this function. - See the GNU General Public License at - for more details. */ -#ifndef TYPE_MACROS_CXX -#define TYPE_MACROS_CXX -#include + +#define UTIL_IS_INSTANCE_FUNCTION(type , TYPE_ID) \ +bool type ## _is_instance( const void * __arg ) { \ + if (__arg == NULL) \ + return false; \ + else { \ + const type ## _type * arg = (const type ## _type * ) __arg; \ + if ( arg->__type_id == TYPE_ID) \ + return true; \ + else \ + return false; \ + } \ +} + + +#define UTIL_IS_INSTANCE_HEADER(type) bool type ## _is_instance( const void * __arg ) + + +#define UTIL_SAFE_CAST_FUNCTION(type , TYPE_ID) \ +type ## _type * type ## _safe_cast( void * __arg ) { \ + if (__arg == NULL) { \ + util_abort("%s: runtime cast failed - tried to dereference NULL\n",__func__); \ + return NULL; \ + } \ + { \ + type ## _type * arg = (type ## _type *) __arg; \ + if ( arg->__type_id == TYPE_ID) \ + return arg; \ + else { \ + util_abort("%s: runtime cast failed: Got ID:%d Expected ID:%d \n", __func__ , arg->__type_id , TYPE_ID); \ + return NULL; \ + } \ + } \ +} +#define UTIL_SAFE_CAST_HEADER( type ) type ## _type * type ## _safe_cast( void * __arg ) + + +#define UTIL_SAFE_CAST_FUNCTION_CONST(type , TYPE_ID) \ +const type ## _type * type ## _safe_cast_const( const void * __arg ) { \ + if (__arg == NULL) { \ + util_abort("%s: runtime cast failed - tried to dereference NULL\n",__func__); \ + return NULL; \ + } \ + { \ + const type ## _type * arg = (const type ## _type *) __arg; \ + if ( arg->__type_id == TYPE_ID) \ + return arg; \ + else { \ + util_abort("%s: runtime cast failed: Got ID:%d Expected ID:%d \n", __func__ , arg->__type_id , TYPE_ID); \ + return NULL; \ + } \ + } \ +} +#define UTIL_SAFE_CAST_HEADER_CONST( type ) const type ## _type * type ## _safe_cast_const( const void * __arg ) + + + + +#define UTIL_TRY_CAST_FUNCTION(type , TYPE_ID) \ +type ## _type * type ## _try_cast( void * __arg ) { \ + if (__arg == NULL) \ + return NULL; \ + { \ + type ## _type * arg = (type ## _type *) __arg; \ + if ( arg->__type_id == TYPE_ID) \ + return arg; \ + else \ + return NULL; \ + } \ +} +#define UTIL_TRY_CAST_HEADER( type ) type ## _type * type ## _try_cast( void * __arg ) + + +#define UTIL_TRY_CAST_FUNCTION_CONST(type , TYPE_ID) \ +const type ## _type * type ## _try_cast_const( const void * __arg ) { \ + if (__arg == NULL) \ + return NULL; \ + { \ + const type ## _type * arg = (type ## _type *) __arg; \ + if ( arg->__type_id == TYPE_ID) \ + return arg; \ + else \ + return NULL; \ + } \ +} +#define UTIL_TRY_CAST_HEADER_CONST( type ) const type ## _type * type ## _try_cast_const( const void * __arg ) + + + + +#define UTIL_TYPE_ID_DECLARATION int __type_id +#define UTIL_TYPE_ID_INIT(var , TYPE_ID) var->__type_id = TYPE_ID; + + + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.h b/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.h index 96f0d1dd97..2ec3abefe5 100644 --- a/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.h +++ b/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.h @@ -1,37 +1,9 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'type_vector_functions.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_TYPE_VECTOR_FUNCTIONS_H -#define ERT_TYPE_VECTOR_FUNCTIONS_H - -#include -#include -#include -#ifdef __cplusplus -extern "C" { -#endif +#include - int_vector_type * bool_vector_alloc_active_list( const bool_vector_type * mask ); - bool_vector_type * int_vector_alloc_mask( const int_vector_type * active_list ); - int_vector_type * bool_vector_alloc_active_index_list(const bool_vector_type * mask , int default_value); - bool double_vector_approx_equal( const double_vector_type * v1 , const double_vector_type * v12 , double epsilon); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.hpp b/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.hpp index 142f711db9..f607faf163 100644 --- a/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/type_vector_functions.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2013 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'type_vector_functions.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,29 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ +#ifndef ERT_TYPE_VECTOR_FUNCTIONS_H +#define ERT_TYPE_VECTOR_FUNCTIONS_H -#ifndef TYPE_VECTOR_FUNCTIONS_CXX -#define TYPE_VECTOR_FUNCTIONS_CXX +#include +#include +#include -#include +#ifdef __cplusplus +extern "C" { +#endif + + int_vector_type * bool_vector_alloc_active_list( const bool_vector_type * mask ); + bool_vector_type * int_vector_alloc_mask( const int_vector_type * active_list ); + int_vector_type * bool_vector_alloc_active_index_list(const bool_vector_type * mask , int default_value); + bool double_vector_approx_equal( const double_vector_type * v1 , const double_vector_type * v12 , double epsilon); +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/util.h b/ThirdParty/Ert/lib/include/ert/util/util.h index 84b406b9d3..5d44346560 100644 --- a/ThirdParty/Ert/lib/include/ert/util/util.h +++ b/ThirdParty/Ert/lib/include/ert/util/util.h @@ -27,7 +27,7 @@ #include -#include +#include @@ -102,7 +102,6 @@ typedef enum {left_pad = 0, center_pad = 2} string_alignement_type; //#define UTIL_CXX_MALLOC(var , num_elm) (typeof (var)) util_malloc( (num_elm) * sizeof var) - void util_bitmask_on(int * , int ); char * util_get_timezone(void); time_t util_make_datetime_utc(int , int , int , int , int , int ); bool util_make_datetime_utc_validated(int sec, int min, int hour , int mday , int month , int year, time_t * t); @@ -128,7 +127,6 @@ typedef enum {left_pad = 0, bool util_char_in(char c, int , const char *); char * util_alloc_sprintf_va(const char * fmt , va_list ap); char * util_alloc_sprintf(const char * , ...); - char * util_alloc_sprintf_escape(const char * src , int max_escape); char * util_realloc_sprintf(char * , const char * , ...); void util_fprintf_int(int , int , FILE * ); void util_fprintf_string(const char * , int , string_alignement_type , FILE * ); @@ -147,6 +145,7 @@ typedef enum {left_pad = 0, bool util_fmt_bit8_stream(FILE * ); char * util_strstr_int_format(const char * string ); int util_int_format_count(const char * string ); + bool util_mkdir_p(const char * path); void util_make_path (const char *); char * util_newest_file(const char *, const char *); double util_file_difftime(const char * , const char *); @@ -177,7 +176,6 @@ typedef enum {left_pad = 0, bool util_ftruncate(FILE * stream , long size); void util_usleep( unsigned long micro_seconds ); - void util_yield(void); int util_roundf( float x ); int util_round( double x ); @@ -205,19 +203,14 @@ typedef enum {left_pad = 0, bool util_chmod_if_owner( const char * filename , mode_t new_mode); #endif -#ifdef HAVE_PROC - bool util_proc_alive(pid_t pid); -#endif - int util_forward_line(FILE * , bool * ); void util_rewind_line(FILE *); + int util_count_content_file_lines(FILE * ); - int util_count_file_lines(FILE * ); FILE * util_mkdir_fopen( const char * filename , const char * mode ); int util_fmove( FILE * stream , long offset , long shift); - FILE * util_fopen(const char * , const char *); + FILE * util_fopen(const char * , const char *); FILE * util_fopen__(const char * filename , const char * mode); - void util_fclose( FILE * stream ); bool util_fopen_test(const char *, const char *); char * util_split_alloc_dirname( const char * input_path ); char * util_split_alloc_filename( const char * input_path ); @@ -225,7 +218,6 @@ typedef enum {left_pad = 0, //char * util_realloc_full_path(char * , const char *, const char *); char * util_alloc_tmp_file(const char * , const char * , bool ); char * util_fscanf_alloc_line(FILE *, bool *); - char * util_fscanf_realloc_line(FILE *, bool * , char *); char * util_fscanf_alloc_token(FILE * ); void util_fskip_token(FILE * ); void util_fskip_space(FILE * , bool *); @@ -245,7 +237,6 @@ typedef enum {left_pad = 0, char * util_alloc_filename(const char * , const char * , const char * ); char * util_realloc_filename(char * , const char * , const char * , const char * ); char * util_alloc_strip_copy(const char *); - char * util_realloc_strip_copy(char *); void util_set_strip_copy(char * , const char *); char * util_alloc_string_sum(const char ** , int); char * util_strcat_realloc(char *, const char * ); @@ -268,7 +259,6 @@ typedef enum {left_pad = 0, char * util_realloc_substring_copy(char * , const char *, int N); char * util_realloc_dequoted_string(char *); char * util_alloc_dequoted_copy(const char *s); - void util_safe_free(void *); void util_free_stringlist(char **, int ); void util_free_NULL_terminated_stringlist(char ** string_list); char * util_alloc_substring_copy(const char *, int offset , int N); @@ -296,7 +286,6 @@ typedef enum {left_pad = 0, void * util_realloc(void * , size_t ); - void util_free(void * ptr); void * util_malloc(size_t ); void * util_calloc( size_t elements , size_t element_size ); void * util_realloc_copy(void * org_ptr , const void * src , size_t byte_size ); @@ -312,7 +301,6 @@ typedef enum {left_pad = 0, char * util_fread_alloc_string(FILE *); void util_fskip_string(FILE *stream); void util_endian_flip_vector(void * data , int element_size , int elements); - int util_proc_mem_free(void); void util_clamp_double(double * value , double limit1, double limit2); @@ -360,7 +348,6 @@ typedef enum {left_pad = 0, const char * util_update_path_var(const char * , const char * , bool ); - int util_get_type( void * data ); void util_fskip_int(FILE * stream); void util_fskip_long(FILE * stream); void util_fskip_bool(FILE * stream); @@ -411,72 +398,6 @@ typedef enum {left_pad = 0, CONTAINS_HEADER(size_t); #undef CONTAINS_HEADER -/*****************************************************************/ -/* - The code below here is a simple functionality to support 'enum - introspection'; the point is that when calling the library functions - from Python/ctypes it is very valuable to have access to the enum - values from the Python side. The enum defintions is just used during - the compile phase, and then subsequently dropped. It is therefor - impossible to determine enum values by inspecting the resulting - object files. - - The approach which has been chosen is that each of the enums which - should support 'introspection' from Python should have a function: - - const char * _iget(int index, int * value) { - ... - } - - which should take an enum element number as input argument and - return a string representation of the corresponding enum element and - also update the value reference to contain the corresponding enum - value. If index is out of range the function should return NULL and - also set value to -1. The python layer can then create an integer - variable with the correct name and value in the calling module. - - The util_enum_element_type and the util_enum_iget() function are - convenience functions which can be used to avoid indirectly - repeating the enum definition in the _iget() function. - - In the example below we create the enum definition in normal way in - the header file, and then in addition we repeat the defintion in a - #define a symbol which is used as argument in the _iget() - function: - - - header_file: - ------------ - enum my_enum { - INVALID = 0, - VALUE1 = 2, - VALUE2 = 17 - } - - // The enum definition is repeated; but at at least at the very same spot of the code. - - #define MY_ENUM_DEF { .value = INVALID, .name="INVALID"} , {.value = VALUE1 , .name="VALUE1"} , {.value = VALUE2 , .name="VALUE2"} - #define MY_ENUM_SIZE 3 - - - source file: - ------------ - - const char * my_enum_iget(int index, int * value) { - return util_enum_iget( index , MY_ENUM_SIZE , (const util_enum_element_type []) MY_ENUM_DEF , value); - } - -*/ - - -typedef struct { - int value; - const char * name; -} util_enum_element_type; - -const char * util_enum_iget( int index , int size , const util_enum_element_type * enum_defs , int * value); - - #ifdef _MSC_VER #define util_abort(fmt , ...) util_abort__(__FILE__ , __func__ , __LINE__ , fmt , __VA_ARGS__) #elif __GNUC__ diff --git a/ThirdParty/Ert/lib/include/ert/util/util_endian.h b/ThirdParty/Ert/lib/include/ert/util/util_endian.h index 3ad1aad0a5..96f2399f4a 100644 --- a/ThirdParty/Ert/lib/include/ert/util/util_endian.h +++ b/ThirdParty/Ert/lib/include/ert/util/util_endian.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'util_endian.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'util_endian.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ @@ -23,9 +23,9 @@ #ifdef __cplusplus extern "C" { #endif - + void util_endian_flip_vector(void * data , int element_size , int elements); - + #ifdef __cplusplus } #endif diff --git a/ThirdParty/Ert/lib/include/ert/util/util_unlink.h b/ThirdParty/Ert/lib/include/ert/util/util_unlink.h index 84a1053d29..3fc1e232c5 100644 --- a/ThirdParty/Ert/lib/include/ert/util/util_unlink.h +++ b/ThirdParty/Ert/lib/include/ert/util/util_unlink.h @@ -1,19 +1,19 @@ /* - Copyright (C) 2017 Statoil ASA, Norway. - - The file 'util_unlink.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2017 Statoil ASA, Norway. + + The file 'util_unlink.h' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ diff --git a/ThirdParty/Ert/lib/include/ert/util/vector.h b/ThirdParty/Ert/lib/include/ert/util/vector.h index 5be24399e7..e6bf1a9822 100644 --- a/ThirdParty/Ert/lib/include/ert/util/vector.h +++ b/ThirdParty/Ert/lib/include/ert/util/vector.h @@ -1,93 +1,9 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'vector.h' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Warning: The libecl code has changed to be compiled as a C++ project. This + header file is retained for a period for compatibility, but you are encouraged + to switch to include the new hpp header directly in your code. */ -#ifndef ERT_VECTOR_H -#define ERT_VECTOR_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - typedef void ( vector_func_type ) (void * , void *); - typedef int ( vector_cmp_ftype) (const void * , const void *); - - typedef struct vector_struct vector_type; - - - vector_type * vector_alloc_new(void); - void vector_grow_NULL( vector_type * vector , int new_size ); - vector_type * vector_alloc_NULL_initialized( int size ); - - int vector_append_ref( vector_type * , const void *); - int vector_append_owned_ref( vector_type * , const void * , free_ftype * del); - int vector_append_copy(vector_type * , const void *, copyc_ftype *, free_ftype *); - - void vector_iset_ref( vector_type * , int , const void *); - void vector_iset_owned_ref( vector_type * , int , const void * , free_ftype * del); - void vector_iset_copy(vector_type * , int , const void *, copyc_ftype *, free_ftype *); - - void vector_safe_iset_copy(vector_type * vector , int index , const void * data, copyc_ftype * copyc , free_ftype * del); - void vector_safe_iset_owned_ref(vector_type * vector , int index , const void * data, free_ftype * del); - void vector_safe_iset_ref(vector_type * vector , int index , const void * data); - - void vector_insert_ref( vector_type * , int , const void *); - void vector_insert_owned_ref( vector_type * , int , const void * , free_ftype * del); - void vector_insert_copy(vector_type * , int , const void *, copyc_ftype *, free_ftype *); - void vector_insert_buffer(vector_type * vector , int index , const void * buffer, int buffer_size); - - void vector_push_front_ref( vector_type * , const void *); - void vector_push_front_owned_ref( vector_type * , const void * , free_ftype * del); - void vector_push_front_copy(vector_type * , const void *, copyc_ftype *, free_ftype *); - - - void vector_clear(vector_type * vector); - void vector_free(vector_type * ); - void vector_free__( void * arg ); - void vector_append_buffer(vector_type * , const void * , int); - void vector_push_buffer(vector_type * , const void * , int); - void * vector_safe_iget(const vector_type * vector, int index); - const void * vector_safe_iget_const(const vector_type * vector, int index); - const void * vector_iget_const(const vector_type * , int ); - void * vector_iget(const vector_type * , int ); - void vector_idel(vector_type * vector , int index); - void vector_shrink( vector_type * vector , int new_size ); - void * vector_get_last(const vector_type * ); - const void * vector_get_last_const(const vector_type * ); - int vector_get_size( const vector_type * ); - void * vector_pop_back(vector_type * ); - void * vector_pop_front(vector_type * ); - void vector_sort(vector_type * vector , vector_cmp_ftype * cmp); - int_vector_type * vector_alloc_sort_perm(const vector_type * vector , vector_cmp_ftype * cmp); - void vector_permute(vector_type * vector , const int_vector_type * perm_vector); - void vector_inplace_reverse(vector_type * vector); - vector_type * vector_alloc_copy(const vector_type * src , bool deep_copy); - - void vector_iset_buffer(vector_type * vector , int index , const void * buffer, int buffer_size); - int vector_find( const vector_type * vector , const void * ptr); +#include - UTIL_IS_INSTANCE_HEADER( vector ); - UTIL_SAFE_CAST_HEADER( vector ); -#ifdef __cplusplus -} -#endif -#endif diff --git a/ThirdParty/Ert/lib/include/ert/util/vector.hpp b/ThirdParty/Ert/lib/include/ert/util/vector.hpp index 99ddd5a31c..ff4f526bc2 100644 --- a/ThirdParty/Ert/lib/include/ert/util/vector.hpp +++ b/ThirdParty/Ert/lib/include/ert/util/vector.hpp @@ -1,7 +1,7 @@ /* - Copyright (C) 2018 Statoil ASA, Norway. + Copyright (C) 2011 Statoil ASA, Norway. - This is part of ERT - Ensemble based Reservoir Tool. + The file 'vector.h' is part of ERT - Ensemble based Reservoir Tool. ERT is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -9,16 +9,85 @@ (at your option) any later version. ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License at for more details. */ -#ifndef VECTOR_CXX -#define VECTOR_CXX +#ifndef ERT_VECTOR_H +#define ERT_VECTOR_H -#include +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + + typedef void ( vector_func_type ) (void * , void *); + typedef int ( vector_cmp_ftype) (const void * , const void *); + + typedef struct vector_struct vector_type; + + + vector_type * vector_alloc_new(void); + void vector_grow_NULL( vector_type * vector , int new_size ); + vector_type * vector_alloc_NULL_initialized( int size ); + + int vector_append_ref( vector_type * , const void *); + int vector_append_owned_ref( vector_type * , const void * , free_ftype * del); + int vector_append_copy(vector_type * , const void *, copyc_ftype *, free_ftype *); + + void vector_iset_ref( vector_type * , int , const void *); + void vector_iset_owned_ref( vector_type * , int , const void * , free_ftype * del); + void vector_iset_copy(vector_type * , int , const void *, copyc_ftype *, free_ftype *); + + void vector_safe_iset_copy(vector_type * vector , int index , const void * data, copyc_ftype * copyc , free_ftype * del); + void vector_safe_iset_owned_ref(vector_type * vector , int index , const void * data, free_ftype * del); + void vector_safe_iset_ref(vector_type * vector , int index , const void * data); + + void vector_insert_ref( vector_type * , int , const void *); + void vector_insert_owned_ref( vector_type * , int , const void * , free_ftype * del); + void vector_insert_copy(vector_type * , int , const void *, copyc_ftype *, free_ftype *); + void vector_insert_buffer(vector_type * vector , int index , const void * buffer, int buffer_size); + + void vector_push_front_ref( vector_type * , const void *); + void vector_push_front_owned_ref( vector_type * , const void * , free_ftype * del); + void vector_push_front_copy(vector_type * , const void *, copyc_ftype *, free_ftype *); + + + void vector_clear(vector_type * vector); + void vector_free(vector_type * ); + void vector_free__( void * arg ); + void vector_append_buffer(vector_type * , const void * , int); + void vector_push_buffer(vector_type * , const void * , int); + void * vector_safe_iget(const vector_type * vector, int index); + const void * vector_safe_iget_const(const vector_type * vector, int index); + const void * vector_iget_const(const vector_type * , int ); + void * vector_iget(const vector_type * , int ); + void vector_idel(vector_type * vector , int index); + void vector_shrink( vector_type * vector , int new_size ); + void * vector_get_last(const vector_type * ); + const void * vector_get_last_const(const vector_type * ); + int vector_get_size( const vector_type * ); + void * vector_pop_back(vector_type * ); + void * vector_pop_front(vector_type * ); + void vector_sort(vector_type * vector , vector_cmp_ftype * cmp); + int_vector_type * vector_alloc_sort_perm(const vector_type * vector , vector_cmp_ftype * cmp); + void vector_permute(vector_type * vector , const int_vector_type * perm_vector); + void vector_inplace_reverse(vector_type * vector); + vector_type * vector_alloc_copy(const vector_type * src , bool deep_copy); + + void vector_iset_buffer(vector_type * vector , int index , const void * buffer, int buffer_size); + int vector_find( const vector_type * vector , const void * ptr); + + UTIL_IS_INSTANCE_HEADER( vector ); + UTIL_SAFE_CAST_HEADER( vector ); + +#ifdef __cplusplus +} +#endif #endif diff --git a/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_grid_cache.hpp b/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_grid_cache.hpp new file mode 100644 index 0000000000..cb96cee2e7 --- /dev/null +++ b/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_grid_cache.hpp @@ -0,0 +1,49 @@ +/* + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'ecl_grid_cache.h' is part of ERT - Ensemble based + Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ + +#ifndef ERT_ECL_GRID_CACHE_H +#define ERT_ECL_GRID_CACHE_H + +#include + +#include + +namespace ecl { + class ecl_grid_cache { + public: + ecl_grid_cache(const ecl_grid_type * grid); + + const std::vector& volume() const; + const std::vector& xpos() const { return this->xp; } + const std::vector& ypos() const { return this->yp; } + const std::vector& zpos() const { return this->zp; } + const std::vector& global_index( ) const { return this->gi; } + int size() const { return this->xp.size(); } + + private: + const ecl_grid_type * grid; + std::vector gi; + std::vector xp; + std::vector yp; + std::vector zp; + mutable std::vector v; + }; +} + +#endif diff --git a/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_sum_file_data.hpp b/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_sum_file_data.hpp new file mode 100644 index 0000000000..3435cc6017 --- /dev/null +++ b/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_sum_file_data.hpp @@ -0,0 +1,150 @@ +#include +#include +#include + +#include + +#include +#include +#include + +namespace ecl { + +#define INVALID_MINISTEP_NR -1 +#define INVALID_TIME_T 0 + + +struct IndexNode { + +IndexNode(time_t sim_time, double sim_seconds, int report_step) : + sim_time(sim_time), + sim_seconds(sim_seconds), + report_step(report_step) +{} + + time_t sim_time; + double sim_seconds; + int report_step; +}; + + +class TimeIndex { +public: + + void add(time_t sim_time, double sim_seconds, int report_step) { + int internal_index = static_cast(this->nodes.size()); + this->nodes.emplace_back(sim_time, sim_seconds, report_step); + + /* Indexing internal_index - report_step */ + if (static_cast(this->report_map.size()) <= report_step) + this->report_map.resize( report_step + 1, std::pair(std::numeric_limits::max(), -1)); + + auto& range = this->report_map[report_step]; + range.first = std::min(range.first, internal_index); + range.second = std::max(range.second, internal_index); + } + + + bool has_report(int report_step) const { + if (report_step >= static_cast(this->report_map.size())) + return false; + + const auto& range_pair = this->report_map[report_step]; + if (range_pair.second < 0) + return false; + + return true; + } + + + void clear() { + this->nodes.clear(); + this->report_map.clear(); + } + + const IndexNode& operator[](size_t index) const { + return this->nodes[index]; + } + + const IndexNode& back() const { + return this->nodes.back(); + } + + size_t size() const { + return this->nodes.size(); + } + + std::pair& report_range(int report_step) { + return this->report_map[report_step]; + } + + const std::pair& report_range(int report_step) const { + return this->report_map[report_step]; + } + +private: + std::vector nodes; + std::vector> report_map; +}; + + +class unsmry_loader; + +class ecl_sum_file_data { + +public: + ecl_sum_file_data(const ecl_smspec_type * smspec); + ~ecl_sum_file_data(); + const ecl_smspec_type * smspec() const; + + int length_before(time_t end_time) const; + void get_time(int length, time_t *data); + void get_data(int params_index, int length, double *data); + int length() const; + time_t get_data_start() const; + time_t get_sim_end() const; + double iget( int time_index , int params_index ) const; + time_t iget_sim_time(int time_index ) const; + double iget_sim_days(int time_index ) const; + double iget_sim_seconds(int time_index ) const; + ecl_sum_tstep_type * iget_ministep( int internal_index ) const; + double get_days_start() const; + double get_sim_length() const; + + std::pair report_range(int report_step) const; + bool report_step_equal( const ecl_sum_file_data& other, bool strict) const; + int report_before(time_t end_time) const; + int get_time_report(int max_internal_index, time_t *data); + int get_data_report(int params_index, int max_internal_index, double *data, double default_value); + int first_report() const; + int last_report() const; + int iget_report(int time_index) const; + bool has_report(int report_step ) const; + int report_step_from_days(double sim_days) const; + int report_step_from_time(time_t sim_time) const; + + ecl_sum_tstep_type * add_new_tstep(int report_step , double sim_seconds); + bool can_write() const; + void fwrite_unified( fortio_type * fortio ) const; + void fwrite_multiple( const char * ecl_case , bool fmt_case ) const; + bool fread(const stringlist_type * filelist, bool lazy_load, int file_options); + +private: + const ecl_smspec_type * ecl_smspec; + + TimeIndex index; + vector_type * data; + + std::unique_ptr loader; + + void append_tstep(ecl_sum_tstep_type * tstep); + void build_index(); + void fwrite_report( int report_step , fortio_type * fortio) const; + bool check_file( ecl_file_type * ecl_file ); + void add_ecl_file(int report_step, const ecl_file_view_type * summary_view, const ecl_smspec_type * smspec); +}; + + + + +} diff --git a/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_unsmry_loader.hpp b/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_unsmry_loader.hpp new file mode 100644 index 0000000000..741373bbed --- /dev/null +++ b/ThirdParty/Ert/lib/private-include/detail/ecl/ecl_unsmry_loader.hpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include + +#include +#include + +namespace ecl { + +class unsmry_loader { +public: + unsmry_loader(const ecl_smspec_type * smspec, const std::string& filename, int file_options); + ~unsmry_loader(); + + std::vector get_vector(int pos) const; + std::vector sim_seconds() const; + std::vector sim_time() const; + int length() const; + + time_t iget_sim_time(int time_index) const; + double iget_sim_seconds(int time_index) const; + std::vector report_steps(int offset) const; + double iget(int time_index, int params_index) const; + +private: + int size; //Number of entries in the smspec index + int time_index; + int time_seconds; + time_t sim_start; + int m_length; //Number of PARAMS in the UNSMRY file + + std::array date_index; + ecl_file_type * file; + ecl_file_view_type * file_view; +}; + + + + + + + +} diff --git a/ThirdParty/Ert/lib/private-include/detail/ecl/layer_cxx.hpp b/ThirdParty/Ert/lib/private-include/detail/ecl/layer_cxx.hpp new file mode 100644 index 0000000000..bd19f36b0f --- /dev/null +++ b/ThirdParty/Ert/lib/private-include/detail/ecl/layer_cxx.hpp @@ -0,0 +1,9 @@ +#ifndef LAYER_CXX_HPP +#define LAYER_CXX_HPP + +#include +#include + +bool layer_trace_block_edge( const layer_type * layer , int i , int j , int value , std::vector& corner_list, int_vector_type * cell_list); + +#endif diff --git a/ThirdParty/Ert/lib/private-include/detail/util/path.hpp b/ThirdParty/Ert/lib/private-include/detail/util/path.hpp new file mode 100644 index 0000000000..fb4e706820 --- /dev/null +++ b/ThirdParty/Ert/lib/private-include/detail/util/path.hpp @@ -0,0 +1,32 @@ +#ifndef PATH_UTIL +#define PATH_UTIL + + +#include +namespace ecl { + namespace util { + namespace path { + /* + Observe that these functions are purely based on string inspection; i.e. + the actual filesystem is *never* consulted. Furthermore the functions + interpret the argument as a *filename* - that implies the (maybe + surprising) semantics: + + dirname("/tmp") => "/" + basename("/tmp") => "tmp" + + Although if you actually checked the filesystem you would of course + discover that /tmp actually is a directory. This is the same behaviour + as the os.path.dirname() and os.path.basename() functions in the Python + library. + */ + + std::string dirname(const std::string& fname); + std::string basename(const std::string& fname); + std::string extension(const std::string& fname); + } + } +} + + +#endif diff --git a/ThirdParty/Ert/lib/private-include/detail/util/string_util.hpp b/ThirdParty/Ert/lib/private-include/detail/util/string_util.hpp new file mode 100644 index 0000000000..a4ba46ed08 --- /dev/null +++ b/ThirdParty/Ert/lib/private-include/detail/util/string_util.hpp @@ -0,0 +1,13 @@ +#ifndef ECL_STRING_UTIL +#define ECL_STRING_UTIL + + +#include +namespace ecl { + namespace util { + std::string string_format(const char * fmt, ...); + } +} + + +#endif diff --git a/ThirdParty/Ert/lib/src/fortio.cpp b/ThirdParty/Ert/lib/src/fortio.cpp new file mode 100644 index 0000000000..19ee477d36 --- /dev/null +++ b/ThirdParty/Ert/lib/src/fortio.cpp @@ -0,0 +1,411 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace { + +/* + * re-implement host <-> network (big-endian) swap functions, because the + * arpa/inet.h htons and friends don't have 8-byte equivalents, and ecl deals a + * lot with double-precision floats. + */ +#ifdef HOST_BIG_ENDIAN + +template< typename T > constexpr T hton( T value ) noexcept { return value; } +template< typename T > constexpr T ntoh( T value ) noexcept { return value; } + +#else + +template< typename T > +constexpr typename std::enable_if< sizeof(T) == 1, T >::type +hton( T value ) noexcept { + return value; +} + +template< typename T > +constexpr typename std::enable_if< sizeof(T) == 2, T >::type +hton( T value ) noexcept { + return ((value & 0x00FF) << 8) + | ((value & 0xFF00) >> 8) + ; +} + +template< typename T > +constexpr typename std::enable_if< sizeof(T) == 4, T >::type +hton( T value ) noexcept { + return ((value & 0x000000FF) << 24) + | ((value & 0x0000FF00) << 8) + | ((value & 0x00FF0000) >> 8) + | ((value & 0xFF000000) >> 24) + ; +} + +template< typename T > +constexpr typename std::enable_if< sizeof(T) == 8, T >::type +hton( T value ) noexcept { + return ((value & 0xFF00000000000000ull) >> 56) + | ((value & 0x00FF000000000000ull) >> 40) + | ((value & 0x0000FF0000000000ull) >> 24) + | ((value & 0x000000FF00000000ull) >> 8) + | ((value & 0x00000000FF000000ull) << 8) + | ((value & 0x0000000000FF0000ull) << 24) + | ((value & 0x000000000000FF00ull) << 40) + | ((value & 0x00000000000000FFull) << 56) + ; +} + +// preserve the ntoh name for symmetry +template< typename T > +constexpr T ntoh( T value ) noexcept { + return hton( value ); +} + +#endif + +/* + * Functions in fortio will try and roll back as much state as possible in case + * of errors, to provide some exception safety. Since these error paths are + * more cleanly handled with returned, the rollback is tied to the fguard's + * destructor. + * + * However, if the rollback itself fails, the file is left in an unspecific + * state, but we have no immediate way to report that, as the destructor does + * not return a value. Instead, an exception is thrown, and all function use + * function-try-blocks. While it's generally bad practice to throw from + * destructors, the eclfio functions are extern C'd, and no exceptions leak. + * Since there are no other destructors run from these functions than that of + * fguard, the destructor-exception is ok, since it never happens during stack + * unwinding. + * + * A string-less exception type is used, and std::exception() is noexcept in + * C++11. + */ +struct fguard { + FILE* fp; + std::fpos_t pos; + + fguard( FILE* x ) : fp( x ) { + const auto err = std::fgetpos( fp, &this->pos ); + + if( err ) { + /* + * when fgetpos fails, presumably everything is broken and we + * didn't even record our previous position. no point even trying + * to roll back from this, so set fp to nullptr and bail + */ + this->fp = nullptr; + throw std::exception(); + } + } + + ~fguard() noexcept( false ) { + if( !this->fp ) return; + + const auto err = std::fsetpos( fp, &this->pos ); + if( err ) throw std::exception(); + } +}; + +struct options { + bool bigendian = true; + bool size_limit = true; + int elemsize = sizeof( std::int32_t ); + + // transform by default unless record is nullptr and this record should be + // skipped + bool transform = true; + bool force_notail = false; + bool allow_notail = false; +}; + +options parse_opts( const char* opts ) noexcept { + options o; + + for( const char* op = opts; *op != '\0'; ++op ) { + switch( *op ) { + case 'c': o.elemsize = sizeof( char ); break; + case 'i': o.elemsize = sizeof( std::int32_t ); break; + case 'f': o.elemsize = sizeof( float ); break; + case 'd': o.elemsize = sizeof( double ); break; + + case 'E': o.bigendian = true; break; + case 'e': o.bigendian = false; break; + + case 't': o.transform = true; break; + case 'T': o.transform = false; break; + + case '~': o.force_notail = true; break; + case '$': o.allow_notail = true; break; + + case '#': o.size_limit = false; break; + default: break; + } + } + + return o; +} + +/* + * to/from host carefully swaps endianness for a large array. + * + * The switch guarantees that byte swap happens properly, even on platforms + * where sizeof(char) == sizeof(int32), without accidently terminating before, + * relying on hton being well-defined on such platforms. Should any non-char, + * int16, and int32 sizes be passed through, nothing should happen, but + * non-zero is returned. + */ + + +template< typename T > +int to_host( char* ptr, std::int32_t nmemb ) noexcept { + T x; + for( int i = 0; i < nmemb; ++i ) { + std::memcpy( &x, ptr, sizeof( x ) ); + x = ntoh( x ); + std::memcpy( ptr, &x, sizeof( x ) ); + ptr += sizeof( x ); + } + + return 0; +} + +int to_host( void* dst, int size, std::int32_t nmemb ) noexcept { + char* ptr = static_cast< char* >( dst ); + + switch( size ) { + case sizeof( std::int16_t ): + return to_host< std::uint16_t >( ptr, nmemb ); + + case sizeof( std::int32_t ): + return to_host< std::uint32_t >( ptr, nmemb ); + + case sizeof( std::int64_t ): + return to_host< std::uint64_t >( ptr, nmemb ); + + case sizeof( char ): + return 0; + } + + return 1; +} + +int from_host( void* dst, int size, std::int32_t nmemb ) noexcept { + return to_host( dst, size, nmemb ); +} + +} + +int eclfio_sizeof( std::FILE* fp, const char* opts, int32_t* out ) try { + const auto o = parse_opts( opts ); + + fguard guard( fp ); + + std::int32_t size; + const auto read = std::fread( &size, sizeof( size ), 1, fp ); + if( read != 1 ) return ECL_ERR_READ; + + if( o.bigendian ) + to_host( &size, sizeof( size ), 1 ); + + *out = size / o.elemsize; + return ECL_OK; + +} catch( std::exception& ) { + return ECL_ERR_SEEK; +} + +int eclfio_skip( FILE* fp, const char* opts, int n ) try { + fguard guard( fp ); + + // TODO: support backwards skips + if( n < 0 ) return ECL_EINVAL; + + for( int i = 0; i < n; ++i ) { + int err = eclfio_get( fp, opts, nullptr, nullptr ); + if( err ) return err; + } + + guard.fp = nullptr; + return ECL_OK; +} catch( std::exception& ) { + return ECL_ERR_SEEK; +} + +int eclfio_get( std::FILE* fp, + const char* opts, + int32_t* recordsize, + void* record ) try { + + auto o = parse_opts( opts ); + + // if this is a skip, opt out of transform altogether + o.transform = o.transform and bool(record); + o.size_limit = o.size_limit and record and recordsize; + + fguard guard( fp ); + + std::int32_t head; + auto read = std::fread( &head, sizeof( head ), 1, fp ); + if( read != 1 ) return ECL_ERR_READ; + + if( o.bigendian ) + to_host( &head, sizeof( head ), 1 ); + + if( head < 0 ) return ECL_INVALID_RECORD; + if( head % o.elemsize != 0 ) return ECL_INVALID_RECORD; + + if( o.size_limit and head > *recordsize * o.elemsize ) + return ECL_EINVAL; + + if( record ) { + read = std::fread( record, head, 1, fp ); + if( read != 1 ) return ECL_ERR_READ; + } else { + /* read-buffer is zero, so skip this record instead of reading it */ + const auto err = std::fseek( fp, head, SEEK_CUR ); + if( err ) return ECL_ERR_READ; + } + + const auto elems = head / o.elemsize; + + if( o.transform and o.bigendian ) { + if( to_host( record, o.elemsize, elems ) ) + return ECL_EINVAL; + } + + if( o.force_notail ) { + if( recordsize ) *recordsize = elems; + guard.fp = nullptr; + return ECL_OK; + } + + fguard tailguard( fp ); + std::int32_t tail; + read = std::fread( &tail, sizeof( tail ), 1, fp ); + + if( read == 1 and o.bigendian ) + to_host( &tail, sizeof( tail ), 1 ); + + /* + * success; record has a tail, and it matched our head. All is good - + * return and don't rewind. This is the most common case + */ + if( read == 1 and head == tail ) { + if( recordsize ) *recordsize = elems; + tailguard.fp = guard.fp = nullptr; + return ECL_OK; + } + + /* + * read was sucessful, but the tail didn't match. However, missing tails + * are ok, so rewind the tail, and preserve position at end-of-record + */ + if( read == 1 and head != tail and o.allow_notail ) { + if( recordsize ) *recordsize = elems; + guard.fp = nullptr; + return ECL_OK; + } + + /* + * last record, and ok to not have tail. don't rewind as this is a success + */ + if( read != 1 and feof( fp ) and o.allow_notail ) { + if( recordsize ) *recordsize = elems; + guard.fp = tailguard.fp = nullptr; + return ECL_OK; + } + + /* + * read was succesful, but the tail didn't match, so flag the record as + * invalid and rewind + */ + if( read == 1 and head != tail ) + return ECL_INVALID_RECORD; + + /* read failed, but not at end-of-file */ + if( read != 1 and ferror( fp ) ) + return ECL_ERR_READ; + + /* + * The read failed at end-of-file, and we expected a tail. Flag the record + * as invalid and roll back the file pointer + */ + if( read != 1 and feof( fp ) and not o.allow_notail ) + return ECL_INVALID_RECORD; + + return ECL_ERR_UNKNOWN; +} catch( std::exception& ) { + return ECL_ERR_SEEK; +} + +int eclfio_put( std::FILE* fp, + const char* opts, + int nmemb, + const void* record ) try { + + const auto o = parse_opts( opts ); + + if( nmemb < 0 ) return ECL_EINVAL; + + if( std::numeric_limits< std::int32_t >::max() + < std::int64_t(nmemb) * std::int64_t(o.elemsize) ) { + /* + * a huge record (>2G) is being requested, but the 4-byte headers don't + * allow that. consider this an invalid argument and bail + */ + return ECL_EINVAL; + } + + fguard guard( fp ); + + std::int32_t head = o.elemsize * nmemb; + + if( o.bigendian ) + from_host( &head, sizeof( head ), 1 ); + + auto write = std::fwrite( &head, sizeof( head ), 1, fp ); + if( write != 1 ) return ECL_ERR_WRITE; + + const auto size = o.elemsize; + + char buffer[ 4096 ]; + auto* src = static_cast< const char* >( record ); + while( nmemb > 0 ) { + const auto items = std::min( nmemb, int(sizeof(buffer)) / size ); + const auto bytes = items * size; + std::memcpy( buffer, src, bytes ); + + if( o.transform and o.bigendian ) { + if( from_host( buffer, size, items ) ) + return ECL_EINVAL; + } + + write = fwrite( buffer, size, items, fp ); + if( int( write ) != items ) return ECL_ERR_WRITE; + + nmemb -= items; + src += bytes; + } + + + if( o.force_notail ) { + guard.fp = nullptr; + return ECL_OK; + } + + write = std::fwrite( &head, sizeof( head ), 1, fp ); + if( write != 1 ) return ECL_ERR_WRITE; + + guard.fp = nullptr; + return ECL_OK; + +} catch( std::exception& ) { + return ECL_ERR_SEEK; +} diff --git a/ThirdParty/Ert/lib/test/fortio.cpp b/ThirdParty/Ert/lib/test/fortio.cpp new file mode 100644 index 0000000000..4b714beae0 --- /dev/null +++ b/ThirdParty/Ert/lib/test/fortio.cpp @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include + +#include + +#include + +#include "matchers.hpp" + +namespace { + +struct fcloser { + void operator()( std::FILE* fp ) { fclose( fp ); } +}; + +using ufile = std::unique_ptr< std::FILE, fcloser >; + +} + +using Catch::Matchers::Equals; + +TEST_CASE("records with broken tail can be read", "[fortio][f77]") { + ufile handle( std::tmpfile() ); + REQUIRE( handle ); + auto* fp = handle.get(); + + std::vector< std::int32_t > src( 10, 0 ); + const std::int32_t head = sizeof( std::int32_t ) * src.size(); + + for( int i = 0; i < int(src.size()); ++i ) + src[ i ] = i; + + auto elems = std::fwrite( &head, sizeof( head ), 1, fp ); + REQUIRE_THAT( elems, FwriteCount( 1 ) ); + + elems = std::fwrite( src.data(), sizeof( head ), src.size(), fp ); + REQUIRE_THAT( elems, FwriteCount( src.size() ) ); + + std::int32_t size = src.size(); + + for( bool write_tail : { true, false } ) SECTION( + write_tail + ? "tail is valid, but mismatch with head" + : "tail is missing" ) { + + if( write_tail ) { + auto tail = head + 1; + auto elems = std::fwrite( &tail, sizeof( head ), 1, fp ); + REQUIRE_THAT( elems, FwriteCount( 1 ) ); + } + + SECTION("querying size is not affected") { + std::rewind( fp ); + + Err err = eclfio_sizeof( fp, "e", &size ); + CHECK( err == Err::ok() ); + CHECK( size == 10 ); + } + + SECTION("failure with strict read") { + std::rewind( fp ); + auto out = src; + const auto pos = std::ftell( fp ); + + Err err = eclfio_get( fp, "e", &size, out.data() ); + CHECK( err == Err::invalid_record() ); + CHECK( size == 10 ); + CHECK( pos == std::ftell( fp ) ); + } + + SECTION("success with allow-notail ($)") { + std::rewind( fp ); + auto out = src; + const auto pos = std::ftell( fp ); + + Err err = eclfio_get( fp, "e$", &size, out.data() ); + CHECK( err == Err::ok() ); + CHECK( size == 10 ); + CHECK( pos < std::ftell( fp ) ); + CHECK_THAT( out, Equals( src ) ); + } + + SECTION("success with force-notail (~)") { + std::rewind( fp ); + auto out = src; + const auto pos = std::ftell( fp ); + + Err err = eclfio_get( fp, "e~", &size, out.data() ); + CHECK( err == Err::ok() ); + CHECK( size == 10 ); + CHECK( pos < std::ftell( fp ) ); + CHECK_THAT( out, Equals( src ) ); + } + } +} + +TEST_CASE("record with valid, but wrong head", "[fortio][f77]") { + ufile handle( std::tmpfile() ); + REQUIRE( handle ); + auto* fp = handle.get(); + + std::vector< std::int32_t > src( 10, 0 ); + const std::int32_t head = sizeof(std::int32_t) * (src.size() + 2) ; + + auto elems = std::fwrite( &head, sizeof( head ), 1, fp ); + REQUIRE_THAT( elems, FwriteCount( 1 ) ); + + elems = std::fwrite( src.data(), sizeof( head ), src.size(), fp ); + REQUIRE_THAT( elems, FwriteCount( src.size() ) ); + + std::rewind( fp ); + const auto pos = std::ftell( fp ); + std::vector< std::int32_t > out( head, 0 ); + std::int32_t size = out.size(); + Err err = eclfio_get( fp, "e", &size, out.data() ); + + CHECK( err == Err::read() ); + CHECK( pos == std::ftell( fp ) ); + CHECK( size == out.size() ); +} + +TEST_CASE("record with invalid head", "[fortio][f77]") { + ufile handle( std::tmpfile() ); + REQUIRE( handle ); + auto* fp = handle.get(); + + std::vector< std::int32_t > src( 10, 0 ); + + for( std::int32_t head : { -4, 11 } ) SECTION( + head < 0 + ? "negative length" + : "length not multiple of element size" ) { + + auto elems = std::fwrite( &head, sizeof( head ), 1, fp ); + REQUIRE_THAT( elems, FwriteCount( 1 ) ); + + const std::vector< std::int32_t > src( 10, 0 ); + elems = std::fwrite( src.data(), sizeof( head ), src.size(), fp ); + REQUIRE_THAT( elems, FwriteCount( src.size() ) ); + + std::rewind( fp ); + const auto pos = std::ftell( fp ); + std::int32_t size = src.size(); + Err err = eclfio_get( fp, "e", nullptr, nullptr ); + + CHECK( err == Err::invalid_record() ); + CHECK( pos == std::ftell( fp ) ); + CHECK( size == src.size() ); + } +} diff --git a/ThirdParty/Ert/lib/test/matchers.hpp b/ThirdParty/Ert/lib/test/matchers.hpp new file mode 100644 index 0000000000..3539d178a8 --- /dev/null +++ b/ThirdParty/Ert/lib/test/matchers.hpp @@ -0,0 +1,73 @@ +#ifndef ECL_TEST_MATCHERS_HPP +#define ECL_TEST_MATCHERS_HPP + +#include +#include + +#include + +class FstreamCount : public Catch::MatcherBase< int > { + public: + FstreamCount( int ex ) : expected( ex ) {} + + virtual bool match( const int& count ) const override { + return count == this->expected; + } + + protected: + int expected; +}; + +struct FreadCount : public FstreamCount { + using FstreamCount::FstreamCount; + virtual std::string describe() const override { + return "elems read, expected " + std::to_string( this->expected ); + } +}; + +struct FwriteCount : public FstreamCount { + using FstreamCount::FstreamCount; + + virtual std::string describe() const override { + return "elems written, expected " + std::to_string( this->expected ); + } +}; + +struct Err { + Err( int ex ) : expected( ex ) {} + + bool operator == ( Err other ) const { + return this->expected == other.expected; + } + bool operator != ( Err other ) const { + return !(*this == other); + } + + static Err ok() { return ECL_OK; } + static Err invalid_record() { return ECL_INVALID_RECORD; } + static Err read() { return ECL_ERR_READ; } + + int expected; +}; + +namespace Catch { +template<> +struct StringMaker< Err > { + static std::string convert( const Err& err ) { + switch( err.expected ) { + case ECL_OK: return "OK"; + case ECL_ERR_SEEK: return "SEEK"; + case ECL_ERR_READ: return "READ"; + case ECL_ERR_WRITE: return "WRITE"; + case ECL_INVALID_RECORD: return "INVALID RECORD"; + case ECL_EINVAL: return "INVALID ARGUMENT"; + case ECL_ERR_UNKNOWN: return "UNKNOWN"; + } + + return "Unknown error"; + } +}; + +} + +#endif //ECL_TEST_MATCHERS_HPP diff --git a/ThirdParty/Ert/lib/test/testsuite.cpp b/ThirdParty/Ert/lib/test/testsuite.cpp new file mode 100644 index 0000000000..4c506ba004 --- /dev/null +++ b/ThirdParty/Ert/lib/test/testsuite.cpp @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN +#include diff --git a/ThirdParty/Ert/lib/util/TestArea.cpp b/ThirdParty/Ert/lib/util/TestArea.cpp deleted file mode 100644 index afd204f9ea..0000000000 --- a/ThirdParty/Ert/lib/util/TestArea.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - Copyright (C) 2016 Statoil ASA, Norway. - - This is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ -#include - -#include -#include -#include -#include -#include - -namespace ERT { - - TestArea::TestArea( ) - { - } - - TestArea::TestArea( const std::string& name ) - { - enter( name ); - } - - void TestArea::enter( const std::string& name ) { - c_ptr.reset( test_work_area_alloc( name.c_str() )); - } - - void TestArea::setStore(bool store) { - assertOpen(); - test_work_area_set_store( c_ptr.get() , store ); - } - - std::string TestArea::getOriginalCwd() const { - assertOpen(); - std::string orgCwd( test_work_area_get_original_cwd( c_ptr.get() )); - return orgCwd; - } - - - std::string TestArea::getCwd() const { - char * cwd_ptr = util_alloc_cwd( ); - std::string cwd( cwd_ptr ); - free( cwd_ptr ); - return cwd; - } - - - std::string TestArea::inputPath( const std::string& path) const { - assertOpen(); - { - char * ptr = test_work_area_alloc_input_path( c_ptr.get() , path.c_str()); - std::string input_path( ptr ); - free( ptr ); - return input_path; - } - } - - - void TestArea::assertOpen() const { - if (!c_ptr) - throw std::runtime_error("Must call TestArea::enter( \"name\" ) before invoking copy operations"); - } - - void TestArea::assertFileExists( const std::string& filename ) const { - std::string input_file = inputPath( filename ); - if (!util_is_file( input_file.c_str() )) - throw std::invalid_argument("File " + filename + " does not exist "); - } - - void TestArea::assertDirectoryExists( const std::string& directory ) const { - std::string input_dir = inputPath( directory ); - if (!util_is_directory( input_dir.c_str() )) - throw std::invalid_argument("Directory " + directory + " does not exist "); - } - - void TestArea::assertEntryExists( const std::string& entry ) const { - std::string input_entry = inputPath( entry ); - if (!util_entry_exists( input_entry.c_str() )) - throw std::invalid_argument("Entry " + entry+ " does not exist "); - } - - - void TestArea::copyFile( const std::string& filename ) const { - assertFileExists( filename ); - test_work_area_copy_file( c_ptr.get() , filename.c_str() ); - } - - - void TestArea::copyDirectory( const std::string& directory) const { - assertDirectoryExists( directory ); - test_work_area_copy_directory( c_ptr.get() , directory.c_str() ); - } - - void TestArea::copyDirectoryContent( const std::string& directory) const { - assertDirectoryExists( directory ); - test_work_area_copy_directory_content( c_ptr.get() , directory.c_str() ); - } - - void TestArea::copyParentContent( const std::string& entry ) const { - assertEntryExists( entry ); - test_work_area_copy_parent_content( c_ptr.get() , entry.c_str() ); - } - - void TestArea::copyParentDirectory( const std::string& entry ) const { - assertEntryExists( entry ); - test_work_area_copy_parent_directory( c_ptr.get() , entry.c_str() ); - } - -} - diff --git a/ThirdParty/Ert/lib/util/arg_pack.cpp b/ThirdParty/Ert/lib/util/arg_pack.cpp deleted file mode 100644 index e204c11be0..0000000000 --- a/ThirdParty/Ert/lib/util/arg_pack.cpp +++ /dev/null @@ -1,661 +0,0 @@ -/* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'arg_pack.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#include -#include -#include -#include - -#include -#include -#include - - -/** - This file implements an arg_pack structure which is a small - convienence utility to pack several arguments into one - argument. The generic use situtation is when calling functions like - e.g. pthread_create() which take one (void *) as argument. You can - then pack several arguments into one arg_pack instance, and then - unpack them at the other end. - - The content of the arg_pack is mainly inserted by appending, in - addition it is possible to insert new items by using _iset() - functions, however these functions will fail hard if the resulting - call sequence will lead to holes in the structure, i.e. - - arg_pack_type * arg_pack = arg_pack_alloc() - arg_pack_append_int( arg_pack , 1); - arg_pack_iset_int( arg_pack , 3 , 0); <--- Will fail hard because - elements 1,2,3 have not been set. - - - When you take them out again that is done with indexed get. - - When elements are inserted into the arg_pack, they are inserted - with a (limited) type information (implictly given by the function - invoked to insert the argument), and the corresponding typed get - must be used to unpack the argument again afterwards. The - excepetion is with the function arg_pack_iget_adress() which can be - used to extract the reference of a scalar. - - - - Example: - -------- - - void some_function(const char * arg1 , int arg2 , double arg3) { - ..... - } - - - void some_function__(void * __arg_pack) { - arg_pack_type * arg_pack = arg_pack_safe_cast( __arg_pack ); - const char * arg1 = arg_pack_iget_ptr( arg_pack , 0); - int arg2 = arg_pack_iget_int( arg_pack , 1); - double arg3 = arg_pack_iget_double(arg_pack , 2); - - some_function( arg1 , arg2 , arg3 ); - } - - - ..... - arg_pack_type * arg_pack = arg_pack_alloc(); - arg_pack_append_ptr(arg_pack , "ARG1"); - arg_pack_append_int(arg_pack , 1); - arg_pack_append_double(arg_pack , 3.14159265); - - pthread_create( , , some_function__ , arg_pack); - -*/ - - - - -#define ARG_PACK_TYPE_ID 668268 - - -typedef struct { - void * buffer; /* This is the actual content - can either point to a remote object, or to storage managed by the arg_pack instance. */ - node_ctype ctype; /* The type of the data which is stored. */ - arg_node_free_ftype * destructor; /* destructor called on buffer - can be NULL. */ - arg_node_copyc_ftype * copyc; /* copy constructor - will typically be NULL. */ -} arg_node_type; - - - -struct arg_pack_struct { - UTIL_TYPE_ID_DECLARATION; - int size; /* The number of arguments appended to this arg_pack instance. */ - int alloc_size; /* The number of nodes allocated to this arg_pack - will in general be greater than size. */ - bool locked; /* To insure against unwaranted modifictaions - you can explicitly lock the arg_pack instance. This only */ - arg_node_type **nodes; /* Vector of nodes */ -}; - - -/*****************************************************************/ -/* First comes the arg_node functions. These are all fully static.*/ - -static arg_node_type * arg_node_alloc_empty() { - arg_node_type * node = (arg_node_type*)util_malloc( sizeof * node ); - node->buffer = NULL; - node->destructor = NULL; - node->ctype = CTYPE_INVALID; - return node; -} - - -static void arg_node_realloc_buffer(arg_node_type * node , int new_size) { - node->buffer = util_realloc(node->buffer , new_size ); -} - - -static void __arg_node_assert_type(const arg_node_type * node , node_ctype arg_type) { - if (arg_type != node->ctype) - util_abort("%s: asked for type:\'%s\' inserted as:\'%s\' - aborting \n" , __func__ , node_ctype_name(arg_type) , node_ctype_name(node->ctype)); -} - - - -/*****************************************************************/ -#define ARG_NODE_GET_RETURN(type) \ -{ \ - type value; \ - memcpy(&value , node->buffer , sizeof value); \ - return value; \ -} - - -static int arg_node_get_int( const arg_node_type * node) { - __arg_node_assert_type( node , CTYPE_INT_VALUE ); - ARG_NODE_GET_RETURN( int ) -} - -static char arg_node_get_char( const arg_node_type * node) { - __arg_node_assert_type( node , CTYPE_CHAR_VALUE ); - ARG_NODE_GET_RETURN( char ) -} - -static double arg_node_get_double( const arg_node_type * node) { - __arg_node_assert_type( node , CTYPE_DOUBLE_VALUE ); - ARG_NODE_GET_RETURN( double ) -} - -static float arg_node_get_float( const arg_node_type * node) { - __arg_node_assert_type( node , CTYPE_FLOAT_VALUE ); - ARG_NODE_GET_RETURN( float ) -} - -static bool arg_node_get_bool( const arg_node_type * node) { - __arg_node_assert_type( node , CTYPE_BOOL_VALUE ); - ARG_NODE_GET_RETURN( bool ) -} - -static size_t arg_node_get_size_t( const arg_node_type * node) { - __arg_node_assert_type( node , CTYPE_SIZE_T_VALUE ); - ARG_NODE_GET_RETURN( size_t ) -} -#undef ARG_NODE_GET_RETURN - -/** - If the argument is inserted as a pointer, you must use get_ptr == - true, otherwise you must use get_ptr == false, and this will give - you the adress of the scalar. - - Observe that if you call XX_get_ptr() on a pointer which is still - owned by the arg_pack, you must be careful when freeing the - arg_pack, as that will delete the pointer you are using as well. -*/ - - -static void * arg_node_get_ptr(const arg_node_type * node , bool get_ptr) { - if (get_ptr) { - if (node->ctype != CTYPE_VOID_POINTER) - util_abort("%s: tried to get pointer from something not a pointer\n",__func__); - } else { - if (node->ctype == CTYPE_VOID_POINTER) - util_abort("%s: tried to get adress to something already a ponter\n",__func__); - } - return node->buffer; -} - - -static node_ctype arg_node_get_ctype( const arg_node_type * arg_node ) { - return arg_node->ctype; -} - -/*****************************************************************/ -/* SET functions. */ - - -#define ARG_NODE_SET(node , value) \ - arg_node_realloc_buffer(node , sizeof value); \ - memcpy(node->buffer , &value , sizeof value); \ - node->destructor = NULL; - - -static void arg_node_set_int( arg_node_type * node , int value) { - ARG_NODE_SET( node , value ); - node->ctype = CTYPE_INT_VALUE; -} - - -static void arg_node_set_char( arg_node_type * node , char value) { - ARG_NODE_SET( node , value ); - node->ctype = CTYPE_CHAR_VALUE; -} - - -static void arg_node_set_float( arg_node_type * node , float value) { - ARG_NODE_SET( node , value ); - node->ctype = CTYPE_FLOAT_VALUE; -} - - -static void arg_node_set_double( arg_node_type * node , double value) { - ARG_NODE_SET( node , value ); - node->ctype = CTYPE_DOUBLE_VALUE; -} - - -static void arg_node_set_bool( arg_node_type * node , bool value) { - ARG_NODE_SET( node , value ); - node->ctype = CTYPE_BOOL_VALUE; -} - - -static void arg_node_set_size_t( arg_node_type * node , size_t value) { - ARG_NODE_SET( node , value ); - node->ctype = CTYPE_SIZE_T_VALUE; -} - -#undef ARG_NODE_SET - - -static void arg_node_set_ptr(arg_node_type * node , const void * ptr , arg_node_copyc_ftype * copyc , arg_node_free_ftype * destructor) { - node->ctype = CTYPE_VOID_POINTER; - node->destructor = destructor; - node->copyc = copyc; - if (copyc != NULL) - node->buffer = copyc( ptr ); - else - node->buffer = (void *) ptr; -} - - - -/*****************************************************************/ - - -static void arg_node_clear(arg_node_type * node) { - if (node->ctype == CTYPE_VOID_POINTER) { - if (node->destructor != NULL) - node->destructor( node->buffer ); - /* When you have cleared - must not reuse the thing. */ - node->destructor = NULL; - node->buffer = NULL; - node->copyc = NULL; - } -} - - -static void arg_node_free(arg_node_type * node) { - arg_node_clear(node); - util_safe_free(node->buffer); - free(node); -} - - - -static const char * arg_node_fmt(const arg_node_type *node) { - switch (node->ctype) { - case(CTYPE_INT_VALUE): - return " %d"; - break; - case(CTYPE_DOUBLE_VALUE): - return " %lg"; - break; - case(CTYPE_FLOAT_VALUE): - return " %g"; - break; - case(CTYPE_BOOL_VALUE): - return " %d"; - break; - case(CTYPE_CHAR_VALUE): - return " %d"; - break; - case(CTYPE_SIZE_T_VALUE): - return " %d"; - break; - default: - util_abort("%s: arg_type:%d not recognized for scanning \n",__func__ , node->ctype); - return ""; /* Dummy to shut up compiler */ - } -} - - -static void arg_node_fprintf(const arg_node_type * node , FILE * stream) { - switch (node->ctype) { - case(CTYPE_INT_VALUE): - fprintf(stream , "int:%d",arg_node_get_int(node)); - break; - case(CTYPE_DOUBLE_VALUE): - fprintf(stream , "double:%g",arg_node_get_double(node)); - break; - case(CTYPE_VOID_POINTER): - fprintf(stream , "pointer:<%p>",arg_node_get_ptr( node , true )); - break; - case(CTYPE_BOOL_VALUE): - fprintf(stream , "bool:%d", arg_node_get_bool( node )); - break; - default: - util_abort("%s: - not implemented for type:%d \n",__func__ , node->ctype); - } -} - - -/*****************************************************************/ -/* Ending node node functions - starting on functons for the whole pack. */ -/*****************************************************************/ - -UTIL_SAFE_CAST_FUNCTION( arg_pack , ARG_PACK_TYPE_ID) -UTIL_SAFE_CAST_FUNCTION_CONST( arg_pack , ARG_PACK_TYPE_ID) -UTIL_IS_INSTANCE_FUNCTION(arg_pack , ARG_PACK_TYPE_ID) - -static void __arg_pack_assert_index(const arg_pack_type * arg , int iarg) { - if (iarg < 0 || iarg >= arg->size) - util_abort("%s: arg_pack() object filled with %d arguments - %d invalid argument number - aborting \n",__func__ , arg->size , iarg); -} - - -static void arg_pack_realloc_nodes(arg_pack_type * arg_pack , int new_size) { - arg_pack->nodes = (arg_node_type**) util_realloc(arg_pack->nodes , new_size * sizeof * arg_pack->nodes ); - { - int i; - for (i = arg_pack->alloc_size; i < new_size; i++) - arg_pack->nodes[i] = arg_node_alloc_empty(); - } - arg_pack->alloc_size = new_size; -} - - -/** - The name of this function is QUITE MISLEADING; the function will - create a new node, with index @index, and return it possibly - freeing the existing with this index. If index == arg_pack->size a - new node will be created at the end of the arg_pack; if index > - arg_pack->size the function will fail hard. -*/ -static arg_node_type * arg_pack_iget_new_node( arg_pack_type * arg_pack , int index) { - if (index < 0 || index > arg_pack->size) - util_abort("%s: index:%d invalid. Valid interval: [0,%d) \n",__func__ , index , arg_pack->size); - { - if (index < arg_pack->size) { - arg_node_free( arg_pack->nodes[index] ); /* Free the existing current node. */ - arg_pack->nodes[index] = arg_node_alloc_empty( ); /* Allocate a new fresh instance. */ - } - - if (arg_pack->size == arg_pack->alloc_size) - arg_pack_realloc_nodes(arg_pack , 1 + arg_pack->alloc_size * 2); /* We have to grow the vector of nodes. */ - - if (index == arg_pack->size) - arg_pack->size++; /* We are asking for the first element beyond the current length of the vector, i.e. append. */ - return arg_pack->nodes[index]; - } -} - - - -static arg_node_type * arg_pack_get_append_node(arg_pack_type * arg_pack) { - if (arg_pack->locked) { - util_abort("%s: tryng to append to a locked arg_pack instance \n",__func__); - return NULL; - } - { - arg_node_type * new_node = arg_pack_iget_new_node( arg_pack , arg_pack->size ); - return new_node; - } -} - - -void arg_pack_lock(arg_pack_type * arg_pack) { - arg_pack->locked = true; -} - - - -arg_pack_type * arg_pack_alloc() { - arg_pack_type * arg_pack = (arg_pack_type*)util_malloc(sizeof * arg_pack ); - UTIL_TYPE_ID_INIT( arg_pack , ARG_PACK_TYPE_ID); - arg_pack->nodes = NULL; - arg_pack->alloc_size = 0; - arg_pack->locked = false; - arg_pack_realloc_nodes(arg_pack , 4); - arg_pack_clear(arg_pack); - return arg_pack; -} - - -void arg_pack_free(arg_pack_type * arg_pack) { - int i; - - for (i=0; i < arg_pack->alloc_size; i++) - arg_node_free( arg_pack->nodes[i] ); - - free(arg_pack->nodes); - free(arg_pack); -} - - -void arg_pack_free__(void * __arg_pack) { - arg_pack_type * arg_pack = arg_pack_safe_cast( __arg_pack ); - arg_pack_free( arg_pack ); -} - - - -void arg_pack_clear(arg_pack_type * arg_pack) { - if (arg_pack->locked) - util_abort("%s: arg_pack has been locked - abortng \n",__func__); - { - int i; - for ( i=0; i < arg_pack->size; i++) - arg_node_clear(arg_pack->nodes[i]); - arg_pack->size = 0; - } -} - - -/******************************************************************/ -/* Access functions: - - 1. Append - 2. iget - 3. iset (can NOT create holes in the vector) - -******************************************************************/ - -#define APPEND_TYPED(type) \ -void arg_pack_append_ ## type (arg_pack_type *pack , type value) { \ - arg_node_type * node = arg_pack_get_append_node( pack ); \ - arg_node_set_ ## type(node , value); \ -} - - -#define ISET_TYPED(type)\ -void arg_pack_iset_ ## type(arg_pack_type * pack, int index, type value) { \ - arg_node_type * node = arg_pack_iget_new_node( pack , index); \ - arg_node_set_ ## type(node , value); \ -} - - -#define IGET_TYPED(type)\ -type arg_pack_iget_ ## type(const arg_pack_type * pack, int index) { \ - __arg_pack_assert_index( pack , index); \ - { \ - arg_node_type * node = pack->nodes[index]; \ - return arg_node_get_ ## type ( node ); \ - } \ -} - - -APPEND_TYPED(int); -APPEND_TYPED(bool); -APPEND_TYPED(float); -APPEND_TYPED(double); -APPEND_TYPED(char); -APPEND_TYPED(size_t); - -IGET_TYPED(int); -IGET_TYPED(bool); -IGET_TYPED(float); -IGET_TYPED(double); -IGET_TYPED(char); -IGET_TYPED(size_t); - -ISET_TYPED(int); -ISET_TYPED(bool); -ISET_TYPED(float); -ISET_TYPED(double); -ISET_TYPED(char); -ISET_TYPED(size_t); - -#undef APPEND_TYPED -#undef IGET_TYPED -#undef ISET_TYPED - - -void * arg_pack_iget_ptr(const arg_pack_type * arg , int iarg) { - __arg_pack_assert_index(arg , iarg); - return arg_node_get_ptr(arg->nodes[iarg] , true); -} - - -const void * arg_pack_iget_const_ptr(const arg_pack_type * arg , int iarg) { - __arg_pack_assert_index(arg , iarg); - return arg_node_get_ptr(arg->nodes[iarg] , true); -} - - -void * arg_pack_iget_adress(const arg_pack_type * arg , int iarg) { - __arg_pack_assert_index(arg , iarg); - return arg_node_get_ptr(arg->nodes[iarg] , false); -} - - -node_ctype arg_pack_iget_ctype(const arg_pack_type * arg_pack ,int index) { - __arg_pack_assert_index(arg_pack , index); - return arg_node_get_ctype( arg_pack->nodes[index] ); -} - -/*****************************************************************/ - - -void arg_pack_iset_copy(arg_pack_type * arg_pack , int index , const void * ptr, arg_node_copyc_ftype * copyc , arg_node_free_ftype * freef) { - arg_node_type * node = arg_pack_iget_new_node( arg_pack , index ); - arg_node_set_ptr(node , ptr , copyc , freef); -} - - -void arg_pack_iset_ptr(arg_pack_type * arg_pack, int index , const void * ptr) { - arg_pack_iset_copy(arg_pack , index , ptr , NULL , NULL); -} - -void arg_pack_iset_owned_ptr(arg_pack_type * arg_pack, int index , void * ptr, arg_node_free_ftype * freef) { - arg_pack_iset_copy(arg_pack , index , ptr , NULL , freef ); -} - - -void arg_pack_append_copy(arg_pack_type * arg_pack , void * ptr, arg_node_copyc_ftype * copyc , arg_node_free_ftype * freef) { - arg_pack_iset_copy( arg_pack , arg_pack->size , ptr , copyc , freef); -} - - -void arg_pack_append_ptr(arg_pack_type * arg_pack, void * ptr) { - arg_pack_iset_ptr( arg_pack , arg_pack->size , ptr ); -} - -void arg_pack_append_const_ptr(arg_pack_type * arg_pack, const void * ptr) { - arg_pack_iset_ptr( arg_pack , arg_pack->size , ptr ); -} - - -void arg_pack_append_owned_ptr(arg_pack_type * arg_pack, void * ptr, arg_node_free_ftype * freef) { - arg_pack_iset_owned_ptr( arg_pack , arg_pack->size , ptr , freef); -} - -int arg_pack_size( const arg_pack_type * arg_pack ) { - return arg_pack->size; -} - -/******************************************************************/ -/* Functions for formatted reading/writing of arg_pack instances. */ - - - -void arg_pack_fscanf(arg_pack_type * arg , FILE * stream, const char * filename) { - - int scan_count = 0; - int iarg; - char * fmt = NULL; - for (iarg = 0; iarg < arg->size; iarg++) { - arg_node_type * node = arg->nodes[iarg]; - fmt = util_strcat_realloc(fmt , arg_node_fmt(node)); - } - - switch(arg->size) { - case(0): - break; - case(1): - { - void *arg0; - arg0 = arg_pack_iget_adress(arg , 0); - scan_count = fscanf(stream , fmt , arg0); - break; - } - case(2): - { - void *arg0, *arg1; - arg0 = arg_pack_iget_adress(arg , 0); - arg1 = arg_pack_iget_adress(arg , 1); - - scan_count = fscanf(stream , fmt , arg0 , arg1); - break; - } - case(3): - { - void *arg0, *arg1 , *arg2; - arg0 = arg_pack_iget_adress(arg , 0); - arg1 = arg_pack_iget_adress(arg , 1); - arg2 = arg_pack_iget_adress(arg , 2); - - scan_count = fscanf(stream , fmt , arg0 , arg1 , arg2); - break; - } - case(4): - { - void *arg0, *arg1 , *arg2 , *arg3; - arg0 = arg_pack_iget_adress(arg , 0); - arg1 = arg_pack_iget_adress(arg , 1); - arg2 = arg_pack_iget_adress(arg , 2); - arg3 = arg_pack_iget_adress(arg , 3); - - scan_count = fscanf(stream , fmt , arg0 , arg1 , arg2 , arg3); - break; - } - case(5): - { - void *arg0, *arg1 , *arg2 , *arg3, *arg4; - arg0 = arg_pack_iget_adress(arg , 0); - arg1 = arg_pack_iget_adress(arg , 1); - arg2 = arg_pack_iget_adress(arg , 2); - arg3 = arg_pack_iget_adress(arg , 3); - arg4 = arg_pack_iget_adress(arg , 4); - - scan_count = fscanf(stream , fmt , arg0 , arg1 , arg2 , arg3 , arg4); - break; - } - - default: - util_abort("%s: sorry %s not allocated for %d arguments from file %s\n",__func__ , __func__ , arg->size, filename); - - } - - if (scan_count != arg->size) { - util_abort("%s: wanted %d arguments - only found: %d in file %s \n", __func__ , arg->size , scan_count, filename); - } - - free(fmt); -} - - -void arg_pack_fprintf(const arg_pack_type * arg_pack , FILE * stream) { - int iarg; - fprintf(stream," ["); - for (iarg = 0; iarg < arg_pack->size; iarg++) { - arg_node_type * node = arg_pack->nodes[iarg]; - arg_node_fprintf(node , stream); - if (iarg < (arg_pack->size - 1)) - fprintf(stream,", "); - } - fprintf(stream, "]\n"); -} - - - - diff --git a/ThirdParty/Ert/lib/util/buffer.cpp b/ThirdParty/Ert/lib/util/buffer.cpp index a1546dd32f..909b220f91 100644 --- a/ThirdParty/Ert/lib/util/buffer.cpp +++ b/ThirdParty/Ert/lib/util/buffer.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/ThirdParty/Ert/lib/util/config_test_input b/ThirdParty/Ert/lib/util/config_test_input index e2678e013b..2d73c1ce17 100644 --- a/ThirdParty/Ert/lib/util/config_test_input +++ b/ThirdParty/Ert/lib/util/config_test_input @@ -1,5 +1,5 @@ KEY1 ARG1 ARG2 ARG3 -KEY2 emacs /tmp/Gurbat/Ensemble/enkf_mount_info 1 F +KEY2 emacs /tmp/Gurbat/Ensemble/enkf_mount_info 1 F KEY1 PISS OFF KEY2 __RESET__ KEY2 ssXX diff --git a/ThirdParty/Ert/lib/util/cxx_string_util.cpp b/ThirdParty/Ert/lib/util/cxx_string_util.cpp new file mode 100644 index 0000000000..5927039620 --- /dev/null +++ b/ThirdParty/Ert/lib/util/cxx_string_util.cpp @@ -0,0 +1,45 @@ +/* + Copyright (C) 2018 Equinor Statoil ASA, Norway. + + The file 'cxx_string_util.cpp' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ + +#include +#include + + +namespace ecl { + namespace util { + + std::string string_format(const char* fmt, ...) { + int length; + std::string s; + { + va_list va; + va_start(va, fmt); + length = vsnprintf(NULL, 0, fmt, va); + va_end(va); + } + s.resize(length + 1); + { + va_list va; + va_start(va, fmt); + vsprintf((char *) s.data(), fmt, va); + va_end(va); + } + return s; + } + } +} diff --git a/ThirdParty/Ert/lib/util/dependencies b/ThirdParty/Ert/lib/util/dependencies index c1bc2f0f07..797ab904cb 100644 --- a/ThirdParty/Ert/lib/util/dependencies +++ b/ThirdParty/Ert/lib/util/dependencies @@ -1,26 +1,26 @@ -list.o : list.c list.h list_node.o -block_fs.o : block_fs.c block_fs.h hash.o util.o vector.o buffer.o -hash_node.o : hash_node.c hash_node.h util.o node_data.o -menu.o : menu.c menu.h util.o vector.o -buffer.o : buffer.c buffer.h util.o -util.o : util.c util.h util_path.c -stringlist.o : stringlist.c stringlist.h util.o vector.o buffer.o -hash.o : hash.c hash.h hash_sll.o hash_node.o node_data.o util.o stringlist.o -timer.o : timer.c timer.h util.o -arg_pack.o : arg_pack.c arg_pack.h util.o node_ctype.o -node_data.o : node_data.c node_data.h util.o node_ctype.o -matrix.o : matrix.c matrix.h util.o thread_pool.o arg_pack.o -vector.o : vector.c vector.h util.o node_data.o -msg.o : msg.c msg.h util.o -hash_sll.o : hash_sll.c hash_sll.h hash_node.o -subst.o : subst.c subst.h util.o vector.o node_data.o -matrix_blas.o : matrix_blas.c matrix_blas.h util.o matrix.o -matrix_lapack.o : matrix_lapack.c matrix_lapack.h matrix.o util.o -template.o : template.c template.h subst.o -list_node.o : list_node.c list_node.h util.o node_data.o -set.o : set.c set.h hash.o util.o -node_ctype.o : node_ctype.c node_ctype.h -path_fmt.o : path_fmt.c path_fmt.h util.o node_ctype.o -str_buffer.o : str_buffer.c str_buffer.h -thread_pool.o : thread_pool.c thread_pool.h util.o -log.o : log.c log.h util.o +list.o : list.c list.h list_node.o +block_fs.o : block_fs.c block_fs.h hash.o util.o vector.o buffer.o +hash_node.o : hash_node.c hash_node.h util.o node_data.o +menu.o : menu.c menu.h util.o vector.o +buffer.o : buffer.c buffer.h util.o +util.o : util.c util.h util_path.c +stringlist.o : stringlist.c stringlist.h util.o vector.o buffer.o +hash.o : hash.c hash.h hash_sll.o hash_node.o node_data.o util.o stringlist.o +timer.o : timer.c timer.h util.o +arg_pack.o : arg_pack.c arg_pack.h util.o node_ctype.o +node_data.o : node_data.c node_data.h util.o node_ctype.o +matrix.o : matrix.c matrix.h util.o thread_pool.o arg_pack.o +vector.o : vector.c vector.h util.o node_data.o +msg.o : msg.c msg.h util.o +hash_sll.o : hash_sll.c hash_sll.h hash_node.o +subst.o : subst.c subst.h util.o vector.o node_data.o +matrix_blas.o : matrix_blas.c matrix_blas.h util.o matrix.o +matrix_lapack.o : matrix_lapack.c matrix_lapack.h matrix.o util.o +template.o : template.c template.h subst.o +list_node.o : list_node.c list_node.h util.o node_data.o +set.o : set.c set.h hash.o util.o +node_ctype.o : node_ctype.c node_ctype.h +path_fmt.o : path_fmt.c path_fmt.h util.o node_ctype.o +str_buffer.o : str_buffer.c str_buffer.h +thread_pool.o : thread_pool.c thread_pool.h util.o +log.o : log.c log.h util.o diff --git a/ThirdParty/Ert/lib/util/ecl_version.cpp b/ThirdParty/Ert/lib/util/ecl_version.cpp index 24acac01e9..083bd674ba 100644 --- a/ThirdParty/Ert/lib/util/ecl_version.cpp +++ b/ThirdParty/Ert/lib/util/ecl_version.cpp @@ -1,4 +1,4 @@ -#include +#include #include #define xstr(s) #s diff --git a/ThirdParty/Ert/lib/util/ert/util/template_type.h b/ThirdParty/Ert/lib/util/ert/util/template_type.h index 0c56145a5f..330187a2ea 100644 --- a/ThirdParty/Ert/lib/util/ert/util/template_type.h +++ b/ThirdParty/Ert/lib/util/ert/util/template_type.h @@ -1,9 +1,9 @@ #ifndef ERT_TEMPLATE_TYPE_H #define ERT_TEMPLATE_TYPE_H -#include +#include -#include +#include #ifdef ERT_HAVE_REGEXP #include @@ -17,7 +17,7 @@ struct template_struct { char * template_buffer; /* The content of the template buffer; only has valid content if internalize_template == true. */ bool internalize_template; /* Should the template be loadad and internalized at template_alloc(). */ subst_list_type * arg_list; /* Key-value mapping established at alloc time. */ - char * arg_string; /* A string representation of the arguments - ONLY used for a _get_ function. */ + char * arg_string; /* A string representation of the arguments - ONLY used for a _get_ function. */ #ifdef ERT_HAVE_REGEXP regex_t start_regexp; regex_t end_regexp; diff --git a/ThirdParty/Ert/lib/util/hash.cpp b/ThirdParty/Ert/lib/util/hash.cpp index 60b62b6590..05c5a1962e 100644 --- a/ThirdParty/Ert/lib/util/hash.cpp +++ b/ThirdParty/Ert/lib/util/hash.cpp @@ -15,8 +15,6 @@ See the GNU General Public License at for more details. */ - -#define _GNU_SOURCE /* Must define this to get access to pthread_rwlock_t */ #include #include #include @@ -27,7 +25,7 @@ #include #include #include -#include +#include #include @@ -455,8 +453,10 @@ stringlist_type * hash_alloc_stringlist(const hash_type * hash) { stringlist_type * stringlist = stringlist_alloc_new(); char ** keylist = hash_alloc_keylist__(hash); int i; - for (i = 0; i < hash_get_size( hash ); i++) - stringlist_append_owned_ref( stringlist , keylist[i] ); + for (i = 0; i < hash_get_size( hash ); i++) { + stringlist_append_copy( stringlist , keylist[i] ); + free(keylist[i]); + } free( keylist ); return stringlist; @@ -709,8 +709,8 @@ hash_type * hash_alloc_from_options(const stringlist_type * options) { // Warning: could not interpret string as KEY:VALUE - ignored - util_safe_free(option); - util_safe_free(value); + free(option); + free(value); } return opt_hash; @@ -729,7 +729,7 @@ hash_type * hash_alloc_from_options(const stringlist_type * options) { addOK = true; } - util_safe_free( key ); + free( key ); } return addOK; } diff --git a/ThirdParty/Ert/lib/util/hash_node.cpp b/ThirdParty/Ert/lib/util/hash_node.cpp index c77b19f993..1a983e0ba7 100644 --- a/ThirdParty/Ert/lib/util/hash_node.cpp +++ b/ThirdParty/Ert/lib/util/hash_node.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'hash_node.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'hash_node.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include @@ -37,7 +37,7 @@ struct hash_node_struct { node_data_type *data; hash_node_type *next_node; }; - + @@ -52,20 +52,20 @@ bool hash_node_key_eq(const hash_node_type * node , uint32_t global_index , cons } -uint32_t hash_node_get_table_index(const hash_node_type * node) { - return node->table_index; +uint32_t hash_node_get_table_index(const hash_node_type * node) { + return node->table_index; } -uint32_t hash_node_get_global_index(const hash_node_type * node) { - return node->global_index; +uint32_t hash_node_get_global_index(const hash_node_type * node) { + return node->global_index; } -const char * hash_node_get_key(const hash_node_type * node) { - return node->key; +const char * hash_node_get_key(const hash_node_type * node) { + return node->key; } -hash_node_type * hash_node_get_next(const hash_node_type * node) { - return node->next_node; +hash_node_type * hash_node_get_next(const hash_node_type * node) { + return node->next_node; } @@ -82,7 +82,7 @@ uint32_t hash_node_set_table_index(hash_node_type *node , uint32_t table_size) { /*****************************************************************/ /* The three functions below here are the only functions accessing the - data field of the hash_node. + data field of the hash_node. */ node_data_type * hash_node_get_data(const hash_node_type * node) { @@ -96,7 +96,7 @@ hash_node_type * hash_node_alloc_new(const char *key, node_data_type * data, has node->key = util_alloc_string_copy( key ); node->data = data; node->next_node = NULL; - + node->global_index = hashf(node->key , strlen(node->key)); hash_node_set_table_index(node , table_size); return node; diff --git a/ThirdParty/Ert/lib/util/hash_sll.cpp b/ThirdParty/Ert/lib/util/hash_sll.cpp index 569d59f948..6f3ec0f623 100644 --- a/ThirdParty/Ert/lib/util/hash_sll.cpp +++ b/ThirdParty/Ert/lib/util/hash_sll.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'hash_sll.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'hash_sll.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include #include @@ -52,7 +52,7 @@ hash_sll_type ** hash_sll_alloc_table(int size) { void hash_sll_del_node(hash_sll_type *hash_sll , hash_node_type *del_node) { - if (del_node == NULL) + if (del_node == NULL) util_abort("%s: tried to delete NULL node - aborting \n",__func__); { @@ -65,8 +65,8 @@ void hash_sll_del_node(hash_sll_type *hash_sll , hash_node_type *del_node) { } if (node == del_node) { - if (p_node == NULL) - /* + if (p_node == NULL) + /* We are attempting to delete the first element in the list. */ hash_sll->head = hash_node_get_next(del_node); @@ -74,7 +74,7 @@ void hash_sll_del_node(hash_sll_type *hash_sll , hash_node_type *del_node) { hash_node_set_next(p_node , hash_node_get_next(del_node)); hash_node_free(del_node); hash_sll->length--; - } else + } else util_abort("%s: tried to delete node not in list - aborting \n",__func__); } @@ -115,10 +115,10 @@ bool hash_sll_empty(const hash_sll_type * hash_sll) { hash_node_type * hash_sll_get(const hash_sll_type *hash_sll, uint32_t global_index , const char *key) { hash_node_type * node = hash_sll->head; - - while ((node != NULL) && (!hash_node_key_eq(node , global_index , key))) + + while ((node != NULL) && (!hash_node_key_eq(node , global_index , key))) node = hash_node_get_next(node); - + return node; } diff --git a/ThirdParty/Ert/lib/util/lookup_table.cpp b/ThirdParty/Ert/lib/util/lookup_table.cpp index f6d0bdf640..616a54eac6 100644 --- a/ThirdParty/Ert/lib/util/lookup_table.cpp +++ b/ThirdParty/Ert/lib/util/lookup_table.cpp @@ -1,41 +1,41 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'lookup_table.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'lookup_table.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include #include #include struct lookup_table_struct { - bool data_owner; + bool data_owner; double_vector_type * x_vector; double_vector_type * y_vector; const double * x_data; - const double * y_data; - int size; + const double * y_data; + int size; double xmin,ymin; double xmax,ymax; int prev_index; - bool sorted; + bool sorted; bool has_low_limit; bool has_high_limit; double low_limit; @@ -50,7 +50,7 @@ static void lookup_table_sort_data( lookup_table_type * lt) { if (double_vector_get_read_only( lt->x_vector )) if (!double_vector_is_sorted( lt->x_vector , false)) util_abort("%s: x vector is not sorted and read-only - this will not fly\n",__func__); - + { perm_vector_type * sort_perm = double_vector_alloc_sort_perm( lt->x_vector ); double_vector_permute( lt->x_vector , sort_perm ); @@ -72,11 +72,11 @@ static void lookup_table_sort_data( lookup_table_type * lt) { /** IFF the @read_only flag is set to true; the x vector MUST be - sorted. + sorted. */ void lookup_table_set_data( lookup_table_type * lt , double_vector_type * x , double_vector_type * y , bool data_owner ) { - + if (lt->data_owner) { double_vector_free( lt->x_vector ); double_vector_free( lt->y_vector ); @@ -117,12 +117,12 @@ lookup_table_type * lookup_table_alloc( double_vector_type * x , double_vector_t x = double_vector_alloc(0 , 0); y = double_vector_alloc(0 , 0); data_owner = true; - } + } lookup_table_set_data( lt , x , y , false ); lt->data_owner = data_owner; lt->has_low_limit = false; lt->has_high_limit = false; - + return lt; } @@ -147,7 +147,7 @@ void lookup_table_free( lookup_table_type * lt ) { if (lt->data_owner) { double_vector_free( lt->x_vector ); double_vector_free( lt->y_vector ); - } + } free( lt ); } @@ -168,7 +168,7 @@ double lookup_table_interp( lookup_table_type * lt , double x) { double x2 = lt->x_data[ index + 1]; double y1 = lt->y_data[ index ]; double y2 = lt->y_data[ index + 1]; - + lt->prev_index = index; return (( x - x1 ) * y2 + (x2 - x) * y1) / (x2 - x1 ); } @@ -188,7 +188,7 @@ double lookup_table_interp( lookup_table_type * lt , double x) { } } } - + double lookup_table_get_max_value( lookup_table_type * lookup_table ) { diff --git a/ThirdParty/Ert/lib/util/mzran.cpp b/ThirdParty/Ert/lib/util/mzran.cpp index a6c54eb9b4..fd1bc353b5 100644 --- a/ThirdParty/Ert/lib/util/mzran.cpp +++ b/ThirdParty/Ert/lib/util/mzran.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include diff --git a/ThirdParty/Ert/lib/util/node_ctype.cpp b/ThirdParty/Ert/lib/util/node_ctype.cpp index 32aa3790e3..b50ce095fd 100644 --- a/ThirdParty/Ert/lib/util/node_ctype.cpp +++ b/ThirdParty/Ert/lib/util/node_ctype.cpp @@ -1,25 +1,25 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'node_ctype.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'node_ctype.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include diff --git a/ThirdParty/Ert/lib/util/node_data.cpp b/ThirdParty/Ert/lib/util/node_data.cpp index 88af1a6abd..ae7d2a3653 100644 --- a/ThirdParty/Ert/lib/util/node_data.cpp +++ b/ThirdParty/Ert/lib/util/node_data.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'node_data.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'node_data.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include #include #include @@ -34,20 +34,20 @@ struct node_data_struct { node_ctype ctype; void *data; int buffer_size; /* This is to facilitate deep copies of buffers. */ - + /* For the copy constructor and delete operator the logic is very simple: - + if they are present they are used. */ copyc_ftype *copyc; /* Copy constructor - can be NULL. */ - free_ftype *del; /* Destructor - can be NULL. */ + free_ftype *del; /* Destructor - can be NULL. */ }; -/** +/** If the node has a copy constructor, the data is copied immediately - so the node contains a copy from object creation time. */ @@ -63,7 +63,7 @@ static node_data_type * node_data_alloc__(const void * data , node_ctype ctype , node->data = node->copyc( data ); else node->data = (void *) data; - + return node; } @@ -83,25 +83,25 @@ node_data_type * node_data_alloc_buffer(const void * data, int buffer_size) { / /* When calling deep_copy the node MUST have a registered constructor, otherwise it will go belly up. HARD. -*/ +*/ static node_data_type * node_data_copyc(const node_data_type * src , bool deep_copy) { node_data_type * next; if (src->buffer_size > 0) { - /* - The source node has internal storage - it has been allocated with _alloc_buffer() + /* + The source node has internal storage - it has been allocated with _alloc_buffer() */ - if (deep_copy) + if (deep_copy) next = node_data_alloc__(util_alloc_copy( src->data , src->buffer_size ) /* A next copy is allocated prior to insert. */ , src->ctype , src->buffer_size , NULL , free); else next = node_data_alloc__(src->data , src->ctype , src->buffer_size , NULL , NULL); /* The copy does not have destructor. */ } else { if (deep_copy) { - if (src->copyc == NULL) - util_abort("%s: Tried allocate deep_copy of mnode with no constructor - aborting. \n",__func__); + if (src->copyc == NULL) + util_abort("%s: Tried allocate deep_copy of mnode with no constructor - aborting. \n",__func__); next = node_data_alloc__(src->data , src->ctype , 0 , src->copyc , src->del); } else next = node_data_alloc__(src->data , src->ctype , 0 , NULL , NULL); /*shallow copy - we 'hide' constructor and destructor. */ @@ -138,7 +138,7 @@ void node_data_free_container(node_data_type * node_data) { void node_data_free(node_data_type * node_data) { if (node_data->del != NULL) node_data->del( (void *) node_data->data ); - + node_data_free_container( node_data ); } diff --git a/ThirdParty/Ert/lib/util/parser.cpp b/ThirdParty/Ert/lib/util/parser.cpp index 0d1c1fdc11..48b963575e 100644 --- a/ThirdParty/Ert/lib/util/parser.cpp +++ b/ThirdParty/Ert/lib/util/parser.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'parser.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'parser.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include #include #include @@ -33,9 +33,9 @@ struct basic_parser_struct char * splitters; /* The string is split into tokens on the occurence of one of these characters - and they are removed. */ char * specials; /* This exactly like the splitters - but these characters are retained as tokens. */ char * delete_set; /* The chracters are just plain removed - but without any splitting on them. */ - char * quoters; - char * comment_start; - char * comment_end; + char * quoters; + char * comment_start; + char * comment_end; }; @@ -95,19 +95,19 @@ basic_parser_type * basic_parser_alloc( parser->specials = NULL; parser->comment_start = NULL; parser->comment_end = NULL; - + basic_parser_set_splitters( parser , splitters ); basic_parser_set_quoters( parser , quoters ); basic_parser_set_specials( parser , specials ); basic_parser_set_delete_set( parser , delete_set ); basic_parser_set_comment_start( parser , comment_start ); basic_parser_set_comment_end( parser , comment_end ); - + if(comment_start == NULL && comment_end != NULL) util_abort("%s: Need to have comment_start when comment_end is set.\n", __func__); if(comment_start != NULL && comment_end == NULL) util_abort("%s: Need to have comment_end when comment_start is set.\n", __func__); - + return parser; } @@ -115,12 +115,12 @@ basic_parser_type * basic_parser_alloc( void basic_parser_free(basic_parser_type * parser) { - util_safe_free( parser->splitters ); - util_safe_free( parser->quoters ); - util_safe_free( parser->specials ); - util_safe_free( parser->comment_start ); - util_safe_free( parser->comment_end ); - util_safe_free( parser->delete_set ); + free( parser->splitters ); + free( parser->quoters ); + free( parser->specials ); + free( parser->comment_start ); + free( parser->comment_end ); + free( parser->delete_set ); free( parser ); } @@ -205,7 +205,7 @@ static int length_of_quotation( const char * buffer) { { int length = 1; char target = buffer[0]; - char current = buffer[1]; + char current = buffer[1]; bool escaped = false; while(current != '\0' && !(current == target && !escaped )) @@ -218,8 +218,8 @@ static int length_of_quotation( const char * buffer) { if ( current == '\0') /* We ran through the whole string without finding the end of the quotation - abort HARD. */ util_abort("%s: could not find quotation closing on %s \n",__func__ , buffer); - - + + return length; } } @@ -248,7 +248,7 @@ static int length_of_comment( const char * buffer_position, const basic_parser_ while(buffer_position[length] != '\0' && in_comment) { if( strncmp( &buffer_position[length], comment_end, len_comment_end) == 0) { in_comment = false; - length += len_comment_end; + length += len_comment_end; } else length += 1; } @@ -288,12 +288,12 @@ static char * alloc_quoted_token( const char * buffer, int length, bool strip_q -/** +/** This does not care about the possible occurence of characters in the delete_set. That is handled when the token is inserted in the token list. */ - + static int length_of_normal_non_splitters( const char * buffer, const basic_parser_type * parser) { bool at_end = false; int length = 0; @@ -339,7 +339,7 @@ static int length_of_delete( const char * buffer , const basic_parser_type * par /** - Allocates a new stringlist. + Allocates a new stringlist. */ stringlist_type * basic_parser_tokenize_buffer( const basic_parser_type * parser, @@ -353,9 +353,9 @@ stringlist_type * basic_parser_tokenize_buffer( int delete_length = 0; stringlist_type * tokens = stringlist_alloc_new(); - + while( position < buffer_size ) { - /** + /** Skip initial splitters. */ splitters_length = length_of_initial_splitters( &buffer[position], parser ); @@ -374,11 +374,11 @@ stringlist_type * basic_parser_tokenize_buffer( continue; } - + /** - Skip characters which are just deleted. + Skip characters which are just deleted. */ - + delete_length = length_of_delete( &buffer[position] , parser ); if (delete_length > 0) { position += delete_length; @@ -387,7 +387,7 @@ stringlist_type * basic_parser_tokenize_buffer( - /** + /** Copy the character if it is in the special set, */ if( is_special( buffer[position], parser ) ) { @@ -405,8 +405,9 @@ stringlist_type * basic_parser_tokenize_buffer( if( is_in_quoters( buffer[position], parser ) ) { int length = length_of_quotation( &buffer[position] ); char * token = alloc_quoted_token( &buffer[position], length, strip_quote_marks ); - stringlist_append_owned_ref( tokens, token ); + stringlist_append_copy( tokens, token ); position += length; + free(token); continue; } @@ -452,9 +453,9 @@ stringlist_type * basic_parser_tokenize_buffer( if (token_length > 0) { /* We do not insert empty tokens. */ token[token_length] = '\0'; - stringlist_append_owned_ref( tokens, token ); - } else - free( token ); /* The whole thing is discarded. */ + stringlist_append_copy( tokens, token ); + } + free( token ); position += length; continue; @@ -503,13 +504,13 @@ static bool fgetc_while_equal( FILE * stream , const char * string , bool case_s int c = fgetc( stream ); if (!case_sensitive) c = toupper( c ); - + if (c != string[string_index]) { equal = false; break; } } - + if (!equal) /* OK - not equal - go back. */ util_fseek( stream , current_pos , SEEK_SET); return equal; @@ -537,14 +538,14 @@ bool basic_parser_fseek_string(const basic_parser_type * parser , FILE * stream { long int initial_pos = util_ftell( stream ); /* Store the inital position. */ bool cont = true; - + if (strstr( string , parser->comment_start ) != NULL) util_abort("%s: sorry the string contains a comment start - will never find it ... \n",__func__); /* A bit harsh ?? */ - + do { int c = fgetc( stream ); if (!case_sensitive) c = toupper( c ); - + /* Special treatment of quoters - does not properly handle escaping of the quoters. */ if (is_in_quoters( c , parser )) { long int quote_start_pos = util_ftell(stream); @@ -553,13 +554,13 @@ bool basic_parser_fseek_string(const basic_parser_type * parser , FILE * stream fprintf(stderr,"Warning: unterminated quotation starting at line: %d \n",util_get_current_linenr( stream )); util_fseek(stream , 0 , SEEK_END); } - /* + /* Now we are either at the first character following a - terminated quotation, or at EOF. + terminated quotation, or at EOF. */ continue; } - + /* Special treatment of comments: */ if (c == parser->comment_start[0]) { /* OK - this might be the start of a comment - let us check further. */ @@ -567,36 +568,36 @@ bool basic_parser_fseek_string(const basic_parser_type * parser , FILE * stream if (comment_start) { long int comment_start_pos = util_ftell(stream) - strlen( parser->comment_start ); /* Start seeking for comment_end */ - if (!util_fseek_string(stream , parser->comment_end , true , true)) { - /* + if (!util_fseek_string(stream , parser->comment_end , true , true)) { + /* No end comment end was found - what to do about that?? The file is just positioned at the end - and the routine - will exit at the next step - with a Warning. + will exit at the next step - with a Warning. */ util_fseek( stream , comment_start_pos , SEEK_SET); fprintf(stderr,"Warning: unterminated comment starting at line: %d \n",util_get_current_linenr( stream )); util_fseek(stream , 0 , SEEK_END); } continue; /* Now we are at the character following a comment end - or at EOF. */ - } + } } - + /*****************************************************************/ - + /* Now c is a regular character - and we can start looking for our string. */ if (c == string[0]) { /* OK - we got the first character right - lets try in more detail: */ bool equal = fgetc_while_equal( stream , &string[1] , case_sensitive); if (equal) { string_found = true; cont = false; - } + } } - - if (c == EOF) + + if (c == EOF) cont = false; - + } while (cont); - + if (string_found) { if (!skip_string) { offset_type offset = (offset_type) strlen( string ); @@ -617,7 +618,7 @@ bool basic_parser_fseek_string(const basic_parser_type * parser , FILE * stream 1. Quoted content is copied verbatim (this takes presedence). 2. All comment sections are removed. 3. Delete characters are deleted. - + */ @@ -641,16 +642,16 @@ void basic_parser_strip_buffer(const basic_parser_type * parser , char ** __buff continue; } - + /** - Skip characters which are just deleted. + Skip characters which are just deleted. */ delete_length = length_of_delete( &src[src_position] , parser ); if (delete_length > 0) { src_position += delete_length; continue; } - + /* Quotations. */ @@ -665,7 +666,7 @@ void basic_parser_strip_buffer(const basic_parser_type * parser , char ** __buff } /** - OK -it is a god damn normal charactar - copy it straight over: + OK -it is a god damn normal charactar - copy it straight over: */ target[target_position] = src[src_position]; src_position += 1; @@ -673,7 +674,7 @@ void basic_parser_strip_buffer(const basic_parser_type * parser , char ** __buff } target[target_position] = '\0'; target = (char*)util_realloc( target , sizeof * target * (target_position + 1) ); - + free( src ); *__buffer = target; } @@ -694,7 +695,7 @@ void basic_parser_strip_buffer(const basic_parser_type * parser , char ** __buff char * basic_parser_fread_alloc_file_content(const char * filename , const char * quote_set , const char * delete_set , const char * comment_start , const char * comment_end) { basic_parser_type * parser = basic_parser_alloc( NULL , quote_set , NULL , delete_set , comment_start , comment_end); char * buffer = util_fread_alloc_file_content( filename , NULL); - + basic_parser_strip_buffer( parser , &buffer ); basic_parser_free( parser ); return buffer; diff --git a/ThirdParty/Ert/lib/util/path.cpp b/ThirdParty/Ert/lib/util/path.cpp new file mode 100644 index 0000000000..30d206e9e3 --- /dev/null +++ b/ThirdParty/Ert/lib/util/path.cpp @@ -0,0 +1,82 @@ +/* + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'path_stack.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ + +#include + +#include + +#include "detail/util/path.hpp" + +namespace ecl { + + namespace util { + + namespace path { + + /* + The bizarre dive down into c_str() is to avoid inadvertendtly + introducing a symbol which is creates a ABI compatibility issue between + the libstdc++ librararies. A bug in the devtoolset compiler? + */ + + std::string dirname(const std::string& fname) { + size_t last_slash = fname.rfind(UTIL_PATH_SEP_CHAR); + if (last_slash == std::string::npos) + return ""; + + if (last_slash == 0) + return fname.substr(0,1); + else + return fname.substr(0, last_slash); + } + + std::string basename(const std::string& fname) { + size_t end_pos = fname.rfind('.'); + size_t offset = fname.rfind(UTIL_PATH_SEP_CHAR); + if (offset == std::string::npos) + offset = 0; + else + offset += 1; + + { + const char * c_str = fname.c_str(); + if (end_pos == std::string::npos || end_pos < offset) + return util_alloc_string_copy( &c_str[offset] ); + + return util_alloc_substring_copy(c_str, offset, end_pos - offset); + } + } + + + std::string extension(const std::string& fname) { + size_t end_pos = fname.rfind('.'); + size_t last_slash = fname.rfind(UTIL_PATH_SEP_CHAR); + if (end_pos == std::string::npos) + return ""; + + if (last_slash == std::string::npos || end_pos > last_slash) { + const char * c_str = fname.c_str(); + return util_alloc_substring_copy( c_str, end_pos + 1, fname.size() - end_pos - 1); + } + + return ""; + } + + } + } +} diff --git a/ThirdParty/Ert/lib/util/path_stack.cpp b/ThirdParty/Ert/lib/util/path_stack.cpp index 3f71a9191b..9ae4ff9433 100644 --- a/ThirdParty/Ert/lib/util/path_stack.cpp +++ b/ThirdParty/Ert/lib/util/path_stack.cpp @@ -23,8 +23,12 @@ #include #include +#include +#include +#include + #include -#include +#include #include /** @@ -41,8 +45,7 @@ struct path_stack_struct { - stringlist_type * stack; - stringlist_type * storage; + std::stack> stack; }; @@ -52,24 +55,12 @@ struct path_stack_struct { */ path_stack_type * path_stack_alloc() { - path_stack_type * path_stack = (path_stack_type*)util_malloc( sizeof * path_stack ); - path_stack->stack = stringlist_alloc_new(); - path_stack->storage = stringlist_alloc_new(); + path_stack_type * path_stack = new path_stack_type(); return path_stack; } -/* - This will destroy the storage taken by the current path_stack - instance. This function will NOT pop any elements off the stack; so - if you have not manully clerad the stack with the right number of - path_stack_pop() calls, you will (probably) destroy the path stack - instance with an incorrect value of cwd. -*/ - void path_stack_free( path_stack_type * path_stack ) { - stringlist_free( path_stack->stack ); - stringlist_free( path_stack->storage ); - free( path_stack ); + delete path_stack; } @@ -94,28 +85,24 @@ bool path_stack_push( path_stack_type * path_stack , const char * path ) { void path_stack_push_cwd( path_stack_type * path_stack ) { char * cwd = util_alloc_cwd(); - stringlist_append_owned_ref( path_stack->storage , cwd); - stringlist_append_ref( path_stack->stack , cwd ); + path_stack->stack.push(cwd); + free(cwd); } -const char * path_stack_pop( path_stack_type * path_stack ) { - char * path = stringlist_pop( path_stack->stack ); - if (util_chdir( path ) == 0) - return path; - else { +void path_stack_pop( path_stack_type * path_stack ) { + const std::string& path = path_stack->stack.top(); + + if (util_chdir( path.c_str() ) != 0) // The directory has become inaccesible ... - util_abort("%s: could not pop back to directory:%s Error:%s\n", __func__ , path , strerror( errno )); - return NULL; - } + util_abort("%s: could not pop back to directory:%s Error:%s\n", __func__ , path.c_str() , strerror( errno )); + + path_stack->stack.pop(); } int path_stack_size( const path_stack_type * path_stack ) { - return stringlist_get_size( path_stack->stack ); + return path_stack->stack.size(); } -const char * path_stack_peek( const path_stack_type * path_stack ) { - return stringlist_get_last( path_stack->stack ); -} diff --git a/ThirdParty/Ert/lib/util/perm_vector.cpp b/ThirdParty/Ert/lib/util/perm_vector.cpp index 0b6ccde713..459eced207 100644 --- a/ThirdParty/Ert/lib/util/perm_vector.cpp +++ b/ThirdParty/Ert/lib/util/perm_vector.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #define PERM_VECTOR_TYPE_ID 661433 diff --git a/ThirdParty/Ert/lib/util/readme.overview b/ThirdParty/Ert/lib/util/readme.overview index 5b3c3dff52..7e395aaa73 100644 --- a/ThirdParty/Ert/lib/util/readme.overview +++ b/ThirdParty/Ert/lib/util/readme.overview @@ -3,10 +3,10 @@ functionalities. The different libraries depend on eachother, and the libraries must be built in correct order. The dependencies is as follows: -libhash : +libhash : libutil : libhash libecl : libhash libutil -librms : libecl libutil libhash +librms : libecl libutil libhash libsched : libecl linutil libhash libenkf : libecl libsched librm linutil libhash @@ -16,7 +16,7 @@ libhash: This library implements the classes hash_type, set_type and libutil: This library is a collection utility routines. Observe that this library only implements routines, and not statefull - objects. + objects. libecl: This library implements functions for reading/writing ECLIPSE restart/summary/init/grid files. @@ -27,7 +27,7 @@ librms: This library implements (basic) reader and writer for binary RMS ROFF files. libenkf: This library implements various high level objects for EnKF - functionality. + functionality. ----------------------------------------------------------------- diff --git a/ThirdParty/Ert/lib/util/rng.cpp b/ThirdParty/Ert/lib/util/rng.cpp index c940eed166..f0daadcb2f 100644 --- a/ThirdParty/Ert/lib/util/rng.cpp +++ b/ThirdParty/Ert/lib/util/rng.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include diff --git a/ThirdParty/Ert/lib/util/set.cpp b/ThirdParty/Ert/lib/util/set.cpp deleted file mode 100644 index 0ee87f81f5..0000000000 --- a/ThirdParty/Ert/lib/util/set.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'set.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#include -#include -#include -#include - -#include -#include -#include -#include - - -#define SET_TYPE_ID 816523 -struct set_struct { - UTIL_TYPE_ID_DECLARATION; - hash_type * key_hash; -}; - - -static UTIL_SAFE_CAST_FUNCTION( set , SET_TYPE_ID ) - - -set_type * set_alloc(int size, const char ** keyList) { - set_type * set = (set_type*) malloc(sizeof * set); - UTIL_TYPE_ID_INIT( set , SET_TYPE_ID ); - set->key_hash = hash_alloc(); - { - int ikey; - for (ikey = 0; ikey < size; ikey++) - set_add_key(set , keyList[ikey]); - } - return set; -} - - -set_type * set_copyc(const set_type * set) -{ - int size = set_get_size(set); - char ** keylist = set_alloc_keylist(set); - set_type * set_copy = set_alloc(size, (const char **) keylist); - int key_nr; - - for( key_nr = 0; key_nr < size; key_nr++) - free(keylist[key_nr]); - free(keylist); - - return set_copy; -} - - -void set_clear( set_type * set ) { - hash_clear( set->key_hash ); -} - - -set_type * set_alloc_empty() { return set_alloc(0 , NULL); } - - -bool set_add_key(set_type * set, const char * key) { - if (hash_has_key(set->key_hash , key)) - return false; - else { - hash_insert_int(set->key_hash , key , 1); - return true; - } -} - -void set_remove_key(set_type * set, const char * key) { - if (!hash_has_key(set->key_hash , key)) { - fprintf(stderr, "%s: set does not have key: %s - aborting \n",__func__ , key); - abort(); - } - hash_del(set->key_hash , key); -} - - -bool set_has_key(const set_type * set, const char * key) { - return hash_has_key(set->key_hash, key); -} - - -void set_fprintf(const set_type * set, const char * sep , FILE * stream) { - const int size = set_get_size(set); - int i; - char ** key_list = set_alloc_keylist(set); - for (i=0; i < size; i++) { - if (i < (size - 1)) - fprintf(stream , "%s%s",key_list[i] , sep); - else - fprintf(stream , "%s",key_list[i]); - free(key_list[i]); - } - free(key_list); -} - - - -int set_get_size(const set_type *set) { return hash_get_size(set->key_hash); } - - -char ** set_alloc_keylist(const set_type * set) { - return hash_alloc_keylist(set->key_hash); -} - - - - -void set_free(set_type * set) { - hash_free(set->key_hash); - free(set); -} - - -void set_free__(void * arg) { - set_type * set = set_safe_cast( arg ); - set_free( set ); -} - - - - - -void set_fwrite(const set_type * set, FILE * stream) { - char ** key_list = set_alloc_keylist(set); - int size = set_get_size(set); - int i; - fwrite(&size , sizeof size , 1 , stream); - for (i=0; i < size; i++) { - util_fwrite_string(key_list[i] , stream); - free(key_list[i]); - } - free(key_list); -} - - -void set_fread(set_type * set , FILE * stream) { - int size, i; - fread(&size , sizeof size , 1 , stream); - for (i=0; i < size; i++) { - char * key = util_fread_alloc_string(stream); - set_add_key(set , key); - free(key); - } -} - - - -set_type * set_fread_alloc(FILE * stream) { - set_type * set = set_alloc_empty(); - set_fread(set , stream); - return set; -} - - -/** - set1 is updated to *ONLY* contain elements which are both in - set1 and set2. -*/ - -void set_intersect(set_type * set1 , const set_type * set2) { - char ** key_list1 = set_alloc_keylist(set1); - int size1 = set_get_size(set1); - int i; - for ( i=0; i < size1; i++) { - if (!set_has_key(set2 , key_list1[i])) - set_remove_key(set1 , key_list1[i]); - free(key_list1[i]); - } - free(key_list1); -} - - - - - -/** - set1 is updated to contain all elements which are (originally) in - either set1 or set2. -*/ - -void set_union(set_type * set1 , const set_type * set2) { - char ** key_list2 = set_alloc_keylist(set2); - int size2 = set_get_size(set2); - int i; - for ( i=0; i < size2; i++) { - set_add_key(set1 , key_list2[i]); - free(key_list2[i]); - } - free(key_list2); -} - - - -/** - set1 is updated so that any keys that are both in set1 and set2 - are removed from set1. -*/ - -void set_minus(set_type * set1, const set_type * set2) { - char ** key_list2 = set_alloc_keylist(set2); - int size2 = set_get_size(set2); - int i; - for ( i=0; i < size2; i++) { - if( set_has_key(set1 , key_list2[i]) ) - set_remove_key(set1, key_list2[i]); - free(key_list2[i]); - } - free(key_list2); -} - - - -/** - This is a **VERY** simple iteration object. - - Do **NOT** use with multi-threading. -*/ - - -struct set_iter_struct -{ - hash_iter_type * hash_iter; -}; - - -set_iter_type * set_iter_alloc(const set_type * set) -{ - set_iter_type * set_iter = (set_iter_type*) util_malloc(sizeof * set_iter); - set_iter->hash_iter = hash_iter_alloc(set->key_hash); - return set_iter; -} - - -void set_iter_free(set_iter_type * set_iter) -{ - hash_iter_free(set_iter->hash_iter); - free(set_iter); -} - - - -bool set_iter_is_complete(const set_iter_type * set_iter) -{ - return hash_iter_is_complete(set_iter->hash_iter); -} - - -const char * set_iter_get_next_key(set_iter_type * set_iter) -{ - return hash_iter_get_next_key(set_iter->hash_iter); -} diff --git a/ThirdParty/Ert/lib/util/statistics.cpp b/ThirdParty/Ert/lib/util/statistics.cpp index ead3d3ff45..9aa170b849 100644 --- a/ThirdParty/Ert/lib/util/statistics.cpp +++ b/ThirdParty/Ert/lib/util/statistics.cpp @@ -1,25 +1,25 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'statistics.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'statistics.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include #include @@ -48,17 +48,17 @@ double statistics_std( const double_vector_type * data_vector ) { double d = (data[i] - mean); std += d*d; } - + return sqrt(std / size); } - + /** Observe that the data vector will be sorted in place. If the vector is already sorted, e.g. from a previous call to statistics_empirical_quantile(), - you can call statistics_empirical_quantile__() directly. + you can call statistics_empirical_quantile__() directly. */ double statistics_empirical_quantile( double_vector_type * data , double quantile ) { @@ -80,11 +80,11 @@ double statistics_empirical_quantile__( const double_vector_type * data , double { const int size = (double_vector_size( data ) - 1); if (double_vector_iget( data , 0) == double_vector_iget( data , size)) - /* + /* All elements are equal - and it is impossible to find a meaingful quantile, we just return "the value". */ - return double_vector_iget( data, 0 ); + return double_vector_iget( data, 0 ); else { double value; double lower_value; @@ -92,19 +92,19 @@ double statistics_empirical_quantile__( const double_vector_type * data , double double real_index; double upper_quantile; double lower_quantile; - + int lower_index; int upper_index; - - + + real_index = quantile * size; lower_index = floor( real_index ); upper_index = ceil( real_index ); - + upper_value = double_vector_iget( data , upper_index ); lower_value = double_vector_iget( data , lower_index ); - /* + /* Will iterate in this loop until we have found upper_value != lower_value. As long as we know that now all elements are equal (the first test), this is guaranteed to succeed, but of @@ -117,24 +117,24 @@ double statistics_empirical_quantile__( const double_vector_type * data , double if (upper_value == lower_value) { upper_index = util_int_min( size , upper_index + 1); upper_value = double_vector_iget( data , upper_index ); - } else + } else break; /*2: Try to shift the lower index down. */ if (upper_value == lower_value) { lower_index = util_int_max( 0 , lower_index - 1); lower_value = double_vector_iget( data , lower_index ); - } else + } else break; - + } - + upper_quantile = upper_index * 1.0 / size; lower_quantile = lower_index * 1.0 / size; /* Linear interpolation: */ { double a = (upper_value - lower_value) / (upper_quantile - lower_quantile); - + value = lower_value + a*(quantile - lower_quantile); return value; } diff --git a/ThirdParty/Ert/lib/util/string_util.cpp b/ThirdParty/Ert/lib/util/string_util.cpp index 509c565c5b..37f258fea7 100644 --- a/ThirdParty/Ert/lib/util/string_util.cpp +++ b/ThirdParty/Ert/lib/util/string_util.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include #include diff --git a/ThirdParty/Ert/lib/util/stringlist.cpp b/ThirdParty/Ert/lib/util/stringlist.cpp index bf134c4f03..237deabc03 100644 --- a/ThirdParty/Ert/lib/util/stringlist.cpp +++ b/ThirdParty/Ert/lib/util/stringlist.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #ifdef ERT_HAVE_OPENDIR #include #include @@ -32,7 +32,7 @@ #include #endif -#include +#include #include #include @@ -94,15 +94,10 @@ void stringlist_fprintf_fmt(const stringlist_type * stringlist, const stringlist This function appends a copy of s into the stringlist. */ void stringlist_append_copy(stringlist_type * stringlist , const char * s) { - vector_append_buffer(stringlist->strings , s , strlen(s) + 1); -} - -void stringlist_append_ref(stringlist_type * stringlist , const char * s) { - vector_append_ref(stringlist->strings , s); -} - -void stringlist_append_owned_ref(stringlist_type * stringlist , const char * s) { - vector_append_owned_ref(stringlist->strings , s , free); + if (s) + vector_append_buffer(stringlist->strings , s , strlen(s) + 1); + else + vector_append_ref(stringlist->strings, NULL ); } /*****************************************************************/ @@ -167,54 +162,7 @@ stringlist_type * stringlist_alloc_argv_copy(const char ** argv , int argc) { } -stringlist_type * stringlist_alloc_argv_ref(const char ** argv , int argc) { - int iarg; - stringlist_type * stringlist = stringlist_alloc_empty( true ); - for (iarg = 0; iarg < argc; iarg++) - stringlist_append_ref( stringlist , argv[iarg]); - - return stringlist; -} - -stringlist_type * stringlist_alloc_argv_owned_ref(const char ** argv , int argc) { - int iarg; - stringlist_type * stringlist = stringlist_alloc_empty( true ); - for (iarg = 0; iarg < argc; iarg++) - stringlist_append_owned_ref( stringlist , argv[iarg]); - - return stringlist; -} - - - -/** - Allocates a new stringlist instance where all the new string are - references to the string found in the existing stringlist - instance. -*/ -stringlist_type * stringlist_alloc_shallow_copy(const stringlist_type * src) { - stringlist_type * copy = stringlist_alloc_empty( false ); - copy->strings = vector_alloc_copy( src->strings , false); - return copy; -} - - -/** - Allocates a new stringlist where the strings are references to the - num_strings found in stringlist from start. -*/ -stringlist_type * stringlist_alloc_shallow_copy_with_limits(const stringlist_type * stringlist, int offset, int num_strings) { - stringlist_type * copy = stringlist_alloc_empty( true ); - int i; - for( i=0; istrings, str); - } - - return copy; -} /* @@ -251,12 +199,6 @@ void stringlist_append_stringlist_copy(stringlist_type * stringlist , const stri } -void stringlist_append_stringlist_ref(stringlist_type * stringlist , const stringlist_type * src) { - int i; - for (i = 0; i < stringlist_get_size( src ); i++) - stringlist_append_ref(stringlist , stringlist_iget(src , i)); -} - /** Insert a copy of a stringlist in some position. @@ -277,10 +219,10 @@ void stringlist_insert_stringlist_copy(stringlist_type * stringlist, const strin int i; for( i=0; id_name, pred_arg)) continue; - stringlist_append_owned_ref(names, util_alloc_filename(path, entry->d_name, NULL)); + { + char * fname = util_alloc_filename(path, entry->d_name, NULL); + stringlist_append_copy(names, fname); + free(fname); + } } closedir(dir); @@ -809,8 +759,11 @@ int stringlist_select_files(stringlist_type * names, const char * path, file_pre if (predicate && !predicate(file_data.cFileName, pred_arg)) continue; - - stringlist_append_owned_ref(names, util_alloc_filename(path, file_data.cFileName, NULL)); + { + char * tmp_fname = util_alloc_filename(path, file_data.cFileName, NULL); + stringlist_append_copy(names, tmp_fname); + free(tmp_fname); + } } while (FindNextFile( file_handle , &file_data) != 0); FindClose( file_handle ); } @@ -836,7 +789,7 @@ int stringlist_append_matching_elements(stringlist_type * target , const stringl return match_count; } - int stringlist_select_matching_elements(stringlist_type * target , const stringlist_type * src , const char * pattern) { +int stringlist_select_matching_elements(stringlist_type * target , const stringlist_type * src , const char * pattern) { stringlist_clear( target ); return stringlist_append_matching_elements( target , src , pattern ); } @@ -849,7 +802,7 @@ static int void_strcmp(const void* s1, const void *s2) { bool stringlist_unique(const stringlist_type * stringlist ) { bool unique = true; - stringlist_type * cpy = stringlist_alloc_shallow_copy(stringlist); + stringlist_type * cpy = stringlist_alloc_deep_copy(stringlist); stringlist_sort(cpy, void_strcmp); for (int i = 0; i < stringlist_get_size(cpy) - 1; i++) { diff --git a/ThirdParty/Ert/lib/util/struct_vector.cpp b/ThirdParty/Ert/lib/util/struct_vector.cpp deleted file mode 100644 index c79891b810..0000000000 --- a/ThirdParty/Ert/lib/util/struct_vector.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'struct_vector.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#include -#include - -#include -#include - - -#define STRUCT_VECTOR_TYPE_ID 772562097 - -struct struct_vector_struct { - UTIL_TYPE_ID_DECLARATION; - int size; - int element_size; - int alloc_size; - - char * data; -}; - -UTIL_IS_INSTANCE_FUNCTION( struct_vector , STRUCT_VECTOR_TYPE_ID) - - -static void struct_vector_resize( struct_vector_type * struct_vector , int new_alloc_size) { - struct_vector->data = (char*)util_realloc( struct_vector->data , struct_vector->element_size * new_alloc_size ); - struct_vector->alloc_size = new_alloc_size; -} - - -void struct_vector_reserve( struct_vector_type * struct_vector , int reserve_size) { - if (reserve_size > struct_vector->alloc_size) - struct_vector_resize( struct_vector , reserve_size ); -} - - - -struct_vector_type * struct_vector_alloc( int element_size ) { - if (element_size <= 0) { - util_abort("%s: fatal error - can not create container for zero size objects\n",__func__); - return NULL; - } - - { - struct_vector_type * vector = (struct_vector_type*)util_malloc( sizeof * vector ); - UTIL_TYPE_ID_INIT( vector , STRUCT_VECTOR_TYPE_ID ); - vector->size = 0; - vector->alloc_size = 0; - vector->element_size = element_size; - vector->data = NULL; - - struct_vector_resize( vector , 10 ); - - return vector; - } -} - -void struct_vector_free( struct_vector_type * struct_vector) { - free( struct_vector->data ); - free( struct_vector ); -} - - -int struct_vector_get_size( const struct_vector_type * struct_vector) { - return struct_vector->size; -} - - - -void struct_vector_append( struct_vector_type * struct_vector , void * value) { - if (struct_vector->size == struct_vector->alloc_size) - struct_vector_resize( struct_vector , 2*struct_vector->alloc_size + 1); - - { - size_t offset = struct_vector->size * struct_vector->element_size; - memcpy( &struct_vector->data[offset] , value , struct_vector->element_size); - struct_vector->size++; - } -} - - -void * struct_vector_get_data( const struct_vector_type * struct_vector ) { - return struct_vector->data; -} - - -void struct_vector_iget( const struct_vector_type * struct_vector , int index , void * value) { - if (index < struct_vector->size) { - size_t offset = index * struct_vector->element_size; - memcpy( value , &struct_vector->data[offset] , struct_vector->element_size); - } else - util_abort("%s: fatal error - invalid index:%d size:%d\n",__func__ , index , struct_vector->size); -} - - -void * struct_vector_iget_ptr( const struct_vector_type * struct_vector , int index ) { - if (index < struct_vector->size) { - size_t offset = index * struct_vector->element_size; - return &struct_vector->data[offset]; - } else - util_abort("%s: fatal error - invalid index:%d size:%d\n",__func__ , index , struct_vector->size); - return NULL; -} - - -void struct_vector_reset( struct_vector_type * struct_vector ) { - struct_vector->size = 0; -} - - -void struct_vector_sort( struct_vector_type * struct_vector , struct_vector_cmp_ftype * cmp) { - qsort(struct_vector->data , struct_vector->size , struct_vector->element_size , cmp); -} diff --git a/ThirdParty/Ert/lib/util/test_util.cpp b/ThirdParty/Ert/lib/util/test_util.cpp index 9115af6feb..0e4349f7e0 100644 --- a/ThirdParty/Ert/lib/util/test_util.cpp +++ b/ThirdParty/Ert/lib/util/test_util.cpp @@ -25,11 +25,10 @@ #include #include "ert/util/build_config.hpp" -#include -#include +#include #include #include -#include +#include void test_error_exit( const char * fmt , ...) { char * s; @@ -373,9 +372,3 @@ void * thread_pool_test_func1( void * arg ) { #endif -void * test_argpack_is_stringlist( void * arg ) { - arg_pack_type * arg_pack = arg_pack_safe_cast( arg ); - void * arg0 = arg_pack_iget_ptr( arg_pack , 0 ); - test_assert_true( stringlist_is_instance( arg0 ) ); - return NULL; -} diff --git a/ThirdParty/Ert/lib/util/test_work_area.cpp b/ThirdParty/Ert/lib/util/test_work_area.cpp index 09e394fa92..32a6267b4c 100644 --- a/ThirdParty/Ert/lib/util/test_work_area.cpp +++ b/ThirdParty/Ert/lib/util/test_work_area.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_abort_gnu_tests.c b/ThirdParty/Ert/lib/util/tests/ert_util_abort_gnu_tests.cpp similarity index 94% rename from ThirdParty/Ert/lib/util/tests/ert_util_abort_gnu_tests.c rename to ThirdParty/Ert/lib/util/tests/ert_util_abort_gnu_tests.cpp index 923240054f..fe59c9dc15 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_abort_gnu_tests.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_abort_gnu_tests.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include void test_assert_util_abort(const char * function_name , void (void *) , void * arg); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_addr2line.c b/ThirdParty/Ert/lib/util/tests/ert_util_addr2line.cpp similarity index 97% rename from ThirdParty/Ert/lib/util/tests/ert_util_addr2line.c rename to ThirdParty/Ert/lib/util/tests/ert_util_addr2line.cpp index 5aa62222c0..06d76bfc28 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_addr2line.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_addr2line.cpp @@ -20,8 +20,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_alloc_file_components.c b/ThirdParty/Ert/lib/util/tests/ert_util_alloc_file_components.cpp similarity index 97% rename from ThirdParty/Ert/lib/util/tests/ert_util_alloc_file_components.c rename to ThirdParty/Ert/lib/util/tests/ert_util_alloc_file_components.cpp index bb9e6d57a9..cfdf63fda2 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_alloc_file_components.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_alloc_file_components.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include bool checkPath(const char * path, const char * directory, const char * base_name, const char * extension) { @@ -40,4 +40,4 @@ int main(int argc , char ** argv) { test_assert_true(checkPath(".filename.ext", NULL, ".filename", "ext")); exit(0); -} \ No newline at end of file +} diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_approx_equal.c b/ThirdParty/Ert/lib/util/tests/ert_util_approx_equal.cpp similarity index 68% rename from ThirdParty/Ert/lib/util/tests/ert_util_approx_equal.c rename to ThirdParty/Ert/lib/util/tests/ert_util_approx_equal.cpp index 1dcc801cd9..d9b9f45acf 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_approx_equal.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_approx_equal.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_approx_equal.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_approx_equal.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include -#include +#include +#include @@ -32,10 +32,10 @@ int main( int argc , char ** argv) { test_assert_double_not_equal( 0.00000000002 , 0.000000000001 ); test_assert_double_equal( 1.00000000002 , 1.000000000001 ); - test_assert_double_equal( 0.0 , 0.0 ); + test_assert_double_equal( 0.0 , 0.0 ); test_assert_double_equal( 0.75 , asin( sin(0.75))); test_assert_double_equal( 2.25 , exp( log(2.25))); test_assert_double_equal( 2.25 , log( exp(2.25))); - + exit(0); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_arg_pack.c b/ThirdParty/Ert/lib/util/tests/ert_util_arg_pack.c deleted file mode 100644 index 63ccdf5c14..0000000000 --- a/ThirdParty/Ert/lib/util/tests/ert_util_arg_pack.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ert_util_arg_pack.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ -#include -#include -#include -#include - -#include -#include - - - -/* - This test must be compiled with -Werror; an important part of the test - is that we should get no warnings related to the const pointers. -*/ - -int main( int argc , char ** argv) { - const char * ptr1 = "Pointer1"; - const char * ptr2 = "Pointer2"; - - arg_pack_type * arg_pack = arg_pack_alloc(); - test_assert_int_equal( 0 , arg_pack_size( arg_pack )); - arg_pack_append_const_ptr( arg_pack , ptr1 ); - arg_pack_append_const_ptr( arg_pack , ptr2 ); - - test_assert_int_equal( 2 , arg_pack_size( arg_pack )); - test_assert_ptr_equal( ptr1 , arg_pack_iget_const_ptr( arg_pack , 0 )); - test_assert_ptr_equal( ptr2 , arg_pack_iget_const_ptr( arg_pack , 1 )); - - - - exit(0); -} diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_before_after.c b/ThirdParty/Ert/lib/util/tests/ert_util_before_after.cpp similarity index 72% rename from ThirdParty/Ert/lib/util/tests/ert_util_before_after.c rename to ThirdParty/Ert/lib/util/tests/ert_util_before_after.cpp index 9ec1b98c26..d5982d27bd 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_before_after.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_before_after.cpp @@ -1,27 +1,27 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_before_after.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_before_after.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include #include - + int main( int argc , char ** argv) { @@ -30,12 +30,12 @@ int main( int argc , char ** argv) { test_assert_true( util_before( t1 , t2 )); test_assert_true( util_after( t2 , t1 )); - + test_assert_false( util_before( t2 , t1 )); test_assert_false( util_after( t1 , t2 )); test_assert_false( util_before( t1 , t1 )); test_assert_false( util_after( t1 , t1 )); - + exit(0); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_binary_split.c b/ThirdParty/Ert/lib/util/tests/ert_util_binary_split.cpp similarity index 83% rename from ThirdParty/Ert/lib/util/tests/ert_util_binary_split.c rename to ThirdParty/Ert/lib/util/tests/ert_util_binary_split.cpp index c5c01f625a..4c3ee41585 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_binary_split.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_binary_split.cpp @@ -1,31 +1,31 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ert_util_binary_split.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ert_util_binary_split.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include void test_split(const char * test_string , bool split_on_first , const char * true1, const char * true2) { char * part1; char * part2; - + util_binary_split_string( test_string , ":" , split_on_first , &part1 , &part2 ); test_assert_string_equal( true1 , part1 ); test_assert_string_equal( true2 , part2 ); @@ -40,7 +40,7 @@ void test_split(const char * test_string , bool split_on_first , const char * tr } int main(int argc , char ** argv) { - + test_split( "Hello:Hello" , true , "Hello" , "Hello"); test_split( "ABC:DEF:GEH" , true , "ABC" , "DEF:GEH"); test_split( "ABC:DEF:GEH" , false , "ABC:DEF" , "GEH"); @@ -50,6 +50,6 @@ int main(int argc , char ** argv) { test_split( "ABCDEFGEH:" , false , "ABCDEFGEH" , NULL); test_split( ":ABCDEFGEH" , false , "ABCDEFGEH" , NULL); test_split( NULL , false , NULL , NULL); - + exit(0); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_buffer.c b/ThirdParty/Ert/lib/util/tests/ert_util_buffer.cpp similarity index 86% rename from ThirdParty/Ert/lib/util/tests/ert_util_buffer.c rename to ThirdParty/Ert/lib/util/tests/ert_util_buffer.cpp index 8c032474ce..a42768df2f 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_buffer.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_buffer.cpp @@ -18,8 +18,8 @@ #include #include -#include -#include +#include +#include @@ -56,7 +56,7 @@ void test_buffer_strstr() { buffer_rewind( buffer ); test_assert_true( buffer_strstr( buffer , "ABC")); test_assert_int_equal( buffer_get_offset(buffer) , 0); - test_assert_string_equal( "ABC" , buffer_get_data(buffer)); + test_assert_string_equal( "ABC" , (const char *) buffer_get_data(buffer)); { size_t pos = buffer_get_offset( buffer ); @@ -83,17 +83,17 @@ void test_buffer_search_replace1() { buffer_rewind(buffer); test_assert_true( buffer_search_replace( buffer, "ABC" , "XYZ" )); buffer_rewind( buffer ); - test_assert_string_equal( "XYZ 123" , buffer_get_data( buffer )); + test_assert_string_equal( "XYZ 123" , (const char *) buffer_get_data( buffer )); buffer_rewind( buffer ); test_assert_true( buffer_search_replace( buffer, "XYZ" , "A")); buffer_rewind( buffer ); - test_assert_string_equal( "A 123" , buffer_get_data( buffer )); + test_assert_string_equal( "A 123" , (const char *) buffer_get_data( buffer )); buffer_rewind( buffer ); test_assert_true( buffer_search_replace( buffer, "A", "XYZ")); buffer_rewind( buffer ); - test_assert_string_equal( "XYZ 123" , buffer_get_data( buffer )); + test_assert_string_equal( "XYZ 123" , (const char *) buffer_get_data( buffer )); buffer_free( buffer ); } @@ -105,11 +105,11 @@ void test_buffer_search_replace2() { buffer_rewind( buffer ); test_assert_false( buffer_search_replace( buffer , "" , "SUPERCase")); - test_assert_string_equal( "MAGIC_PRINT magic-list.txt __MAGIC__" , buffer_get_data( buffer)); + test_assert_string_equal( "MAGIC_PRINT magic-list.txt __MAGIC__" , (const char *) buffer_get_data( buffer)); buffer_rewind( buffer ); test_assert_true( buffer_search_replace( buffer , "" , "default")); - test_assert_string_equal( "MAGIC_PRINT magic-list.txt default __MAGIC__" , buffer_get_data( buffer)); + test_assert_string_equal( "MAGIC_PRINT magic-list.txt default __MAGIC__" , (const char *) buffer_get_data( buffer)); buffer_free( buffer ); @@ -120,14 +120,14 @@ void test_char_ptr( ) { buffer_type * buffer = buffer_alloc(1024); buffer_fwrite_char_ptr( buffer , "Hello World"); test_assert_size_t_equal( buffer_get_size( buffer ) , 12 ); - test_assert_int_equal( strlen( buffer_get_data( buffer )) , 11); + test_assert_int_equal( strlen( (const char *) buffer_get_data( buffer )) , 11); buffer_clear( buffer ); buffer_fwrite_char_ptr(buffer , "Hello" ); buffer_strcat( buffer , " " ); buffer_strcat( buffer , "World" ); test_assert_size_t_equal( buffer_get_size( buffer ) , 12 ); - test_assert_int_equal( strlen( buffer_get_data( buffer )) , 11); + test_assert_int_equal( strlen( (const char *) buffer_get_data( buffer )) , 11); buffer_free( buffer ); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_chdir.c b/ThirdParty/Ert/lib/util/tests/ert_util_chdir.cpp similarity index 94% rename from ThirdParty/Ert/lib/util/tests/ert_util_chdir.c rename to ThirdParty/Ert/lib/util/tests/ert_util_chdir.cpp index 283d08869a..bd84459deb 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_chdir.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_chdir.cpp @@ -18,9 +18,9 @@ #include #include -#include +#include #include -#include +#include void test_chdir() { diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_clamp.c b/ThirdParty/Ert/lib/util/tests/ert_util_clamp.cpp similarity index 75% rename from ThirdParty/Ert/lib/util/tests/ert_util_clamp.c rename to ThirdParty/Ert/lib/util/tests/ert_util_clamp.cpp index 3ff94c275b..e56640ada0 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_clamp.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_clamp.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_clamp.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_clamp.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include +#include int main(int argc , char ** argv) { @@ -37,7 +37,7 @@ int main(int argc , char ** argv) { value = 0; util_clamp_double( &value , 2 , 1 ); test_assert_double_equal( value , 1 ); - + value = 0; util_clamp_double( &value , -2 , 0 ); test_assert_double_equal( value , 0 ); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_copy_file.c b/ThirdParty/Ert/lib/util/tests/ert_util_copy_file.cpp similarity index 75% rename from ThirdParty/Ert/lib/util/tests/ert_util_copy_file.c rename to ThirdParty/Ert/lib/util/tests/ert_util_copy_file.cpp index 20a7f6fe20..6ccb4f99ed 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_copy_file.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_copy_file.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2014 Statoil ASA, Norway. - + Copyright (C) 2014 Statoil ASA, Norway. + The file 'enkf_util_copy_file.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include @@ -22,10 +22,10 @@ #include #include -#include -#include +#include +#include #include -#include +#include @@ -33,7 +33,7 @@ void test_copy_file( const char * executable ) { struct stat stat_buf; mode_t mode0,mode1; stat( executable , &stat_buf ); - + mode0 = stat_buf.st_mode; { test_work_area_type * test_area = test_work_area_alloc( "executable-copy" ); @@ -42,7 +42,7 @@ void test_copy_file( const char * executable ) { test_assert_true( util_file_exists( "test.x" )); stat( "test.x" , &stat_buf ); mode1 = stat_buf.st_mode; - + test_assert_true( mode0 == mode1 ); test_work_area_free( test_area ); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_cwd_test.c b/ThirdParty/Ert/lib/util/tests/ert_util_cwd_test.cpp similarity index 68% rename from ThirdParty/Ert/lib/util/tests/ert_util_cwd_test.c rename to ThirdParty/Ert/lib/util/tests/ert_util_cwd_test.cpp index d5c593fe5f..0b59b4fa69 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_cwd_test.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_cwd_test.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_cwd_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_cwd_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include +#include int main(int argc , char ** argv) { char * cwd = argv[1]; diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_datetime.c b/ThirdParty/Ert/lib/util/tests/ert_util_datetime.cpp similarity index 96% rename from ThirdParty/Ert/lib/util/tests/ert_util_datetime.c rename to ThirdParty/Ert/lib/util/tests/ert_util_datetime.cpp index 1958657190..2564784ee0 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_datetime.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_datetime.cpp @@ -20,9 +20,8 @@ #include #include -#include -#include - +#include +#include int main( int argc , char ** argv) { diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_file_readable.c b/ThirdParty/Ert/lib/util/tests/ert_util_file_readable.cpp similarity index 74% rename from ThirdParty/Ert/lib/util/tests/ert_util_file_readable.c rename to ThirdParty/Ert/lib/util/tests/ert_util_file_readable.cpp index 35a5cdd250..25e29b5a42 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_file_readable.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_file_readable.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ert_util_file_readable.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ert_util_file_readable.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include @@ -22,7 +22,7 @@ #include #include -#include +#include void assert_equal( bool equal ) { @@ -39,7 +39,7 @@ int main(int argc , char ** argv) { char * path; util_alloc_file_components( argv[0] , &path , NULL , NULL); test_assert_false( util_file_readable( path )); - util_safe_free( path ); + free( path ); } { const char * file = "/tmp/test_file.txt"; diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_filename.c b/ThirdParty/Ert/lib/util/tests/ert_util_filename.cpp similarity index 96% rename from ThirdParty/Ert/lib/util/tests/ert_util_filename.c rename to ThirdParty/Ert/lib/util/tests/ert_util_filename.cpp index 0612a98071..d42150605e 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_filename.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_filename.cpp @@ -21,8 +21,8 @@ #include #include -#include -#include +#include +#include void test_dirname() { diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_hash_test.c b/ThirdParty/Ert/lib/util/tests/ert_util_hash_test.cpp similarity index 60% rename from ThirdParty/Ert/lib/util/tests/ert_util_hash_test.c rename to ThirdParty/Ert/lib/util/tests/ert_util_hash_test.cpp index b7a5779e2c..d157750e23 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_hash_test.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_hash_test.cpp @@ -1,28 +1,28 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_hash_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_hash_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include int main(int argc , char ** argv) { - + hash_type * h = hash_alloc(); test_assert_bool_equal( hash_add_option( h , "Key" ) , false ); @@ -31,10 +31,10 @@ int main(int argc , char ** argv) { test_assert_true( hash_add_option( h , "Key1:Value" ) ); test_assert_true( hash_add_option( h , "Key2:Value1:Value2" ) ); test_assert_true( hash_add_option( h , "Key3:Value1:value2:Value3" ) ); - - test_assert_string_equal( hash_get( h , "Key1" ) , "Value" ); - test_assert_string_equal( hash_get( h , "Key2" ) , "Value1:Value2" ); - test_assert_string_equal( hash_get( h , "Key3" ) , "Value1:value2:Value3" ); + + test_assert_string_equal( (const char *) hash_get( h , "Key1" ) , "Value" ); + test_assert_string_equal( (const char *) hash_get( h , "Key2" ) , "Value1:Value2" ); + test_assert_string_equal( (const char *) hash_get( h , "Key3" ) , "Value1:value2:Value3" ); test_assert_false( hash_has_key( h , "Key" )); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_mkdir_p.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_mkdir_p.cpp new file mode 100644 index 0000000000..30a2ea8d39 --- /dev/null +++ b/ThirdParty/Ert/lib/util/tests/ert_util_mkdir_p.cpp @@ -0,0 +1,50 @@ +/* + Copyright (C) 2018 Statoil ASA, Norway. + + The file 'ert_util_mkdir_p.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ +#include +#include + +#include +#include +#include + + +int main(int argc , char ** argv) { + test_work_area_type * work_area = test_work_area_alloc("Test_area"); + + // Regular use + test_assert_true( util_mkdir_p("some/path/with/many/levels")); + + + // Absolute path where the root exists. + { + char * abs_path = util_alloc_abs_path("a/path/with/abs/prefix"); + test_assert_true( util_mkdir_p(abs_path)); + + // Already exists: + test_assert_true( util_mkdir_p(abs_path)); + free(abs_path); + } + + // Permission denied + test_assert_true(util_mkdir_p("read_only")); + chmod("read_only", 0555); + test_assert_false(util_mkdir_p("read_only/no/not/this")); + + test_work_area_free(work_area); + exit(0); +} diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_normal_path.c b/ThirdParty/Ert/lib/util/tests/ert_util_normal_path.cpp similarity index 97% rename from ThirdParty/Ert/lib/util/tests/ert_util_normal_path.c rename to ThirdParty/Ert/lib/util/tests/ert_util_normal_path.cpp index 4fbb95ca12..ff1f117020 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_normal_path.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_normal_path.cpp @@ -19,8 +19,8 @@ #include #include -#include -#include +#include +#include #include diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_parent_path.c b/ThirdParty/Ert/lib/util/tests/ert_util_parent_path.cpp similarity index 78% rename from ThirdParty/Ert/lib/util/tests/ert_util_parent_path.c rename to ThirdParty/Ert/lib/util/tests/ert_util_parent_path.cpp index 4990846747..b5af351b93 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_parent_path.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_parent_path.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_parent_path.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_parent_path.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include @@ -23,7 +23,7 @@ #include #include -#include +#include void test_path(const char * expected_parent , const char * input_path ) { @@ -39,7 +39,7 @@ int main(int argc , char ** argv) { test_path("" , "path"); test_path(NULL , ""); test_path(NULL , NULL); - + test_path("path/parent" , "path/parent/leaf"); test_path("/path/parent" , "/path/parent/leaf"); test_path("/path/parent" , "/path/parent/leaf/"); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_path_stack_test.c b/ThirdParty/Ert/lib/util/tests/ert_util_path_stack_test.cpp similarity index 69% rename from ThirdParty/Ert/lib/util/tests/ert_util_path_stack_test.c rename to ThirdParty/Ert/lib/util/tests/ert_util_path_stack_test.cpp index c582c8b2a6..ddc26dbaf0 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_path_stack_test.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_path_stack_test.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_path_stack_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_path_stack_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include @@ -22,9 +22,9 @@ #include -#include -#include -#include +#include +#include +#include @@ -37,27 +37,21 @@ int main(int argc , char ** argv) { path_stack_type * path_stack = path_stack_alloc(); path_stack_push_cwd( path_stack ); - + if (path_stack_push( path_stack , "NotExist-1111")) test_error_exit("Pushed unexisting path\n"); - + if (!path_stack_push( path_stack, path1 )) test_error_exit("Failed to push:%s \n",path1 ); - + util_chdir( path2 ); if (util_is_cwd( path1 )) test_error_exit("Failed to chdir(%s) \n",path2 ); - - { - if (path_stack_size( path_stack ) != 2) - test_error_exit("Wrong stack size"); - - if (strcmp( path1 , path_stack_peek( path_stack )) != 0) - test_error_exit("peek error"); - } - + + if (path_stack_size( path_stack ) != 2) + test_error_exit("Wrong stack size"); + path_stack_pop( path_stack ); - printf("After pop: cwd:%s path1:%s \n",util_alloc_cwd() , path1); if (!util_is_cwd( path1 )) test_error_exit("path_stack_pop failed \n"); @@ -67,13 +61,13 @@ int main(int argc , char ** argv) { if (path_stack_size( path_stack ) != 0) test_error_exit("Wrong stack size"); - + if (!path_stack_push(path_stack , NULL)) test_error_exit("Hmmm - push(NULL) failed \n"); if (path_stack_size( path_stack ) != 1) test_error_exit("Wrong stack size"); - + path_stack_pop( path_stack ); path_stack_free( path_stack); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_ping.c b/ThirdParty/Ert/lib/util/tests/ert_util_ping.cpp similarity index 65% rename from ThirdParty/Ert/lib/util/tests/ert_util_ping.c rename to ThirdParty/Ert/lib/util/tests/ert_util_ping.cpp index 4910a11dcb..58f8e69ba3 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_ping.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_ping.cpp @@ -1,25 +1,25 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_ping.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_ping.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include +#include +#include #include diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_realpath.c b/ThirdParty/Ert/lib/util/tests/ert_util_realpath.cpp similarity index 95% rename from ThirdParty/Ert/lib/util/tests/ert_util_realpath.c rename to ThirdParty/Ert/lib/util/tests/ert_util_realpath.cpp index 7aa5d53fbf..7f8c6e814e 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_realpath.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_realpath.cpp @@ -19,8 +19,8 @@ #include #include -#include -#include +#include +#include void test_path(const char * input , const char * expected) { char * rpath = util_alloc_realpath__( input ); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_relpath_test.c b/ThirdParty/Ert/lib/util/tests/ert_util_relpath_test.cpp similarity index 84% rename from ThirdParty/Ert/lib/util/tests/ert_util_relpath_test.c rename to ThirdParty/Ert/lib/util/tests/ert_util_relpath_test.cpp index 900b04894d..e19b336e99 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_relpath_test.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_relpath_test.cpp @@ -1,28 +1,28 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_relpath_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_relpath_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include #include -#include +#include #include -#include +#include void test_path(int nr , const char * root , const char * path , const char * true_path) { @@ -32,8 +32,8 @@ void test_path(int nr , const char * root , const char * path , const char * tru test_error_exit("Case:%d rel_path(%s,%s) -> %s failed - expected: %s\n" , nr , root , path , rel_path , true_path); else printf("Case:%d OK \n",nr); - - util_safe_free( rel_path ); + + free( rel_path ); } int main(int argc , char ** argv) { @@ -49,7 +49,7 @@ int main(int argc , char ** argv) { const char * root3 = "/tmp/root/path"; const char * path3 = "/tmp/root/"; const char * true3 = "../"; - + const char * root4 = "/tmp/root/path"; const char * path4 = "relative"; const char * true4 = "relative"; @@ -61,7 +61,7 @@ int main(int argc , char ** argv) { const char * root6 = "/tmp/root/path"; const char * path6 = "/tmpX/root/pathX/relative"; const char * true6 = "../../../tmpX/root/pathX/relative"; - + const char * root7 = "/tmp/root/path"; const char * path7 = "/tmp/root/path"; const char * true7 = ""; @@ -71,7 +71,7 @@ int main(int argc , char ** argv) { const char * true8 = "root/path"; #endif - + test_path( 1 , root1 , path1 , true1 ); test_path( 2 , root2 , path2 , true2 ); test_path( 3 , root3 , path3 , true3 ); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_rng.c b/ThirdParty/Ert/lib/util/tests/ert_util_rng.cpp similarity index 73% rename from ThirdParty/Ert/lib/util/tests/ert_util_rng.c rename to ThirdParty/Ert/lib/util/tests/ert_util_rng.cpp index 8096c031e6..ed12cffa83 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_rng.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_rng.cpp @@ -1,39 +1,39 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ert_util_rng.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ert_util_rng.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include -#include +#include +#include #define MAX_INT 666661 int main(int argc , char ** argv) { - rng_type * rng = rng_alloc( MZRAN , INIT_DEFAULT ); + rng_type * rng = rng_alloc( MZRAN , INIT_DEFAULT ); { int val1 = rng_get_int( rng , MAX_INT); int val2 = rng_get_int( rng , MAX_INT); test_assert_int_not_equal( val1 , val2 ); - + rng_init( rng , INIT_DEFAULT ); val2 = rng_get_int( rng , MAX_INT ); test_assert_int_equal( val1 , val2 ); @@ -41,16 +41,16 @@ int main(int argc , char ** argv) { { int val2 , val1; int state_size = rng_state_size( rng ); - char * buffer1 = util_calloc( state_size , sizeof * buffer1 ); - char * buffer2 = util_calloc( state_size , sizeof * buffer2 ); + char * buffer1 = (char *) util_calloc( state_size , sizeof * buffer1 ); + char * buffer2 = (char *) util_calloc( state_size , sizeof * buffer2 ); test_assert_int_not_equal( state_size , 0 ); test_assert_int_equal( state_size , MZRAN_STATE_SIZE ); - + rng_init( rng , INIT_DEFAULT ); rng_get_state( rng , buffer1 ); val1 = rng_get_int( rng , MAX_INT); val2 = rng_get_int( rng , MAX_INT); - + test_assert_int_not_equal( val1 , val2 ); rng_set_state( rng , buffer1 ); val2 = rng_get_int( rng , MAX_INT); @@ -62,7 +62,7 @@ int main(int argc , char ** argv) { val2 = rng_get_int( rng , MAX_INT); rng_get_state( rng , buffer2 ); test_assert_mem_not_equal( buffer1 , buffer2 , state_size ); - + free( buffer1 ); free( buffer2 ); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_spawn.c b/ThirdParty/Ert/lib/util/tests/ert_util_spawn.cpp similarity index 94% rename from ThirdParty/Ert/lib/util/tests/ert_util_spawn.c rename to ThirdParty/Ert/lib/util/tests/ert_util_spawn.cpp index 0a81e4194f..19d402f031 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_spawn.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_spawn.cpp @@ -21,10 +21,10 @@ #include #include -#include -#include +#include +#include #include -#include +#include static const char * stdout_msg = "stdout_xxx"; @@ -81,7 +81,7 @@ void test_spawn_no_redirect() { } -void * test_spawn_redirect__( void * path ) { +void * test_spawn_redirect__( const char * path ) { char * stdout_file; char * stderr_file; char * script; @@ -128,9 +128,9 @@ void * test_spawn_redirect__( void * path ) { test_assert_file_content( stdout_file , stdout_msg ); test_assert_file_content( stderr_file , stderr_msg ); - util_free( stdout_file ); - util_free( stderr_file ); - util_free( script ); + free( stdout_file ); + free( stderr_file ); + free( script ); return NULL; } @@ -161,8 +161,9 @@ void test_spawn_redirect_threaded() { util_make_path( path ); char * script = util_alloc_filename( path , "script" , NULL); make_script(script, stdout_msg, stderr_msg); - stringlist_append_owned_ref(script_fullpaths, script); - util_free(path); + stringlist_append_copy(script_fullpaths, script); + free(script); + free(path); } // Set file access permissions @@ -178,7 +179,7 @@ void test_spawn_redirect_threaded() { } stringlist_free(script_fullpaths); - util_free(path_codes); + free(path_codes); test_work_area_free( test_area ); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_split_path.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_split_path.cpp new file mode 100644 index 0000000000..4fce2b4e81 --- /dev/null +++ b/ThirdParty/Ert/lib/util/tests/ert_util_split_path.cpp @@ -0,0 +1,50 @@ +/* + Copyright (C) 2018 Statoil ASA, Norway. + + The file 'ert_util_split_path.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. +*/ + +#include + +#include "detail/util/path.hpp" + +using namespace ecl::util; + +int main(int argc , char ** argv) { + + test_assert_std_string_equal( std::string(""), path::dirname("entry")); + test_assert_std_string_equal( std::string("entry") , path::basename("entry")); + test_assert_std_string_equal( std::string(""), path::extension("entry")); + + test_assert_std_string_equal( std::string("path"), path::dirname("path/base.ext")); + test_assert_std_string_equal( std::string("base") , path::basename("path/base.ext")); + test_assert_std_string_equal( std::string("ext"), path::extension("path/base.ext")); + + test_assert_std_string_equal( std::string("/tmp"), path::dirname("/tmp/file")); + test_assert_std_string_equal( std::string("file") , path::basename("/tmp/file")); + test_assert_std_string_equal( std::string(""), path::extension("/tmp/file")); + + test_assert_std_string_equal( std::string("/"), path::dirname("/tmp")); + test_assert_std_string_equal( std::string("tmp") , path::basename("/tmp")); + test_assert_std_string_equal( std::string(""), path::extension("/tmp")); + + test_assert_std_string_equal( std::string("/tmp/user.ext"), path::dirname("/tmp/user.ext/file.ext")); + test_assert_std_string_equal( std::string("file") , path::basename("/tmp/user.ext/file.ext")); + test_assert_std_string_equal( std::string("ext"), path::extension("/tmp/user.ext/file.ext")); + + test_assert_std_string_equal( std::string("/tmp/user.ext"), path::dirname("/tmp/user.ext/")); + test_assert_std_string_equal( std::string("") , path::basename("/tmp/user.ext/")); + test_assert_std_string_equal( std::string(""), path::extension("/tmp/user.ext/")); +} diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_sprintf_escape.c b/ThirdParty/Ert/lib/util/tests/ert_util_sprintf_escape.c deleted file mode 100644 index 0496ea72d3..0000000000 --- a/ThirdParty/Ert/lib/util/tests/ert_util_sprintf_escape.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_sprintf_escape.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ -#include -#include - -#include -#include - - - -int main(int argc , char ** argv) { - test_assert_string_equal( NULL , util_alloc_sprintf_escape( NULL , 0)); - test_assert_string_equal( "String", util_alloc_sprintf_escape( "String" , 0)); - test_assert_string_equal( "String", util_alloc_sprintf_escape( "String" , 10)); - - test_assert_string_equal( "S%%tring%%", util_alloc_sprintf_escape( "S%tring%" , 0)); - test_assert_string_equal( "S%%tring%%", util_alloc_sprintf_escape( "S%tring%" , 2)); - test_assert_string_equal( "S%%tring%%", util_alloc_sprintf_escape( "S%tring%" , 10)); - test_assert_string_equal( "S%%tring%" , util_alloc_sprintf_escape( "S%tring%" , 1)); - test_assert_string_equal( "%%%%" , util_alloc_sprintf_escape( "%%" , 0)); - test_assert_string_equal( "%%%%" , util_alloc_sprintf_escape( "%%%" , 1)); - - exit(0); -} diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_sscan_test.c b/ThirdParty/Ert/lib/util/tests/ert_util_sscan_test.cpp similarity index 97% rename from ThirdParty/Ert/lib/util/tests/ert_util_sscan_test.c rename to ThirdParty/Ert/lib/util/tests/ert_util_sscan_test.cpp index afe0f92ab1..60f4d180e1 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_sscan_test.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_sscan_test.cpp @@ -1,19 +1,19 @@ /* Copyright (C) 2014 Statoil ASA, Norway. - + The file 'ert_util_sscan_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include @@ -25,7 +25,7 @@ #include #include -#include +#include diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_statistics.c b/ThirdParty/Ert/lib/util/tests/ert_util_statistics.cpp similarity index 66% rename from ThirdParty/Ert/lib/util/tests/ert_util_statistics.c rename to ThirdParty/Ert/lib/util/tests/ert_util_statistics.cpp index 71ebdf654f..ea859328f1 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_statistics.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_statistics.cpp @@ -1,32 +1,32 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - - The file 'ert_util_statistics.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2013 Statoil ASA, Norway. + + The file 'ert_util_statistics.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include -#include -#include +#include +#include void test_mean_std() { double_vector_type * d = double_vector_alloc(0,0); - + double_vector_append(d , 0 ); double_vector_append(d , 1 ); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_strcat_test.c b/ThirdParty/Ert/lib/util/tests/ert_util_strcat_test.cpp similarity index 75% rename from ThirdParty/Ert/lib/util/tests/ert_util_strcat_test.c rename to ThirdParty/Ert/lib/util/tests/ert_util_strcat_test.cpp index a3831dde94..a7042a38eb 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_strcat_test.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_strcat_test.cpp @@ -1,33 +1,33 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_strcat_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_strcat_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include +#include #include -#include +#include void test_strcat(char * s1 , const char *s2 , const char * expected) { char * cat = util_strcat_realloc(s1 , s2 ); if (test_check_string_equal( cat , expected )) - util_safe_free( cat ); + free( cat ); else test_error_exit("util_strcat_realloc(%s,%s) Got:%s expected:%s \n",s1,s2,cat , expected); } @@ -35,7 +35,7 @@ void test_strcat(char * s1 , const char *s2 , const char * expected) { int main(int argc , char ** argv) { test_strcat(NULL , NULL , NULL); - + { const char * s = "Hei"; test_strcat(NULL, util_alloc_string_copy(s) , s); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_string_util.c b/ThirdParty/Ert/lib/util/tests/ert_util_string_util.cpp similarity index 90% rename from ThirdParty/Ert/lib/util/tests/ert_util_string_util.c rename to ThirdParty/Ert/lib/util/tests/ert_util_string_util.cpp index 5bd2123348..65389d7176 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_string_util.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_string_util.cpp @@ -1,28 +1,28 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_string_util.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_string_util.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include void test_int_vector(const int_vector_type * list , int length , ...) { @@ -45,7 +45,7 @@ void test_active_list() { int_vector_type * active_list = string_util_alloc_active_list("1,3- 10,15"); test_assert_true( string_util_init_active_list("1,3- 10,15" , active_list) ); test_int_vector( active_list , 10 , 1,3,4,5,6,7,8,9,10,15); - + test_assert_true( string_util_update_active_list("1,3- 10,15,8" , active_list) ); test_int_vector( active_list , 10 , 1,3,4,5,6,7,8,9,10,15); @@ -54,7 +54,7 @@ void test_active_list() { test_assert_true( string_util_update_active_list("14-16" , active_list) ); test_int_vector( active_list , 12 , 1,3,4,5,6,7,8,9,10,14,15,16); - + test_assert_true( string_util_update_active_list("0" , active_list) ); test_int_vector( active_list , 13 , 0,1,3,4,5,6,7,8,9,10,14,15,16); @@ -72,7 +72,7 @@ static void test2( const bool_vector_type * active_mask ) { test_assert_true( bool_vector_iget( active_mask , 9 )); test_assert_true( bool_vector_iget( active_mask , 10 )); test_assert_true( bool_vector_iget( active_mask , 15 )); - + test_assert_false( bool_vector_iget( active_mask , 0 )); test_assert_false( bool_vector_iget( active_mask , 2 )); test_assert_false( bool_vector_iget( active_mask , 11 )); @@ -83,7 +83,7 @@ static void test2( const bool_vector_type * active_mask ) { void test_active_mask() { bool_vector_type * active_mask = string_util_alloc_active_mask("1,3 -6,6- 10, 15"); - + test2( active_mask ); test_assert_true( string_util_init_active_mask("1,3- 10,15" , active_mask)); test2( active_mask ); @@ -133,7 +133,7 @@ void test_value_list() { test_int_vector( int_vector , 5,1,2,3,4,5); int_vector_free( int_vector ); } - + } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_stringlist_test.c b/ThirdParty/Ert/lib/util/tests/ert_util_stringlist_test.cpp similarity index 87% rename from ThirdParty/Ert/lib/util/tests/ert_util_stringlist_test.c rename to ThirdParty/Ert/lib/util/tests/ert_util_stringlist_test.cpp index db0817293d..1ad4c890a7 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_stringlist_test.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_stringlist_test.cpp @@ -20,28 +20,24 @@ #include #include -#include -#include -#include +#include +#include +#include void test_char() { const char * S1 = "S1"; const char * S2 = "S2"; const char * S3 = "S3"; stringlist_type * s = stringlist_alloc_new(); - stringlist_append_ref( s , S1 ); - stringlist_append_ref( s , S2 ); - stringlist_append_ref( s , S3 ); + stringlist_append_copy( s , S1 ); + stringlist_append_copy( s , S2 ); + stringlist_append_copy( s , S3 ); { - char ** ref = stringlist_alloc_char_ref( s ); char ** copy = stringlist_alloc_char_copy( s ); int i; for (i=0; i < stringlist_get_size( s ); i++) { - if (ref[i] != stringlist_iget(s , i)) - exit(1); - if (strcmp( stringlist_iget( s , i ) , copy[i]) != 0) exit(1); @@ -67,9 +63,9 @@ void test_join() { test_assert_string_equal("", empty_join); } - stringlist_append_ref( s , elt0 ); - stringlist_append_ref( s , elt1 ); - stringlist_append_ref( s , elt2 ); + stringlist_append_copy( s , elt0 ); + stringlist_append_copy( s , elt1 ); + stringlist_append_copy( s , elt2 ); const char * sep0 = ""; const char * sep1 = "!!!"; @@ -84,18 +80,18 @@ void test_join() { test_assert_string_equal( j2, "AAA abc BBB abc CCC"); stringlist_type * s1 = stringlist_alloc_new(); - stringlist_append_ref( s1 , elt0 ); + stringlist_append_copy( s1 , elt0 ); test_assert_string_equal( "AAA", stringlist_alloc_joined_string( s1, sep0)); test_assert_string_equal( "AAA", stringlist_alloc_joined_string( s1, sep1)); test_assert_string_equal( "AAA", stringlist_alloc_joined_string( s1, sep2)); stringlist_type * sub = stringlist_alloc_new(); - stringlist_append_ref( sub , elt0 ); - stringlist_append_ref( sub , elt1 ); - stringlist_append_ref( sub , elt2 ); - stringlist_append_ref( sub , elt3 ); - stringlist_append_ref( sub , elt4 ); - stringlist_append_ref( sub , elt5 ); + stringlist_append_copy( sub , elt0 ); + stringlist_append_copy( sub , elt1 ); + stringlist_append_copy( sub , elt2 ); + stringlist_append_copy( sub , elt3 ); + stringlist_append_copy( sub , elt4 ); + stringlist_append_copy( sub , elt5 ); test_assert_string_equal( "CCC:DDD:EEE", stringlist_alloc_joined_substring( sub, 2, 5, ":")); } @@ -107,9 +103,9 @@ void test_reverse() { const char *s2 = "CCC"; stringlist_type * s = stringlist_alloc_new(); - stringlist_append_ref( s , s0 ); - stringlist_append_ref( s , s1 ); - stringlist_append_ref( s , s2 ); + stringlist_append_copy( s , s0 ); + stringlist_append_copy( s , s1 ); + stringlist_append_copy( s , s2 ); stringlist_reverse(s); @@ -121,9 +117,9 @@ void test_reverse() { void test_iget_as_int() { stringlist_type * s = stringlist_alloc_new(); - stringlist_append_ref(s , "1000" ); - stringlist_append_ref(s , "1000X" ); - stringlist_append_ref(s , "XXXX" ); + stringlist_append_copy(s , "1000" ); + stringlist_append_copy(s , "1000X" ); + stringlist_append_copy(s , "XXXX" ); { int value; @@ -145,9 +141,9 @@ void test_iget_as_int() { void test_iget_as_double() { stringlist_type * s = stringlist_alloc_new(); - stringlist_append_ref(s , "1000.90" ); - stringlist_append_ref(s , "1000" ); - stringlist_append_ref(s , "XXXX" ); + stringlist_append_copy(s , "1000.90" ); + stringlist_append_copy(s , "1000" ); + stringlist_append_copy(s , "XXXX" ); { double value; @@ -170,20 +166,20 @@ void test_iget_as_double() { void test_iget_as_bool() { stringlist_type * s = stringlist_alloc_new(); - stringlist_append_ref(s , "TRUE" ); - stringlist_append_ref(s , "True" ); - stringlist_append_ref(s , "true" ); - stringlist_append_ref(s , "T" ); - stringlist_append_ref(s , "1" ); + stringlist_append_copy(s , "TRUE" ); + stringlist_append_copy(s , "True" ); + stringlist_append_copy(s , "true" ); + stringlist_append_copy(s , "T" ); + stringlist_append_copy(s , "1" ); - stringlist_append_ref(s , "FALSE" ); - stringlist_append_ref(s , "False" ); - stringlist_append_ref(s , "false" ); - stringlist_append_ref(s , "F" ); - stringlist_append_ref(s , "0" ); + stringlist_append_copy(s , "FALSE" ); + stringlist_append_copy(s , "False" ); + stringlist_append_copy(s , "false" ); + stringlist_append_copy(s , "F" ); + stringlist_append_copy(s , "0" ); - stringlist_append_ref(s , "not_so_bool" ); - stringlist_append_ref(s , "8" ); + stringlist_append_copy(s , "not_so_bool" ); + stringlist_append_copy(s , "8" ); { @@ -353,7 +349,7 @@ bool not_FILE_predicate(const char * name, const void * arg) { void test_predicate_matching() { test_work_area_type * work_area = test_work_area_alloc("predicate_test"); stringlist_type * s = stringlist_alloc_new(); - stringlist_append_ref(s, "s"); + stringlist_append_copy(s, "s"); stringlist_select_files(s, "does/not/exist", NULL, NULL); test_assert_int_equal(stringlist_get_size(s), 0); @@ -395,13 +391,13 @@ void test_unique() { test_assert_true( stringlist_unique( s )); - stringlist_append_ref( s, "S1"); + stringlist_append_copy( s, "S1"); test_assert_true( stringlist_unique( s )); - stringlist_append_ref( s, "S2"); + stringlist_append_copy( s, "S2"); test_assert_true( stringlist_unique( s )); - stringlist_append_ref( s, "S2"); + stringlist_append_copy( s, "S2"); test_assert_false( stringlist_unique( s )); } diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_strstr_int_format.c b/ThirdParty/Ert/lib/util/tests/ert_util_strstr_int_format.cpp similarity index 81% rename from ThirdParty/Ert/lib/util/tests/ert_util_strstr_int_format.c rename to ThirdParty/Ert/lib/util/tests/ert_util_strstr_int_format.cpp index 9836fb12f9..567323c8eb 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_strstr_int_format.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_strstr_int_format.cpp @@ -1,26 +1,26 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_str_str_int_format.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_str_str_int_format.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include +#include #include -#include +#include void test_util_strstr() { diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_struct_vector.c b/ThirdParty/Ert/lib/util/tests/ert_util_struct_vector.c deleted file mode 100644 index 1ac9aa25a5..0000000000 --- a/ThirdParty/Ert/lib/util/tests/ert_util_struct_vector.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 2014 Statoil ASA, Norway. - - The file 'ert_util_struct_vector.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ -#include -#include - -#include "ert/util/build_config.h" -#include -#include -#include - - - -struct test_struct { - int x; - double y; - int z; -}; - - - -void test_create() { - struct test_struct d; - struct_vector_type * struct_vector = struct_vector_alloc( sizeof d ); - test_assert_true( struct_vector_is_instance( struct_vector )); - test_assert_int_equal( struct_vector_get_size( struct_vector ) , 0 ); - struct_vector_reserve( struct_vector , 1000 ); - test_assert_int_equal( struct_vector_get_size( struct_vector ) , 0 ); - struct_vector_free( struct_vector ); -} - -void alloc_invalid() { - struct_vector_alloc( 0 ); -} - - -void test_create_invalid() { - test_assert_util_abort( "struct_vector_alloc" , alloc_invalid , NULL ); -} - -void test_append_iget() { - struct test_struct d1 = (struct test_struct) {.x = 100, .y = 99, .z = 234}; - struct test_struct d2 = (struct test_struct) {.x = 0, .y = 0, .z = 0}; - - struct_vector_type * struct_vector = struct_vector_alloc( sizeof d1 ); - - struct_vector_append( struct_vector , &d1 ); - test_assert_int_equal( struct_vector_get_size( struct_vector ) , 1 ); - struct_vector_reserve( struct_vector , 0 ); - test_assert_int_equal( struct_vector_get_size( struct_vector ) , 1 ); - - test_assert_false( d1.x == d2.x ); - test_assert_false( d1.y == d2.y ); - test_assert_false( d1.z == d2.z ); - - struct_vector_iget( struct_vector , 0 , &d2); - test_assert_true( d1.x == d2.x ); - test_assert_true( d1.y == d2.y ); - test_assert_true( d1.z == d2.z ); - - { - struct test_struct * d = struct_vector_get_data( struct_vector ); - struct test_struct d3 = d[0]; - test_assert_true( d1.x == d3.x ); - test_assert_true( d1.y == d3.y ); - test_assert_true( d1.z == d3.z ); - } - struct_vector_reset( struct_vector ); - test_assert_int_equal( struct_vector_get_size( struct_vector ) , 0 ); - - struct_vector_free( struct_vector ); -} - - - -int cmp( const void * _d1, const void * _d2) { - const struct test_struct * d1 = (const struct test_struct *) _d1; - const struct test_struct * d2 = (const struct test_struct *) _d2; - - return d1->x - d2->x; -} - - -int rcmp( const void * _d1, const void * _d2) { - return cmp(_d2 , _d1); -} - - - -void test_sort() { - struct test_struct d; - struct_vector_type * struct_vector = struct_vector_alloc( sizeof d ); - for (int i = 0; i < 10; i++) { - struct test_struct d = {.x = 9 - i, - .y = 9 - i, - .z = 9 - i }; - struct_vector_append( struct_vector , &d ); - } - struct_vector_sort( struct_vector , cmp ); - for (int i = 0; i < 9; i++) { - struct test_struct d1; - struct test_struct d2; - struct_vector_iget( struct_vector , i ,&d1 ); - struct_vector_iget( struct_vector , i + 1,&d2 ); - test_assert_true( cmp(&d1 , &d2) <= 0); - } - - struct_vector_sort( struct_vector , rcmp ); - for (int i = 0; i < 9; i++) { - struct test_struct d1; - struct test_struct d2; - struct_vector_iget( struct_vector , i ,&d1 ); - struct_vector_iget( struct_vector , i + 1,&d2 ); - test_assert_true( cmp(&d1 , &d2) >= 0); - } -} - - - -int main(int argc , char ** argv) { - test_create(); - test_create_invalid(); - test_append_iget(); - test_sort(); -} diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_test_area_xx.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_test_area_xx.cpp deleted file mode 100644 index 1d787b4a5b..0000000000 --- a/ThirdParty/Ert/lib/util/tests/ert_util_test_area_xx.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (C) 2016 Statoil ASA, Norway. - - This is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or1 - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. -*/ - -#include -#include - -#include - -// Warning: this test hardcodes an assumption of the name -// of the executable running as argv[0]. -#define LOCAL_ARGV0 "ert_util_test_area_xx" - - -void test_enter( const char* argv0 ) { - ERT::TestArea ta; - test_assert_throw( ta.copyFile( argv0 ) , std::runtime_error ); - - ta.enter("test/enter"); - ta.copyFile( argv0 ); - test_assert_true( util_file_exists( LOCAL_ARGV0 )); -} - - -void test_copy( const char* argv0 ) { - ERT::TestArea ta("test/copy"); - - test_assert_throw( ta.copyFile( "does/not/exist" ) , std::invalid_argument ); - test_assert_throw( ta.copyDirectory( argv0 ) , std::invalid_argument ); - - ta.copyFile( argv0 ); - test_assert_true( util_file_exists( LOCAL_ARGV0 )); - - util_unlink_existing( LOCAL_ARGV0 ); - test_assert_false( util_file_exists( LOCAL_ARGV0)); - - ta.copyParentContent( argv0 ); - test_assert_true( util_file_exists( LOCAL_ARGV0)); - - { - ERT::TestArea ta2("test2/copy"); - ta2.copyFile( LOCAL_ARGV0 ); - test_assert_true( util_file_exists( LOCAL_ARGV0)); - } -} - - - - -void test_create() { - char * cwd0 = util_alloc_cwd(); - char * cwd1; - { - ERT::TestArea ta("test/area"); - cwd1 = util_alloc_cwd(); - test_assert_string_not_equal( cwd0 , cwd1 ); - test_assert_string_equal( cwd1 , ta.getCwd().c_str()); - test_assert_string_equal( cwd0 , ta.getOriginalCwd( ).c_str() ); - } - test_assert_false( util_is_directory(cwd1) ); - free( cwd1 ); - free( cwd0 ); -} - - -int main(int argc , char **argv) { - test_create(); - - test_assert_true( util_file_exists( argv[0] )); - test_copy( argv[0] ); - test_enter( argv[0] ); -} diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_functions.c b/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_functions.cpp similarity index 90% rename from ThirdParty/Ert/lib/util/tests/ert_util_type_vector_functions.c rename to ThirdParty/Ert/lib/util/tests/ert_util_type_vector_functions.cpp index 07d126a4ce..802e8e69cf 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_functions.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_functions.cpp @@ -1,29 +1,29 @@ /* - Copyright (C) 2013 Statoil ASA, Norway. - + Copyright (C) 2013 Statoil ASA, Norway. + The file 'ert_util_type_vector_functions.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include -#include -#include -#include -#include +#include +#include +#include +#include void test_index_list() { @@ -33,7 +33,7 @@ void test_index_list() { int_vector_append( index_list , 30 ); { bool_vector_type * mask = int_vector_alloc_mask( index_list ); - + test_assert_false( bool_vector_get_default( mask )); test_assert_int_equal( 31 , bool_vector_size( mask )); test_assert_true( bool_vector_iget( mask , 10 )); @@ -115,7 +115,7 @@ void test_approx_equal() { double_vector_append( d2 , 3.0 ); test_assert_true( double_vector_approx_equal( d1 , d2 ,1e-6)); - + double_vector_append( d3 , 1.0 ); double_vector_append( d3 , 2.0 ); double_vector_append( d3 , 3.0 ); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_test.c b/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_test.cpp similarity index 99% rename from ThirdParty/Ert/lib/util/tests/ert_util_type_vector_test.c rename to ThirdParty/Ert/lib/util/tests/ert_util_type_vector_test.cpp index 05245bc53e..1a447db084 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_test.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_type_vector_test.cpp @@ -18,9 +18,9 @@ #include #include -#include -#include -#include +#include +#include +#include void assert_equal( bool equal ) { if (!equal) diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_unique_ptr.cpp b/ThirdParty/Ert/lib/util/tests/ert_util_unique_ptr.cpp index a3f6a32f58..a2873abd6c 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_unique_ptr.cpp +++ b/ThirdParty/Ert/lib/util/tests/ert_util_unique_ptr.cpp @@ -17,7 +17,7 @@ */ #include -#include +#include void test_stringlist() { diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_vector_test.c b/ThirdParty/Ert/lib/util/tests/ert_util_vector_test.cpp similarity index 81% rename from ThirdParty/Ert/lib/util/tests/ert_util_vector_test.c rename to ThirdParty/Ert/lib/util/tests/ert_util_vector_test.cpp index a569871813..ade1cb5f99 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_vector_test.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_vector_test.cpp @@ -18,9 +18,9 @@ #include #include -#include -#include -#include +#include +#include +#include @@ -101,19 +101,19 @@ void test_sort() { test_assert_int_equal( 4 , int_vector_iget( sort_map , 3 )); test_assert_int_equal( 3 , int_vector_iget( sort_map , 4 )); - test_assert_string_equal( "0" , vector_iget(v2 , 0 )); - test_assert_string_equal( "1" , vector_iget(v2 , 1 )); - test_assert_string_equal( "2" , vector_iget(v2 , 2 )); - test_assert_string_equal( "3" , vector_iget(v2 , 3 )); - test_assert_string_equal( "4" , vector_iget(v2 , 4 )); + test_assert_string_equal( "0" , (const char *) vector_iget(v2 , 0 )); + test_assert_string_equal( "1" , (const char *) vector_iget(v2 , 1 )); + test_assert_string_equal( "2" , (const char *) vector_iget(v2 , 2 )); + test_assert_string_equal( "3" , (const char *) vector_iget(v2 , 3 )); + test_assert_string_equal( "4" , (const char *) vector_iget(v2 , 4 )); vector_permute( v1 , sort_map ); - test_assert_string_equal( "0" , vector_iget(v1 , 0 )); - test_assert_string_equal( "1" , vector_iget(v1 , 1 )); - test_assert_string_equal( "2" , vector_iget(v1 , 2 )); - test_assert_string_equal( "3" , vector_iget(v1 , 3 )); - test_assert_string_equal( "4" , vector_iget(v1 , 4 )); + test_assert_string_equal( "0" , (const char *) vector_iget(v1 , 0 )); + test_assert_string_equal( "1" , (const char *) vector_iget(v1 , 1 )); + test_assert_string_equal( "2" , (const char *) vector_iget(v1 , 2 )); + test_assert_string_equal( "3" , (const char *) vector_iget(v1 , 3 )); + test_assert_string_equal( "4" , (const char *) vector_iget(v1 , 4 )); int_vector_free( sort_map ); } vector_free( v1 ); diff --git a/ThirdParty/Ert/lib/util/tests/ert_util_work_area.c b/ThirdParty/Ert/lib/util/tests/ert_util_work_area.cpp similarity index 92% rename from ThirdParty/Ert/lib/util/tests/ert_util_work_area.c rename to ThirdParty/Ert/lib/util/tests/ert_util_work_area.cpp index df117455f6..29e344729a 100644 --- a/ThirdParty/Ert/lib/util/tests/ert_util_work_area.c +++ b/ThirdParty/Ert/lib/util/tests/ert_util_work_area.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'ert_util_PATH_test.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'ert_util_PATH_test.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include @@ -22,8 +22,8 @@ #include #include -#include -#include +#include +#include void test_get_cwd() { @@ -50,12 +50,12 @@ void create_test_area(const char * test_name , bool store) { char * pre_cwd = util_alloc_cwd(); test_work_area_type * work_area = test_work_area_alloc( test_name ); char * work_path = util_alloc_string_copy( test_work_area_get_cwd( work_area )); - + test_work_area_set_store( work_area , store ); test_assert_true( util_is_directory( work_path )); test_work_area_free( work_area ); test_assert_bool_equal( store , util_entry_exists( work_path )); - + { char * post_cwd = util_alloc_cwd(); test_assert_string_equal( pre_cwd , post_cwd ); @@ -69,7 +69,7 @@ void create_test_area(const char * test_name , bool store) { void test_install_file_exists(const char * filename ) { char * abs_input_path = util_alloc_abs_path( filename ); test_work_area_type * work_area = test_work_area_alloc( "FILE-TEST" ); - + test_work_area_install_file( work_area , filename ); test_assert_true( util_files_equal( abs_input_path , filename )); test_work_area_free( work_area ); @@ -96,9 +96,9 @@ void test_copy_file( const char * src_file ) { char * filename = util_split_alloc_filename( src_file ); test_work_area_type * work_area = test_work_area_alloc( "copy-file" ); test_work_area_copy_file( work_area , src_file ); - + test_assert_true( util_file_exists( filename )); - + test_work_area_free( work_area ); free( filename ); } @@ -116,7 +116,7 @@ void test_copy_parent_directory( const char * path ) { test_assert_false( test_work_area_copy_parent_directory( work_area , "Does/not/exist") ); test_assert_true( test_work_area_copy_parent_directory( work_area , path ) ); - + test_assert_true( util_entry_exists( parent_path )); test_assert_true( util_is_directory( parent_path )); @@ -132,7 +132,7 @@ void test_copy_parent_content( const char * path ) { test_assert_false( test_work_area_copy_parent_content( work_area , "Does/not/exist") ); test_assert_true( test_work_area_copy_parent_content( work_area , path ) ); - + { struct dirent ** src_namelist; @@ -143,7 +143,7 @@ void test_copy_parent_content( const char * path ) { test_assert_int_equal( src_size , target_size ); for (int i=0; i < src_size; i++) { test_assert_string_equal( src_namelist[i]->d_name , target_namelist[i]->d_name); - + free( src_namelist[i] ); free( target_namelist[i] ); } @@ -223,15 +223,15 @@ int main(int argc , char ** argv) { test_input(); test_get_cwd(); test_get_original_cwd(); - + test_copy_file( rel_path_file ); test_copy_file( abs_path_file ); - test_copy_parent_directory( rel_path_file ); - test_copy_parent_directory( abs_path_file ); + test_copy_parent_directory( rel_path_file ); + test_copy_parent_directory( abs_path_file ); - test_copy_parent_content( rel_path_file ); - test_copy_parent_content( abs_path_file ); + test_copy_parent_content( rel_path_file ); + test_copy_parent_content( abs_path_file ); test_with_prefix(); test_update_store(); diff --git a/ThirdParty/Ert/lib/util/tests/test_thread_pool.c b/ThirdParty/Ert/lib/util/tests/test_thread_pool.cpp similarity index 95% rename from ThirdParty/Ert/lib/util/tests/test_thread_pool.c rename to ThirdParty/Ert/lib/util/tests/test_thread_pool.cpp index d7338a9522..1700de5a3b 100644 --- a/ThirdParty/Ert/lib/util/tests/test_thread_pool.c +++ b/ThirdParty/Ert/lib/util/tests/test_thread_pool.cpp @@ -18,8 +18,8 @@ #include #include -#include -#include +#include +#include pthread_mutex_t lock; diff --git a/ThirdParty/Ert/lib/util/timer.cpp b/ThirdParty/Ert/lib/util/timer.cpp index 49dd562754..c333a20663 100644 --- a/ThirdParty/Ert/lib/util/timer.cpp +++ b/ThirdParty/Ert/lib/util/timer.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2011 Statoil ASA, Norway. - - The file 'timer.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2011 Statoil ASA, Norway. + + The file 'timer.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include @@ -21,7 +21,7 @@ #include #include -#include +#include #include #ifdef __cplusplus @@ -43,7 +43,7 @@ struct timer_struct { timer_type * timer_alloc(bool epoch_time) { timer_type *timer; timer = (timer_type*)util_malloc(sizeof * timer ); - + timer->epoch_time = epoch_time; timer_reset(timer); return timer; @@ -56,7 +56,7 @@ void timer_free(timer_type *timer) { void timer_start(timer_type *timer) { - if (timer->running) + if (timer->running) util_abort("%s: Timer already running. Use timer_stop() or timer_restart(). Aborting \n",__func__ ); timer->running = true; @@ -64,14 +64,14 @@ void timer_start(timer_type *timer) { time( &timer->epoch_start ); else timer->clock_start = clock(); - + } double timer_stop(timer_type *timer) { time_t epoch_time; clock_t clock_time = clock(); - + time(&epoch_time); if (timer->running) { double cpu_sec; @@ -79,7 +79,7 @@ double timer_stop(timer_type *timer) { cpu_sec = 1.0 * (epoch_time - timer->epoch_start); else cpu_sec = 1.0 * (clock_time - timer->clock_start) / CLOCKS_PER_SEC; - + timer->count++; timer->sum1 += cpu_sec; timer->sum2 += cpu_sec * cpu_sec; @@ -88,9 +88,9 @@ double timer_stop(timer_type *timer) { timer->running = false; return cpu_sec; - } else + } else util_abort("%s: Timer is not running. Aborting \n",__func__ ); - + return -1; } diff --git a/ThirdParty/Ert/lib/util/util.c b/ThirdParty/Ert/lib/util/util.c index 94e42f9c81..53a0c8584a 100644 --- a/ThirdParty/Ert/lib/util/util.c +++ b/ThirdParty/Ert/lib/util/util.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include "ert/util/build_config.h" #include @@ -89,7 +89,7 @@ #endif #include -#include +#include /* @@ -271,8 +271,6 @@ static bool EOL_CHAR(char c) { return false; } -#undef strncpy // This is for some reason needed in RH3 - /* The difference between /dev/random and /dev/urandom is that the former will block if the entropy pool is close to empty: @@ -487,23 +485,6 @@ void util_string_tr(char * s, char c1, char c2) { } -void util_rewind_line(FILE *stream) { - bool at_eol = false; - int c; - - do { - if (util_ftell(stream) == 0) - at_eol = true; - else { - util_fseek(stream , -1 , SEEK_CUR); - c = fgetc(stream); - at_eol = EOL_CHAR(c); - if (!at_eol) - util_fseek(stream , -1 , SEEK_CUR); - } - } while (!at_eol); -} - /** @@ -677,10 +658,6 @@ char * util_fscanf_alloc_line(FILE *stream , bool *at_eof) { } -char * util_fscanf_realloc_line(FILE *stream , bool *at_eof , char *line) { - return util_fscanf_alloc_line__(stream , at_eof , line); -} - @@ -703,20 +680,6 @@ void util_usleep( unsigned long micro_seconds ) { #endif } -void util_yield() { -#if defined(WITH_PTHREAD) && (defined(HAVE_YIELD_NP) || defined(HAVE_YIELD)) - #ifdef HAVE_YIELD_NP - pthread_yield_np(); - #else - #ifdef HAVE_YIELD - pthread_yield(); - #endif - #endif -#else - util_usleep(1000); -#endif -} - static char * util_getcwd(char * buffer , int size) { #ifdef HAVE_POSIX_GETCWD return getcwd( buffer , size ); @@ -1077,49 +1040,6 @@ void util_fskip_lines(FILE * stream , int lines) { } -/* - The last line(s) without content are not counted, i.e. - - File: - ---------- - |Line1 - |Line2 - | - |Line4 - |empty1 - |empty2 - |empty3 - - will return a value of four. -*/ - -int util_forward_line(FILE * stream , bool * at_eof) { - bool at_eol = false; - int col = 0; - *at_eof = false; - - do { - char c = fgetc(stream); - if (c == EOF) { - *at_eof = true; - at_eol = true; - } else { - if (EOL_CHAR(c)) { - at_eol = true; - c = fgetc(stream); - if (c == EOF) - *at_eof = true; - else { - if (!EOL_CHAR(c)) - util_fseek(stream , -1 , SEEK_CUR); - } - } else - col++; - } - } while (!at_eol); - return col; -} - bool util_char_in(char c , int set_size , const char * set) { @@ -1907,25 +1827,6 @@ bool util_fscanf_int(FILE * stream , int * value) { -/** - This function counts the number of lines from the current position - in the file, to the end of line. The file pointer is repositioned - at the end of the counting. -*/ - - -int util_count_file_lines(FILE * stream) { - long int init_pos = util_ftell(stream); - int lines = 0; - bool at_eof = false; - do { - int col = util_forward_line(stream , &at_eof); - if (col > 0) lines++; - } while (!at_eof); - util_fseek(stream , init_pos , SEEK_SET); - return lines; -} - int util_count_content_file_lines(FILE * stream) { int lines = 0; @@ -2664,7 +2565,7 @@ bool util_same_file(const char * file1 , const char * file2) { return same_file; } else - return false; + return false; #endif } @@ -3219,16 +3120,6 @@ char * util_alloc_strip_copy(const char *src) { -char * util_realloc_strip_copy(char *src) { - if (src == NULL) - return NULL; - else { - char * strip_copy = util_alloc_strip_copy(src); - free(src); - return strip_copy; - } -} - char ** util_alloc_stringlist_copy(const char **src, int len) { if (src != NULL) { @@ -3327,16 +3218,6 @@ char * util_realloc_substring_copy(char * old_string , const char *src , int len } -/** - This function check that a pointer is different from NULL, and - frees the memory if that is the case. -*/ - - -void util_safe_free(void *ptr) { - if (ptr != NULL) free(ptr); -} - @@ -3444,7 +3325,7 @@ void util_free_stringlist(char **list , int N) { int i; if (list != NULL) { for (i=0; i < N; i++) { - util_safe_free( list[i] ); + free( list[i] ); } free(list); } @@ -4285,18 +4166,6 @@ double util_double_vector_stddev(int N, const double * vector) { -/** - This function will update *value so that on return ALL bits which - are set in bitmask, are also set in value. No other bits in *value - should be modified - i.e. it is a logical or. -*/ - -void util_bitmask_on(int * value , int mask) { - int tmp = *value; - tmp = (tmp | mask); - *value = tmp; -} - FILE * util_fopen__(const char * filename , const char * mode) { return fopen(filename, mode); @@ -4312,16 +4181,6 @@ FILE * util_fopen(const char * filename , const char * mode) { -/** - This micro function is only provided for the convenience of java - wrapping; if you wonder "What on earth should I use this function - for" - you can just forget about it. -*/ - -void util_fclose( FILE * stream ) { - fclose( stream ); -} - /** @@ -4463,9 +4322,6 @@ void * util_realloc_copy(void * org_ptr , const void * src , size_t byte_size ) } } -void util_free(void * ptr) { - free( ptr ); -} @@ -4564,41 +4420,6 @@ char * util_alloc_sprintf(const char * fmt , ...) { } -char * util_alloc_sprintf_escape(const char * src , int max_escape) { - if (src == NULL) - return NULL; - - if (max_escape == 0) - max_escape = strlen( src ); - - { - const int src_len = strlen( src ); - char * target = (char*)util_calloc( max_escape + strlen(src) + 1 , sizeof * target); - - int escape_count = 0; - int src_offset = 0; - int target_offset = 0; - - while (true) { - if (src[src_offset] == '%') { - if (escape_count < max_escape) { - target[target_offset] = '%'; - target_offset++; - escape_count++; - } - } - target[target_offset] = src[src_offset]; - target_offset++; - src_offset++; - if (src_offset == src_len) - break; - } - target[target_offset] = '\0'; - target = (char*)util_realloc( target , (target_offset + 1) * sizeof * target); - return target; - } -} - /* char * util_realloc_sprintf(char * s , const char * fmt , ...) { @@ -4625,7 +4446,7 @@ char * util_realloc_sprintf(char * s , const char * fmt , ...) { va_start(ap , fmt); new_s = util_alloc_sprintf_va( fmt , ap ); - util_safe_free(s); + free(s); va_end(ap); return new_s; @@ -4716,19 +4537,6 @@ void util_exit(const char * fmt , ...) { -/** - This function is quite dangerous - it will always return something; - it is the responsability of the calling scope to check that it - makes sense. Will return 0 on input NULL. -*/ - -int util_get_type( void * data ) { - if (data == NULL) - return 0; - else - return ((int *) data)[0]; -} - @@ -4768,18 +4576,6 @@ int util_get_current_linenr(FILE * stream) { -const char * util_enum_iget( int index , int size , const util_enum_element_type * enum_defs , int * value) { - if ((index < 0) || (index >= size)) { - *value = -1; - return NULL; - } else { - const util_enum_element_type elm = enum_defs[ index ]; - *value = elm.value; - return elm.name; - } -} - - @@ -4877,7 +4673,7 @@ bool util_is_abs_path(const char * path) { #ifdef ERT_WINDOWS if ((path[0] == '/') || (path[0] == '\\')) return true; - else + else if ((isalpha(path[0]) && (path[1] == ':'))) return true; @@ -4903,8 +4699,13 @@ static int util_mkdir( const char * path ) { #endif } +/* + Acts like the shell command 'mkdir -p' - i.e. creating a full directory tree. + The return value is: util_is_directory(_path) - i.e. will return true if the + directory exists at the end, and false otherwise. +*/ -void util_make_path(const char *_path) { +bool util_mkdir_p(const char *_path) { char *active_path; char *path = (char *) _path; int current_pos = 0; @@ -4912,6 +4713,7 @@ void util_make_path(const char *_path) { if (!util_is_directory(path)) { int i = 0; active_path = (char*)util_calloc(strlen(path) + 1 , sizeof * active_path ); + do { size_t n = strcspn(path , UTIL_PATH_SEP_STRING); if (n < strlen(path)) @@ -4924,27 +4726,25 @@ void util_make_path(const char *_path) { if (!util_is_directory(active_path)) { if (util_mkdir(active_path) != 0) { - bool fail = false; - switch (errno) { - case(EEXIST): - if (util_is_directory(active_path)) - fail = false; + if (errno != EEXIST) break; - default: - fail = true; - break; - } - if (fail) - util_abort("%s: failed to make directory:%s - aborting\n: %s(%d) \n",__func__ , active_path , strerror(errno), errno); } } } while (strlen(active_path) < strlen(_path)); + free(active_path); } + return util_is_directory(_path); } +void util_make_path(const char * path) { + bool mkdir_ok = util_mkdir_p(path); + if (!mkdir_ok) + util_abort("%s: failed to make directory:%s - aborting\n: %s(%d) \n",__func__ , path , strerror(errno), errno); +} + /** This function will allocate a unique filename with a random part in it. If the the path corresponding to the first argument does not @@ -5019,7 +4819,7 @@ char * util_alloc_filename(const char * path , const char * basename , const cha file = (char*) util_calloc(length , sizeof * file ); file[0] = '\0'; - + if (path && strlen(path)) { strcat(file, path); strcat(file, UTIL_PATH_SEP_STRING ); @@ -5035,31 +4835,13 @@ char * util_alloc_filename(const char * path , const char * basename , const cha char * util_realloc_filename(char * filename , const char * path , const char * basename , const char * extension) { - util_safe_free(filename); + free(filename); return util_alloc_filename( path , basename , extension ); } -#ifdef HAVE_PROC -bool util_proc_alive(pid_t pid) { - char proc_path[16]; - sprintf(proc_path , "/proc/%d" , pid); - return util_is_directory(proc_path); -} -#endif - -int util_proc_mem_free(void) { - FILE *stream = util_fopen("/proc/meminfo" , "r"); - int mem; - util_fskip_lines(stream , 1); - util_fskip_token(stream); - util_fscanf_int(stream , &mem); - fclose(stream); - return mem; -} - @@ -5081,8 +4863,8 @@ char * util_split_alloc_filename( const char * input_path ) { if (basename) filename = util_alloc_filename( NULL , basename , extension ); - util_safe_free( basename ); - util_safe_free( extension ); + free( basename ); + free( extension ); } return filename; @@ -5146,10 +4928,6 @@ char * util_alloc_parent_path( const char * path) { #ifdef ERT_HAVE_UNISTD -int util_type_get_id( const void * data ) { - int type_id = ((const int*) data)[0]; - return type_id; -} int util_chdir(const char * path) { return chdir( path ); diff --git a/ThirdParty/Ert/lib/util/util_abort_gnu.c b/ThirdParty/Ert/lib/util/util_abort_gnu.c index 1e651fd8b9..e3daca3883 100644 --- a/ThirdParty/Ert/lib/util/util_abort_gnu.c +++ b/ThirdParty/Ert/lib/util/util_abort_gnu.c @@ -34,7 +34,7 @@ #include #include -#include +#include #include @@ -105,7 +105,7 @@ static bool util_addr2line_lookup__(const void * bt_addr , char ** func_name , c address_found = true; free( stdout_file_name ); - util_safe_free( line_string ); + free( line_string ); } free( tmp_fname ); fclose(stream); @@ -200,9 +200,9 @@ static void util_fprintf_backtrace(FILE * stream) { } } - util_safe_free( func_name ); - util_safe_free( file_name ); - util_safe_free( padding ); + free( func_name ); + free( file_name ); + free( padding ); } fprintf(stream , "--------------------------------------------------------------------------------\n"); } @@ -301,7 +301,7 @@ void util_abort__(const char * file , const char * function , int line , const c } if (abort_dump != stderr) { - util_fclose(abort_dump); + fclose(abort_dump); fprintf(stderr, "\nError message: "); { va_list args; diff --git a/ThirdParty/Ert/lib/util/util_abort_simple.c b/ThirdParty/Ert/lib/util/util_abort_simple.c index 56586fd994..7345a356db 100644 --- a/ThirdParty/Ert/lib/util/util_abort_simple.c +++ b/ThirdParty/Ert/lib/util/util_abort_simple.c @@ -21,12 +21,12 @@ void util_abort__(const char * file , const char * function , int line , const c fprintf(stderr, "Version info : %s\n" , (__abort_program_message == NULL) ? "" : __abort_program_message); fprintf(stderr, "\nError message: "); fprintf(stderr , "Abort called from: %s (%s:%d) \n",function , file , line); - { + { va_list ap; va_start(ap , fmt); vfprintf(stderr , fmt , ap); va_end(ap); - } + } fprintf(stderr,"-----------------------------------------------------------------\n"); signal(SIGABRT , SIG_DFL); diff --git a/ThirdParty/Ert/lib/util/util_endian.cpp b/ThirdParty/Ert/lib/util/util_endian.cpp index 3c88e55545..0613f0e639 100644 --- a/ThirdParty/Ert/lib/util/util_endian.cpp +++ b/ThirdParty/Ert/lib/util/util_endian.cpp @@ -1,19 +1,19 @@ /* - Copyright (C) 2012 Statoil ASA, Norway. - - The file 'util_endian.c' is part of ERT - Ensemble based Reservoir Tool. - - ERT is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ERT is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License at - for more details. + Copyright (C) 2012 Statoil ASA, Norway. + + The file 'util_endian.c' is part of ERT - Ensemble based Reservoir Tool. + + ERT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ERT is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License at + for more details. */ #include #include @@ -30,12 +30,12 @@ /* Macros for endian flipping. The macros create a new endian-flipped - value, and should be used as: + value, and should be used as: flipped_value = FLIP32( value ) - + The macros are not exported and only available through the function - util_endian_flip_vector(). + util_endian_flip_vector(). */ @@ -66,7 +66,7 @@ static uint16_t util_endian_convert16( uint16_t u ) { static uint32_t util_endian_convert32( uint32_t u ) { const uint32_t m8 = (uint32_t) 0x00FF00FFUL; const uint32_t m16 = (uint32_t) 0x0000FFFFUL; - + u = (( u >> 8U ) & m8) | ((u & m8) << 8U); u = (( u >> 16U ) & m16) | ((u & m16) << 16U); return u; @@ -78,7 +78,7 @@ static uint64_t util_endian_convert64( uint64_t u ) { const uint64_t m16 = (uint64_t) 0x0000FFFF0000FFFFULL; const uint64_t m32 = (uint64_t) 0x00000000FFFFFFFFULL; - + u = (( u >> 8U ) & m8) | ((u & m8) << 8U); u = (( u >> 16U ) & m16) | ((u & m16) << 16U); u = (( u >> 32U ) & m32) | ((u & m32) << 32U); @@ -90,7 +90,7 @@ static uint64_t util_endian_convert32_64( uint64_t u ) { const uint64_t m8 = (uint64_t) 0x00FF00FF00FF00FFULL; const uint64_t m16 = (uint64_t) 0x0000FFFF0000FFFFULL; - + u = (( u >> 8U ) & m8) | ((u & m8) << 8U); u = (( u >> 16U ) & m16) | ((u & m16) << 16U); return u; @@ -103,7 +103,7 @@ void util_endian_flip_vector(void *data, int element_size , int elements) { switch (element_size) { case(1): break; - case(2): + case(2): { uint16_t *tmp16 = (uint16_t *) data; @@ -134,10 +134,10 @@ void util_endian_flip_vector(void *data, int element_size , int elements) { break; #else uint32_t *tmp32 = (uint32_t *) data; - + for (i = 0; i #include -#include +#include #include #include @@ -23,9 +23,9 @@ mode_t util_getmode( const char * file ) { bool util_chmod_if_owner( const char * filename , mode_t new_mode) { stat_type buffer; - uid_t exec_uid = getuid(); + uid_t exec_uid = getuid(); util_stat( filename , &buffer ); - + if (exec_uid == buffer.st_uid) { /* OKAY - the current running uid is also the owner of the file. */ mode_t current_mode = buffer.st_mode & ( S_IRWXU + S_IRWXG + S_IRWXO ); if (current_mode != new_mode) { @@ -33,7 +33,7 @@ bool util_chmod_if_owner( const char * filename , mode_t new_mode) { return true; } } - + return false; /* No update performed. */ } @@ -56,7 +56,7 @@ bool util_chmod_if_owner( const char * filename , mode_t new_mode) { bool util_addmode_if_owner( const char * filename , mode_t add_mode) { stat_type buffer; util_stat( filename , &buffer ); - + { mode_t current_mode = buffer.st_mode & ( S_IRWXU + S_IRWXG + S_IRWXO ); mode_t target_mode = (current_mode | add_mode); @@ -73,15 +73,15 @@ bool util_addmode_if_owner( const char * filename , mode_t add_mode) { bool util_delmode_if_owner( const char * filename , mode_t del_mode) { stat_type buffer; util_stat( filename , &buffer ); - + { mode_t current_mode = buffer.st_mode & ( S_IRWXU + S_IRWXG + S_IRWXO ); mode_t target_mode = (current_mode - (current_mode & del_mode)); - + return util_chmod_if_owner( filename , target_mode ); } } - + /** @@ -94,7 +94,7 @@ void static util_clear_directory__( const char *path , bool strict_uid , bool un if (dirH != NULL) { const uid_t uid = getuid(); struct dirent *dentry; - + while ( (dentry = readdir(dirH)) != NULL) { stat_type buffer; mode_t mode; @@ -104,19 +104,19 @@ void static util_clear_directory__( const char *path , bool strict_uid , bool un if (lstat(full_path , &buffer) == 0) { mode = buffer.st_mode; - - if (S_ISDIR(mode)) + + if (S_ISDIR(mode)) /* - Recursively descending into sub directory. + Recursively descending into sub directory. */ util_clear_directory__(full_path , strict_uid , true); - else if (S_ISLNK(mode)) + else if (S_ISLNK(mode)) /* Symbolic links are unconditionally removed. */ unlink(full_path); else if (S_ISREG(mode)) { - /* + /* It is a regular file - we remove it (if we own it!). */ if ((!strict_uid) || (buffer.st_uid == uid)) { @@ -124,7 +124,7 @@ void static util_clear_directory__( const char *path , bool strict_uid , bool un if (unlink_return != 0) { /* Unlink failed - we don't give a shit. */ } - } + } } } free(full_path); @@ -150,7 +150,7 @@ void static util_clear_directory__( const char *path , bool strict_uid , bool un If the parameter @strict_uid is set to true, the function will only attempt to remove entries where the calling uid is also the owner - of the entry. + of the entry. If the parameter @unlink_root is true the directory @path will also be removed, otherwise it will be left as an empty directory. @@ -159,7 +159,7 @@ void static util_clear_directory__( const char *path , bool strict_uid , bool un are not signalled in any way! The function is in util_getuid() because uid_t and getuid() are so - important elements of the function. + important elements of the function. */ diff --git a/ThirdParty/Ert/lib/util/util_lockf.cpp b/ThirdParty/Ert/lib/util/util_lockf.cpp index 9114b9d0d9..b88ab59e4a 100644 --- a/ThirdParty/Ert/lib/util/util_lockf.cpp +++ b/ThirdParty/Ert/lib/util/util_lockf.cpp @@ -2,12 +2,12 @@ #include #include -#include +#include #include #include -/** +/** This function will TRY to aquire an exclusive lock to the file filename. If the file does not exist it will be created. The mode will be changed to 'mode' (irrespective of whether it exists @@ -29,20 +29,20 @@ resource it should close the file descriptor. ** Observe that with this locking scheme the existence of a lockfile - ** is not really interesting. + ** is not really interesting. Observe that the lockf() system call, which this function is based on, will always succeed in the same process. I.e. this function can NOT be used to protect against concurrent update from two threads in the same process. */ - + bool util_try_lockf(const char * lockfile , mode_t mode , int * __fd) { int status; int lock_fd; - lock_fd = open(lockfile , O_WRONLY + O_CREAT , mode); - if (lock_fd == -1) + lock_fd = open(lockfile , O_WRONLY + O_CREAT , mode); + if (lock_fd == -1) util_abort("%s: failed to open lockfile:%s %d/%s\n",__func__ , lockfile,errno , strerror(errno)); fchmod(lock_fd , mode); @@ -65,7 +65,7 @@ bool util_try_lockf(const char * lockfile , mode_t mode , int * __fd) { } -/* +/* Opens a file, and locks it for exclusive acces. fclose() will release all locks. */ @@ -78,15 +78,15 @@ FILE * util_fopen_lockf(const char * filename, const char * mode) { flags = O_RDWR; /* Observe that the open call must have write option to be able to place a lock - even though we only attempt to read from the file. */ if (strcmp(mode , "w") == 0) flags += O_CREAT; - + fd = open(filename , flags, S_IRUSR|S_IWUSR); - if (fd == -1) + if (fd == -1) util_abort("%s: failed to open:%s with flags:%d \n",__func__ , filename , flags); - + lock_status = lockf(fd , F_LOCK , 0); if (lock_status != 0) util_abort("%s: failed to lock file: %s %s(%d) \n",__func__ , filename , strerror(errno) , errno); - + return fdopen(fd , mode); } diff --git a/ThirdParty/Ert/lib/util/util_opendir.cpp b/ThirdParty/Ert/lib/util/util_opendir.cpp index 6984baf67f..68ec1b53bd 100644 --- a/ThirdParty/Ert/lib/util/util_opendir.cpp +++ b/ThirdParty/Ert/lib/util/util_opendir.cpp @@ -2,21 +2,36 @@ #include #include -#include +#include #include #include bool util_copy_file__(const char * src_file , const char * target_file, size_t buffer_size , void * buffer , bool abort_on_error); + + +static DIR * util_walk_opendir__( const char * root_path ) { + + DIR * dirH = opendir( root_path ); + if (dirH == NULL) { + if (errno == EACCES) + fprintf(stderr,"** Warning could not open directory:%s - permission denied - IGNORED.\n" , root_path); + else + util_abort("%s: failed to open directory:%s / %s \n",__func__ , root_path , strerror(errno)); + } + return dirH; +} + + static void util_copy_directory__(const char * src_path , const char * target_path , int buffer_size , void * buffer ) { if (!util_is_directory(src_path)) util_abort("%s: %s is not a directory \n",__func__ , src_path); - + util_make_path(target_path); { DIR * dirH = opendir( src_path ); - if (dirH == NULL) + if (dirH == NULL) util_abort("%s: failed to open directory:%s / %s \n",__func__ , src_path , strerror(errno)); { @@ -48,12 +63,12 @@ static void util_copy_directory__(const char * src_path , const char * target_pa void util_copy_directory_content(const char * src_path , const char * target_path) { int buffer_size = 16 * 1024 * 1024; /* 16 MB */ void * buffer = util_malloc( buffer_size ); - + util_copy_directory__( src_path , target_path , buffer_size , buffer); free( buffer ); } -/** +/** Equivalent to shell command cp -r src_path target_path */ @@ -71,19 +86,50 @@ void util_copy_directory(const char * src_path , const char * __target_path) { target_path = util_alloc_filename(__target_path , path_tail , NULL); util_copy_directory_content(src_path , target_path ); - + free(target_path); util_free_stringlist( path_parts , num_components ); } +/** + This function will evaluate all file_callbacks for all the files in + the root_path directory. +*/ + +static void util_walk_file_callbacks__(const char * root_path , + int current_depth , + walk_file_callback_ftype * file_callback , + void * file_callback_arg) { + + + DIR * dirH = util_walk_opendir__( root_path ); + if (dirH != NULL) { + struct dirent * dp; + do { + dp = readdir(dirH); + if (dp != NULL) { + if (dp->d_name[0] != '.') { + char * full_path = util_alloc_filename(root_path , dp->d_name , NULL); + + if (util_is_file( full_path ) && file_callback != NULL) + file_callback( root_path , dp->d_name , file_callback_arg); + + free(full_path); + } + } + } while (dp != NULL); + closedir( dirH ); + } +} + /** This function will start at 'root_path' and then recursively go through all file/subdirectore located below root_path. For each file/directory in the tree it will call the user-supplied funtions - 'file_callback' and 'dir_callback'. + 'file_callback' and 'dir_callback'. - The arguments to file_callback will be: + The arguments to file_callback will be: file_callback(root_path, file , file_callback_arg): @@ -110,12 +156,12 @@ void util_copy_directory(const char * src_path , const char * __target_path) { The call: util_walk_directory("Root" , file_callback , file_arg , dir_callback , dir_arg); - + Will result in the following calls to the callbacks: - file_callback("Root" , "File1" , file_arg); - file_callback("Root" , "File2" , file_arg); - file_callback("Root/dir" , "fileXX" , arg); + file_callback("Root" , "File1" , file_arg); + file_callback("Root" , "File2" , file_arg); + file_callback("Root/dir" , "fileXX" , arg); dir_callback("Root" , "dir" , 1 , dir_arg); dir_callback("Root/dir" , "dir2" , 2 , dir_arg); @@ -131,59 +177,16 @@ void util_copy_directory(const char * src_path , const char * __target_path) { */ -static void util_walk_directory__(const char * root_path , - bool depth_first , +static void util_walk_directory__(const char * root_path , + bool depth_first , int current_depth , - walk_file_callback_ftype * file_callback , - void * file_callback_arg , - walk_dir_callback_ftype * dir_callback , + walk_file_callback_ftype * file_callback , + void * file_callback_arg , + walk_dir_callback_ftype * dir_callback , void * dir_callback_arg); -static DIR * util_walk_opendir__( const char * root_path ) { - DIR * dirH = opendir( root_path ); - if (dirH == NULL) { - if (errno == EACCES) - fprintf(stderr,"** Warning could not open directory:%s - permission denied - IGNORED.\n" , root_path); - else - util_abort("%s: failed to open directory:%s / %s \n",__func__ , root_path , strerror(errno)); - } - return dirH; -} - - - -/** - This function will evaluate all file_callbacks for all the files in - the root_path directory. -*/ - -static void util_walk_file_callbacks__(const char * root_path , - int current_depth , - walk_file_callback_ftype * file_callback , - void * file_callback_arg) { - - - DIR * dirH = util_walk_opendir__( root_path ); - if (dirH != NULL) { - struct dirent * dp; - do { - dp = readdir(dirH); - if (dp != NULL) { - if (dp->d_name[0] != '.') { - char * full_path = util_alloc_filename(root_path , dp->d_name , NULL); - - if (util_is_file( full_path ) && file_callback != NULL) - file_callback( root_path , dp->d_name , file_callback_arg); - - free(full_path); - } - } - } while (dp != NULL); - closedir( dirH ); - } -} @@ -198,17 +201,17 @@ static void util_walk_file_callbacks__(const char * root_path , directory will not be descended into. (If dir_callback == NULL that amounts to return true.) */ - -static void util_walk_descend__(const char * root_path , - bool depth_first , + +static void util_walk_descend__(const char * root_path , + bool depth_first , int current_depth , - walk_file_callback_ftype * file_callback , - void * file_callback_arg , - walk_dir_callback_ftype * dir_callback , + walk_file_callback_ftype * file_callback , + void * file_callback_arg , + walk_dir_callback_ftype * dir_callback , void * dir_callback_arg) { - + DIR * dirH = util_walk_opendir__( root_path ); if (dirH != NULL) { struct dirent * dp; @@ -217,12 +220,12 @@ static void util_walk_descend__(const char * root_path , if (dp != NULL) { if (dp->d_name[0] != '.') { char * full_path = util_alloc_filename(root_path , dp->d_name , NULL); - + if ((util_is_directory( full_path ) && (!util_is_link(full_path)))) { bool descend = true; if (dir_callback != NULL) descend = dir_callback( root_path , dp->d_name , current_depth , dir_callback_arg); - + if (descend && util_file_exists(full_path)) /* The callback might have removed it. */ util_walk_directory__( full_path , depth_first , current_depth + 1 , file_callback, file_callback_arg , dir_callback , dir_callback_arg ); } @@ -233,17 +236,17 @@ static void util_walk_descend__(const char * root_path , closedir( dirH ); } } - - -static void util_walk_directory__(const char * root_path , - bool depth_first , + + +static void util_walk_directory__(const char * root_path , + bool depth_first , int current_depth , - walk_file_callback_ftype * file_callback , - void * file_callback_arg , - walk_dir_callback_ftype * dir_callback , + walk_file_callback_ftype * file_callback , + void * file_callback_arg , + walk_dir_callback_ftype * dir_callback , void * dir_callback_arg) { - + if (depth_first) { util_walk_descend__( root_path , depth_first , current_depth , file_callback , file_callback_arg , dir_callback , dir_callback_arg ); util_walk_file_callbacks__( root_path , current_depth , file_callback , file_callback_arg ); @@ -255,10 +258,10 @@ static void util_walk_directory__(const char * root_path , -void util_walk_directory(const char * root_path , - walk_file_callback_ftype * file_callback , - void * file_callback_arg , - walk_dir_callback_ftype * dir_callback , +void util_walk_directory(const char * root_path , + walk_file_callback_ftype * file_callback , + void * file_callback_arg , + walk_dir_callback_ftype * dir_callback , void * dir_callback_arg) { bool depth_first = false; diff --git a/ThirdParty/Ert/lib/util/util_spawn.cpp b/ThirdParty/Ert/lib/util/util_spawn.cpp index 429e05c95d..dea8845aa3 100644 --- a/ThirdParty/Ert/lib/util/util_spawn.cpp +++ b/ThirdParty/Ert/lib/util/util_spawn.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include extern char **environ; diff --git a/ThirdParty/Ert/lib/util/util_symlink.cpp b/ThirdParty/Ert/lib/util/util_symlink.cpp index bfa79dd893..7dbd330ef6 100644 --- a/ThirdParty/Ert/lib/util/util_symlink.cpp +++ b/ThirdParty/Ert/lib/util/util_symlink.cpp @@ -4,7 +4,7 @@ #include "ert/util/build_config.hpp" #include -#include +#include #ifndef ERT_HAVE_SYMLINK @@ -24,12 +24,12 @@ char * util_alloc_link_target(const char * link) { void util_make_slink(const char *target , const char * link) { if (util_file_exists(link)) { if (util_is_link(link)) { - if (!util_same_file(target , link)) + if (!util_same_file(target , link)) util_abort("%s: %s already exists - not pointing to: %s - aborting \n",__func__ , link , target); - } else + } else util_abort("%s: %s already exists - is not a link - aborting \n",__func__ , link); } else { - if (symlink(target , link) != 0) + if (symlink(target , link) != 0) util_abort("%s: linking %s -> %s failed - aborting: %s \n",__func__ , link , target , strerror(errno)); } } @@ -72,15 +72,15 @@ char * util_alloc_link_target(const char * link) { do { target = (char*)util_realloc(target , buffer_size ); target_length = readlink(link , target , buffer_size); - - if (target_length == -1) + + if (target_length == -1) util_abort("%s: readlink(%s,...) failed with error:%s - aborting\n",__func__ , link , strerror(errno)); - + if (target_length < (buffer_size - 1)) /* Must leave room for the trailing \0 */ retry = false; else buffer_size *= 2; - + } while (retry); target[target_length] = '\0'; target = (char*)util_realloc( target , strlen( target ) + 1 ); /* Shrink down to accurate size. */ @@ -111,11 +111,11 @@ char * util_alloc_atlink_target(const char * path , const char * link) { dir = opendir( path ); if (dir == NULL) return NULL; - + path_fd = dirfd( dir ); if (path_fd == -1) return NULL; - + { bool retry = true; int target_length; @@ -123,19 +123,19 @@ char * util_alloc_atlink_target(const char * path , const char * link) { do { target = (char*)util_realloc(target , buffer_size ); target_length = readlinkat( path_fd , link , target , buffer_size); - - if (target_length == -1) + + if (target_length == -1) util_abort("%s: readlinkat(%s,...) failed with error:%s - aborting\n",__func__ , link , strerror(errno)); - + if (target_length < (buffer_size - 1)) /* Must leave room for the trailing \0 */ retry = false; else buffer_size *= 2; - + } while (retry); target[target_length] = '\0'; target = (char*)util_realloc( target , strlen( target ) + 1 ); /* Shrink down to accurate size. */ - } + } closedir( dir ); return target; } diff --git a/ThirdParty/Ert/lib/util/util_unlink.cpp b/ThirdParty/Ert/lib/util/util_unlink.cpp index 4cf13ecfa8..be7d633665 100644 --- a/ThirdParty/Ert/lib/util/util_unlink.cpp +++ b/ThirdParty/Ert/lib/util/util_unlink.cpp @@ -18,7 +18,7 @@ #include "ert/util/build_config.hpp" -#include +#include #if defined(HAVE_WINDOWS_UNLINK) diff --git a/ThirdParty/Ert/lib/util/util_zlib.cpp b/ThirdParty/Ert/lib/util/util_zlib.cpp index 95c813b68b..73d9db03f7 100644 --- a/ThirdParty/Ert/lib/util/util_zlib.cpp +++ b/ThirdParty/Ert/lib/util/util_zlib.cpp @@ -5,7 +5,7 @@ #include -#include +#include /** This function reads data from the input pointer data, and writes a @@ -23,8 +23,8 @@ void util_compress_buffer(const void * data , int data_size , void * zbuffer , u Have some not reproducible "one-in-a-thousand" problems with the return value from compress. It seemingly randomly returns: - -2 == Z_STREAM_ERROR. - + -2 == Z_STREAM_ERROR. + According to the documentation in zlib.h compress should only return one of the three values: @@ -33,7 +33,7 @@ void util_compress_buffer(const void * data , int data_size , void * zbuffer , u We mask the Z_STREAM_ERROR return value as Z_OK, with a FAT-AND_UGLY_WARNING, and continue with fingers crossed. */ - + if (compress_result == Z_STREAM_ERROR) { fprintf(stderr,"*****************************************************************\n"); fprintf(stderr,"** W A R N I N G **\n"); @@ -46,8 +46,8 @@ void util_compress_buffer(const void * data , int data_size , void * zbuffer , u printf("data_size:%d compressed_size:%ld \n",data_size , *compressed_size); util_abort("%s - kkk \n", __func__ ); } - - if (compress_result != Z_OK) + + if (compress_result != Z_OK) util_abort("%s: returned %d - different from Z_OK - aborting\n",__func__ , compress_result); } else *compressed_size = 0; @@ -108,7 +108,7 @@ void util_fwrite_compressed(const void * _data , int size , FILE * stream) { int required_buffer_size = (int) ceil(size * 1.001 + 64); int buffer_size , block_size; void * zbuffer; - + buffer_size = util_int_min(required_buffer_size , max_buffer_size); do { zbuffer = malloc(buffer_size); @@ -117,7 +117,7 @@ void util_fwrite_compressed(const void * _data , int size , FILE * stream) { } while(zbuffer == NULL); memset(zbuffer , 0 , buffer_size); block_size = (int) (floor(buffer_size / 1.002) - 64); - + { int header_write; header_write = fwrite(&size , sizeof size , 1 , stream); @@ -125,7 +125,7 @@ void util_fwrite_compressed(const void * _data , int size , FILE * stream) { if (header_write != 2) util_abort("%s: failed to write header to disk: %s \n",__func__ , strerror(errno)); } - + { int offset = 0; do { @@ -135,7 +135,7 @@ void util_fwrite_compressed(const void * _data , int size , FILE * stream) { fwrite(&compressed_size , sizeof compressed_size , 1 , stream); { unsigned long bytes_written = fwrite(zbuffer , 1 , compressed_size , stream); - if (bytes_written < compressed_size) + if (bytes_written < compressed_size) util_abort("%s: wrote only %d/%ld bytes to compressed file - aborting \n",__func__ , bytes_written , compressed_size); } offset += this_block_size; @@ -157,8 +157,8 @@ void util_fread_compressed(void *__data , FILE * stream) { int buffer_size; int size , offset; void * zbuffer; - - fread(&size , sizeof size , 1 , stream); + + fread(&size , sizeof size , 1 , stream); if (size == 0) return; @@ -172,9 +172,9 @@ void util_fread_compressed(void *__data , FILE * stream) { fread(&compressed_size , sizeof compressed_size , 1 , stream); { unsigned long bytes_read = fread(zbuffer , 1 , compressed_size , stream); - if (bytes_read < compressed_size) + if (bytes_read < compressed_size) util_abort("%s: read only %d/%d bytes from compressed file - aborting \n",__func__ , bytes_read , compressed_size); - + } uncompress_result = uncompress(&data[offset] , &block_size , (const Bytef*)zbuffer , compressed_size); if (uncompress_result != Z_OK) { @@ -188,12 +188,12 @@ void util_fread_compressed(void *__data , FILE * stream) { if (uncompress_result < 0 && uncompress_result != Z_BUF_ERROR) util_abort("%s: fatal uncompress error: %d \n",__func__ , uncompress_result); } - + offset += block_size; { int file_offset; - fread(&file_offset , sizeof offset , 1 , stream); - if (file_offset != offset) + fread(&file_offset , sizeof offset , 1 , stream); + if (file_offset != offset) util_abort("%s: something wrong when reding compressed stream - aborting \n",__func__); } } while (offset < size); @@ -212,8 +212,8 @@ void * util_fread_alloc_compressed(FILE * stream) { char * data; int size; - fread(&size , sizeof size , 1 , stream); - if (size == 0) + fread(&size , sizeof size , 1 , stream); + if (size == 0) return NULL; else { util_fseek(stream , current_pos , SEEK_SET); @@ -225,14 +225,14 @@ void * util_fread_alloc_compressed(FILE * stream) { /** - Returns the **UNCOMPRESSED** size of a compressed section. + Returns the **UNCOMPRESSED** size of a compressed section. */ int util_fread_sizeof_compressed(FILE * stream) { long pos = ftell(stream); int size; - fread(&size , sizeof size , 1 , stream); + fread(&size , sizeof size , 1 , stream); util_fseek( stream , pos , SEEK_SET ); return size; } @@ -246,7 +246,7 @@ void util_fskip_compressed(FILE * stream) { fread(&size , sizeof size , 1 , stream); if (size == 0) return; - + fread(&buffer_size , sizeof buffer_size , 1 , stream); do { unsigned long compressed_size; diff --git a/ThirdParty/Ert/lib/util/vector.cpp b/ThirdParty/Ert/lib/util/vector.cpp index 64b0043038..27da7ff790 100644 --- a/ThirdParty/Ert/lib/util/vector.cpp +++ b/ThirdParty/Ert/lib/util/vector.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include diff --git a/ThirdParty/Ert/lib/util/vector_template.cpp b/ThirdParty/Ert/lib/util/vector_template.cpp index 80958d44e9..de5ee77a28 100644 --- a/ThirdParty/Ert/lib/util/vector_template.cpp +++ b/ThirdParty/Ert/lib/util/vector_template.cpp @@ -99,7 +99,7 @@ #include #include -#include +#include #include #ifdef __cplusplus @@ -752,7 +752,7 @@ void @TYPE@_vector_free_data(@TYPE@_vector_type * vector) { void @TYPE@_vector_free(@TYPE@_vector_type * vector) { if (vector->data_owner) - util_safe_free( vector->data ); + free( vector->data ); @TYPE@_vector_free_container( vector ); } diff --git a/ThirdParty/Ert/python/CMakeLists.txt b/ThirdParty/Ert/python/CMakeLists.txt index 4ed4cd838e..6463a7704c 100644 --- a/ThirdParty/Ert/python/CMakeLists.txt +++ b/ThirdParty/Ert/python/CMakeLists.txt @@ -1,5 +1,3 @@ -install( DIRECTORY cmake DESTINATION share ) - set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") include(init_python) init_python( 2.7 ) diff --git a/ThirdParty/Ert/python/cmake/Modules/find_python_package.cmake b/ThirdParty/Ert/python/cmake/Modules/find_python_package.cmake index 3e62b604e5..37cfde2c3d 100644 --- a/ThirdParty/Ert/python/cmake/Modules/find_python_package.cmake +++ b/ThirdParty/Ert/python/cmake/Modules/find_python_package.cmake @@ -4,11 +4,17 @@ function(find_python_package_version package) set(PY_VERSION_ACCESSOR "__version__") set(PY_package_name ${package}) + if(${package} MATCHES "PyQt5") + set(PY_package_name "PyQt5.Qt") + set(PY_VERSION_ACCESSOR "PYQT_VERSION_STR") + endif() + if(${package} MATCHES "PyQt4") set(PY_package_name "PyQt4.Qt") set(PY_VERSION_ACCESSOR "PYQT_VERSION_STR") endif() + execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" "import os.path; import inspect; import ${PY_package_name} as py_m; print(\"%s;%s\" % (py_m.${PY_VERSION_ACCESSOR} , os.path.dirname(os.path.dirname(inspect.getfile(py_m)))))" RESULT_VARIABLE _${package}_fail# error code 0 if success OUTPUT_VARIABLE stdout_output # major.minor.patch diff --git a/ThirdParty/Ert/python/ecl/CMakeLists.txt b/ThirdParty/Ert/python/ecl/CMakeLists.txt index 3a9139aaf2..a4fc7c7baa 100644 --- a/ThirdParty/Ert/python/ecl/CMakeLists.txt +++ b/ThirdParty/Ert/python/ecl/CMakeLists.txt @@ -13,6 +13,11 @@ add_subdirectory(summary) add_subdirectory(util) add_subdirectory(well) + +if (INSTALL_ERT_LEGACY) + add_subdirectory(ecl) +endif() + configure_file(ecl_lib_info_build.py.in ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX}/ecl/__ecl_lib_info.py ) configure_file(ecl_lib_info_install.py.in ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX}/ecl_lib_info_install.py ) install(FILES ${PROJECT_BINARY_DIR}/${PYTHON_INSTALL_PREFIX}/ecl_lib_info_install.py DESTINATION ${PYTHON_INSTALL_PREFIX}/ecl RENAME __ecl_lib_info.py) diff --git a/ThirdParty/Ert/python/ecl/__init__.py b/ThirdParty/Ert/python/ecl/__init__.py index 9988076250..50cb5823bd 100644 --- a/ThirdParty/Ert/python/ecl/__init__.py +++ b/ThirdParty/Ert/python/ecl/__init__.py @@ -111,12 +111,16 @@ if not os.path.isdir( ecl_lib_path ): ecl_lib_path = None - if sys.hexversion < required_version_hex: raise Exception("ERT Python requires Python 2.7.") def load(name): - return cwrapload(name, path=ecl_lib_path, so_version=ert_so_version) + try: + return cwrapload(name, path=ecl_lib_path, so_version=ert_so_version) + except ImportError: + # For pip installs, setup.py puts the shared lib in this directory + own_dir=os.path.dirname(os.path.abspath(__file__)) + return cwrapload(name, path=own_dir, so_version=ert_so_version) class EclPrototype(Prototype): lib = load("libecl") diff --git a/ThirdParty/Ert/python/ecl/ecl/CMakeLists.txt b/ThirdParty/Ert/python/ecl/ecl/CMakeLists.txt new file mode 100644 index 0000000000..24fdbb8090 --- /dev/null +++ b/ThirdParty/Ert/python/ecl/ecl/CMakeLists.txt @@ -0,0 +1,5 @@ +set(PYTHON_SOURCES + __init__.py +) +add_python_package("python.ecl.ecl" ${PYTHON_INSTALL_PREFIX}/ecl/ecl "${PYTHON_SOURCES}" True) + diff --git a/ThirdParty/Ert/python/ecl/ecl/__init__.py b/ThirdParty/Ert/python/ecl/ecl/__init__.py new file mode 100644 index 0000000000..6e055a4e79 --- /dev/null +++ b/ThirdParty/Ert/python/ecl/ecl/__init__.py @@ -0,0 +1,12 @@ +# The structure of the python packages have been reorganized several times, +# unfortunately we have not managed to deprecate properly and guide users over +# to the new layout. We therefor now have two(?) varietes of old layout which +# must(?) be supported for a while. +# +# from ert.ecl import EclEgrid +# from ecl.ecl import EclGrid +# +# Both of these legacy forms are controlled by the cmake switch +# INSTALL_ERT_LEGACY. + +from ert.ecl import * diff --git a/ThirdParty/Ert/python/ecl/ecl_type.py b/ThirdParty/Ert/python/ecl/ecl_type.py index 477aeddb50..330d636a9a 100644 --- a/ThirdParty/Ert/python/ecl/ecl_type.py +++ b/ThirdParty/Ert/python/ecl/ecl_type.py @@ -13,6 +13,7 @@ # # See the GNU General Public License at # for more details. +from __future__ import absolute_import from cwrap import BaseCClass, BaseCEnum from ecl import EclPrototype diff --git a/ThirdParty/Ert/python/ecl/ecl_util.py b/ThirdParty/Ert/python/ecl/ecl_util.py index 2742c498fa..3835d3e5ae 100644 --- a/ThirdParty/Ert/python/ecl/ecl_util.py +++ b/ThirdParty/Ert/python/ecl/ecl_util.py @@ -24,7 +24,7 @@ In addition to the enum definitions there are a few stateless functions from ecl_util.c which are not bound to any class type. """ - +from __future__ import absolute_import import ctypes from cwrap import BaseCEnum diff --git a/ThirdParty/Ert/python/ecl/eclfile/ecl_file_view.py b/ThirdParty/Ert/python/ecl/eclfile/ecl_file_view.py index 16b09643c6..ccb29032fa 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/ecl_file_view.py +++ b/ThirdParty/Ert/python/ecl/eclfile/ecl_file_view.py @@ -25,6 +25,7 @@ class EclFileView(BaseCClass): TYPE_NAME = "ecl_file_view" _iget_kw = EclPrototype("ecl_kw_ref ecl_file_view_iget_kw( ecl_file_view , int)") _iget_named_kw = EclPrototype("ecl_kw_ref ecl_file_view_iget_named_kw( ecl_file_view , char* , int)") + _get_unique_kw = EclPrototype("char* ecl_file_view_iget_distinct_kw( ecl_file_view, int )") _get_size = EclPrototype("int ecl_file_view_get_size( ecl_file_view )") _get_num_named_kw = EclPrototype("int ecl_file_view_get_num_named_kw( ecl_file_view , char* )") _get_unique_size = EclPrototype("int ecl_file_view_get_num_distinct_kw( ecl_file_view )") @@ -133,6 +134,11 @@ def num_keywords(self, kw): def unique_size(self): return self._get_unique_size() + + def unique_kw(self): + return [self._get_unique_kw(index) for index in range(self.unique_size())] + + def block_view2(self, start_kw, stop_kw, start_index): idx = start_index if start_kw: diff --git a/ThirdParty/Ert/python/ecl/eclfile/ecl_kw.py b/ThirdParty/Ert/python/ecl/eclfile/ecl_kw.py index 9f43dda574..d5cd61dcad 100644 --- a/ThirdParty/Ert/python/ecl/eclfile/ecl_kw.py +++ b/ThirdParty/Ert/python/ecl/eclfile/ecl_kw.py @@ -352,7 +352,7 @@ def free(self): def __repr__(self): si = len(self) nm = self.getName() - mm = 'type=%s' % str(self.getEclType()) + mm = 'type=%s' % str(self.data_type) if self.isNumeric(): mi, ma = self.getMinMax() mm = 'min=%.2f, max=%.2f' % (mi,ma) @@ -968,7 +968,9 @@ def get_min(self): @property def type(self): - return self.getEclType() + warnings.warn("ecl_kw.type is deprecated, use .data_type", + DeprecationWarning) + return self._get_type() @property def data_type(self): @@ -1190,7 +1192,7 @@ def first_different(self, other, offset=0, epsilon=0, abs_epsilon=None, rel_epsi if offset >= len(self): raise IndexError("Offset:%d invalid - size:%d" % (offset, len(self))) - if self.getEclType() != other.getEclType(): + if self.data_type!= other.data_type: raise TypeError("The two keywords have different type") if abs_epsilon is None: diff --git a/ThirdParty/Ert/python/ecl/grid/ecl_grid.py b/ThirdParty/Ert/python/ecl/grid/ecl_grid.py index 1a923140ac..9afc3acd30 100644 --- a/ThirdParty/Ert/python/ecl/grid/ecl_grid.py +++ b/ThirdParty/Ert/python/ecl/grid/ecl_grid.py @@ -27,6 +27,7 @@ import warnings import numpy +import pandas import sys import os.path import math @@ -36,7 +37,7 @@ from ecl import EclPrototype from ecl.util.util import monkey_the_camel from ecl.util.util import IntVector -from ecl import EclDataType, EclUnitTypeEnum +from ecl import EclDataType, EclUnitTypeEnum, EclTypeEnum from ecl.eclfile import EclKW, FortIO from ecl.grid import Cell @@ -115,6 +116,13 @@ class EclGrid(BaseCClass): _export_zcorn = EclPrototype("ecl_kw_obj ecl_grid_alloc_zcorn_kw(ecl_grid)") _export_actnum = EclPrototype("ecl_kw_obj ecl_grid_alloc_actnum_kw(ecl_grid)") _export_mapaxes = EclPrototype("ecl_kw_obj ecl_grid_alloc_mapaxes_kw(ecl_grid)") + _get_unit_system = EclPrototype("ecl_unit_enum ecl_grid_get_unit_system(ecl_grid)") + _export_index_frame = EclPrototype("void ecl_grid_export_index(ecl_grid, int*, int*, bool)") + _export_data_as_int = EclPrototype("void ecl_grid_export_data_as_int(int, int*, ecl_kw, int*)", bind = False) + _export_data_as_double = EclPrototype("void ecl_grid_export_data_as_double(int, int*, ecl_kw, double*)", bind = False) + _export_volume = EclPrototype("void ecl_grid_export_volume(ecl_grid, int, int*, double*)") + _export_position = EclPrototype("void ecl_grid_export_position(ecl_grid, int, int*, double*)") + _export_corners = EclPrototype("void export_corners(ecl_grid, int, int*, double*)") @@ -1147,15 +1155,14 @@ def save_grdecl(self, pyfile, output_unit=EclUnitTypeEnum.ECL_METRIC_UNITS): cfile = CFILE(pyfile) self._fprintf_grdecl2(cfile, output_unit) - def save_EGRID(self, filename, output_unit=EclUnitTypeEnum.ECL_METRIC_UNITS): - """ - Will save the current grid as a EGRID file. - """ - self._fwrite_EGRID2(filename, output_unit) + def save_EGRID(self, filename, output_unit=None): + if output_unit is None: + output_unit = self.unit_system + self._fwrite_EGRID2(filename, output_unit) def save_GRID(self, filename, output_unit=EclUnitTypeEnum.ECL_METRIC_UNITS): """ - Will save the current grid as a EGRID file. + Will save the current grid as a GRID file. """ self._fwrite_GRID2( filename, output_unit) @@ -1254,6 +1261,136 @@ def create_volume_keyword(self, active_size=True): return self._create_volume_keyword(active_size) + def export_index(self, active_only = False): + """ + Exports a pandas dataframe containing index data of grid cells. + + The global_index of the cells is used as index in the pandas frame. + columns 0, 1, 2 are i, j, k, respectively + column 3 contains the active_index + if active_only == True, only active cells are listed, + otherwise all cells are listed. + This index frame should typically be passed to the epxport_data(), + export_volume() and export_corners() functions. + """ + if active_only: + size = self.get_num_active() + else: + size = self.get_global_size() + indx = numpy.zeros(size, dtype=numpy.int32) + data = numpy.zeros([size, 4], dtype=numpy.int32) + self._export_index_frame( indx.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)), data.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)), active_only ) + df = pandas.DataFrame(data=data, index=indx, columns=['i', 'j', 'k', 'active']) + return df + + def export_data(self, index_frame, kw, default = 0): + """ + Exports keywoard data to a numpy vector. + + Index_fram must be a pandas dataframe with the same structure + as obtained from export_index. + kw must have size of either global_size or num_active. + The length of the numpy vector is the number of rows in index_frame. + If kw is of length num_active, values in the output vector + corresponding to inactive cells are set to default. + """ + if not isinstance(index_frame, pandas.DataFrame): + raise TypeError("index_frame must be pandas.DataFrame") + if len(kw) == self.get_global_size(): + index = numpy.array( index_frame.index, dtype=numpy.int32 ) + elif len(kw) == self.get_num_active(): + index = numpy.array( index_frame["active"], dtype=numpy.int32 ) + else: + raise ValueError("The keyword must have a 3D compatible length") + + if kw.type is EclTypeEnum.ECL_INT_TYPE: + data = numpy.full( len(index), default, dtype=numpy.int32 ) + self._export_data_as_int( len(index), + index.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)), + kw, + data.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)) ) + return data + elif kw.type is EclTypeEnum.ECL_FLOAT_TYPE or kw.type is EclTypeEnum.ECL_DOUBLE_TYPE: + data = numpy.full( len(index), default, dtype=numpy.float64 ) + self._export_data_as_double( len(index), + index.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)), + kw, + data.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) ) + return data + else: + raise TypeError("Keyword must be either int, float or double.") + + def export_volume(self, index_frame): + """ + Exports cell volume data to a numpy vector. + + Index_fram must be a pandas dataframe with the same structure + as obtained from export_index. + """ + index = numpy.array( index_frame.index, dtype=numpy.int32 ) + data = numpy.zeros( len(index ), dtype=numpy.float64 ) + self._export_volume( len(index), + index.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)), + data.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) ) + return data + + def export_position(self, index_frame): + """Exports cell position coordinates to a numpy vector (matrix), with columns + 0, 1, 2 denoting coordinates x, y, and z, respectively. + + Index_fram must be a pandas dataframe with the same structure + as obtained from export_index. + """ + index = numpy.array( index_frame.index, dtype=numpy.int32 ) + data = numpy.zeros( [len(index), 3], dtype=numpy.float64 ) + self._export_position( len(index), + index.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)), + data.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) ) + return data + + def export_corners(self, index_frame): + """Exports cell corner position coordinates to a numpy vector (matrix). + + Index_fram must be a pandas dataframe with the same structure + as obtained from export_index. + Example of a row of the output matrix: + 0 1 2 .... 21 22 23 + x1 y1 z1 .... x8 y8 z8 + + In total there are eight 8 corners. They are described as follows: + The corners in a cell are numbered 0 - 7, where corners 0-3 constitute + one layer and the corners 4-7 consitute the other layer. Observe + that the numbering does not follow a consistent rotation around the face: + + + j + 6---7 /|\ + | | | + 4---5 | + | + o----------> i + 2---3 + | | + 0---1 + + Many grids are left-handed, i.e. the direction of increasing z will + point down towards the center of the earth. Hence in the figure above + the layer 4-7 will be deeper down in the reservoir than layer 0-3, and + also have higher z-value. + + Warning: The main author of this code suspects that the coordinate + system can be right-handed as well, giving a z axis which will + increase 'towards the sky'; the safest way is probably to check this + explicitly if it matters for the case at hand. + """ + index = numpy.array( index_frame.index, dtype=numpy.int32 ) + data = numpy.zeros( [len(index), 24], dtype=numpy.float64 ) + self._export_corners( len(index), + index.ctypes.data_as(ctypes.POINTER(ctypes.c_int32)), + data.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) ) + return data + + def export_coord(self): return self._export_coord() @@ -1269,6 +1406,10 @@ def export_mapaxes(self): return self._export_mapaxes() + @property + def unit_system(self): + return self._get_unit_system() + monkey_the_camel(EclGrid, 'loadFromGrdecl', EclGrid.load_from_grdecl, classmethod) monkey_the_camel(EclGrid, 'loadFromFile', EclGrid.load_from_file, classmethod) monkey_the_camel(EclGrid, 'createRectangular', EclGrid.create_rectangular, classmethod) diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_smspec_node.py b/ThirdParty/Ert/python/ecl/summary/ecl_smspec_node.py index 291b5ec949..893eb66162 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_smspec_node.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_smspec_node.py @@ -42,6 +42,7 @@ class EclSMSPECNode(BaseCClass): _gen_key2 = EclPrototype("char* smspec_node_get_gen_key2( smspec_node )") _var_type = EclPrototype("ecl_sum_var_type smspec_node_get_var_type( smspec_node )") _cmp = EclPrototype("int smspec_node_cmp( smspec_node , smspec_node)") + _get_default = EclPrototype("float smspec_node_get_default(smspec_node)") def __init__(self): super(EclSMSPECNode, self).__init__(0) # null pointer @@ -106,6 +107,19 @@ def keyword(self): def num(self): return self.getNum( ) + + @property + def default(self): + """Will return the default value for this key. + + The default value is typically used when fetching values from a + historical case, when the key is only present in the restarted case. + The default value is also used to initialize the PARAMS vector when + writing to file. + """ + return self._get_default() + + def get_key1(self): """ Returns the primary composite key, i.e. like 'WOPR:OPX' for this diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_sum.py b/ThirdParty/Ert/python/ecl/summary/ecl_sum.py index 2d2970ad9e..029334836a 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_sum.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_sum.py @@ -84,10 +84,9 @@ def date2num(dt): dt.microsecond/MUSECONDS_PER_DAY) return base - class EclSum(BaseCClass): TYPE_NAME = "ecl_sum" - _fread_alloc_case = EclPrototype("void* ecl_sum_fread_alloc_case__(char*, char*, bool)", bind=False) + _fread_alloc_case2 = EclPrototype("void* ecl_sum_fread_alloc_case2__(char*, char*, bool, bool, int)", bind=False) _fread_alloc = EclPrototype("void* ecl_sum_fread_alloc(char*, stringlist, char*, bool)", bind=False) _create_restart_writer = EclPrototype("ecl_sum_obj ecl_sum_alloc_restart_writer2(char*, char*, int, bool, bool, char*, time_t, bool, int, int, int)", bind = False) _create_writer = EclPrototype("ecl_sum_obj ecl_sum_alloc_writer(char*, bool, bool, char*, time_t, bool, int, int, int)", bind = False) @@ -95,11 +94,8 @@ class EclSum(BaseCClass): _iiget = EclPrototype("double ecl_sum_iget(ecl_sum, int, int)") _free = EclPrototype("void ecl_sum_free(ecl_sum)") _data_length = EclPrototype("int ecl_sum_get_data_length(ecl_sum)") - _scale_vector = EclPrototype("void ecl_sum_scale_vector(ecl_sum, int, double)") - _shift_vector = EclPrototype("void ecl_sum_shift_vector(ecl_sum, int, double)") _iget_sim_days = EclPrototype("double ecl_sum_iget_sim_days(ecl_sum, int) ") _iget_report_step = EclPrototype("int ecl_sum_iget_report_step(ecl_sum, int) ") - _iget_mini_step = EclPrototype("int ecl_sum_iget_mini_step(ecl_sum, int) ") _iget_sim_time = EclPrototype("time_t ecl_sum_iget_sim_time(ecl_sum, int) ") _get_report_end = EclPrototype("int ecl_sum_iget_report_end(ecl_sum, int)") _get_general_var = EclPrototype("double ecl_sum_get_general_var(ecl_sum, int, char*)") @@ -133,6 +129,7 @@ class EclSum(BaseCClass): _get_report_step_from_days = EclPrototype("int ecl_sum_get_report_step_from_days(ecl_sum, double)") _get_report_time = EclPrototype("time_t ecl_sum_get_report_time(ecl_sum, int)") _fwrite_sum = EclPrototype("void ecl_sum_fwrite(ecl_sum)") + _can_write = EclPrototype("bool ecl_sum_can_write(ecl_sum)") _set_case = EclPrototype("void ecl_sum_set_case(ecl_sum, char*)") _alloc_time_vector = EclPrototype("time_t_vector_obj ecl_sum_alloc_time_vector(ecl_sum, bool)") _alloc_data_vector = EclPrototype("double_vector_obj ecl_sum_alloc_data_vector(ecl_sum, int, bool)") @@ -143,6 +140,8 @@ class EclSum(BaseCClass): _add_tstep = EclPrototype("ecl_sum_tstep_ref ecl_sum_add_tstep(ecl_sum, int, double)") _export_csv = EclPrototype("void ecl_sum_export_csv(ecl_sum, char*, stringlist, char*, char*)") _identify_var_type = EclPrototype("ecl_sum_var_type ecl_sum_identify_var_type(char*)", bind = False) + _is_rate = EclPrototype("bool smspec_node_identify_rate(char*)", bind = False) + _is_total = EclPrototype("bool smspec_node_identify_total(char*, ecl_sum_var_type)", bind = False) _get_last_value = EclPrototype("double ecl_sum_get_last_value_gen_key(ecl_sum, char*)") _get_first_value = EclPrototype("double ecl_sum_get_first_value_gen_key(ecl_sum, char*)") _init_numpy_vector = EclPrototype("void ecl_sum_init_double_vector(ecl_sum, char*, double*)") @@ -150,9 +149,8 @@ class EclSum(BaseCClass): _init_numpy_datetime64 = EclPrototype("void ecl_sum_init_datetime64_vector(ecl_sum, int64*, int)") - def __init__(self, load_case, join_string=":", include_restart=True): - """ - Loads a new EclSum instance with summary data. + def __init__(self, load_case, join_string=":", include_restart=True, lazy_load=True, file_options=0): + """Loads a new EclSum instance with summary data. Loads a new summary results from the ECLIPSE case given by argument @load_case; @load_case should be the basename of the ECLIPSE @@ -167,15 +165,24 @@ def __init__(self, load_case, join_string=":", include_restart=True): If the @include_restart parameter is set to true the summary loader will, in the case of a restarted ECLIPSE simulation, try to load summary results also from the restarted case. + + If the @lazy_load parameter is set to true the loader will not load all + the data from a UNSMRY file at creation time, but wait until the data + is actually requested. This will reduce startup time and memory usage, + whereas getting a vector will be slower. When the summary data is split + over multiple CASE.Snnn files all the data will be loaded at + construction time, and the @lazy_load option is ignored. If the + lazy_load functionality is used the file_options intege flag is passed + when opening the UNSMRY file. + """ if not load_case: raise ValueError('load_case must be the basename of the simulation') - c_pointer = self._fread_alloc_case(load_case, join_string, include_restart) + c_pointer = self._fread_alloc_case2(load_case, join_string, include_restart, lazy_load, file_options) if c_pointer is None: raise IOError("Failed to create summary instance from argument:%s" % load_case) super(EclSum, self).__init__(c_pointer) - self.__private_init() self._load_case = load_case @@ -201,22 +208,26 @@ def load(cls, smspec_file, unsmry_file, key_join_string = ":", include_restart = @classmethod def createCReference(cls, c_pointer, parent=None): result = super(EclSum, cls).createCReference(c_pointer, parent) - if not result is None: - result.__private_init() return result @classmethod def createPythonObject(cls, c_pointer): result = super(EclSum, cls).createPythonObject(c_pointer) - result.__private_init() return result - @classmethod - def var_type(cls, keyword): - return cls._identify_var_type(keyword) + @staticmethod + def var_type(keyword): + return EclSum._identify_var_type(keyword) + @staticmethod + def is_rate(keyword): + return EclSum._is_rate(keyword) + + @staticmethod + def is_total(keyword): + return EclSum._is_total(keyword, EclSum.var_type(keyword)) @staticmethod def writer(case, @@ -297,49 +308,6 @@ def add_t_step(self, report_step, sim_days): - def __private_init(self): - # Initializing the time vectors - length = self.length - self.__dates = [0] * length - self.__report_step = numpy.zeros(length, dtype=numpy.int32) - self.__mini_step = numpy.zeros(length, dtype=numpy.int32) - self.__days = numpy.zeros(length) - self.__mpl_dates = numpy.zeros(length) - - for i in range(length): - self.__days[i] = self._iget_sim_days(i) - self.__dates[i] = self.iget_date(i) - self.__report_step[i] = self._iget_report_step(i) - self.__mini_step[i] = self._iget_mini_step(i) - self.__mpl_dates[i] = date2num(self.__dates[i]) - - index_list = self.report_index_list() - - length = len(index_list) - index_list.count(-1) - self.__datesR = [0] * length - self.__report_stepR = numpy.zeros(length, dtype=numpy.int32) - self.__mini_stepR = numpy.zeros(length, dtype=numpy.int32) - self.__daysR = numpy.zeros(length) - self.__mpl_datesR = numpy.zeros(length) - - # Slightly hysterical heuristics to accomoate for the - # situation where there are holes in the report steps series; - # when a report step is completely missing there will be -1 - # entries in the index_list. - i1 = 0 - for i0 in range(length): - while True: - time_index = index_list[i1] - i1 += 1 - if time_index >= 0: - break - - self.__daysR[i0] = self._iget_sim_days(time_index) - self.__datesR[i0] = self.iget_date(time_index) - self.__report_stepR[i0] = self._iget_report_step(time_index) - self.__mini_stepR[i0] = self._iget_mini_step(time_index) - self.__mpl_datesR[i0] = date2num(self.__datesR[i0]) - def get_vector(self, key, report_only=False): """ @@ -348,6 +316,7 @@ def get_vector(self, key, report_only=False): Will raise exception KeyError if the summary object does not have @key. """ + warnings.warn("The method get_vector() has been deprecated, use numpy_vector() instead", DeprecationWarning) self.assertKeyValid(key) if report_only: return EclSumVector(self, key, report_only=True) @@ -425,7 +394,7 @@ def _make_time_vector(self, time_index): time_points.append(t) return time_points - def numpy_vector(self, key, time_index = None): + def numpy_vector(self, key, time_index=None, report_only=False): """Will return numpy vector of all the values corresponding to @key. The optional argument @time_index can be used to limit the time points @@ -441,10 +410,22 @@ def numpy_vector(self, key, time_index = None): The function will raise KeyError if the requested key does not exist. If many keys are needed it will be faster to use the pandas_frame() function. + + If you set the optional argument report_only to True the you will only + get values at the report dates. Observe that passing report_only=True + can not be combined with a value for time_index, that will give you a + ValueError exception. + """ if key not in self: raise KeyError("No such key:%s" % key) + if report_only: + if time_index is None: + time_index = self.report_dates + else: + raise ValueError("Can not suuply both time_index and report_only=True") + if time_index is None: np_vector = numpy.zeros(len(self)) self._init_numpy_vector(key ,np_vector.ctypes.data_as(ctypes.POINTER(ctypes.c_double))) @@ -475,6 +456,15 @@ def dates(self): return np_dates.tolist() + @property + def report_dates(self): + dates = [] + if len(self): + for report in range(self.first_report,self.last_report + 1): + dates.append(self.get_report_time( report )) + return dates + + def pandas_frame(self, time_index = None, column_keys = None): """Will create a pandas frame with summary data. @@ -664,26 +654,30 @@ def __getitem__(self, key): The returned value will be a EclSumVector instance. """ + warnings.warn("The method the [] operator will change behaviour in the future. It will then return a plain numpy vector. You are advised to change to use the numpy_vector() method right away", DeprecationWarning) return self.get_vector(key) + def scale_vector(self, key, scalar): - """ecl_sum.scaleVector("WOPR:OPX", 0.78) - will scale all the elements in the 'WOPR:OPX' vector with 0.78. - """ - if not key in self: - raise KeyError("Summary object does not have key:%s" % key) + msg = """The function EclSum.scale_vector has been removed. As an alternative you +are advised to fetch vector as a numpy vector and then scale that yourself: + + vec = ecl_sum.numpy_vector(key) + vec *= scalar - key_index = self._get_general_var_index(key) - self._scale_vector(key_index, float(scalar)) + """ + raise NotImplementedError(msg) def shift_vector(self, key, addend): - """ecl_sum.shiftVector("WOPR:OPX", 0.78) - will shift (add) all the elements in the 'WOPR:OPX' vector with 0.78. + msg = """The function EclSum.shift_vector has been removed. As an alternative you +are advised to fetch vector as a numpy vector and then scale that yourself: + + vec = ecl_sum.numpy_vector(key) + vec += scalar + """ - if not key in self: - raise KeyError("Summary object does not have key:%s" % key) - key_index = self._get_general_var_index(key) - self._shift_vector(key_index, float(addend)) + raise NotImplementedError(msg) + def check_sim_time(self, date): """ @@ -1033,9 +1027,12 @@ def get_days(self, report_only=False): 'days' values corresponding to report steps will be included. """ if report_only: - return self.__daysR + dates = self.report_dates + start_date = self.data_start + start = datetime.date(start_date.year, start_date.month, start_date.day) + return [ (x - start).total_seconds( ) / 86400 for x in dates ] else: - return self.__days + return [ self._iget_sim_days(index) for index in range(len(self)) ] def get_dates(self, report_only=False): """ @@ -1047,9 +1044,9 @@ def get_dates(self, report_only=False): to report steps will be included. """ if report_only: - return self.__datesR + return self.report_dates else: - return self.__dates + return self.dates @property def mpl_dates(self): @@ -1060,8 +1057,10 @@ def mpl_dates(self): i.e. floats - generated by the date2num() function at the top of this file. """ + warnings.warn("The mpl_dates property has been deprecated - use numpy_dates instead", DeprecationWarning) return self.get_mpl_dates(False) + def get_mpl_dates(self, report_only=False): """ Will return a numpy vector of dates ready for matplotlib @@ -1072,39 +1071,11 @@ def get_mpl_dates(self, report_only=False): format, i.e. floats - generated by the date2num() function at the top of this file. """ + warnings.warn("The get_mpl_dates( ) method has been deprecated - use numpy_dates instead", DeprecationWarning) if report_only: - return self.__mpl_datesR + return [ date2num(dt) for dt in self.report_dates ] else: - return self.__mpl_dates - - @property - def mini_step(self): - """ - Will return a a python list of ministep values. - - Will return a Python list of ministep values from this summary - case; the ministep values are the internal indexing of - timesteps provided by the reservoir simulator. In normal cases - this will be: [0,1,2,3,4,5,....], but in the case of restarted - simulations it can start at a higher value, and there can also - be 'holes' in the series if 'RPTONLY' has been used in THE - ECLIPSE datafile. - """ - return self.get_mini_step(False) - - def get_mini_step(self, report_only=False): - """ - Will return a a python list of ministep values. - - If the optional argument @report_only is set to True, only - dates values corresponding to report steps will be - included. See documentation of property: 'mini_step' for - further documentation. - """ - if report_only: - return self.__mini_stepR - else: - return self.__mini_step + return [ date2num(dt) for dt in self.dates ] @property @@ -1125,9 +1096,13 @@ def report_step(self): def get_report_step(self, report_only=False): if report_only: - return self.__report_stepR + report_steps = list(range(self.first_report, self.last_report + 1)) else: - return self.__report_step + report_steps = [] + for index in range(len(self)): + report_steps.append( self._iget_report_step(index) ) + + return report_steps #----------------------------------------------------------------- @@ -1171,6 +1146,11 @@ def first_day(self): @property def sim_length(self): + """Will return the total time span for the simulation data. + + The lengt will be returned in time unit used in the simulation data; + i.e. typically days. + """ return self.getSimulationLength() @property @@ -1420,9 +1400,14 @@ def keys(self, pattern=None): return s + def can_write(self): + return self._can_write( ) def fwrite(self, ecl_case=None): + if not self.can_write(): + raise NotImplementedError("Write method is not implemented for this case. lazy_load=True??") + if ecl_case: self._set_case(ecl_case) diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_sum_node.py b/ThirdParty/Ert/python/ecl/summary/ecl_sum_node.py index ed4ccfc680..23cd98b06f 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_sum_node.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_sum_node.py @@ -1,6 +1,6 @@ class EclSumNode(object): - def __init__(self, mini_step, report_step, days, date, mpl_date, value): + def __init__(self, report_step, days, date, mpl_date, value): """ EclSumNode is a 'struct' with a summary value and time. @@ -11,7 +11,6 @@ def __init__(self, mini_step, report_step, days, date, mpl_date, value): value : The actual value report_step : The report step - mini_step : The ministep days : Days since simulation start date : The simulation date mpl_date : A date format suitable for matplotlib @@ -19,7 +18,6 @@ def __init__(self, mini_step, report_step, days, date, mpl_date, value): """ self.value = value self.report_step = report_step - self.mini_step = mini_step self.days = days self.date = date self.mpl_date = mpl_date diff --git a/ThirdParty/Ert/python/ecl/summary/ecl_sum_vector.py b/ThirdParty/Ert/python/ecl/summary/ecl_sum_vector.py index 4ec15faedd..8c7a614eef 100644 --- a/ThirdParty/Ert/python/ecl/summary/ecl_sum_vector.py +++ b/ThirdParty/Ert/python/ecl/summary/ecl_sum_vector.py @@ -47,7 +47,6 @@ def __init__(self, parent, key, report_only = False): self.__dates = parent.get_dates(report_only) self.__days = parent.get_days(report_only) self.__mpl_dates = parent.get_mpl_dates(report_only) - self.__mini_step = parent.get_mini_step(report_only) self.__report_step = parent.get_report_step(report_only) self.__values = None @@ -70,7 +69,7 @@ def assert_values(self): This function will load and internalize all the values. """ if self.__values is None: - self.__values = self.parent.get_values(self.key, self.report_only) + self.__values = self.parent.numpy_vector(self.key, report_only = self.report_only) @property def values(self): @@ -103,20 +102,6 @@ def mpl_dates(self): """ return self.__mpl_dates - @property - def mini_step(self): - """ - All the ministeps of the vector. - - Ministeps is the ECLIPSE notion of timesteps. The ministeps - are numbered sequentially starting at zero; if you have loaded - the entire simulation the ministep number will correspond to - the natural indexing. The length of each ministep is - determined by the convergence properties of the ECLIPSE - simulation. - """ - return self.__mini_step - @property def report_step(self): """ @@ -131,8 +116,7 @@ def __iget(self, index): through the [] operator, otherwise you can come across unitialized data. """ - return EclSumNode(self.__mini_step[index], - self.__report_step[index], + return EclSumNode(self.__report_step[index], self.__days[index], self.__dates[index], self.__mpl_dates[index], diff --git a/ThirdParty/Ert/python/ecl/util/test/extended_testcase.py b/ThirdParty/Ert/python/ecl/util/test/extended_testcase.py index 7f71f31969..89b9b62c81 100644 --- a/ThirdParty/Ert/python/ecl/util/test/extended_testcase.py +++ b/ThirdParty/Ert/python/ecl/util/test/extended_testcase.py @@ -62,11 +62,6 @@ def __init__(self , *args , **kwargs): super(ExtendedTestCase , self).__init__(*args , **kwargs) - def __str__(self): - return 'ExtendedTestCase( TESTADATA_ROOT=%s, SOURCE_ROOT=%s, SHARE_ROOT=%s)' % (self.TESTDATA_ROOT, - self.SOURCE_ROOT, - self.SHARE_ROOT) - def assertFloatEqual(self, first, second, msg=None, tolerance=1e-6): try: f_first, f_second = float(first), float(second) diff --git a/ThirdParty/Ert/python/ecl/util/util/CMakeLists.txt b/ThirdParty/Ert/python/ecl/util/util/CMakeLists.txt index 8374950ce2..c3b4cf13d7 100644 --- a/ThirdParty/Ert/python/ecl/util/util/CMakeLists.txt +++ b/ThirdParty/Ert/python/ecl/util/util/CMakeLists.txt @@ -16,7 +16,6 @@ set(PYTHON_SOURCES vector_template.py permutation_vector.py version.py - arg_pack.py cwd_context.py ) diff --git a/ThirdParty/Ert/python/ecl/util/util/__init__.py b/ThirdParty/Ert/python/ecl/util/util/__init__.py index feccb678d1..aa5edf30b6 100644 --- a/ThirdParty/Ert/python/ecl/util/util/__init__.py +++ b/ThirdParty/Ert/python/ecl/util/util/__init__.py @@ -62,7 +62,6 @@ from .hash import Hash, StringHash, DoubleHash, IntegerHash from .thread_pool import ThreadPool from .install_abort_signals import installAbortSignals, updateAbortSignals -from .arg_pack import ArgPack from .cwd_context import CWDContext diff --git a/ThirdParty/Ert/python/ecl/util/util/stringlist.py b/ThirdParty/Ert/python/ecl/util/util/stringlist.py index fcdc185d88..19d4de759e 100644 --- a/ThirdParty/Ert/python/ecl/util/util/stringlist.py +++ b/ThirdParty/Ert/python/ecl/util/util/stringlist.py @@ -1,18 +1,18 @@ -# Copyright (C) 2011 Statoil ASA, Norway. -# -# The file 'stringlist.py' is part of ERT - Ensemble based Reservoir Tool. -# -# ERT is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# ERT is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. -# -# See the GNU General Public License at -# for more details. +# Copyright (C) 2011 Statoil ASA, Norway. +# +# The file 'stringlist.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at +# for more details. """ Simple wrapping of stringlist 'class' from C library. @@ -23,7 +23,7 @@ For a pure Python application you should just stick with a normal Python list of string objects; but when interfacing with the C libraries there are situations where you might need to instantiate a -StringList object. +StringList object. The StringList constructor can take an optional argument which should be an iterable consisting of strings, and the strings property will @@ -58,7 +58,7 @@ class StringList(BaseCClass): def __init__(self, initial=None): """ Creates a new stringlist instance. - + Creates a new stringlist instance. The optional argument @initial should be an iterable of strings which will be the initial content of the StringList; the content will be copied @@ -124,7 +124,7 @@ def __setitem__(self, index, value): def __getitem__(self, index): """ Implements [] read operator on the stringlist. - + The __getitem__ method supports negative, i.e. from the right, indexing; but not slices. """ @@ -157,7 +157,7 @@ def __iadd__(self , other): self.append( s ) return self - + def __add__(self , other): copy = StringList( initial = self ) copy += other @@ -173,15 +173,15 @@ def __ior__(self , other): if not s in self: self.append( s ) return self - - + + def __or__(self , other): copy = StringList( initial = self ) copy |= other return copy - - + + def contains(self, s): """ Checks if the list contains @s. @@ -222,8 +222,8 @@ def empty(self): def pop(self): """ - Will remove the last element from the list and return it. - + Will remove the last element from the list and return it. + Will raise IndexError if list is empty. """ if not self.empty(): @@ -275,7 +275,7 @@ def sort(self, cmp_flag=0): The string comparison can be altered with the value of the optional cmp_flag parameter: - + 0 : Normal strcmp() string comparison 1 : util_strcmp_int() string comparison 2 : util_strcmp_float() string comparison diff --git a/ThirdParty/Ert/python/ert/util/__init__.py b/ThirdParty/Ert/python/ert/util/__init__.py index 48e2d7bff7..be7a5f4310 100644 --- a/ThirdParty/Ert/python/ert/util/__init__.py +++ b/ThirdParty/Ert/python/ert/util/__init__.py @@ -13,7 +13,6 @@ from ecl.util.util import Hash, StringHash, DoubleHash, IntegerHash from ecl.util.util import ThreadPool from ecl.util.util import installAbortSignals, updateAbortSignals -from ecl.util.util import ArgPack try: from res.util import SubstitutionList diff --git a/ThirdParty/Ert/python/tests/ecl_tests/CMakeLists.txt b/ThirdParty/Ert/python/tests/ecl_tests/CMakeLists.txt index 6444b8bfe3..5196dd1016 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/CMakeLists.txt +++ b/ThirdParty/Ert/python/tests/ecl_tests/CMakeLists.txt @@ -1,6 +1,7 @@ set(TEST_SOURCES __init__.py test_deprecation.py + test_ecl_ecl.py test_removed.py test_ecl_3dkw.py test_ecl_file_statoil.py @@ -14,10 +15,15 @@ set(TEST_SOURCES test_fault_blocks_statoil.py test_faults.py test_fortio.py + test_grdecl_statoil.py test_grdecl.py test_grid.py + test_grid_pandas.py test_cell.py test_grid_statoil.py + test_grid_statoil_coarse.py + test_grid_statoil_dual.py + test_grid_statoil_large_case.py test_grid_generator.py test_indexed_read.py test_ecl_kw_statoil.py @@ -48,6 +54,7 @@ add_python_package("python.tests.ecl_tests" ${PYTHON_INSTALL_PREFIX}/tests/ecl_ addPythonTest(tests.ecl_tests.test_fk_user_data.FKTest) addPythonTest(tests.ecl_tests.test_cell.CellTest) addPythonTest(tests.ecl_tests.test_grid.GridTest LABELS SLOW_1) +addPythonTest(tests.ecl_tests.test_grid_pandas.GridPandasTest) addPythonTest(tests.ecl_tests.test_grid_generator.GridGeneratorTest LABELS SLOW_2) addPythonTest(tests.ecl_tests.test_ecl_kw.KWTest LABELS SLOW_2) addPythonTest(tests.ecl_tests.test_kw_function.KWFunctionTest) @@ -71,10 +78,18 @@ addPythonTest(tests.ecl_tests.test_ecl_type.EclDataTypeTest) addPythonTest(tests.ecl_tests.test_region.RegionTest) addPythonTest(tests.ecl_tests.test_debug.DebugTest) +if (INSTALL_ERT_LEGACY) + addPythonTest(tests.ecl_tests.test_ecl_ecl.EclEclTest) +endif() + addPythonTest(tests.ecl_tests.test_ecl_file_statoil.EclFileStatoilTest) +addPythonTest(tests.ecl_tests.test_grdecl_statoil.GRDECLStatoilTest) addPythonTest(tests.ecl_tests.test_grdecl.GRDECLTest) addPythonTest(tests.ecl_tests.test_grid_statoil.GridTest) +addPythonTest(tests.ecl_tests.test_grid_statoil_coarse.GridCoarceTest) +addPythonTest(tests.ecl_tests.test_grid_statoil_dual.GridDualTest) +addPythonTest(tests.ecl_tests.test_grid_statoil_large_case.GridLargeCaseTest) addPythonTest(tests.ecl_tests.test_ecl_kw_statoil.KWTest) addPythonTest(tests.ecl_tests.test_ecl_init_file.InitFileTest) addPythonTest(tests.ecl_tests.test_ecl_restart_file.RestartFileTest) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_ecl.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_ecl.py new file mode 100644 index 0000000000..b017a82ee7 --- /dev/null +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_ecl.py @@ -0,0 +1,15 @@ +from tests import EclTest + +class EclEclTest(EclTest): + + def test_import(self): + import ecl.ecl as ecl + grid = ecl.EclGrid + sum = ecl.EclSum + f = ecl.EclFile + rft = ecl.EclRFTFile + + def test_import2(self): + from ecl.ecl import EclFile + from ecl.ecl import EclGrid + from ecl.ecl import EclSum diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file.py index 717012aed3..c04ef9ef9a 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file.py @@ -183,10 +183,32 @@ def test_broken_file(self): with TestAreaContext("test_broken_file"): with open("CASE.FINIT", "w") as f: f.write("This - is not a ECLISPE file\nsdlcblhcdbjlwhc\naschscbasjhcasc\nascasck c s s aiasic asc") + f = EclFile("CASE.FINIT") + self.assertEqual(len(f), 0) - with self.assertRaises(IOError): - f = EclFile("CASE.FINIT") + kw = EclKW("HEADER", 100, EclDataType.ECL_INT) + with openFortIO("FILE",mode=FortIO.WRITE_MODE) as f: + kw.fwrite(f) + kw.fwrite(f) + + with open("FILE", "a+") as f: + f.write("Seom random gibberish") + + f = EclFile("FILE") + self.assertEqual(len(f), 2) + + + with openFortIO("FILE",mode=FortIO.WRITE_MODE) as f: + kw.fwrite(f) + kw.fwrite(f) + + file_size = os.path.getsize("FILE") + with open("FILE", "a+") as f: + f.truncate(file_size * 0.75) + + f = EclFile("FILE") + self.assertEqual(len(f), 1) def test_block_view(self): diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file_statoil.py index 8377b639f0..8cffcbc259 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_file_statoil.py @@ -137,19 +137,6 @@ def test_save_fmt(self): self.assertFilesAreEqual("ECLIPSE.FUNRST", self.test_fmt_file) - def test_truncated(self): - with TestAreaContext("python/ecl_file/truncated") as work_area: - work_area.copy_file(self.test_file) - size = os.path.getsize("ECLIPSE.UNRST") - with open("ECLIPSE.UNRST" , "r+") as f: - f.truncate( size / 2 ) - - with self.assertRaises(IOError): - rst_file = EclFile("ECLIPSE.UNRST") - - with self.assertRaises(IOError): - rst_file = EclFile("ECLIPSE.UNRST", flags=EclFileFlagEnum.ECL_FILE_WRITABLE) - def test_restart_view(self): f = EclFile( self.test_file ) with self.assertRaises(ValueError): diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw.py index 88d4fa9fb7..7528b85b66 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_kw.py @@ -72,8 +72,7 @@ def test_deprecated_datatypes(self): self.assertEqual(EclTypeEnum.ECL_INT_TYPE, kw.type) - self.assertTrue(len(w) > 0) - self.assertTrue(issubclass(w[-1].category, DeprecationWarning)) + self.assertTrue(len(w) == 1) def kw_test(self, data_type, data, fmt): name1 = "file1.txt" diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum.py index 2177dbce95..80c69003b7 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum.py @@ -141,7 +141,12 @@ def test_missing_unsmry_keyword(self): def test_labscale(self): case = self.createTestPath("Statoil/ECLIPSE/LabScale/HDMODEL") - sum = EclSum(case) + sum = EclSum(case, lazy_load=True) self.assertEqual(sum.getStartTime(), datetime.datetime(2013,1,1,0,0,0)) self.assertEqual(sum.getEndTime() , datetime.datetime(2013,1,1,19,30,0)) - self.assertFloatEqual(sum.getSimulationLength(), 0.8125) + self.assertFloatEqual(sum.getSimulationLength(), 19.50) + + sum = EclSum(case, lazy_load=False) + self.assertEqual(sum.getStartTime(), datetime.datetime(2013,1,1,0,0,0)) + self.assertEqual(sum.getEndTime() , datetime.datetime(2013,1,1,19,30,0)) + self.assertFloatEqual(sum.getSimulationLength(), 19.50) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum_vector.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum_vector.py index 454fa9143a..90e799eb1b 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum_vector.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_sum_vector.py @@ -38,7 +38,7 @@ def test_reportOnly_warns(self): warnings.simplefilter("always") vector = EclSumVector(self.ecl_sum, "FOPT", True) - assert len(w) == 1 + self.assertEqual(len(w), 2) assert issubclass(w[-1].category, DeprecationWarning) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_util.py b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_util.py index 89003401c1..fc5c03d7dc 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_util.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_ecl_util.py @@ -21,12 +21,12 @@ class EclUtilTest(EclTest): def test_enums(self): - source_file_path = "lib/include/ert/ecl/ecl_util.h" + source_file_path = "lib/include/ert/ecl/ecl_util.hpp" self.assertEnumIsFullyDefined(EclFileEnum, "ecl_file_enum", source_file_path) self.assertEnumIsFullyDefined(EclPhaseEnum, "ecl_phase_enum", source_file_path) self.assertEnumIsFullyDefined(EclUnitTypeEnum, "ert_ecl_unit_enum", source_file_path) - source_file_path = "lib/include/ert/ecl/ecl_type.h" + source_file_path = "lib/include/ert/ecl/ecl_type.hpp" self.assertEnumIsFullyDefined(EclTypeEnum, "ecl_type_enum", source_file_path) def test_file_type(self): diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl.py index 6063c109e0..58337e00ef 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl.py @@ -1,7 +1,6 @@ -#!/usr/bin/env python -# Copyright (C) 2011 Statoil ASA, Norway. +# Copyright (C) 2018 Statoil ASA, Norway. # -# The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. +# The file 'test_grdecl.py' is part of ERT - Ensemble based Reservoir Tool. # # ERT is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,110 +15,23 @@ # for more details. import os -from ecl.eclfile import EclKW, Ecl3DKW -from ecl.grid import EclGrid -from tests import EclTest, statoil_test +from ecl.eclfile import EclKW +from ecl.util.test import TestAreaContext +from tests import EclTest +import cwrap -from cwrap import open as copen - - -@statoil_test() class GRDECLTest(EclTest): - def setUp(self): - self.src_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/include/example_permx.GRDECL") - self.file_list = [] - - def addFile(self, filename): - self.file_list.append(filename) - - def tearDown(self): - for f in self.file_list: - if os.path.exists(f): - os.unlink(f) - - - def test_Load( self ): - kw = EclKW.read_grdecl(copen(self.src_file, "r"), "PERMX") - self.assertTrue(kw) - - grid = EclGrid( self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE" )) - kw = Ecl3DKW.read_grdecl(grid , copen(self.src_file, "r"), "PERMX") - self.assertTrue( isinstance( kw , Ecl3DKW )) - - - - def test_reload( self ): - kw = EclKW.read_grdecl(copen(self.src_file, "r"), "PERMX") - tmp_file1 = "/tmp/permx1.grdecl" - tmp_file2 = "/tmp/permx2.grdecl" - self.addFile(tmp_file1) - self.addFile(tmp_file2) - - fileH = copen(tmp_file1, "w") - kw.write_grdecl(fileH) - fileH.close() - - kw1 = EclKW.read_grdecl(copen(tmp_file1, "r"), "PERMX") - - fileH = copen(tmp_file2, "w") - kw1.write_grdecl(fileH) - fileH.close() - - self.assertFilesAreEqual(tmp_file1, tmp_file2) - - - def test_fseek( self ): - file = copen(self.src_file, "r") - self.assertTrue(EclKW.fseek_grdecl(file, "PERMX")) - self.assertFalse(EclKW.fseek_grdecl(file, "PERMY")) - file.close() - - file = copen(self.src_file, "r") - kw1 = EclKW.read_grdecl(file, "PERMX") - self.assertFalse(EclKW.fseek_grdecl(file, "PERMX")) - self.assertTrue(EclKW.fseek_grdecl(file, "PERMX", rewind=True)) - file.close() - - - def test_fseek2(self): - test_src = self.createTestPath("local/ECLIPSE/grdecl-test/test.grdecl") - # Test kw at the the very start - file = copen(test_src, "r") - self.assertTrue(EclKW.fseek_grdecl(file, "PERMX")) - - # Test commented out kw: - self.assertFalse(EclKW.fseek_grdecl(file, "PERMY")) - self.assertFalse(EclKW.fseek_grdecl(file, "PERMZ")) - - # Test ignore not start of line: - self.assertTrue(EclKW.fseek_grdecl(file, "MARKER")) - self.assertFalse(EclKW.fseek_grdecl(file, "PERMXYZ")) - - # Test rewind - self.assertFalse(EclKW.fseek_grdecl(file, "PERMX", rewind=False)) - self.assertTrue(EclKW.fseek_grdecl(file, "PERMX", rewind=True)) - - # Test multiline comments + blanks - self.assertTrue(EclKW.fseek_grdecl(file, "LASTKW")) - - - def test_fseek_dos(self): - test_src = self.createTestPath("local/ECLIPSE/grdecl-test/test.grdecl_dos") # File formatted with \r\n line endings. - # Test kw at the the very start - file = copen(test_src, "r") - self.assertTrue(EclKW.fseek_grdecl(file, "PERMX")) - # Test commented out kw: - self.assertFalse(EclKW.fseek_grdecl(file, "PERMY")) - self.assertFalse(EclKW.fseek_grdecl(file, "PERMZ")) + def test_64bit_memory(self): + with TestAreaContext("large_memory"): + block_size = 10**6 + with open("test.grdecl","w") as f: + f.write("COORD\n") + for i in range(1000): + f.write("%d*0.15 \n" % block_size) + f.write("/\n") - # Test ignore not start of line: - self.assertTrue(EclKW.fseek_grdecl(file, "MARKER")) - self.assertFalse(EclKW.fseek_grdecl(file, "PERMXYZ")) + with cwrap.open("test.grdecl") as f: + kw = EclKW.read_grdecl(f,"COORD") - # Test rewind - self.assertFalse(EclKW.fseek_grdecl(file, "PERMX", rewind=False)) - self.assertTrue(EclKW.fseek_grdecl(file, "PERMX", rewind=True)) - # Test multiline comments + blanks - self.assertTrue(EclKW.fseek_grdecl(file, "LASTKW")) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl_statoil.py new file mode 100644 index 0000000000..a627d84cd9 --- /dev/null +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grdecl_statoil.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +# Copyright (C) 2011 Statoil ASA, Norway. +# +# The file 'sum_test.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at +# for more details. + +import os +from ecl.eclfile import EclKW, Ecl3DKW +from ecl.grid import EclGrid +from tests import EclTest, statoil_test + +from cwrap import open as copen + + +@statoil_test() +class GRDECLStatoilTest(EclTest): + def setUp(self): + self.src_file = self.createTestPath("Statoil/ECLIPSE/Gurbat/include/example_permx.GRDECL") + self.file_list = [] + + def addFile(self, filename): + self.file_list.append(filename) + + def tearDown(self): + for f in self.file_list: + if os.path.exists(f): + os.unlink(f) + + + def test_Load( self ): + kw = EclKW.read_grdecl(copen(self.src_file, "r"), "PERMX") + self.assertTrue(kw) + + grid = EclGrid( self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE" )) + kw = Ecl3DKW.read_grdecl(grid , copen(self.src_file, "r"), "PERMX") + self.assertTrue( isinstance( kw , Ecl3DKW )) + + + + def test_reload( self ): + kw = EclKW.read_grdecl(copen(self.src_file, "r"), "PERMX") + tmp_file1 = "/tmp/permx1.grdecl" + tmp_file2 = "/tmp/permx2.grdecl" + self.addFile(tmp_file1) + self.addFile(tmp_file2) + + fileH = copen(tmp_file1, "w") + kw.write_grdecl(fileH) + fileH.close() + + kw1 = EclKW.read_grdecl(copen(tmp_file1, "r"), "PERMX") + + fileH = copen(tmp_file2, "w") + kw1.write_grdecl(fileH) + fileH.close() + + self.assertFilesAreEqual(tmp_file1, tmp_file2) + + + def test_fseek( self ): + file = copen(self.src_file, "r") + self.assertTrue(EclKW.fseek_grdecl(file, "PERMX")) + self.assertFalse(EclKW.fseek_grdecl(file, "PERMY")) + file.close() + + file = copen(self.src_file, "r") + kw1 = EclKW.read_grdecl(file, "PERMX") + self.assertFalse(EclKW.fseek_grdecl(file, "PERMX")) + self.assertTrue(EclKW.fseek_grdecl(file, "PERMX", rewind=True)) + file.close() + + + def test_fseek2(self): + test_src = self.createTestPath("local/ECLIPSE/grdecl-test/test.grdecl") + # Test kw at the the very start + file = copen(test_src, "r") + self.assertTrue(EclKW.fseek_grdecl(file, "PERMX")) + + # Test commented out kw: + self.assertFalse(EclKW.fseek_grdecl(file, "PERMY")) + self.assertFalse(EclKW.fseek_grdecl(file, "PERMZ")) + + # Test ignore not start of line: + self.assertTrue(EclKW.fseek_grdecl(file, "MARKER")) + self.assertFalse(EclKW.fseek_grdecl(file, "PERMXYZ")) + + # Test rewind + self.assertFalse(EclKW.fseek_grdecl(file, "PERMX", rewind=False)) + self.assertTrue(EclKW.fseek_grdecl(file, "PERMX", rewind=True)) + + # Test multiline comments + blanks + self.assertTrue(EclKW.fseek_grdecl(file, "LASTKW")) + + + def test_fseek_dos(self): + test_src = self.createTestPath("local/ECLIPSE/grdecl-test/test.grdecl_dos") # File formatted with \r\n line endings. + # Test kw at the the very start + file = copen(test_src, "r") + self.assertTrue(EclKW.fseek_grdecl(file, "PERMX")) + + # Test commented out kw: + self.assertFalse(EclKW.fseek_grdecl(file, "PERMY")) + self.assertFalse(EclKW.fseek_grdecl(file, "PERMZ")) + + # Test ignore not start of line: + self.assertTrue(EclKW.fseek_grdecl(file, "MARKER")) + self.assertFalse(EclKW.fseek_grdecl(file, "PERMXYZ")) + + # Test rewind + self.assertFalse(EclKW.fseek_grdecl(file, "PERMX", rewind=False)) + self.assertTrue(EclKW.fseek_grdecl(file, "PERMX", rewind=True)) + + # Test multiline comments + blanks + self.assertTrue(EclKW.fseek_grdecl(file, "LASTKW")) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid.py index 6c4be05924..b3df4dee7c 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grid.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid.py @@ -16,7 +16,7 @@ # for more details. import os.path import six -from unittest import skipIf +from unittest import skipIf, skip import time import itertools from numpy import linspace @@ -235,6 +235,10 @@ def test_node_pos(self): self.assertEqual( p7 , (10,20,30)) + # The broken file was previously handled by the ecl_file_open() call internally + # in the ecl_grid implementation. That will now not fail for a broken file, and then + # the grid class needs to do more/better checking itself. + @skip("Needs better error checking inside in the ecl_grid") def test_truncated_file(self): grid = GridGen.createRectangular( (10,20,30) , (1,1,1) ) with TestAreaContext("python/ecl_grid/truncated"): diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_pandas.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_pandas.py new file mode 100644 index 0000000000..f02bdb8f17 --- /dev/null +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_pandas.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# Copyright (C) 2018 Statoil ASA, Norway. +# +# The file 'test_grid.pandas' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at +# for more details. + +import numpy as np +import pandas as pd + +from ecl import EclTypeEnum + +from ecl.eclfile import EclKW + +from ecl.grid import EclGrid + +from tests import EclTest + +class GridPandasTest(EclTest): + + def test_dataframe_actnum(self): + grid = EclGrid.create_rectangular( (2,3,1), (1,1,1) , actnum=[1, 1, 0, 0, 1, 1]) + df = grid.export_index(True) + index_matrix = np.array([ [0, 0, 0, 0], + [1, 0, 0, 1], + [0, 2, 0, 2], + [1, 2, 0, 3] ]) + assert( np.array_equal(df.values, index_matrix) ) + + kw_int_active = EclKW('int_act', 4, EclTypeEnum.ECL_INT_TYPE) + kw_int_active[0] = 9 + kw_int_active[1] = 8 + kw_int_active[2] = 7 + kw_int_active[3] = 6 + data = grid.export_data(df, kw_int_active) + assert( len(data) == 4 ) + assert( np.array_equal(data, np.array([9, 8, 7, 6])) ) + + kw_float_active = EclKW('float_at', 4, EclTypeEnum.ECL_FLOAT_TYPE) + kw_float_active[0] = 10.5 + kw_float_active[1] = 9.25 + kw_float_active[2] = 2.0 + kw_float_active[3] = 1.625 + data = grid.export_data(df, kw_float_active) + assert( len(data) == 4 ) + assert( np.array_equal(data, np.array([10.5, 9.25, 2.0, 1.625])) ) + + kw_int_global = EclKW('int_glob', 6, EclTypeEnum.ECL_INT_TYPE) + kw_int_global[0] = 0 + kw_int_global[1] = 2 + kw_int_global[2] = 4 + kw_int_global[3] = 6 + kw_int_global[4] = 8 + kw_int_global[5] = 9 + data = grid.export_data(df, kw_int_global) + assert( len(data) == 4) + assert( np.array_equal(data, np.array([0, 2, 8, 9])) ) + + kw_double_global = EclKW('double_g', 6, EclTypeEnum.ECL_DOUBLE_TYPE) + kw_double_global[0] = 1.1 + kw_double_global[1] = 2.2 + kw_double_global[2] = 3.3 + kw_double_global[3] = 4.4 + kw_double_global[4] = 5.5 + kw_double_global[5] = 6.6 + data = grid.export_data(df, kw_double_global) + assert( np.array_equal(data, np.array([1.1, 2.2, 5.5, 6.6])) ) + + df = grid.export_index() #DataFrame has now 6 rows + global_index = df.index; + assert( np.array_equal(global_index, np.array([0, 1, 2, 3, 4, 5])) ) + + data = grid.export_data(df, kw_int_active, 9999) + assert( np.array_equal(data, np.array([9, 8, 9999, 9999, 7, 6])) ) + + data = grid.export_data(df, kw_float_active, 2222.0) + assert( np.array_equal(data, np.array([10.5, 9.25, 2222.0, 2222.0, 2.0, 1.625])) ) + + + def test_dataframe_grid_data(self): + grid = EclGrid.create_rectangular( (2,3,1), (1,1,1) , actnum=[1, 1, 0, 0, 1, 1]) + index_frame = grid.export_index() + volume_data = grid.export_volume(index_frame) + assert( len(volume_data) == 6 ) + assert( np.array_equal(volume_data, np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0])) ) + + position_data = grid.export_position(index_frame) + x_pos = position_data[:, 0] + y_pos = position_data[:, 1] + z_pos = position_data[:, 2] + assert( np.array_equal(x_pos, np.array([0.5, 1.5, 0.5, 1.5, 0.5, 1.5])) ) + assert( np.array_equal(y_pos, np.array([0.5, 0.5, 1.5, 1.5, 2.5, 2.5])) ) + assert( np.array_equal(z_pos, np.array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5])) ) + + corner_data = grid.export_corners(index_frame) + compare = np.array([[0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0], + [1.0, 0.0, 0.0, 2.0, 0.0, 0.0, 1.0, 1.0, 0.0, 2.0, 1.0, 0.0, 1.0, 0.0, 1.0, 2.0, 0.0, 1.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0], + [0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 2.0, 0.0, 1.0, 2.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 2.0, 1.0, 1.0, 2.0, 1.0], + [1.0, 1.0, 0.0, 2.0, 1.0, 0.0, 1.0, 2.0, 0.0, 2.0, 2.0, 0.0, 1.0, 1.0, 1.0, 2.0, 1.0, 1.0, 1.0, 2.0, 1.0, 2.0, 2.0, 1.0], + [0.0, 2.0, 0.0, 1.0, 2.0, 0.0, 0.0, 3.0, 0.0, 1.0, 3.0, 0.0, 0.0, 2.0, 1.0, 1.0, 2.0, 1.0, 0.0, 3.0, 1.0, 1.0, 3.0, 1.0], + [1.0, 2.0, 0.0, 2.0, 2.0, 0.0, 1.0, 3.0, 0.0, 2.0, 3.0, 0.0, 1.0, 2.0, 1.0, 2.0, 2.0, 1.0, 1.0, 3.0, 1.0, 2.0, 3.0, 1.0]]) + assert( np.array_equal(corner_data, compare) ) + + diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil.py index 19f6be7295..a925b6ac0b 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil.py @@ -25,7 +25,7 @@ from cwrap import open as copen import time -from ecl import EclDataType +from ecl import EclDataType, EclUnitTypeEnum from ecl.eclfile import EclKW, EclFile, openEclFile from ecl.grid import EclGrid from ecl.util.util import DoubleVector, IntVector @@ -242,24 +242,6 @@ def test_save(self): g2 = self.create("test.grdecl") self.assertTrue(g1.equal(g2)) - @skipIf(EclTest.slowTestShouldNotRun(), "Slow test of coarse grid skipped!") - def test_coarse(self): - #work_area = TestArea("python/grid-test/testCoarse") - with TestAreaContext("python/grid-test/testCoarse"): - testGRID = True - g1 = EclGrid(self.createTestPath("Statoil/ECLIPSE/LGCcase/LGC_TESTCASE2.EGRID")) - - g1.save_EGRID("LGC.EGRID") - g2 = EclGrid("LGC.EGRID") - self.assertTrue(g1.equal(g2, verbose=True)) - - if testGRID: - g1.save_GRID("LGC.GRID") - g3 = EclGrid("LGC.GRID") - self.assertTrue(g1.equal(g3, verbose=True)) - - self.assertTrue(g1.coarse_groups() == 3384) - def test_raise_IO_error(self): with self.assertRaises(IOError): @@ -293,52 +275,6 @@ def test_boundingBox(self): self.assertEqual( bbox , ((3,3) , (7,3) , (7,7) , (3,7))) - - - - @skipIf(EclTest.slowTestShouldNotRun(), "Slow test of dual grid skipped!") - def test_dual(self): - with TestAreaContext("python/grid-test/testDual"): - grid = EclGrid(self.egrid_file()) - self.assertFalse(grid.dualGrid()) - self.assertTrue(grid.getNumActiveFracture() == 0) - - grid2 = EclGrid(self.grid_file()) - self.assertFalse(grid.dualGrid()) - self.assertTrue(grid.getNumActiveFracture() == 0) - - dgrid = EclGrid(self.createTestPath("Statoil/ECLIPSE/DualPoro/DUALPOR_MSW.EGRID")) - self.assertTrue(dgrid.getNumActive() == dgrid.getNumActiveFracture()) - self.assertTrue(dgrid.getNumActive() == 46118) - - dgrid2 = EclGrid(self.createTestPath("Statoil/ECLIPSE/DualPoro/DUALPOR_MSW.GRID")) - self.assertTrue(dgrid.getNumActive() == dgrid.getNumActiveFracture()) - self.assertTrue(dgrid.getNumActive() == 46118) - self.assertTrue(dgrid.equal(dgrid2)) - - - # The DUAL_DIFF grid has been manipulated to create a - # situation where some cells are only matrix active, and some - # cells are only fracture active. - dgrid = EclGrid(self.createTestPath("Statoil/ECLIPSE/DualPoro/DUAL_DIFF.EGRID")) - self.assertTrue(dgrid.getNumActive() == 106) - self.assertTrue(dgrid.getNumActiveFracture() == 105) - - self.assertTrue(dgrid.get_active_fracture_index(global_index=0) == -1) - self.assertTrue(dgrid.get_active_fracture_index(global_index=2) == -1) - self.assertTrue(dgrid.get_active_fracture_index(global_index=3) == 0) - self.assertTrue(dgrid.get_active_fracture_index(global_index=107) == 104) - - self.assertTrue(dgrid.get_active_index(global_index=1) == 1) - self.assertTrue(dgrid.get_active_index(global_index=105) == 105) - self.assertTrue(dgrid.get_active_index(global_index=106) == -1) - self.assertTrue(dgrid.get_global_index1F(2) == 5) - - dgrid.save_EGRID("DUAL_DIFF.EGRID") - dgrid2 = EclGrid("DUAL_DIFF.EGRID") - self.assertTrue(dgrid.equal(dgrid2 , verbose = True)) - - @skipIf(EclTest.slowTestShouldNotRun(), "Slow test of numActive large memory skipped!") def test_num_active_large_memory(self): case = self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE") @@ -391,12 +327,6 @@ def test_volume_kw(self): self.assertEqual( volume , grid.cell_volume( global_index = global_index )) - - def test_large_case(self): - grdecl_file = self.createTestPath("Statoil/ECLIPSE/1.6.0_issueGrdecl/test_aug2016_gridOnly.grdecl") - grid = EclGrid.loadFromGrdecl( grdecl_file ) - - def test_lgr_get(self): grid = EclGrid(self.createTestPath("Statoil/ECLIPSE/Troll/MSW_LGR/2BRANCHES-CCEWELLPATH-NEW-SCH-TUNED-AR3.EGRID")) for (nr,name) in [ ( 104 , "LG003017"), diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_coarse.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_coarse.py new file mode 100644 index 0000000000..11f94ebc90 --- /dev/null +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_coarse.py @@ -0,0 +1,42 @@ +# Copyright (C) 2018 Statoil ASA, Norway. +# +# The file 'test_grid_statoil_coarse.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at +# for more details. +import math + +from ecl.util.test import TestAreaContext +from ecl.grid import EclGrid + +from tests import EclTest, statoil_test + + +@statoil_test() +class GridCoarceTest(EclTest): + + def test_coarse(self): + #work_area = TestArea("python/grid-test/testCoarse") + with TestAreaContext("python/grid-test/testCoarse"): + testGRID = True + g1 = EclGrid(self.createTestPath("Statoil/ECLIPSE/LGCcase/LGC_TESTCASE2.EGRID")) + + g1.save_EGRID("LGC.EGRID") + g2 = EclGrid("LGC.EGRID") + self.assertTrue(g1.equal(g2, verbose=True)) + + if testGRID: + g1.save_GRID("LGC.GRID") + g3 = EclGrid("LGC.GRID") + self.assertTrue(g1.equal(g3, verbose=True)) + + self.assertTrue(g1.coarse_groups() == 3384) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_dual.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_dual.py new file mode 100644 index 0000000000..eeb907c075 --- /dev/null +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_dual.py @@ -0,0 +1,71 @@ +# Copyright (C) 2018 Statoil ASA, Norway. +# +# The file 'test_grid_statoil_dual.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at +# for more details. +import math + +from ecl.util.test import TestAreaContext +from ecl.grid import EclGrid + +from tests import EclTest, statoil_test + +@statoil_test() +class GridDualTest(EclTest): + + def egrid_file(self): + return self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID") + + def grid_file(self): + return self.createTestPath("Statoil/ECLIPSE/Gurbat/ECLIPSE.GRID") + + def test_dual(self): + with TestAreaContext("python/grid-test/testDual"): + grid = EclGrid(self.egrid_file()) + self.assertFalse(grid.dualGrid()) + self.assertTrue(grid.getNumActiveFracture() == 0) + + grid2 = EclGrid(self.grid_file()) + self.assertFalse(grid.dualGrid()) + self.assertTrue(grid.getNumActiveFracture() == 0) + + dgrid = EclGrid(self.createTestPath("Statoil/ECLIPSE/DualPoro/DUALPOR_MSW.EGRID")) + self.assertTrue(dgrid.getNumActive() == dgrid.getNumActiveFracture()) + self.assertTrue(dgrid.getNumActive() == 46118) + + dgrid2 = EclGrid(self.createTestPath("Statoil/ECLIPSE/DualPoro/DUALPOR_MSW.GRID")) + self.assertTrue(dgrid.getNumActive() == dgrid.getNumActiveFracture()) + self.assertTrue(dgrid.getNumActive() == 46118) + self.assertTrue(dgrid.equal(dgrid2)) + + + # The DUAL_DIFF grid has been manipulated to create a + # situation where some cells are only matrix active, and some + # cells are only fracture active. + dgrid = EclGrid(self.createTestPath("Statoil/ECLIPSE/DualPoro/DUAL_DIFF.EGRID")) + self.assertTrue(dgrid.getNumActive() == 106) + self.assertTrue(dgrid.getNumActiveFracture() == 105) + + self.assertTrue(dgrid.get_active_fracture_index(global_index=0) == -1) + self.assertTrue(dgrid.get_active_fracture_index(global_index=2) == -1) + self.assertTrue(dgrid.get_active_fracture_index(global_index=3) == 0) + self.assertTrue(dgrid.get_active_fracture_index(global_index=107) == 104) + + self.assertTrue(dgrid.get_active_index(global_index=1) == 1) + self.assertTrue(dgrid.get_active_index(global_index=105) == 105) + self.assertTrue(dgrid.get_active_index(global_index=106) == -1) + self.assertTrue(dgrid.get_global_index1F(2) == 5) + + dgrid.save_EGRID("DUAL_DIFF.EGRID") + dgrid2 = EclGrid("DUAL_DIFF.EGRID") + self.assertTrue(dgrid.equal(dgrid2 , verbose = True)) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_large_case.py b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_large_case.py new file mode 100644 index 0000000000..09b4b366df --- /dev/null +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_grid_statoil_large_case.py @@ -0,0 +1,29 @@ +# Copyright (C) 2018 Statoil ASA, Norway. +# +# The file 'test_grid_statoil_large_case.py' is part of ERT - Ensemble based Reservoir Tool. +# +# ERT is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ERT is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. +# +# See the GNU General Public License at +# for more details. +import math + +from ecl.util.test import TestAreaContext +from ecl.grid import EclGrid + +from tests import EclTest, statoil_test + + +@statoil_test() +class GridLargeCaseTest(EclTest): + + def test_large_case(self): + grdecl_file = self.createTestPath("Statoil/ECLIPSE/1.6.0_issueGrdecl/test_aug2016_gridOnly.grdecl") + grid = EclGrid.loadFromGrdecl( grdecl_file ) diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_sum.py b/ThirdParty/Ert/python/tests/ecl_tests/test_sum.py index c4dc3f46a5..b29c8e0da9 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_sum.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_sum.py @@ -101,7 +101,7 @@ def test_TIME_special_case(self): def test_identify_var_type(self): - self.assertEnumIsFullyDefined( EclSumVarType , "ecl_smspec_var_type" , "lib/include/ert/ecl/smspec_node.h") + self.assertEnumIsFullyDefined( EclSumVarType , "ecl_smspec_var_type" , "lib/include/ert/ecl/smspec_node.hpp") self.assertEqual( EclSum.varType( "WWCT:OP_X") , EclSumVarType.ECL_SMSPEC_WELL_VAR ) self.assertEqual( EclSum.varType( "RPR") , EclSumVarType.ECL_SMSPEC_REGION_VAR ) self.assertEqual( EclSum.varType( "WNEWTON") , EclSumVarType.ECL_SMSPEC_MISC_VAR ) @@ -229,33 +229,6 @@ def assert_solve(self, case): self.assertEqual( sol[1] , t2 ) - def test_ecl_sum_vector_algebra(self): - scalar = 0.78 - addend = 2.718281828459045 - - case = create_case() - with self.assertRaises( KeyError ): - case.scaleVector( "MISSING:KEY" , scalar) - case.shiftVector( "MISSING:KEY" , addend) - - # scale all vectors with scalar - for key in case.keys(): - x = case.get_values(key) # get vector key - case.scaleVector(key , scalar) - y = case.get_values(key) - x = x * scalar # numpy vector scaling - for i in range(len(x)): - self.assertFloatEqual(x[i], y[i]) - - # shift all vectors with addend - for key in case.keys(): - x = case.get_values(key) # get vector key - case.shiftVector(key , addend) - y = case.get_values(key) - x = x + addend # numpy vector shifting - for i in range(len(x)): - self.assertFloatEqual(x[i], y[i]) - def test_different_names(self): case = create_case() @@ -523,7 +496,7 @@ def test_numpy_vector(self): dates = [datetime.datetime(2000,1,1)] + case.dates + [datetime.datetime(2020,1,1)] fopr = case.numpy_vector("FOPR", time_index = dates) fopt = case.numpy_vector("FOPT", time_index = dates) - + self.assertEqual(len(fopt), len(dates)) self.assertEqual(fopr[0], 0) self.assertEqual(fopr[-1], 0) @@ -532,8 +505,22 @@ def test_numpy_vector(self): self.assertEqual(fopt[0], case.first_value("FOPT")) self.assertEqual(fopt[-1], case.last_value("FOPT")) + with self.assertRaises(ValueError): + v = case.numpy_vector("FOPR", time_index=dates, report_only=True) + + v = case.numpy_vector("FOPR", report_only=True) + self.assertEqual(len(v), len(case.report_dates)) + def test_vector(self): + case = create_case() + + # The get_vector method is extremely deprecated. + v1 = case.get_vector("FOPT") + v2 = case.get_vector("FOPT", report_only = True) + s1 = sum( [x.value for x in v1 ]) + s2 = sum( [x.value for x in v2 ]) + def test_pandas(self): case = create_case() dates = [datetime.datetime(2000,1,1)] + case.dates + [datetime.datetime(2020,1,1)] @@ -560,3 +547,41 @@ def test_pandas(self): rows, columns = frame.shape self.assertEqual(len(case.keys()), columns) self.assertEqual(len(case), rows) + + + def test_total_and_rate(self): + self.assertTrue( EclSum.is_total("FOPT")) + self.assertTrue( EclSum.is_total("WWPT:OP_3")) + self.assertFalse( EclSum.is_total("RPR:2")) + + self.assertTrue( EclSum.is_rate("WOPR:OP_4")) + self.assertFalse( EclSum.is_rate("BPR:123")) + self.assertTrue(EclSum.is_rate("FWIR")) + + + def test_load_case(self): + path = os.path.join(self.TESTDATA_ROOT, "local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3") + case = EclSum( path ) + self.assertFloatEqual(case.sim_length, 545.0) + + fopr = case.numpy_vector("FOPR") + for time_index,value in enumerate(fopr): + self.assertEqual(fopr[time_index], value) + + + + def test_write_not_implemented(self): + path = os.path.join(self.TESTDATA_ROOT, "local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3") + case = EclSum( path, lazy_load=True ) + self.assertFalse(case.can_write()) + with self.assertRaises(NotImplementedError): + case.fwrite( ) + + + + def test_directory_conflict(self): + with TestAreaContext("dir_conflict"): + case = create_case("UNITS") + case.fwrite() + os.mkdir("UNITS") + case2 = EclSum("./UNITS") diff --git a/ThirdParty/Ert/python/tests/ecl_tests/test_sum_statoil.py b/ThirdParty/Ert/python/tests/ecl_tests/test_sum_statoil.py index 2ab3a5fa31..477d5135e3 100644 --- a/ThirdParty/Ert/python/tests/ecl_tests/test_sum_statoil.py +++ b/ThirdParty/Ert/python/tests/ecl_tests/test_sum_statoil.py @@ -63,7 +63,7 @@ def test_invalid(self): def test_KeyError(self): sum = self.ecl_sum with self.assertRaises(KeyError): - v = sum["KeyMissing"] + v = sum.numpy_vector("KeyMissing") with self.assertRaises(KeyError): v = sum.get_interp("Missing" , days = 750) @@ -98,9 +98,9 @@ def test_interp(self): self.assertEqual(sum.get_interp("WOPR:OP_1" , days = 31) , 7996) self.assertEqual(sum.get_interp("WOPR:OP_1" , date=datetime.date(2000,2,1)) , 7996) - FPR = sum["FPR"] - self.assertFloatEqual(sum.get_interp("FPR" , days = 0) , FPR[0].value) - self.assertFloatEqual(sum.get_interp("FPR" , days = 31) , FPR[1].value) + FPR = sum.numpy_vector("FPR") + self.assertFloatEqual(sum.get_interp("FPR" , days = 0) , FPR[0]) + self.assertFloatEqual(sum.get_interp("FPR" , days = 31) , FPR[1]) with self.assertRaises(ValueError): sum.get_interp("WOPR:OP_1") @@ -135,7 +135,7 @@ def test_last( self ): self.assertFloatEqual(last.days, 1826.0) self.assertEqual(last.date, datetime.datetime(2004, 12, 31, 0, 0, 0)) - self.assertFloatEqual(self.ecl_sum.get_last_value("FGPT"), 6605249024.0) + self.assertFloatEqual(self.ecl_sum.last_value("FGPT"), 6605249024.0) self.assertEqual( len(self.ecl_sum) , 63 ) @@ -202,15 +202,12 @@ def test_report(self): self.assertFloatEqual(sum.get_from_report("FOPT", 10), 6.67447e+06) - @skipIf(EclTest.slowTestShouldNotRun(), "Slow test skipped") def test_fwrite(self): - # todo: What is tested here? - # work_area = TestArea("python/sum-test/fwrite", True) + ecl_sum = EclSum(self.case, lazy_load=False) with TestAreaContext("python/sum-test/fwrite") as work_area: - self.ecl_sum.fwrite(ecl_case="CASE") + ecl_sum.fwrite(ecl_case="CASE") self.assertTrue(True) - def test_block(self): sum = self.ecl_sum index_ijk = sum.get_key_index("BPR:15,28,1") @@ -370,7 +367,7 @@ def test_timeRange(self): def test_Heidrun(self): sum = EclSum( self.createTestPath("Statoil/ECLIPSE/Heidrun/Summary/FF12_2013B3_CLEAN_RS")) self.assertEqual( 452 , len(sum)) - self.assertFloatEqual( 1.8533144e+8 , sum.get_last_value("FOPT")) + self.assertFloatEqual( 1.8533144e+8 , sum.last_value("FOPT")) trange = sum.timeRange( start = datetime.date( 2015 , 1 , 1), interval = "1M") self.assertTrue( trange[0] == datetime.date( 2016 , 2 , 1 )) @@ -447,11 +444,12 @@ def test_restart_mapping(self): self.assertFalse( "WGPR:NOT_21_D" in history ) self.assertTrue( "WGPR:NOT_21_D" in total ) - self.assertEqual( total.iget( "WGPR:NOT_21_D", 5) , 0) # Default value + node = total.smspec_node("WGPR:NOT_21_D") + self.assertEqual( total.iget( "WGPR:NOT_21_D", 5) , node.default) def test_write(self): with TestAreaContext("my_space") as area: - intersect_summary = EclSum( self.createTestPath( "Statoil/ECLIPSE/SummaryRestart/iter-1/NOR-2013A_R007-0") ) + intersect_summary = EclSum( self.createTestPath( "Statoil/ECLIPSE/SummaryRestart/iter-1/NOR-2013A_R007-0"), lazy_load=False ) self.assertIsNotNone(intersect_summary) write_location = os.path.join(os.getcwd(), "CASE") @@ -485,7 +483,7 @@ def test_ix_write(self): ]: with TestAreaContext("my_space" + data_set.split("/")[-1]) as area: - intersect_summary = EclSum(self.createTestPath(data_set)) + intersect_summary = EclSum(self.createTestPath(data_set), lazy_load=False) self.assertIsNotNone(intersect_summary) write_location = os.path.join(os.getcwd(), "CASE") @@ -530,3 +528,10 @@ def test_resample(self): def test_summary_units(self): self.assertEqual(self.ecl_sum.unit_system, EclUnitTypeEnum.ECL_METRIC_UNITS) + + + # The case loaded in this test originates in a simulation + # which was shut down brutally. This test verifies that we + # can create a valid ecl_sum instance from what we find. + def test_broken_case(self): + ecl_sum = EclSum( self.createTestPath("Statoil/ECLIPSE/SummaryFail3/COMBINED-AUTUMN2018_CARBSENS-0")) diff --git a/ThirdParty/Ert/python/tests/legacy_tests/test_util.py b/ThirdParty/Ert/python/tests/legacy_tests/test_util.py index a52dd8f442..90d2d60df7 100644 --- a/ThirdParty/Ert/python/tests/legacy_tests/test_util.py +++ b/ThirdParty/Ert/python/tests/legacy_tests/test_util.py @@ -13,7 +13,6 @@ from ert.util import Hash, StringHash, DoubleHash, IntegerHash from ert.util import ThreadPool from ert.util import installAbortSignals, updateAbortSignals -from ert.util import ArgPack from tests import EclTest diff --git a/ThirdParty/Ert/python/tests/test_install.in b/ThirdParty/Ert/python/tests/test_install.in index e7e154739a..acc2126649 100644 --- a/ThirdParty/Ert/python/tests/test_install.in +++ b/ThirdParty/Ert/python/tests/test_install.in @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash export PYTHONPATH=@CMAKE_INSTALL_PREFIX@/@PYTHON_INSTALL_PREFIX@:@CTEST_PYTHONPATH@:$PYTHONPATH diff --git a/ThirdParty/Ert/python/tests/util_tests/CMakeLists.txt b/ThirdParty/Ert/python/tests/util_tests/CMakeLists.txt index a14e586e39..cd68a8f3be 100644 --- a/ThirdParty/Ert/python/tests/util_tests/CMakeLists.txt +++ b/ThirdParty/Ert/python/tests/util_tests/CMakeLists.txt @@ -11,7 +11,6 @@ set(TEST_SOURCES test_version.py test_work_area.py test_path_context.py - test_arg_pack.py test_spawn.py ) @@ -27,6 +26,5 @@ addPythonTest(tests.util_tests.test_work_area.WorkAreaTest) addPythonTest(tests.util_tests.test_version.VersionTest) addPythonTest(tests.util_tests.test_path_context.PathContextTest) addPythonTest(tests.util_tests.test_thread_pool.ThreadPoolTest) -addPythonTest(tests.util_tests.test_arg_pack.ArgPackTest) addPythonTest(tests.util_tests.test_spawn.SpawnTest) #addPythonTest(tests.util.test_substitution_list.SubstitutionListTest) diff --git a/ThirdParty/Ert/python/tests/util_tests/test_arg_pack.py b/ThirdParty/Ert/python/tests/util_tests/test_arg_pack.py deleted file mode 100644 index 69f77c68b5..0000000000 --- a/ThirdParty/Ert/python/tests/util_tests/test_arg_pack.py +++ /dev/null @@ -1,36 +0,0 @@ -import ecl -from ecl import EclPrototype -from tests import EclTest -from ecl.util.util import ArgPack, StringList - -TEST_LIB = EclPrototype.lib - - -class ArgPackTest(EclTest): - def test_create(self): - arg = ArgPack() - self.assertEqual(len(arg), 0) - - arg.append(StringList()) - self.assertEqual(len(arg), 1) - - arg.append(3.14) - self.assertEqual(len(arg), 2) - - o = object() - with self.assertRaises(TypeError): - arg.append(o) - - def test_args(self): - arg = ArgPack(1, 2, 3) - self.assertEqual(len(arg), 3) - - def test_append_ptr(self): - arg = ArgPack(StringList()) - self.assertEqual(len(arg), 1) - - func = getattr(TEST_LIB, "test_argpack_is_stringlist") - func.restype = None - func.argtypes = [ArgPack] - - func(arg) diff --git a/ThirdParty/Ert/python/tests/util_tests/test_rng.py b/ThirdParty/Ert/python/tests/util_tests/test_rng.py index aba91bfed4..2a4f786705 100644 --- a/ThirdParty/Ert/python/tests/util_tests/test_rng.py +++ b/ThirdParty/Ert/python/tests/util_tests/test_rng.py @@ -7,18 +7,18 @@ class RngTest(EclTest): def test_enums(self): - self.assertEnumIsFullyDefined(RngAlgTypeEnum, "rng_alg_type", "lib/include/ert/util/rng.h") - self.assertEnumIsFullyDefined(RngInitModeEnum, "rng_init_mode", "lib/include/ert/util/rng.h") + self.assertEnumIsFullyDefined(RngAlgTypeEnum, "rng_alg_type", "lib/include/ert/util/rng.hpp") + self.assertEnumIsFullyDefined(RngInitModeEnum, "rng_init_mode", "lib/include/ert/util/rng.hpp") def test_rng_default(self): rng = RandomNumberGenerator() self.assertIsInstance(rng.getDouble(), float) def test_rng_state(self): - rng = RandomNumberGenerator() + rng = RandomNumberGenerator() with self.assertRaises(ValueError): rng.setState("12") - + rng.setState("0123456789ABCDEF") val1 = rng.getInt() val2 = rng.getInt() @@ -27,7 +27,7 @@ def test_rng_state(self): rng.setState("0123456789ABCDEF") self.assertEqual( rng.getInt() , val1) self.assertEqual( rng.getInt() , val2) - + def test_load_save(self): diff --git a/ThirdParty/Ert/python/tests/well_tests/test_ecl_well.py b/ThirdParty/Ert/python/tests/well_tests/test_ecl_well.py index 1d7d2ee32f..cb3b5c3038 100644 --- a/ThirdParty/Ert/python/tests/well_tests/test_ecl_well.py +++ b/ThirdParty/Ert/python/tests/well_tests/test_ecl_well.py @@ -122,13 +122,13 @@ def checkWellInfo(well_info, well_count, report_step_count): def test_well_type_enum(self): - source_file_path = "lib/include/ert/ecl_well/well_conn.h" + source_file_path = "lib/include/ert/ecl_well/well_conn.hpp" # The header file has duplicated symbols, so the simple test fails. # self.assertEnumIsFullyDefined(WellTypeEnum, "well_type_enum", source_file_path) def test_well_connection_direction_enum(self): - source_file_path = "lib/include/ert/ecl_well/well_conn.h" + source_file_path = "lib/include/ert/ecl_well/well_conn.hpp" self.assertEnumIsFullyDefined(WellConnectionDirectionEnum, "well_conn_dir_enum", source_file_path) diff --git a/ThirdParty/Ert/redhat/ecl.spec b/ThirdParty/Ert/redhat/ecl.spec index 47b7a85513..cca9c92159 100644 --- a/ThirdParty/Ert/redhat/ecl.spec +++ b/ThirdParty/Ert/redhat/ecl.spec @@ -2,10 +2,10 @@ # spec file for package ecl # -%define tag rc1 +%define tag final Name: ecl -Version: 2017.10 +Version: 2018.10 Release: 0 Summary: ECL library License: GPL-3+ @@ -14,7 +14,7 @@ Url: http://ert.nr.no Source0: https://github.com/Statoil/libecl/archive/release/%{version}/%{tag}.tar.gz#/%{name}-%{version}.tar.gz BuildRequires: lapack-devel zlib-devel iputils BuildRequires: devtoolset-6-toolchain -%{?!el6:BuildRequires: python-devel numpy} +%{?!el6:BuildRequires: python-devel numpy python-pandas python-cwrap} %{?el6:BuildRequires: cmake3} %{?!el6:BuildRequires: cmake} BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -31,17 +31,10 @@ Group: System/Libraries %package -n python-ecl Summary: ECL - Python bindings Group: Python/Libraries -Requires: libecl1 +Requires: libecl1 numpy python-six python-pandas python-cwrap %description -n python-ecl libecl is a package for reading and writing the result files from the Eclipse reservoir simulator. This package contains the Python bindings. - -%package -n python-cwrap -Summary: Simplify ctypes based wrapping of C code. -Group: Python/Libraries - -%description -n python-cwrap -Package to simplify ctypes based wrapping of C code. } %description -n libecl1 @@ -62,7 +55,7 @@ This package contains the development and header files for ecl %build scl enable devtoolset-6 bash -DESTDIR=${RPM_BUILD_ROOT} %{?el6:cmake3} %{?!el6:cmake} -DBUILD_SHARED_LIBS=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%{_prefix} -DBUILD_ECL_SUMMARY=1 %{?el6:-DENABLE_PYTHON=0} %{?!el6:-DENABLE_PYTHON=1}-DCMAKE_CXX_COMPILER=/opt/rh/devtoolset-6/root/usr/bin/g++ -DCMAKE_C_COMPILER=/opt/rh/devtoolset-6/root/usr/bin/gcc -DCMAKE_Fortran_COMPILER=/opt/rh/devtoolset-6/root/usr/bin/gfortran +DESTDIR=${RPM_BUILD_ROOT} %{?el6:cmake3} %{?!el6:cmake} -DBUILD_SHARED_LIBS=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%{_prefix} -DBUILD_ECL_SUMMARY=1 %{?el6:-DENABLE_PYTHON=0} %{?!el6:-DENABLE_PYTHON=1} -DCMAKE_CXX_COMPILER=/opt/rh/devtoolset-6/root/usr/bin/g++ -DCMAKE_C_COMPILER=/opt/rh/devtoolset-6/root/usr/bin/gcc -DCMAKE_Fortran_COMPILER=/opt/rh/devtoolset-6/root/usr/bin/gfortran make %install @@ -94,8 +87,4 @@ rm -rf %{buildroot} %files -n python-ecl %defattr(-,root,root,-) /usr/lib/python2.7/site-packages/ecl/* - -%files -n python-cwrap -%defattr(-,root,root,-) -/usr/lib/python2.7/site-packages/cwrap/* } diff --git a/ThirdParty/Ert/script/download-pr b/ThirdParty/Ert/script/download-pr index f3b54c7588..7e6f01ad12 100644 --- a/ThirdParty/Ert/script/download-pr +++ b/ThirdParty/Ert/script/download-pr @@ -13,7 +13,7 @@ def getPRList( api_token, pr1, pr2): sys.stderr.write("Downloading PR: ") while True: url = url_fmt % pr - response = requests.get( url , {"access_token" : api_token}) + response = requests.get( url , params = {"access_token" : api_token}) for i in range(prev_len): sys.stdout.write("\b") @@ -38,11 +38,14 @@ def printPRList( pr_list , fileH): title = pr["title"] body = pr["body"] nr = pr["number"] + url = "https://github.com/Statoil/libecl/pull/{}/".format(nr) try: - fileH.write( "[%d] *%s*\n\n" % (nr , title)) + title = str(title) except UnicodeEncodeError: - fileH.write(" [%d] : UnicodeError") + title = "UnicodeError" + + fileH.write( "[`{nr} <{url}>`] : {title}".format(nr = nr, url=url, title = title)) try: fileH.write( "%s\n\n\n" % body ) @@ -63,7 +66,7 @@ def main(): filename = "/tmp/relnotes-%d-%d" % (pr1 , pr2) printPRList( pr_list , open(filename , "w")) - print "Have created file: %s which can be a starting point for release notes" % filename + print "\nHave created file: %s which can be a starting point for release notes" % filename diff --git a/ThirdParty/Ert/setup.py b/ThirdParty/Ert/setup.py new file mode 100644 index 0000000000..5dacb9973b --- /dev/null +++ b/ThirdParty/Ert/setup.py @@ -0,0 +1,52 @@ +import os +import subprocess + +from setuptools import setup, Extension, find_packages +from setuptools.command.build_ext import build_ext +from distutils.version import LooseVersion + + +class CMakeExtension(Extension): + def __init__(self, name, sourcedir=''): + Extension.__init__(self, name, sources=[]) + self.sourcedir = os.path.abspath(sourcedir) + + +class CMakeBuild(build_ext): + def run(self): + for ext in self.extensions: + self.build_extension(ext) + + def build_extension(self, ext): + cmake_args = [] # Fill in extra stuff we may need + extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))) + cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir] + cfg = 'Debug' if self.debug else 'Release' + cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg] + build_args = ['--config', cfg, '--', '-j2'] + if not os.path.exists(self.build_temp): + os.makedirs(self.build_temp) + env = os.environ.copy() + subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, cwd=self.build_temp, env=env) + subprocess.check_call(['cmake', '--build', '.'] + build_args, cwd=self.build_temp) + +setup( + name='statoil_libecl', + version='0.1.1', + author_email='chandan.nath@gmail.com', + description='libecl', + long_description=open("README.md", "r").read(), + long_description_content_type="text/markdown", + url="https://github.com/statoil/libecl", + license="GNU General Public License, Version 3, 29 June 2007", + packages=find_packages(where='python', exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), + package_dir={'': 'python'}, + ext_package='ecl', + ext_modules=[CMakeExtension('libecl')], + cmdclass=dict(build_ext=CMakeBuild), + install_requires=[ + 'cwrap', + 'numpy', + 'pandas', + ], +) diff --git a/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.DATA b/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.DATA new file mode 100644 index 0000000000..ccfa835647 --- /dev/null +++ b/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.DATA @@ -0,0 +1,898 @@ +-- This reservoir simulation deck is made available under the Open Database +-- License: http://opendatacommons.org/licenses/odbl/1.0/. Any rights in +-- individual contents of the database are licensed under the Database Contents +-- License: http://opendatacommons.org/licenses/dbcl/1.0/ + +-- Copyright (C) 2016 Statoil + +-- NOTE: This deck is currently not supported by the OPM +-- simulator flow due to lack of support for LGR. + +-- This case is created for testing flow diagnostic implementations +-- in ResInsight. It is a simple shoe-box grid with an added fault +-- giving non-neighboring connections and two added local grid refinements. + + +RUNSPEC =============================================================== + +TITLE + SIMPLE 2PH MODEL WITH SINGLE FAULT, LGR, AQUIFER (CT & Num) and GRUPNET + +DIMENS + 20 20 10 / + +METRIC + +OIL + +WATER + +GAS + +TABDIMS + 2* 24 2* 20 20 1* 1 7* / +EQLDIMS + 2* 100 2* / +REGDIMS + 2 5* / +WELLDIMS + 12 100 4 12 0 0 0 0 0 0 0 0 / + +AQUDIMS + 5 5 1* 1* 1 50 1* 1* / + +WSEGDIMS + 4 30 4 / + +FAULTDIM + 10 / + + +TRACERS +-- NOTRAC NWTRAC NGTRAC NETRAC Diff/NODiff + 0 2 0 0 'DIFF' / + + +NSTACK + 25 / +START +1 JAN 2017 / + +LGR + 2 10000 / + + +UNIFOUT + +GRID =============================================================== + +INCLUDE + 'include/SHIFTTOP.GRDECL' / + +FAULTS +--name I1 I2 J1 J2 K1 K2 Dir + FLT1 10 10 1 10 1 5 X / + FLT2 10 10 1 10 6 10 X / + FLT3 10 10 11 20 1 5 X / + FLT4 10 10 11 20 6 10 X / + FLT5 4 8 15 15 1 10 Y / +/ + +MULTFLT + 'FLT1' 0.1 / + 'FLT2' 0.2 / + 'FLT3' 0.3 / + 'FLT4' 0.4 / + 'FLT5' 0.5 / +/ + + +PORO +4000*0.3 +/ + +PERMX +2000*80.0 +800*150.0 +1200*50.0 +/ + +PERMY +2000*80.0 +800*150.0 +1200*50.0 +/ + +PERMZ +2000*15.0 +800*25.0 +1200*15.0 +/ + +NOECHO + +CARFIN +---- Name I1 I2 J1 J2 K1 K2 NX NY NZ + 'CENTER' 8 12 8 12 4 6 20 20 9 / +ENDFIN +CARFIN + 'WELLI1' 1 3 1 3 1 10 9 9 20 2 / +ENDFIN + +INIT +/ + +AQUNUM +--# I J K A L Poro Perm Depth Pres PVT SAT + 1 20 11 5 1.0E+6 10000 1* 2000 1* 500 1* 1* / + 1 20 11 6 1.0E+6 10000 1* 2000 1* 500 1* 1* / + 1 20 11 7 1.0E+6 10000 1* 2000 1* 500 1* 1* / + 2 20 11 9 1.0E+6 10000 1* 2000 1* 500 1* 1* / + 2 20 11 10 1.0E+6 10000 1* 2000 1* 500 1* 1* / +/ + +AQUCON + 1 19 19 11 11 5 7 'I+' 1.0 / + 2 19 19 11 11 9 10 'I+' 1.0 / +/ + + +PROPS =============================================================== + +DENSITY + 900 1000 1 / +PVCDO -- pref Bo Co muo vo + 400 1.05 1.0E-05 5 0 + / + +PVTW + 400 1 1.0E-06 1 0 / + +ROCK + 400 0 / + +PVDG +--Press Bg Visc + 50 0.024958 0.01441 +110 0.011072 0.01609 +170 0.007156 0.01834 +190 0.006433 0.01923 +250.8 0.005013 0.02234 +301.59 0.004323 0.02542 +360.8 0.003819 0.02974 +374.31 0.003735 0.03087 +387.36 0.003662 0.03202 +399.99 0.003598 0.0332 +412.21 0.003543 0.03442 +424.05 0.003496 0.03566 +543.83 0.003295 0.05582 +594.29 0.003200 0.07567 +/ + + +--Corey parametrization using exponent of 2 +SWOF +-- Sw Krw Krow + 0.1000 0.0000 1.0000 0.0000 + 0.1500 0.0020 0.8789 0.0000 + 0.2000 0.0078 0.7656 0.0000 + 0.2500 0.0176 0.6602 0.0000 + 0.3000 0.0313 0.5625 0.0000 + 0.3500 0.0488 0.4727 0.0000 + 0.4000 0.0703 0.3906 0.0000 + 0.4500 0.0957 0.3164 0.0000 + 0.5000 0.1250 0.2500 0.0000 + 0.5500 0.1582 0.1914 0.0000 + 0.6000 0.1953 0.1406 0.0000 + 0.6500 0.2363 0.0977 0.0000 + 0.7000 0.2813 0.0625 0.0000 + 0.7500 0.3301 0.0352 0.0000 + 0.8000 0.3828 0.0156 0.0000 + 0.8500 0.4395 0.0039 0.0000 + 0.9000 0.5000 0.0000 0.0000 +/ + +SGOF +-- Sg Krg Krog Pcog + .0000 .0000 1.00 .00 + .0500 .0000 0.80 .00 + .1000 .0300 0.40 .00 + .2000 .1000 0.10 .00 + .3000 .2400 0.05 .00 + .4000 .33 0.00 .00 + .5000 .4200 0.00 .00 + .9000 1.000 0.00 .00 / table 1 + + +TRACER + 'TR1' WAT / + 'TR2' WAT / +/ + +TRACITVD + / + + + +REGIONS =============================================================== + +-- ARRAY VALUE ------- BOX ------ +-- I1 I2 J1 J2 K1 K2 +EQUALS + FIPNUM 1 1 10 1 20 1 10 / + FIPNUM 2 11 20 1 20 1 10 / +/ + +SOLUTION =============================================================== +EQUIL + 0 400 500 0 / + +RPTSOL + RESTART=2 / + +RPTRST + FLORES / + +TBLKFTR1 + 4000*0 / + +TBLKFTR2 + 4000*0 / + +AQUCT +--# Depth Pres Perm Por Compr Radius H Angle PVTW Table Csalt Taq +1 3 500 2000 0.2 1E-5 10000 20 90 1* / + +AQUANCON +1 20 20 11 11 1 3 'I+' / +/ + +SUMMARY =============================================================== +ALL +FNQT + +BPR + 10 10 5 / +/ + +COFR + 'P1' 18 2 5 / +/ + +LBOSAT +-- LGR Name Local Cell + 'CENTER' 5 5 5 / +/ + +LCWIT +-- LGR Name Well Name Local Cell + 'WELLI1' 'I1' 5 5 5 / +/ + +LWWIR +-- LGR Name Well Name + 'WELLI1' 'I1' / +/ + +RWFT + 1 2 / +/ + +ROIP +/ + +WTPRTR1 +/ + +WTPRTR2 +/ + +WTPTTR1 +/ + +WTPTTR2 +/ + +WTITTR1 +/ + +WTITTR2 +/ + +-- Analytical Aqufier +AAQR + / +AAQT + / +AAQP + / +-- Numerical Aquifer +ANQR + / + +ANQT + / + +ANQP + / +-- ----------------- + +-- Multi-Segment Wells +SOFR + 'P2' 1 / + 'P2' 2 / + 'P2' 3 / + 'P2' 10 / + 'P2' 13 / + 'P2' 18 / + 'P2' 20 / + 'P2' 22 / + 'P2' 23 / + / + +SOFRF + 'P2' 1 / + 'P2' 2 / + 'P2' 3 / + 'P2' 10 / + 'P2' 13 / + 'P2' 18 / + 'P2' 20 / + 'P2' 22 / + 'P2' 23 / + / + +SOFRS + 'P2' 1 / + 'P2' 2 / + 'P2' 3 / + 'P2' 10 / + 'P2' 13 / + 'P2' 18 / + 'P2' 20 / + 'P2' 22 / + 'P2' 23 / + / + +SWFR + 'P2' 1 / + / + +SGFR + 'P2' 1 / + 'P2' 2 / + 'P2' 3 / + 'P2' 10 / + 'P2' 13 / + 'P2' 18 / + 'P2' 20 / + 'P2' 22 / + 'P2' 23 / + / + +SGFRF + 'P2' 1 / + 'P2' 2 / + 'P2' 3 / + 'P2' 10 / + 'P2' 13 / + 'P2' 18 / + 'P2' 20 / + 'P2' 22 / + 'P2' 23 / + / + +SGFR + 'P2' 1 / + 'P2' 2 / + 'P2' 3 / + 'P2' 10 / + 'P2' 13 / + 'P2' 18 / + 'P2' 20 / + 'P2' 22 / + 'P2' 23 / + / + +SWCT + 'P2' 1 / + 'P2' 3 / + 'P2' 13 / + 'P2' 14 / + 'P2' 15 / + 'P2' 16 / + 'P2' 17 / + / + +SGOR + 'P2' 1 / + 'P2' 23 / + 'P2' 25 / + 'P2' 27 / + / + +SPR + 'P2' / + / + +SPRDH + 'P2' 2 / + 'P2' 3 / + / + +SPRDF + 'P2' / +/ + +SWFR + 'I2' 1 / + 'I2' 4 / + 'I2' 5 / + / + +SWCT + 'I2' 4 / + / + +SGOR + 'I2' 4 / + / + +SPR + 'I2' / + / + +SPRDH + 'I2' 2 / + 'I2' 3 / + / + +SPRDF + 'I2' / + / + + -- Network +GPR +/ + +GPRB +/ + +SCHEDULE =============================================================== + + +RPTSCHED + FIP WELSPECS WELLS / + +RPTRST + BASIC=2 FLORES / + +GRUPTREE + PRODA FIELD / + WIA FIELD / +/ + +GRUPNET + FIELD 1* / + PRODA 25 9999 / + WIA 400 9999 / +/ + + + +WELSPECS +-- 'I1' '1' 2 2 1* 'WATER' / + I2_GI WIA 2 18 0 GAS / + I2 WIA 2 18 0 WATER / + P1 PRODA 18 2 0 OIL / + P2 PRODA 18 18 0 OIL / + P1_RFT PRODA 18 2 0 OIL / + P2_RFT PRODA 18 18 0 OIL / +/ + +COMPDAT + 'P1' 2* 2 2 'SHUT' 2* 0.2 1* 0 / + 'P1' 2* 3 10 'OPEN' 2* 0.2 1* 0 / + 'P1_RFT' 2* 6 10 'OPEN' 2* 0.2 1* 0 / +/ + +COMPDAT + 'I2_GI' 2 18 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'I2_GI' 2 17 2 2 'SHUT' 2* 0.2 3* 'Y' / + 'I2_GI' 2 16 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'I2_GI' 2 15 2 2 'SHUT' 2* 0.2 3* 'Y' / + 'I2_GI' 2 14 2 2 'OPEN' 2* 0.2 3* 'Y' / + + 'I2_GI' 2 18 7 7 'SHUT' 2* 0.2 3* 'Y' / + 'I2_GI' 2 17 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'I2_GI' 2 16 7 7 'SHUT' 2* 0.2 3* 'Y' / + 'I2_GI' 2 15 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'I2_GI' 2 14 7 7 'SHUT' 2* 0.2 3* 'Y' / + + + 'I2' 2 18 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'I2' 2 17 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'I2' 2 16 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'I2' 2 15 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'I2' 2 14 2 2 'OPEN' 2* 0.2 3* 'Y' / + + 'I2' 2 18 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'I2' 2 17 7 7 'SHUT' 2* 0.2 3* 'Y' / + 'I2' 2 16 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'I2' 2 15 7 7 'SHUT' 2* 0.2 3* 'Y' / + 'I2' 2 14 7 7 'OPEN' 2* 0.2 3* 'Y' / + + 'P2' 18 18 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 17 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 16 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 15 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 14 2 2 'OPEN' 2* 0.2 3* 'Y' / + + 'P2' 18 18 5 5 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 17 5 5 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 16 5 5 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 15 5 5 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 14 5 5 'OPEN' 2* 0.2 3* 'Y' / + + 'P2' 18 18 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 17 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 16 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 15 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'P2' 18 14 7 7 'OPEN' 2* 0.2 3* 'Y' / + + 'P2_RFT' 18 18 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 17 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 16 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 15 2 2 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 14 2 2 'OPEN' 2* 0.2 3* 'Y' / + + 'P2_RFT' 18 18 5 5 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 17 5 5 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 16 5 5 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 15 5 5 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 14 5 5 'OPEN' 2* 0.2 3* 'Y' / + + 'P2_RFT' 18 18 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 17 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 16 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 15 7 7 'OPEN' 2* 0.2 3* 'Y' / + 'P2_RFT' 18 14 7 7 'OPEN' 2* 0.2 3* 'Y' / +/ + +WELSEGS +-- Name Dep 1 Tlen 1 Vol 1 + 'I2_GI' 0 1 1* 'INC' / + +-- First Last Branch Outlet Length Depth Diam Ruff Area Vol +-- Seg Seg Num Seg Chang +-- Main Stem + 2 14 1 1 1 1 0.2 1.E-3 1* 1* / + -- Top Branch + 15 15 2 2 2 0 0.2 1.E-3 1* 1* / + 16 19 2 15 10 0 0.2 1.E-3 1* 1* / +-- Bottom Branch + 20 20 3 7 2 0 0.2 1.E-3 1* 1* / + 21 24 3 20 10 0 0.2 1.E-3 1* 1* / +/ + +COMPSEGS +-- Name + 'I2_GI' / + +-- I J K Brn Start End Dirn End +-- No Length Length Penet Range +-- Top Branch + 2 18 2 2 2 1* 'Y' 14 / +-- Bottom Branch + 2 18 7 3 7 1* 'Y' 14 / + / + +WELSEGS +-- Name Dep 1 Tlen 1 Vol 1 + 'I2' 0 1 1* 'INC' / + +-- First Last Branch Outlet Length Depth Diam Ruff Area Vol +-- Seg Seg Num Seg Chang +-- Main Stem + 2 14 1 1 1 1 0.2 1.E-3 1* 1* / + -- Top Branch + 15 15 2 2 2 0 0.2 1.E-3 1* 1* / + 16 19 2 15 10 0 0.2 1.E-3 1* 1* / +-- Bottom Branch + 20 20 3 7 2 0 0.2 1.E-3 1* 1* / + 21 24 3 20 10 0 0.2 1.E-3 1* 1* / +/ + +COMPSEGS +-- Name + 'I2' / + +-- I J K Brn Start End Dirn End +-- No Length Length Penet Range +-- Top Branch + 2 18 2 2 2 1* 'Y' 14 / +-- Bottom Branch + 2 18 7 3 7 1* 'Y' 14 / + / + +WELSEGS +-- Name Dep 1 Tlen 1 Vol 1 + 'P2' 0 1 1* 'INC' / + +-- First Last Branch Outlet Length Depth Diam Ruff Area Vol +-- Seg Seg Num Seg Chang +-- Main Stem + 2 12 1 1 1 1 0.2 1.E-3 1* 1* / +-- Top Branch + 13 13 2 2 2 0 0.2 1.E-3 1* 1* / + 14 17 2 13 10 0 0.2 1.E-3 1* 1* / +-- Middle Branch + 18 18 3 5 2 0 0.2 1.E-3 1* 1* / + 19 22 3 18 10 0 0.2 1.E-3 1* 1* / +-- Bottom Branch + 23 23 4 7 2 0 0.2 1.E-3 1* 1* / + 24 27 4 23 10 0 0.2 1.E-3 1* 1* / + / + + +COMPSEGS +-- Name + 'P2' / + +-- I J K Brn Start End Dirn End +-- No Length Length Penet Range +-- Top Branch + 18 18 2 2 2 1* 'Y' 14 / +-- Middle Branch + 18 18 5 3 5 1* 'Y' 14 / +-- Bottom Branch + 18 18 7 4 7 1* 'Y' 14 / +/ + + +WELSPECL + 'I1' 'WIA' 'WELLI1' 5 5 1* 'WATER' / Injector + 'I1_GI' 'WIA' 'WELLI1' 5 5 1* 'GAS' / Injector +/ +COMPDATL + 'I1' 'WELLI1' 1* 1* 1 12 'OPEN' 2* 0.2 1* 0 / + 'I1' 'WELLI1' 1* 1* 13 20 'SHUT' 2* 0.2 1* 0 / + 'I1_GI' 'WELLI1' 1* 1* 1 6 'SHUT' 2* 0.2 1* 0 / + 'I1_GI' 'WELLI1' 1* 1* 7 14 'OPEN' 2* 0.2 1* 0 / + 'I1_GI' 'WELLI1' 1* 1* 15 16 'SHUT' 2* 0.2 1* 0 / + 'I1_GI' 'WELLI1' 1* 1* 17 20 'OPEN' 2* 0.2 1* 0 / + +/ + + +WCONPROD + 'P1' 'OPEN' 'BHP' 5* 350/ + 'P2' 'OPEN' 'BHP' 5* 345/ +'P1_RFT' 'STOP' 'BHP' 5* 345/ +'P2_RFT' 'STOP' 'BHP' 5* 345/ + +/ + +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 40 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 10 1* 550/ + 'I1_GI' 'GAS' 'STOP' 'RATE' 0 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 0 1* 550/ +/ + +WTRACER + 'I1' 'TR1' 1.0 / + 'I2' 'TR2' 1.0 / +/ + + +TUNING +0.1 30 / +/ +12 1 250 1* 25 / + +DATES + 1 FEB 2017 / + / + +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 0 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 0 1* 550/ + 'I1_GI' 'GAS' 'OPEN' 'RATE' 40000 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 10000 1* 550/ +/ + +DATES + 1 MAR 2017 / + / + + +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 40 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 10 1* 550/ + 'I1_GI' 'GAS' 'OPEN' 'RATE' 0 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 0 1* 550/ +/ + + +WRFTPLT +--Well RFT PLT Segment + P1_RFT YES REPT / + P2_RFT NO YES YES / + / + +DATES + 1 APR 2017 / + / + + +WCONINJE + 'I1' 'WATER' 'STOP' 'RATE' 0 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 0 1* 550/ + 'I1_GI' 'GAS' 'OPEN' 'RATE' 40000 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 10000 1* 550/ +/ + +DATES + 1 MAY 2017 / + / + + +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 40 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 10 1* 550/ + 'I1_GI' 'GAS' 'STOP' 'RATE' 0 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 0 1* 550/ +/ +DATES + 1 JUN 2017 / + / + + +WCONINJE + 'I1' 'WATER' 'STOP' 'RATE' 0 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 0 1* 550/ + 'I1_GI' 'GAS' 'OPEN' 'RATE' 40000 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 10000 1* 550/ +/ + +DATES + 1 JUL 2017 / + / + +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 40 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 10 1* 550/ + 'I1_GI' 'GAS' 'STOP' 'RATE' 0 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 0 1* 550/ +/ +DATES + 1 AUG 2017 / + / + + WCONINJE + 'I1' 'WATER' 'STOP' 'RATE' 0 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 0 1* 550/ + 'I1_GI' 'GAS' 'OPEN' 'RATE' 40000 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 10000 1* 550/ +/ + +DATES + 1 SEP 2017 / + / + + +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 40 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 10 1* 550/ + 'I1_GI' 'GAS' 'STOP' 'RATE' 0 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 0 1* 550/ +/ +DATES + 1 OCT 2017 / + / + + + WCONINJE + 'I1' 'WATER' 'SHUT' 'RATE' 0 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 0 1* 550/ + 'I1_GI' 'GAS' 'OPEN' 'RATE' 40000 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 10000 1* 550/ +/ + +DATES + 1 NOV 2017 / + / + + +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 40 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 10 1* 550/ + 'I1_GI' 'GAS' 'SHUT' 'RATE' 0 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 0 1* 550/ +/ + +DATES + 1 DEC 2017 / + / + + + WCONINJE + 'I1' 'WATER' 'SHUT' 'RATE' 0 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 0 1* 550/ + 'I1_GI' 'GAS' 'OPEN' 'RATE' 40000 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 10000 1* 550/ +/ + +DATES + 1 JAN 2018 / + / + + +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 40 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 10 1* 550/ + 'I1_GI' 'GAS' 'SHUT' 'RATE' 0 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 0 1* 550/ +/ + +DATES + 1 FEB 2018 / + / + + + WCONINJE + 'I1' 'WATER' 'SHUT' 'RATE' 0 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 0 1* 550/ + 'I1_GI' 'GAS' 'OPEN' 'RATE' 40000 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 10000 1* 550/ +/ + +DATES + 1 MAR 2018 / + / + + +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 40 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 10 1* 550/ + 'I1_GI' 'GAS' 'SHUT' 'RATE' 0 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 0 1* 550/ +/ + +DATES + 1 APR 2018 / + / + + + WCONINJE + 'I1' 'WATER' 'SHUT' 'RATE' 0 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 0 1* 550/ + 'I1_GI' 'GAS' 'OPEN' 'RATE' 40000 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 10000 1* 550/ +/ + +DATES + 1 MAY 2018 / + / + + +WCONINJE + 'I1' 'WATER' 'OPEN' 'RATE' 40 1* 550/ + 'I2' 'WATER' 'OPEN' 'RATE' 10 1* 550/ + 'I1_GI' 'GAS' 'SHUT' 'RATE' 0 1* 550/ + 'I2_GI' 'GAS' 'OPEN' 'RATE' 0 1* 550/ +/ + + + + + +TSTEP + 4*15 / + + +END + + + diff --git a/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.SMSPEC b/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.SMSPEC new file mode 100644 index 0000000000..68c81eef2a Binary files /dev/null and b/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.SMSPEC differ diff --git a/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.UNSMRY b/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.UNSMRY new file mode 100644 index 0000000000..38dd0b61fa Binary files /dev/null and b/ThirdParty/Ert/test-data/local/ECLIPSE/cp_simple3/SIMPLE_SUMMARY3.UNSMRY differ diff --git a/ThirdParty/NRLib/CMakeLists.txt b/ThirdParty/NRLib/CMakeLists.txt index 0b865c0cf2..6b0f1a261e 100644 --- a/ThirdParty/NRLib/CMakeLists.txt +++ b/ThirdParty/NRLib/CMakeLists.txt @@ -28,7 +28,7 @@ if (MSVC) set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/wd4996") endif() -add_subdirectory(well_UnitTests) +#add_subdirectory(well_UnitTests) target_include_directories(${PROJECT_NAME} PUBLIC diff --git a/ThirdParty/NRLib/well_UnitTests/CMakeLists.txt b/ThirdParty/NRLib/well_UnitTests/CMakeLists.txt index 7938ccdb9a..219a979dd6 100644 --- a/ThirdParty/NRLib/well_UnitTests/CMakeLists.txt +++ b/ThirdParty/NRLib/well_UnitTests/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required (VERSION 2.8) project ( well_UnitTests ) +if (MSVC AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 19.11)) + # VS 2017 : Disable warnings from from gtest code, using deprecated code related to TR1 + add_definitions(-D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING) + message("Add flag to disable warings from gtest - _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") +endif() include_directories ( ${CMAKE_CURRENT_SOURCE_DIR}/../.. diff --git a/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp b/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp index 200ea39b51..d61b7978ee 100644 --- a/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp +++ b/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp @@ -298,7 +298,7 @@ const QBrush& QwtPlotIntervalCurve::brush() const QRectF QwtPlotIntervalCurve::boundingRect() const { QRectF rect = QwtPlotSeriesItem::boundingRect(); - if ( rect.isValid() && orientation() == Qt::Vertical ) + if ( rect.width() >= 0.0 && rect.height() >= 0.0 && orientation() == Qt::Vertical ) rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() ); return rect; diff --git a/ThirdParty/boost-Subset/boost/config/compiler/visualc.hpp b/ThirdParty/boost-Subset/boost/config/compiler/visualc.hpp index 93908cea50..2b260c6a3c 100644 --- a/ThirdParty/boost-Subset/boost/config/compiler/visualc.hpp +++ b/ThirdParty/boost-Subset/boost/config/compiler/visualc.hpp @@ -286,12 +286,3 @@ # define BOOST_COMPILER "Microsoft Visual C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) #endif -// -// last known and checked version is 19.00.23026 (VC++ 2015 RTM): -#if (_MSC_VER > 1900) -# if defined(BOOST_ASSERT_CONFIG) -# error "Unknown compiler version - please run the configure tests and report the results" -# else -# pragma message("Unknown compiler version - please run the configure tests and report the results") -# endif -#endif diff --git a/ThirdParty/custom-opm-flowdiag-app/CMakeLists.txt b/ThirdParty/custom-opm-flowdiag-app/CMakeLists.txt index c37bd33e02..d54ae136a9 100644 --- a/ThirdParty/custom-opm-flowdiag-app/CMakeLists.txt +++ b/ThirdParty/custom-opm-flowdiag-app/CMakeLists.txt @@ -5,7 +5,6 @@ project (custom-opm-flowdiag-app) include_directories( ../custom-opm-flowdiagnostics/opm-flowdiagnostics opm-flowdiagnostics-applications - opmCore ) include (opm-flowdiagnostics-applications/CMakeLists_files.cmake) diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/examples/extractPropCurves.cpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/examples/extractPropCurves.cpp index cbfbfed881..acf60e4dd4 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/examples/extractPropCurves.cpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/examples/extractPropCurves.cpp @@ -54,13 +54,13 @@ namespace { const auto& x = graph.first; const auto& y = graph.second; - os << name << '{' << k << "} = [\n"; + os << name << '{' << k << "} = extendTab([\n"; for (auto n = x.size(), i = 0*n; i < n; ++i) { os << x[i] << ' ' << y[i] << '\n'; } - os << "];\n\n"; + os << "]);\n\n"; k += 1; } @@ -118,7 +118,7 @@ namespace { const auto graph = sfunc.getSatFuncCurve(func, activeCell, scaling); - printGraph(std::cout, "krg", graph); + printGraph(std::cout, "crv.krg", graph); } void krog(const Opm::ECLSaturationFunc& sfunc, @@ -140,7 +140,7 @@ namespace { const auto graph = sfunc.getSatFuncCurve(func, activeCell, scaling); - printGraph(std::cout, "krog", graph); + printGraph(std::cout, "crv.krog", graph); } void krow(const Opm::ECLSaturationFunc& sfunc, @@ -162,7 +162,7 @@ namespace { const auto graph = sfunc.getSatFuncCurve(func, activeCell, scaling); - printGraph(std::cout, "krow", graph); + printGraph(std::cout, "crv.krow", graph); } void krw(const Opm::ECLSaturationFunc& sfunc, @@ -184,7 +184,7 @@ namespace { const auto graph = sfunc.getSatFuncCurve(func, activeCell, scaling); - printGraph(std::cout, "krw", graph); + printGraph(std::cout, "crv.krw", graph); } // ----------------------------------------------------------------- @@ -209,7 +209,7 @@ namespace { const auto graph = sfunc.getSatFuncCurve(func, activeCell, scaling); - printGraph(std::cout, "pcgo", graph); + printGraph(std::cout, "crv.pcgo", graph); } void pcow(const Opm::ECLSaturationFunc& sfunc, @@ -231,7 +231,7 @@ namespace { const auto graph = sfunc.getSatFuncCurve(func, activeCell, scaling); - printGraph(std::cout, "pcow", graph); + printGraph(std::cout, "crv.pcow", graph); } // ----------------------------------------------------------------- @@ -245,7 +245,7 @@ namespace { const auto graph = pvtCurves .getPvtCurve(RC::FVF, Opm::ECLPhaseIndex::Vapour, activeCell); - printGraph(std::cout, "Bg", graph); + printGraph(std::cout, "crv.Bg", graph); } void mu_g(const Opm::ECLPVT::ECLPvtCurveCollection& pvtCurves, @@ -256,7 +256,7 @@ namespace { const auto graph = pvtCurves .getPvtCurve(RC::Viscosity, Opm::ECLPhaseIndex::Vapour, activeCell); - printGraph(std::cout, "mu_g", graph); + printGraph(std::cout, "crv.mu_g", graph); } void Bo(const Opm::ECLPVT::ECLPvtCurveCollection& pvtCurves, @@ -267,7 +267,7 @@ namespace { const auto graph = pvtCurves .getPvtCurve(RC::FVF, Opm::ECLPhaseIndex::Liquid, activeCell); - printGraph(std::cout, "Bo", graph); + printGraph(std::cout, "crv.Bo", graph); } void mu_o(const Opm::ECLPVT::ECLPvtCurveCollection& pvtCurves, @@ -278,7 +278,7 @@ namespace { const auto graph = pvtCurves .getPvtCurve(RC::Viscosity, Opm::ECLPhaseIndex::Liquid, activeCell); - printGraph(std::cout, "mu_o", graph); + printGraph(std::cout, "crv.mu_o", graph); } // ----------------------------------------------------------------- @@ -293,7 +293,7 @@ namespace { const auto graph = pvtCurves .getPvtCurve(RC::SaturatedState, PI::Vapour, activeCell); - printGraph(std::cout, "rvSat", graph); + printGraph(std::cout, "crv.rvSat", graph); } void rsSat(const Opm::ECLPVT::ECLPvtCurveCollection& pvtCurves, @@ -305,7 +305,7 @@ namespace { const auto graph = pvtCurves .getPvtCurve(RC::SaturatedState, PI::Liquid, activeCell); - printGraph(std::cout, "rsSat", graph); + printGraph(std::cout, "crv.rsSat", graph); } // ----------------------------------------------------------------- @@ -340,37 +340,6 @@ namespace { return Opm::ECLUnits::serialisedUnitConventions(init); } - Opm::SatFunc::EPSEvalInterface::InvalidEndpointBehaviour - handleInvalid(const std::string& behaviour) - { - using IEB = Opm::SatFunc:: - EPSEvalInterface::InvalidEndpointBehaviour; - - if ((behaviour == "ignore") || - (behaviour == "ignore-point") || - (behaviour == "ignore_point") || - (behaviour == "ignorepoint")) - { - return IEB::IgnorePoint; - } - - return IEB::UseUnscaled; - } - - auto handleInvalid(const Opm::ParameterGroup& prm) - -> decltype(handleInvalid("ignore")) - { - for (const auto* param : { "handle_invalid" , - "hInv", "handleInv" }) - { - if (prm.has(param)) { - return handleInvalid(prm.get(param)); - } - } - - return handleInvalid("ignore"); - } - int getActiveCell(const Opm::ECLGraph& G, const Opm::ParameterGroup& prm) { @@ -424,8 +393,7 @@ namespace { prm.getDefault("useEPS", std::string{"off"}); auto scaling = Opm::ECLSaturationFunc::SatFuncScaling{}; - scaling.enable = static_cast(0); - scaling.invalid = handleInvalid(prm); + scaling.enable = static_cast(0); if (std::regex_search(useEPS, horiz)) { scaling.enable |= T::Horizontal; @@ -460,6 +428,8 @@ try { pvtCC.setOutputUnits(std::move(units)); } + std::cout << "function crv = pcurves()\n"; + // ----------------------------------------------------------------- // Relative permeability @@ -470,7 +440,8 @@ try { // ----------------------------------------------------------------- // Capillary pressure - if (prm.getDefault("pcgo", false)) { pcgo(sfunc, cellID, scaling); } + if (prm.getDefault("pcog", false) || // Alias pcog -> pcgo + prm.getDefault("pcgo", false)) { pcgo(sfunc, cellID, scaling); } if (prm.getDefault("pcow", false)) { pcow(sfunc, cellID, scaling); } // ----------------------------------------------------------------- diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLEndPointScaling.cpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLEndPointScaling.cpp index 5bd31f9949..8e48f978f2 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLEndPointScaling.cpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLEndPointScaling.cpp @@ -1,4 +1,5 @@ /* + Copyright 2018 Equinor ASA. Copyright 2017 Statoil ASA. This file is part of the Open Porous Media Project (OPM). @@ -34,8 +35,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -87,16 +88,33 @@ namespace { return tep; } + bool haveKeywordData(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const std::string& vector) + { + const auto& grids = G.activeGrids(); + + return std::any_of(std::begin(grids), std::end(grids), + [&init, &vector](const std::string& gridID) + { + return init.haveKeywordData(vector, gridID); + }); + } + template std::vector gridDefaultedVector(const ::Opm::ECLGraph& G, const ::Opm::ECLInitFileData& init, const std::string& vector, const std::vector& dflt, - CvrtVal&& cvrt) + CvrtVal&& cvrt, + const std::vector& fallback + = std::vector{}) { auto ret = std::vector(G.numCells()); + const auto sentinel = 1.0e20; + assert (! dflt.empty() && "Internal Error"); auto cellID = std::vector::size_type{0}; @@ -112,14 +130,100 @@ namespace { : std::vector(nc, -1.0e21); for (auto c = 0*nc; c < nc; ++c, ++cellID) { - ret[cellID] = (std::abs(val[c]) < 1.0e20) - ? cvrt(val[c]) : dflt[snum[c] - 1]; + const auto fb = fallback.empty() + ? -sentinel : fallback[c]; + + auto& r = ret[cellID]; + + if (std::abs(val[c]) < sentinel) { + r = cvrt(val[c]); + } + else if (std::abs(fb) < sentinel) { + r = cvrt(fb); + } + else { + r = dflt[snum[c] - 1]; + } } } return ret; } + std::vector + sgCrit(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const ::Opm::SatFunc::CreateEPS::RawTableEndPoints& tep) + { + return gridDefaultedVector(G, init, "SGCR", tep.crit.gas, + [](const double s) { return s; }); + } + + std::vector + sogCrit(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const ::Opm::SatFunc::CreateEPS::RawTableEndPoints& tep) + { + return gridDefaultedVector(G, init, "SOGCR", tep.crit.oil_in_gas, + [](const double s) { return s; }); + } + + std::vector + sowCrit(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const ::Opm::SatFunc::CreateEPS::RawTableEndPoints& tep) + { + return gridDefaultedVector(G, init, "SOWCR", tep.crit.oil_in_water, + [](const double s) { return s; }); + } + + std::vector + swCrit(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const ::Opm::SatFunc::CreateEPS::RawTableEndPoints& tep) + { + return gridDefaultedVector(G, init, "SWCR", tep.crit.water, + [](const double s) { return s; }); + } + + std::vector + sgMax(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const ::Opm::SatFunc::CreateEPS::RawTableEndPoints& tep) + { + return gridDefaultedVector(G, init, "SGU", tep.smax.gas, + [](const double s) { return s; }); + } + + std::vector + soMax(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const ::Opm::SatFunc::CreateEPS::RawTableEndPoints& tep) + { + auto smax = std::vector(G.numCells()); + + const auto sgl = ::Opm::SatFunc::scaledConnateGas (G, init, tep); + const auto swl = ::Opm::SatFunc::scaledConnateWater(G, init, tep); + + std::transform(std::begin(sgl), std::end(sgl), std::begin(swl), + std::begin(smax), + [](const double sg, const double sw) -> double + { + return 1.0 - (sg + sw); + }); + + return smax; + } + + std::vector + swMax(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const ::Opm::SatFunc::CreateEPS::RawTableEndPoints& tep) + { + return gridDefaultedVector(G, init, "SWU", tep.smax.water, + [](const double s) { return s; }); + } + double defaultedScaledSaturation(const double s, const double dflt) { // Use input scaled saturation ('s') if not defaulted (|s| < 1e20), @@ -130,19 +234,25 @@ namespace { return (std::abs(s) < 1.0e+20) ? s : dflt; } - bool validSaturation(const double s) + bool + haveScaledRelPermAtCritSat(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const ::Opm::SatFunc::CreateEPS::EPSOptions& opt) { - return (! (s < 0.0)) && (! (s > 1.0)); - } + switch (opt.thisPh) { + case ::Opm::ECLPhaseIndex::Aqua: + return haveKeywordData(G, init, "KRWR"); - bool validSaturations(std::initializer_list sats) - { - return std::accumulate(std::begin(sats), - std::end (sats), true, - [](const bool result, const double s) -> bool - { - return result && validSaturation(s); - }); + case ::Opm::ECLPhaseIndex::Liquid: + return (opt.subSys == ::Opm::SatFunc::CreateEPS::SubSystem::OilGas) + ? haveKeywordData(G, init, "KRORG") + : haveKeywordData(G, init, "KRORW"); + + case ::Opm::ECLPhaseIndex::Vapour: + return haveKeywordData(G, init, "KRGR"); + } + + return false; } } @@ -155,9 +265,7 @@ class Opm::SatFunc::TwoPointScaling::Impl public: Impl(std::vector smin, std::vector smax) - : smin_ (std::move(smin)) - , smax_ (std::move(smax)) - , handle_invalid_(InvalidEndpointBehaviour::UseUnscaled) + : smin_(std::move(smin)), smax_(std::move(smax)) { if (this->smin_.size() != this->smax_.size()) { throw std::invalid_argument { @@ -179,11 +287,6 @@ class Opm::SatFunc::TwoPointScaling::Impl std::vector smin_; std::vector smax_; - InvalidEndpointBehaviour handle_invalid_; - - void handleInvalidEndpoint(const SaturationAssoc& sp, - std::vector& effsat) const; - double sMin(const std::vector::size_type cell, const TableEndPoints& tep) const { @@ -219,12 +322,6 @@ Impl::eval(const TableEndPoints& tep, const auto sLO = this->sMin(cell, tep); const auto sHI = this->sMax(cell, tep); - if (! validSaturations({ sLO, sHI })) { - this->handleInvalidEndpoint(eval_pt, effsat); - - continue; - } - effsat.push_back(0.0); auto& s_eff = effsat.back(); @@ -264,12 +361,6 @@ Impl::reverse(const TableEndPoints& tep, const auto sLO = this->sMin(cell, tep); const auto sHI = this->sMax(cell, tep); - if (! validSaturations({ sLO, sHI })) { - this->handleInvalidEndpoint(eval_pt, unscaledsat); - - continue; - } - unscaledsat.push_back(0.0); auto& s_unsc = unscaledsat.back(); @@ -296,26 +387,6 @@ Impl::reverse(const TableEndPoints& tep, return unscaledsat; } -void -Opm::SatFunc::TwoPointScaling::Impl:: -handleInvalidEndpoint(const SaturationAssoc& sp, - std::vector& effsat) const -{ - if (this->handle_invalid_ == InvalidEndpointBehaviour::UseUnscaled) { - // User requests that invalid scaling be treated as unscaled - // saturations. Pick that. - effsat.push_back(sp.sat); - return; - } - - if (this->handle_invalid_ == InvalidEndpointBehaviour::IgnorePoint) { - // User requests that invalid scaling be ignored. Signal invalid - // scaled saturation to caller as NaN. - effsat.push_back(std::nan("")); - return; - } -} - // --------------------------------------------------------------------- // Class Opm::SatFunc::PureVerticalScaling::Impl // --------------------------------------------------------------------- @@ -325,6 +396,9 @@ class Opm::SatFunc::PureVerticalScaling::Impl public: explicit Impl(std::vector fmax) : fmax_(std::move(fmax)) + , inf_ (std::numeric_limits::has_infinity + ? std::numeric_limits::infinity() + : std::numeric_limits::max()) {} std::vector @@ -334,6 +408,16 @@ class Opm::SatFunc::PureVerticalScaling::Impl private: std::vector fmax_; + + double inf_; + + std::vector + zeroMaxVal(const SaturationPoints& sp) const; + + std::vector + nonZeroMaxVal(const SaturationPoints& sp, + const double maxVal, + std::vector val) const; }; std::vector @@ -344,10 +428,40 @@ vertScale(const FunctionValues& f, { assert (sp.size() == val.size() && "Internal Error in Vertical Scaling"); - auto ret = std::move(val); - const auto maxVal = f.max.val; + if (! (std::abs(maxVal) > 0.0)) { + return this->zeroMaxVal(sp); + } + + return this->nonZeroMaxVal(sp, maxVal, std::move(val)); +} + +std::vector +Opm::SatFunc::PureVerticalScaling::Impl:: +zeroMaxVal(const SaturationPoints& sp) const +{ + auto ret = std::vector(sp.size(), 0.0); + + for (auto n = sp.size(), i = 0*n; i < n; ++i) { + const auto fmax = this->fmax_[ sp[i].cell ]; + + ret[i] = (std::abs(fmax) > 0.0) + ? (std::signbit(fmax) ? -this->inf_ : this->inf_) + : 0.0; + } + + return ret; +} + +std::vector +Opm::SatFunc::PureVerticalScaling::Impl:: +nonZeroMaxVal(const SaturationPoints& sp, + const double maxVal, + std::vector val) const +{ + auto ret = std::move(val); + for (auto n = sp.size(), i = 0*n; i < n; ++i) { ret[i] *= this->fmax_[ sp[i].cell ] / maxVal; } @@ -364,9 +478,11 @@ class Opm::SatFunc::CritSatVerticalScaling::Impl public: explicit Impl(std::vector sdisp, std::vector fdisp, + std::vector smax, std::vector fmax) : sdisp_(std::move(sdisp)) , fdisp_(std::move(fdisp)) + , smax_ (std::move(smax)) , fmax_ (std::move(fmax)) {} @@ -378,6 +494,7 @@ class Opm::SatFunc::CritSatVerticalScaling::Impl private: std::vector sdisp_; std::vector fdisp_; + std::vector smax_; std::vector fmax_; }; @@ -387,44 +504,52 @@ vertScale(const FunctionValues& f, const SaturationPoints& sp, std::vector val) const { - assert ((sp.size() == val.size()) && "Internal Error in Vertical Scaling"); - assert (! (f.max.val < f.disp.val) && "Internal Error in Table Extraction"); - assert (! (f.max.sat < f.disp.sat) && "Internal Error in Table Extraction"); + assert ((sp.size() == val.size()) && "Internal Error in Vertical Scaling"); auto ret = std::move(val); - const auto fdisp = f.disp.val; const auto sdisp = f.disp.sat; - const auto fmax = f.max .val; const auto smax = f.max .sat; - const auto sepfv = fmax > fdisp; const auto sep_s = sdisp > smax; + const auto fdisp = f.disp.val; + const auto fmax = std::max(f.disp.val, f.max.val); + const auto sepfv = fmax > fdisp; for (auto n = sp.size(), i = 0*n; i < n; ++i) { auto& y = ret[i]; const auto c = sp[i].cell; const auto s = sp[i].sat; - const auto sr = this->sdisp_[c]; + const auto sr = std::min(this->sdisp_[c], this->smax_[c]); const auto fr = this->fdisp_[c]; + const auto sm = this->smax_ [c]; const auto fm = this->fmax_ [c]; - if (! (s > sr)) { - // s <= sr: Pure vertical scaling in left interval. + if (s < sr) { + // s < sr: Pure vertical scaling in left interval. y *= fr / fdisp; } else if (sepfv) { - // Normal case: Kr(Smax) > Kr(Sr) + // s \in [sr, sm), sm > sr; normal case: Kr(Smax) > Kr(Sr). + // + // Linear function between (sr,fr) and (sm,fm) in terms of + // function value 'y'. This usually alters the shape of the + // relative permeability function in this interval (e.g., + // roughly quadratic to linear). const auto t = (y - fdisp) / (fmax - fdisp); y = fr + t*(fm - fr); } - else if (sep_s) { - // Special case: Kr(Smax) == Kr(Sr). Use linear function from - // saturations. - const auto t = (s - sdisp) / (smax - sdisp); + else if (s < sm) { + // s \in [sr, sm), sm > sr; special case: Kr(Smax) == Kr(Sr). + // + // Use linear function between (sr,fr) and (sm,fm) in terms of + // saturation value 's'. This usually alters the shape of the + // relative permeability function in this interval (e.g., + // roughly quadratic to linear). + const auto t = (s - sr) / (sm - sr); y = fr + t*(fm - fr); } else { - // Smax == Sr; Almost arbitrarily pick fmax_[c]. + // sm == sr (pure scaling). Almost arbitrarily pick fmax_[c]. y = fm; } } @@ -442,10 +567,7 @@ class Opm::SatFunc::ThreePointScaling::Impl Impl(std::vector smin , std::vector sdisp, std::vector smax ) - : smin_ (std::move(smin )) - , sdisp_ (std::move(sdisp)) - , smax_ (std::move(smax )) - , handle_invalid_(InvalidEndpointBehaviour::UseUnscaled) + : smin_(std::move(smin)), sdisp_(std::move(sdisp)), smax_(std::move(smax)) { if ((this->sdisp_.size() != this->smin_.size()) || (this->sdisp_.size() != this->smax_.size())) @@ -470,11 +592,6 @@ class Opm::SatFunc::ThreePointScaling::Impl std::vector sdisp_; std::vector smax_; - InvalidEndpointBehaviour handle_invalid_; - - void handleInvalidEndpoint(const SaturationAssoc& sp, - std::vector& effsat) const; - double sMin(const std::vector::size_type cell, const TableEndPoints& tep) const { @@ -518,12 +635,6 @@ Impl::eval(const TableEndPoints& tep, const auto sR = this->sDisp(cell, tep); const auto sHI = this->sMax (cell, tep); - if (! validSaturations({ sLO, sR, sHI })) { - this->handleInvalidEndpoint(eval_pt, effsat); - - continue; - } - effsat.push_back(0.0); auto& s_eff = effsat.back(); @@ -531,22 +642,26 @@ Impl::eval(const TableEndPoints& tep, // s <= sLO s_eff = tep.low; } - else if (! (eval_pt.sat < sHI)) { - // s >= sHI - s_eff = tep.high; - } - else if (eval_pt.sat < sR) { - // s \in (sLO, sR) + else if (eval_pt.sat < std::min(sR, sHI)) { + // s in scaled interval [sLO, sR) + // Map to tabulated saturation in [tep.low, tep.disp) const auto t = (eval_pt.sat - sLO) / (sR - sLO); s_eff = tep.low + t*(tep.disp - tep.low); } - else { - // s \in (sR, sHI) + else if (eval_pt.sat < sHI) { + // s in scaled interval [sR, sHI) + // Map to tabulated saturation in [tep.disp, tep.high) + assert (sHI > sR); + const auto t = (eval_pt.sat - sR) / (sHI - sR); s_eff = tep.disp + t*(tep.high - tep.disp); } + else { + // s >= sHI + s_eff = tep.high; + } } return effsat; @@ -567,12 +682,6 @@ Impl::reverse(const TableEndPoints& tep, const auto sR = this->sDisp(cell, tep); const auto sHI = this->sMax (cell, tep); - if (! validSaturations({ sLO, sR, sHI })) { - this->handleInvalidEndpoint(eval_pt, unscaledsat); - - continue; - } - unscaledsat.push_back(0.0); auto& s_unsc = unscaledsat.back(); @@ -581,99 +690,53 @@ Impl::reverse(const TableEndPoints& tep, // Map to Minimum Input Saturation in cell (sLO). s_unsc = sLO; } - else if (! (eval_pt.sat < tep.high)) { - // s >= maximum tabulated saturation. - // Map to Maximum Input Saturation in cell (sHI). - s_unsc = sHI; - } else if (eval_pt.sat < tep.disp) { - // s in tabulated interval (tep.low, tep.disp) + // s in tabulated interval [tep.low, tep.disp) // Map to Input Saturation in (sLO, sR) const auto t = (eval_pt.sat - tep.low) / (tep.disp - tep.low); - s_unsc = sLO + t*(sR - sLO); + s_unsc = std::min(sLO + t*(sR - sLO), sHI); } - else { - // s in tabulated interval (tep.disp, tep.high) - // Map to Input Saturation in (sR, sHI) + else if (eval_pt.sat < tep.high) { + // s in tabulated interval [tep.disp, tep.high) + // Map to Input Saturation in [sR, sHI) + assert (tep.high > tep.disp); + const auto t = (eval_pt.sat - tep.disp) / (tep.high - tep.disp); - s_unsc = sR + t*(sHI - sR); + s_unsc = std::min(sR + t*std::max(sHI - sR, 0.0), sHI); + } + else { + // s >= maximum tabulated saturation. + // + // Map to Maximum Input Saturation in cell (sHI) if maximum + // tabulated saturation is strictly greater than critical + // displacing saturation--otherwise map to critical displacing + // saturation. + // + // Needed to handle cases in which \code tep.disp==tep.high + // \endcode but scaled versions of these might differ, i.e. when + // sR < sHI, but the corresponding saturation points in the + // underlying input table coincide. + s_unsc = (tep.high > tep.disp) ? sHI : sR; } } return unscaledsat; } -void -Opm::SatFunc::ThreePointScaling::Impl:: -handleInvalidEndpoint(const SaturationAssoc& sp, - std::vector& effsat) const -{ - if (this->handle_invalid_ == InvalidEndpointBehaviour::UseUnscaled) { - // User requests that invalid scaling be treated as unscaled - // saturations. Pick that. - effsat.push_back(sp.sat); - return; - } - - if (this->handle_invalid_ == InvalidEndpointBehaviour::IgnorePoint) { - // User requests that invalid scaling be ignored. Signal invalid - // scaled saturation to caller as NaN. - effsat.push_back(std::nan("")); - return; - } -} - // --------------------------------------------------------------------- // EPS factory functions for two-point and three-point scaling options // --------------------------------------------------------------------- -namespace { - bool haveScaledRelPermAtCritSatKeyword(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init, - const std::string& kw) - { - auto haveKW = false; - - for (const auto& grid : G.activeGrids()) { - haveKW = haveKW || init.haveKeywordData(kw, grid); - } - - return haveKW; - } - - bool haveScaledRelPermAtCritSat(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init, - const ::Opm::ECLPhaseIndex phase, - const ::Opm::SatFunc::CreateEPS::SubSystem subSys) - { - switch (phase) { - case ::Opm::ECLPhaseIndex::Aqua: - return haveScaledRelPermAtCritSatKeyword(G, init, "KRWR"); - - case ::Opm::ECLPhaseIndex::Liquid: - return (subSys == ::Opm::SatFunc::CreateEPS::SubSystem::OilGas) - ? haveScaledRelPermAtCritSatKeyword(G, init, "KROGR") - : haveScaledRelPermAtCritSatKeyword(G, init, "KROWR"); - - case ::Opm::ECLPhaseIndex::Vapour: - return haveScaledRelPermAtCritSatKeyword(G, init, "KRGR"); - } - - return false; - } -} // namespace Anonymous - namespace Create { using EPSOpt = ::Opm::SatFunc::CreateEPS::EPSOptions; using RTEP = ::Opm::SatFunc::CreateEPS::RawTableEndPoints; using TEP = ::Opm::SatFunc::EPSEvalInterface::TableEndPoints; - using InvBeh = ::Opm::SatFunc::EPSEvalInterface::InvalidEndpointBehaviour; namespace TwoPoint { using EPS = ::Opm::SatFunc::TwoPointScaling; @@ -682,35 +745,42 @@ namespace Create { struct Kr { static EPSPtr G(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init); + const ::Opm::ECLInitFileData& init, + const RTEP& tep); static EPSPtr OG(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init); + const ::Opm::ECLInitFileData& init, + const RTEP& tep); static EPSPtr OW(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init); + const ::Opm::ECLInitFileData& init, + const RTEP& tep); static EPSPtr W(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init); + const ::Opm::ECLInitFileData& init, + const RTEP& tep); }; struct Pc { static EPSPtr GO(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init); + const ::Opm::ECLInitFileData& init, + const RTEP& tep); static EPSPtr OW(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init); + const ::Opm::ECLInitFileData& init, + const RTEP& tep); }; static EPSPtr scalingFunction(const ::Opm::ECLGraph& G, const ::Opm::ECLInitFileData& init, - const EPSOpt& opt); + const EPSOpt& opt, + const RTEP& tep); static std::vector unscaledEndPoints(const RTEP& ep, const EPSOpt& opt); @@ -723,25 +793,30 @@ namespace Create { struct Kr { static EPSPtr G(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init); + const ::Opm::ECLInitFileData& init, + const RTEP& tep); static EPSPtr OG(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init); + const ::Opm::ECLInitFileData& init, + const RTEP& tep); static EPSPtr OW(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init); + const ::Opm::ECLInitFileData& init, + const RTEP& tep); static EPSPtr W(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init); + const ::Opm::ECLInitFileData& init, + const RTEP& tep); }; static EPSPtr - scalingFunction(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init, - const ::Opm::SatFunc::CreateEPS::EPSOptions& opt); + scalingFunction(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const EPSOpt& opt, + const RTEP& tep); static std::vector unscaledEndPoints(const RTEP& ep, const EPSOpt& opt); @@ -795,29 +870,94 @@ namespace Create { using FValVec = ::Opm::SatFunc::CreateEPS::Vertical::FuncValVector; using ScalPtr = std::unique_ptr; + namespace CritDispSat { + struct KrG { + static std::vector + twoPointMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep, + const bool activeOil); + + static std::vector + alternateMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep, + const bool activeOil); + }; + + struct KrGO { + static std::vector + twoPointMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep); + + static std::vector + alternateMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep); + }; + + struct KrOW { + static std::vector + twoPointMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep); + + static std::vector + alternateMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep); + }; + + struct KrW { + static std::vector + twoPointMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep, + const bool activeOil); + + static std::vector + alternateMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep, + const bool activeOil); + }; + + std::vector + transformedCritSat(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const std::vector& t, + const std::vector& left, + const std::vector& right); + } // namespace CritDispSat + struct Kr { static ScalPtr G(const ::Opm::ECLGraph& G, const ::Opm::ECLInitFileData& init, - const RTEP& tep, + std::vector&& sdisp, + std::vector&& smax, const FValVec& fval); static ScalPtr GO(const ::Opm::ECLGraph& G, const ::Opm::ECLInitFileData& init, - const RTEP& tep, + std::vector&& sdisp, + std::vector&& smax, const FValVec& fval); static ScalPtr OW(const ::Opm::ECLGraph& G, const ::Opm::ECLInitFileData& init, - const RTEP& tep, + std::vector&& sdisp, + std::vector&& smax, const FValVec& fval); static ScalPtr W(const ::Opm::ECLGraph& G, const ::Opm::ECLInitFileData& init, - const RTEP& tep, + std::vector&& sdisp, + std::vector&& smax, const FValVec& fval); }; @@ -834,10 +974,11 @@ namespace Create { // Implementation of Create::TwoPoint::scalingFunction() Create::TwoPoint::EPSPtr Create::TwoPoint::Kr::G(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init) + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - auto sgcr = G.rawLinearisedCellData(init, "SGCR"); - auto sgu = G.rawLinearisedCellData(init, "SGU"); + auto sgcr = sgCrit(G, init, tep); + auto sgu = sgMax (G, init, tep); if ((sgcr.size() != sgu.size()) || (sgcr.size() != G.numCells())) @@ -855,9 +996,10 @@ Create::TwoPoint::Kr::G(const ::Opm::ECLGraph& G, Create::TwoPoint::EPSPtr Create::TwoPoint::Kr::OG(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init) + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - auto sogcr = G.rawLinearisedCellData(init, "SOGCR"); + auto sogcr = sogCrit(G, init, tep); if (sogcr.size() != G.numCells()) { throw std::invalid_argument { @@ -866,40 +1008,7 @@ Create::TwoPoint::Kr::OG(const ::Opm::ECLGraph& G, }; } - auto smax = std::vector(sogcr.size(), 1.0); - - // Adjust maximum S_o for scaled connate gas saturations. - { - const auto sgl = G.rawLinearisedCellData(init, "SGL"); - - if (sgl.size() != sogcr.size()) { - throw std::invalid_argument { - "Missing or Mismatching Connate Gas " - "Saturation in Oil/Gas System" - }; - } - - for (auto n = sgl.size(), i = 0*n; i < n; ++i) { - smax[i] -= sgl[i]; - } - } - - // Adjust maximum S_o for scaled connate water saturations (if relevant). - { - const auto swl = G.rawLinearisedCellData(init, "SWL"); - - if (swl.size() == sogcr.size()) { - for (auto n = swl.size(), i = 0*n; i < n; ++i) { - smax[i] -= swl[i]; - } - } - else if (! swl.empty()) { - throw std::invalid_argument { - "Mismatching Connate Water " - "Saturation in Oil/Gas System" - }; - } - } + auto smax = soMax(G, init, tep); return EPSPtr { new EPS { std::move(sogcr), std::move(smax) } @@ -908,9 +1017,10 @@ Create::TwoPoint::Kr::OG(const ::Opm::ECLGraph& G, Create::TwoPoint::EPSPtr Create::TwoPoint::Kr::OW(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init) + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - auto sowcr = G.rawLinearisedCellData(init, "SOWCR"); + auto sowcr = sowCrit(G, init, tep); if (sowcr.size() != G.numCells()) { throw std::invalid_argument { @@ -919,40 +1029,7 @@ Create::TwoPoint::Kr::OW(const ::Opm::ECLGraph& G, }; } - auto smax = std::vector(sowcr.size(), 1.0); - - // Adjust maximum S_o for scaled connate water saturations. - { - const auto swl = G.rawLinearisedCellData(init, "SWL"); - - if (swl.size() != sowcr.size()) { - throw std::invalid_argument { - "Missing or Mismatching Connate Water " - "Saturation in Oil/Water System" - }; - } - - for (auto n = swl.size(), i = 0*n; i < n; ++i) { - smax[i] -= swl[i]; - } - } - - // Adjust maximum S_o for scaled connate gas saturations (if relevant). - { - const auto sgl = G.rawLinearisedCellData(init, "SGL"); - - if (sgl.size() == sowcr.size()) { - for (auto n = sgl.size(), i = 0*n; i < n; ++i) { - smax[i] -= sgl[i]; - } - } - else if (! sgl.empty()) { - throw std::invalid_argument { - "Mismatching Connate Gas " - "Saturation in Oil/Water System" - }; - } - } + auto smax = soMax(G, init, tep); return EPSPtr { new EPS { std::move(sowcr), std::move(smax) } @@ -961,10 +1038,11 @@ Create::TwoPoint::Kr::OW(const ::Opm::ECLGraph& G, Create::TwoPoint::EPSPtr Create::TwoPoint::Kr::W(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init) + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - auto swcr = G.rawLinearisedCellData(init, "SWCR"); - auto swu = G.rawLinearisedCellData(init, "SWU"); + auto swcr = swCrit(G, init, tep); + auto swu = swMax (G, init, tep); if (swcr.empty() || swu.empty()) { throw std::invalid_argument { @@ -979,16 +1057,20 @@ Create::TwoPoint::Kr::W(const ::Opm::ECLGraph& G, Create::TwoPoint::EPSPtr Create::TwoPoint::Pc::GO(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init) + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - // Try dedicated scaled Sg_conn for Pc first - auto sgl = G.rawLinearisedCellData(init, "SGLPC"); - if (sgl.empty()) { - // Fall back to general scaled Sg_conn if not available. - sgl = G.rawLinearisedCellData(init, "SGL"); - } + // Use dedicated scaled Sg_conn for Pc if defined in at least one + // subgrid. Use SGL otherwise. Same default value (i.e., table's + // connate gas saturation) for both vectors. + const auto sgl = ::Opm::SatFunc::scaledConnateGas(G, init, tep); + + auto sglpc = haveKeywordData(G, init, "SGLPC") + ? gridDefaultedVector(G, init, "SGLPC", tep.conn.gas, + [](const double s) { return s; }, sgl) + : sgl; - auto sgu = G.rawLinearisedCellData(init, "SGU"); + auto sgu = sgMax(G, init, tep); if ((sgl.size() != sgu.size()) || (sgl.size() != G.numCells())) @@ -1000,22 +1082,26 @@ Create::TwoPoint::Pc::GO(const ::Opm::ECLGraph& G, } return EPSPtr { - new EPS { std::move(sgl), std::move(sgu) } + new EPS { std::move(sglpc), std::move(sgu) } }; } Create::TwoPoint::EPSPtr Create::TwoPoint::Pc::OW(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init) + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - // Try dedicated scaled Sw_conn for Pc first - auto swl = G.rawLinearisedCellData(init, "SWLPC"); - if (swl.empty()) { - // Fall back to general scaled Sw_conn if not available. - swl = G.rawLinearisedCellData(init, "SWL"); - } + // Use dedicated scaled Sw_conn for Pc if defined in at least one + // subgrid. Use SWL otherwise. Same default value (i.e., table's + // connate water saturation) for both vectors. + const auto swl = ::Opm::SatFunc::scaledConnateWater(G, init, tep); + + auto swlpc = haveKeywordData(G, init, "SWLPC") + ? gridDefaultedVector(G, init, "SWLPC", tep.conn.water, + [](const double s) { return s; }, swl) + : swl; - auto swu = G.rawLinearisedCellData(init, "SWU"); + auto swu = swMax(G, init, tep); if ((swl.size() != swu.size()) || (swl.size() != G.numCells())) @@ -1027,15 +1113,16 @@ Create::TwoPoint::Pc::OW(const ::Opm::ECLGraph& G, } return EPSPtr { - new EPS { std::move(swl), std::move(swu) } + new EPS { std::move(swlpc), std::move(swu) } }; } Create::TwoPoint::EPSPtr Create::TwoPoint:: -scalingFunction(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init, - const ::Opm::SatFunc::CreateEPS::EPSOptions& opt) +scalingFunction(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const EPSOpt& opt, + const RTEP& tep) { using FCat = ::Opm::SatFunc::CreateEPS::FunctionCategory; using SSys = ::Opm::SatFunc::CreateEPS::SubSystem; @@ -1054,10 +1141,10 @@ scalingFunction(const ::Opm::ECLGraph& G, } if (opt.thisPh == PhIdx::Aqua) { - return Create::TwoPoint::Kr::W(G, init); + return Create::TwoPoint::Kr::W(G, init, tep); } - return Create::TwoPoint::Kr::OW(G, init); + return Create::TwoPoint::Kr::OW(G, init, tep); } if (opt.subSys == SSys::OilGas) { @@ -1069,10 +1156,10 @@ scalingFunction(const ::Opm::ECLGraph& G, } if (opt.thisPh == PhIdx::Vapour) { - return Create::TwoPoint::Kr::G(G, init); + return Create::TwoPoint::Kr::G(G, init, tep); } - return Create::TwoPoint::Kr::OG(G, init); + return Create::TwoPoint::Kr::OG(G, init, tep); } } @@ -1085,11 +1172,11 @@ scalingFunction(const ::Opm::ECLGraph& G, } if (opt.thisPh == PhIdx::Vapour) { - return Create::TwoPoint::Pc::GO(G, init); + return Create::TwoPoint::Pc::GO(G, init, tep); } if (opt.thisPh == PhIdx::Aqua) { - return Create::TwoPoint::Pc::OW(G, init); + return Create::TwoPoint::Pc::OW(G, init, tep); } } @@ -1174,10 +1261,11 @@ Create::TwoPoint::unscaledEndPoints(const RTEP& ep, const EPSOpt& opt) Create::ThreePoint::EPSPtr Create::ThreePoint::Kr::G(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init) + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - auto sgcr = G.rawLinearisedCellData(init, "SGCR"); - auto sgu = G.rawLinearisedCellData(init, "SGU"); + auto sgcr = sgCrit(G, init, tep); + auto sgu = sgMax (G, init, tep); if ((sgcr.size() != sgu.size()) || (sgcr.size() != G.numCells())) @@ -1188,54 +1276,22 @@ Create::ThreePoint::Kr::G(const ::Opm::ECLGraph& G, }; } - auto sr = std::vector(G.numCells(), 1.0); - - // Adjust displacing saturation for connate water. - { - const auto swl = G.rawLinearisedCellData(init, "SWL"); - - if (swl.size() == sgcr.size()) { - for (auto n = swl.size(), i = 0*n; i < n; ++i) { - sr[i] -= swl[i]; - } - } - else if (! swl.empty()) { - throw std::invalid_argument { - "Connate Water Saturation Array Mismatch " - "in Three-Point Scaling Option" - }; - } - } - - // Adjust displacing saturation for critical S_o in O/G system. - { - const auto sogcr = G.rawLinearisedCellData(init, "SOGCR"); - - if (sogcr.size() == sgcr.size()) { - for (auto n = sogcr.size(), i = 0*n; i < n; ++i) { - sr[i] -= sogcr[i]; - } - } - else if (! sogcr.empty()) { - throw std::invalid_argument { - "Critical Oil Saturation (O/G System) Array " - "Size Mismatch in Three-Point Scaling Option" - }; - } - } + auto sdisp = CritSatVertical::CritDispSat:: + KrG::alternateMethod(G, init, tep, true); return EPSPtr { new EPS { - std::move(sgcr), std::move(sr), std::move(sgu) + std::move(sgcr), std::move(sdisp), std::move(sgu) } }; } Create::ThreePoint::EPSPtr Create::ThreePoint::Kr::OG(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init) + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - auto sogcr = G.rawLinearisedCellData(init, "SOGCR"); + auto sogcr = sogCrit(G, init, tep); if (sogcr.size() != G.numCells()) { throw std::invalid_argument { @@ -1244,61 +1300,11 @@ Create::ThreePoint::Kr::OG(const ::Opm::ECLGraph& G, }; } - auto smax = std::vector(sogcr.size(), 1.0); - - // Adjust maximum S_o for scaled connate gas saturations. - { - const auto sgl = G.rawLinearisedCellData(init, "SGL"); - - if (sgl.size() != sogcr.size()) { - throw std::invalid_argument { - "Missing or Mismatching Connate Gas " - "Saturation in Oil/Gas System" - }; - } - - for (auto n = sgl.size(), i = 0*n; i < n; ++i) { - smax[i] -= sgl[i]; - } - } - - auto sdisp = std::vector(sogcr.size(), 1.0); - - // Adjust displacing S_o for scaled critical gas saturation. - { - const auto sgcr = G.rawLinearisedCellData(init, "SGCR"); - - if (sgcr.size() != sogcr.size()) { - throw std::invalid_argument { - "Missing or Mismatching Scaled Critical Gas " - "Saturation in Oil/Gas System" - }; - } - - for (auto n = sgcr.size(), i = 0*n; i < n; ++i) { - sdisp[i] -= sgcr[i]; - } - } - - // Adjust displacing and maximum S_o for scaled connate water - // saturations (if relevant). - { - const auto swl = G.rawLinearisedCellData(init, "SWL"); - - if (swl.size() == sogcr.size()) { - for (auto n = swl.size(), i = 0*n; i < n; ++i) { - sdisp[i] -= swl[i]; - smax [i] -= swl[i]; - } - } - else if (! swl.empty()) { - throw std::invalid_argument { - "Mismatching Scaled Connate Water " - "Saturation in Oil/Gas System" - }; - } - } - + auto sdisp = CritSatVertical::CritDispSat:: + KrGO::alternateMethod(G, init, tep); + + auto smax = soMax(G, init, tep); + return EPSPtr { new EPS { std::move(sogcr), std::move(sdisp), std::move(smax) @@ -1308,9 +1314,10 @@ Create::ThreePoint::Kr::OG(const ::Opm::ECLGraph& G, Create::ThreePoint::EPSPtr Create::ThreePoint::Kr::OW(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init) + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - auto sowcr = G.rawLinearisedCellData(init, "SOWCR"); + auto sowcr = sowCrit(G, init, tep); if (sowcr.size() != G.numCells()) { throw std::invalid_argument { @@ -1319,60 +1326,10 @@ Create::ThreePoint::Kr::OW(const ::Opm::ECLGraph& G, }; } - auto smax = std::vector(sowcr.size(), 1.0); - - // Adjust maximum S_o for scaled connate water saturations. - { - const auto swl = G.rawLinearisedCellData(init, "SWL"); - - if (swl.size() != sowcr.size()) { - throw std::invalid_argument { - "Missing or Mismatching Connate Water " - "Saturation in Oil/Water System" - }; - } - - for (auto n = swl.size(), i = 0*n; i < n; ++i) { - smax[i] -= swl[i]; - } - } - - auto sdisp = std::vector(sowcr.size(), 1.0); - - // Adjust displacing S_o for scaled critical water saturations. - { - const auto swcr = G.rawLinearisedCellData(init, "SWCR"); - - if (swcr.size() != sowcr.size()) { - throw std::invalid_argument { - "Missing or Mismatching Scaled Critical Water " - "Saturation in Oil/Water System" - }; - } - - for (auto n = swcr.size(), i = 0*n; i < n; ++i) { - sdisp[i] -= swcr[i]; - } - } - - // Adjust displacing and maximum S_o for scaled connate gas saturations - // (if relevant). - { - const auto sgl = G.rawLinearisedCellData(init, "SGL"); + auto sdisp = CritSatVertical::CritDispSat:: + KrOW::alternateMethod(G, init, tep); - if (sgl.size() == sowcr.size()) { - for (auto n = sgl.size(), i = 0*n; i < n; ++i) { - sdisp[i] -= sgl[i]; - smax [i] -= sgl[i]; - } - } - else if (! sgl.empty()) { - throw std::invalid_argument { - "Mismatching Connate Gas " - "Saturation in Oil/Water System" - }; - } - } + auto smax = soMax(G, init, tep); return EPSPtr { new EPS { @@ -1383,10 +1340,11 @@ Create::ThreePoint::Kr::OW(const ::Opm::ECLGraph& G, Create::ThreePoint::EPSPtr Create::ThreePoint::Kr::W(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init) + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - auto swcr = G.rawLinearisedCellData(init, "SWCR"); - auto swu = G.rawLinearisedCellData(init, "SWU"); + auto swcr = swCrit(G, init, tep); + auto swu = swMax (G, init, tep); if ((swcr.size() != G.numCells()) || (swcr.size() != swu.size())) @@ -1396,41 +1354,8 @@ Create::ThreePoint::Kr::W(const ::Opm::ECLGraph& G, }; } - auto sdisp = std::vector(swcr.size(), 1.0); - - // Adjust displacing S_w for scaled critical oil saturation. - { - const auto sowcr = G.rawLinearisedCellData(init, "SOWCR"); - - if (sowcr.size() == swcr.size()) { - for (auto n = sowcr.size(), i = 0*n; i < n; ++i) { - sdisp[i] -= sowcr[i]; - } - } - else if (! sowcr.empty()) { - throw std::invalid_argument { - "Missing or Mismatching Scaled Critical " - "Oil Saturation in Oil/Water System" - }; - } - } - - // Adjust displacing S_w for scaled connate gas saturation. - { - const auto sgl = G.rawLinearisedCellData(init, "SGL"); - - if (sgl.size() == swcr.size()) { - for (auto n = sgl.size(), i = 0*n; i < n; ++i) { - sdisp[i] -= sgl[i]; - } - } - else if (! sgl.empty()) { - throw std::invalid_argument { - "Missing or Mismatching Scaled Connate " - "Gas Saturation in Oil/Water System" - }; - } - } + auto sdisp = CritSatVertical::CritDispSat:: + KrW::alternateMethod(G, init, tep, true); return EPSPtr { new EPS { @@ -1441,9 +1366,10 @@ Create::ThreePoint::Kr::W(const ::Opm::ECLGraph& G, Create::ThreePoint::EPSPtr Create::ThreePoint:: -scalingFunction(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init, - const ::Opm::SatFunc::CreateEPS::EPSOptions& opt) +scalingFunction(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const EPSOpt& opt, + const RTEP& tep) { #if !defined(NDEBUG) using FCat = ::Opm::SatFunc::CreateEPS::FunctionCategory; @@ -1464,10 +1390,10 @@ scalingFunction(const ::Opm::ECLGraph& G, } if (opt.thisPh == PhIdx::Aqua) { - return Create::ThreePoint::Kr::W(G, init); + return Create::ThreePoint::Kr::W(G, init, tep); } - return Create::ThreePoint::Kr::OW(G, init); + return Create::ThreePoint::Kr::OW(G, init, tep); } if (opt.subSys == SSys::OilGas) { @@ -1479,10 +1405,10 @@ scalingFunction(const ::Opm::ECLGraph& G, } if (opt.thisPh == PhIdx::Vapour) { - return Create::ThreePoint::Kr::G(G, init); + return Create::ThreePoint::Kr::G(G, init, tep); } - return Create::ThreePoint::Kr::OG(G, init); + return Create::ThreePoint::Kr::OG(G, init, tep); } // Invalid. @@ -1726,63 +1652,356 @@ scalingFunction(const ::Opm::ECLGraph& G, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Implementation of Create::CritSatVertical::scalingFunction() -namespace { - template - std::vector - extractCritSat(const std::vector& tep, - Extract&& extract) +std::vector +Create::CritSatVertical::CritDispSat:: +KrG::twoPointMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep, + const bool activeOil) +{ + const auto& sgcr = tep.crit.gas; + const auto& sgu = tep.smax.gas; + + auto t = std::vector(sgcr.size(), 0.0); + if (activeOil) { + // G/O or G/O/W system + for (auto n = sgcr.size(), i = 0*n; i < n; ++i) { + const auto sr = 1.0 - (tep.crit.oil_in_gas[i] + + tep.conn.water [i]); + + t[i] = (sr - sgcr[i]) / (sgu[i] - sgcr[i]); + } + } + else { + // G/W system. + for (auto n = sgcr.size(), i = 0*n; i < n; ++i) { + const auto sr = 1.0 - tep.crit.water[i]; + + t[i] = (sr - sgcr[i]) / (sgu[i] - sgcr[i]); + } + } + + return transformedCritSat(G, init, t, + sgCrit(G, init, tep), + sgMax (G, init, tep)); +} + +std::vector +Create::CritSatVertical::CritDispSat:: +KrG::alternateMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep, + const bool activeOil) +{ + auto sdisp = std::vector(G.numCells(), 0.0); + + if (activeOil) { + // G/O or G/O/W system. + const auto sogcr = sogCrit(G, init, tep); + const auto swl = ::Opm::SatFunc::scaledConnateWater(G, init, tep); + + std::transform(std::begin(sogcr), std::end(sogcr), std::begin(swl), + std::begin(sdisp), + [](const double so, const double sw) -> double + { + return 1.0 - (so + sw); + }); + } + else { + // G/W system. + const auto swcr = swCrit(G, init, tep); + + std::transform(std::begin(swcr), std::end(swcr), + std::begin(sdisp), + [](const double sw) -> double + { + return 1.0 - sw; + }); + } + + return sdisp; +} + +std::vector +Create::CritSatVertical::CritDispSat:: +KrGO::twoPointMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep) +{ + const auto& sogcr = tep.crit.oil_in_gas; + + auto t = std::vector(sogcr.size(), 0.0); { - auto scr = std::vector(tep.size(), 0.0); + const auto& sgco = tep.conn.gas; + const auto& swco = tep.conn.water; + const auto& sgcr = tep.crit.gas; - std::transform(std::begin(tep), std::end(tep), std::begin(scr), - std::forward(extract)); + for (auto n = sgcr.size(), i = 0*n; i < n; ++i) { + const auto sr = 1.0 - (sgcr[i] + swco[i]); + const auto smax = 1.0 - (sgco[i] + swco[i]); // >= sr - return scr; + t[i] = (sr - sogcr[i]) / (smax - sogcr[i]); + } } + + return transformedCritSat(G, init, t, + sogCrit(G, init, tep), + soMax (G, init, tep)); } -Create::CritSatVertical::ScalPtr -Create::CritSatVertical::Kr::G(const ::Opm::ECLGraph& G, - const ::Opm::ECLInitFileData& init, - const RTEP& rtep, - const FValVec& fval) +std::vector +Create::CritSatVertical::CritDispSat:: +KrGO::alternateMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep) { - using FVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues; + auto sdisp = std::vector(G.numCells(), 0.0); + + const auto sgcr = sgCrit(G, init, tep); + const auto swl = ::Opm::SatFunc::scaledConnateWater(G, init, tep); + + std::transform(std::begin(sgcr), std::end(sgcr), std::begin(swl), + std::begin(sdisp), + [](const double sg, const double sw) -> double + { + return 1.0 - (sg + sw); + }); + + return sdisp; +} + +std::vector +Create::CritSatVertical::CritDispSat:: +KrOW::twoPointMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep) +{ + const auto& sowcr = tep.crit.oil_in_water; + + auto t = std::vector(sowcr.size(), 0.0); + { + const auto& sgco = tep.conn.gas; + const auto& swco = tep.conn.water; + const auto& swcr = tep.crit.water; + + for (auto n = swcr.size(), i = 0*n; i < n; ++i) { + const auto sr = 1.0 - (swcr[i] + sgco[i]); + const auto smax = 1.0 - (swco[i] + sgco[i]); // >= sr + + t[i] = (sr - sowcr[i]) / (smax - sowcr[i]); + } + } + + return transformedCritSat(G, init, t, + sowCrit(G, init, tep), + soMax (G, init, tep)); +} + +std::vector +Create::CritSatVertical::CritDispSat:: +KrOW::alternateMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep) +{ + auto sdisp = std::vector(G.numCells(), 0.0); + + const auto swcr = swCrit(G, init, tep); + const auto sgl = ::Opm::SatFunc::scaledConnateGas(G, init, tep); + + std::transform(std::begin(swcr), std::end(swcr), std::begin(sgl), + std::begin(sdisp), + [](const double sw, const double sg) -> double + { + return 1.0 - (sg + sw); + }); + + return sdisp; +} + +std::vector +Create::CritSatVertical::CritDispSat:: +KrW::twoPointMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep, + const bool activeOil) +{ + const auto& swcr = tep.crit.water; + const auto& swu = tep.smax.water; + + auto t = std::vector(swcr.size(), 0.0); + if (activeOil) { + // G/O or G/O/W system + for (auto n = swcr.size(), i = 0*n; i < n; ++i) { + const auto sr = 1.0 - (tep.crit.oil_in_water[i] + + tep.conn.gas [i]); + + t[i] = (sr - swcr[i]) / (swu[i] - swcr[i]); + } + } + else { + // G/W system. + for (auto n = swcr.size(), i = 0*n; i < n; ++i) { + const auto sr = 1.0 - tep.crit.gas[i]; - const auto& ih = init.keywordData(INTEHEAD_KW); - const auto iphs = static_cast(ih[INTEHEAD_PHASE_INDEX]); + t[i] = (sr - swcr[i]) / (swu[i] - swcr[i]); + } + } - auto sdisp = std::vector(G.numCells()); + return transformedCritSat(G, init, t, + swCrit(G, init, tep), + swMax (G, init, tep)); +} - if ((iphs & (1u << 0)) != 0) { // Oil active - auto sogcr = - gridDefaultedVector(G, init, "SOGCR", rtep.crit.oil_in_gas, - [](const double s) { return s; }); +std::vector +Create::CritSatVertical::CritDispSat:: +KrW::alternateMethod(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const RTEP& tep, + const bool activeOil) +{ + auto sdisp = std::vector(G.numCells(), 0.0); - auto swl = - gridDefaultedVector(G, init, "SWL", rtep.conn.water, - [](const double s) { return s; }); + if (activeOil) { + // G/O or G/O/W system. + const auto sowcr = sowCrit(G, init, tep); + const auto sgl = ::Opm::SatFunc::scaledConnateGas(G, init, tep); - std::transform(std::begin(sogcr), std::end(sogcr), - std::begin(swl), std::begin(sdisp), - [](const double so, const double sw) + std::transform(std::begin(sowcr), std::end(sowcr), std::begin(sgl), + std::begin(sdisp), + [](const double so, const double sg) -> double { - return 1.0 - (so + sw); + return 1.0 - (so + sg); }); } - else { // Oil not active (G/W?) - auto swcr = - gridDefaultedVector(G, init, "SWCR", rtep.crit.water, - [](const double s) { return s; }); + else { + // G/W system. + const auto sgcr = sgCrit(G, init, tep); - std::transform(std::begin(swcr), std::end(swcr), + std::transform(std::begin(sgcr), std::end(sgcr), std::begin(sdisp), - [](const double sw) + [](const double sg) -> double { - return 1.0 - sw; + return 1.0 - sg; }); } + return sdisp; +} + +std::vector +Create::CritSatVertical::CritDispSat:: +transformedCritSat(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const std::vector& t, + const std::vector& left, + const std::vector& right) +{ + auto sdisp = std::vector(G.numCells(), 0.0); + + auto cellID = std::vector::size_type{0}; + for (const auto& gridID : G.activeGrids()) { + const auto nc = G.numCells(gridID); + + const auto& snum = init.haveKeywordData("SATNUM", gridID) + ? G.rawLinearisedCellData(init, "SATNUM", gridID) + : std::vector(nc, 1); + + for (auto c = 0*nc; c < nc; ++c, ++cellID) { + const auto x = t[snum[c] - 1]; + + sdisp[cellID] = (1.0 - x)*left[cellID] + x*right[cellID]; + } + } + + return sdisp; +} + +namespace { + std::vector + critDispSat(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const ::Opm::SatFunc::CreateEPS::EPSOptions& opt, + const ::Opm::SatFunc::CreateEPS::RawTableEndPoints& rtep) + { + namespace CDS = Create::CritSatVertical::CritDispSat; + + if (opt.curve != ::Opm::SatFunc::CreateEPS::FunctionCategory::Relperm) { + return {}; + } + + const auto& ih = init.keywordData(INTEHEAD_KW); + const auto activeOil = + (ih[INTEHEAD_PHASE_INDEX] & (1u << 0u)) != 0; + + if (opt.subSys == ::Opm::SatFunc::CreateEPS::SubSystem::OilGas) { + if (opt.thisPh == ::Opm::ECLPhaseIndex::Aqua) { + throw std::invalid_argument { + "Cannot request Critical Scaled Saturation " + "for water in Gas/Oil system" + }; + } + + if (opt.thisPh == ::Opm::ECLPhaseIndex::Liquid) { + return !opt.use3PtScaling + ? CDS::KrGO::twoPointMethod (G, init, rtep) + : CDS::KrGO::alternateMethod(G, init, rtep); + } + + return !opt.use3PtScaling + ? CDS::KrG::twoPointMethod (G, init, rtep, activeOil) + : CDS::KrG::alternateMethod(G, init, rtep, activeOil); + } + + if (opt.subSys == ::Opm::SatFunc::CreateEPS::SubSystem::OilWater) { + if (opt.thisPh == ::Opm::ECLPhaseIndex::Vapour) { + throw std::invalid_argument { + "Cannot request Critical Scaled Saturation " + "for gas in Oil/Water system" + }; + } + + if (opt.thisPh == ::Opm::ECLPhaseIndex::Liquid) { + return !opt.use3PtScaling + ? CDS::KrOW::twoPointMethod (G, init, rtep) + : CDS::KrOW::alternateMethod(G, init, rtep); + } + + return !opt.use3PtScaling + ? CDS::KrW::twoPointMethod (G, init, rtep, activeOil) + : CDS::KrW::alternateMethod(G, init, rtep, activeOil); + } + + // Invalid + return {}; + } + + std::vector + maximumSat(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + const ::Opm::SatFunc::CreateEPS::EPSOptions& opt, + const ::Opm::SatFunc::CreateEPS::RawTableEndPoints& tep) + { + switch (opt.thisPh) { + case ::Opm::ECLPhaseIndex::Aqua: return swMax(G, init, tep); + case ::Opm::ECLPhaseIndex::Liquid: return soMax(G, init, tep); + case ::Opm::ECLPhaseIndex::Vapour: return sgMax(G, init, tep); + } + + throw std::invalid_argument { + "Unsupported Phase Index" + }; + } +} + +Create::CritSatVertical::ScalPtr +Create::CritSatVertical::Kr::G(const ::Opm::ECLGraph& G, + const ::Opm::ECLInitFileData& init, + std::vector&& sdisp, + std::vector&& smax, + const FValVec& fval) +{ + using FVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues; + auto dflt_fdisp = std::vector(fval.size(), 0.0); std::transform(std::begin(fval), std::end(fval), std::begin(dflt_fdisp), @@ -1803,7 +2022,8 @@ Create::CritSatVertical::Kr::G(const ::Opm::ECLGraph& G, return ScalPtr { new ::Opm::SatFunc::CritSatVerticalScaling { - std::move(sdisp), std::move(fdisp), std::move(fmax) + std::move(sdisp), std::move(fdisp), + std::move(smax) , std::move(fmax) } }; } @@ -1811,26 +2031,11 @@ Create::CritSatVertical::Kr::G(const ::Opm::ECLGraph& G, Create::CritSatVertical::ScalPtr Create::CritSatVertical::Kr::GO(const ::Opm::ECLGraph& G, const ::Opm::ECLInitFileData& init, - const RTEP& tep, + std::vector&& sdisp, + std::vector&& smax, const FValVec& fval) { using FVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues; - auto sdisp = std::vector(G.numCells()); - - auto sgcr = - gridDefaultedVector(G, init, "SGCR", tep.crit.gas, - [](const double s) { return s; }); - - auto swl = - gridDefaultedVector(G, init, "SWL", tep.conn.water, - [](const double s) { return s; }); - - std::transform(std::begin(sgcr), std::end(sgcr), - std::begin(swl), std::begin(sdisp), - [](const double sg, const double sw) - { - return 1.0 - (sg + sw); - }); auto dflt_fdisp = std::vector(fval.size(), 0.0); std::transform(std::begin(fval), std::end(fval), @@ -1852,7 +2057,8 @@ Create::CritSatVertical::Kr::GO(const ::Opm::ECLGraph& G, return ScalPtr { new ::Opm::SatFunc::CritSatVerticalScaling { - std::move(sdisp), std::move(fdisp), std::move(fmax) + std::move(sdisp), std::move(fdisp), + std::move(smax) , std::move(fmax) } }; } @@ -1860,26 +2066,11 @@ Create::CritSatVertical::Kr::GO(const ::Opm::ECLGraph& G, Create::CritSatVertical::ScalPtr Create::CritSatVertical::Kr::OW(const ::Opm::ECLGraph& G, const ::Opm::ECLInitFileData& init, - const RTEP& tep, + std::vector&& sdisp, + std::vector&& smax, const FValVec& fval) { using FVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues; - auto sdisp = std::vector(G.numCells()); - - auto swcr = - gridDefaultedVector(G, init, "SWCR", tep.crit.water, - [](const double s) { return s; }); - - auto sgl = - gridDefaultedVector(G, init, "SGL", tep.conn.gas, - [](const double s) { return s; }); - - std::transform(std::begin(swcr), std::end(swcr), - std::begin(sgl), std::begin(sdisp), - [](const double sw, const double sg) - { - return 1.0 - (sg + sw); - }); auto dflt_fdisp = std::vector(fval.size(), 0.0); std::transform(std::begin(fval), std::end(fval), @@ -1901,7 +2092,8 @@ Create::CritSatVertical::Kr::OW(const ::Opm::ECLGraph& G, return ScalPtr { new ::Opm::SatFunc::CritSatVerticalScaling { - std::move(sdisp), std::move(fdisp), std::move(fmax) + std::move(sdisp), std::move(fdisp), + std::move(smax) , std::move(fmax) } }; } @@ -1909,45 +2101,12 @@ Create::CritSatVertical::Kr::OW(const ::Opm::ECLGraph& G, Create::CritSatVertical::ScalPtr Create::CritSatVertical::Kr::W(const ::Opm::ECLGraph& G, const ::Opm::ECLInitFileData& init, - const RTEP& tep, + std::vector&& sdisp, + std::vector&& smax, const FValVec& fval) { using FVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues; - const auto& ih = init.keywordData(INTEHEAD_KW); - const auto iphs = static_cast(ih[INTEHEAD_PHASE_INDEX]); - - auto sdisp = std::vector(G.numCells()); - - if ((iphs & (1u << 0)) != 0) { // Oil active - auto sowcr = - gridDefaultedVector(G, init, "SOWCR", tep.crit.oil_in_water, - [](const double s) { return s; }); - - auto sgl = - gridDefaultedVector(G, init, "SGL", tep.conn.gas, - [](const double s) { return s; }); - - std::transform(std::begin(sowcr), std::end(sowcr), - std::begin(sgl), std::begin(sdisp), - [](const double so, const double sg) - { - return 1.0 - (so + sg); - }); - } - else { // Oil not active (G/W?) - auto sgcr = - gridDefaultedVector(G, init, "SGCR", tep.crit.gas, - [](const double s) { return s; }); - - std::transform(std::begin(sgcr), std::end(sgcr), - std::begin(sdisp), - [](const double sg) - { - return 1.0 - sg; - }); - } - auto dflt_fdisp = std::vector(fval.size(), 0.0); std::transform(std::begin(fval), std::end(fval), std::begin(dflt_fdisp), @@ -1968,7 +2127,8 @@ Create::CritSatVertical::Kr::W(const ::Opm::ECLGraph& G, return ScalPtr { new ::Opm::SatFunc::CritSatVerticalScaling { - std::move(sdisp), std::move(fdisp), std::move(fmax) + std::move(sdisp), std::move(fdisp), + std::move(smax) , std::move(fmax) } }; } @@ -1984,6 +2144,9 @@ scalingFunction(const ::Opm::ECLGraph& G, using SSys = ::Opm::SatFunc::CreateEPS::SubSystem; using PhIdx = ::Opm::ECLPhaseIndex; + auto scr = critDispSat(G, init, opt, tep); + auto smax = maximumSat (G, init, opt, tep); + if (opt.subSys == SSys::OilWater) { if (opt.thisPh == PhIdx::Vapour) { throw std::invalid_argument { @@ -1993,10 +2156,12 @@ scalingFunction(const ::Opm::ECLGraph& G, } if (opt.thisPh == PhIdx::Aqua) { - return Create::CritSatVertical::Kr::W(G, init, tep, fvals); + return Create::CritSatVertical:: + Kr::W(G, init, std::move(scr), std::move(smax), fvals); } - return Create::CritSatVertical::Kr::OW(G, init, tep, fvals); + return Create::CritSatVertical:: + Kr::OW(G, init, std::move(scr), std::move(smax), fvals); } if (opt.subSys == SSys::OilGas) { @@ -2008,10 +2173,12 @@ scalingFunction(const ::Opm::ECLGraph& G, } if (opt.thisPh == PhIdx::Vapour) { - return Create::CritSatVertical::Kr::G(G, init, tep, fvals); + return Create::CritSatVertical:: + Kr::G(G, init, std::move(scr), std::move(smax), fvals); } - return Create::CritSatVertical::Kr::GO(G, init, tep, fvals); + return Create::CritSatVertical:: + Kr::GO(G, init, std::move(scr), std::move(smax), fvals); } // Invalid. @@ -2209,8 +2376,10 @@ Opm::SatFunc::ThreePointScaling::clone() const Opm::SatFunc::CritSatVerticalScaling:: CritSatVerticalScaling(std::vector sdisp, std::vector fdisp, + std::vector smax, std::vector fmax) - : pImpl_(new Impl(std::move(sdisp), std::move(fdisp), std::move(fmax))) + : pImpl_(new Impl(std::move(sdisp), std::move(fdisp), + std::move(smax) , std::move(fmax))) {} Opm::SatFunc::CritSatVerticalScaling::~CritSatVerticalScaling() @@ -2266,19 +2435,20 @@ Opm::SatFunc::CritSatVerticalScaling::clone() const std::unique_ptr Opm::SatFunc::CreateEPS::Horizontal:: -fromECLOutput(const ECLGraph& G, - const ECLInitFileData& init, - const EPSOptions& opt) +fromECLOutput(const ECLGraph& G, + const ECLInitFileData& init, + const EPSOptions& opt, + const RawTableEndPoints& tep) { if ((opt.curve == FunctionCategory::CapPress) || (! opt.use3PtScaling)) { - return Create::TwoPoint::scalingFunction(G, init, opt); + return Create::TwoPoint::scalingFunction(G, init, opt, tep); } if ((opt.curve == FunctionCategory::Relperm) && opt.use3PtScaling) { - return Create::ThreePoint::scalingFunction(G, init, opt); + return Create::ThreePoint::scalingFunction(G, init, opt, tep); } // Invalid @@ -2290,8 +2460,8 @@ fromECLOutput(const ECLGraph& G, std::vector Opm::SatFunc::CreateEPS::Horizontal:: -unscaledEndPoints(const RawTableEndPoints& ep, - const EPSOptions& opt) +unscaledEndPoints(const EPSOptions& opt, + const RawTableEndPoints& ep) { if ((opt.curve == FunctionCategory::CapPress) || (! opt.use3PtScaling)) @@ -2319,8 +2489,7 @@ fromECLOutput(const ECLGraph& G, const RawTableEndPoints& tep, const FuncValVector& fvals) { - const auto haveScaleCRS = - haveScaledRelPermAtCritSat(G, init, opt.thisPh, opt.subSys); + const auto haveScaleCRS = haveScaledRelPermAtCritSat(G, init, opt); if ((opt.curve == FunctionCategory::CapPress) || (! haveScaleCRS)) { @@ -2351,8 +2520,7 @@ unscaledFunctionValues(const ECLGraph& G, { auto ret = std::vector{}; - const auto haveScaleCRS = - haveScaledRelPermAtCritSat(G, init, opt.thisPh, opt.subSys); + const auto haveScaleCRS = haveScaledRelPermAtCritSat(G, init, opt); if ((opt.curve == FunctionCategory::CapPress) || (! haveScaleCRS)) { auto opt_cpy = opt; @@ -2364,6 +2532,9 @@ unscaledFunctionValues(const ECLGraph& G, ret.resize(uep.size()); for (auto n = uep.size(), i = 0*n; i < n; ++i) { + ret[i].disp.sat = uep[i].disp; + ret[i].disp.val = evalSF(static_cast(i), ret[i].disp.sat); + ret[i].max.sat = uep[i].high; ret[i].max.val = evalSF(static_cast(i), ret[i].max.sat); } @@ -2388,3 +2559,24 @@ unscaledFunctionValues(const ECLGraph& G, return ret; } + +// --------------------------------------------------------------------- +// Factory functions Opm::SatFunc::scaledConnate*() + +std::vector +Opm::SatFunc::scaledConnateGas(const ECLGraph& G, + const ECLInitFileData& init, + const CreateEPS::RawTableEndPoints& tep) +{ + return gridDefaultedVector(G, init, "SGL", tep.conn.gas, + [](const double s) { return s; }); +} + +std::vector +Opm::SatFunc::scaledConnateWater(const ECLGraph& G, + const ECLInitFileData& init, + const CreateEPS::RawTableEndPoints& tep) +{ + return gridDefaultedVector(G, init, "SWL", tep.conn.water, + [](const double s) { return s; }); +} diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLEndPointScaling.hpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLEndPointScaling.hpp index 42cc2aa679..4fbc84aba2 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLEndPointScaling.hpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLEndPointScaling.hpp @@ -67,19 +67,6 @@ namespace Opm { namespace SatFunc { double sat; }; - /// Policy for how to handle an invalid end-point scaling (e.g., if - /// lower and/or upper scaled saturations have nonsensical values - /// like -1.0E+20). - enum class InvalidEndpointBehaviour { - /// Use the unscaled value for this point. - UseUnscaled, - - /// Ignore this scaling request (e.g., produce no graphical - /// output for a scaled saturation function when the scaled - /// end-points are meaningless). - IgnorePoint, - }; - /// Convenience type alias. using SaturationPoints = std::vector; @@ -469,6 +456,7 @@ namespace Opm { namespace SatFunc { /// Constructor. explicit CritSatVerticalScaling(std::vector sdisp, std::vector fdisp, + std::vector smax, std::vector fmax); /// Destructor. @@ -573,13 +561,6 @@ namespace Opm { namespace SatFunc { /// auto eps = CreateEPS::fromECLOutput(G, init, opt); /// \endcode ::Opm::ECLPhaseIndex thisPh; - - /// How to handle an invalid end-point scaling (e.g., if lower - /// and/or upper scaled saturations have nonsensical values like - /// -1.0E+20). - EPSEvalInterface::InvalidEndpointBehaviour handle_invalid { - EPSEvalInterface::InvalidEndpointBehaviour::UseUnscaled - }; }; /// Collection of raw saturation table end points. @@ -669,9 +650,10 @@ namespace Opm { namespace SatFunc { /// \return EPS evaluator for the particular curve defined by /// the input options. static std::unique_ptr - fromECLOutput(const ECLGraph& G, - const ECLInitFileData& init, - const EPSOptions& opt); + fromECLOutput(const ECLGraph& G, + const ECLInitFileData& init, + const EPSOptions& opt, + const RawTableEndPoints& tep); /// Extract table end points relevant to a particular horizontal /// EPS evaluator from raw tabulated saturation functions. @@ -692,8 +674,8 @@ namespace Opm { namespace SatFunc { /// \code eval() \endcode of the \code EPSEvalInterface /// \endcode that corresponds to the input options. static std::vector - unscaledEndPoints(const RawTableEndPoints& ep, - const EPSOptions& opt); + unscaledEndPoints(const EPSOptions& opt, + const RawTableEndPoints& ep); }; /// Named constructors for vertical (value) scaling of saturation @@ -762,6 +744,16 @@ namespace Opm { namespace SatFunc { const SatFuncEvaluator& evalSF); }; }; + + std::vector + scaledConnateGas(const ECLGraph& G, + const ECLInitFileData& init, + const CreateEPS::RawTableEndPoints& tep); + + std::vector + scaledConnateWater(const ECLGraph& G, + const ECLInitFileData& init, + const CreateEPS::RawTableEndPoints& tep); }} // namespace Opm::SatFunc #endif // OPM_ECLENDPOINTSCALING_HEADER_INCLUDED diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLFluxCalc.cpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLFluxCalc.cpp index c4f9429d4f..f0fd31c91f 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLFluxCalc.cpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLFluxCalc.cpp @@ -18,16 +18,20 @@ */ #include + #include -#include #include +#include + #include #include +#include #include #include #include #include +#include #include #include @@ -174,7 +178,6 @@ namespace { }; } } - } // Anonymous namespace Opm @@ -208,6 +211,11 @@ namespace Opm ECLFluxCalc::flux(const ECLRestartData& rstrt, const ECLPhaseIndex phase) const { + if (! this->phaseIsActive(phase)) { + // Inactive phase. Return empty flux vector. + return {}; + } + // Obtain dynamic data. const auto dyn_data = this->phaseProperties(rstrt, phase); @@ -225,6 +233,11 @@ namespace Opm ECLFluxCalc::massflux(const ECLRestartData& rstrt, const ECLPhaseIndex phase) const { + if (! this->phaseIsActive(phase)) { + // Inactive phase. Return empty (mass) flux vector. + return {}; + } + // Obtain dynamic data. const auto dyn_data = this->phaseProperties(rstrt, phase); @@ -297,6 +310,19 @@ namespace Opm } + bool ECLFluxCalc::phaseIsActive(const ECLPhaseIndex phase) const + { + switch (phase) { + case ECLPhaseIndex::Aqua: return this->pvtWat_ != nullptr; + case ECLPhaseIndex::Liquid: return this->pvtOil_ != nullptr; + case ECLPhaseIndex::Vapour: return this->pvtGas_ != nullptr; + } + + throw std::invalid_argument { + "phaseIsActive(): Invalid Phase Identifier" + }; + } + ECLFluxCalc::DynamicData ECLFluxCalc::phaseProperties(const ECLRestartData& rstrt, @@ -319,41 +345,18 @@ namespace Opm // Allocate space for storing the cell values. dyn_data.density.assign(this->graph_.numCells(), 0.0); + // Extract phase saturation. + dyn_data.saturation = + ::Opm::phaseSaturation(this->graph_, rstrt, phase); + switch (phase) { case ECLPhaseIndex::Aqua: - dyn_data.saturation = this->graph_.rawLinearisedCellData(rstrt, "SWAT"); return this->watPVT(std::move(dyn_data)); case ECLPhaseIndex::Liquid: - dyn_data.saturation = this->graph_.rawLinearisedCellData(rstrt, "SOIL"); - if (!dyn_data.saturation.empty()) { - return this->oilPVT(rstrt, std::move(dyn_data)); - } else { - // SOIL vector not provided. Compute from SWAT and/or SGAS. - // may read two times - auto sw = this->graph_.rawLinearisedCellData(rstrt, "SWAT"); - auto sg = this->graph_.rawLinearisedCellData(rstrt, "SGAS"); - std::vector& so = dyn_data.saturation; - so.assign(this->graph_.numCells(), 1.0); - auto adjust_So_for_other_phase = - [&so](const std::vector& s) - { - std::transform(std::begin(so), std::end(so), - std::begin(s) , - std::begin(so), std::minus()); - }; - if (sg.size() == this->graph_.numCells()) { - adjust_So_for_other_phase(sg); - } - - if (sw.size() == this->graph_.numCells()) { - adjust_So_for_other_phase(sw); - } - return this->oilPVT(rstrt, std::move(dyn_data)); - } + return this->oilPVT(rstrt, std::move(dyn_data)); case ECLPhaseIndex::Vapour: - dyn_data.saturation = this->graph_.rawLinearisedCellData(rstrt, "SGAS"); return this->gasPVT(rstrt, std::move(dyn_data)); } @@ -362,7 +365,8 @@ namespace Opm }; } - double ECLFluxCalc::surfaceDensity(const ECLPhaseIndex phase) const{ + double ECLFluxCalc::surfaceDensity(const ECLPhaseIndex phase) const + { switch (phase) { case ECLPhaseIndex::Aqua: return this->pvtWat_->surfaceMassDensity(0); @@ -373,6 +377,11 @@ namespace Opm case ECLPhaseIndex::Vapour: return this->pvtGas_->surfaceMassDensity(0); } + + throw std::invalid_argument { + "Unsupported Phase Index " + + std::to_string(static_cast(phase)) + }; } diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLFluxCalc.hpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLFluxCalc.hpp index 341f91326a..d9e666ea3e 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLFluxCalc.hpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLFluxCalc.hpp @@ -63,13 +63,13 @@ namespace Opm /// graph.neighbours() \endcode. /// /// \param[in] rstrt ECL Restart data set from which to extract - /// relevant data per cell. + /// relevant data per cell. /// /// \param[in] phase Canonical phase for which to retrive flux. /// - /// \return Flux values corresponding to selected phase. - /// Empty if required data is missing. - /// Numerical values in SI units (rm^3/s). + /// \return Flux values corresponding to selected phase. Empty if + /// requisite data is missing. Numerical values in SI units + /// (rm^3/s). std::vector flux(const ECLRestartData& rstrt, const ECLPhaseIndex phase) const; @@ -78,20 +78,19 @@ namespace Opm /// graph.neighbours() \endcode. /// /// \param[in] rstrt ECL Restart data set from which to extract - /// relevant data per cell. + /// relevant data per cell. /// /// \param[in] phase Canonical phase for which to retrive flux. /// - /// \return Mass flux values corresponding to selected phase. - /// Empty if required data is missing. - /// Numerical values in SI units (kg/s). + /// \return Mass flux values corresponding to selected phase. Empty + /// if requisite data is missing. Numerical values in SI units + /// (kg/s). std::vector massflux(const ECLRestartData& rstrt, const ECLPhaseIndex phase) const; - /// Return type for the phaseProperties() method, - /// encapsulates dynamic properties for a single - /// phase. + /// Return type for the phaseProperties() method, encapsulates + /// dynamic properties for a single phase. struct DynamicData { std::vector pressure; @@ -103,27 +102,25 @@ namespace Opm /// Retrive dynamical properties of a single phase on all cells. /// /// \param[in] rstrt ECL Restart data set from which to extract - /// relevant data per cell. + /// relevant data per cell. /// /// \param[in] phase Canonical phase for which to retrive properties. /// - /// \return DynamicData struct containing cell-values for phase properties. - /// Numerical values in SI units (kg/s). + /// \return DynamicData struct containing cell-values for phase + /// properties. Numerical values in SI units (kg/s). DynamicData phaseProperties(const ECLRestartData& rstrt, const ECLPhaseIndex phase) const; /// Retrive the constant surface density of a phase. /// - /// \param[in] phase Canonical phase for which to retrive the surface density. + /// \param[in] phase Canonical phase for which to retrive the + /// surface density. /// /// \return Density of given phase at surface conditions. - /// Numerical value in SI units (kg/m^3). + /// Numerical value in SI units (kg/m^3). double surfaceDensity(const ECLPhaseIndex phase) const; - private: - - double singleFlux(const int connection, const DynamicData& dyn_data) const; @@ -131,6 +128,8 @@ namespace Opm const DynamicData& dyn_data) const; + bool phaseIsActive(const ECLPhaseIndex phase) const; + DynamicData gasPVT(const ECLRestartData& rstrt, DynamicData&& dyn_data) const; diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLPvtGas.cpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLPvtGas.cpp index fef7dd5140..c712476ee3 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLPvtGas.cpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLPvtGas.cpp @@ -90,6 +90,8 @@ namespace { class PVxGBase { public: + virtual ~PVxGBase() {} + virtual std::vector formationVolumeFactor(const std::vector& rv, const std::vector& pg) const = 0; diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLPvtOil.cpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLPvtOil.cpp index 362ae167f8..95e67c1260 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLPvtOil.cpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLPvtOil.cpp @@ -121,6 +121,15 @@ namespace { return std::make_pair(ToSI::disGas(*u), deadOilUnitConverter(*u)); } + + std::vector::size_type const_compr_index() + { +#if defined(LOGIHEAD_CONSTANT_OILCOMPR_INDEX) + return LOGIHEAD_CONSTANT_OILCOMPR_INDEX; +#else + return (39 - 1); // Reverse engineering... +#endif // LOGIHEAD_CONSTANT_OILCOMPR_INDEX + } } // --------------------------------------------------------------------- @@ -129,6 +138,8 @@ namespace { class PVxOBase { public: + virtual ~PVxOBase() {} + virtual std::vector formationVolumeFactor(const std::vector& rs, const std::vector& po) const = 0; @@ -200,12 +211,12 @@ class DeadOilConstCompr : public PVxOBase } private: - double po_ref_ { 1.0 }; - double fvf_ { 1.0 }; // B - double visc_ { 1.0 }; // mu - double Co_ { 1.0 }; + double po_ref_ { 1.0 }; + double fvf_ { 1.0 }; // B + double visc_ { 1.0 }; // mu + double Co_ { 1.0 }; double cv_ { 0.0 }; // Cv - double rhoS_ { 0.0 }; + double rhoS_ { 0.0 }; double recipFvf(const double po) const { @@ -243,20 +254,20 @@ class DeadOilConstCompr : public PVxOBase }; DeadOilConstCompr::DeadOilConstCompr(ElemIt xBegin, - ElemIt xEnd, - const ConvertUnits& convert, - std::vector& colIt) + ElemIt xEnd, + const ConvertUnits& convert, + std::vector& colIt) { // Recall: Table is // // [ Po, Bo, Co, mu_o, Cv ] // - // xBegin is Pw, colIt is remaining four columns. + // xBegin is Po, colIt is remaining four columns. - this->fvf_ = convert.column[0](*colIt[0]); // Bo - this->Co_ = convert.column[1](*colIt[1]); // Co + this->fvf_ = convert.column[0](*colIt[0]); // Bo + this->Co_ = convert.column[1](*colIt[1]); // Co this->visc_ = convert.column[2](*colIt[2]); // mu_o - this->cv_ = convert.column[3](*colIt[3]); // Cw - Cv + this->cv_ = convert.column[3](*colIt[3]); // Cv // Honour requirement that constructor advances column iterators. const auto N = std::distance(xBegin, xEnd); @@ -278,7 +289,6 @@ DeadOilConstCompr::DeadOilConstCompr(ElemIt xBegin, } } - // ===================================================================== class DeadOil : public PVxOBase @@ -405,7 +415,7 @@ class LiveOil : public PVxOBase namespace { std::vector> createDeadOil(const ::Opm::ECLPropTableRawData& raw, - const bool const_compr, + const bool const_compr, const int usys) { using PVTInterp = std::unique_ptr; @@ -502,7 +512,7 @@ namespace { std::vector> createPVTFunction(const ::Opm::ECLPropTableRawData& raw, - const bool const_compr, + const bool const_compr, const int usys) { if (raw.numPrimary == 0) { @@ -611,7 +621,7 @@ class Opm::ECLPVT::Oil::Impl Opm::ECLPVT::Oil::Impl:: Impl(const ECLPropTableRawData& raw, const int usys, - const bool const_compr, + const bool const_compr, std::vector rhoS) : eval_(createPVTFunction(raw, const_compr, usys)) , rhoS_(std::move(rhoS)) @@ -776,9 +786,8 @@ fromECLOutput(const ECLInitFileData& init) return OPtr{}; } - const auto& lh = init.keywordData(LOGIHEAD_KW); - const int LOGIHEAD_CONST_COMPR_INDEX = 38; - const bool is_const_compr = lh[LOGIHEAD_CONST_COMPR_INDEX]; + const auto& lh = init.keywordData(LOGIHEAD_KW); + const auto is_const_compr = static_cast(lh[const_compr_index()]); auto raw = ::Opm::ECLPropTableRawData{}; diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLResultData.cpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLResultData.cpp index d2e977cd5f..d0effa9510 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLResultData.cpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLResultData.cpp @@ -473,13 +473,13 @@ namespace { explicit InitFileSections(const ecl_file_type* init); struct Section { - Section(const ecl_file_view_type* blk) + Section(ecl_file_view_type* blk) : block (blk) , first_kw(Details::firstBlockKeyword(block)) {} - const ecl_file_view_type* block; - std::string first_kw; + ecl_file_view_type* block; + std::string first_kw; }; const std::vector
& sections() const @@ -502,7 +502,7 @@ namespace { } private: - const ecl_file_view_type* init_; + ecl_file_view_type* init_; std::vector
sect_; }; @@ -796,7 +796,7 @@ ECLImpl::InitFileSections::InitFileSections(const ecl_file_type* init) ? sectID - 1 : 0*sectID; // Main section 'sectID': [ start_kw, LGRSGONE ] - const auto* sect = + auto* sect = ecl_file_view_add_blockview2(this->init_, start_kw, end_kw, start_kw_occurrence); @@ -808,12 +808,12 @@ ECLImpl::InitFileSections::InitFileSections(const ecl_file_type* init) const auto occurrence = 0; // Main grid sub-section of 'sectID': [ start_kw, LGR ] - const auto* main_grid_sect = + auto* main_grid_sect = ecl_file_view_add_blockview2(sect, firstkw.c_str(), LGR_KW, occurrence); // LGR sub-section of 'sectID': [ LGR, LGRSGONE ] - const auto* lgr_sect = + auto* lgr_sect = ecl_file_view_add_blockview2(sect, LGR_KW, end_kw, occurrence); @@ -965,7 +965,7 @@ class Opm::ECLRestartData::Impl /// Saved original active view from host (prior to restricting view /// to single grid ID). - const ecl_file_view_type* save_; + ecl_file_view_type* save_; }; /// Casename prefix. Mostly to implement copy ctor. @@ -986,7 +986,7 @@ class Opm::ECLRestartData::Impl std::unique_ptr gridIDCache_; /// Current active result-set view. - mutable const ecl_file_view_type* activeBlock_{ nullptr }; + mutable ecl_file_view_type* activeBlock_{ nullptr }; /// Support for passing \code *this \endcode to ERT functions that /// require an \c ecl_file_type, particularly the function that selects @@ -1276,7 +1276,7 @@ class Opm::ECLInitFileData::Impl /// Sections of the INIT result set. ECLImpl::InitFileSections sections_; - mutable const ecl_file_view_type* activeBlock_{ nullptr }; + mutable ecl_file_view_type* activeBlock_{ nullptr }; /// Negative look-up cache for haveKeywordData() queries. mutable MissingKW missing_kw_; @@ -1415,6 +1415,10 @@ lookup(const std::string& vector, const std::string& gridName) const } } + // Status of 'vector' unknown for 'gridName'. Actually look for the + // vector in gridName's sections (main grid if gridName.empty(), + // otherwise named local grid). + if (gridName.empty()) { return this->lookupMainGrid(key); } diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLSaturationFunc.cpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLSaturationFunc.cpp index 522def78e6..134bc4e857 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLSaturationFunc.cpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLSaturationFunc.cpp @@ -48,6 +48,13 @@ #include namespace { + std::vector + gas_saturation(const ::Opm::ECLGraph& G, + const ::Opm::ECLRestartData& rstrt) + { + return G.rawLinearisedCellData(rstrt, "SGAS"); + } + std::vector oil_saturation(const std::vector& sg, const std::vector& sw, @@ -84,6 +91,13 @@ namespace { return so; } + std::vector + water_saturation(const ::Opm::ECLGraph& G, + const ::Opm::ECLRestartData& rstrt) + { + return G.rawLinearisedCellData(rstrt, "SWAT"); + } + std::vector satnumVector(const ::Opm::ECLGraph& G, const ::Opm::ECLInitFileData& init) @@ -101,17 +115,17 @@ namespace { Opm::FlowDiagnostics::Graph transformOilCurve(const Opm::FlowDiagnostics::Graph& curve, - const double So_offset) + const double max2PhaseSatSum) { auto Sx = std::vector{}; Sx.reserve(curve.first.size()); { const auto& So = curve.first; std::transform(So.rbegin(), So.rend(), std::back_inserter(Sx), - [So_offset](const double so) - { - return So_offset - so; - }); + [max2PhaseSatSum](const double so) + { + return max2PhaseSatSum - so; + }); } auto y = std::vector{ @@ -721,9 +735,9 @@ class Opm::ECLSaturationFunc::Impl void setOutputUnits(std::unique_ptr usys); std::vector - relperm(const ECLGraph& G, - const ECLRestartData& rstrt, - const ECLPhaseIndex p) const; + relperm(const ECLGraph& G, + const ECLRestartData& rstrt, + const ECLPhaseIndex p) const; std::vector getSatFuncCurve(const std::vector& func, @@ -758,8 +772,7 @@ class Opm::ECLSaturationFunc::Impl const ActPh& active) { auto opt = Create::EPSOptions{}; - opt.use3PtScaling = use3PtScaling; - opt.handle_invalid = SatFuncScaling::IEB::UseUnscaled; + opt.use3PtScaling = use3PtScaling; if (active.oil) { this->create_oil_eps(host, G, init, ep, active, opt); @@ -772,6 +785,22 @@ class Opm::ECLSaturationFunc::Impl if (active.wat) { this->create_wat_eps(host, G, init, ep, opt); } + + this->sgl_ = ::Opm::SatFunc::scaledConnateGas (G, init, ep); + this->swl_ = ::Opm::SatFunc::scaledConnateWater(G, init, ep); + } + + // --------------------------------------------- + // ---------- Scaled connate saturations ------- + + double scaledConnateGas(const int cell) const + { + return this->sgl_[cell]; + } + + double scaledConnateWater(const int cell) const + { + return this->swl_[cell]; } // --------------------------------------------- @@ -880,7 +909,7 @@ class Opm::ECLSaturationFunc::Impl const std::vector& sw, std::vector& kr) const { - this->vertScale(this->wat_.kr, rmap, sw,kr); + this->vertScale(this->wat_.kr, rmap, sw, kr); } void vertScalePcGO(const ECLRegionMapping& rmap, @@ -999,6 +1028,9 @@ class Opm::ECLSaturationFunc::Impl FullEPS gas_; FullEPS wat_; + std::vector sgl_; + std::vector swl_; + // ---------------------------------------------- // ------- End-point scaling (engine) ----------- @@ -1171,9 +1203,9 @@ class Opm::ECLSaturationFunc::Impl auto& eps = this->oil_in_og_; eps.scaling = Create::Horizontal:: - fromECLOutput(G, init, opt); + fromECLOutput(G, init, opt, ep); - eps.tep = this->endPoints(ep, opt); + eps.tep = this->endPoints(opt, ep); eps.vertfuncval = this-> vertFuncVal(G, init, ep, opt, [&host] @@ -1196,9 +1228,9 @@ class Opm::ECLSaturationFunc::Impl auto& eps = this->oil_in_ow_; eps.scaling = Create::Horizontal:: - fromECLOutput(G, init, opt); + fromECLOutput(G, init, opt, ep); - eps.tep = this->endPoints(ep, opt); + eps.tep = this->endPoints(opt, ep); eps.vertfuncval = this-> vertFuncVal(G, init, ep, opt, [&host] @@ -1234,9 +1266,9 @@ class Opm::ECLSaturationFunc::Impl auto& eps = this->gas_.kr; eps.scaling = Create::Horizontal:: - fromECLOutput(G, init, opt); + fromECLOutput(G, init, opt, ep); - eps.tep = this->endPoints(ep, opt); + eps.tep = this->endPoints(opt, ep); eps.vertfuncval = this-> vertFuncVal(G, init, ep, opt, [&host] @@ -1262,9 +1294,9 @@ class Opm::ECLSaturationFunc::Impl auto& eps = this->gas_.pc; eps.scaling = Create::Horizontal:: - fromECLOutput(G, init, opt); + fromECLOutput(G, init, opt, ep); - eps.tep = this->endPoints(ep, opt); + eps.tep = this->endPoints(opt, ep); eps.vertfuncval = this-> vertFuncVal(G, init, ep, opt, [&host] @@ -1300,9 +1332,9 @@ class Opm::ECLSaturationFunc::Impl auto& eps = this->wat_.kr; eps.scaling = Create::Horizontal:: - fromECLOutput(G, init, opt); + fromECLOutput(G, init, opt, ep); - eps.tep = this->endPoints(ep, opt); + eps.tep = this->endPoints(opt, ep); eps.vertfuncval = this-> vertFuncVal(G, init, ep, opt, [&host] @@ -1328,9 +1360,9 @@ class Opm::ECLSaturationFunc::Impl auto& eps = this->wat_.pc; eps.scaling = Create::Horizontal:: - fromECLOutput(G, init, opt); + fromECLOutput(G, init, opt, ep); - eps.tep = this->endPoints(ep, opt); + eps.tep = this->endPoints(opt, ep); eps.vertfuncval = this-> vertFuncVal(G, init, ep, opt, [&host] @@ -1339,6 +1371,11 @@ class Opm::ECLSaturationFunc::Impl return host.wat_->pcow(regID, { sat })[0]; }); + // Special case treatment of PCOW. Maximum value at minimum S. + for (auto& fval : *eps.vertfuncval) { + fval.max.val = std::max(fval.disp.val, fval.max.val); + } + eps.vertscaling = Create::Vertical:: fromECLOutput(G, init, opt, ep, *eps.vertfuncval); @@ -1349,10 +1386,11 @@ class Opm::ECLSaturationFunc::Impl } EndPtsPtr - endPoints(const RawTEP& ep, const Create::EPSOptions& opt) + endPoints(const Create::EPSOptions& opt, + const RawTEP& ep) { return EndPtsPtr { - new EPSEndPtVec(Create::Horizontal::unscaledEndPoints(ep, opt)) + new EPSEndPtVec(Create::Horizontal::unscaledEndPoints(opt, ep)) }; } @@ -1509,6 +1547,11 @@ class Opm::ECLSaturationFunc::Impl regOp(regID, rmap); } } + + double max2PSatSum(const RawCurve& fi, + const std::size_t regID, + const int cell, + const SatFuncScaling& scaling) const; }; Opm::ECLSaturationFunc::Impl::Impl(const ECLGraph& G, @@ -1788,11 +1831,13 @@ getSatFuncCurve(const std::vector& func, this->kroCurve(*oil_assoc.second, regID, fi.subsys, oil_assoc.first, scaling); - const auto So_off = (fi.subsys == RawCurve::SubSystem::OilGas) - ? oil_assoc.first.back() // Sg = Max{So} - So in G/O system - : 1.0; // Sw = 1.0 - So in O/W system + // Maximum attainable value of "So + S{g,w}" in pertinent + // two-phase system in this cell. Expected to be 1-SWL for G/O + // systems and 1-SGL (almost always == 1) for O/W systems. + const auto max2PhaseSatSum = + this->max2PSatSum(fi, regID, activeCell, scaling); - graph.push_back(transformOilCurve(kro, So_off)); + graph.push_back(transformOilCurve(kro, max2PhaseSatSum)); } break; @@ -1850,8 +1895,8 @@ kro(const ECLGraph& G, return kr; } - const auto& sg = G.rawLinearisedCellData(rstrt, "SGAS"); - const auto& sw = G.rawLinearisedCellData(rstrt, "SWAT"); + const auto& sg = gas_saturation(G, rstrt); + const auto& sw = water_saturation(G, rstrt); auto so_g = oil_saturation(sg, sw, G, rstrt); auto so_w = so_g; @@ -1948,12 +1993,15 @@ kroCurve(const ECLRegionMapping& rmap, if (enableVerticalSFScaling(scaling) && (this->eps_ != nullptr)) { + auto vkr_eval_sat = abscissas; + vkr_eval_sat.resize(so.size(), 1.0); + // Evaluate vertical scaling in input saturations. if (subsys == RawCurve::SubSystem::OilGas) { - this->eps_->vertScaleKrOG(rmap, so, kr); + this->eps_->vertScaleKrOG(rmap, vkr_eval_sat, kr); } else { - this->eps_->vertScaleKrOW(rmap, so, kr); + this->eps_->vertScaleKrOW(rmap, vkr_eval_sat, kr); } } @@ -1976,7 +2024,7 @@ krg(const ECLGraph& G, return kr; } - auto sg = G.rawLinearisedCellData(rstrt, "SGAS"); + auto sg = gas_saturation(G, rstrt); if (enableHorizontalEPS(scaling) && this->eps_) { this->eps_->scaleKrGas(this->rmap_, sg); @@ -2044,8 +2092,11 @@ krgCurve(const ECLRegionMapping& rmap, if (enableVerticalSFScaling(scaling) && (this->eps_ != nullptr)) { + auto vkr_eval_sat = abscissas; + vkr_eval_sat.resize(sg.size(), 1.0); + // Evaluate vertical scaling in input saturations. - this->eps_->vertScaleKrGas(rmap, sg, kr); + this->eps_->vertScaleKrGas(rmap, vkr_eval_sat, kr); } // FD::Graph == pair, vector> @@ -2093,8 +2144,11 @@ pcgoCurve(const ECLRegionMapping& rmap, if (enableVerticalSFScaling(scaling) && (this->eps_ != nullptr)) { + auto pcg_eval_sat = abscissas; + pcg_eval_sat.resize(sg.size(), 1.0); + // Evaluate vertical scaling in input saturations. - this->eps_->vertScalePcGO(rmap, sg, pc); + this->eps_->vertScalePcGO(rmap, pcg_eval_sat, pc); } if (this->usys_output_ != nullptr) { @@ -2122,7 +2176,7 @@ krw(const ECLGraph& G, return kr; } - auto sw = G.rawLinearisedCellData(rstrt, "SWAT"); + auto sw = water_saturation(G, rstrt); if (enableHorizontalEPS(scaling) && this->eps_) { this->eps_->scaleKrWat(this->rmap_, sw); @@ -2190,8 +2244,11 @@ krwCurve(const ECLRegionMapping& rmap, if (enableVerticalSFScaling(scaling) && (this->eps_ != nullptr)) { + auto vkr_eval_sat = abscissas; + vkr_eval_sat.resize(sw.size(), 1.0); + // Evaluate vertical scaling in input saturations. - this->eps_->vertScaleKrWat(rmap, sw, kr); + this->eps_->vertScaleKrWat(rmap, vkr_eval_sat, kr); } // FD::Graph == pair, vector> @@ -2239,8 +2296,11 @@ pcowCurve(const ECLRegionMapping& rmap, if (enableVerticalSFScaling(scaling) && (this->eps_ != nullptr)) { + auto pcw_eval_sat = abscissas; + pcw_eval_sat.resize(sw.size(), 1.0); + // Evaluate vertical scaling in input saturations. - this->eps_->vertScalePcOW(rmap, sw, pc); + this->eps_->vertScalePcOW(rmap, pcw_eval_sat, pc); } if (this->usys_output_ != nullptr) { @@ -2352,6 +2412,12 @@ extractRawTableEndPoints(const EPSEvaluator::ActPh& active) const ep.crit.oil_in_water = this->oil_->sowcr(); ep.smax.oil = this->oil_->somax(); } + else { + ep.conn.oil = zero; + ep.crit.oil_in_gas = zero; + ep.crit.oil_in_water = zero; + ep.smax.oil = zero; + } if (active.gas) { ep.conn.gas = this->gas_->sgco(); @@ -2370,14 +2436,72 @@ extractRawTableEndPoints(const EPSEvaluator::ActPh& active) const ep.smax.water = this->wat_->swmax(); } else { - ep.conn.water = zero; - ep.crit.water = zero; - ep.smax.water = zero; + auto swco = std::vector(zero.size()); + + std::transform(std::begin(ep.smax.oil), std::end(ep.smax.oil), + std::begin(ep.conn.gas), + std::begin(swco), + [](const double somax, const double sgco) + { + // Typically 1 - somax. + return 1.0 - (somax + sgco); + }); + + ep.conn.water = swco; + ep.crit.water = swco; + ep.smax.water = std::move(swco); } return ep; } +double +Opm::ECLSaturationFunc::Impl:: +max2PSatSum(const RawCurve& fi, + const std::size_t regID, + const int cell, + const SatFuncScaling& scaling) const +{ + auto smin = 0.0; + + if (fi.subsys == RawCurve::SubSystem::OilGas) { + // Max 2p Saturation sum = 1 - SWL + if (enableHorizontalEPS(scaling)) { + if (this->eps_ != nullptr) { + smin = this->eps_->scaledConnateWater(cell); + } + else { + throw std::logic_error { + "Cannot Activate EPS without Backing Object" + }; + } + } + else { + const auto swco = this->wat_->swco(); + smin = swco[regID - 1]; + } + } + else { + // Max 2p Saturation sum = 1 - SGL (almost always = 1) + if (enableHorizontalEPS(scaling)) { + if (this->eps_ != nullptr) { + smin = this->eps_->scaledConnateGas(cell); + } + else { + throw std::logic_error { + "Cannot Activate EPS without Backing Object" + }; + } + } + else { + const auto sgco = this->gas_->sgco(); + smin = sgco[regID - 1]; + } + } + + return 1.0 - smin; +} + // ===================================================================== Opm::ECLSaturationFunc:: @@ -2454,3 +2578,31 @@ getSatFuncCurve(const std::vector& func, { return this->pImpl_->getSatFuncCurve(func, activeCell, scaling); } + +// ===================================================================== + +std::vector +Opm::phaseSaturation(const ECLGraph& G, + const ECLRestartData& rstrt, + const ECLPhaseIndex phase) +{ + switch (phase) { + case ECLPhaseIndex::Aqua: + return water_saturation(G, rstrt); + + case ECLPhaseIndex::Liquid: { + const auto sg = gas_saturation(G, rstrt); + const auto sw = water_saturation(G, rstrt); + + return oil_saturation(sg, sw, G, rstrt); + } + + case ECLPhaseIndex::Vapour: + return gas_saturation(G, rstrt); + } + + throw std::invalid_argument { + "Unsupported Phase Index " + + std::to_string(static_cast(phase)) + }; +} diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLSaturationFunc.hpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLSaturationFunc.hpp index ff9926d0aa..811467125f 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLSaturationFunc.hpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/opm/utility/ECLSaturationFunc.hpp @@ -41,6 +41,34 @@ namespace Opm { class ECLRestartData; class ECLInitFileData; + /// Extract phase saturation of single phase for all active cells in all + /// grids. + /// + /// Handles the case of oil saturation being explicitly stored in a + /// result set or implicitly defined from the gas and/or water + /// saturations. + /// + /// \param[in] G Connected topology of current model's active cells. + /// Needed to linearise phase saturations (e.g., SOIL) that are + /// distributed on local grids to all of the model's active cells + /// (\code member function G.rawLinearisedCellData() \endcode). + /// + /// \param[in] rstrt ECLIPSE restart vectors. Result set view + /// assumed to be positioned at a particular report step of + /// interest. + /// + /// \param[in] phase Phase for which to extract the phase saturation + /// values. + /// + /// \return Phase saturation values of active phase \p phase for all + /// active cells in model \p G. Empty if phase \p phase is not + /// actually active in the current result set or if the saturation + /// values are not stored on the current report/restart step. + std::vector + phaseSaturation(const ECLGraph& G, + const ECLRestartData& rstrt, + const ECLPhaseIndex phase); + /// Gateway to engine for computing relative permeability values based /// on tabulated saturation functions in ECL output. class ECLSaturationFunc @@ -85,19 +113,12 @@ namespace Opm { Vertical = 1 << 1u, }; - using IEB = SatFunc::EPSEvalInterface::InvalidEndpointBehaviour; - SatFuncScaling() - : enable (Type::Horizontal | Type::Vertical) - , invalid(IEB::UseUnscaled) + : enable(Type::Horizontal | Type::Vertical) {} // Default: Use both Horizontal and Vertical if specified. unsigned char enable; - - // Default: Use unscaled values in case of invalid scaled - // saturations occurring in the result set. - IEB invalid; }; /// Constructor diff --git a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/tests/test_eclendpointscaling.cpp b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/tests/test_eclendpointscaling.cpp index b666f08109..3a65935ec4 100644 --- a/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/tests/test_eclendpointscaling.cpp +++ b/ThirdParty/custom-opm-flowdiag-app/opm-flowdiagnostics-applications/tests/test_eclendpointscaling.cpp @@ -31,9 +31,17 @@ #include +#include +#include +#include + +#include + #include #include #include +#include +#include #include namespace { @@ -70,6 +78,23 @@ namespace { return sp; } + std::vector + makeTable(const std::size_t ncol, + std::initializer_list data) + { + auto result = std::vector(data.size(), 0.0); + const auto nrows = data.size() / ncol; + + auto di = std::begin(data); + for (auto i = 0*nrows; i < nrows; ++i) { + for (auto j = 0*ncol; j < ncol; ++j, ++di) { + result[i + j*nrows] = *di; + } + } + + return result; + } + std::vector sw_core1d_example() { return { @@ -179,6 +204,192 @@ namespace { 1.000000000000000e+00, }; } + + std::vector sgfn_raw() + { + return makeTable(5, { + 0, 0, 0, 0, 0, + 5.000e-02, 1.655000000000000e-03, 0, 3.310000000000000e-02, 0, + 1.000e-01, 6.913000000000000e-03, 0, 1.051600000000000e-01, 0, + 1.500e-01, 1.621300000000000e-02, 0, 1.860000000000001e-01, 0, + 2.000e-01, 2.999000000000000e-02, 0, 2.755399999999998e-01, 0, + 2.500e-01, 4.865500000000000e-02, 0, 3.733000000000000e-01, 0, + 3.000e-01, 7.257300000000000e-02, 0, 4.783600000000001e-01, 0, + 3.500e-01, 1.020460000000000e-01, 0, 5.894600000000001e-01, 0, + 4.000e-01, 1.372870000000000e-01, 0, 7.048199999999992e-01, 0, + 4.500e-01, 1.784020000000000e-01, 0, 8.223000000000005e-01, 0, + 5.000e-01, 2.253680000000000e-01, 0, 9.393200000000004e-01, 0, + 5.500e-01, 2.780300000000000e-01, 0, 1.053239999999999e+00, 0, + 6.000e-01, 3.360930000000000e-01, 0, 1.161260000000001e+00, 0, + 6.500e-01, 3.991350000000000e-01, 0, 1.260840000000000e+00, 0, + 7.000e-01, 4.666310000000000e-01, 0, 1.349920000000002e+00, 0, + 7.500e-01, 5.380000000000000e-01, 0, 1.427379999999999e+00, 0, + 8.000e-01, 6.126650000000000e-01, 0, 1.493299999999998e+00, 0, + 8.500e-01, 6.901690000000000e-01, 0, 1.550080000000002e+00, 0, + 9.000e-01, 7.703950000000001e-01, 0, 1.604519999999999e+00, 0, + 9.500e-01, 8.542180000000000e-01, 0, 1.676460000000002e+00, 0, + 9.999e-01, 9.499000000000000e-01, 0, 1.917474949899796e+00, 0, + 1.000e+00, 9.500000000000000e-01, 0, 1.000000000000000e+00, 0, + }); + } + + std::vector sofn_raw() + { + return makeTable(5, { + 0, 0, 0, 0, 0, + 9.999999999998899e-05, 0, 0, 0, 0, + 5.000000000000004e-02, 1.000000000000000e-05, 7.000000000000000e-06, 1.999999999999998e-04, 1.402805611222443e-04, + 9.999999999999998e-02, 1.200000000000000e-04, 8.800000000000000e-05, 2.200000000000003e-03, 1.620000000000002e-03, + 1.500000000000000e-01, 5.100000000000000e-04, 3.840000000000000e-04, 7.799999999999994e-03, 5.919999999999996e-03, + 2.000000000000000e-01, 1.490000000000000e-03, 1.117000000000000e-03, 1.960000000000003e-02, 1.466000000000002e-02, + 2.500000000000000e-01, 3.460000000000000e-03, 2.597000000000000e-03, 3.939999999999996e-02, 2.959999999999997e-02, + 3.000000000000000e-01, 6.990000000000000e-03, 5.254000000000000e-03, 7.059999999999993e-02, 5.313999999999995e-02, + 3.500000000000000e-01, 1.284000000000000e-02, 9.662000000000000e-03, 1.170000000000002e-01, 8.816000000000013e-02, + 4.000000000000000e-01, 2.199000000000000e-02, 1.658600000000000e-02, 1.829999999999998e-01, 1.384799999999999e-01, + 4.500000000000000e-01, 3.572000000000000e-02, 2.703500000000000e-02, 2.746000000000004e-01, 2.089800000000003e-01, + 5.000000000000000e-01, 5.565000000000000e-02, 4.232400000000000e-02, 3.985999999999996e-01, 3.057799999999997e-01, + 5.500000000000000e-01, 8.373999999999999e-02, 6.415100000000000e-02, 5.617999999999994e-01, 4.365399999999996e-01, + 6.000000000000000e-01, 1.223700000000000e-01, 9.467100000000001e-02, 7.726000000000013e-01, 6.104000000000009e-01, + 6.500000000000000e-01, 1.741500000000000e-01, 1.365540000000000e-01, 1.035599999999999e+00, 8.376599999999993e-01, + 7.000000000000000e-01, 2.417700000000000e-01, 1.929920000000000e-01, 1.352400000000002e+00, 1.128760000000001e+00, + 7.500000000000000e-01, 3.275700000000000e-01, 2.675890000000000e-01, 1.715999999999998e+00, 1.491939999999999e+00, + 8.000000000000000e-01, 4.328600000000000e-01, 3.640430000000000e-01, 2.105799999999999e+00, 1.929079999999998e+00, + 8.500000000000000e-01, 5.571700000000001e-01, 4.855060000000000e-01, 2.486200000000004e+00, 2.429260000000003e+00, + 9.000000000000000e-01, 6.974600000000000e-01, 6.335620000000000e-01, 2.805799999999996e+00, 2.961119999999997e+00, + 9.500000000000000e-01, 8.478200000000000e-01, 8.068880000000000e-01, 3.007200000000005e+00, 3.466520000000006e+00, + 9.999000000000000e-01, 9.990000000000000e-01, 9.996137760000001e-01, 3.029659318637271e+00, 3.862239999999997e+00, + 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000111e+01, 3.862239999999221e+00, + }); + } + + std::vector swfn_raw() + { + return makeTable(5, { + 0, 0, 3.756330000000000e+00, 0, 0, + 1.00e-04, 0, 3.756320000000000e+00, 0, -1.000000000006551e-01, + 5.00e-02, 8.6000e-04, 1.869810000000000e+00, 1.723446893787575e-02, -3.780581162324650e+01, + 1.00e-01, 2.6300e-03, 1.237310000000000e+00, 3.539999999999999e-02, -1.265000000000000e+01, + 1.50e-01, 5.2400e-03, 9.182100000000000e-01, 5.220000000000001e-02, -6.382000000000001e+00, + 2.00e-01, 8.7700e-03, 7.245100000000000e-01, 7.059999999999998e-02, -3.873999999999998e+00, + 2.50e-01, 1.3380e-02, 5.934100000000000e-01, 9.220000000000000e-02, -2.622000000000000e+00, + 3.00e-01, 1.9270e-02, 4.981100000000000e-01, 1.178000000000000e-01, -1.906000000000000e+00, + 3.50e-01, 2.6720e-02, 4.251100000000000e-01, 1.490000000000001e-01, -1.460000000000000e+00, + 4.00e-01, 3.6080e-02, 3.669100000000000e-01, 1.871999999999998e-01, -1.163999999999998e+00, + 4.50e-01, 4.7810e-02, 3.191100000000000e-01, 2.346000000000000e-01, -9.560000000000004e-01, + 5.00e-01, 6.2500e-02, 2.788100000000000e-01, 2.938000000000001e-01, -8.060000000000003e-01, + 5.50e-01, 8.0900e-02, 2.440100000000000e-01, 3.679999999999997e-01, -6.959999999999993e-01, + 6.00e-01, 1.0394e-01, 2.135100000000000e-01, 4.608000000000007e-01, -6.100000000000008e-01, + 6.50e-01, 1.3277e-01, 1.863100000000000e-01, 5.765999999999993e-01, -5.439999999999996e-01, + 7.00e-01, 1.6869e-01, 1.616100000000000e-01, 7.184000000000011e-01, -4.940000000000007e-01, + 7.50e-01, 2.1302e-01, 1.390100000000000e-01, 8.865999999999988e-01, -4.519999999999998e-01, + 8.00e-01, 2.6667e-01, 1.180100000000000e-01, 1.073000000000000e+00, -4.199999999999994e-01, + 8.50e-01, 3.2918e-01, 9.830999999999999e-02, 1.250200000000001e+00, -3.940000000000007e-01, + 9.00e-01, 3.9706e-01, 7.961000000000000e-02, 1.357600000000000e+00, -3.739999999999996e-01, + 9.50e-01, 4.6103e-01, 6.161000000000000e-02, 1.279400000000001e+00, -3.600000000000005e-01, + 1.00e+00, 5.0000e-01, 4.408000000000000e-02, 7.793999999999994e-01, -3.505999999999996e-01, + }); + } + + Opm::ECLPropTableRawData makeSatFunc(std::vector data) + { + auto table = Opm::ECLPropTableRawData{}; + + table.data = std::move(data); + + table.numTables = 1; + table.numPrimary = 1; + table.numCols = 5; + table.numRows = table.data.size() / table.numCols; + + return table; + } + + Opm::SatFuncInterpolant sgfn() + { + // Input tables follow METRIC unit conventions. + const auto usys = Opm::ECLUnits::createUnitSystem(1); + + auto convert = Opm::SatFuncInterpolant::ConvertUnits{}; + + convert.indep = [](const double s) { return s; }; + + // Krg(Sg) + convert.column.emplace_back( + [](const double kr) { return kr; }); + + // Pcgo(Sg) + convert.column.push_back( + Opm::ECLPVT::CreateUnitConverter::ToSI::pressure(*usys)); + + // dKrg/dSg + convert.column.emplace_back( + [](const double dkr) { return dkr; }); + + // dPcgo/dSg + convert.column.push_back( + Opm::ECLPVT::CreateUnitConverter::ToSI::pressure(*usys)); + + return { + makeSatFunc(sgfn_raw()), convert + }; + } + + Opm::SatFuncInterpolant sofn() + { + auto convert = Opm::SatFuncInterpolant::ConvertUnits{}; + + convert.indep = [](const double s) { return s; }; + + // Krow(So) + convert.column.emplace_back( + [](const double kr) { return kr; }); + + // Krog(So) + convert.column.emplace_back( + [](const double kr) { return kr; }); + + // dKrow/dSo + convert.column.emplace_back( + [](const double dkr) { return dkr; }); + + // dKrow/dSo + convert.column.emplace_back( + [](const double dkr) { return dkr; }); + + return { + makeSatFunc(sofn_raw()), convert + }; + } + + Opm::SatFuncInterpolant swfn() + { + // Input tables follow METRIC unit conventions. + const auto usys = Opm::ECLUnits::createUnitSystem(1); + + auto convert = Opm::SatFuncInterpolant::ConvertUnits{}; + + convert.indep = [](const double s) { return s; }; + + // Krw(Sw) + convert.column.emplace_back( + [](const double kr) { return kr; }); + + // Pcow(Sw) + convert.column.push_back( + Opm::ECLPVT::CreateUnitConverter::ToSI::pressure(*usys)); + + // dKrw/dSw + convert.column.emplace_back( + [](const double dkr) { return dkr; }); + + // dPcow/dSw + convert.column.push_back( + Opm::ECLPVT::CreateUnitConverter::ToSI::pressure(*usys)); + + return { + makeSatFunc(swfn_raw()), convert + }; + } } // Namespace Anonymous // ===================================================================== @@ -625,6 +836,185 @@ BOOST_AUTO_TEST_CASE (ScaledBoth) BOOST_AUTO_TEST_SUITE_END () +// ===================================================================== + +BOOST_AUTO_TEST_SUITE (HorizontalScaling_SatFuncCurves) + +BOOST_AUTO_TEST_CASE (KrGas_2Pt) +{ + const auto interp = sgfn(); + + using Interp = std::remove_cv< + std::remove_reference::type + >::type; + + const auto SG = std::vector{ + 0.0, 0.025, 0.05, 0.075, 0.1 , 0.125, 0.15 , 0.175, + 0.2, 0.225, 0.25, 0.275, 0.3 , 0.325, 0.35 , 0.375, + 0.4, 0.425, 0.45, 0.475, 0.49995, 0.5, + }; + + // Live Sg in [0, 0.5]. Map to [0, 1] for table lookup + const auto eps = ::Opm::SatFunc:: + TwoPointScaling{ { 0.0 }, { 0.5 } }; + + const auto tep = ::Opm::SatFunc::EPSEvalInterface::TableEndPoints { + interp.connateSat()[0] , // low + interp.connateSat()[0] , // disp (ignored) + interp.maximumSat()[0] // max + }; + + // Forward: Scaled SG -> Lookup/Table sg + { + const auto expect = interp.saturationPoints(Interp::InTable{0}); + const auto sg = eps.eval(tep, associate(SG)); + + check_is_close(sg, expect); + } + + // Reverse: Lookup/Table sg -> Scaled SG + { + const auto sg = interp.saturationPoints(Interp::InTable{0}); + const auto scaled = eps.reverse(tep, associate(sg)); + + check_is_close(scaled, SG); + } +} + +BOOST_AUTO_TEST_CASE (KrOW_3pt) +{ + const auto interp = sofn(); + + using Interp = std::remove_cv< + std::remove_reference::type + >::type; + + const auto swl = 0.1; + const auto swcr = 0.1; // Swcr == Swco in table. + const auto sgl = 0.0; + + // Scaled end-points: + // SOWCR = 0.2, SWCR = 0.25, SWL = 0.15, SGL = 0 + // => Mobile So in [ 0.2, 0.85 ], Sr = 0.75. + + const auto eps = ::Opm::SatFunc:: + ThreePointScaling{ { 0.2 }, { 0.75 }, { 0.85 } }; + + const auto tep = ::Opm::SatFunc::EPSEvalInterface::TableEndPoints { + interp.criticalSat(Interp::ResultColumn{0})[0], // low + 1.0 - (swcr + sgl), // disp (Sr) + 1.0 - (swl + sgl), // max + }; + + // Forward: Scaled SO -> Lookup/Table so. + { + const auto SO = std::vector { + 0.0, 0.05, 0.1, 0.15, + + // ------------ Sowcr ----------------- + + 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, + 0.5, 0.55, 0.6, 0.65, 0.7, 0.725, 0.749, + + // ------------ Sr -------------------- + + 0.75, 0.7501, 0.8, 0.825, 0.85, + }; + + const auto so = eps.eval(tep, associate(SO)); + + const auto expect = std::vector{ + // so = Sowcr. (SO < SLO) + + 9.9999999999988987e-05, // SO = 0.0 + 9.9999999999988987e-05, // SO = 0.05 + 9.9999999999988987e-05, // SO = 0.1 + 9.9999999999988987e-05, // SO = 0.15 + + // ------------ SLO ------------------ + + // so = tep.low + t*(tep.disp - tep.low) + // = 1.0e-4 + t*(0.9 - 1.0e-4) + // + // t = (SO - SLO) / (SR - SLO) + // = (SO - 0.2) / (0.75 - 0.2) + + 9.9999999999988987e-05, // SO = 0.2 + 0.081909090909090876, // SO = 0.25 + 0.16371818181818176, // SO = 0.3 + 0.24552727272727265, // SO = 0.35 + 0.32733636363636365, // SO = 0.4 + 0.40914545454545453, // SO = 0.45 + 0.49095454545454542, // SO = 0.5 + 0.57276363636363636, // SO = 0.55 + 0.6545727272727272, // SO = 0.6 + 0.73638181818181814, // SO = 0.65 + 0.81819090909090897, // SO = 0.7 + 0.85909545454545433, // SO = 0.725 + 0.89836381818181799, // SO = 0.749 + + // ------------ Sr -------------------- + + // Everything below here maps to Somax (=1-Swco) because the + // 'tep' data says that Sdisp == Smax in the (purported) input + // table. The actual SOFN data (sofn_raw()) does not account + // for Swco = 0.1 (> 0) and therefore provides satfunc values + // for So > 0.9. + + 0.90000000000000002, // SO = 0.75 + 0.90000000000000002, // SO = 0.751 + 0.90000000000000002, // SO = 0.8 + 0.90000000000000002, // SO = 0.825 + 0.90000000000000002, // SO = 0.85 + }; + + check_is_close(so, expect); + } + + // Reverse: Lookup/Table so -> Scaled SO. + // + // Note that "tep.disp" is equal to "tep.high" in the input table. In + // this particular case, the reverse scaling will map high saturation + // values to 'Sr' rather than the maximum mobile So (= 0.85) in order to + // enable distinguishing scaled critical saturation from scaled maximum + // saturation for purpose of converting to "regular" phase saturations + // (i.e., SW or SG). + { + const auto SO = std::vector { + 0.20000000000000001, // so = 0 + 0.20000000000000001, // so = 9.9999999999988987e-05 + 0.23049783309256588, // so = 0.050000000000000037 + 0.2610567840871208, // so = 0.099999999999999978 + 0.29161573508167576, // so = 0.14999999999999999 + 0.32217468607623073, // so = 0.20000000000000001 + 0.35273363707078564, // so = 0.25 + 0.38329258806534061, // so = 0.29999999999999999 + 0.41385153905989558, // so = 0.34999999999999998 + 0.44441049005445055, // so = 0.40000000000000002 + 0.47496944104900546, // so = 0.45000000000000001 + 0.50552839204356048, // so = 0.5 + 0.53608734303811545, // so = 0.55000000000000004 + 0.56664629403267042, // so = 0.59999999999999998 + 0.59720524502722527, // so = 0.65000000000000002 + 0.62776419602178024, // so = 0.69999999999999996 + 0.6583231470163351, // so = 0.75 + 0.68888209801089018, // so = 0.80000000000000004 + 0.71944104900544503, // so = 0.84999999999999998 + 0.75, // so = 0.90000000000000002 + 0.75, // so = 0.94999999999999996 + 0.75, // so = 0.99990000000000001 + 0.75, // so = 1 + }; + + const auto so = interp.saturationPoints(Interp::InTable{0}); + const auto scaled = eps.reverse(tep, associate(so)); + + check_is_close(scaled, SO); + } +} + +BOOST_AUTO_TEST_SUITE_END () + // ===================================================================== // Three-point (alternative) scaling, applicable to relperm only. // --------------------------------------------------------------------- @@ -955,11 +1345,12 @@ BOOST_AUTO_TEST_CASE (Sw2_Regular) SFPt{ 0.9, 0.81 }, // Maximum }; - // Scaled residual displacement sat: 0.7 + // Scaled residual displacement sat: 0.7 (unchanged) // Scaled Kr at Scaled Sr (KRxR): 0.6 + // Scaled maximum saturation: 0.9 (unchanged) // Scaled Kr at Smax: (KRx) 0.7 const auto scaler = Opm::SatFunc:: - CritSatVerticalScaling({ 0.71 }, { 0.6 }, { 0.7 }); + CritSatVerticalScaling({ 0.71 }, { 0.6 }, { 0.9 }, { 0.7 }); const auto y = scaler.vertScale(f, sw, kr); @@ -1005,7 +1396,7 @@ BOOST_AUTO_TEST_CASE (Core1D_Coincident_FVal) }; const auto scaler = Opm::SatFunc:: - CritSatVerticalScaling({ 0.93 }, { 0.9 }, { 1.0 }); + CritSatVerticalScaling({ 0.93 }, { 0.9 }, { 1.0 }, { 1.0 }); const auto y = scaler.vertScale(f, s, kr); @@ -1065,3 +1456,149 @@ BOOST_AUTO_TEST_CASE (Core1D_Coincident_FVal) } BOOST_AUTO_TEST_SUITE_END () + +// ===================================================================== + +BOOST_AUTO_TEST_SUITE (VerticalScaling_SatFuncCurves) + +BOOST_AUTO_TEST_CASE (Pcow_2Pt) +{ + using SFPt = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues::Point; + using SFVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues; + + const auto interp = swfn(); + + using Interp = std::remove_cv< + std::remove_reference::type + >::type; + + using ImportedOpm::unit::barsa; + + // Maximum Pcow reset to 10 barsa. + const auto vscale = ::Opm::SatFunc::PureVerticalScaling { + { 10.0*barsa } + }; + + const auto sw = interp.saturationPoints(Interp::InTable{0}); + const auto pc = interp // Pc_ow = ResultColumn{1} + .interpolate(Interp::InTable{0}, Interp::ResultColumn{1}, sw); + + const auto f = SFVal{ + SFPt{ 1.0, 0.04408*barsa }, // Displacement + SFPt{ 0.0, 3.75633*barsa }, // Maximum + }; + + const auto PC = vscale.vertScale(f, associate(sw), pc); + + const auto expect = std::vector { // pc * (10.0 / 3.75633) + 1000000, + 999997.33782708121, + 497775.75452635949, + 329393.31741353922, + 244443.37957527695, + 192877.09013851287, + 157976.00317331014, + 132605.49525733895, + 113171.63295024665, + 97677.786562948415, + 84952.60001118113, + 74224.043148498662, + 64959.681391145081, + 56840.053988866792, + 49598.943649785826, + 43023.376540399804, + 37006.865743957533, + 31416.302614520024, + 26171.821964523886, + 21193.558606405721, + 16401.64735260214, + 11734.85822598121, + }; +} + +BOOST_AUTO_TEST_CASE (KrOG_3Pt) +{ + using SFPt = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues::Point; + using SFVal = ::Opm::SatFunc::VerticalScalingInterface::FunctionValues; + + const auto interp = sofn(); + + using Interp = std::remove_cv< + std::remove_reference::type + >::type; + + const auto so = interp.saturationPoints(Interp::InTable{0}); + const auto krog = interp // krog = ResultColumn{1} + .interpolate(Interp::InTable{0}, Interp::ResultColumn{1}, so); + + const auto f = SFVal{ + SFPt{ 0.6, 0.094671 }, // Displacement + SFPt{ 1.0, 1.0 }, // Maximum + }; + + const auto vscale = ::Opm::SatFunc::CritSatVerticalScaling { + // s , Kr + { 0.6 }, { 0.25 }, + { 1.0 }, { 0.6 } + }; + + const auto KROG = vscale.vertScale(f, associate(so), krog); + + const auto expect = std::vector { + // Left interval (So <= Sr = f.disp.sat = 0.6) + // + // Pure vertical scaling (multiply by a constant factor). + // + // Kr = Kr(So) * (KRORG / Kr(Sr; table)) + // = Kr(So) * (KRORG / f.disp.val) + // = Kr(So) * (0.25 / 0.094671) + // + 0, // So = 0, Kr(So) = 0, + 0, // So = 1.0e-4 Kr(So) = 0, + 1.8485069345417287e-05, // So = 0.05 Kr(So) = 7.0000e-06 + 0.00023238372891381731, // So = 0.1 Kr(So) = 8.8000e-05 + 0.0010140380898057484, // So = 0.15 Kr(So) = 3.8400e-04 + 0.0029496889226901584, // So = 0.2 Kr(So) = 1.1170e-03 + 0.0068579607271498132, // So = 0.25 Kr(So) = 2.5970e-03 + 0.013874364905831774, // So = 0.3 Kr(So) = 5.2540e-03 + 0.025514677145060262, // So = 0.35 Kr(So) = 9.6620e-03 + 0.043799051451870158, // So = 0.4 Kr(So) = 1.6586e-02 + 0.071391978536193765, // So = 0.45 Kr(So) = 2.7035e-02 + 0.11176601071077732, // So = 0.5 Kr(So) = 4.2324e-02 + 0.16940509765398062, // So = 0.55 Kr(So) = 6.4151e-02 + 0.25, // So = 0.6 Kr(So) = 9.4671e-02 + + // ------------------------------------------ + // + // Right interval (So >= Sr) + // + // Scaled Kr values defined by linear function between relperm + // points (Kr(Sr),KRORG) and (Krmax,KRO) + // + // Kr(So) - Kr(Sr) + // Kr = KRORG + ----------------- (KRO - KRORG) + // Krmax - Kr(Sr) + // + // Kr(So) - f.disp.val + // = KRORG + ------------------------ (KRO - KRORG) + // f.max.val - f.disp.val + // + // Kr(So) - 0.094671 + // = 0.25 + ------------------- (0.6 - 0.25) + // 1 - 0.094671 + // + 0.26619195894531161, // So = 0.65 Kr(So) = 0.136554 + 0.28801087781347995, // So = 0.7 Kr(So) = 0.192992 + 0.31685006224256596, // So = 0.75 Kr(So) = 0.267589 + 0.35413915825075742, // So = 0.8 Kr(So) = 0.364043 + 0.40109672837167476, // So = 0.85 Kr(So) = 0.485506 + 0.45833514667043695, // So = 0.9 Kr(So) = 0.633562 + 0.52534294162674566, // So = 0.95 Kr(So) = 0.806888 + 0.59985068588325352, // So = 0.9999 Kr(So) = 0.999613776 + 0.59999999999999998, // So = 1.0 Kr(So) = 1.0 + }; + + check_is_close(KROG, expect); +} + +BOOST_AUTO_TEST_SUITE_END () diff --git a/ThirdParty/custom-opm-flowdiag-app/opmCore/opm/parser/eclipse/Units/Units.hpp b/ThirdParty/custom-opm-flowdiag-app/opmCore/opm/parser/eclipse/Units/Units.hpp deleted file mode 100644 index cc1dde7e66..0000000000 --- a/ThirdParty/custom-opm-flowdiag-app/opmCore/opm/parser/eclipse/Units/Units.hpp +++ /dev/null @@ -1,326 +0,0 @@ -//=========================================================================== -// -// File: Units.hpp -// -// Created: Thu Jul 2 09:19:08 2009 -// -// Author(s): Halvor M Nilsen -// -// $Date$ -// -// $Revision$ -// -//=========================================================================== - -/* -Copyright 2009, 2010, 2011, 2012 SINTEF ICT, Applied Mathematics. -Copyright 2009, 2010, 2011, 2012 Statoil ASA. - -This file is part of the Open Porous Media project (OPM). - -OPM is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -OPM is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with OPM. If not, see . -*/ - -#ifndef OPM_UNITS_HEADER -#define OPM_UNITS_HEADER - -/** -The unit sets emplyed in ECLIPSE, in particular the FIELD units, -are quite inconsistent. Ideally one should choose units for a set -of base quantities like Mass,Time and Length and then derive the -units for e.g. pressure and flowrate in a consisten manner. However -that is not the case; for instance in the metric system we have: - -[Length] = meters -[time] = days -[mass] = kg - -This should give: - -[Pressure] = [mass] / ([length] * [time]^2) = kg / (m * days * days) - -Instead pressure is given in Bars. When it comes to FIELD units the -number of such examples is long. -*/ -namespace Opm { -namespace prefix - /// Conversion prefix for units. -{ -constexpr const double micro = 1.0e-6; /**< Unit prefix [\f$\mu\f$] */ -constexpr const double milli = 1.0e-3; /**< Unit prefix [m] */ -constexpr const double centi = 1.0e-2; /**< Non-standard unit prefix [c] */ -constexpr const double deci = 1.0e-1; /**< Non-standard unit prefix [d] */ -constexpr const double kilo = 1.0e3; /**< Unit prefix [k] */ -constexpr const double mega = 1.0e6; /**< Unit prefix [M] */ -constexpr const double giga = 1.0e9; /**< Unit prefix [G] */ -} // namespace prefix - -namespace unit - /// Definition of various units. - /// All the units are defined in terms of international standard - /// units (SI). Example of use: We define a variable \c k which - /// gives a permeability. We want to set \c k to \f$1\,mD\f$. - /// \code - /// using namespace Opm::unit - /// double k = 0.001*darcy; - /// \endcode - /// We can also use one of the prefixes defined in Opm::prefix - /// \code - /// using namespace Opm::unit - /// using namespace Opm::prefix - /// double k = 1.0*milli*darcy; - /// \endcode -{ -///\name Common powers -/// @{ -constexpr double square(double v) { return v * v; } -constexpr double cubic (double v) { return v * v * v; } -/// @} - -// -------------------------------------------------------------- -// Basic (fundamental) units and conversions -// -------------------------------------------------------------- - -/// \name Length -/// @{ -constexpr const double meter = 1; -constexpr const double inch = 2.54 * prefix::centi*meter; -constexpr const double feet = 12 * inch; -/// @} - -/// \name Time -/// @{ -constexpr const double second = 1; -constexpr const double minute = 60 * second; -constexpr const double hour = 60 * minute; -constexpr const double day = 24 * hour; -constexpr const double year = 365 * day; -/// @} - -/// \name Volume -/// @{ -constexpr const double gallon = 231 * cubic(inch); -constexpr const double stb = 42 * gallon; -constexpr const double liter = 1 * cubic(prefix::deci*meter); -/// @} - -/// \name Mass -/// @{ -constexpr const double kilogram = 1; -constexpr const double gram = 1.0e-3 * kilogram; -// http://en.wikipedia.org/wiki/Pound_(mass)#Avoirdupois_pound -constexpr const double pound = 0.45359237 * kilogram; -/// @} - -// -------------------------------------------------------------- -// Standardised constants -// -------------------------------------------------------------- - -/// \name Standardised constant -/// @{ -constexpr const double gravity = 9.80665 * meter/square(second); -/// @} - -// -------------------------------------------------------------- -// Derived units and conversions -// -------------------------------------------------------------- - -/// \name Force -/// @{ -constexpr const double Newton = kilogram*meter / square(second); // == 1 -constexpr const double dyne = 1e-5*Newton; -constexpr const double lbf = pound * gravity; // Pound-force - /// @} - - /// \name Pressure - /// @{ -constexpr const double Pascal = Newton / square(meter); // == 1 -constexpr const double barsa = 100000 * Pascal; -constexpr const double atm = 101325 * Pascal; -constexpr const double psia = lbf / square(inch); -/// @} - -/// \name Temperature. This one is more complicated -/// because the unit systems used by Eclipse (i.e. degrees -/// Celsius and degrees Fahrenheit require to add or -/// subtract an offset for the conversion between from/to -/// Kelvin -/// @{ -constexpr const double degCelsius = 1.0; // scaling factor °C -> K -constexpr const double degCelsiusOffset = 273.15; // offset for the °C -> K conversion - -constexpr const double degFahrenheit = 5.0/9; // scaling factor °F -> K -constexpr const double degFahrenheitOffset = 255.37; // offset for the °C -> K conversion - /// @} - - /// \name Viscosity - /// @{ -constexpr const double Pas = Pascal * second; // == 1 -constexpr const double Poise = prefix::deci*Pas; -/// @} - -namespace perm_details { -constexpr const double p_grad = atm / (prefix::centi*meter); -constexpr const double area = square(prefix::centi*meter); -constexpr const double flux = cubic (prefix::centi*meter) / second; -constexpr const double velocity = flux / area; -constexpr const double visc = prefix::centi*Poise; -constexpr const double darcy = (velocity * visc) / p_grad; -// == 1e-7 [m^2] / 101325 -// == 9.869232667160130e-13 [m^2] -} -/// \name Permeability -/// @{ -/// -/// A porous medium with a permeability of 1 darcy permits a flow (flux) -/// of \f$1\,\mathit{cm}^3/s\f$ of a fluid with viscosity -/// \f$1\,\mathit{cP}\f$ (\f$1\,mPa\cdot s\f$) under a pressure gradient -/// of \f$1\,\mathit{atm}/\mathit{cm}\f$ acting across an area of -/// \f$1\,\mathit{cm}^2\f$. -/// -constexpr const double darcy = perm_details::darcy; -/// @} - -/** -* Unit conversion routines. -*/ -namespace convert { -/** -* Convert from external units of measurements to equivalent -* internal units of measurements. Note: The internal units of -* measurements are *ALWAYS*, and exclusively, SI. -* -* Example: Convert a double @c kx, containing a permeability value -* in units of milli-darcy (mD) to the equivalent value in SI units -* (i.e., \f$m^2\f$). -* \code -* using namespace Opm::unit; -* using namespace Opm::prefix; -* convert::from(kx, milli*darcy); -* \endcode -* -* @param[in] q Physical quantity. -* @param[in] unit Physical unit of measurement. -* @return Value of @c q in equivalent SI units of measurements. -*/ -constexpr double from(const double q, const double unit) -{ - return q * unit; -} - -/** -* Convert from internal units of measurements to equivalent -* external units of measurements. Note: The internal units of -* measurements are *ALWAYS*, and exclusively, SI. -* -* Example: Convert a std::vector p, containing -* pressure values in the SI unit Pascal (i.e., unit::Pascal) to the -* equivalent values in Psi (unit::psia). -* \code -* using namespace Opm::unit; -* std::transform(p.begin(), p.end(), p.begin(), -* boost::bind(convert::to, _1, psia)); -* \endcode -* -* @param[in] q Physical quantity, measured in SI units. -* @param[in] unit Physical unit of measurement. -* @return Value of @c q in unit unit. -*/ -constexpr double to(const double q, const double unit) -{ - return q / unit; -} -} // namespace convert -} - -namespace Metric { -using namespace prefix; -using namespace unit; -constexpr const double Pressure = barsa; -constexpr const double Temperature = degCelsius; -constexpr const double TemperatureOffset = degCelsiusOffset; -constexpr const double AbsoluteTemperature = degCelsius; // actually [K], but the these two are identical -constexpr const double Length = meter; -constexpr const double Time = day; -constexpr const double Mass = kilogram; -constexpr const double Permeability = milli*darcy; -constexpr const double Transmissibility = centi*Poise*cubic(meter)/(day*barsa); -constexpr const double LiquidSurfaceVolume = cubic(meter); -constexpr const double GasSurfaceVolume = cubic(meter); -constexpr const double ReservoirVolume = cubic(meter); -constexpr const double GasDissolutionFactor = GasSurfaceVolume/LiquidSurfaceVolume; -constexpr const double OilDissolutionFactor = LiquidSurfaceVolume/GasSurfaceVolume; -constexpr const double Density = kilogram/cubic(meter); -constexpr const double PolymerDensity = kilogram/cubic(meter); -constexpr const double Salinity = kilogram/cubic(meter); -constexpr const double Viscosity = centi*Poise; -constexpr const double Timestep = day; -constexpr const double SurfaceTension = dyne/(centi*meter); -} - - -namespace Field { -using namespace prefix; -using namespace unit; -constexpr const double Pressure = psia; -constexpr const double Temperature = degFahrenheit; -constexpr const double TemperatureOffset = degFahrenheitOffset; -constexpr const double AbsoluteTemperature = degFahrenheit; // actually [°R], but the these two are identical -constexpr const double Length = feet; -constexpr const double Time = day; -constexpr const double Mass = pound; -constexpr const double Permeability = milli*darcy; -constexpr const double Transmissibility = centi*Poise*stb/(day*psia); -constexpr const double LiquidSurfaceVolume = stb; -constexpr const double GasSurfaceVolume = 1000*cubic(feet); -constexpr const double ReservoirVolume = stb; -constexpr const double GasDissolutionFactor = GasSurfaceVolume/LiquidSurfaceVolume; -constexpr const double OilDissolutionFactor = LiquidSurfaceVolume/GasSurfaceVolume; -constexpr const double Density = pound/cubic(feet); -constexpr const double PolymerDensity = pound/stb; -constexpr const double Salinity = pound/stb; -constexpr const double Viscosity = centi*Poise; -constexpr const double Timestep = day; -constexpr const double SurfaceTension = dyne/(centi*meter); -} - - -namespace Lab { -using namespace prefix; -using namespace unit; -constexpr const double Pressure = atm; -constexpr const double Temperature = degCelsius; -constexpr const double TemperatureOffset = degCelsiusOffset; -constexpr const double AbsoluteTemperature = degCelsius; // actually [K], but the these two are identical -constexpr const double Length = centi*meter; -constexpr const double Time = hour; -constexpr const double Mass = gram; -constexpr const double Permeability = milli*darcy; -constexpr const double Transmissibility = centi*Poise*cubic(centi*meter)/(hour*atm); -constexpr const double LiquidSurfaceVolume = cubic(centi*meter); -constexpr const double GasSurfaceVolume = cubic(centi*meter); -constexpr const double ReservoirVolume = cubic(centi*meter); -constexpr const double GasDissolutionFactor = GasSurfaceVolume/LiquidSurfaceVolume; -constexpr const double OilDissolutionFactor = LiquidSurfaceVolume/GasSurfaceVolume; -constexpr const double Density = gram/cubic(centi*meter); -constexpr const double PolymerDensity = gram/cubic(centi*meter); -constexpr const double Salinity = gram/cubic(centi*meter); -constexpr const double Viscosity = centi*Poise; -constexpr const double Timestep = hour; -constexpr const double SurfaceTension = dyne/(centi*meter); -} - -} - -#endif // OPM_UNITS_HEADER diff --git a/doc/command_file.plantuml b/doc/command_file.plantuml new file mode 100644 index 0000000000..109c3be8c8 --- /dev/null +++ b/doc/command_file.plantuml @@ -0,0 +1,40 @@ +@startuml +left to right direction + +class RiaArgumentParser { + parseArguments(); + executeCommandFile(); +} + +class RicfCommandFileExecutor { + executeCommands(); + prepareFileCommandsForExecution(); +} + +class RicfCommandFileReader { + readCommands(); +} + +class RicfObjectCapability { + readFields(); +} + +package "Command Objects" { + +class RicfCommandObject { + execute(); +} + + RicfCommandObject <|-- RicfOpenProject + RicfCommandObject <|-- RicfSetExportFolder +} + +RicfObjectCapability <|-- RicfCommandObject + +RiaApplication -> RiaArgumentParser +RiaArgumentParser -> RicfCommandFileExecutor +RicfCommandFileExecutor --> RicfCommandObject +RicfCommandFileExecutor -> RicfCommandFileReader +RicfCommandFileReader --> RicfObjectCapability + +@enduml diff --git a/doc/observed_data.plantuml b/doc/observed_data.plantuml deleted file mode 100644 index 579c39b725..0000000000 --- a/doc/observed_data.plantuml +++ /dev/null @@ -1,28 +0,0 @@ -@startuml -left to right direction - - -RifSummaryReaderInterface <|- RifReaderEclipseSummary -RifSummaryReaderInterface <|- RifColumnBasedAsciiData -RifSummaryReaderInterface <|- RifColumnBasedUserData -RifSummaryReaderInterface <|- RifKeywordVectorUserData - -RifColumnBasedAsciiData *-- "N" RifColumnBasedAsciiDataParser -RifColumnBasedUserData *-- "1" RifColumnBasedUserDataParser -RifKeywordVectorUserData *-- "1" RifKeywordVectorUserDataParser - -RimSummaryCase <|-- RimFileSummaryCase -RimSummaryCase <|-- RimGridSummaryCase -RimSummaryCase <|-- RimObservedData - -RimObservedData <|-- RimObservedEclipseUserData -RimObservedData <|-- RimAsciiColumnBasedData - -RimObservedEclipseUserData *--> RifSummaryReaderInterface - -RimAsciiColumnBasedData *--> RifColumnBasedAsciiData -RimFileSummaryCase *--> RifReaderEclipseSummary -RimGridSummaryCase *--> RifReaderEclipseSummary - - -@enduml diff --git a/doc/summary_cases_and_readers.plantuml b/doc/summary_cases_and_readers.plantuml new file mode 100644 index 0000000000..068bb7cfb5 --- /dev/null +++ b/doc/summary_cases_and_readers.plantuml @@ -0,0 +1,58 @@ +@startuml +left to right direction + +RifSummaryReaderInterface <|-- RifCalculatedSummaryCurveReader +RifSummaryReaderInterface <|-- RifColumnBasedUserData +RifSummaryReaderInterface <|-- RifCsvUserData +RifSummaryReaderInterface <|-- RifKeywordVectorUserData +RifSummaryReaderInterface <|-- RifReaderEclipseSummary +RifSummaryReaderInterface <|-- RifReaderObservedData +RifSummaryReaderInterface <|-- RifEnsembleStatisticsReader +RifSummaryReaderInterface <|-- RifDerivedEnsembleReader + +RifColumnBasedUserData *-- "1" RifColumnBasedUserDataParser +RifKeywordVectorUserData *-- "1" RifKeywordVectorUserDataParser +RifReaderObservedData --> RifCsvUserDataParser + +RimSummaryCaseCollection --> "*" RimSummaryCase + +RimSummaryCaseCollection <|-- RimDerivedEnsembleCaseCollection + +RimDerivedEnsembleCaseCollection --> "*" RimDerivedEnsembleCase + +RimSummaryCase <|-- RimCalculatedSummaryCase +RimSummaryCase <|-- RimFileSummaryCase +RimSummaryCase <|-- RimGridSummaryCase +RimSummaryCase <|-- RimObservedData +RimSummaryCase <|-- RimEnsembleStatisticsCase +RimSummaryCase <|-- RimDerivedEnsembleCase + +RimObservedData <|-- RimObservedEclipseUserData +RimObservedData <|-- RimCsvUserData +RimObservedData <|-- RimSummaryObservedDataFile + +RimCalculatedSummaryCase --> RifCalculatedSummaryCurveReader + +RimDerivedEnsembleCase --> RifDerivedEnsembleReader + +RimSummaryObservedDataFile --> RifReaderObservedData + +RimObservedEclipseUserData *--> RifSummaryReaderInterface + +RimCsvUserData -> RicPasteAsciiDataToSummaryPlotFeatureUi +RimCsvUserData --> RifCsvUserData + +RimFileSummaryCase *--> RifReaderEclipseSummary +RimGridSummaryCase *--> RifReaderEclipseSummary + +RicPasteAsciiDataToSummaryPlotFeatureUi --> RifCsvUserDataParser + +RimEnsembleCurveSet -> "1" RimSummaryCaseCollection + +RimEnsembleCurveSet --> "1" RimEnsembleStatisticsCase +RimEnsembleStatisticsCase --> RifEnsembleStatisticsReader + +RimSummaryCaseMainCollection -> "*" RimSummaryCase +RimSummaryCaseMainCollection -> "*" RimSummaryCaseCollection + +@enduml diff --git a/patches/qwt_single_interval_sample_fix.patch b/patches/qwt_single_interval_sample_fix.patch new file mode 100644 index 0000000000..c68fb1d8ae --- /dev/null +++ b/patches/qwt_single_interval_sample_fix.patch @@ -0,0 +1,26 @@ +From 08ad8a98db66e2f222554c61ead97cccc31f2531 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Jensen?= +Date: Wed, 4 Jul 2018 09:15:29 +0200 +Subject: [PATCH] Qwt fix. Fix plotting of interval series having only one + sample + +--- + ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp b/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp +index 200ea39b5..d61b7978e 100644 +--- a/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp ++++ b/ThirdParty/Qwt/src/qwt_plot_intervalcurve.cpp +@@ -298,7 +298,7 @@ const QBrush& QwtPlotIntervalCurve::brush() const + QRectF QwtPlotIntervalCurve::boundingRect() const + { + QRectF rect = QwtPlotSeriesItem::boundingRect(); +- if ( rect.isValid() && orientation() == Qt::Vertical ) ++ if ( rect.width() >= 0.0 && rect.height() >= 0.0 && orientation() == Qt::Vertical ) + rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() ); + + return rect; +-- +2.16.2.windows.1 + diff --git a/scripts/ceesol-sample-clang-build.ps1 b/scripts/ceesol-sample-clang-build.ps1 deleted file mode 100644 index d1ba3e1a79..0000000000 --- a/scripts/ceesol-sample-clang-build.ps1 +++ /dev/null @@ -1,231 +0,0 @@ -<# -.SYNOPSIS - Compiles or tidies up code from Visual Studio .vcxproj project files. - It sets up the scene required for clang-build.ps1 to do its job, and makes - command-line usage for projects and files quicker. - - Before calling sample-clang-build.ps1 you need to set the current directory - to the root source directory. - -.PARAMETER aVcxprojToCompile - Alias 'proj'. Array of project(s) to compile. If empty, all projects are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, - e.g. "msicomp" compiles all msicomp projects. - - Can be passed as comma separated values. - -.PARAMETER aVcxprojToIgnore - Alias 'proj-ignore'. Array of project(s) to ignore, from the matched ones. - If empty, all already matched projects are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, - e.g. "msicomp" compiles all msicomp projects. - - Can be passed as comma separated values. - -.PARAMETER aVcxprojConfigPlatform - Alias 'active-config'. The configuration-platform pair, separated by |, - to be used when processing project files. - - E.g. 'Debug|Win32'. - If not specified, the first configuration-plaform found in the current project is used. - -.PARAMETER aCppToCompile - Alias 'file'. What cpp(s) to compile from the found project(s). If empty, all CPPs are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, - e.g. "table" compiles all CPPs containing 'table'. - -.PARAMETER aCppToIgnore - Alias 'file-ignore'. Array of file(s) to ignore, from the matched ones. - If empty, all already matched files are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, - e.g. "table" ignores all CPPs containing 'table'. - - Can be passed as comma separated values. - - -.PARAMETER aContinueOnError - Alias 'continue'. Switch to continue project compilation even when errors occur. - -.PARAMETER aClangCompileFlags - Alias 'clang-flags'. Flags given to clang++ when compiling project, - alongside project-specific defines. - -.PARAMETER aDisableNameRegexMatching - Alias 'literal'. Switch to take project and cpp name filters literally, not by regex matching. - -.PARAMETER aTidyFlags - Alias 'tidy'. If not empty clang-tidy will be called with given flags, instead of clang++. - The tidy operation is applied to whole translation units, meaning all directory headers - included in the CPP will be tidied up too. Changes will not be applied, only simulated. - - If aTidyFixFlags is present, it takes precedence over this parameter. - -.PARAMETER aTidyFixFlags - Alias 'tidy-fix'. If not empty clang-tidy will be called with given flags, instead of clang++. - The tidy operation is applied to whole translation units, meaning all directory headers - included in the CPP will be tidied up too. Changes will be applied to the file(s). - - If present, this parameter takes precedence over aTidyFlags. - -.PARAMETER aAfterTidyFixFormatStyle - Alias 'format-style'. Used in combination with 'tidy-fix'. If present, clang-tidy will - also format the fixed file(s), using the specified style. - Possible values: - not present, no formatting will be done - - 'file' - Literally 'file', not a placeholder. - Uses .clang-format file in the closest parent directory. - - 'llvm' - - 'google' - - 'webkit' - - 'mozilla' - -.EXAMPLE - PS .\sample-clang-build.ps1 -dir -proj foo,bar -file meow -tidy "-*,modernize-*" - - Runs clang-tidy, using "-*,modernize-*", on all CPPs containing 'meow' in their name from - the projects containing 'foo' or 'bar' in their names. - - Doesn't actually apply the clang-tidy module changes to CPPs. - It will only print the tidy module output. - -.EXAMPLE - PS .\sample-clang-build.ps1 -dir -proj foo,bar -file meow -tidy-fix "-*,modernize-*" - - Runs clang-tidy, using "-*,modernize-*", on all CPPs containing 'meow' in their name from - the projects containing 'foo' or 'bar' in their names. - - It will apply all tidy module changes to CPPs. - -.EXAMPLE - PS .\sample-clang-build.ps1 -dir -proj foo -proj-ignore foobar - - Runs clang++ on all CPPs in foo... projects, except foobar - -.OUTPUTS - Will output Clang warnings and errors to screen. The return code will be 0 for success, >0 for failure. - -.NOTES - Author: Gabriel Diaconita -#> -param( [alias("proj")] [Parameter(Mandatory=$false)][string[]] $aVcxprojToCompile - , [alias("proj-ignore")] [Parameter(Mandatory=$false)][string[]] $aVcxprojToIgnore - , [alias("active-config")][Parameter(Mandatory=$false)][string] $aVcxprojConfigPlatform - , [alias("file")] [Parameter(Mandatory=$false)][string] $aCppToCompile - , [alias("file-ignore")] [Parameter(Mandatory=$false)][string[]] $aCppToIgnore - , [alias("continue")] [Parameter(Mandatory=$false)][switch] $aContinueOnError - , [alias("literal")] [Parameter(Mandatory=$false)][switch] $aDisableNameRegexMatching - , [alias("tidy")] [Parameter(Mandatory=$false)][string] $aTidyFlags - , [alias("tidy-fix")] [Parameter(Mandatory=$false)][string] $aTidyFixFlags - , [alias("format-style")] [Parameter(Mandatory=$false)][string] $aAfterTidyFixFormatStyle - ) - -# ------------------------------------------------------------------------------------------------ - -Set-Variable -name kClangCompileFlags -Option Constant ` - -value @( "-Wall" - , "-fms-compatibility-version=19.10" - , "-Wmicrosoft" - , "-Wno-invalid-token-paste" - , "-Wno-unknown-pragmas" - , "-Wno-unused-variable" - , "-Wno-unused-value" - , "-Wno-undefined-var-template" - , "-Wno-microsoft-enum-value" - , "-Wno-inconsistent-missing-override" - , "-Wno-extra-tokens" - , "-Wno-c99-extensions" - , "-Wno-logical-op-parentheses" - , "-Wno-invalid-source-encoding" - ) - -Set-Variable -name kVisualStudioVersion -value "2017" -Option Constant -Set-Variable -name kVisualStudioSku -value "Professional" -Option Constant -Set-Variable -name localVarUseParallelCompile -value $True -Option Constant -Set-Variable -name localVarCppToIgnore -Option Constant ` - -value @( "gtest" - , "moc_" - ) - - -# ------------------------------------------------------------------------------------------------ - -Function Merge-Array([string[]] $aArray) -{ - # we need to individually wrap items into quotes as values - # can contain PS control characters (e.g. - in -std=c++14) - $quotedArray = ($aArray | ForEach-Object { """$_"""}) - return ($quotedArray -join ",") -} - -[string] $scriptDirectory = (Split-Path -parent $PSCommandPath) - -[string] $clangScript = "$scriptDirectory\clang-build.ps1" -[string[]] $scriptParams = @("-aSolutionsPath", "'$(Get-Location)'") - -if (![string]::IsNullOrEmpty($aVcxprojToCompile)) -{ - $scriptParams += ("-aVcxprojToCompile", (Merge-Array $aVcxprojToCompile)) -} - -if (![string]::IsNullOrEmpty($aVcxprojToIgnore)) -{ - $scriptParams += ("-aVcxprojToIgnore", (Merge-Array $aVcxprojToIgnore)) -} - -if (![string]::IsNullOrEmpty($aVcxprojConfigPlatform)) -{ - $scriptParams += ("-aVcxprojConfigPlatform", (Merge-Array $aVcxprojConfigPlatform)) -} - -if (![string]::IsNullOrEmpty($aCppToCompile)) -{ - $scriptParams += ("-aCppToCompile", (Merge-Array $aCppToCompile)) -} - -if (![string]::IsNullOrEmpty($localVarCppToIgnore)) -{ - $scriptParams += ("-aCppToIgnore", (Merge-Array $localVarCppToIgnore)) -} - -$scriptParams += ("-aClangCompileFlags", (Merge-Array $kClangCompileFlags)) - -if (![string]::IsNullOrEmpty($aTidyFlags)) -{ - $scriptParams += ("-aTidyFlags", (Merge-Array (@($aTidyFlags)))) -} - -if (![string]::IsNullOrEmpty($aTidyFixFlags)) -{ - $scriptParams += ("-aTidyFixFlags", (Merge-Array (@($aTidyFixFlags)))) -} - -if (![string]::IsNullOrEmpty($aAfterTidyFixFormatStyle)) -{ - $scriptParams += ("-aAfterTidyFixFormatStyle", $aAfterTidyFixFormatStyle) -} - -if ($localVarUseParallelCompile) -{ - $scriptParams += ("-aUseParallelCompile") -} - -if ($aContinueOnError) -{ - $scriptParams += ("-aContinueOnError") -} - -if ($True) -{ - $scriptParams += ("-aTreatAdditionalIncludesAsSystemIncludes") -} - -if ($aDisableNameRegexMatching) -{ - $scriptParams += ("-aDisableNameRegexMatching") -} - -$scriptParams += ("-aVisualStudioVersion", $kVisualStudioVersion) -$scriptParams += ("-aVisualStudioSku", $kVisualStudioSku) -$scriptParams += ("-aTidyHeaderFilter", ".*") - -Invoke-Expression "&'$clangScript' $scriptParams" diff --git a/scripts/clang-build.ps1 b/scripts/clang-build.ps1 index 8c8c37c8b8..07b67bd0c3 100644 --- a/scripts/clang-build.ps1 +++ b/scripts/clang-build.ps1 @@ -1,5 +1,4 @@ -#Requires -Version 3 -<# +<# .SYNOPSIS Compiles or tidies up code from Visual Studio .vcxproj project files. @@ -8,45 +7,47 @@ One or more of these projects will be compiled or tidied up (modernized), using Clang. .PARAMETER aSolutionsPath - Alias 'dir'. Source directory to find sln files. + Alias 'dir'. Source directory to find sln files. Projects will be extracted from each sln. - + Important: You can pass an absolute path to a sln. This way, no file searching will be done, and - only the projects from this solution file will be taken into acount. + only the projects from this solution file will be taken into account. .PARAMETER aVcxprojToCompile Alias 'proj'. Array of project(s) to compile. If empty, all projects found in solutions are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, + If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, e.g. "msicomp" compiles all projects containing 'msicomp'. Absolute disk paths to vcxproj files are accepted. - + Can be passed as comma separated values. .PARAMETER aVcxprojToIgnore - Alias 'proj-ignore'. Array of project(s) to ignore, from the matched ones. + Alias 'proj-ignore'. Array of project(s) to ignore, from the matched ones. If empty, all already matched projects are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, + If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, e.g. "msicomp" ignores projects containing 'msicomp'. Can be passed as comma separated values. .PARAMETER aVcxprojConfigPlatform - Alias 'active-config'. The configuration-platform pair, separated by |, + Alias 'active-config'. The configuration-platform pair, separated by |, to be used when processing project files. - E.g. 'Debug|Win32'. - If not specified, the first configuration-plaform found in the current project is used. + E.g. 'Debug|Win32'. + If not specified, the first configuration-platform found in the current project is used. .PARAMETER aCppToCompile Alias 'file'. What cpp(s) to compile from the found project(s). If empty, all CPPs are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, + If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, e.g. "table" compiles all CPPs containing 'table'. + Note: If any headers are given then all translation units that include them will be processed. + .PARAMETER aCppToIgnore - Alias 'file-ignore'. Array of file(s) to ignore, from the matched ones. + Alias 'file-ignore'. Array of file(s) to ignore, from the matched ones. If empty, all already matched files are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, + If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, e.g. "table" ignores all CPPs containing 'table'. Can be passed as comma separated values. @@ -61,38 +62,38 @@ Alias 'treat-sai'. Switch to treat project additional include directories as system includes. .PARAMETER aClangCompileFlags - Alias 'clang-flags'. Flags given to clang++ when compiling project, + Alias 'clang-flags'. Flags given to clang++ when compiling project, alongside project-specific defines. .PARAMETER aDisableNameRegexMatching Alias 'literal'. Switch to take project and cpp name filters literally, not by regex matching. .PARAMETER aTidyFlags - Alias 'tidy'. If not empty clang-tidy will be called with given flags, instead of clang++. - The tidy operation is applied to whole translation units, meaning all directory headers + Alias 'tidy'. If not empty clang-tidy will be called with given flags, instead of clang++. + The tidy operation is applied to whole translation units, meaning all directory headers included in the CPP will be tidied up too. Changes will not be applied, only simulated. If aTidyFixFlags is present, it takes precedence over this parameter. - If '.clang-tidy' value is given, configuration will be read from .clang-tidy file + If '.clang-tidy' value is given, configuration will be read from .clang-tidy file in the closest parent directory. - + .PARAMETER aTidyFixFlags - Alias 'tidy-fix'. If not empty clang-tidy will be called with given flags, instead of clang++. - The tidy operation is applied to whole translation units, meaning all directory headers + Alias 'tidy-fix'. If not empty clang-tidy will be called with given flags, instead of clang++. + The tidy operation is applied to whole translation units, meaning all directory headers included in the CPP will be tidied up too. Changes will be applied to the file(s). If present, this parameter takes precedence over aTidyFlags. - If '.clang-tidy' value is given, configuration will be read from .clang-tidy file + If '.clang-tidy' value is given, configuration will be read from .clang-tidy file in the closest parent directory. - + .PARAMETER aAfterTidyFixFormatStyle Alias 'format-style'. Used in combination with 'tidy-fix'. If present, clang-tidy will also format the fixed file(s), using the specified style. Possible values: - not present, no formatting will be done - 'file' - Literally 'file', not a placeholder. + Literally 'file', not a placeholder. Uses .clang-format file in the closest parent directory. - 'llvm' - 'google' @@ -100,33 +101,88 @@ - 'mozilla' .PARAMETER aVisualStudioVersion - Alias 'vs-ver'. Version of Visual Studio (VC++) installed and that'll be used for + Alias 'vs-ver'. Version of Visual Studio (VC++) installed and that'll be used for standard library include directories. E.g. 2017. + Optional. If not given, it will be inferred based on the project toolset version. + .PARAMETER aVisualStudioSku - Alias 'vs-sku'. Sku of Visual Studio (VC++) installed and that'll be used for + Alias 'vs-sku'. Sku of Visual Studio (VC++) installed and that'll be used for standard library include directories. E.g. Professional. + If not given, the first detected Visual Studio SKU will be used. + .NOTES Author: Gabriel Diaconita #> -param( [alias("dir")] [Parameter(Mandatory=$true)] [string] $aSolutionsPath - , [alias("proj")] [Parameter(Mandatory=$false)][string[]] $aVcxprojToCompile - , [alias("proj-ignore")] [Parameter(Mandatory=$false)][string[]] $aVcxprojToIgnore - , [alias("active-config")][Parameter(Mandatory=$false)][string] $aVcxprojConfigPlatform - , [alias("file")] [Parameter(Mandatory=$false)][string] $aCppToCompile - , [alias("file-ignore")] [Parameter(Mandatory=$false)][string[]] $aCppToIgnore - , [alias("parallel")] [Parameter(Mandatory=$false)][switch] $aUseParallelCompile - , [alias("continue")] [Parameter(Mandatory=$false)][switch] $aContinueOnError - , [alias("treat-sai")] [Parameter(Mandatory=$false)][switch] $aTreatAdditionalIncludesAsSystemIncludes - , [alias("clang-flags")] [Parameter(Mandatory=$true)] [string[]] $aClangCompileFlags - , [alias("literal")] [Parameter(Mandatory=$false)][switch] $aDisableNameRegexMatching - , [alias("tidy")] [Parameter(Mandatory=$false)][string] $aTidyFlags - , [alias("tidy-fix")] [Parameter(Mandatory=$false)][string] $aTidyFixFlags - , [alias("header-filter")][Parameter(Mandatory=$false)][string] $aTidyHeaderFilter - , [alias("format-style")] [Parameter(Mandatory=$false)][string] $aAfterTidyFixFormatStyle - , [alias("vs-ver")] [Parameter(Mandatory=$true)] [string] $aVisualStudioVersion - , [alias("vs-sku")] [Parameter(Mandatory=$true)] [string] $aVisualStudioSku +#Requires -Version 3 +param( [alias("proj")] + [Parameter(Mandatory=$false, HelpMessage="Filter project(s) to compile/tidy")] + [string[]] $aVcxprojToCompile + + , [alias("dir")] + [Parameter(Mandatory=$false, HelpMessage="Source directory for finding solutions; projects will be found from each sln")] + [string] $aSolutionsPath + + , [alias("proj-ignore")] + [Parameter(Mandatory=$false, HelpMessage="Specify projects to ignore")] + [string[]] $aVcxprojToIgnore + + , [alias("active-config")] + [Parameter(Mandatory=$false, HelpMessage="Config/platform to be used, e.g. Debug|Win32")] + [string] $aVcxprojConfigPlatform + + , [alias("file")] + [Parameter(Mandatory=$false, HelpMessage="Filter file(s) to compile/tidy")] + [string[]] $aCppToCompile + + , [alias("file-ignore")] + [Parameter(Mandatory=$false, HelpMessage="Specify file(s) to ignore")] + [string[]] $aCppToIgnore + + , [alias("parallel")] + [Parameter(Mandatory=$false, HelpMessage="Compile/tidy projects in parallel")] + [switch] $aUseParallelCompile + + , [alias("continue")] + [Parameter(Mandatory=$false, HelpMessage="Allow CPT to continue after encounteringan error")] + [switch] $aContinueOnError + + , [alias("treat-sai")] + [Parameter(Mandatory=$false, HelpMessage="Treat project additional include directories as system includes")] + [switch] $aTreatAdditionalIncludesAsSystemIncludes + + , [alias("clang-flags")] + [Parameter(Mandatory=$false, HelpMessage="Specify compilation flags to CLANG")] + [string[]] $aClangCompileFlags + + , [alias("literal")] + [Parameter(Mandatory=$false, HelpMessage="Disable regex matching for all paths received as script parameters")] + [switch] $aDisableNameRegexMatching + + , [alias("tidy")] + [Parameter(Mandatory=$false, HelpMessage="Specify flags to CLANG TIDY")] + [string] $aTidyFlags + + , [alias("tidy-fix")] + [Parameter(Mandatory=$false, HelpMessage="Specify flags to CLANG TIDY & FIX")] + [string] $aTidyFixFlags + + , [alias("header-filter")] + [Parameter(Mandatory=$false, HelpMessage="Enable Clang-Tidy to run on header files")] + [string] $aTidyHeaderFilter + + , [alias("format-style")] + [Parameter(Mandatory=$false, HelpMessage="Used with 'tidy-fix'; tells CLANG TIDY-FIX to also format the fixed file(s)")] + [string] $aAfterTidyFixFormatStyle + + , [alias("vs-ver")] + [Parameter(Mandatory=$false, HelpMessage="Version of Visual Studio toolset to use for loading project")] + [string] $aVisualStudioVersion = "2017" + + , [alias("vs-sku")] + [Parameter(Mandatory=$false, HelpMessage="Edition of Visual Studio toolset to use for loading project")] + [string] $aVisualStudioSku ) # System Architecture Constants @@ -149,69 +205,11 @@ Set-Variable -name kScriptFailsExitCode -value 47 -option Set-Variable -name kExtensionVcxproj -value ".vcxproj" -option Constant Set-Variable -name kExtensionSolution -value ".sln" -option Constant Set-Variable -name kExtensionClangPch -value ".clang.pch" -option Constant - -# ------------------------------------------------------------------------------------------------ -# Vcxproj Related Constants - -Set-Variable -name kVcxprojXpathPreprocessorDefs ` - -value "ns:Project/ns:ItemDefinitionGroup/ns:ClCompile/ns:PreprocessorDefinitions" ` - -option Constant - -Set-Variable -name kVcxprojXpathAdditionalIncludes ` - -value "ns:Project/ns:ItemDefinitionGroup/ns:ClCompile/ns:AdditionalIncludeDirectories" ` - -option Constant - -Set-Variable -name kVcxprojXpathHeaders ` - -value "ns:Project/ns:ItemGroup/ns:ClInclude" ` - -option Constant - -Set-Variable -name kVcxprojXpathCompileFiles ` - -value "ns:Project/ns:ItemGroup/ns:ClCompile" ` - -option Constant - -Set-Variable -name kVcxprojXpathWinPlatformVer ` - -value "ns:Project/ns:PropertyGroup/ns:WindowsTargetPlatformVersion" ` - -option Constant - -Set-Variable -name kVcxprojXpathForceIncludes ` - -value "ns:Project/ns:ItemDefinitionGroup/ns:ClCompile/ns:ForcedIncludeFiles" ` - -option Constant - -Set-Variable -name kVcxprojXpathPCH ` - -value "ns:Project/ns:ItemGroup/ns:ClCompile/ns:PrecompiledHeader[text()='Create']" ` - -option Constant - -Set-Variable -name kVcxprojXpathToolset ` - -value "ns:Project/ns:PropertyGroup[@Label='Configuration']/ns:PlatformToolset" ` - -option Constant - -Set-Variable -name kVcxprojXpathDefaultConfigPlatform ` - -value "ns:Project/ns:ItemGroup[@Label='ProjectConfigurations']/ns:ProjectConfiguration[1]" ` - -option Constant - -Set-Variable -name kVcxprojXpathConditionedElements ` - -value "//*[@Condition]" ` - -option Constant - -Set-Variable -name kVcxprojXpathChooseElements ` - -value "ns:Project//ns:Choose" ` - -option Constant - -Set-Variable -name kVcxprojXpathPropGroupElements ` - -value "ns:Project//ns:PropertyGroup/*" ` - -option Constant - -Set-Variable -name kVcxprojXpathCppStandard ` - -value "ns:Project/ns:ItemDefinitionGroup/ns:ClCompile/ns:LanguageStandard" ` - -option Constant - -Set-Variable -name kVSDefaultWinSDK -value '8.1' -option Constant -Set-Variable -name kVSDefaultWinSDK_XP -value '7.0' -option Constant +Set-Variable -name kExtensionC -value ".c" -option Constant # ------------------------------------------------------------------------------------------------ # Clang-Related Constants -Set-Variable -name kDefaultCppStd -value "stdcpp14" -option Constant Set-Variable -name kClangFlagSupressLINK -value @("-fsyntax-only") -option Constant Set-Variable -name kClangFlagWarningIsError -value @("-Werror") -option Constant Set-Variable -name kClangFlagIncludePch -value "-include-pch" -option Constant @@ -224,6 +222,7 @@ Set-Variable -name kClangFlagNoUnusedArg -value "-Wno-unused-command-line-arg Set-Variable -name kClangFlagNoMsInclude -value "-Wno-microsoft-include" ` -Option Constant Set-Variable -name kClangFlagFileIsCPP -value "-x c++" -option Constant +Set-Variable -name kClangFlagFileIsC -value "-x c" -option Constant Set-Variable -name kClangFlagForceInclude -value "-include" -option Constant Set-Variable -name kClangCompiler -value "clang++.exe" -option Constant @@ -245,41 +244,6 @@ Set-Variable -name kLLVMInstallLocations -value @("${Env:ProgramW6432}\LLVM\b ,"${Env:ProgramFiles(x86)}\LLVM\bin" ) -option Constant -# ------------------------------------------------------------------------------------------------ -# Helpers for locating Visual Studio on the computer - -# VsWhere is available starting with Visual Studio 2017 version 15.2. -Set-Variable -name kVsWhereLocation ` - -value "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" ` - -option Constant - -# Default installation path of Visual Studio 2017. We'll use when VsWhere isn't available. -Set-Variable -name kVs15DefaultLocation ` - -value "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\$aVisualStudioVersion\$aVisualStudioSku" ` - -option Constant - -# Registry key containing information about Visual Studio 2015 installation path. -Set-Variable -name kVs2015RegistryKey ` - -value "HKLM:SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0" ` - -option Constant - -#------------------------------------------------------------------------------------------------- -# PlatformToolset-Related Constants - -Set-Variable -name kDefinesUnicode -value @("-DUNICODE" - ,"-D_UNICODE" - ) ` - -option Constant - -Set-Variable -name kDefinesClangXpTargeting ` - -value @("-D_USING_V110_SDK71_") ` - -option Constant - - -Set-Variable -name kIncludePathsXPTargetingSDK ` - -value "${Env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v7.1A\Include" ` - -option Constant - #------------------------------------------------------------------------------------------------- # Custom Types @@ -292,48 +256,13 @@ Add-Type -TypeDefinition @" } "@ -Set-Variable -name kVStudioDefaultPlatformToolset -Value "v141" -option Constant - -Set-Variable -name "kMsbuildExpressionToPsRules" -option Constant ` - -value @(<# backticks are control characters in PS, replace them #> - ('`' , '''' )` - <# Temporarily replace $( #> ` - , ('\$\s*\(' , '!@#' )` - <# Escape $ #> ` - , ('\$' , '`$' )` - <# Put back $( #> ` - , ('!@#' , '$(' )` - <# Various operators #> ` - , ("([\s\)\'""])!=" , '$1 -ne ' )` - , ("([\s\)\'""])<=" , '$1 -le ' )` - , ("([\s\)\'""])>=" , '$1 -ge ' )` - , ("([\s\)\'""])==" , '$1 -eq ' )` - , ("([\s\)\'""])<" , '$1 -lt ' )` - , ("([\s\)\'""])>" , '$1 -gt ' )` - , ("([\s\)\'""])or" , '$1 -or ' )` - , ("([\s\)\'""])and" , '$1 -and ' )` - <# Use only double quotes #> ` - , ("\'" , '"' )` - , ("Exists\((.*?)\)(\s|$)" , '(Exists($1))$2' )` - , ("HasTrailingSlash\((.*?)\)(\s|$)" , '(HasTrailingSlash($1))$2' )` - , ("(\`$\()(Registry:)(.*?)(\))" , '$$(GetRegValue("$3"))' )` - ) - -Set-Variable -name "kMsbuildConditionToPsRules" -option Constant ` - -value @(<# Use only double quotes #> ` - ("\'" , '"' )` - <# We need to escape double quotes since we will eval() the condition #> ` - , ('"' , '""' )` - ) - -Set-Variable -name "kRedundantSeparatorsReplaceRules" -option Constant ` - -value @( <# handle multiple consecutive separators #> ` - (";+" , ";") ` - <# handle separator at end #> ` - , (";$" , "") ` - <# handle separator at beginning #> ` - , ("^;" , "") ` - ) + @( "$PSScriptRoot\psClang\io.ps1" + , "$PSScriptRoot\psClang\visualstudio-detection.ps1" + , "$PSScriptRoot\psClang\msbuild-expression-eval.ps1" + , "$PSScriptRoot\psClang\msbuild-project-load.ps1" + , "$PSScriptRoot\psClang\msbuild-project-data.ps1" + , "$PSScriptRoot\psClang\get-header-references.ps1" + ) | ForEach-Object { . $_ } #------------------------------------------------------------------------------------------------- # Global variables @@ -341,28 +270,17 @@ Set-Variable -name "kRedundantSeparatorsReplaceRules" -option Constant ` # temporary files created during project processing (e.g. PCH files) [System.Collections.ArrayList] $global:FilesToDeleteWhenScriptQuits = @() -# vcxproj and property sheet files declare MsBuild properties (e.g. $(MYPROP)). -# they are used in project xml nodes expressions. we have a -# translation engine (MSBUILD-POWERSHELL) for these. it relies on -# PowerShell to evaluate these expressions. We have to inject project -# properties in the Powershell runtime context. We keep track of them in -# this list, to be cleaned before the next project begins processing -[System.Collections.ArrayList] $global:ProjectSpecificVariables = @() +# filePath-fileData for SLN files located in source directory +[System.Collections.Generic.Dictionary[String,String]] $global:slnFiles = @{} # flag to signal when errors are encounteres during project processing [Boolean] $global:FoundErrors = $false -# current vcxproj and property sheets -[xml[]] $global:projectFiles = @(); +# default ClangPowerTools version of visual studio to use +[string] $global:cptDefaultVisualStudioVersion = "2017" -# path of current project -[string] $global:vcxprojPath = ""; - -# namespace of current project vcxproj XML -[System.Xml.XmlNamespaceManager] $global:xpathNS = $null; - -# filePath-fileData for SLN files located in source directory -[System.Collections.Generic.Dictionary[String,String]] $global:slnFiles = @{} +# version of VS currently used +[string] $global:cptVisualStudioVersion = $aVisualStudioVersion #------------------------------------------------------------------------------------------------- # Global functions @@ -392,146 +310,6 @@ Function Fail-Script([parameter(Mandatory=$false)][string] $msg = "Got errors.") Exit-Script($kScriptFailsExitCode) } -Function Set-Var([parameter(Mandatory=$false)][string] $name, - [parameter(Mandatory=$false)][string] $value) -{ - Write-Verbose "SET_VAR $($name): $value" - Set-Variable -name $name -Value $value -Scope Global - - if (!$global:ProjectSpecificVariables.Contains($name)) - { - $global:ProjectSpecificVariables.Add($name) | Out-Null - } -} - -Function Clear-Vars() -{ - Write-Verbose-Array -array $global:ProjectSpecificVariables ` - -name "Deleting project specific variables" - - foreach ($var in $global:ProjectSpecificVariables) - { - Remove-Variable -name $var -scope Global -ErrorAction SilentlyContinue - } - - $global:ProjectSpecificVariables.Clear() -} - -Function Write-Message([parameter(Mandatory=$true)][string] $msg - ,[Parameter(Mandatory=$true)][System.ConsoleColor] $color) -{ - $foregroundColor = $host.ui.RawUI.ForegroundColor - $host.ui.RawUI.ForegroundColor = $color - Write-Output $msg - $host.ui.RawUI.ForegroundColor = $foregroundColor -} - -# Writes an error without the verbose powershell extra-info (script line location, etc.) -Function Write-Err([parameter(ValueFromPipeline, Mandatory=$true)][string] $msg) -{ - Write-Message -msg $msg -color Red -} - -Function Write-Success([parameter(ValueFromPipeline, Mandatory=$true)][string] $msg) -{ - Write-Message -msg $msg -color Green -} - -Function Write-Verbose-Array($array, $name) -{ - Write-Verbose "$($name):" - $array | ForEach-Object { Write-Verbose " $_" } -} - -Function Exists-Command([Parameter(Mandatory=$true)][string] $command) -{ - try - { - Get-Command -name $command -ErrorAction Stop - return $true - } - catch - { - return $false - } -} - -Function Get-FileDirectory([Parameter(Mandatory=$true)][string] $filePath) -{ - return ([System.IO.Path]::GetDirectoryName($filePath) + "\") -} - -Function Get-FileName( [Parameter(Mandatory=$true)][string] $path - , [Parameter(Mandatory=$false)][switch] $noext) -{ - if ($noext) - { - return ([System.IO.Path]::GetFileNameWithoutExtension($path)) - } - else - { - return ([System.IO.Path]::GetFileName($path)) - } -} - -Function IsFileMatchingName( [Parameter(Mandatory=$true)][string] $filePath - , [Parameter(Mandatory=$true)][string] $matchName) -{ - if ([System.IO.Path]::IsPathRooted($matchName)) - { - return $filePath -ieq $matchName - } - - [string] $fileName = (Get-FileName -path $filePath) - [string] $fileNameNoExt = (Get-FileName -path $filePath -noext) - if ($aDisableNameRegexMatching) - { - return (($fileName -eq $matchName) -or ($fileNameNoExt -eq $matchName)) - } - else - { - return (($fileName -match $matchName) -or ($fileNameNoExt -match $matchName)) - } -} - - <# - .DESCRIPTION - Merges an absolute and a relative file path. - .EXAMPLE - Havin base = C:\Windows\System32 and child = .. we get C:\Windows - .EXAMPLE - Havin base = C:\Windows\System32 and child = ..\..\..\.. we get C:\ (cannot go further up) - .PARAMETER base - The absolute path from which we start. - .PARAMETER child - The relative path to be merged into base. - .PARAMETER ignoreErrors - If this switch is not present, an error will be triggered if the resulting path - is not present on disk (e.g. c:\Windows\System33). - - If present and the resulting path does not exist, the function returns an empty string. - #> -Function Canonize-Path( [Parameter(Mandatory=$true)][string] $base - , [Parameter(Mandatory=$true)][string] $child - , [switch] $ignoreErrors) -{ - [string] $errorAction = If ($ignoreErrors) {"SilentlyContinue"} Else {"Stop"} - - if ([System.IO.Path]::IsPathRooted($child)) - { - if (!(Test-Path $child)) - { - return "" - } - return $child - } - else - { - [string[]] $paths = Join-Path -Path "$base" -ChildPath "$child" -Resolve -ErrorAction $errorAction - return $paths - } -} - Function Get-SourceDirectory() { [bool] $isDirectory = ($(Get-Item $aSolutionsPath) -is [System.IO.DirectoryInfo]) @@ -539,7 +317,7 @@ Function Get-SourceDirectory() { return $aSolutionsPath } - else + else { return (Get-FileDirectory -filePath $aSolutionsPath) } @@ -548,8 +326,7 @@ Function Get-SourceDirectory() function Load-Solutions() { Write-Verbose "Scanning for solution files" - $slns = Get-ChildItem -recurse -LiteralPath "$aSolutionsPath" ` - | Where-Object { $_.Extension -eq $kExtensionSolution } + $slns = Get-ChildItem -recurse -LiteralPath "$aSolutionsPath" -Filter "*$kExtensionSolution" foreach ($sln in $slns) { $slnPath = $sln.FullName @@ -562,7 +339,7 @@ function Load-Solutions() function Get-SolutionProjects([Parameter(Mandatory=$true)][string] $slnPath) { [string] $slnDirectory = Get-FileDirectory -file $slnPath - $matches = [regex]::Matches($global:slnFiles[$slnPath], 'Project\([{}\"A-Z0-9\-]+\) = \S+,\s(\S+),') + $matches = [regex]::Matches($global:slnFiles[$slnPath], 'Project\([{}\"A-Z0-9\-]+\) = \".*?\",\s\"(.*?)\"') $projectAbsolutePaths = $matches ` | ForEach-Object { Canonize-Path -base $slnDirectory ` -child $_.Groups[1].Value.Replace('"','') -ignoreErrors } ` @@ -583,1127 +360,106 @@ function Get-ProjectSolution() return "" } -Function Get-MscVer() -{ - return ((Get-Item "$(Get-VisualStudio-Path)\VC\Tools\MSVC\" | Get-ChildItem) | select -last 1).Name -} - -Function InitializeMsBuildCurrentFileProperties([Parameter(Mandatory=$true)][string] $filePath) -{ - Set-Var -name "MSBuildThisFileFullPath" -value $filePath - Set-Var -name "MSBuildThisFileExtension" -value ([IO.Path]::GetExtension($filePath)) - Set-Var -name "MSBuildThisFile" -value (Get-FileName -path $filePath) - Set-Var -name "MSBuildThisFileName" -value (Get-FileName -path $filePath -noext) - Set-Var -name "MSBuildThisFileDirectory" -value (Get-FileDirectory -filePath $filePath) -} - -Function InitializeMsBuildProjectProperties() -{ - Write-Verbose "Importing environment variables into current scope" - foreach ($var in (Get-ChildItem Env:)) - { - Set-Var -name $var.Name -value $var.Value - } - - Set-Var -name "MSBuildProjectFullPath" -value $global:vcxprojPath - Set-Var -name "ProjectDir" -value (Get-FileDirectory -filePath $global:vcxprojPath) - Set-Var -name "MSBuildProjectExtension" -value ([IO.Path]::GetExtension($global:vcxprojPath)) - Set-Var -name "MSBuildProjectFile" -value (Get-FileName -path $global:vcxprojPath) - Set-Var -name "MSBuildProjectName" -value (Get-FileName -path $global:vcxprojPath -noext) - Set-Var -name "MSBuildProjectDirectory" -value (Get-FileDirectory -filePath $global:vcxprojPath) - Set-Var -name "MSBuildProgramFiles32" -value "${Env:ProgramFiles(x86)}" - # defaults for projectname and targetname, may be overriden by project settings - Set-Var -name "ProjectName" -value $MSBuildProjectName - Set-Var -name "TargetName" -value $MSBuildProjectName - - # These would enable full project platform references parsing, experimental right now - if ($env:CPT_LOAD_ALL -eq '1') - { - Set-Var -name "ConfigurationType" -value "Application" - Set-Var -name "VCTargetsPath" -value "$(Get-VisualStudio-Path)\Common7\IDE\VC\VCTargets\" - Set-Var -name "VsInstallRoot" -value (Get-VisualStudio-Path) - Set-Var -name "MSBuildExtensionsPath" -value "$(Get-VisualStudio-Path)\MSBuild" - Set-Var -name "LocalAppData" -value $env:LOCALAPPDATA - Set-Var -name "UserRootDir" -value "$LocalAppData\Microsoft\MSBuild\v4.0" - Set-Var -name "UniversalCRT_IncludePath" -value "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\10.0.10240.0\ucrt" - } - - [string] $vsVer = "15.0" - if ($aVisualStudioVersion -eq "2015") - { - $vsVer = "14.0" - } - Set-Var -name "VisualStudioVersion" -value $vsVer - Set-Var -name "MSBuildToolsVersion" -value $vsVer - - [string] $projectSlnPath = Get-ProjectSolution - [string] $projectSlnDir = Get-FileDirectory -filePath $projectSlnPath - Set-Var -name "SolutionDir" -value $projectSlnDir -} - -Function Should-CompileProject([Parameter(Mandatory=$true)][string] $vcxprojPath) -{ - if ($aVcxprojToCompile -eq $null) - { - return $true - } - - foreach ($projMatch in $aVcxprojToCompile) - { - if (IsFileMatchingName -filePath $vcxprojPath -matchName $projMatch) - { - return $true - } - } - - return $false -} - -Function Should-IgnoreProject([Parameter(Mandatory=$true)][string] $vcxprojPath) -{ - if ($aVcxprojToIgnore -eq $null) - { - return $false - } - - foreach ($projIgnoreMatch in $aVcxprojToIgnore) - { - if (IsFileMatchingName -filePath $vcxprojPath -matchName $projIgnoreMatch) - { - return $true - } - } - - return $false -} - -Function Should-IgnoreFile([Parameter(Mandatory=$true)][string] $file) -{ - if ($aCppToIgnore -eq $null) - { - return $false - } - - foreach ($projIgnoreMatch in $aCppToIgnore) - { - if (IsFileMatchingName -filePath $file -matchName $projIgnoreMatch) - { - return $true - } - } - - return $false -} - -Function Get-ProjectFilesToCompile([Parameter(Mandatory=$false)][string] $pchCppName) -{ - [Boolean] $pchDisabled = [string]::IsNullOrEmpty($pchCppName) - - [string[]] $projectEntries = Select-ProjectNodes($kVcxprojXpathCompileFiles) | ` - Where-Object { ($_.Include -ne $null) -and - ($pchDisabled -or ($_.Include -ne $pchCppName)) - } | ` - Select-Object -Property "Include" -ExpandProperty "Include" - [string[]] $files = @() - foreach ($entry in $projectEntries) - { - [string[]] $matchedFiles = Canonize-Path -base $ProjectDir -child $entry - if ($matchedFiles.Count -gt 0) - { - $files += $matchedFiles - } - } - - if ($files.Count -gt 0) - { - $files = $files | Where-Object { ! (Should-IgnoreFile -file $_) } - } - - return $files -} - -Function Get-ProjectHeaders() -{ - [string[]] $headers = Select-ProjectNodes($kVcxprojXpathHeaders) | ForEach-Object {$_.Include } - - [string[]] $headerPaths = @() - - foreach ($headerEntry in $headers) - { - [string[]] $paths = Canonize-Path -base $ProjectDir -child $headerEntry -ignoreErrors - if ($paths.Count -gt 0) - { - $headerPaths += $paths - } - } - return $headerPaths -} - -Function Get-Project-SDKVer() -{ - [string] $sdkVer = (Select-ProjectNodes($kVcxprojXpathWinPlatformVer)).InnerText - - If ([string]::IsNullOrEmpty($sdkVer)) { "" } Else { $sdkVer.Trim() } -} - -Function Is-Project-Unicode() -{ - $propGroup = Select-ProjectNodes("ns:Project/ns:PropertyGroup[@Label='Configuration']") - - return ($propGroup.CharacterSet -eq "Unicode") -} - -Function Get-Project-CppStandard() -{ - [string] $cachedValueVarName = "ClangPowerTools:CppStd" - - [string] $cachedVar = (Get-Variable $cachedValueVarName -ErrorAction SilentlyContinue -ValueOnly) - if (![string]::IsNullOrEmpty($cachedVar)) - { - return $cachedVar - } - - [string] $cppStd = "" - - $cppStdNode = Select-ProjectNodes($kVcxprojXpathCppStandard) - if ($cppStdNode) - { - $cppStd = $cppStdNode.InnerText - } - else - { - $cppStd = $kDefaultCppStd - } - - $cppStdMap = @{ 'stdcpplatest' = 'c++1z' - ; 'stdcpp14' = 'c++14' - ; 'stdcpp17' = 'c++17' - } - - [string] $cppStdClangValue = $cppStdMap[$cppStd] - Set-Var -name $cachedValueVarName -value $cppStdClangValue - - return $cppStdClangValue -} - -Function Get-ClangCompileFlags() -{ - [string[]] $flags = $aClangCompileFlags - if (!($flags -match "-std=.*")) - { - [string] $cppStandard = Get-Project-CppStandard - - $flags = @("-std=$cppStandard") + $flags - } - - return $flags -} - -Function Get-ProjectPlatformToolset() -{ - $propGroup = Select-ProjectNodes($kVcxprojXpathToolset) - - $toolset = $propGroup.InnerText - - if ($toolset) - { - return $toolset - } - else - { - return $kVStudioDefaultPlatformToolset - } -} - -Function Get-VisualStudio-Includes([Parameter(Mandatory=$true)][string] $vsPath, - [Parameter(Mandatory=$false)][string] $mscVer) -{ - [string] $mscVerToken = "" - If (![string]::IsNullOrEmpty($mscVer)) - { - $mscVerToken = "Tools\MSVC\$mscVer\" - } - - return @( "$vsPath\VC\$($mscVerToken)include" - , "$vsPath\VC\$($mscVerToken)atlmfc\include" - ) -} - -Function Get-VisualStudio-Path() -{ - if ($aVisualStudioVersion -eq "2015") - { - $installLocation = (Get-Item $kVs2015RegistryKey).GetValue("InstallDir") - return Canonize-Path -base $installLocation -child "..\.." - } - else - { - if (Test-Path $kVsWhereLocation) - { - [string] $product = "Microsoft.VisualStudio.Product.$aVisualStudioSku" - return (& "$kVsWhereLocation" -nologo ` - -property installationPath ` - -products $product ` - -prerelease) - } - - if (Test-Path -Path $kVs15DefaultLocation) - { - return $kVs15DefaultLocation - } - - throw "Cannot locate Visual Studio location" - } -} - -Function Get-ProjectIncludeDirectories([Parameter(Mandatory=$false)][string] $stdafxDir) +Function Get-Projects() { - [string[]] $returnArray = ($IncludePath -split ";") | ` - Where-Object { ![string]::IsNullOrEmpty($_) } | ` - ForEach-Object { Canonize-Path -base $ProjectDir -child $_ -ignoreErrors } | ` - Where-Object { ![string]::IsNullOrEmpty($_) } | ` - ForEach-Object { $_ -replace '\\$', '' } - if ($env:CPT_LOAD_ALL -eq '1') - { - return $returnArray - } - - [string] $vsPath = Get-VisualStudio-Path - Write-Verbose "Visual Studio location: $vsPath" - - [string] $platformToolset = Get-ProjectPlatformToolset - - if ($aVisualStudioVersion -eq "2015") - { - $returnArray += Get-VisualStudio-Includes -vsPath $vsPath - } - else - { - $mscVer = Get-MscVer -visualStudioPath $vsPath - Write-Verbose "MSCVER: $mscVer" - - $returnArray += Get-VisualStudio-Includes -vsPath $vsPath -mscVer $mscVer - } - - $sdkVer = Get-Project-SDKVer - - # We did not find a WinSDK version in the vcxproj. We use Visual Studio's defaults - if ([string]::IsNullOrEmpty($sdkVer)) - { - if ($platformToolset.EndsWith("xp")) - { - $sdkVer = $kVSDefaultWinSDK_XP - } - else - { - $sdkVer = $kVSDefaultWinSDK - } - } - - Write-Verbose "WinSDK version: $sdkVer" - - # ---------------------------------------------------------------------------------------------- - # Windows 10 + [string[]] $projects = @() - if ((![string]::IsNullOrEmpty($sdkVer)) -and ($sdkVer.StartsWith("10"))) + foreach ($slnPath in $global:slnFiles.Keys) { - $returnArray += @("${Env:ProgramFiles(x86)}\Windows Kits\10\Include\$sdkVer\ucrt") - - if ($platformToolset.EndsWith("xp")) - { - $returnArray += @($kIncludePathsXPTargetingSDK) - } - else + [string[]] $solutionProjects = Get-SolutionProjects -slnPath $slnPath + if ($solutionProjects.Count -gt 0) { - $returnArray += @( "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\$sdkVer\um" - , "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\$sdkVer\shared" - , "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\$sdkVer\winrt" - ) - } - } - - # ---------------------------------------------------------------------------------------------- - # Windows 8 / 8.1 - - if ((![string]::IsNullOrEmpty($sdkVer)) -and ($sdkVer.StartsWith("8."))) - { - $returnArray += @("${Env:ProgramFiles(x86)}\Windows Kits\10\Include\10.0.10240.0\ucrt") - - if ($platformToolset.EndsWith("xp")) - { - $returnArray += @($kIncludePathsXPTargetingSDK) - } - else - { - $returnArray += @( "${Env:ProgramFiles(x86)}\Windows Kits\$sdkVer\Include\um" - , "${Env:ProgramFiles(x86)}\Windows Kits\$sdkVer\Include\shared" - , "${Env:ProgramFiles(x86)}\Windows Kits\$sdkVer\Include\winrt" - ) - } - } - - # ---------------------------------------------------------------------------------------------- - # Windows 7 - - if ((![string]::IsNullOrEmpty($sdkVer)) -and ($sdkVer.StartsWith("7.0"))) - { - $returnArray += @("$vsPath\VC\Auxiliary\VS\include") - - if ($platformToolset.EndsWith("xp")) - { - $returnArray += @( "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\10.0.10240.0\ucrt" - , $kIncludePathsXPTargetingSDK - ) - } - else - { - $returnArray += @( "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\7.0\ucrt") - } - } - - if (![string]::IsNullOrEmpty($stdafxDir)) - { - $returnArray = @($stdafxDir) + $returnArray - } - - return ( $returnArray | ForEach-Object { $_ -replace '\\$', '' } ) -} - -Function Get-Projects() -{ - [string[]] $projects = @() - - foreach ($slnPath in $global:slnFiles.Keys) - { - [string[]] $solutionProjects = Get-SolutionProjects -slnPath $slnPath - if ($solutionProjects.Count -gt 0) - { - $projects += $solutionProjects + $projects += $solutionProjects } } return ($projects | Select -Unique); } -Function Get-PchCppIncludeHeader([Parameter(Mandatory=$true)][string] $pchCppFile) -{ - [string] $cppPath = Canonize-Path -base $ProjectDir -child $pchCppFile - [string] $fileContent = Get-Content -path $cppPath - - return [regex]::match($fileContent,'#include "(\S+)"').Groups[1].Value -} - -<# -.DESCRIPTION - Retrieve directory in which stdafx.h resides -#> -Function Get-ProjectStdafxDir([Parameter(Mandatory=$true)][string] $pchHeaderName) -{ - [string[]] $projectHeaders = Get-ProjectHeaders - [string] $stdafxPath = $projectHeaders | Where-Object { (Get-FileName -path $_) -cmatch $pchHeaderName } - if ([string]::IsNullOrEmpty($stdafxPath)) - { - $stdafxPath = Canonize-Path -base $ProjectDir ` - -child $pchHeaderName - } - - [string] $stdafxDir = Get-FileDirectory($stdafxPath) - - return $stdafxDir -} - -<# -.DESCRIPTION - Retrieve directory in which the PCH CPP resides (e.g. stdafx.cpp, stdafxA.cpp) -#> -Function Get-Project-PchCpp() -{ - $pchCppRelativePath = Select-ProjectNodes($kVcxprojXpathPCH) | - Select-Object -ExpandProperty ParentNode | - Select-Object -first 1 | - Select-Object -ExpandProperty Include - - return $pchCppRelativePath -} - -Function Get-ClangIncludeDirectories( [Parameter(Mandatory=$false)][string[]] $includeDirectories - , [Parameter(Mandatory=$false)][string[]] $additionalIncludeDirectories - ) -{ - [string[]] $returnDirs = @() - - foreach ($includeDir in $includeDirectories) - { - $returnDirs += "-isystem""$includeDir""" - } - foreach ($includeDir in $additionalIncludeDirectories) - { - if ($aTreatAdditionalIncludesAsSystemIncludes) - { - $returnDirs += "-isystem""$includeDir""" - } - else - { - $returnDirs += "-I""$includeDir""" - } - } - - return $returnDirs -} - -Function Generate-Pch( [Parameter(Mandatory=$true)] [string] $stdafxDir - , [Parameter(Mandatory=$false)][string[]] $includeDirectories - , [Parameter(Mandatory=$false)][string[]] $additionalIncludeDirectories - , [Parameter(Mandatory=$true)] [string] $stdafxHeaderName - , [Parameter(Mandatory=$false)][string[]] $preprocessorDefinitions) -{ - [string] $stdafx = (Canonize-Path -base $stdafxDir -child $stdafxHeaderName) - [string] $vcxprojShortName = [System.IO.Path]::GetFileNameWithoutExtension($global:vcxprojPath); - [string] $stdafxPch = (Join-Path -path (Get-SourceDirectory) ` - -ChildPath "$vcxprojShortName$kExtensionClangPch") - Remove-Item -Path "$stdafxPch" -ErrorAction SilentlyContinue | Out-Null - - $global:FilesToDeleteWhenScriptQuits.Add($stdafxPch) | Out-Null - - # Supress -Werror for PCH generation as it throws warnings quite often in code we cannot control - [string[]] $clangFlags = Get-ClangCompileFlags | Where-Object { $_ -ne $kClangFlagWarningIsError } - - [string[]] $compilationFlags = @("""$stdafx""" - ,$kClangFlagEmitPch - ,$kClangFlagMinusO - ,"""$stdafxPch""" - ,$clangFlags - ,$kClangFlagNoUnusedArg - ,$preprocessorDefinitions - ) - - $compilationFlags += Get-ClangIncludeDirectories -includeDirectories $includeDirectories ` - -additionalIncludeDirectories $additionalIncludeDirectories - - Write-Verbose "INVOKE: ""$($global:llvmLocation)\$kClangCompiler"" $compilationFlags" - - [System.Diagnostics.Process] $processInfo = Start-Process -FilePath $kClangCompiler ` - -ArgumentList $compilationFlags ` - -WorkingDirectory "$(Get-SourceDirectory)" ` - -NoNewWindow ` - -Wait ` - -PassThru - if ($processInfo.ExitCode -ne 0) - { - Fail-Script "Errors encountered during PCH creation" - } - - return $stdafxPch -} - -function HasTrailingSlash([Parameter(Mandatory=$true)][string] $str) -{ - return $str.EndsWith('\') -or $str.EndsWith('/') -} - -function Exists([Parameter(Mandatory=$false)][string] $path) -{ - if ([string]::IsNullOrEmpty($path)) - { - return $false - } - - return Test-Path $path -} - -function GetRegValue([Parameter(Mandatory=$true)][string] $regPath) -{ - Write-Debug "REG_READ $regPath" - - [int] $separatorIndex = $regPath.IndexOf('@') - [string] $valueName = "" - if ($separatorIndex -gt 0) - { - [string] $valueName = $regPath.Substring($separatorIndex + 1) - $regPath = $regPath.Substring(0, $separatorIndex) - } - if ([string]::IsNullOrEmpty($valueName)) - { - throw "Cannot retrieve an empty registry value" - } - $regPath = $regPath -replace "HKEY_LOCAL_MACHINE\\", "HKLM:\" - - if (Test-Path $regPath) - { - return (Get-Item $regPath).GetValue($valueName) - } - else - { - return "" - } -} - -function Evaluate-MSBuildExpression([string] $expression, [switch] $isCondition) -{ - Write-Debug "Start evaluate MSBuild expression $expression" - - foreach ($rule in $kMsbuildExpressionToPsRules) - { - $expression = $expression -replace $rule[0], $rule[1] - } - - if ( !$isCondition -and ($expression.IndexOf('$') -lt 0)) - { - # we can stop here, further processing is not required - return $expression - } - - [int] $expressionStartIndex = -1 - [int] $openParantheses = 0 - for ([int] $i = 0; $i -lt $expression.Length; $i += 1) - { - if ($expression.Substring($i, 1) -eq '(') - { - if ($i -gt 0 -and $expressionStartIndex -lt 0 -and $expression.Substring($i - 1, 1) -eq '$') - { - $expressionStartIndex = $i - 1 - } - - if ($expressionStartIndex -ge 0) - { - $openParantheses += 1 - } - } - - if ($expression.Substring($i, 1) -eq ')' -and $expressionStartIndex -ge 0) - { - $openParantheses -= 1 - if ($openParantheses -lt 0) - { - throw "Parse error" - } - if ($openParantheses -eq 0) - { - [string] $content = $expression.Substring($expressionStartIndex + 2, - $i - $expressionStartIndex - 2) - [int] $initialLength = $content.Length - - if ([regex]::Match($content, "[a-zA-Z_][a-zA-Z0-9_\-]+").Value -eq $content) - { - # we have a plain property retrieval - $content = "`${$content}" - } - else - { - # dealing with a more complex expression - $content = $content -replace '(^|\s+|\$\()([a-zA-Z_][a-zA-Z0-9_]+)(\.|\)|$)', '$1$$$2$3' - } - - $newCond = $expression.Substring(0, $expressionStartIndex + 2) + - $content + $expression.Substring($i) - $expression = $newCond - - $i += ($content.Length - $initialLength) - $expressionStartIndex = -1 - } - } - } - - Write-Debug "Intermediate PS expression: $expression" - - try - { - [string] $toInvoke = "(`$s = ""$expression"")" - if ($isCondition) - { - $toInvoke = "(`$s = ""`$($expression)"")" - } - - $res = Invoke-Expression $toInvoke - } - catch - { - write-debug $_.Exception.Message - } - - Write-Debug "Evaluated expression to: $res" - - return $res -} -function Evaluate-MSBuildCondition([Parameter(Mandatory=$true)][string] $condition) -{ - Write-Debug "Evaluating condition $condition" - foreach ($rule in $kMsbuildConditionToPsRules) - { - $condition = $condition -replace $rule[0], $rule[1] - } - $expression = Evaluate-MSBuildExpression -expression $condition -isCondition - - if ($expression -ieq "true") - { - return $true - } - - if ($expression -ieq "false") - { - return $false - } - - [bool] $res = $false - try - { - $res = (Invoke-Expression $expression) -eq $true - } - catch - { - Write-Debug $_.Exception.Message - } - Write-Debug "Evaluated condition to $res" - - return $res -} - -<# -.DESCRIPTION -A wrapper over the XmlDOcument.SelectNodes function. For convenience. -Not to be used directly. Please use Select-ProjectNodes instead. -#> -function Help:Get-ProjectFileNodes([xml] $projectFile, [string] $xpath) -{ - [System.Xml.XmlElement[]] $nodes = $projectFile.SelectNodes($xpath, $global:xpathNS) - return $nodes -} - -function GetNodeInheritanceToken([System.Xml.XmlNode] $node) -{ - [string] $inheritanceToken = "%($($node.Name))"; - if ($node.InnerText.Contains($inheritanceToken)) - { - return $inheritanceToken - } - - return "" -} - -function ReplaceInheritedNodeValue([System.Xml.XmlNode] $currentNode - ,[System.Xml.XmlNode] $nodeToInheritFrom - ) -{ - [string] $inheritanceToken = GetNodeInheritanceToken($currentNode) - if ([string]::IsNullOrEmpty($inheritanceToken)) - { - # no need to inherit - return $false - } - - [string] $replaceWith = "" - if ($nodeToInheritFrom) - { - $replaceWith = $nodeToInheritFrom.InnerText - } - - [string] $whatToReplace = [regex]::Escape($inheritanceToken); - if ([string]::IsNullOrEmpty($replaceWith)) - { - # handle semicolon separators - [string] $escTok = [regex]::Escape($inheritanceToken) - $whatToReplace = "(;$escTok)|($escTok;)|($escTok)" - } - - # replace inherited token and redundant separators - $replacementRules = @(,($whatToReplace, $replaceWith)) + $kRedundantSeparatorsReplaceRules - foreach ($rule in $replacementRules) - { - $currentNode.InnerText = $currentNode.InnerText -replace $rule[0], $rule[1] - } - - return $currentNode.InnerText.Contains($inheritanceToken) -} - -<# -.SYNOPSIS -Selects one or more nodes from the project. -.DESCRIPTION -We often need to access data from the project, e.g. additional includes, Win SDK version. -A naive implementation would be to simply look inside the vcxproj, but that leaves out -property sheets. - -This function takes care to retrieve the nodes we're searching by looking in both the .vcxproj -and property sheets, taking care to inherit values accordingly. -.EXAMPLE -Give an example of how to use it -.EXAMPLE -Give another example of how to use it. -.PARAMETER xpath -XPath we want to use for searching nodes. -.PARAMETER fileIndex -Optional. Index of the project xml file we want to start our search in. -0 = .vcxproj and then, recursively, all property sheets -1 = first property sheet and then, recursively, all other property sheets -etc. -#> -function Select-ProjectNodes([Parameter(Mandatory=$true)] [string][string] $xpath - ,[Parameter(Mandatory=$false)] [int] $fileIndex = 0) -{ - [System.Xml.XmlElement[]] $nodes = @() - - if ($fileIndex -ge $global:projectFiles.Count) - { - return $nodes - } - - $nodes = Help:Get-ProjectFileNodes -projectFile $global:projectFiles[$fileIndex] ` - -xpath $xpath - - # nothing on this level or we're dealing with an ItemGroup, go above - if ($nodes.Count -eq 0 -or $xpath.Contains("ItemGroup")) - { - [System.Xml.XmlElement[]] $upperNodes = Select-ProjectNodes -xpath $xpath -fileIndex ($fileIndex + 1) - if ($upperNodes.Count -gt 0) - { - $nodes += $upperNodes - } - return $nodes - } - - if ($nodes[$nodes.Count -1]."#text") - { - # we found textual settings that can be inherited. see if we should inherit - - [System.Xml.XmlNode] $nodeToReturn = $nodes[$nodes.Count -1] - if ($nodeToReturn.Attributes.Count -gt 0) - { - throw "Did not expect node to have attributes" - } - - [bool] $shouldInheritMore = ![string]::IsNullOrEmpty((GetNodeInheritanceToken -node $nodeToReturn)) - for ([int] $i = $nodes.Count - 2; ($i -ge 0) -and $shouldInheritMore; $i -= 1) - { - $shouldInheritMore = ReplaceInheritedNodeValue -currentNode $nodeToReturn -nodeToInheritFrom $nodes[$i] - } - - if ($shouldInheritMore) - { - [System.Xml.XmlElement[]] $inheritedNodes = Select-ProjectNodes -xpath $xpath -fileIndex ($fileIndex + 1) - if ($inheritedNodes.Count -gt 1) - { - throw "Did not expect to inherit more than one node" - } - if ($inheritedNodes.Count -eq 1) - { - $shouldInheritMore = ReplaceInheritedNodeValue -currentNode $nodeToReturn -nodeToInheritFrom $inheritedNodes[0] - } - } - - # we still could have to inherit from parents but when not loading - # all MS prop sheets we have nothing to inherit from, delete inheritance token - ReplaceInheritedNodeValue -currentNode $nodeToReturn -nodeToInheritFrom $null | Out-Null - - return @($nodeToReturn) - } - else - { - # return what we found - return $nodes - } -} - -<# -.DESCRIPTION - Finds the first config-platform pair in the vcxproj. - We'll use it for all project data retrievals. - - Items for other config-platform pairs will be removed from the DOM. - This is needed so that our XPath selectors don't get confused when looking for data. -#> -function Detect-ProjectDefaultConfigPlatform([string] $projectValue) -{ - [string]$configPlatformName = "" - - if (![string]::IsNullOrEmpty($aVcxprojConfigPlatform)) - { - $configPlatformName = $aVcxprojConfigPlatform - } - else - { - $configPlatformName = $projectValue - } - - if ([string]::IsNullOrEmpty($configPlatformName)) - { - throw "Could not automatically detect a configuration platform" - } - - [string[]] $configAndPlatform = $configPlatformName.Split('|') - Set-Var -Name "Configuration" -Value $configAndPlatform[0] - Set-Var -Name "Platform" -Value $configAndPlatform[1] -} - -function HandleChooseNode([System.Xml.XmlNode] $aChooseNode) -{ - SanitizeProjectNode $aChooseNode - if ($aChooseNode.ChildNodes.Count -eq 0) - { - return - } - - [System.Xml.XmlElement] $selectedChild = $aChooseNode.ChildNodes | ` - Where-Object { $_.GetType().Name -eq "XmlElement" } | ` - Select -first 1 - - foreach ($selectedGrandchild in $selectedChild.ChildNodes) - { - $aChooseNode.ParentNode.AppendChild($selectedGrandchild.Clone()) | Out-Null - } - - $aChooseNode.ParentNode.RemoveChild($aChooseNode) | Out-Null -} - -function SanitizeProjectNode([System.Xml.XmlNode] $node) -{ - if ($node.Name -ieq "#comment") - { - return - } - - [System.Collections.ArrayList] $nodesToRemove = @() - - if ($node.Name -ieq "#text" -and $node.InnerText.Length -gt 0) - { - # evaluate node content - $node.InnerText = Evaluate-MSBuildExpression $node.InnerText - } - - if ($node.Name -ieq "Import") - { - [string] $relPath = Evaluate-MSBuildExpression $node.GetAttribute("Project") - [string[]] $paths = Canonize-Path -base (Get-Location) -child $relPath -ignoreErrors - - foreach ($path in $paths) - { - if (![string]::IsNullOrEmpty($path) -and (Test-Path $path)) - { - Write-Verbose "Property sheet: $path" - SanitizeProjectFile($path) - } - else - { - Write-Verbose "Could not find property sheet $relPath" - } - } - } - - if ( ($node.Name -ieq "ClCompile" -or $node.Name -ieq "ClInclude") -and - ![string]::IsNullOrEmpty($node.GetAttribute("Include")) ) - { - [string] $expandedAttr = Evaluate-MSBuildExpression $node.GetAttribute("Include") - $node.Attributes["Include"].Value = $expandedAttr - } - - if ($node.Name -ieq "Choose") - { - HandleChooseNode $chooseChild - } - - if ($node.Name -ieq "Otherwise") - { - [System.Xml.XmlElement[]] $siblings = $node.ParentNode.ChildNodes | ` - Where-Object { $_.GetType().Name -ieq "XmlElement" -and $_ -ne $node } - if ($siblings.Count -gt 0) - { - # means there's a element that matched - # should not be evaluated, we could set unwated properties - return - } - } - - if ($node.Name -ieq "ItemGroup" -and $node.GetAttribute("Label") -ieq "ProjectConfigurations") - { - Detect-ProjectDefaultConfigPlatform $node.ChildNodes[0].GetAttribute("Include") - } - - if ($node.ParentNode.Name -ieq "PropertyGroup") - { - # set new property value - [string] $propertyName = $node.Name - [string] $propertyValue = Evaluate-MSBuildExpression $node.InnerText - - Set-Var -Name $propertyName -Value $propertyValue - - return - } - - foreach ($child in $node.ChildNodes) - { - [bool] $validChild = $true - if ($child.GetType().Name -ieq "XmlElement") - { - if ($child.HasAttribute("Condition")) - { - # process node condition - [string] $nodeCondition = $child.GetAttribute("Condition") - $validChild = ((Evaluate-MSBuildCondition($nodeCondition)) -eq $true) - if ($validChild) - { - $child.RemoveAttribute("Condition") - } - } - } - if (!$validChild) - { - $nodesToRemove.Add($child) | out-null - continue - } - else - { - SanitizeProjectNode($child) - } - } - - foreach ($nodeToRemove in $nodesToRemove) - { - $nodeToRemove.ParentNode.RemoveChild($nodeToRemove) | out-null - } -} - -<# -.DESCRIPTION - Sanitizes a project xml file, by removing config-platform pairs different from the - one we selected. - This is needed so that our XPath selectors don't get confused when looking for data. -#> -function SanitizeProjectFile([string] $projectFilePath) -{ - Write-Verbose "`nSanitizing $projectFilePath" - - [xml] $fileXml = Get-Content $projectFilePath - $global:projectFiles += @($fileXml) - $global:xpathNS = New-Object System.Xml.XmlNamespaceManager($fileXml.NameTable) - $global:xpathNS.AddNamespace("ns", $fileXml.DocumentElement.NamespaceURI) - - Push-Location (Get-FileDirectory -filePath $projectFilePath) - - InitializeMsBuildCurrentFileProperties -filePath $projectFilePath - SanitizeProjectNode($fileXml.Project) - - Pop-Location -} - -<# -.DESCRIPTION - Tries to find a Directory.Build.props property sheet, starting from the - project directories, going up. When one is found, the search stops. - - Multiple Directory.Build.props sheets are not supported. -#> -function Get-AutoPropertySheet() +Function Get-ClangIncludeDirectories( [Parameter(Mandatory=$false)][string[]] $includeDirectories + , [Parameter(Mandatory=$false)][string[]] $additionalIncludeDirectories + ) { - $startPath = $global:vcxprojPath - while ($true) + [string[]] $returnDirs = @() + + foreach ($includeDir in $includeDirectories) + { + $returnDirs += "-isystem""$includeDir""" + } + foreach ($includeDir in $additionalIncludeDirectories) { - $propSheetPath = Canonize-Path -base $startPath ` - -child "Directory.Build.props" ` - -ignoreErrors - if (![string]::IsNullOrEmpty($propSheetPath)) + if ($aTreatAdditionalIncludesAsSystemIncludes) { - return $propSheetPath + $returnDirs += "-isystem""$includeDir""" } - - $newPath = Canonize-Path -base $startPath -child ".." - if ($newPath -eq $startPath) + else { - return "" + $returnDirs += "-I""$includeDir""" } - $startPath = $newPath } + + return $returnDirs } -<# -.DESCRIPTION -Loads vcxproj and property sheets into memory. This needs to be called only once -when processing a project. Accessing project nodes can be done using Select-ProjectNodes. -#> -function LoadProject([string] $vcxprojPath) +Function Generate-Pch( [Parameter(Mandatory=$true)] [string] $stdafxDir + , [Parameter(Mandatory=$false)][string[]] $includeDirectories + , [Parameter(Mandatory=$false)][string[]] $additionalIncludeDirectories + , [Parameter(Mandatory=$true)] [string] $stdafxHeaderName + , [Parameter(Mandatory=$false)][string[]] $preprocessorDefinitions) { - $global:vcxprojPath = $vcxprojPath - - InitializeMsBuildProjectProperties - - # see if we can find a Directory.Build.props automatic prop sheet - [string[]] $propSheetAbsolutePaths = @() - [xml[]] $autoPropSheetXmls = $null - $autoPropSheet = Get-AutoPropertySheet - if (![string]::IsNullOrEmpty($autoPropSheet)) + if (Is-CProject) { - SanitizeProjectFile -projectFilePath $autoPropSheet - $autoPropSheetXmls = $global:projectFiles + Write-Verbose "Skipping PCH creation for C project." + return "" } - # the auto-prop sheet has to be last in the node retrieval sources - # but properties defined in it have to be accessible in all project files :( - $global:projectFiles = @() + [string] $stdafx = (Canonize-Path -base $stdafxDir -child $stdafxHeaderName) + [string] $vcxprojShortName = [System.IO.Path]::GetFileNameWithoutExtension($global:vcxprojPath); + [string] $stdafxPch = (Join-Path -path (Get-SourceDirectory) ` + -ChildPath "$vcxprojShortName$kExtensionClangPch") + Remove-Item -Path "$stdafxPch" -ErrorAction SilentlyContinue | Out-Null + + $global:FilesToDeleteWhenScriptQuits.Add($stdafxPch) | Out-Null - SanitizeProjectFile -projectFilePath $global:vcxprojPath + # Suppress -Werror for PCH generation as it throws warnings quite often in code we cannot control + [string[]] $clangFlags = Get-ClangCompileFlags | Where-Object { $_ -ne $kClangFlagWarningIsError } - if ($autoPropSheetXml) - { - $global:projectFiles += $autoPropSheetXmls - } -} + [string[]] $compilationFlags = @("""$stdafx""" + ,$kClangFlagEmitPch + ,$kClangFlagMinusO + ,"""$stdafxPch""" + ,$clangFlags + ,$kClangFlagNoUnusedArg + ,$preprocessorDefinitions + ) -<# -.DESCRIPTION - Retrieve array of preprocessor definitions for a given project, in Clang format (-DNAME ) -#> -Function Get-ProjectPreprocessorDefines() -{ - [string[]] $tokens = (Select-ProjectNodes $kVcxprojXpathPreprocessorDefs).InnerText -split ";" + $compilationFlags += Get-ClangIncludeDirectories -includeDirectories $includeDirectories ` + -additionalIncludeDirectories $additionalIncludeDirectories - # make sure we add the required prefix and escape double quotes - [string[]]$defines = ( $tokens | ` - Where-Object { $_ } | ` - ForEach-Object { '"' + $(($kClangDefinePrefix + $_) -replace '"','\"') + '"' } ) + # Remove empty arguments from the list because Start-Process will complain + $compilationFlags = $compilationFlags | Where-Object { $_ } | Select -Unique - if (Is-Project-Unicode) - { - $defines += $kDefinesUnicode - } + Write-Verbose "INVOKE: ""$($global:llvmLocation)\$kClangCompiler"" $compilationFlags" - [string] $platformToolset = Get-ProjectPlatformToolset - if ($platformToolset.EndsWith("xp")) + [System.Diagnostics.Process] $processInfo = Start-Process -FilePath $kClangCompiler ` + -ArgumentList $compilationFlags ` + -WorkingDirectory "$(Get-SourceDirectory)" ` + -NoNewWindow ` + -Wait ` + -PassThru + if (($processInfo.ExitCode -ne 0) -and (!$aContinueOnError)) { - $defines += $kDefinesClangXpTargeting + Fail-Script "Errors encountered during PCH creation" } - return $defines -} - -Function Get-ProjectAdditionalIncludes() -{ - [string[]] $tokens = @() - - $data = Select-ProjectNodes $kVcxprojXpathAdditionalIncludes - $tokens += ($data).InnerText -split ";" - - foreach ($token in $tokens) + if (Test-Path $stdafxPch) { - if ([string]::IsNullOrEmpty($token)) - { - continue - } - - [string] $includePath = Canonize-Path -base $ProjectDir -child $token -ignoreErrors - if (![string]::IsNullOrEmpty($includePath)) - { - $includePath -replace '\\$', '' - } + return $stdafxPch } -} - -Function Get-ProjectForceIncludes() -{ - [System.Xml.XmlElement] $forceIncludes = Select-ProjectNodes $kVcxprojXpathForceIncludes - if ($forceIncludes) + else { - return $forceIncludes.InnerText -split ";" + return "" } - - return $null } Function Get-ExeToCall([Parameter(Mandatory=$true)][WorkloadType] $workloadType) @@ -1724,14 +480,22 @@ Function Get-CompileCallArguments( [Parameter(Mandatory=$false)][string[]] $prep , [Parameter(Mandatory=$true)][string] $fileToCompile) { [string[]] $projectCompileArgs = @() - if (! [string]::IsNullOrEmpty($pchFilePath)) + if (! [string]::IsNullOrEmpty($pchFilePath) -and ! $fileToCompile.EndsWith($kExtensionC)) { $projectCompileArgs += @($kClangFlagIncludePch , """$pchFilePath""") } - - $projectCompileArgs += @( $kClangFlagFileIsCPP + + $isCpp = $true + $languageFlag = $kClangFlagFileIsCPP + if ($fileToCompile.EndsWith($kExtensionC)) + { + $isCpp = $false + $languageFlag = $kClangFlagFileIsC + } + + $projectCompileArgs += @( $languageFlag , """$fileToCompile""" - , @(Get-ClangCompileFlags) + , @(Get-ClangCompileFlags -isCpp $isCpp) , $kClangFlagSupressLINK , $preprocessorDefinitions ) @@ -1742,7 +506,7 @@ Function Get-CompileCallArguments( [Parameter(Mandatory=$false)][string[]] $prep if ($forceIncludeFiles) { $projectCompileArgs += $kClangFlagNoMsInclude; - + foreach ($file in $forceIncludeFiles) { $projectCompileArgs += "$kClangFlagForceInclude $file" @@ -1764,7 +528,7 @@ Function Get-TidyCallArguments( [Parameter(Mandatory=$false)][string[]] $preproc if ($fix -and $aTidyFixFlags -ne $kClangTidyUseFile) { $tidyArgs += "$kClangTidyFlagChecks$aTidyFixFlags" - } + } elseif ($aTidyFlags -ne $kClangTidyUseFile) { $tidyArgs += "$kClangTidyFlagChecks$aTidyFlags" @@ -1793,20 +557,28 @@ Function Get-TidyCallArguments( [Parameter(Mandatory=$false)][string[]] $preproc $tidyArgs += $kClangTidyFixFlags } - else + else { $tidyArgs += $kClangTidyFlags } - + $tidyArgs += Get-ClangIncludeDirectories -includeDirectories $includeDirectories ` -additionalIncludeDirectories $additionalIncludeDirectories - + + $isCpp = $true + $languageFlag = $kClangFlagFileIsCPP + if ($fileToTidy.EndsWith($kExtensionC)) + { + $isCpp = $false + $languageFlag = $kClangFlagFileIsC + } + # We reuse flags used for compilation and preprocessor definitions. - $tidyArgs += @(Get-ClangCompileFlags) + $tidyArgs += @(Get-ClangCompileFlags -isCpp $isCpp) $tidyArgs += $preprocessorDefinitions - $tidyArgs += $kClangFlagFileIsCPP - - if (! [string]::IsNullOrEmpty($pchFilePath)) + $tidyArgs += $languageFlag + + if (! [string]::IsNullOrEmpty($pchFilePath) -and ! $fileToTidy.EndsWith($kExtensionC)) { $tidyArgs += @($kClangFlagIncludePch , """$pchFilePath""") } @@ -1814,7 +586,7 @@ Function Get-TidyCallArguments( [Parameter(Mandatory=$false)][string[]] $preproc if ($forceIncludeFiles) { $tidyArgs += $kClangFlagNoMsInclude; - + foreach ($file in $forceIncludeFiles) { $tidyArgs += "$kClangFlagForceInclude $file" @@ -1871,7 +643,7 @@ Function Process-ProjectResult($compileResult) $global:FoundErrors = $true } - else + else { if ( $compileResult.Output.Length -gt 0) { @@ -1908,7 +680,7 @@ Function Wait-ForWorkerJobSlot() # We allow as many background workers as we have logical CPU cores $runningJobs = @(Get-Job -State Running) - if ($runningJobs.Count -ge $kLogicalCoreCount) + if ($runningJobs.Count -ge $kLogicalCoreCount) { Wait-AndProcessBuildJobs -any } @@ -1920,20 +692,46 @@ Function Run-ClangJobs([Parameter(Mandatory=$true)] $clangJobs) $jobWorkToBeDone = ` { param( $job ) - + Push-Location $job.WorkingDirectory - $callOutput = & $job.FilePath $job.ArgumentList.Split(' ') 2>&1 |` - ForEach-Object { $_.ToString() } |` - Out-String + [string] $clangConfigFile = [System.IO.Path]::GetTempFileName() + + [string] $clangConfigContent = "" + if ($job.FilePath -like '*tidy*') + { + # We have to separate Clang args from Tidy args + $splitparams = $job.ArgumentList -split "--" + $clangConfigContent = $splitparams[1] + $job.ArgumentList = ($splitparams[0] + " -- --config ""$clangConfigFile""") + } + else + { + # Tell Clang to take its args from a config file + $clangConfigContent = $job.ArgumentList + $job.ArgumentList = "--config ""$clangConfigFile""" + } + + # escape slashes for file paths + # make sure escaped double quotes are not messed up + $clangConfigContent = $clangConfigContent -replace '\\([^"])', '\\$1' + + # save arguments to clang config file + $clangConfigContent > $clangConfigFile + + # When PowerShell encounters errors, the first one is handled differently from consecutive ones + # To circumvent this, do not execute the job directly, but execute it via cmd.exe + # See also https://stackoverflow.com/a/35980675 + $callOutput = cmd /c $job.FilePath $job.ArgumentList.Split(' ') '2>&1' | Out-String $callSuccess = $LASTEXITCODE -eq 0 + Remove-Item $clangConfigFile Pop-Location return New-Object PsObject -Prop @{ "File" = $job.File; "Success" = $callSuccess; - "Output" = $callOutput } + "Output" = $callOutput } } [int] $jobCount = $clangJobs.Count @@ -1968,23 +766,76 @@ Function Run-ClangJobs([Parameter(Mandatory=$true)] $clangJobs) Function Process-Project( [Parameter(Mandatory=$true)][string] $vcxprojPath , [Parameter(Mandatory=$true)][WorkloadType] $workloadType) -{ +{ + #----------------------------------------------------------------------------------------------- # Load data LoadProject($vcxprojPath) + #----------------------------------------------------------------------------------------------- + # DETECT PLATFORM TOOLSET + + [string] $platformToolset = Get-ProjectPlatformToolset + Write-Verbose "Platform toolset: $platformToolset" + + if ( ([int]$platformToolset.Remove(0, 1).Replace("_xp", "")) -le 140) + { + if ($global:cptVisualStudioVersion -ne '2015') + { + # we need to reload everything and use VS2015 + Write-Verbose "Switching to VS2015 because of v140 toolset. Reloading project..." + $global:cptVisualStudioVersion = "2015" + LoadProject($vcxprojPath) + } + } + else + { + if ($global:cptVisualStudioVersion -ne $global:cptDefaultVisualStudioVersion) + { + # we need to reload everything and the default vs version + Write-Verbose "Switching to default VsVer because of toolset. Reloading project..." + $global:cptVisualStudioVersion = $global:cptDefaultVisualStudioVersion + LoadProject($vcxprojPath) + } + } + #----------------------------------------------------------------------------------------------- # FIND FORCE INCLUDES [string[]] $forceIncludeFiles = Get-ProjectForceIncludes Write-Verbose "Force includes: $forceIncludeFiles" + #----------------------------------------------------------------------------------------------- + # DETECT PROJECT PREPROCESSOR DEFINITIONS + + [string[]] $preprocessorDefinitions = Get-ProjectPreprocessorDefines + if ($global:cptVisualStudioVersion -eq "2017") + { + # [HACK] pch generation crashes on VS 15.5 because of STL library, known bug. + # Triggered by addition of line directives to improve std::function debugging. + # There's a definition that supresses line directives. + + $preprocessorDefinitions += "-D_DEBUG_FUNCTIONAL_MACHINERY" + } + + Write-Verbose-Array -array $preprocessorDefinitions -name "Preprocessor definitions" + + #----------------------------------------------------------------------------------------------- + # DETECT PROJECT ADDITIONAL INCLUDE DIRECTORIES AND CONSTRUCT INCLUDE PATHS + + [string[]] $additionalIncludeDirectories = Get-ProjectAdditionalIncludes + Write-Verbose-Array -array $additionalIncludeDirectories -name "Additional include directories" + + [string[]] $includeDirectories = Get-ProjectIncludeDirectories + Write-Verbose-Array -array $includeDirectories -name "Include directories" + #----------------------------------------------------------------------------------------------- # LOCATE STDAFX.H DIRECTORY [string] $stdafxCpp = Get-Project-PchCpp [string] $stdafxDir = "" [string] $stdafxHeader = "" - + [string] $stdafxHeaderFullPath = "" + if (![string]::IsNullOrEmpty($stdafxCpp)) { Write-Verbose "PCH cpp name: $stdafxCpp" @@ -1993,14 +844,26 @@ Function Process-Project( [Parameter(Mandatory=$true)][string] $vcxprojPat { $stdafxHeader = $forceIncludeFiles[0] } - else + + if (!$stdafxHeader) { $stdafxHeader = Get-PchCppIncludeHeader -pchCppFile $stdafxCpp } + if (!$stdafxHeader) + { + $pchNode = Select-ProjectNodes "//ns:ClCompile[@Include='$stdafxCpp']/ns:PrecompiledHeaderFile" + if ($pchNode) + { + $stdafxHeader = $pchNode.InnerText + } + } + Write-Verbose "PCH header name: $stdafxHeader" - $stdafxDir = Get-ProjectStdafxDir -pchHeaderName $stdafxHeader - } + $stdafxDir = Get-ProjectStdafxDir -pchHeaderName $stdafxHeader ` + -includeDirectories $includeDirectories ` + -additionalIncludeDirectories $additionalIncludeDirectories + } if ([string]::IsNullOrEmpty($stdafxDir)) { @@ -2009,59 +872,72 @@ Function Process-Project( [Parameter(Mandatory=$true)][string] $vcxprojPat else { Write-Verbose ("PCH directory: $stdafxDir") + + $includeDirectories = @(Remove-PathTrailingSlash -path $stdafxDir) + $includeDirectories + + $stdafxHeaderFullPath = Canonize-Path -base $stdafxDir -child $stdafxHeader -ignoreErrors } + #----------------------------------------------------------------------------------------------- - # DETECT PROJECT PREPROCESSOR DEFINITIONS + # FIND LIST OF CPPs TO PROCESS - [string[]] $preprocessorDefinitions = Get-ProjectPreprocessorDefines - if ($aVisualStudioVersion -eq "2017") + [System.Collections.Hashtable] $projCpps = @{} + foreach ($fileToCompileInfo in (Get-ProjectFilesToCompile -pchCppName $stdafxCpp)) { - # [HACK] pch generation crashes on VS 15.5 because of STL library, known bug. - # Triggered by addition of line directives to improve std::function debugging. - # There's a definition that supresses line directives. - - [string] $mscVer = Get-MscVer -visualStudioPath $vsPath - if ($mscVer -eq "14.12.25827") + if ($fileToCompileInfo.File) { - $preprocessorDefinitions += "-D_DEBUG_FUNCTIONAL_MACHINERY" + $projCpps[$fileToCompileInfo.File] = $fileToCompileInfo } } - - Write-Verbose-Array -array $preprocessorDefinitions -name "Preprocessor definitions" - - #----------------------------------------------------------------------------------------------- - # DETECT PLATFORM TOOLSET - - [string] $platformToolset = Get-ProjectPlatformToolset - Write-Verbose "Platform toolset: $platformToolset" - - #----------------------------------------------------------------------------------------------- - # DETECT PROJECT ADDITIONAL INCLUDE DIRECTORIES AND CONSTRUCT INCLUDE PATHS - - [string[]] $additionalIncludeDirectories = Get-ProjectAdditionalIncludes - Write-Verbose-Array -array $additionalIncludeDirectories -name "Additional include directories" - - [string[]] $includeDirectories = Get-ProjectIncludeDirectories -stdafxDir $stdafxDir - Write-Verbose-Array -array $includeDirectories -name "Include directories" - #----------------------------------------------------------------------------------------------- - # FIND LIST OF CPPs TO PROCESS + if ($projCpps.Count -gt 0 -and $aCppToCompile.Count -gt 0) + { + [System.Collections.Hashtable] $filteredCpps = @{} + [bool] $dirtyStdafx = $false + foreach ($cpp in $aCppToCompile) + { + if ($cpp -ieq $stdafxHeaderFullPath) + { + # stdafx modified => compile all + $dirtyStdafx = $true + break + } - [string[]] $projCpps = Get-ProjectFilesToCompile -pchCppName $stdafxCpp + if (![string]::IsNullOrEmpty($cpp)) + { + if ([System.IO.Path]::IsPathRooted($cpp)) + { + if ($projCpps.ContainsKey($cpp)) + { + # really fast, use cache + $filteredCpps[$cpp] = $projCpps[$cpp] + } + } + else + { + # take the slow road and check if it matches + $projCpps.Keys | Where-Object { IsFileMatchingName -filePath $_ -matchName $cpp } | ` + ForEach-Object { $filteredCpps[$_] = $true } + } + } + } - if (![string]::IsNullOrEmpty($aCppToCompile)) - { - $projCpps = ( $projCpps | - Where-Object { IsFileMatchingName -filePath $_ ` - -matchName $aCppToCompile } ) + if (!$dirtyStdafx) + { + $projCpps = $filteredCpps + } + else + { + Write-Verbose "PCH header has been targeted as dirty. Building entire project" + } } Write-Verbose ("Processing " + $projCpps.Count + " cpps") - + #----------------------------------------------------------------------------------------------- # CREATE PCH IF NEED BE, ONLY FOR TWO CPPS OR MORE [string] $pchFilePath = "" - if ($projCpps.Count -ge 2 -and + if ($projCpps.Keys.Count -ge 2 -and ![string]::IsNullOrEmpty($stdafxDir)) { # COMPILE PCH @@ -2072,19 +948,31 @@ Function Process-Project( [Parameter(Mandatory=$true)][string] $vcxprojPat -includeDirectories $includeDirectories ` -additionalIncludeDirectories $additionalIncludeDirectories Write-Verbose "PCH: $pchFilePath" + if ([string]::IsNullOrEmpty($pchFilePath) -and $aContinueOnError) + { + Write-Output "Skipping project. Reason: cannot create PCH." + return + } } - + #----------------------------------------------------------------------------------------------- # PROCESS CPP FILES. CONSTRUCT COMMAND LINE JOBS TO BE INVOKED $clangJobs = @() - foreach ($cpp in $projCpps) - { + foreach ($cpp in $projCpps.Keys) + { [string] $exeToCall = Get-ExeToCall -workloadType $workloadType - + + [string] $finalPchPath = $pchFilePath + if ($projCpps[$cpp].Pch -eq [UsePch]::NotUsing) + { + $finalPchPath = "" + Write-Verbose "`n[PCH] Will ignore precompiled headers for $cpp`n" + } + [string] $exeArgs = Get-ExeCallArguments -workloadType $workloadType ` - -pchFilePath $pchFilePath ` + -pchFilePath $finalPchPath ` -preprocessorDefinitions $preprocessorDefinitions ` -forceIncludeFiles $forceIncludeFiles ` -currentFile $cpp ` @@ -2097,7 +985,7 @@ Function Process-Project( [Parameter(Mandatory=$true)][string] $vcxprojPat 'File' = $cpp } $clangJobs += $newJob } - + #----------------------------------------------------------------------------------------------- # PRINT DIAGNOSTICS @@ -2105,37 +993,36 @@ Function Process-Project( [Parameter(Mandatory=$true)][string] $vcxprojPat { Write-Verbose "INVOKE: ""$($global:llvmLocation)\$exeToCall"" $($clangJobs[0].ArgumentList)" } - + #----------------------------------------------------------------------------------------------- # RUN CLANG JOBS Run-ClangJobs -clangJobs $clangJobs - - #----------------------------------------------------------------------------------------------- - # CLEAN GLOBAL VARIABLES SPECIFIC TO CURRENT PROJECT - - Clear-Vars } - + #------------------------------------------------------------------------------------------------- # Script entry point Clear-Host # clears console #------------------------------------------------------------------------------------------------- -# Print script parameters +# If we didn't get a location to run CPT at, use the current working directory -$bParams = $PSCmdlet.MyInvocation.BoundParameters -if ($bParams) +if (!$aSolutionsPath) { - [string] $paramStr = "clang-build.ps1 invocation args: `n" - foreach ($key in $bParams.Keys) - { - $paramStr += " $($key) = $($bParams[$key]) `n" - } - Write-Verbose $paramStr + $aSolutionsPath = Get-Location } +# ------------------------------------------------------------------------------------------------ +# Load param values from configuration file (if exists) + +Update-ParametersFromConfigFile + +#------------------------------------------------------------------------------------------------- +# Print script parameters + +Print-InvocationArguments + #------------------------------------------------------------------------------------------------- # Script entry point @@ -2161,60 +1048,120 @@ Push-Location (Get-SourceDirectory) # fetch .sln paths and data Load-Solutions -# This powershell process may already have completed jobs. Discard them. +# This PowerShell process may already have completed jobs. Discard them. Remove-Job -State Completed Write-Verbose "Source directory: $(Get-SourceDirectory)" Write-Verbose "Scanning for project files" [System.IO.FileInfo[]] $projects = Get-Projects +[int] $initialProjectCount = $projects.Count Write-Verbose ("Found $($projects.Count) projects") +# ------------------------------------------------------------------------------------------------ +# If we get headers in the -file arg we have to detect CPPs that include that header + +if ($aCppToCompile.Count -gt 0) +{ + # We've been given particular files to compile. If headers are among them + # we'll find all source files that include them and tag them for processing. + [string[]] $headerRefs = Get-HeaderReferences -files $aCppToCompile + if ($headerRefs.Count -gt 0) + { + Write-Verbose-Array -name "Detected source files" -array $headerRefs + + $aCppToCompile += $headerRefs + } +} + +# ------------------------------------------------------------------------------------------------ + [System.IO.FileInfo[]] $projectsToProcess = @() +[System.IO.FileInfo[]] $ignoredProjects = @() -if ([string]::IsNullOrEmpty($aVcxprojToCompile) -and - [string]::IsNullOrEmpty($aVcxprojToIgnore)) +if (!$aVcxprojToCompile -and !$aVcxprojToIgnore) { - Write-Verbose "PROCESSING ALL PROJECTS" - $projectsToProcess = $projects + $projectsToProcess = $projects # we process all projects } else { - $projectsToProcess = $projects | - Where-Object { (Should-CompileProject -vcxprojPath $_.FullName) ` - -and !(Should-IgnoreProject -vcxprojPath $_.FullName ) } + # some filtering has to be done + + if ($aVcxprojToCompile) + { + $projects = $projects | Where-Object { Should-CompileProject -vcxprojPath $_.FullName } + $projectsToProcess = $projects + } + + if ($aVcxprojToIgnore) + { + $projectsToProcess = $projects | ` + Where-Object { !(Should-IgnoreProject -vcxprojPath $_.FullName ) } + + $ignoredProjects = ($projects | Where-Object { $projectsToProcess -notcontains $_ }) + } +} + +if ($projectsToProcess.Count -eq 0) +{ + Write-Err "Cannot find given project(s)" +} + +if ($aCppToCompile -and $projectsToProcess.Count -gt 1) +{ + # We've been given particular files to compile, we can narrow down + # the projects to be processed (those that include any of the particular files) - if ($projectsToProcess.Count -gt 1) + # For obvious performance reasons, no filtering is done when there's only one project to process. + [System.IO.FileInfo[]] $projectsThatIncludeFiles = Get-SourceCodeIncludeProjects -projectPool $projectsToProcess ` + -files $aCppToCompile + Write-Verbose-Array -name "Detected projects" -array $projectsThatIncludeFiles + + # some projects include files using wildcards, we won't match anything in them + # so when matching nothing we don't do filtering at all + if ($projectsThatIncludeFiles) { - Write-Output ("PROJECTS: `n`t" + ($projectsToProcess -join "`n`t")) - $projectsToProcess = $projectsToProcess + $projectsToProcess = $projectsThatIncludeFiles } - - if ($projectsToProcess.Count -eq 0) +} + +if ($projectsToProcess.Count -eq $initialProjectCount) +{ + Write-Verbose "PROCESSING ALL PROJECTS" +} +else +{ + #Write-Output ("PROJECTS: `n`t" + ($projectsToProcess -join "`n`t")) + Write-Array -name "PROJECTS" -array $projectsToProcess + + if ($ignoredProjects) { - Write-Err "Cannot find given project" + Write-Array -name "IGNORED PROJECTS" -array $ignoredProjects } } +# ------------------------------------------------------------------------------------------------ + $projectCounter = $projectsToProcess.Length; foreach ($project in $projectsToProcess) -{ +{ [string] $vcxprojPath = $project.FullName; [WorkloadType] $workloadType = [WorkloadType]::Compile - if (![string]::IsNullOrEmpty($aTidyFlags)) + if (![string]::IsNullOrEmpty($aTidyFlags)) { - $workloadType = [WorkloadType]::Tidy + $workloadType = [WorkloadType]::Tidy } - + if (![string]::IsNullOrEmpty($aTidyFixFlags)) { $workloadType = [WorkloadType]::TidyFix } - Write-Output ("`nPROJECT$(if ($projectCounter -gt 1) { " #$projectCounter" } else { } ): " + $vcxprojPath) + Write-Output ("PROJECT$(if ($projectCounter -gt 1) { " #$projectCounter" } else { } ): " + $vcxprojPath) Process-Project -vcxprojPath $vcxprojPath -workloadType $workloadType + Write-Output "" # empty line separator $projectCounter -= 1 } @@ -2226,4 +1173,4 @@ if ($global:FoundErrors) else { Exit-Script -} \ No newline at end of file +} diff --git a/scripts/cpt.config b/scripts/cpt.config new file mode 100644 index 0000000000..aaf7149204 --- /dev/null +++ b/scripts/cpt.config @@ -0,0 +1,41 @@ + + + + + "-Wall" + , "-fms-compatibility-version=19.10" + , "-Wmicrosoft" + , "-Wno-invalid-token-paste" + , "-Wno-unknown-pragmas" + , "-Wno-unused-variable" + , "-Wno-unused-value" + , "-Wno-undefined-var-template" + , "-Wno-microsoft-enum-value" + , "-Wno-inconsistent-missing-override" + , "-Wno-extra-tokens" + , "-Wno-c99-extensions" + , "-Wno-logical-op-parentheses" + , "-Wno-invalid-source-encoding" + + + '.*' + + + + 'Professional' + + "gtest";"moc_" + + diff --git a/scripts/msbuild_translation_tests.ps1 b/scripts/msbuild_translation_tests.ps1 deleted file mode 100644 index 0340cf2eed..0000000000 --- a/scripts/msbuild_translation_tests.ps1 +++ /dev/null @@ -1,334 +0,0 @@ -# Tests for ClangPowerTools MSBUILD Expression/Condition translation - -$Configuration = "Release2" -$Platform = "Win32" -$UserRootDir = "c:\test" -$SolutionDir = "C:\AI Trunk\ClangPowerToolsProblem" -$ProjectDir = "C:\AI Trunk\win" -$TargetName = "YOLOTest" -$varB = 1 - -# ------------------------------------------------------------------------------------------------------------------- - -Set-Variable -name "kMsbuildExpressionToPsRules" -option Constant ` - -value @(<# backticks are control characters in PS, replace them #> - ('`' , '''' )` - <# Temporarily replace $( #> ` - , ('\$\s*\(' , '!@#' )` - <# Escape $ #> ` - , ('\$' , '`$' )` - <# Put back $( #> ` - , ('!@#' , '$(' )` - <# Various operators #> ` - , ("([\s\)\'""])!=" , '$1 -ne ' )` - , ("([\s\)\'""])<=" , '$1 -le ' )` - , ("([\s\)\'""])>=" , '$1 -ge ' )` - , ("([\s\)\'""])==" , '$1 -eq ' )` - , ("([\s\)\'""])<" , '$1 -lt ' )` - , ("([\s\)\'""])>" , '$1 -gt ' )` - , ("([\s\)\'""])or" , '$1 -or ' )` - , ("([\s\)\'""])and" , '$1 -and ' )` - <# Use only double quotes #> ` - , ("\'" , '"' )` - , ("Exists\((.*?)\)(\s|$)" , '(Exists($1))$2' )` - , ("HasTrailingSlash\((.*?)\)(\s|$)" , '(HasTrailingSlash($1))$2' )` - , ("(\`$\()(Registry:)(.*?)(\))" , '$$(GetRegValue("$3"))' )` - ) - -Set-Variable -name "kMsbuildConditionToPsRules" -option Constant ` - -value @(<# Use only double quotes #> ` - ("\'" , '"' )` - <# We need to escape double quotes since we will eval() the condition #> ` - , ('"' , '""' )` - ) - -function GetRegValue([Parameter(Mandatory=$true)][string] $regPath) -{ - [int] $separatorIndex = $regPath.IndexOf('@') - [string] $valueName = "" - if ($separatorIndex -gt 0) - { - [string] $valueName = $regPath.Substring($separatorIndex + 1) - $regPath = $regPath.Substring(0, $separatorIndex) - } - if ([string]::IsNullOrEmpty($valueName)) - { - throw "Cannot retrieve an empty registry value" - } - $regPath = $regPath -replace "HKEY_LOCAL_MACHINE\\", "HKLM:\" - - if (Test-Path $regPath) - { - return (Get-Item $regPath).GetValue($valueName) - } - else - { - return "" - } -} - -function HasTrailingSlash([Parameter(Mandatory=$true)][string] $str) -{ - return $str.EndsWith('\') -or $str.EndsWith('/') -} - -function Exists([Parameter(Mandatory=$false)][string] $path) -{ - if ([string]::IsNullOrEmpty($path)) - { - return $false - } - return Test-Path $path -} - -function Evaluate-MSBuildExpression([string] $expression, [switch] $isCondition) -{ - Write-Debug "Start evaluate MSBuild expression $expression" - - foreach ($rule in $kMsbuildExpressionToPsRules) - { - $expression = $expression -replace $rule[0], $rule[1] - } - - if ( !$isCondition -and ($expression.IndexOf('$') -lt 0)) - { - # we can stop here, further processing is not required - return $expression - } - - [int] $expressionStartIndex = -1 - [int] $openParantheses = 0 - for ([int] $i = 0; $i -lt $expression.Length; $i += 1) - { - if ($expression.Substring($i, 1) -eq '(') - { - if ($i -gt 0 -and $expressionStartIndex -lt 0 -and $expression.Substring($i - 1, 1) -eq '$') - { - $expressionStartIndex = $i - 1 - } - - if ($expressionStartIndex -ge 0) - { - $openParantheses += 1 - } - } - - if ($expression.Substring($i, 1) -eq ')' -and $expressionStartIndex -ge 0) - { - $openParantheses -= 1 - if ($openParantheses -lt 0) - { - throw "Parse error" - } - if ($openParantheses -eq 0) - { - [string] $content = $expression.Substring($expressionStartIndex + 2, - $i - $expressionStartIndex - 2) - [int] $initialLength = $content.Length - - if ([regex]::Match($content, "[a-zA-Z_][a-zA-Z0-9_\-]+").Value -eq $content) - { - # we have a plain property retrieval - $content = "`${$content}" - } - else - { - # dealing with a more complex expression - $content = $content -replace '(^|\s+|\$\()([a-zA-Z_][a-zA-Z0-9_]+)(\.|\)|$)', '$1$$$2$3' - } - - $newCond = $expression.Substring(0, $expressionStartIndex + 2) + - $content + $expression.Substring($i) - $expression = $newCond - - $i += ($content.Length - $initialLength) - $expressionStartIndex = -1 - } - } - } - - Write-Debug "Intermediate PS expression: $expression" - - try - { - [string] $toInvoke = "(`$s = ""$expression"")" - if ($isCondition) - { - $toInvoke = "(`$s = ""`$($expression)"")" - } - - $res = Invoke-Expression $toInvoke - } - catch - { - write-debug $_.Exception.Message - } - - Write-Debug "Evaluated expression to: $res" - - return $res -} - -function Evaluate-MSBuildCondition([Parameter(Mandatory=$true)][string] $condition) -{ - Write-Debug "Evaluating condition $condition" - foreach ($rule in $kMsbuildConditionToPsRules) - { - $condition = $condition -replace $rule[0], $rule[1] - } - $expression = Evaluate-MSBuildExpression -expression $condition -isCondition - - if ($expression -ieq "true") - { - return $true - } - - if ($expression -ieq "false") - { - return $false - } - - [bool] $res = $false - try - { - $res = (Invoke-Expression $expression) -eq $true - } - catch - { - Write-Debug $_.Exception.Message - } - Write-Debug "Evaluated condition to $res" - - return $res -} - -Clear-Host - -function Test-Condition([string] $condition, [bool]$expectation, [switch] $expectFailure) -{ - [boolean] $condValue - try - { - $condValue = Evaluate-MSBuildCondition $condition - } - catch - { - if ($expectFailure) - { - Write-Output "TEST OK" - return - } - else - { - Write-Output $_.Exception.Message - throw "Test failed" - } - } - - if ($condValue -ne $expectation) - { - Write-Output "Expected $expectation | Got $condValue" - throw "Test failed" - } - Write-Output "TEST OK" -} - -function Test-Expression($expresion) -{ - $res = Evaluate-MSBuildExpression $expresion - Write-output $res -} -# ---------------------------------------------------------------------------- - -Test-Condition "'`$(ImportDirectoryBuildProps)' == 'true' and exists('`$(DirectoryBuildPropsPath)')" -expectation $false - -Test-Expression '$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\15.0\AD7Metrics\ExpressionEvaluator\{3A12D0B7-C26C-11D0-B442-00A0244A1DD2}\{994B45C4-E6E9-11D2-903F-00C04FA302A1}@LoadInShimManagedEE)' -Test-Expression '$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@InstallationFolder)' -Test-Expression '$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@InstallationFolder)' - -Test-Expression '$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)' -Test-Expression '$(GetRegValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@InstallationFolder"))' - - -Test-Condition "'`$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)' != ''" ` - -expectation $true - -Test-Condition "'`$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DevDiv\vs\Servicing\11.0\professional@Version)' == ''" ` - -expectation $true - - -Test-Condition -condition "'`$(Configuration)|`$(Platform)'=='Debug|Win32' or '`$(Configuration)' == 'Release2'" ` - -expectation $true - -Test-Condition -condition "'`$(Platform)'=='x64' or '`$(Platform)'=='Win32' or '`$(Platform)'=='Durango' or exists('`$(UserRootDir)\Microsoft.Cpp.`$(Platform).user.props2')"` - -expectation $true - -Test-Condition -condition "exists('c:\ai trunk')"` - -expectation $true - -Test-Condition -condition "'`$(Configuration)|`$(Platform)'=='Release|Win32'"` - -expectation $false - -Test-Condition -condition '$(Platform.Replace(" ", "")) and $(testB)'` - -expectation $false - -Test-Condition -condition '$(Platform) and $(varB)'` - -expectation $true - -Test-Condition -condition "exists('`$(UserRootDir)\Microsoft.Cpp.`$(Platform).user.props')"` - -expectation $true - -Test-Expression -expression "`$(SolutionDir)\Tools\PropertySheets\Evolution.Module.props" -Test-Expression -expresion "WIN32_LEAN_AND_MEAN and `$(Configuration)" - -Test-Condition -condition "exists('`$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(``WindowsMobile, Version=10.0.10240.0``, `$(TargetPlatformIdentifier), `$(TargetPlatformVersion), `$(SDKReferenceDirectoryRoot), `$(SDKExtensionDirectoryRoot), `$(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\WindowsMobile.props')"` - -expectFailure - -Test-Expression -expression "`$Foo;`$(ProjectDir);..\..;..\..\third-party" - -Test-Condition -condition "`$(TargetName.EndsWith('Test'))"` - -expectation $true - -Test-Condition -condition "`$(TargetName.EndsWith('Test2'))"` - -expectation $false - -$var = 4 -Test-Condition -condition '$(var) == 2 and 4 == 4'` - -expectation $false - -Test-Expression -expression "%(ASDASD);`$(TargetName)" - -$PkgMicrosoft_Gsl = "..\.." -Test-Condition -condition "Exists('`$(PkgMicrosoft_Gsl)\build\native\Microsoft.Gsl.targets') OR ! Exists('`$(PkgMicrosoft_Gsl)\build\native\Microsoft.Gsl.targets')"` - -expectation $true - -$myVar = 'TwoThree' -$MySelector = "One;Two;Three" -Test-Condition -condition "`$(MySelector.Contains(`$(myVar.Substring(3, 3))))"` - -expectation $true - -$MySelector = "One;Two;Three" -$myVar = "Two" -Test-Condition -condition "`$(MySelector.Contains(`$(myVar)))"` - -expectation $true - -$MySelector = "One;Two;Three" -Test-Condition -condition "`$(MySelector.Contains(Three))"` - -expectFailure - -$MySelector = "One;Two;Three" -Test-Condition -condition "`$(MySelector.Contains('Three'))"` - -expectation $true - -Test-Condition -condition "`$([System.DateTime]::Now.Year) == 2018"` - -expectation $true - -Test-Condition -condition "HasTrailingSlash('c:\windows\')"` - -expectation $true - -Test-Condition -condition "HasTrailingSlash('c:\windows\') and hasTrailingSlash('c:\temp/')"` - -expectation $true - -$prop = "c:\windows\" -Test-Condition -condition "hasTrailingSlash(`$(prop))"` - -expectation $true \ No newline at end of file diff --git a/scripts/psClang/get-header-references.ps1 b/scripts/psClang/get-header-references.ps1 new file mode 100644 index 0000000000..6df59e63f6 --- /dev/null +++ b/scripts/psClang/get-header-references.ps1 @@ -0,0 +1,213 @@ +# line limit for scanning files for #include +[int] $global:cpt_header_include_line_limit = 30 + +# after the line limit, if any includes are still found we +# extend the limit with this value +[int] $global:cpt_header_include_line_extension = 10 + +[string[]] $global:headerExtensions = @('h', 'hh', 'hpp', 'hxx') +[string[]] $global:sourceExtensions = @('c', 'cc', 'cpp', 'cxx') + +Function detail:FindHeaderReferences( [Parameter(Mandatory = $false)] [string[]] $headers + , [Parameter(Mandatory = $false)] [System.IO.FileInfo[]] $filePool + , [Parameter(Mandatory = $false)] [System.Collections.Hashtable] $alreadyFound = @{} + ) +{ + if (!$headers) + { + return @() + } + + [string] $regexHeaders = ($headers | ForEach-Object { ([System.IO.FileInfo]$_).BaseName } ` + | Select-Object -Unique ` + | Where-Object { $_ -ine "stdafx" -and $_ -ine "resource" } ` + ) -join '|' + + if ($regexHeaders.Length -eq 0) + { + return @() + } + + [string] $regex = "[/""]($regexHeaders)\.($($global:headerExtensions -join '|'))""" + Write-Debug "Regex for header reference find: $regex`n" + + [string[]] $returnRefs = @() + if (!$filePool) + { + # initialize pool of files that we look into + [string[]] $allFileExts = ($global:sourceExtensions + ` + $global:headerExtensions) | ForEach-Object { "*.$_" } + $filePool = Get-ChildItem -recurse -include $allFileExts + } + + foreach ($file in $filePool) + { + if ($alreadyFound.ContainsKey($file.FullName)) + { + continue + } + + [int] $lineCount = 0 + [int] $lineLimit = $global:cpt_header_include_line_limit + foreach($line in [System.IO.File]::ReadLines($file)) + { + if ([string]::IsNullOrWhiteSpace($line)) + { + # skip empty lines + continue + } + + if ($line -match $regex) + { + if ( ! $alreadyFound.ContainsKey($file.FullName)) + { + $alreadyFound[$file.FullName] = $true + $returnRefs += $file.FullName + } + + if ($lineCount -eq $lineLimit) + { + # we still have includes to scan + $lineLimit += $global:cpt_header_include_line_extension + } + } + + if ( (++$lineCount) -gt $lineLimit) + { + break + } + } + } + + if ($returnRefs.Count -gt 0) + { + [string[]] $headersLeftToSearch = ($returnRefs | Where-Object ` + { FileHasExtension -filePath $_ ` + -ext $global:headerExtensions } ) + if ($headersLeftToSearch.Count -gt 0) + { + Write-Debug "[!] Recursive reference detection in progress for: " + Write-Debug ($headersLeftToSearch -join "`n") + $returnRefs += detail:FindHeaderReferences -headers $headersLeftToSearch ` + -filePool $filePool ` + -alreadyFound $alreadyFound + } + } + + $returnRefs = $returnRefs | Select-Object -Unique + Write-Debug "Found header refs (regex $regex)" + Write-Debug ($returnRefs -join "`n") + return $returnRefs +} + +<# +.SYNOPSIS +Detects source files that reference given headers. + +Returns an array with full paths of files that reference the header(s). +.DESCRIPTION +When modifying a header, all translation units that include that header +have to compiled. This function detects those files that include it. +.PARAMETER files +Header files of which we want references to be found +Any files that are not headers will be ignored. +#> +Function Get-HeaderReferences([Parameter(Mandatory = $false)][string[]] $files) +{ + if ($files.Count -eq 0) + { + return @() + } + + # we take interest only in files that reference headers + $files = $files | Where-Object { FileHasExtension -filePath $_ ` + -ext $global:headerExtensions } + + [string[]] $refs = @() + + if ($files.Count -gt 0) + { + Write-Verbose-Timed "Headers changed. Detecting which source files to process..." + $refs = detail:FindHeaderReferences -headers $files + Write-Verbose-Timed "Finished detecting source files." + } + + return $refs +} + +<# +.SYNOPSIS +Detects projects that reference given source files (i.e. cpps). + +Returns an array with full paths of detected projects. +.DESCRIPTION +When modifying a file, only projects that reference that file should be recompiled. +.PARAMETER projectPool +Projects in which to look +.PARAMETER files +Source files to be found in projects. +#> +Function Get-SourceCodeIncludeProjects([Parameter(Mandatory = $false)][System.IO.FileInfo[]] $projectPool, + [Parameter(Mandatory = $false)][string[]] $files) +{ + [System.Collections.Hashtable] $fileCache = @{} + foreach ($file in $files) + { + if ($file) + { + $fileCache[$file.Trim().ToLower()] = $true + } + } + + [System.IO.FileInfo[]] $matchedProjects = @() + + [string] $clPrefix = '' + [string] $endGroupTag = '' + + foreach ($proj in $projectPool) + { + [string] $projDir = $proj.Directory.FullName + + [bool] $inClIncludeSection = $false + foreach($line in [System.IO.File]::ReadLines($proj.FullName)) + { + $line = $line.Trim() + + if ($line.StartsWith($clPrefix)) + { + if (!$inClIncludeSection) + { + $inClIncludeSection = $true + } + + [string] $filePath = $line.Substring($clPrefix.Length, ` + $line.Length - $clPrefix.Length - $clSuffix.Length) + if (![System.IO.Path]::IsPathRooted($filePath)) + { + $filePath = Canonize-Path -base $projDir -child $filePath -ignoreErrors + } + if ([string]::IsNullOrEmpty($filePath)) + { + continue + } + + [System.IO.FileInfo] $sourceFile = $filePath + if ($fileCache.ContainsKey($sourceFile.FullName.Trim().ToLower()) -or ` + $fileCache.ContainsKey($sourceFile.Name.Trim().ToLower())) + { + $matchedProjects += $proj + break + } + } + + if ($inClIncludeSection -and $line -eq $endGroupTag) + { + # nothing more to check in this project + break + } + } + } + + return $matchedProjects +} diff --git a/scripts/psClang/io.ps1 b/scripts/psClang/io.ps1 new file mode 100644 index 0000000000..c706ca5492 --- /dev/null +++ b/scripts/psClang/io.ps1 @@ -0,0 +1,238 @@ +#Console IO +# ------------------------------------------------------------------------------------------------ +Function Write-Message([parameter(Mandatory = $true)][string] $msg + , [Parameter(Mandatory = $true)][System.ConsoleColor] $color) +{ + $foregroundColor = $host.ui.RawUI.ForegroundColor + $host.ui.RawUI.ForegroundColor = $color + Write-Output $msg + $host.ui.RawUI.ForegroundColor = $foregroundColor +} + +# Writes an error without the verbose PowerShell extra-info (script line location, etc.) +Function Write-Err([parameter(ValueFromPipeline, Mandatory = $true)][string] $msg) +{ + Write-Message -msg $msg -color Red +} + +Function Write-Success([parameter(ValueFromPipeline, Mandatory = $true)][string] $msg) +{ + Write-Message -msg $msg -color Green +} + +Function Write-Array($array, $name) +{ + Write-Output "$($name):" + $array | ForEach-Object { Write-Output " $_" } + Write-Output "" # empty line separator +} + +Function Write-Verbose-Array($array, $name) +{ + Write-Verbose "$($name):" + $array | ForEach-Object { Write-Verbose " $_" } + Write-Verbose "" # empty line separator +} + +Function Write-Verbose-Timed([parameter(ValueFromPipeline, Mandatory = $true)][string] $msg) +{ + Write-Verbose "$([DateTime]::Now.ToString("[HH:mm:ss]")) $msg" +} + +Function Print-InvocationArguments() +{ + $bParams = $PSCmdlet.MyInvocation.BoundParameters + if ($bParams) + { + [string] $paramStr = "clang-build.ps1 invocation args: `n" + foreach ($key in $bParams.Keys) + { + $paramStr += " $($key) = $($bParams[$key]) `n" + } + Write-Verbose $paramStr + } +} + +Function Print-CommandParameters([Parameter(Mandatory = $true)][string] $command) +{ + $params = @() + foreach ($param in ((Get-Command $command).ParameterSets[0].Parameters)) + { + if (!$param.HelpMessage) + { + continue + } + + $params += New-Object PsObject -Prop @{ "Option" = "-$($param.Aliases[0])" + ; "Description" = $param.HelpMessage + } + } + + $params | Sort-Object -Property "Option" | Out-Default +} + + + +# Function that gets the name of a command argument when it is only known by its alias +# For streamlining purposes, it also accepts the name itself. +Function Get-CommandParameterName([Parameter(Mandatory = $true)][string] $command + ,[Parameter(Mandatory = $true)][string] $nameOrAlias) +{ + foreach ($param in ((Get-Command $command).ParameterSets[0].Parameters)) + { + if ($param.Name -eq $nameOrAlias -or + $param.Aliases -contains $nameOrAlias) + { + return $param.Name + } + } + return "" +} + +# File IO +# ------------------------------------------------------------------------------------------------ +Function Remove-PathTrailingSlash([Parameter(Mandatory = $true)][string] $path) +{ + return $path -replace '\\$', '' +} + +Function Get-FileDirectory([Parameter(Mandatory = $true)][string] $filePath) +{ + return ([System.IO.Path]::GetDirectoryName($filePath) + "\") +} + +Function Get-FileName( [Parameter(Mandatory = $true)][string] $path + , [Parameter(Mandatory = $false)][switch] $noext) +{ + if ($noext) + { + return ([System.IO.Path]::GetFileNameWithoutExtension($path)) + } + else + { + return ([System.IO.Path]::GetFileName($path)) + } +} + +Function IsFileMatchingName( [Parameter(Mandatory = $true)][string] $filePath + , [Parameter(Mandatory = $true)][string] $matchName) +{ + if ([System.IO.Path]::IsPathRooted($matchName)) + { + return $filePath -ieq $matchName + } + + if ($aDisableNameRegexMatching) + { + [string] $fileName = (Get-FileName -path $filePath) + [string] $fileNameNoExt = (Get-FileName -path $filePath -noext) + return (($fileName -eq $matchName) -or ($fileNameNoExt -eq $matchName)) + } + else + { + return $filePath -match $matchName + } +} + +Function FileHasExtension( [Parameter(Mandatory = $true)][string] $filePath + , [Parameter(Mandatory = $true)][string[]] $ext + ) +{ + foreach ($e in $ext) + { + if ($filePath.EndsWith($e)) + { + return $true + } + } + return $false +} + +<# + .DESCRIPTION + Merges an absolute and a relative file path. + .EXAMPLE + Having base = C:\Windows\System32 and child = .. we get C:\Windows + .EXAMPLE + Having base = C:\Windows\System32 and child = ..\..\..\.. we get C:\ (cannot go further up) + .PARAMETER base + The absolute path from which we start. + .PARAMETER child + The relative path to be merged into base. + .PARAMETER ignoreErrors + If this switch is not present, an error will be triggered if the resulting path + is not present on disk (e.g. c:\Windows\System33). + + If present and the resulting path does not exist, the function returns an empty string. + #> +Function Canonize-Path( [Parameter(Mandatory = $true)][string] $base + , [Parameter(Mandatory = $true)][string] $child + , [switch] $ignoreErrors) +{ + [string] $errorAction = If ($ignoreErrors) {"SilentlyContinue"} Else {"Stop"} + + if ([System.IO.Path]::IsPathRooted($child)) + { + if (!(Test-Path $child)) + { + return "" + } + return $child + } + else + { + [string[]] $paths = Join-Path -Path "$base" -ChildPath "$child" -Resolve -ErrorAction $errorAction + return $paths + } +} + +function HasTrailingSlash([Parameter(Mandatory = $true)][string] $str) +{ + return $str.EndsWith('\') -or $str.EndsWith('/') +} + + +function EnsureTrailingSlash([Parameter(Mandatory = $true)][string] $str) +{ + [string] $ret = If (HasTrailingSlash($str)) { $str } else { "$str\" } + return $ret +} + +function Exists([Parameter(Mandatory = $false)][string] $path) +{ + if ([string]::IsNullOrEmpty($path)) + { + return $false + } + + return Test-Path $path +} + +function MakePathRelative( [Parameter(Mandatory = $true)][string] $base + , [Parameter(Mandatory = $true)][string] $target + ) +{ + Push-Location "$base\" + [string] $relativePath = (Resolve-Path -Relative $target) -replace '^\.\\','' + Pop-Location + if ( (HasTrailingSlash $target) -or $target.EndsWith('.') ) + { + $relativePath += '\' + } + return "$relativePath" +} + +# Command IO +# ------------------------------------------------------------------------------------------------ +Function Exists-Command([Parameter(Mandatory = $true)][string] $command) +{ + try + { + Get-Command -name $command -ErrorAction Stop | out-null + return $true + } + catch + { + return $false + } +} diff --git a/scripts/psClang/io.tests.ps1 b/scripts/psClang/io.tests.ps1 new file mode 100644 index 0000000000..a16fca59fc --- /dev/null +++ b/scripts/psClang/io.tests.ps1 @@ -0,0 +1,104 @@ +#Clear-Host + +# IMPORT code blocks + +Set-Variable -name "kScriptLocation" ` + -value (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) <#` + -option Constant#> + +@( + , "$kScriptLocation\io.ps1" + ) | ForEach-Object { . $_ } + +Describe "File IO" { + It "Remove-PathTrailingSlash" { + Remove-PathTrailingSlash "c:\windows\" | Should -BeExactly "c:\windows" + Remove-PathTrailingSlash "c:\windows" | Should -BeExactly "c:\windows" + Remove-PathTrailingSlash "..\foo\bar\" | Should -BeExactly "..\foo\bar" + } + + It "Get-FileDirectory" { + Get-FileDirectory "$env:SystemRoot\explorer.exe" | Should -BeExactly "$env:SystemRoot\" + Get-FileDirectory "$env:SystemRoot\explorer.exe" | Should -BeExactly "$env:SystemRoot\" + Get-FileDirectory "$env:SystemRoot\foobar.nonexistent" | Should -BeExactly "$env:SystemRoot\" + Get-FileDirectory "foo\bar" | Should -BeExactly "foo\" + } + + It "Get-FileName" { + Get-FileName "$env:SystemRoot\explorer.exe" | Should -BeExactly "explorer.exe" + Get-FileName "$env:SystemRoot\foobar.nonexistent" | Should -BeExactly "foobar.nonexistent" + } + + It "IsFileMatchingName - no regex" { + # Mocking script parameter aDisableNameRegexMatching + [bool] $aDisableNameRegexMatching = $true + + $path = "$env:SystemRoot\notepad.exe" + IsFileMatchingName -filePath $path -matchName "notepad" | Should -BeExactly $true + IsFileMatchingName -filePath $path -matchName "notepad.exe" | Should -BeExactly $true + IsFileMatchingName -filePath $path -matchName "notepad.ex" | Should -BeExactly $false + IsFileMatchingName -filePath $path -matchName "note" | Should -BeExactly $false + IsFileMatchingName -filePath $path -matchName ".*" | Should -BeExactly $false + } + + It "IsFileMatchingName - with regex" { + # Mocking script parameter aDisableNameRegexMatching + [bool] $aDisableNameRegexMatching = $false + + $path = "$env:SystemRoot\notepad.exe" + IsFileMatchingName -filePath $path -matchName "notepad" | Should -BeExactly $true + IsFileMatchingName -filePath $path -matchName "notepad.exe" | Should -BeExactly $true + IsFileMatchingName -filePath $path -matchName "notepad.ex" | Should -BeExactly $true + IsFileMatchingName -filePath $path -matchName "note" | Should -BeExactly $true + IsFileMatchingName -filePath $path -matchName ".*" | Should -BeExactly $true + } + + It "FileHasExtension" { + FileHasExtension -filePath "c:\foo.bar" -ext 'bar' | Should -BeExactly $true + FileHasExtension -filePath "c:\foo.bar" -ext 'bar2' | Should -BeExactly $false + FileHasExtension -filePath "c:\foo.bar" -ext @('bar') | Should -BeExactly $true + FileHasExtension -filePath "c:\foo.bar" -ext @('bar2') | Should -BeExactly $false + FileHasExtension -filePath "c:\foo.bar" -ext @('bar', 'bar2') | Should -BeExactly $true + FileHasExtension -filePath "c:\foo.bar" -ext @('bar2', 'bar') | Should -BeExactly $true + FileHasExtension -filePath "c:\foo.bar" -ext @('bar2', 'bar2') | Should -BeExactly $false + } + + It "Canonize-Path" { + $sysDrive = "$env:SystemDrive\" + Canonize-Path -base $sysDrive -child "Windows" | Should -Be $env:SystemRoot + { Canonize-Path -base $sysDrive -child "foobar" } | Should -throw + { Canonize-Path -base $sysDrive -child "foobar" -ignoreErrors } | Should -not -throw + Canonize-Path -base $sysDrive -child "foobar" -ignoreErrors | Should -BeExactly $null + + [string[]] $files = Canonize-Path -base $sysDrive -child "*" # get all children + $files.Count | Should -BeGreaterThan 1 + } + + It "Exists" { + [string] $winDir = $env:SystemRoot + Exists $winDir | should -BeExactly $true + Exists "$winDir\notepad.exe" | should -BeExactly $true + Exists "$winDir\foobar_surely_nonextant" | should -BeExactly $false + } + + It "HasTrailingSlash" { + HasTrailingSlash "ab" | should -BeExactly $false + HasTrailingSlash "ab\" | should -BeExactly $true + HasTrailingSlash "ab/" | should -BeExactly $true + HasTrailingSlash "a/b/" | should -BeExactly $true + } + + It "EnsureTrailingSlash" { + EnsureTrailingSlash "ab" | should -BeExactly "ab\" + EnsureTrailingSlash "ab\" | should -BeExactly "ab\" + EnsureTrailingSlash "ab/" | should -BeExactly "ab/" + EnsureTrailingSlash "a/b/" | should -BeExactly "a/b/" + } +} + +Describe "Command IO" { + It "Exists-Command" { + Exists-Command "Get-Process" | Should -BeExactly $true + Exists-Command "Get-JiggyWithIt" | Should -BeExactly $false + } +} diff --git a/scripts/psClang/msbuild-expression-eval.ps1 b/scripts/psClang/msbuild-expression-eval.ps1 new file mode 100644 index 0000000000..47a862110b --- /dev/null +++ b/scripts/psClang/msbuild-expression-eval.ps1 @@ -0,0 +1,208 @@ +# REQUIRES io.ps1 to be included + +Set-Variable -name "kMsbuildExpressionToPsRules" <#-option Constant#> ` + -value @( ` + <# backticks are control characters in PS, replace them #> ` + ('`' , '''' )` + <# Temporarily replace $( #> ` + , ('\$\s*\(' , '!@#' )` + <# Escape $ #> ` + , ('\$' , '`$' )` + <# Put back $( #> ` + , ('!@#' , '$(' )` + <# Various operators #> ` + , ("([\s\)\'""])!=" , '$1 -ne ' )` + , ("([\s\)\'""])<=" , '$1 -le ' )` + , ("([\s\)\'""])>=" , '$1 -ge ' )` + , ("([\s\)\'""])==" , '$1 -eq ' )` + , ("([\s\)\'""])<" , '$1 -lt ' )` + , ("([\s\)\'""])>" , '$1 -gt ' )` + , ("([\s\)\'""])or" , '$1 -or ' )` + , ("([\s\)\'""])and" , '$1 -and ' )` + <# Use only double quotes #> ` + , ("\'" , '"' )` + , ("Exists\((.*?)\)(\s|$)" , '(Exists($1))$2' )` + , ("HasTrailingSlash\((.*?)\)(\s|$)" , '(HasTrailingSlash($1))$2')` + , ("(\`$\()(Registry:)(.*?)(\))" , '$$(GetRegValue("$3"))' )` + , ("\[MSBuild\]::GetDirectoryNameOfFileAbove\((.+?),\s*`"?'?((\$.+?\))|(.+?))((|`"|')\))+"` + ,'GetDirNameOfFileAbove -startDir $1 -targetFile ''$2'')' )` + , ("\[MSBuild\]::MakeRelative\((.+?),\s*""?'?((\$.+?\))|(.+?))((|""|')\)\))+"` + ,'MakePathRelative -base $1 -target "$2")' )` +) + +Set-Variable -name "kMsbuildConditionToPsRules" <#-option Constant#> ` + -value @(<# Use only double quotes #> ` + ,("\'" , '"' )` +) + +function GetDirNameOfFileAbove( [Parameter(Mandatory = $true)][string] $startDir + , [Parameter(Mandatory = $true)][string] $targetFile + ) +{ + if ($targetFile.Contains('$')) + { + $targetFile = Invoke-Expression $targetFile + } + + [string] $base = $startDir + while ([string]::IsNullOrEmpty((Canonize-Path -base $base ` + -child $targetFile ` + -ignoreErrors))) + { + $base = [System.IO.Path]::GetDirectoryName($base) + if ([string]::IsNullOrEmpty($base)) + { + return "" + } + } + return $base +} + +function GetRegValue([Parameter(Mandatory = $true)][string] $regPath) +{ + Write-Debug "REG_READ $regPath" + + [int] $separatorIndex = $regPath.IndexOf('@') + [string] $valueName = "" + if ($separatorIndex -gt 0) + { + [string] $valueName = $regPath.Substring($separatorIndex + 1) + $regPath = $regPath.Substring(0, $separatorIndex) + } + if ([string]::IsNullOrEmpty($valueName)) + { + throw "Cannot retrieve an empty registry value" + } + $regPath = $regPath -replace "HKEY_LOCAL_MACHINE\\", "HKLM:\" + + if (Test-Path $regPath) + { + return (Get-Item $regPath).GetValue($valueName) + } + else + { + return "" + } +} + +function Evaluate-MSBuildExpression([string] $expression, [switch] $isCondition) +{ + Write-Debug "Start evaluate MSBuild expression $expression" + + foreach ($rule in $kMsbuildExpressionToPsRules) + { + $expression = $expression -replace $rule[0], $rule[1] + } + + if ( !$isCondition -and ($expression.IndexOf('$') -lt 0)) + { + # we can stop here, further processing is not required + return $expression + } + + [int] $expressionStartIndex = -1 + [int] $openParantheses = 0 + for ([int] $i = 0; $i -lt $expression.Length; $i += 1) + { + if ($expression[$i] -eq '(') + { + if ($i -gt 0 -and $expressionStartIndex -lt 0 -and $expression[$i - 1] -eq '$') + { + $expressionStartIndex = $i - 1 + } + + if ($expressionStartIndex -ge 0) + { + $openParantheses += 1 + } + } + + if ($expression[$i] -eq ')' -and $expressionStartIndex -ge 0) + { + $openParantheses -= 1 + if ($openParantheses -lt 0) + { + throw "Parse error" + } + if ($openParantheses -eq 0) + { + [string] $content = $expression.Substring($expressionStartIndex + 2, + $i - $expressionStartIndex - 2) + [int] $initialLength = $content.Length + + if ([regex]::Match($content, "[a-zA-Z_][a-zA-Z0-9_\-]+").Value -eq $content) + { + # we have a plain property retrieval + $content = "`${$content}" + } + else + { + # dealing with a more complex expression + $content = $content -replace '(^|\s+|\$\()([a-zA-Z_][a-zA-Z0-9_]+)(\.|\)|$)', '$1$$$2$3' + } + + $newCond = $expression.Substring(0, $expressionStartIndex + 2) + + $content + $expression.Substring($i) + $expression = $newCond + + $i += ($content.Length - $initialLength) + $expressionStartIndex = -1 + } + } + } + + $expression = $expression.replace('"', '""') + Write-Debug "Intermediate PS expression: $expression" + + try + { + + [string] $toInvoke = "(`$s = ""$expression"")" + if ($isCondition) + { + $toInvoke = "(`$s = ""`$($expression)"")" + } + + $res = Invoke-Expression $toInvoke + } + catch + { + write-debug $_.Exception.Message + } + + Write-Debug "Evaluated expression to: $res" + + return $res +} +function Evaluate-MSBuildCondition([Parameter(Mandatory = $true)][string] $condition) +{ + Write-Debug "Evaluating condition $condition" + foreach ($rule in $kMsbuildConditionToPsRules) + { + $condition = $condition -replace $rule[0], $rule[1] + } + $expression = Evaluate-MSBuildExpression -expression $condition -isCondition + + if ($expression -ieq "true") + { + return $true + } + + if ($expression -ieq "false") + { + return $false + } + + [bool] $res = $false + try + { + $res = (Invoke-Expression $expression) -eq $true + } + catch + { + Write-Debug $_.Exception.Message + } + Write-Debug "Evaluated condition to $res" + + return $res +} diff --git a/scripts/psClang/msbuild-expression-eval.tests.ps1 b/scripts/psClang/msbuild-expression-eval.tests.ps1 new file mode 100644 index 0000000000..2a6a384258 --- /dev/null +++ b/scripts/psClang/msbuild-expression-eval.tests.ps1 @@ -0,0 +1,232 @@ +#Clear-Host + +# IMPORT code blocks + +Set-Variable -name "kScriptLocation" ` + -value (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) <#` + -option Constant#> + +@( + , "$kScriptLocation\io.ps1" + , "$kScriptLocation\msbuild-expression-eval.ps1" + ) | ForEach-Object { . $_ } + +Describe "MSBuild - Powershell Expression translation" { + It "Plain expressions" { + Evaluate-MSBuildExpression "MyProjectString" | Should -BeExactly "MyProjectString" + Evaluate-MSBuildExpression "1905" | Should -BeExactly "1905" + Evaluate-MSBuildExpression "a;;b;c" | Should -BeExactly "a;;b;c" + Evaluate-MSBuildExpression "a-b-c" | Should -BeExactly "a-b-c" + Evaluate-MSBuildExpression "1-2-3" | Should -BeExactly "1-2-3" + Evaluate-MSBuildExpression "{1-2-3-4}" | Should -BeExactly "{1-2-3-4}" + Evaluate-MSBuildExpression "1.2.3.4" | Should -BeExactly "1.2.3.4" + Evaluate-MSBuildExpression "c:\foo\bar.ini" | Should -BeExactly "c:\foo\bar.ini" + Evaluate-MSBuildExpression "..\foo\bar" | Should -BeExactly "..\foo\bar" + } + + It "Arithmetical operators" { + Evaluate-MSBuildExpression "`$(1+2+3)" | Should -BeExactly "6" + Evaluate-MSBuildExpression "`$(1-2-3)" | Should -BeExactly "-4" + Evaluate-MSBuildExpression "`$(1*2*3)" | Should -BeExactly "6" + Evaluate-MSBuildExpression "`$(10/2)" | Should -BeExactly "5" + } + + It "Read from registry" { + $e = '$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion@ProgramFilesDir)' + Evaluate-MSBuildExpression $e | Should -BeExactly $env:ProgramFiles + + $e = '$(GetRegValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion@ProgramFilesDir"))' + Evaluate-MSBuildExpression $e | Should -BeExactly $env:ProgramFiles + } + + It "Property expansion" { + $ProjectDir = "C:\Users\Default" + Evaluate-MSBuildExpression "`$Foo;`$(ProjectDir);..\..;..\..\third-party" ` + | Should -BeExactly '$Foo;C:\Users\Default;..\..;..\..\third-party' + + $TargetName = "Test" + Evaluate-MSBuildExpression "%(ASDASD);`$(TargetName)" | Should -BeExactly "%(ASDASD);Test" + + $prop = "123" + Evaluate-MSBuildExpression 'plaintext;"$(prop)"' | Should -BeExactly 'plaintext;"123"' + Evaluate-MSBuildExpression 'plaintext;''$(prop)''' | Should -BeExactly 'plaintext;"123"' + Evaluate-MSBuildExpression 'plaintext;$(prop)-$(prop)' | Should -BeExactly 'plaintext;123-123' + + $TestDir = $env:ProgramFiles + Evaluate-MSBuildExpression '$(TestDir)\first\second' | Should -BeExactly "$env:ProgramFiles\first\second" + } + + It "GetDirectoryNameOfFileAbove() MSBuild builtin function" { + [string] $MSBuildThisFileDirectory = $env:SystemRoot + + $e = '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), ''Program Files'')Program Files' + Evaluate-MSBuildExpression $e | Should -BeExactly $env:ProgramFiles + + $e = '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), "Program Files")Program Files' + Evaluate-MSBuildExpression $e | Should -BeExactly $env:ProgramFiles + + [string] $whatToFind = "Program Files" + $e = '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), ''$(whatToFind)'')Program Files' + Evaluate-MSBuildExpression $e | Should -BeExactly $env:ProgramFiles + + $e = '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Program Files)Program Files' + Evaluate-MSBuildExpression $e | Should -BeExactly $env:ProgramFiles + + [string] $_DirectoryBuildPropsFile = "clang-build.ps1" + [string] $MSBuildProjectDirectory = "$PSScriptRoot" + [string] $DirParent = [System.IO.Directory]::GetParent($MSBuildProjectDirectory) + + $e = '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), ''$(_DirectoryBuildPropsFile)''))' + Evaluate-MSBuildExpression $e | Should -Be "$DirParent" + } + + It "MakeRelative() MSBuild builtin function" { + $SystemDrive = $env:SystemDrive + $SystemRoot = $env:SystemRoot + $ProgramFiles = $env:ProgramFiles + + $e = "`$([MSBuild]::MakeRelative('$SystemDrive', '$SystemRoot'))" + Evaluate-MSBuildExpression $e | Should -Be "Windows" + + $e = "`$([MSBuild]::MakeRelative(`$(SystemDrive), '$SystemRoot'))" + Evaluate-MSBuildExpression $e | Should -Be "Windows" + + $e = '$([MSBuild]::MakeRelative($(SystemDrive), $(SystemRoot)\System32))' + Evaluate-MSBuildExpression $e | Should -Be "Windows\System32" + + $e = '$([MSBuild]::MakeRelative($(SystemRoot), $(SystemRoot)\System32))' + Evaluate-MSBuildExpression $e | Should -Be "System32" + + $e = '$([MSBuild]::MakeRelative($(ProgramFiles), $(SystemRoot)\System32))' + Evaluate-MSBuildExpression $e | Should -Be "..\Windows\System32" + } + + It ".NET Method invocation" { + $Sys32Folder = "System32" + $WinDir = $env:SystemRoot + $e = '$([System.IO.Path]::Combine(''$(WinDir)'', ''$(Sys32Folder)''))' + Evaluate-MSBuildExpression $e | Should -BeExactly "$WinDir\$Sys32Folder" + } +} + +Describe "Condition evaluation" { + It "Logical operators" { + Evaluate-MSBuildCondition '0 != 1' | Should -BeExactly $true + Evaluate-MSBuildCondition '1 != 1' | Should -BeExactly $false + Evaluate-MSBuildCondition '1 == 1' | Should -BeExactly $true + Evaluate-MSBuildCondition '0 == 1' | Should -BeExactly $false + Evaluate-MSBuildCondition '0 < 1' | Should -BeExactly $true + Evaluate-MSBuildCondition '1 <= 1' | Should -BeExactly $true + Evaluate-MSBuildCondition '1 < 0' | Should -BeExactly $false + Evaluate-MSBuildCondition '1 <= 0' | Should -BeExactly $false + Evaluate-MSBuildCondition '1 > 0' | Should -BeExactly $true + Evaluate-MSBuildCondition '1 >= 1' | Should -BeExactly $true + Evaluate-MSBuildCondition '1 < 0 or 0 < 1' | Should -BeExactly $true + Evaluate-MSBuildCondition '!(1 < 0 or 0 < 1)' | Should -BeExactly $false + Evaluate-MSBuildCondition '1 < 0 and 0 < 1' | Should -BeExactly $false + Evaluate-MSBuildCondition '1 < 0 and 0 < 1' | Should -BeExactly $false + Evaluate-MSBuildCondition '((1 < 0) or (0 < 1)) and !("a"=="b")' | Should -BeExactly $true + Evaluate-MSBuildCondition '"apple" == "apple"' | Should -BeExactly $true + Evaluate-MSBuildCondition '''apple'' == ''apple''' | Should -BeExactly $true + Evaluate-MSBuildCondition '''apple'' == ''pear''' | Should -BeExactly $false + Evaluate-MSBuildCondition '"apple" != "pear"' | Should -BeExactly $true + } + + It "Registry access" { + $c = "'`$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion@ProgramFilesDir)' != ''" + Evaluate-MSBuildCondition $c | Should -BeExactly $true + + $ProgramFiles = $env:ProgramFiles + $c = "'`$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion@ProgramFilesDir)' == '`$(ProgramFiles)'" + Evaluate-MSBuildCondition $c | Should -BeExactly $true + + $c = "'`$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion@NonexistentValue)' == ''" + Evaluate-MSBuildCondition $c | Should -BeExactly $true + } + + It "Variable expansion" { + + $Configuration = "Release2" + $Platform = "Win32" + + Evaluate-MSBuildCondition "'`$(Configuration)|`$(Platform)'=='Debug|Win32' or '`$(Configuration)' == 'Release2'" | Should -BeExactly $true + Evaluate-MSBuildCondition "'`$(Configuration)|`$(Platform)'=='Release|Win32'" | Should -BeExactly $false + Evaluate-MSBuildCondition '$(Platform.Replace(" ", "")) and $(testB)' | Should -BeExactly $false + } + + It "Prop to Bool decay" { + $First = "something" + $Second = "else" + + Evaluate-MSBuildCondition '$(First) and $(Second)' | Should -BeExactly $true + + Remove-Variable "First" + + Evaluate-MSBuildCondition '$(First) and $(Second)' | Should -BeExactly $false + } + + It "Exists() MSBuild builtin function" { + + $WinDir = $env:SystemRoot + Evaluate-MSBuildCondition "exists('`$(WinDir)')" | Should -BeExactly $true + Evaluate-MSBuildCondition "1 == 1 and exists('`$(WinDir)')" | Should -BeExactly $true + Evaluate-MSBuildCondition "exists('`$(WinDir)\System32')" | Should -BeExactly $true + + $WinDir += "gibberish12345" + Evaluate-MSBuildCondition "exists('`$(WinDir)')" | Should -BeExactly $false + Evaluate-MSBuildCondition "0 == 1 and exists('`$(WinDir)')" | Should -BeExactly $false + + [System.Reflection.Assembly]::LoadWithPartialName("System.IO") + $eression = 'Exists("$([System.IO.Directory]::GetCurrentDirectory())")' + Evaluate-MSBuildCondition $eression | Should -BeExactly $true + $eression = 'Exists("$([System.IO.Directory]::GetCurrentDirectory())\nonexistent12345")' + Evaluate-MSBuildCondition $eression | Should -BeExactly $false + + $Sys32 = "$env:SystemRoot\System32" + $WinDir = "$Sys32..\.." + Evaluate-MSBuildCondition "Exists('`$(Sys32)\..')" | Should -BeExactly $true + } + + It "Access to [String] builtin functions" { + + $TargetName = "AnotherTest" + Evaluate-MSBuildCondition "`$(TargetName.EndsWith('Test'))" | Should -BeExactly $true + Evaluate-MSBuildCondition "`$(TargetName.EndsWith('Test2'))" | Should -BeExactly $false + + $myVar = 'TwoThree' + $MySelector = "One;Two;Three" + Evaluate-MSBuildCondition "`$(MySelector.Contains(`$(myVar.Substring(3, 3))))"` + | Should -BeExactly $true + + $MySelector = "One;Two;Three" + $myVar = "Two" + Evaluate-MSBuildCondition "`$(MySelector.Contains(`$(myVar)))" | Should -BeExactly $true + + $MySelector = "One;Two;Three" + Evaluate-MSBuildCondition "`$(MySelector.Contains('Three'))" | Should -BeExactly $true + Evaluate-MSBuildCondition "`$(MySelector.Contains('Four'))" | Should -BeExactly $false + } + + It ".NET method invocation" { + $year = (Get-Date).Year + Evaluate-MSBuildCondition "`$([System.DateTime]::Now.Year) == `$(year)" | Should -BeExactly $true + Evaluate-MSBuildCondition "`$([System.DateTime]::Now.Year) != `$(year)" | Should -BeExactly $false + } + + It "HasTrailingSlash() MSBuild builtin function" { + Evaluate-MSBuildCondition "HasTrailingSlash('c:\windows\')" | Should -BeExactly $true + Evaluate-MSBuildCondition "HasTrailingSlash('c:\windows')" | Should -BeExactly $false + + $c = "HasTrailingSlash('c:\windows\') and hasTrailingSlash('c:\temp/')" + Evaluate-MSBuildCondition $c | Should -BeExactly $true + + $c = "HasTrailingSlash('c:\windows\') and !hasTrailingSlash('c:\temp/')" + Evaluate-MSBuildCondition $c | Should -BeExactly $false + + $prop = "c:\windows\" + Evaluate-MSBuildCondition "hasTrailingSlash(`$(prop))" | Should -BeExactly $true + + $prop = "c:\windows" + Evaluate-MSBuildCondition "hasTrailingSlash(`$(prop))" | Should -BeExactly $false + } +} diff --git a/scripts/psClang/msbuild-project-data.ps1 b/scripts/psClang/msbuild-project-data.ps1 new file mode 100644 index 0000000000..c8b1b8e030 --- /dev/null +++ b/scripts/psClang/msbuild-project-data.ps1 @@ -0,0 +1,583 @@ +#------------------------------------------------------------------------------------------------- +# PlatformToolset constants + +Set-Variable -name kDefinesUnicode -value @("-DUNICODE" + ,"-D_UNICODE" + ) ` + -option Constant + +Set-Variable -name kDefinesMultiThreaded -value @("-D_MT") ` + -option Constant + +Set-Variable -name kDefinesClangXpTargeting ` + -value @("-D_USING_V110_SDK71_") ` + -option Constant + +Set-Variable -name kIncludePathsXPTargetingSDK ` + -value "${Env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v7.1A\Include" ` + -option Constant + +Set-Variable -name kVStudioDefaultPlatformToolset -Value "v141" -option Constant + +Set-Variable -name kClangFlag32BitPlatform -value "-m32" -option Constant + +# ------------------------------------------------------------------------------------------------ +# Xpath selectors + +Set-Variable -name kVcxprojXpathPreprocessorDefs ` + -value "ns:Project/ns:ItemDefinitionGroup/ns:ClCompile/ns:PreprocessorDefinitions" ` + -option Constant + +Set-Variable -name kVcxprojXpathAdditionalIncludes ` + -value "ns:Project/ns:ItemDefinitionGroup/ns:ClCompile/ns:AdditionalIncludeDirectories" ` + -option Constant + +Set-Variable -name kVcxprojXpathRuntimeLibrary ` + -value "ns:Project/ns:ItemDefinitionGroup/ns:ClCompile/ns:RuntimeLibrary" ` + -option Constant + +Set-Variable -name kVcxprojXpathHeaders ` + -value "ns:Project/ns:ItemGroup/ns:ClInclude" ` + -option Constant + +Set-Variable -name kVcxprojXpathCompileFiles ` + -value "ns:Project/ns:ItemGroup/ns:ClCompile" ` + -option Constant + +Set-Variable -name kVcxprojXpathWinPlatformVer ` + -value "ns:Project/ns:PropertyGroup/ns:WindowsTargetPlatformVersion" ` + -option Constant + +Set-Variable -name kVcxprojXpathForceIncludes ` + -value "ns:Project/ns:ItemDefinitionGroup/ns:ClCompile/ns:ForcedIncludeFiles" ` + -option Constant + +Set-Variable -name kVcxprojXpathPCH ` + -value "ns:Project/ns:ItemGroup/ns:ClCompile/ns:PrecompiledHeader[text()='Create']" ` + -option Constant + +Set-Variable -name kVcxprojXpathToolset ` + -value "ns:Project/ns:PropertyGroup[@Label='Configuration']/ns:PlatformToolset" ` + -option Constant + +Set-Variable -name kVcxprojXpathCppStandard ` + -value "ns:Project/ns:ItemDefinitionGroup/ns:ClCompile/ns:LanguageStandard" ` + -option Constant + + +Set-Variable -name kVcxprojXpathProjectCompileAs ` + -value "ns:Project/ns:ItemDefinitionGroup/ns:ClCompile/ns:CompileAs" ` + -option Constant + +# ------------------------------------------------------------------------------------------------ +# Default platform sdks and standard + +Set-Variable -name kVSDefaultWinSDK -value '8.1' -option Constant +Set-Variable -name kVSDefaultWinSDK_XP -value '7.0' -option Constant +Set-Variable -name kDefaultCppStd -value "stdcpp14" -option Constant + +# ------------------------------------------------------------------------------------------------ +Set-Variable -name kCProjectCompile -value "CompileAsC" -option Constant + +Add-Type -TypeDefinition @" + public enum UsePch + { + Use, + NotUsing, + Create + } +"@ + +Function Should-CompileProject([Parameter(Mandatory = $true)][string] $vcxprojPath) +{ + if ($aVcxprojToCompile -eq $null) + { + return $true + } + + foreach ($projMatch in $aVcxprojToCompile) + { + if (IsFileMatchingName -filePath $vcxprojPath -matchName $projMatch) + { + return $true + } + } + + return $false +} + +Function Should-IgnoreProject([Parameter(Mandatory = $true)][string] $vcxprojPath) +{ + if ($aVcxprojToIgnore -eq $null) + { + return $false + } + + foreach ($projIgnoreMatch in $aVcxprojToIgnore) + { + if (IsFileMatchingName -filePath $vcxprojPath -matchName $projIgnoreMatch) + { + return $true + } + } + + return $false +} + +Function Should-CompileFile([Parameter(Mandatory = $false)][System.Xml.XmlNode] $fileNode + , [Parameter(Mandatory = $false)][string] $pchCppName +) +{ + if ($fileNode -eq $null) + { + return $false + } + + [string] $file = $fileNode.Include + + if (($file -eq $null) -or (![string]::IsNullOrEmpty($pchCppName) -and ($file -eq $pchCppName))) + { + return $false + } + + [System.Xml.XmlNode] $excluded = $fileNode.SelectSingleNode("ns:ExcludedFromBuild", $global:xpathNS) + + if (($excluded -ne $null) -and ($excluded.InnerText -ne $null) -and ($excluded.InnerText -ieq "true")) + { + return $false + } + + return $true +} + +Function Should-IgnoreFile([Parameter(Mandatory = $true)][string] $file) +{ + if ($aCppToIgnore -eq $null) + { + return $false + } + + foreach ($projIgnoreMatch in $aCppToIgnore) + { + if (IsFileMatchingName -filePath $file -matchName $projIgnoreMatch) + { + return $true + } + } + + return $false +} + +Function Get-ProjectFilesToCompile([Parameter(Mandatory = $false)][string] $pchCppName) +{ + [System.Xml.XmlElement[]] $projectEntries = Select-ProjectNodes($kVcxprojXpathCompileFiles) | ` + Where-Object { Should-CompileFile -fileNode $_ -pchCppName $pchCppName } + + [System.Collections.ArrayList] $files = @() + foreach ($entry in $projectEntries) + { + [string[]] $matchedFiles = Canonize-Path -base $ProjectDir -child $entry.GetAttribute("Include") + [UsePch] $usePch = [UsePch]::Use + + $nodePch = $entry.SelectSingleNode('ns:PrecompiledHeader', $global:xpathNS) + if ($nodePch -and ![string]::IsNullOrEmpty($nodePch.'#text')) + { + switch ($nodePch.'#text') + { + 'NotUsing' { $usePch = [UsePch]::NotUsing } + 'Create' { $usePch = [UsePch]::Create } + } + } + + if ($matchedFiles.Count -gt 0) + { + foreach ($file in $matchedFiles) + { + $files += New-Object PsObject -Prop @{ "File"= $file; + "Pch" = $usePch; } + } + } + } + + if ($files.Count -gt 0) + { + $files = @($files | Where-Object { ! (Should-IgnoreFile -file $_.File) }) + } + + return $files +} + +Function Get-ProjectHeaders() +{ + [string[]] $headers = Select-ProjectNodes($kVcxprojXpathHeaders) | ForEach-Object {$_.Include } + + [string[]] $headerPaths = @() + + foreach ($headerEntry in $headers) + { + [string[]] $paths = Canonize-Path -base $ProjectDir -child $headerEntry -ignoreErrors + if ($paths.Count -gt 0) + { + $headerPaths += $paths + } + } + return $headerPaths +} + +Function Is-CProject() +{ + [string] $compileAs = (Select-ProjectNodes($kVcxprojXpathProjectCompileAs)).InnerText + return $compileAs -eq $kCProjectCompile +} + +Function Get-Project-SDKVer() +{ + [string] $sdkVer = (Select-ProjectNodes($kVcxprojXpathWinPlatformVer)).InnerText + + If ([string]::IsNullOrEmpty($sdkVer)) { "" } Else { $sdkVer.Trim() } +} + +Function Is-Project-MultiThreaded() +{ + $propGroup = Select-ProjectNodes($kVcxprojXpathRuntimeLibrary) + + $runtimeLibrary = $propGroup.InnerText + + return ![string]::IsNullOrEmpty($runtimeLibrary) +} + +Function Is-Project-Unicode() +{ + $propGroup = Select-ProjectNodes("ns:Project/ns:PropertyGroup[@Label='Configuration']/ns:CharacterSet") + if (! $propGroup) + { + return $false + } + return ($propGroup.InnerText -ieq "Unicode") +} + +Function Get-Project-CppStandard() +{ + [string] $cachedValueVarName = "ClangPowerTools:CppStd" + + [string] $cachedVar = (Get-Variable $cachedValueVarName -ErrorAction SilentlyContinue -ValueOnly) + if (![string]::IsNullOrEmpty($cachedVar)) + { + return $cachedVar + } + + [string] $cppStd = "" + + $cppStdNode = Select-ProjectNodes($kVcxprojXpathCppStandard) + if ($cppStdNode) + { + $cppStd = $cppStdNode.InnerText + } + else + { + $cppStd = $kDefaultCppStd + } + + $cppStdMap = @{ 'stdcpplatest' = 'c++1z' + ; 'stdcpp14' = 'c++14' + ; 'stdcpp17' = 'c++17' + } + + [string] $cppStdClangValue = $cppStdMap[$cppStd] + Set-Var -name $cachedValueVarName -value $cppStdClangValue + + return $cppStdClangValue +} + +Function Get-ClangCompileFlags([Parameter(Mandatory = $false)][bool] $isCpp = $true) +{ + [string[]] $flags = $aClangCompileFlags + if ($isCpp -and !($flags -match "-std=.*")) + { + [string] $cppStandard = Get-Project-CppStandard + + $flags = @("-std=$cppStandard") + $flags + } + + if ($Platform -ieq "x86" -or $Platform -ieq "Win32") + { + $flags += @($kClangFlag32BitPlatform) + } + + return $flags +} + +Function Get-ProjectPlatformToolset() +{ + $propGroup = Select-ProjectNodes($kVcxprojXpathToolset) + + $toolset = $propGroup.InnerText + + if ($toolset) + { + return $toolset + } + else + { + return $kVStudioDefaultPlatformToolset + } +} + +Function Get-ProjectIncludeDirectories() +{ + [string[]] $returnArray = ($IncludePath -split ";") | ` + Where-Object { ![string]::IsNullOrWhiteSpace($_) } | ` + ForEach-Object { Canonize-Path -base $ProjectDir -child $_.Trim() -ignoreErrors } | ` + Where-Object { ![string]::IsNullOrEmpty($_) } | ` + ForEach-Object { $_ -replace '\\$', '' } + if ($env:CPT_LOAD_ALL -eq '1') + { + return $returnArray + } + + [string] $vsPath = Get-VisualStudio-Path + Write-Verbose "Visual Studio location: $vsPath" + + [string] $platformToolset = Get-ProjectPlatformToolset + + if ($global:cptVisualStudioVersion -eq "2015") + { + $returnArray += Get-VisualStudio-Includes -vsPath $vsPath + } + else + { + $mscVer = Get-MscVer -visualStudioPath $vsPath + Write-Verbose "MSCVER: $mscVer" + + $returnArray += Get-VisualStudio-Includes -vsPath $vsPath -mscVer $mscVer + } + + $sdkVer = Get-Project-SDKVer + + # We did not find a WinSDK version in the vcxproj. We use Visual Studio's defaults + if ([string]::IsNullOrEmpty($sdkVer)) + { + if ($platformToolset.EndsWith("xp")) + { + $sdkVer = $kVSDefaultWinSDK_XP + } + else + { + $sdkVer = $kVSDefaultWinSDK + } + } + + Write-Verbose "WinSDK version: $sdkVer" + + # ---------------------------------------------------------------------------------------------- + # Windows 10 + + if ((![string]::IsNullOrEmpty($sdkVer)) -and ($sdkVer.StartsWith("10"))) + { + $returnArray += @("${Env:ProgramFiles(x86)}\Windows Kits\10\Include\$sdkVer\ucrt") + + if ($platformToolset.EndsWith("xp")) + { + $returnArray += @($kIncludePathsXPTargetingSDK) + } + else + { + $returnArray += @( "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\$sdkVer\um" + , "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\$sdkVer\shared" + , "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\$sdkVer\winrt" + , "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\$sdkVer\cppwinrt" + ) + } + } + + # ---------------------------------------------------------------------------------------------- + # Windows 8 / 8.1 + + if ((![string]::IsNullOrEmpty($sdkVer)) -and ($sdkVer.StartsWith("8."))) + { + $returnArray += @("${Env:ProgramFiles(x86)}\Windows Kits\10\Include\10.0.10240.0\ucrt") + + if ($platformToolset.EndsWith("xp")) + { + $returnArray += @($kIncludePathsXPTargetingSDK) + } + else + { + $returnArray += @( "${Env:ProgramFiles(x86)}\Windows Kits\$sdkVer\Include\um" + , "${Env:ProgramFiles(x86)}\Windows Kits\$sdkVer\Include\shared" + , "${Env:ProgramFiles(x86)}\Windows Kits\$sdkVer\Include\winrt" + ) + } + } + + # ---------------------------------------------------------------------------------------------- + # Windows 7 + + if ((![string]::IsNullOrEmpty($sdkVer)) -and ($sdkVer.StartsWith("7.0"))) + { + $returnArray += @("$vsPath\VC\Auxiliary\VS\include") + + if ($platformToolset.EndsWith("xp")) + { + $returnArray += @( "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\10.0.10240.0\ucrt" + , $kIncludePathsXPTargetingSDK + ) + } + else + { + $returnArray += @( "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\7.0\ucrt") + } + } + + return ( $returnArray | ForEach-Object { Remove-PathTrailingSlash -path $_ } ) +} + +<# +.DESCRIPTION + Retrieve directory in which the PCH CPP resides (e.g. stdafx.cpp, stdafxA.cpp) +#> +Function Get-Project-PchCpp() +{ + $pchCppRelativePath = Select-ProjectNodes($kVcxprojXpathPCH) | + Select-Object -ExpandProperty ParentNode | + Select-Object -first 1 | + Select-Object -ExpandProperty Include + + return $pchCppRelativePath +} + + +<# +.DESCRIPTION + Retrieve array of preprocessor definitions for a given project, in Clang format (-DNAME ) +#> +Function Get-ProjectPreprocessorDefines() +{ + [string[]] $tokens = (Select-ProjectNodes $kVcxprojXpathPreprocessorDefs).InnerText -split ";" + + # make sure we add the required prefix and escape double quotes + [string[]]$defines = ( $tokens | ` + ForEach-Object { $_.Trim() } | ` + Where-Object { $_ } | ` + ForEach-Object { '"' + $(($kClangDefinePrefix + $_) -replace '"', '\"') + '"' } ) + + if (Is-Project-Unicode) + { + $defines += $kDefinesUnicode + } + + if (Is-Project-MultiThreaded) + { + $defines += $kDefinesMultiThreaded + } + + [string] $platformToolset = Get-ProjectPlatformToolset + if ($platformToolset.EndsWith("xp")) + { + $defines += $kDefinesClangXpTargeting + } + + return $defines +} + +Function Get-ProjectAdditionalIncludes() +{ + [string[]] $tokens = @() + + $data = Select-ProjectNodes $kVcxprojXpathAdditionalIncludes + $tokens += ($data).InnerText -split ";" + + foreach ($token in $tokens) + { + if ([string]::IsNullOrWhiteSpace($token)) + { + continue + } + + [string] $includePath = Canonize-Path -base $ProjectDir -child $token.Trim() -ignoreErrors + if (![string]::IsNullOrEmpty($includePath)) + { + $includePath -replace '\\$', '' + } + } +} + +Function Get-ProjectForceIncludes() +{ + [System.Xml.XmlElement] $forceIncludes = Select-ProjectNodes $kVcxprojXpathForceIncludes + if ($forceIncludes) + { + return $forceIncludes.InnerText -split ";" + } + + return $null +} + +<# +.DESCRIPTION + Retrieve directory in which stdafx.h resides +#> +Function Get-ProjectStdafxDir( [Parameter(Mandatory = $true)] [string] $pchHeaderName + , [Parameter(Mandatory = $false)] [string[]] $includeDirectories + , [Parameter(Mandatory = $false)] [string[]] $additionalIncludeDirectories +) +{ + [string] $stdafxPath = "" + + [string[]] $projectHeaders = Get-ProjectHeaders + if ($projectHeaders.Count -gt 0) + { + # we need to use only backslashes so that we can match against file header paths + $pchHeaderName = $pchHeaderName.Replace("/", "\") + + $stdafxPath = $projectHeaders | Where-Object { (Get-FileName -path $_) -eq $pchHeaderName } + } + + if ([string]::IsNullOrEmpty($stdafxPath)) + { + [string[]] $searchPool = @($ProjectDir); + if ($includeDirectories.Count -gt 0) + { + $searchPool += $includeDirectories + } + if ($additionalIncludeDirectories.Count -gt 0) + { + $searchPool += $additionalIncludeDirectories + } + + foreach ($dir in $searchPool) + { + [string] $stdafxPath = Canonize-Path -base $dir -child $pchHeaderName -ignoreErrors + if (![string]::IsNullOrEmpty($stdafxPath)) + { + break + } + } + } + + if ([string]::IsNullOrEmpty($stdafxPath)) + { + return "" + } + else + { + [string] $stdafxDir = Get-FileDirectory($stdafxPath) + return $stdafxDir + } +} + +Function Get-PchCppIncludeHeader([Parameter(Mandatory = $true)][string] $pchCppFile) +{ + [string] $cppPath = Canonize-Path -base $ProjectDir -child $pchCppFile + + [string[]] $fileLines = Get-Content -path $cppPath + foreach ($line in $fileLines) + { + $regexMatch = [regex]::match($line, '^\s*#include\s+"(\S+)"') + if ($regexMatch.Success) + { + return $regexMatch.Groups[1].Value + } + } + return "" +} diff --git a/scripts/psClang/msbuild-project-data.tests.ps1 b/scripts/psClang/msbuild-project-data.tests.ps1 new file mode 100644 index 0000000000..7257a5bb6d --- /dev/null +++ b/scripts/psClang/msbuild-project-data.tests.ps1 @@ -0,0 +1,19 @@ +#Clear-Host + +# IMPORT code blocks + +Set-Variable -name "kScriptLocation" ` + -value (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) <#` + -option Constant#> + +@( + , "$kScriptLocation\io.ps1" + , "$kScriptLocation\msbuild-expression-eval.ps1" + , "$kScriptLocation\msbuild-project-load.ps1" + , "$kScriptLocation\msbuild-project-data.ps1" + ) | ForEach-Object { . $_ } + +Describe "VC++ Project Data Processing" { + It "To be implemented" { + } +} diff --git a/scripts/psClang/msbuild-project-load.ps1 b/scripts/psClang/msbuild-project-load.ps1 new file mode 100644 index 0000000000..1c868d6cbd --- /dev/null +++ b/scripts/psClang/msbuild-project-load.ps1 @@ -0,0 +1,623 @@ +#------------------------------------------------------------------------------------------------- +# Global variables + +# vcxproj and property sheet files declare MsBuild properties (e.g. $(MYPROP)). +# they are used in project xml nodes expressions. we have a +# translation engine (MSBUILD-POWERSHELL) for these. it relies on +# PowerShell to evaluate these expressions. We have to inject project +# properties in the PowerShell runtime context. We keep track of them in +# this list, so that each project can know to clean previous vars before loading begins. +if (! (Test-Path variable:global:ProjectSpecificVariables)) +{ + [System.Collections.ArrayList] $global:ProjectSpecificVariables = @() +} + +if (! (Test-Path variable:global:ScriptParameterBackupValues)) +{ + [System.Collections.Hashtable] $global:ScriptParameterBackupValues = @{} +} + +# current vcxproj and property sheets +[xml[]] $global:projectFiles = @(); + +# path of current project +[string] $global:vcxprojPath = ""; + +# namespace of current project vcxproj XML +[System.Xml.XmlNamespaceManager] $global:xpathNS = $null; + + +Set-Variable -name "kRedundantSeparatorsReplaceRules" -option Constant ` + -value @( <# handle multiple consecutive separators #> ` + (";+" , ";") ` + <# handle separator at end #> ` + , (";$" , "") ` + <# handle separator at beginning #> ` + , ("^;" , "") ` + ) + +Function Set-Var([parameter(Mandatory = $false)][string] $name + ,[parameter(Mandatory = $false)] $value + ,[parameter(Mandatory = $false)][switch] $asScriptParameter + ) +{ + if ($asScriptParameter) + { + if (Test-Path "variable:$name") + { + $oldVar = Get-Variable $name + $oldValue = $oldVar.Value + + if ($oldValue -and + $oldValue.GetType() -and + $oldValue.GetType().ToString() -eq "System.Management.Automation.SwitchParameter") + { + $oldValue = $oldValue.ToBool() + } + + $global:ScriptParameterBackupValues[$name] = $oldValue + } + else + { + $global:ScriptParameterBackupValues[$name] = $null + } + } + + Write-Verbose "SET_VAR $($name): $value" + if ($asScriptParameter) + { + Set-Variable -name $name -Value $value -Scope Script + } + else + { + Set-Variable -name $name -Value $value -Scope Global + } + + if (!$asScriptParameter -and !$global:ProjectSpecificVariables.Contains($name)) + { + $global:ProjectSpecificVariables.Add($name) | Out-Null + } +} + +Function Clear-Vars() +{ + Write-Verbose-Array -array $global:ProjectSpecificVariables ` + -name "Deleting variables initialized by previous project" + + foreach ($var in $global:ProjectSpecificVariables) + { + Remove-Variable -name $var -scope Global -ErrorAction SilentlyContinue + } + + foreach ($varName in $global:ScriptParameterBackupValues.Keys) + { + Write-Verbose "Restoring $varName to old value $($ScriptParameterBackupValues[$varName])" + Set-Variable -name $varName -value $ScriptParameterBackupValues[$varName] + } + + $global:ScriptParameterBackupValues.Clear() + + $global:ProjectSpecificVariables.Clear() +} + +Function UpdateScriptParameter([Parameter(Mandatory = $true)] [string] $paramName + ,[Parameter(Mandatory = $false)][string] $paramValue) +{ + [bool] $isSwitch = $false + $evalParamValue = "" # no type specified because we don't know it yet + + if ($paramValue) # a parameter + { + $evalParamValue = Invoke-Expression $paramValue # evaluate expression to get actual value + } + else # a switch + { + $isSwitch = $true + } + + # the parameter name we detected may be an alias => translate it into the real name + [string] $realParamName = Get-CommandParameterName -command "$PSScriptRoot\..\clang-build.ps1" ` + -nameOrAlias $paramName + if (!$realParamName) + { + Write-Output "OVERVIEW: Clang Power Tools: compiles or tidies up code from Visual Studio .vcxproj project files`n" + + Write-Output "USAGE: clang-build.ps1 [options]`n" + + Write-Output "OPTIONS: " + Print-CommandParameters "$PSScriptRoot\..\clang-build.ps1" + + Fail-Script "Unsupported option '$paramName'. Check cpt.config." + } + + if ($isSwitch) + { + Set-Var -name $realParamName -value $true -asScriptParameter + } + else + { + Set-Var -name $realParamName -value $evalParamValue -asScriptParameter + } +} + +Function Get-ConfigFileParameters() +{ + [System.Collections.Hashtable] $retArgs = @{} + + [string] $startDir = If ([string]::IsNullOrWhiteSpace($ProjectDir)) { $aSolutionsPath } else { $ProjectDir } + [string] $configFile = (GetDirNameOfFileAbove -startDir $startDir -targetFile "cpt.config") + "\cpt.config" + if (!(Test-Path $configFile)) + { + return $retArgs + } + Write-Verbose "Found cpt.config in $configFile" + + [xml] $configXml = Get-Content $configFile + $configXpathNS= New-Object System.Xml.XmlNamespaceManager($configXml.NameTable) + $configXpathNS.AddNamespace("ns", $configXml.DocumentElement.NamespaceURI) + + [System.Xml.XmlElement[]] $argElems = $configXml.SelectNodes("/ns:cpt-config/*", $configXpathNS) + + foreach ($argEl in $argElems) + { + if ($argEl.Name.StartsWith("vsx-")) + { + continue # settings for the Visual Studio Extension + } + + if ($argEl.HasAttribute("Condition")) + { + [bool] $isApplicable = Evaluate-MSBuildCondition -condition $argEl.GetAttribute("Condition") + if (!$isApplicable) + { + continue + } + } + $retArgs[$argEl.Name] = $argEl.InnerText + } + + return $retArgs +} + +Function Update-ParametersFromConfigFile() +{ + [System.Collections.Hashtable] $configParams = Get-ConfigFileParameters + if (!$configParams) + { + return + } + + foreach ($paramName in $configParams.Keys) + { + UpdateScriptParameter -paramName $paramName -paramValue $configParams[$paramName] + } +} + +Function InitializeMsBuildProjectProperties() +{ + Write-Verbose "Importing environment variables into current scope" + foreach ($var in (Get-ChildItem Env:)) + { + Set-Var -name $var.Name -value $var.Value + } + + Set-Var -name "MSBuildProjectFullPath" -value $global:vcxprojPath + Set-Var -name "ProjectDir" -value (Get-FileDirectory -filePath $global:vcxprojPath) + Set-Var -name "MSBuildProjectExtension" -value ([IO.Path]::GetExtension($global:vcxprojPath)) + Set-Var -name "MSBuildProjectFile" -value (Get-FileName -path $global:vcxprojPath) + Set-Var -name "MSBuildProjectName" -value (Get-FileName -path $global:vcxprojPath -noext) + Set-Var -name "MSBuildProjectDirectory" -value (Get-FileDirectory -filePath $global:vcxprojPath) + Set-Var -name "MSBuildProgramFiles32" -value "${Env:ProgramFiles(x86)}" + # defaults for projectname and targetname, may be overriden by project settings + Set-Var -name "ProjectName" -value $MSBuildProjectName + Set-Var -name "TargetName" -value $MSBuildProjectName + + # These would enable full project platform references parsing, experimental right now + if ($env:CPT_LOAD_ALL -eq '1') + { + Set-Var -name "ConfigurationType" -value "Application" + Set-Var -name "VCTargetsPath" -value "$(Get-VisualStudio-Path)\Common7\IDE\VC\VCTargets\" + Set-Var -name "VsInstallRoot" -value (Get-VisualStudio-Path) + Set-Var -name "MSBuildExtensionsPath" -value "$(Get-VisualStudio-Path)\MSBuild" + Set-Var -name "LocalAppData" -value $env:LOCALAPPDATA + Set-Var -name "UserRootDir" -value "$LocalAppData\Microsoft\MSBuild\v4.0" + Set-Var -name "UniversalCRT_IncludePath" -value "${Env:ProgramFiles(x86)}\Windows Kits\10\Include\10.0.10240.0\ucrt" + } + + [string] $vsVer = "15.0" + if ($global:cptVisualStudioVersion -eq "2015") + { + $vsVer = "14.0" + } + Set-Var -name "VisualStudioVersion" -value $vsVer + Set-Var -name "MSBuildToolsVersion" -value $vsVer + + [string] $projectSlnPath = Get-ProjectSolution + [string] $projectSlnDir = Get-FileDirectory -filePath $projectSlnPath + Set-Var -name "SolutionDir" -value $projectSlnDir + [string] $projectSlnName = Get-FileName -path $projectSlnPath -noext + Set-Var -name "SolutionName" -value $projectSlnName + + Update-ParametersFromConfigFile +} + +Function InitializeMsBuildCurrentFileProperties([Parameter(Mandatory = $true)][string] $filePath) +{ + Set-Var -name "MSBuildThisFileFullPath" -value $filePath + Set-Var -name "MSBuildThisFileExtension" -value ([IO.Path]::GetExtension($filePath)) + Set-Var -name "MSBuildThisFile" -value (Get-FileName -path $filePath) + Set-Var -name "MSBuildThisFileName" -value (Get-FileName -path $filePath -noext) + Set-Var -name "MSBuildThisFileDirectory" -value (Get-FileDirectory -filePath $filePath) +} + +<# +.DESCRIPTION +A wrapper over the XmlDOcument.SelectNodes function. For convenience. +Not to be used directly. Please use Select-ProjectNodes instead. +#> +function Help:Get-ProjectFileNodes([xml] $projectFile, [string] $xpath) +{ + [System.Xml.XmlElement[]] $nodes = $projectFile.SelectNodes($xpath, $global:xpathNS) + return $nodes +} + +function GetNodeInheritanceToken([System.Xml.XmlNode] $node) +{ + [string] $inheritanceToken = "%($($node.Name))"; + if ($node.InnerText.Contains($inheritanceToken)) + { + return $inheritanceToken + } + + return "" +} + +function ReplaceInheritedNodeValue([System.Xml.XmlNode] $currentNode + , [System.Xml.XmlNode] $nodeToInheritFrom +) +{ + [string] $inheritanceToken = GetNodeInheritanceToken($currentNode) + if ([string]::IsNullOrEmpty($inheritanceToken)) + { + # no need to inherit + return $false + } + + [string] $replaceWith = "" + if ($nodeToInheritFrom) + { + $replaceWith = $nodeToInheritFrom.InnerText + } + + [string] $whatToReplace = [regex]::Escape($inheritanceToken); + if ([string]::IsNullOrEmpty($replaceWith)) + { + # handle semicolon separators + [string] $escTok = [regex]::Escape($inheritanceToken) + $whatToReplace = "(;$escTok)|($escTok;)|($escTok)" + } + + # replace inherited token and redundant separators + $replacementRules = @(, ($whatToReplace, $replaceWith)) + $kRedundantSeparatorsReplaceRules + foreach ($rule in $replacementRules) + { + $currentNode.InnerText = $currentNode.InnerText -replace $rule[0], $rule[1] + } + + return $currentNode.InnerText.Contains($inheritanceToken) +} + +<# +.SYNOPSIS +Selects one or more nodes from the project. +.DESCRIPTION +We often need to access data from the project, e.g. additional includes, Win SDK version. +A naive implementation would be to simply look inside the vcxproj, but that leaves out +property sheets. + +This function takes care to retrieve the nodes we're searching by looking in both the .vcxproj +and property sheets, taking care to inherit values accordingly. +.EXAMPLE +Give an example of how to use it +.EXAMPLE +Give another example of how to use it. +.PARAMETER xpath +XPath we want to use for searching nodes. +.PARAMETER fileIndex +Optional. Index of the project xml file we want to start our search in. +0 = .vcxproj and then, recursively, all property sheets +1 = first property sheet and then, recursively, all other property sheets +etc. +#> +function Select-ProjectNodes([Parameter(Mandatory = $true)] [string][string] $xpath + , [Parameter(Mandatory = $false)] [int] $fileIndex = 0) +{ + [System.Xml.XmlElement[]] $nodes = @() + + if ($fileIndex -ge $global:projectFiles.Count) + { + return $nodes + } + + $nodes = Help:Get-ProjectFileNodes -projectFile $global:projectFiles[$fileIndex] ` + -xpath $xpath + + # nothing on this level or we're dealing with an ItemGroup, go above + if ($nodes.Count -eq 0 -or $xpath.Contains("ItemGroup")) + { + [System.Xml.XmlElement[]] $upperNodes = Select-ProjectNodes -xpath $xpath -fileIndex ($fileIndex + 1) + if ($upperNodes.Count -gt 0) + { + $nodes += $upperNodes + } + return $nodes + } + + if ($nodes[$nodes.Count - 1]."#text") + { + # we found textual settings that can be inherited. see if we should inherit + + [System.Xml.XmlNode] $nodeToReturn = $nodes[$nodes.Count - 1] + if ($nodeToReturn.Attributes.Count -gt 0) + { + throw "Did not expect node to have attributes" + } + + [bool] $shouldInheritMore = ![string]::IsNullOrEmpty((GetNodeInheritanceToken -node $nodeToReturn)) + for ([int] $i = $nodes.Count - 2; ($i -ge 0) -and $shouldInheritMore; $i -= 1) + { + $shouldInheritMore = ReplaceInheritedNodeValue -currentNode $nodeToReturn -nodeToInheritFrom $nodes[$i] + } + + if ($shouldInheritMore) + { + [System.Xml.XmlElement[]] $inheritedNodes = Select-ProjectNodes -xpath $xpath -fileIndex ($fileIndex + 1) + if ($inheritedNodes.Count -gt 1) + { + throw "Did not expect to inherit more than one node" + } + if ($inheritedNodes.Count -eq 1) + { + $shouldInheritMore = ReplaceInheritedNodeValue -currentNode $nodeToReturn -nodeToInheritFrom $inheritedNodes[0] + } + } + + # we still could have to inherit from parents but when not loading + # all MS prop sheets we have nothing to inherit from, delete inheritance token + ReplaceInheritedNodeValue -currentNode $nodeToReturn -nodeToInheritFrom $null | Out-Null + + return @($nodeToReturn) + } + else + { + # return what we found + return $nodes + } +} + +<# +.DESCRIPTION + Finds the first config-platform pair in the vcxproj. + We'll use it for all project data retrievals. + + Items for other config-platform pairs will be removed from the DOM. + This is needed so that our XPath selectors don't get confused when looking for data. +#> +function Detect-ProjectDefaultConfigPlatform([string] $projectValue) +{ + [string]$configPlatformName = "" + + if (![string]::IsNullOrEmpty($aVcxprojConfigPlatform)) + { + $configPlatformName = $aVcxprojConfigPlatform + } + else + { + $configPlatformName = $projectValue + } + + if ([string]::IsNullOrEmpty($configPlatformName)) + { + throw "Could not automatically detect a configuration platform" + } + + [string[]] $configAndPlatform = $configPlatformName.Split('|') + Set-Var -Name "Configuration" -Value $configAndPlatform[0] + Set-Var -Name "Platform" -Value $configAndPlatform[1] +} + +function HandleChooseNode([System.Xml.XmlNode] $aChooseNode) +{ + SanitizeProjectNode $aChooseNode + if ($aChooseNode.ChildNodes.Count -eq 0) + { + return + } + + [System.Xml.XmlElement] $selectedChild = $aChooseNode.ChildNodes | ` + Where-Object { $_.GetType().Name -eq "XmlElement" } | ` + Select -first 1 + + foreach ($selectedGrandchild in $selectedChild.ChildNodes) + { + $aChooseNode.ParentNode.AppendChild($selectedGrandchild.Clone()) | Out-Null + } + + $aChooseNode.ParentNode.RemoveChild($aChooseNode) | Out-Null +} + +function SanitizeProjectNode([System.Xml.XmlNode] $node) +{ + if ($node.Name -ieq "#comment") + { + return + } + + [System.Collections.ArrayList] $nodesToRemove = @() + + if ($node.Name -ieq "#text" -and $node.InnerText.Length -gt 0) + { + # evaluate node content + $node.InnerText = Evaluate-MSBuildExpression $node.InnerText + } + + if ($node.Name -ieq "Import") + { + [string] $relPath = Evaluate-MSBuildExpression $node.GetAttribute("Project") + [string[]] $paths = Canonize-Path -base (Get-Location) -child $relPath -ignoreErrors + + foreach ($path in $paths) + { + if (![string]::IsNullOrEmpty($path) -and (Test-Path $path)) + { + Write-Verbose "Property sheet: $path" + [string] $currentFile = $global:currentMSBuildFile + SanitizeProjectFile($path) + + $global:currentMSBuildFile = $currentFile + InitializeMsBuildCurrentFileProperties -filePath $global:currentMSBuildFile + } + else + { + Write-Verbose "Could not find property sheet $relPath" + } + } + } + + if ( ($node.Name -ieq "ClCompile" -or $node.Name -ieq "ClInclude") -and + ![string]::IsNullOrEmpty($node.GetAttribute("Include")) ) + { + [string] $expandedAttr = Evaluate-MSBuildExpression $node.GetAttribute("Include") + $node.Attributes["Include"].Value = $expandedAttr + } + + if ($node.Name -ieq "Choose") + { + HandleChooseNode $chooseChild + } + + if ($node.Name -ieq "Otherwise") + { + [System.Xml.XmlElement[]] $siblings = $node.ParentNode.ChildNodes | ` + Where-Object { $_.GetType().Name -ieq "XmlElement" -and $_ -ne $node } + if ($siblings.Count -gt 0) + { + # means there's a element that matched + # should not be evaluated, we could set unwated properties + return + } + } + + if ($node.Name -ieq "ItemGroup" -and $node.GetAttribute("Label") -ieq "ProjectConfigurations") + { + [System.Xml.XmlElement] $firstChild = $node.ChildNodes | ` + Where-Object { $_.GetType().Name -ieq "XmlElement" } | ` + Select-Object -First 1 + Detect-ProjectDefaultConfigPlatform $firstChild.GetAttribute("Include") + } + + if ($node.ParentNode.Name -ieq "PropertyGroup") + { + # set new property value + [string] $propertyName = $node.Name + [string] $propertyValue = Evaluate-MSBuildExpression $node.InnerText + + Set-Var -Name $propertyName -Value $propertyValue + + return + } + + foreach ($child in $node.ChildNodes) + { + [bool] $validChild = $true + if ($child.GetType().Name -ieq "XmlElement") + { + if ($child.HasAttribute("Condition")) + { + # process node condition + [string] $nodeCondition = $child.GetAttribute("Condition") + $validChild = ((Evaluate-MSBuildCondition($nodeCondition)) -eq $true) + if ($validChild) + { + $child.RemoveAttribute("Condition") + } + } + } + if (!$validChild) + { + $nodesToRemove.Add($child) | out-null + continue + } + else + { + SanitizeProjectNode($child) + } + } + + foreach ($nodeToRemove in $nodesToRemove) + { + $nodeToRemove.ParentNode.RemoveChild($nodeToRemove) | out-null + } +} + +<# +.DESCRIPTION + Sanitizes a project xml file, by removing config-platform pairs different from the + one we selected. + This is needed so that our XPath selectors don't get confused when looking for data. +#> +function SanitizeProjectFile([string] $projectFilePath) +{ + Write-Verbose "`nSanitizing $projectFilePath" + + [xml] $fileXml = Get-Content $projectFilePath + $global:projectFiles += @($fileXml) + $global:xpathNS = New-Object System.Xml.XmlNamespaceManager($fileXml.NameTable) + $global:xpathNS.AddNamespace("ns", $fileXml.DocumentElement.NamespaceURI) + $global:currentMSBuildFile = $projectFilePath + + Push-Location (Get-FileDirectory -filePath $projectFilePath) + + InitializeMsBuildCurrentFileProperties -filePath $projectFilePath + SanitizeProjectNode($fileXml.Project) + + Pop-Location +} + +<# +.DESCRIPTION +Loads vcxproj and property sheets into memory. This needs to be called only once +when processing a project. Accessing project nodes can be done using Select-ProjectNodes. +#> +function LoadProject([string] $vcxprojPath) +{ + # Clean global variables that have been set by a previous project load + Clear-Vars + + $global:vcxprojPath = $vcxprojPath + + InitializeMsBuildProjectProperties + + $global:projectFiles = @() + + SanitizeProjectFile -projectFilePath $global:vcxprojPath + + if ($env:CPT_LOAD_ALL -ne "1") + { + # Tries to find a Directory.Build.props property sheet, starting from the + # project directory, going up. When one is found, the search stops. + # Multiple Directory.Build.props sheets are not supported. + [string] $directoryBuildSheetPath = (GetDirNameOfFileAbove -startDir $ProjectDir ` + -targetFile "Directory.Build.props") + "\Directory.Build.props" + if (Test-Path $directoryBuildSheetPath) + { + SanitizeProjectFile($directoryBuildSheetPath) + } + + [string] $vcpkgIncludePath = "$env:LOCALAPPDATA\vcpkg\vcpkg.user.targets" + if (Test-Path $vcpkgIncludePath) + { + SanitizeProjectFile($vcpkgIncludePath) + } + } +} diff --git a/scripts/psClang/msbuild-project-load.tests.ps1 b/scripts/psClang/msbuild-project-load.tests.ps1 new file mode 100644 index 0000000000..b09e029030 --- /dev/null +++ b/scripts/psClang/msbuild-project-load.tests.ps1 @@ -0,0 +1,18 @@ +#Clear-Host + +# IMPORT code blocks + +Set-Variable -name "kScriptLocation" ` + -value (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) <#` + -option Constant#> + +@( + , "$kScriptLocation\io.ps1" + , "$kScriptLocation\msbuild-expression-eval.ps1" + , "$kScriptLocation\msbuild-project-load.ps1" + ) | ForEach-Object { . $_ } + +Describe "VC++ Project Data Loading" { + It "To be implemented" { + } +} diff --git a/scripts/psClang/visualstudio-detection.ps1 b/scripts/psClang/visualstudio-detection.ps1 new file mode 100644 index 0000000000..d155b6c8fa --- /dev/null +++ b/scripts/psClang/visualstudio-detection.ps1 @@ -0,0 +1,102 @@ +# ------------------------------------------------------------------------------------------------ +# Helpers for locating Visual Studio on the computer + +# VsWhere is available starting with Visual Studio 2017 version 15.2. +Set-Variable -name kVsWhereLocation ` + -value "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" #` +#-option Constant + +# Default installation path of Visual Studio 2017. We'll use when VsWhere isn't available. +Set-Variable -name kVs15DefaultLocation ` + -value "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\$global:cptVisualStudioVersion\$aVisualStudioSku" #` +#-option Constant + +# Registry key containing information about Visual Studio 2015 installation path. +Set-Variable -name kVs2015RegistryKey ` + -value "HKLM:SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0" #` +#-option Constant + +# Default location for v140 toolset when installed as a feature of a VS 2017 installation +Set-Variable -name kVs2017Toolset140DiskLocation ` + -value "${Env:ProgramFiles(x86)}\Microsoft Visual Studio 14.0" #` +#-option Constant + +Function Get-MscVer() +{ + return ((Get-Item "$(Get-VisualStudio-Path)\VC\Tools\MSVC\" | Get-ChildItem) | select -last 1).Name +} + +Function Get-VisualStudio-Includes([Parameter(Mandatory = $true)][string] $vsPath, + [Parameter(Mandatory = $false)][string] $mscVer) +{ + [string] $mscVerToken = "" + If (![string]::IsNullOrEmpty($mscVer)) + { + $mscVerToken = "Tools\MSVC\$mscVer\" + } + + return @( "$vsPath\VC\$($mscVerToken)include" + , "$vsPath\VC\$($mscVerToken)atlmfc\include" + ) +} + +Function Get-VisualStudio-Path() +{ + if ($global:cptVisualStudioVersion -eq "2015") + { + # try to detect full installation + [string] $installLocation = (Get-Item $kVs2015RegistryKey).GetValue("InstallDir") + if ($installLocation) + { + $installLocation = Canonize-Path -base $installLocation -child "..\.." -ignoreErrors + } + if ($installLocation) + { + return $installLocation + } + + # we may have a VS 2017 installation with v140 toolset feature + [string] $iostreamLocation = Canonize-Path -base $kVs2017Toolset140DiskLocation ` + -child "VC\include\iostream" -ignoreErrors + if ($iostreamLocation) + { + return $kVs2017Toolset140DiskLocation + } + + Write-Err "Visual Studio 2015 installation location could not be detected" + } + else + { + if (Test-Path $kVsWhereLocation) + { + + [string] $product = "*" + if (![string]::IsNullOrEmpty($aVisualStudioSku)) + { + $product = "Microsoft.VisualStudio.Product.$aVisualStudioSku" + } + + [string[]] $output = (& "$kVsWhereLocation" -nologo ` + -property installationPath ` + -products $product ` + -prerelease) + + # the -prerelease switch is not available on older VS2017 versions + if (($output -join "").Contains("0x57")) <# error code for unknown parameter #> + { + $output = (& "$kVsWhereLocation" -nologo ` + -property installationPath ` + -products $product) + } + + return $output[0] + } + + if (Test-Path -Path $kVs15DefaultLocation) + { + return $kVs15DefaultLocation + } + + throw "Cannot locate Visual Studio location" + } +} diff --git a/scripts/psClang/visualstudio-detection.tests.ps1 b/scripts/psClang/visualstudio-detection.tests.ps1 new file mode 100644 index 0000000000..e3cca847df --- /dev/null +++ b/scripts/psClang/visualstudio-detection.tests.ps1 @@ -0,0 +1,73 @@ +#Clear-Host + +# IMPORT code blocks + +Set-Variable -name "kScriptLocation" ` + -value (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) <#` + -option Constant#> + +@( + , "$kScriptLocation\io.ps1" + , "$kScriptLocation\visualstudio-detection.ps1" + ) | ForEach-Object { . $_ } + +Describe "Visual Studio detection" { + # Mock script parameters + $global:cptVisualStudioVersion = "2017" + $aVisualStudioSku = "Professional" + + It "Get-MscVer" { + [string[]] $mscVer = Get-MscVer + $mscVer.Count | Should -BeExactly 1 + $mscVer[0] | Should -Not -BeNullOrEmpty + $mscVer[0].Length | Should -BeGreaterThan 3 + $mscVer[0].Contains(".") | Should -BeExactly $true + } + + It "Get-VisualStudio-Path" { + $vsPath = Get-VisualStudio-Path + $vsPath | Should -Not -BeNullOrEmpty + } + + It "Get-VisualStudio-Path [2015]" { + # see first if VS 2015 is installed + [Microsoft.Win32.RegistryKey] $vs14Key = Get-Item "HKLM:SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0" + [bool] $vs2015isInstalled = $vs14Key -and ![string]::IsNullOrEmpty($vs14Key.GetValue("InstallDir")) + + $oldMockValue = $global:cptVisualStudioVersion + + $vsPath = Get-VisualStudio-Path + $vsPath | Should -Not -BeNullOrEmpty + + # Re-Mock script parameter + $global:cptVisualStudioVersion = "2015" + + # Maybe we have a VS 2017 installation with v140 toolset installed + [string] $vs2017ToolsetV140Path = "${Env:ProgramFiles(x86)}\Microsoft Visual Studio 14.0" + if (Test-Path "$vs2017ToolsetV140Path\VC\include\iostream") + { + $vs2015isInstalled = $true + } + + if ($vs2015isInstalled) + { + $vs2015Path = Get-VisualStudio-Path + $vs2015Path | Should -Not -BeNullOrEmpty + $vs2015Path | Should -Not -Be $vsPath + } + else + { + { Get-VisualStudio-Path } | Should -Throw + } + + $global:cptVisualStudioVersion = $oldMockValue + } + + It "Get-VisualStudio-Includes" { + [string] $vsPath = Get-VisualStudio-Path + [string] $mscver = Get-MscVer + [string[]] $includes = Get-VisualStudio-Includes -vsPath $vsPath -mscVer $mscver + $includes.Count | Should -BeGreaterThan 1 + $includes | ForEach-Object { [System.IO.Directory]::Exists($_) | Should -BeExactly $true } + } +} diff --git a/scripts/psClang/~advinst.tests.ps1 b/scripts/psClang/~advinst.tests.ps1 new file mode 100644 index 0000000000..ebbd16a6cd --- /dev/null +++ b/scripts/psClang/~advinst.tests.ps1 @@ -0,0 +1,20 @@ +. "$PsScriptRoot\io.ps1" +Describe "ai" { + It "Should build Advanced Installer" { + + [string] $advinstRepo = $env:ADVINST + + if ($advinstRepo) + { + Push-Location $advinstRepo + + [string] $scriptLocation = Canonize-Path -base "$PSScriptRoot" -child "..\clang-build.ps1" + &"$scriptLocation" 2>&1 | Out-Default + [int] $exitCode = $LASTEXITCODE + Pop-Location + + Write-Output "$PSScriptRoot" + $exitCode | Should -BeExactly 0 + } + } +} \ No newline at end of file diff --git a/scripts/sample-clang-build.ps1 b/scripts/sample-clang-build.ps1 deleted file mode 100644 index 577deff5c5..0000000000 --- a/scripts/sample-clang-build.ps1 +++ /dev/null @@ -1,225 +0,0 @@ -<# -.SYNOPSIS - Compiles or tidies up code from Visual Studio .vcxproj project files. - It sets up the scene required for clang-build.ps1 to do its job, and makes - command-line usage for projects and files quicker. - - Before calling sample-clang-build.ps1 you need to set the current directory - to the root source directory. - -.PARAMETER aVcxprojToCompile - Alias 'proj'. Array of project(s) to compile. If empty, all projects are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, - e.g. "msicomp" compiles all msicomp projects. - - Can be passed as comma separated values. - -.PARAMETER aVcxprojToIgnore - Alias 'proj-ignore'. Array of project(s) to ignore, from the matched ones. - If empty, all already matched projects are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, - e.g. "msicomp" compiles all msicomp projects. - - Can be passed as comma separated values. - -.PARAMETER aVcxprojConfigPlatform - Alias 'active-config'. The configuration-platform pair, separated by |, - to be used when processing project files. - - E.g. 'Debug|Win32'. - If not specified, the first configuration-plaform found in the current project is used. - -.PARAMETER aCppToCompile - Alias 'file'. What cpp(s) to compile from the found project(s). If empty, all CPPs are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, - e.g. "table" compiles all CPPs containing 'table'. - -.PARAMETER aCppToIgnore - Alias 'file-ignore'. Array of file(s) to ignore, from the matched ones. - If empty, all already matched files are compiled. - If the -literal switch is present, name is matched exactly. Otherwise, regex matching is used, - e.g. "table" ignores all CPPs containing 'table'. - - Can be passed as comma separated values. - -.PARAMETER aUseParallelCompile - Alias 'parallel'. Switch to run in parallel mode, on all logical CPU cores. - -.PARAMETER aContinueOnError - Alias 'continue'. Switch to continue project compilation even when errors occur. - -.PARAMETER aTreatAdditionalIncludesAsSystemIncludes - Alias 'treat-sai'. Switch to treat project additional include directories as system includes. - -.PARAMETER aClangCompileFlags - Alias 'clang-flags'. Flags given to clang++ when compiling project, - alongside project-specific defines. - -.PARAMETER aDisableNameRegexMatching - Alias 'literal'. Switch to take project and cpp name filters literally, not by regex matching. - -.PARAMETER aTidyFlags - Alias 'tidy'. If not empty clang-tidy will be called with given flags, instead of clang++. - The tidy operation is applied to whole translation units, meaning all directory headers - included in the CPP will be tidied up too. Changes will not be applied, only simulated. - - If aTidyFixFlags is present, it takes precedence over this parameter. - -.PARAMETER aTidyFixFlags - Alias 'tidy-fix'. If not empty clang-tidy will be called with given flags, instead of clang++. - The tidy operation is applied to whole translation units, meaning all directory headers - included in the CPP will be tidied up too. Changes will be applied to the file(s). - - If present, this parameter takes precedence over aTidyFlags. - -.PARAMETER aAfterTidyFixFormatStyle - Alias 'format-style'. Used in combination with 'tidy-fix'. If present, clang-tidy will - also format the fixed file(s), using the specified style. - Possible values: - not present, no formatting will be done - - 'file' - Literally 'file', not a placeholder. - Uses .clang-format file in the closest parent directory. - - 'llvm' - - 'google' - - 'webkit' - - 'mozilla' - -.EXAMPLE - PS .\sample-clang-build.ps1 -dir -proj foo,bar -file meow -tidy "-*,modernize-*" - - Runs clang-tidy, using "-*,modernize-*", on all CPPs containing 'meow' in their name from - the projects containing 'foo' or 'bar' in their names. - - Doesn't actually apply the clang-tidy module changes to CPPs. - It will only print the tidy module output. - -.EXAMPLE - PS .\sample-clang-build.ps1 -dir -proj foo,bar -file meow -tidy-fix "-*,modernize-*" - - Runs clang-tidy, using "-*,modernize-*", on all CPPs containing 'meow' in their name from - the projects containing 'foo' or 'bar' in their names. - - It will apply all tidy module changes to CPPs. - -.EXAMPLE - PS .\sample-clang-build.ps1 -dir -proj foo -proj-ignore foobar - - Runs clang++ on all CPPs in foo... projects, except foobar - -.OUTPUTS - Will output Clang warnings and errors to screen. The return code will be 0 for success, >0 for failure. - -.NOTES - Author: Gabriel Diaconita -#> -param( [alias("proj")] [Parameter(Mandatory=$false)][string[]] $aVcxprojToCompile - , [alias("proj-ignore")] [Parameter(Mandatory=$false)][string[]] $aVcxprojToIgnore - , [alias("active-config")][Parameter(Mandatory=$false)][string] $aVcxprojConfigPlatform - , [alias("file")] [Parameter(Mandatory=$false)][string] $aCppToCompile - , [alias("file-ignore")] [Parameter(Mandatory=$false)][string[]] $aCppToIgnore - , [alias("parallel")] [Parameter(Mandatory=$false)][switch] $aUseParallelCompile - , [alias("continue")] [Parameter(Mandatory=$false)][switch] $aContinueOnError - , [alias("treat-sai")] [Parameter(Mandatory=$false)][switch] $aTreatAdditionalIncludesAsSystemIncludes - , [alias("literal")] [Parameter(Mandatory=$false)][switch] $aDisableNameRegexMatching - , [alias("tidy")] [Parameter(Mandatory=$false)][string] $aTidyFlags - , [alias("tidy-fix")] [Parameter(Mandatory=$false)][string] $aTidyFixFlags - , [alias("format-style")] [Parameter(Mandatory=$false)][string] $aAfterTidyFixFormatStyle - ) - -# ------------------------------------------------------------------------------------------------ - -Set-Variable -name kClangCompileFlags -Option Constant ` - -value @( "-Werror" - , "-Wall" - , "-fms-compatibility-version=19.10" - , "-Wmicrosoft" - , "-Wno-invalid-token-paste" - , "-Wno-unknown-pragmas" - , "-Wno-unused-value" - ) - -Set-Variable -name kVisualStudioVersion -value "2017" -Option Constant -Set-Variable -name kVisualStudioSku -value "Professional" -Option Constant - -# ------------------------------------------------------------------------------------------------ - -Function Merge-Array([string[]] $aArray) -{ - # we need to individually wrap items into quotes as values - # can contain PS control characters (e.g. - in -std=c++14) - $quotedArray = ($aArray | ForEach-Object { """$_"""}) - return ($quotedArray -join ",") -} - -[string] $scriptDirectory = (Split-Path -parent $PSCommandPath) - -[string] $clangScript = "$scriptDirectory\clang-build.ps1" -[string[]] $scriptParams = @("-aSolutionsPath", "'$(Get-Location)'") - -if (![string]::IsNullOrEmpty($aVcxprojToCompile)) -{ - $scriptParams += ("-aVcxprojToCompile", (Merge-Array $aVcxprojToCompile)) -} - -if (![string]::IsNullOrEmpty($aVcxprojToIgnore)) -{ - $scriptParams += ("-aVcxprojToIgnore", (Merge-Array $aVcxprojToIgnore)) -} - -if (![string]::IsNullOrEmpty($aVcxprojConfigPlatform)) -{ - $scriptParams += ("-aVcxprojConfigPlatform", (Merge-Array $aVcxprojConfigPlatform)) -} - -if (![string]::IsNullOrEmpty($aCppToCompile)) -{ - $scriptParams += ("-aCppToCompile", (Merge-Array $aCppToCompile)) -} - -if (![string]::IsNullOrEmpty($aCppToIgnore)) -{ - $scriptParams += ("-aCppToIgnore", (Merge-Array $aCppToIgnore)) -} - -$scriptParams += ("-aClangCompileFlags", (Merge-Array $kClangCompileFlags)) - -if (![string]::IsNullOrEmpty($aTidyFlags)) -{ - $scriptParams += ("-aTidyFlags", (Merge-Array (@($aTidyFlags)))) -} - -if (![string]::IsNullOrEmpty($aTidyFixFlags)) -{ - $scriptParams += ("-aTidyFixFlags", (Merge-Array (@($aTidyFixFlags)))) -} - -if (![string]::IsNullOrEmpty($aAfterTidyFixFormatStyle)) -{ - $scriptParams += ("-aAfterTidyFixFormatStyle", $aAfterTidyFixFormatStyle) -} - -if ($aUseParallelCompile) -{ - $scriptParams += ("-aUseParallelCompile") -} - -if ($aContinueOnError) -{ - $scriptParams += ("-aContinueOnError") -} - -if ($aTreatAdditionalIncludesAsSystemIncludes) -{ - $scriptParams += ("-aTreatAdditionalIncludesAsSystemIncludes") -} - -if ($aDisableNameRegexMatching) -{ - $scriptParams += ("-aDisableNameRegexMatching") -} - -$scriptParams += ("-aVisualStudioVersion", $kVisualStudioVersion) -$scriptParams += ("-aVisualStudioSku", $kVisualStudioSku) -$scriptParams += ("-aTidyHeaderFilter", ".*") - -Invoke-Expression "&'$clangScript' $scriptParams"