ResSimpy 2.5.2__tar.gz → 2.5.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. {ressimpy-2.5.2 → ressimpy-2.5.3}/PKG-INFO +1 -1
  2. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/FileOperations/file_operations.py +17 -9
  3. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusProc.py +33 -23
  4. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusProcs.py +9 -0
  5. ressimpy-2.5.3/ResSimpy/Nexus/DataModels/Network/NexusStreamTracer.py +89 -0
  6. ressimpy-2.5.3/ResSimpy/Nexus/DataModels/Network/NexusStreamTracers.py +73 -0
  7. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusWellLists.py +1 -1
  8. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/StructuredGrid/NexusGrid.py +25 -24
  9. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusNetwork.py +38 -12
  10. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/nexus_collect_tables.py +1 -1
  11. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/nexus_constraint_operations.py +1 -1
  12. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/nexus_file_operations.py +1 -1
  13. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/nexus_model_file_generator.py +15 -3
  14. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Time/ISODateTime.py +3 -0
  15. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/__init__.py +1 -1
  16. {ressimpy-2.5.2 → ressimpy-2.5.3}/pyproject.toml +3 -3
  17. {ressimpy-2.5.2 → ressimpy-2.5.3}/LICENSE.MD +0 -0
  18. {ressimpy-2.5.2 → ressimpy-2.5.3}/README.md +0 -0
  19. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Aquifer.py +0 -0
  20. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Completion.py +0 -0
  21. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Constraint.py +0 -0
  22. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/DataObjectMixin.py +0 -0
  23. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Drill.py +0 -0
  24. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/DrillSite.py +0 -0
  25. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/DynamicProperty.py +0 -0
  26. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/DynamicPropertyContainer.py +0 -0
  27. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Equilibration.py +0 -0
  28. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Ftrans.py +0 -0
  29. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Gaslift.py +0 -0
  30. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Grid.py +0 -0
  31. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/GridArrayDefinition.py +0 -0
  32. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/GridArrayFunction.py +0 -0
  33. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/GuideRate.py +0 -0
  34. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/LGR.py +0 -0
  35. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Multir.py +0 -0
  36. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Network.py +0 -0
  37. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/NetworkList.py +0 -0
  38. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/NetworkObject.py +0 -0
  39. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Node.py +0 -0
  40. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/NodeConnection.py +0 -0
  41. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/OperationsMixin.py +0 -0
  42. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Over.py +0 -0
  43. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/PVT.py +0 -0
  44. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/RelPerm.py +0 -0
  45. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/RelPermEndPoint.py +0 -0
  46. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Reporting.py +0 -0
  47. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Rock.py +0 -0
  48. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Separator.py +0 -0
  49. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Simulator.py +0 -0
  50. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/SolverParameter.py +0 -0
  51. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Target.py +0 -0
  52. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Valve.py +0 -0
  53. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Water.py +0 -0
  54. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Well.py +0 -0
  55. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/WellConnection.py +0 -0
  56. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Wellbore.py +0 -0
  57. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/Wellhead.py +0 -0
  58. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/__init__.py +0 -0
  59. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/DataModelBaseClasses/output_request.py +0 -0
  60. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Enums/FluidTypeEnums.py +0 -0
  61. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Enums/FrequencyEnum.py +0 -0
  62. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Enums/GridFunctionTypes.py +0 -0
  63. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Enums/HowEnum.py +0 -0
  64. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Enums/OutputType.py +0 -0
  65. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Enums/PenetrationDirectionEnum.py +0 -0
  66. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Enums/TimeSteppingMethodEnum.py +0 -0
  67. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Enums/UnitsEnum.py +0 -0
  68. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Enums/WellTypeEnum.py +0 -0
  69. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Enums/__init__.py +0 -0
  70. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/FileOperations/File.py +0 -0
  71. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/FileOperations/FileBase.py +0 -0
  72. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/FileOperations/__init__.py +0 -0
  73. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/FileOperations/simulator_constants.py +0 -0
  74. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/Constraints.py +0 -0
  75. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/DrillSites.py +0 -0
  76. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/Drills.py +0 -0
  77. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/Grids.py +0 -0
  78. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/GuideRates.py +0 -0
  79. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/Hydraulics.py +0 -0
  80. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/LGRs.py +0 -0
  81. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/NetworkLists.py +0 -0
  82. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/NodeConnections.py +0 -0
  83. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/Nodes.py +0 -0
  84. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/SolverParameters.py +0 -0
  85. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/Targets.py +0 -0
  86. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/WellConnections.py +0 -0
  87. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/Wellbores.py +0 -0
  88. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/Wellheads.py +0 -0
  89. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/Wells.py +0 -0
  90. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/GenericContainerClasses/__init__.py +0 -0
  91. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/FcsConfig.py +0 -0
  92. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/FcsFile.py +0 -0
  93. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusAction.py +0 -0
  94. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusActions.py +0 -0
  95. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusActivationChange.py +0 -0
  96. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusActivationChanges.py +0 -0
  97. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusConList.py +0 -0
  98. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusConLists.py +0 -0
  99. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusConstraint.py +0 -0
  100. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusConstraints.py +0 -0
  101. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusDrill.py +0 -0
  102. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusDrillSite.py +0 -0
  103. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusDrillSites.py +0 -0
  104. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusDrills.py +0 -0
  105. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusGuideRate.py +0 -0
  106. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusGuideRates.py +0 -0
  107. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusNode.py +0 -0
  108. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusNodeConnection.py +0 -0
  109. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusNodeConnections.py +0 -0
  110. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusNodeList.py +0 -0
  111. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusNodeLists.py +0 -0
  112. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusNodes.py +0 -0
  113. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusStation.py +0 -0
  114. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusStations.py +0 -0
  115. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusTarget.py +0 -0
  116. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusTargets.py +0 -0
  117. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusWellConnection.py +0 -0
  118. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusWellConnections.py +0 -0
  119. {ressimpy-2.5.2/ResSimpy/Nexus/DataModels → ressimpy-2.5.3/ResSimpy/Nexus/DataModels/Network}/NexusWellList.py +0 -0
  120. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusWellbore.py +0 -0
  121. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusWellbores.py +0 -0
  122. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusWellhead.py +0 -0
  123. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/NexusWellheads.py +0 -0
  124. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/Network/__init__.py +0 -0
  125. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusAquiferMethod.py +0 -0
  126. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusCompletion.py +0 -0
  127. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusEquilMethod.py +0 -0
  128. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusFile.py +0 -0
  129. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusGasliftMethod.py +0 -0
  130. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusHydraulicsMethod.py +0 -0
  131. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusIPRMethod.py +0 -0
  132. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusOptions.py +0 -0
  133. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusPVTMethod.py +0 -0
  134. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusRelPermEndPoint.py +0 -0
  135. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusRelPermMethod.py +0 -0
  136. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusReportingRequests.py +0 -0
  137. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusRockMethod.py +0 -0
  138. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusSeparatorMethod.py +0 -0
  139. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusSolverParameter.py +0 -0
  140. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusValveMethod.py +0 -0
  141. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusWaterMethod.py +0 -0
  142. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusWell.py +0 -0
  143. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/NexusWellMod.py +0 -0
  144. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/StructuredGrid/NexusFtrans.py +0 -0
  145. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/StructuredGrid/NexusGridArrayFunction.py +0 -0
  146. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/StructuredGrid/NexusLGR.py +0 -0
  147. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/StructuredGrid/NexusLGRs.py +0 -0
  148. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/StructuredGrid/NexusMultir.py +0 -0
  149. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/StructuredGrid/NexusOver.py +0 -0
  150. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/StructuredGrid/NexusTOver.py +0 -0
  151. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/StructuredGrid/__init__.py +0 -0
  152. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/__init__.py +0 -0
  153. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/DataModels/nexus_grid_to_proc.py +0 -0
  154. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusAquiferMethods.py +0 -0
  155. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusEnums/ActivationChangeEnum.py +0 -0
  156. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusEnums/DateFormatEnum.py +0 -0
  157. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusEnums/__init__.py +0 -0
  158. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusEquilMethods.py +0 -0
  159. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusGasliftMethods.py +0 -0
  160. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusGrids.py +0 -0
  161. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusHydraulicsMethods.py +0 -0
  162. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusIPRMethods.py +0 -0
  163. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/__init__.py +0 -0
  164. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/adsorption_keywords.py +0 -0
  165. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/alphaf_keywords.py +0 -0
  166. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/aquifer_keywords.py +0 -0
  167. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/choke_keywords.py +0 -0
  168. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/compressor_keywords.py +0 -0
  169. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/eos_defaults_keywords.py +0 -0
  170. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/equil_keywords.py +0 -0
  171. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/esp_keywords.py +0 -0
  172. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/fcs_keywords.py +0 -0
  173. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/fluxin_keywords.py +0 -0
  174. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/gaslift_keywords.py +0 -0
  175. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/hyd_keywords.py +0 -0
  176. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/icd_keywords.py +0 -0
  177. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/ipr_keywords.py +0 -0
  178. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/nexus_keywords.py +0 -0
  179. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/options_keywords.py +0 -0
  180. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/polymer_keywords.py +0 -0
  181. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/proc_keywords.py +0 -0
  182. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/pump_keywords.py +0 -0
  183. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/pvt_keywords.py +0 -0
  184. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/relpm_keywords.py +0 -0
  185. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/rock_keywords.py +0 -0
  186. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/runcontrol_keywords.py +0 -0
  187. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/separator_keywords.py +0 -0
  188. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/structured_grid_keywords.py +0 -0
  189. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/surface_keywords.py +0 -0
  190. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/tracer_init_keywords.py +0 -0
  191. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/valve_keywords.py +0 -0
  192. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/water_keywords.py +0 -0
  193. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusKeywords/wells_keywords.py +0 -0
  194. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusPVTMethods.py +0 -0
  195. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusRelPermMethods.py +0 -0
  196. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusReporting.py +0 -0
  197. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusRockMethods.py +0 -0
  198. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusSeparatorMethods.py +0 -0
  199. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusSimulator.py +0 -0
  200. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusSolverParameters.py +0 -0
  201. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusValveMethods.py +0 -0
  202. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusWaterMethods.py +0 -0
  203. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/NexusWells.py +0 -0
  204. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/__init__.py +0 -0
  205. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/array_function_operations.py +0 -0
  206. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/constants.py +0 -0
  207. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/load_wells.py +0 -0
  208. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/logfile_operations.py +0 -0
  209. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/nexus_add_new_object_to_file.py +0 -0
  210. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/nexus_load_faults.py +0 -0
  211. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/nexus_load_list_table.py +0 -0
  212. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/nexus_modify_object_in_file.py +0 -0
  213. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/nexus_remove_object_from_file.py +0 -0
  214. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/rel_perm_operations.py +0 -0
  215. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/runcontrol_operations.py +0 -0
  216. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Nexus/structured_grid_operations.py +0 -0
  217. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/DataModels/Network/__init__.py +0 -0
  218. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/DataModels/OpenGoSimCompletion.py +0 -0
  219. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/DataModels/OpenGoSimWell.py +0 -0
  220. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/DataModels/__init__.py +0 -0
  221. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/Enums/SimulationTypeEnum.py +0 -0
  222. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/Enums/__init__.py +0 -0
  223. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/Model_Parts/OpenGoSimNetwork.py +0 -0
  224. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/Model_Parts/__init__.py +0 -0
  225. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/OpenGoSimKeywords/OpenGoSimKeywords.py +0 -0
  226. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/OpenGoSimKeywords/__init__.py +0 -0
  227. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/OpenGoSimSimulator.py +0 -0
  228. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/OpenGoSimWells.py +0 -0
  229. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/OpenGoSim/__init__.py +0 -0
  230. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Time/__init__.py +0 -0
  231. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Units/AttributeMapping.py +0 -0
  232. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Units/AttributeMappings/BaseUnitMapping.py +0 -0
  233. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Units/AttributeMappings/CompletionUnitMapping.py +0 -0
  234. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Units/AttributeMappings/ConstraintUnitMapping.py +0 -0
  235. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Units/AttributeMappings/DynamicPropertyUnitMapping.py +0 -0
  236. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Units/AttributeMappings/NetworkUnitMapping.py +0 -0
  237. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Units/AttributeMappings/__init__.py +0 -0
  238. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Units/Units.py +0 -0
  239. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Units/__init__.py +0 -0
  240. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Utils/__init__.py +0 -0
  241. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Utils/dynamic_method_manipulations.py +0 -0
  242. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Utils/factory_methods.py +0 -0
  243. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Utils/general_utilities.py +0 -0
  244. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Utils/generic_repr.py +0 -0
  245. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Utils/grid_filtering_functions.py +0 -0
  246. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Utils/invert_nexus_map.py +0 -0
  247. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Utils/obj_to_dataframe.py +0 -0
  248. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Utils/obj_to_table_string.py +0 -0
  249. {ressimpy-2.5.2 → ressimpy-2.5.3}/ResSimpy/Utils/to_dict_generic.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ResSimpy
3
- Version: 2.5.2
3
+ Version: 2.5.3
4
4
  Summary: A Python library for working with Reservoir Simulator Models.
5
5
  License: Apache-2.0
6
6
  License-File: LICENSE.MD
@@ -726,17 +726,19 @@ def split_lines_for_long_string(long_string: str, max_length: int, comment_chara
726
726
  return compiled_string
727
727
 
728
728
 
729
- def split_list_of_strings_by_length(list_of_strings: list[str], max_length: int) -> list[str]:
729
+ def split_list_of_strings_by_length(list_of_strings: list[str], max_length: int,
730
+ comment_characters: None | list[str] = None) -> list[str]:
730
731
  """Splits a list of strings into a new list of strings with a maximum length.
731
732
 
732
733
  Args:
733
734
  list_of_strings (list[str]): The list of strings to be split.
734
735
  max_length (int): The maximum length of each string in the new list.
736
+ comment_characters (Optional[list[str]]): The comment characters to filter out. Defaults to None
735
737
 
736
738
  Returns:
737
739
  list[str]: A new list of strings split from the original list.
738
740
  """
739
- return [split_lines_for_long_string(string, max_length) for string in list_of_strings]
741
+ return [split_lines_for_long_string(string, max_length, comment_characters) for string in list_of_strings]
740
742
 
741
743
 
742
744
  def get_full_file_path(file_path: str, origin: str, rootdir: Optional[str] = None, is_nexus: bool = True) -> str:
@@ -804,14 +806,20 @@ def split_file_as_list_by_date(file_as_list: list[str], date_token: str = 'TIME'
804
806
  of that token.
805
807
  """
806
808
  split_file: dict[str, list[str]] = {}
807
- current_token_value = None
809
+ date_token_value = None
810
+ no_token_dict_key = f'BEFORE_FIRST_{date_token}'
811
+
808
812
  for i, line in enumerate(file_as_list):
809
813
  if check_token(date_token, line, comment_characters=comment_characters):
810
814
  # TODO handle 3 part dates in this bit
811
- current_token_value = get_expected_token_value(token=date_token, token_line=line,
812
- file_list=file_as_list[i:],
813
- comment_characters=comment_characters)
814
- split_file[current_token_value] = [line]
815
- elif current_token_value is not None:
816
- split_file[current_token_value].append(line)
815
+ date_token_value = get_expected_token_value(token=date_token, token_line=line,
816
+ file_list=file_as_list[i:],
817
+ comment_characters=comment_characters)
818
+ split_file[date_token_value] = [line]
819
+ elif date_token_value is None:
820
+ if no_token_dict_key not in split_file:
821
+ split_file[no_token_dict_key] = []
822
+ split_file[no_token_dict_key].append(line)
823
+ elif date_token_value is not None:
824
+ split_file[date_token_value].append(line)
817
825
  return split_file
@@ -1,6 +1,11 @@
1
1
  from dataclasses import dataclass
2
- from typing import Optional, Mapping
2
+ from typing import Optional
3
+
4
+ from ResSimpy.DataModelBaseClasses.NetworkObject import NetworkObject
5
+ from ResSimpy.Enums.UnitsEnum import UnitSystem
6
+ from ResSimpy.Nexus.NexusEnums.DateFormatEnum import DateFormat
3
7
  from ResSimpy.Nexus.NexusKeywords.proc_keywords import PREDEFINED_VARS, CONDITIONAL_KEYWORDS, NEXUS_ALL_PROC_FUNCS
8
+ from ResSimpy.Units.AttributeMappings.BaseUnitMapping import BaseUnitMapping
4
9
 
5
10
 
6
11
  # set custom error message
@@ -9,18 +14,15 @@ class SetError(Exception):
9
14
 
10
15
 
11
16
  @dataclass(kw_only=True, repr=True)
12
- class NexusProc:
17
+ class NexusProc(NetworkObject):
13
18
  """Class that represents a single nexus procedure."""
14
- __date: Optional[str]
15
- __name: Optional[str]
16
19
  __priority: Optional[int]
17
20
  __contents: Optional[list[str]]
18
21
  __contents_breakdown: dict[str, int]
19
22
 
20
- def __init__(self, date: Optional[str] = None,
21
- contents: Optional[list[str]] = None,
22
- name: Optional[str] = None,
23
- priority: Optional[int] = None) -> None:
23
+ def __init__(self, date: Optional[str] = None, contents: Optional[list[str]] = None,
24
+ name: Optional[str] = None, priority: Optional[int] = None, unit_system: Optional[UnitSystem] = None,
25
+ start_date: Optional[str] = None, date_format: Optional[DateFormat] = None) -> None:
24
26
  """Initialize the attributes of the class.
25
27
 
26
28
  Attributes:
@@ -33,33 +35,23 @@ class NexusProc:
33
35
  Methods:
34
36
  reset_nexus_proc_function_counts(): Returns a dictionary of zero counts for the nexus proc functions.
35
37
  """
36
-
37
- self.__date = date
38
- self.__name = name
39
38
  self.__priority = priority
40
39
  self.__contents = contents
40
+
41
41
  self.__contents_breakdown = self.reset_nexus_proc_function_counts()
42
+ super().__init__(properties_dict={}, date=date, date_format=date_format, start_date=start_date,
43
+ unit_system=unit_system, name=name)
42
44
 
43
45
  @property
44
46
  def contents(self) -> Optional[list[str]]:
45
47
  """Returns the contents of the main body of the procedure."""
46
48
  return self.__contents
47
49
 
48
- @property
49
- def date(self) -> Optional[str]:
50
- """Returns the date that the procedure occurred."""
51
- return self.__date
52
-
53
50
  @property
54
51
  def priority(self) -> Optional[int]:
55
52
  """Returns the priority of the procedure."""
56
53
  return self.__priority
57
54
 
58
- @property
59
- def name(self) -> Optional[str]:
60
- """Returns the name of the procedure."""
61
- return self.__name
62
-
63
55
  @property
64
56
  def contents_breakdown(self) -> dict[str, int]:
65
57
  """Returns the dictionary counts of the proc functions."""
@@ -76,9 +68,9 @@ class NexusProc:
76
68
  'Nexus Keyword Manual page 1013.')
77
69
 
78
70
  @staticmethod
79
- def get_keyword_mapping() -> Mapping[str, tuple[str, type]]:
71
+ def get_keyword_mapping() -> dict[str, tuple[str, type]]:
80
72
  """Gets the mapping of nexus keywords to attribute definitions."""
81
- keywords = {
73
+ keywords: dict[str, tuple[str, type]] = {
82
74
  'NAME': ('name', str),
83
75
  'PRIORITY': ('priority', str)
84
76
  }
@@ -99,3 +91,21 @@ class NexusProc:
99
91
  to_search = predef_vars | cond | all_proc_funcs
100
92
 
101
93
  return to_search
94
+
95
+ def to_string(self) -> str:
96
+ """Outputs the procedure as a string in the format it would be written in a Nexus file."""
97
+ output_str = "PROCS"
98
+ if self.name is not None:
99
+ output_str += f" NAME {self.name}"
100
+ if self.priority is not None:
101
+ output_str += f" PRIORITY {self.priority}"
102
+ output_str += '\n'
103
+ if self.contents is not None:
104
+ output_str += '\n'.join(self.contents) + '\n'
105
+ output_str += "ENDPROCS\n"
106
+ return output_str
107
+
108
+ @property
109
+ def units(self) -> BaseUnitMapping:
110
+ """Returns the attribute to unit map for the data object."""
111
+ return BaseUnitMapping(None)
@@ -4,6 +4,7 @@ from dataclasses import dataclass, field
4
4
  from typing import Sequence, TYPE_CHECKING
5
5
 
6
6
  from ResSimpy.Nexus.DataModels.Network.NexusProc import NexusProc
7
+ from ResSimpy.Time.ISODateTime import ISODateTime
7
8
 
8
9
  if TYPE_CHECKING:
9
10
  from ResSimpy.Nexus.NexusNetwork import NexusNetwork
@@ -35,3 +36,11 @@ class NexusProcs:
35
36
  def _add_to_memory(self, procs_to_add: list[NexusProc]) -> None:
36
37
  """Adds the list of Nexus procedure objects to memory."""
37
38
  self.__procs.extend(procs_to_add)
39
+
40
+ def to_string_for_date(self, date: ISODateTime) -> str:
41
+ """Outputs the procedures for a specific date."""
42
+ output_str = ''
43
+ procs_for_date = [x for x in self.__procs if x.iso_date == date]
44
+ for proc in procs_for_date:
45
+ output_str += proc.to_string()
46
+ return output_str
@@ -0,0 +1,89 @@
1
+ """Class representing a single Nexus STREAM_TRACER entry."""
2
+
3
+ from __future__ import annotations
4
+ from dataclasses import dataclass
5
+
6
+ from ResSimpy.DataModelBaseClasses.DataObjectMixin import DataObjectMixinDictType
7
+ from ResSimpy.Enums.UnitsEnum import UnitSystem
8
+ from ResSimpy.Nexus.NexusEnums.DateFormatEnum import DateFormat
9
+ from ResSimpy.DataModelBaseClasses.NetworkObject import NetworkObject
10
+ from ResSimpy.Units.AttributeMappings.BaseUnitMapping import BaseUnitMapping
11
+
12
+
13
+ @dataclass(kw_only=True, repr=False)
14
+ class NexusStreamTracer(NetworkObject):
15
+ """Represents a single row in a Nexus STREAM_TRACER table.
16
+
17
+ A STREAM_TRACER block associates named streams with a fluid component and
18
+ an optional tracer name and concentration, e.g.::
19
+
20
+ STREAM_TRACER
21
+ NAME COMPONENT TRACER CONCENTRATION
22
+ SEAWTR WATER SALT 1.0
23
+ TRTWTR WATER SALT 1.0
24
+ ENDSTREAM_TRACER
25
+
26
+ Attributes:
27
+ name (str): The stream name (NAME column). Used in WELLS tables as the STREAM value.
28
+ component (str): The fluid component associated with this stream (COMPONENT column),
29
+ e.g. ``'WATER'``, ``'GAS'``, ``'OIL'``.
30
+ tracer (Optional[str]): The tracer label (TRACER column). Defaults to None.
31
+ concentration (Optional[float]): Tracer concentration (CONCENTRATION column). Defaults to None.
32
+ """
33
+
34
+ component: str | None = None
35
+ tracer: str | None = None
36
+ concentration: float | None = None
37
+
38
+ def __init__(
39
+ self,
40
+ properties_dict: DataObjectMixinDictType | None = None,
41
+ date: str | None = None,
42
+ date_format: DateFormat | None = None,
43
+ start_date: str | None = None,
44
+ unit_system: UnitSystem | None = None,
45
+ name: str | None = None,
46
+ component: str | None = None,
47
+ tracer: str | None = None,
48
+ concentration: float | None = None,
49
+ ) -> None:
50
+ """Initialises the NexusStreamTracer class.
51
+
52
+ Args:
53
+ properties_dict (Optional[dict]): dict of the properties to set on the object.
54
+ date (Optional[str]): The date of the object.
55
+ date_format (Optional[DateFormat]): The date format that the object uses.
56
+ start_date (Optional[str]): The start date of the model.
57
+ unit_system (Optional[UnitSystem]): The unit system of the object e.g. ENGLISH, METRIC.
58
+ name (Optional[str]): The stream name (NAME column).
59
+ component (Optional[str]): Fluid component, e.g. ``'WATER'``, ``'GAS'``, ``'OIL'``.
60
+ tracer (Optional[str]): Tracer label (TRACER column).
61
+ concentration (Optional[float]): Tracer concentration (CONCENTRATION column).
62
+ """
63
+ self.component = component
64
+ self.tracer = tracer
65
+ self.concentration = concentration
66
+
67
+ super().__init__(
68
+ properties_dict=properties_dict,
69
+ date=date,
70
+ date_format=date_format,
71
+ start_date=start_date,
72
+ unit_system=unit_system,
73
+ name=name,
74
+ )
75
+
76
+ @staticmethod
77
+ def get_keyword_mapping() -> dict[str, tuple[str, type]]:
78
+ """Gets the mapping of Nexus STREAM_TRACER column headers to attribute definitions."""
79
+ return {
80
+ 'NAME': ('name', str),
81
+ 'COMPONENT': ('component', str),
82
+ 'TRACER': ('tracer', str),
83
+ 'CONCENTRATION': ('concentration', float),
84
+ }
85
+
86
+ @property
87
+ def units(self) -> BaseUnitMapping:
88
+ """Returns the attribute-to-unit map for this data object."""
89
+ return BaseUnitMapping(unit_system=self.unit_system)
@@ -0,0 +1,73 @@
1
+ """Container class for Nexus STREAM_TRACER entries."""
2
+
3
+ from __future__ import annotations
4
+ from dataclasses import dataclass, field
5
+ from typing import Sequence, TYPE_CHECKING
6
+
7
+ from ResSimpy.Nexus.DataModels.Network.NexusStreamTracer import NexusStreamTracer
8
+
9
+ if TYPE_CHECKING:
10
+ from ResSimpy.Nexus.NexusNetwork import NexusNetwork
11
+
12
+
13
+ @dataclass(kw_only=True)
14
+ class NexusStreamTracers:
15
+ """Container for all :class:`NexusStreamTracer` objects parsed from STREAM_TRACER blocks.
16
+
17
+ Also exposes a :py:attr:`component_map` property that returns a ``dict[str, str]``
18
+ mapping each stream name (uppercased) to its declared COMPONENT, which is used by
19
+ :class:`~ResSimpy.Nexus.NexusNetwork.NexusNetwork` to classify well types.
20
+ """
21
+
22
+ __stream_tracers: list[NexusStreamTracer] = field(default_factory=list)
23
+
24
+ def __init__(self, parent_network: NexusNetwork) -> None:
25
+ """Initialises the NexusStreamTracers class.
26
+
27
+ Args:
28
+ parent_network (NexusNetwork): The network that these stream tracers belong to.
29
+ """
30
+ self.__parent_network: NexusNetwork = parent_network
31
+ self.__stream_tracers: list[NexusStreamTracer] = []
32
+
33
+ def get_all(self) -> Sequence[NexusStreamTracer]:
34
+ """Returns all loaded :class:`NexusStreamTracer` objects."""
35
+ self.__parent_network.get_load_status()
36
+ return self.__stream_tracers
37
+
38
+ def get_by_name(self, name: str) -> NexusStreamTracer | None:
39
+ """Returns the first :class:`NexusStreamTracer` whose stream name matches *name* (case-insensitive).
40
+
41
+ Args:
42
+ name (str): Stream name to look up.
43
+
44
+ Returns:
45
+ NexusStreamTracer | None: Matching object, or ``None`` if not found.
46
+ """
47
+ self.__parent_network.get_load_status()
48
+ name_upper = name.upper()
49
+ for st in self.__stream_tracers:
50
+ if st.name is not None and st.name.upper() == name_upper:
51
+ return st
52
+ return None
53
+
54
+ @property
55
+ def component_map(self) -> dict[str, str]:
56
+ """Returns a ``dict`` mapping stream name → component (both uppercased).
57
+
58
+ Example::
59
+
60
+ {'SEAWTR': 'WATER', 'TRTWTR': 'WATER', 'GASSTREAM': 'GAS'}
61
+ """
62
+ self.__parent_network.get_load_status()
63
+ return {
64
+ st.name.upper(): st.component.upper()
65
+ for st in self.__stream_tracers
66
+ if st.name is not None and st.component is not None
67
+ }
68
+
69
+ def _add_to_memory(self, stream_tracers_to_add: list[NexusStreamTracer] | None) -> None:
70
+ """Appends a list of :class:`NexusStreamTracer` objects to the internal store."""
71
+ if stream_tracers_to_add is None:
72
+ return
73
+ self.__stream_tracers.extend(stream_tracers_to_add)
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Literal, Sequence
6
6
 
7
7
  from ResSimpy.DataModelBaseClasses.NetworkList import NetworkList
8
8
  from ResSimpy.GenericContainerClasses.NetworkLists import NetworkLists
9
- from ResSimpy.Nexus.DataModels.NexusWellList import NexusWellList
9
+ from ResSimpy.Nexus.DataModels.Network.NexusWellList import NexusWellList
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  from ResSimpy.Nexus.NexusNetwork import NexusNetwork
@@ -6,7 +6,7 @@ import copy
6
6
  import numpy as np
7
7
  import pandas as pd
8
8
  from dataclasses import dataclass, field
9
- from typing import Optional, TYPE_CHECKING, Any, Final
9
+ from typing import TYPE_CHECKING, Any, Final
10
10
  import warnings
11
11
  from sys import maxsize
12
12
 
@@ -43,14 +43,14 @@ class PropertyToLoad:
43
43
 
44
44
  @dataclass(kw_only=True)
45
45
  class NexusGrid(Grid):
46
- __array_functions_list: Optional[list[list[str]]] = None
47
- __array_functions_df: Optional[pd.DataFrame] = None
46
+ __array_functions_list: list[list[str]] | None = None
47
+ __array_functions_df: pd.DataFrame | None = None
48
48
  __array_functions_loaded: bool = False
49
- __grid_file_contents: Optional[list[str]] = None
50
- __grid_file_nested: Optional[list[str]] = None
51
- __faults_df: Optional[pd.DataFrame] = None
49
+ __grid_file_contents: list[str] | None = None
50
+ __grid_file_nested: list[str] | None = None
51
+ __faults_df: pd.DataFrame | None = None
52
52
  __grid_faults_loaded: bool = False
53
- __grid_nexus_file: Optional[NexusFile] = None
53
+ __grid_nexus_file: NexusFile | None = None
54
54
  __corp: GridArrayDefinition
55
55
  __dx: GridArrayDefinition
56
56
  __dy: GridArrayDefinition
@@ -125,14 +125,14 @@ class NexusGrid(Grid):
125
125
  __kyeff: GridArrayDefinition
126
126
  __kzeff: GridArrayDefinition
127
127
  __grid_multir_loaded: bool = False
128
- __multir: Optional[list[NexusMultir]] = None
128
+ __multir: list[NexusMultir] | None = None
129
129
  __lgrs: NexusLGRs
130
130
  __overs: list[NexusOver] = field(default_factory=list)
131
131
  __tovers: list[NexusTOver] = field(default_factory=list)
132
132
  __ftrans: list[NexusFtrans] = field(default_factory=list)
133
133
  __model_unit_system: UnitSystem
134
134
 
135
- def __init__(self, model_unit_system: UnitSystem, grid_nexus_file: Optional[NexusFile] = None,
135
+ def __init__(self, model_unit_system: UnitSystem, grid_nexus_file: NexusFile | None = None,
136
136
  assume_loaded: bool = False,
137
137
  ) -> None:
138
138
  """Initialises the NexusGrid class.
@@ -146,15 +146,15 @@ class NexusGrid(Grid):
146
146
  super().__init__(assume_loaded=assume_loaded)
147
147
  self.__array_functions_loaded: bool = assume_loaded
148
148
  self.__grid_faults_loaded: bool = assume_loaded
149
- self.__array_functions_list: Optional[list[list[str]]] = None
150
- self.__array_functions_df: Optional[pd.DataFrame] = None
151
- self.__grid_file_contents: Optional[list[str]] = None if grid_nexus_file is None else \
149
+ self.__array_functions_list: list[list[str]] | None = None
150
+ self.__array_functions_df: pd.DataFrame | None = None
151
+ self.__grid_file_contents: list[str] | None = None if grid_nexus_file is None else \
152
152
  grid_nexus_file.get_flat_list_str_file_including_includes
153
- self.__grid_file_nested: Optional[list[str]] = None if grid_nexus_file is None else \
153
+ self.__grid_file_nested: list[str] | None = None if grid_nexus_file is None else \
154
154
  grid_nexus_file.file_content_as_list
155
- self.__faults_df: Optional[pd.DataFrame] = None
156
- self.__grid_nexus_file: Optional[NexusFile] = grid_nexus_file
157
- self.__grid_array_functions: Optional[list[NexusGridArrayFunction]] = None
155
+ self.__faults_df: pd.DataFrame | None = None
156
+ self.__grid_nexus_file: NexusFile | None = grid_nexus_file
157
+ self.__grid_array_functions: list[NexusGridArrayFunction] | None = None
158
158
  self.__corp: GridArrayDefinition = GridArrayDefinition()
159
159
  self.__iequil: GridArrayDefinition = GridArrayDefinition()
160
160
  self.__ipvt: GridArrayDefinition = GridArrayDefinition()
@@ -257,14 +257,14 @@ class NexusGrid(Grid):
257
257
  # Prevent reload from disk
258
258
  self._grid_properties_loaded = True
259
259
 
260
- def to_dict(self) -> dict[str, Optional[int] | GridArrayDefinition]:
260
+ def to_dict(self) -> dict[str, int | None | GridArrayDefinition]:
261
261
  """Returns a dictionary representation of grid array.
262
262
  Checks if grid properties are not loaded and loads them.
263
263
  """
264
264
  self.load_grid_properties_if_not_loaded()
265
265
 
266
266
  original_dict = self.__dict__
267
- new_dict: dict[str, Optional[int] | GridArrayDefinition] = {}
267
+ new_dict: dict[str, int | None | GridArrayDefinition] = {}
268
268
  for key in original_dict.keys():
269
269
  new_key = key
270
270
  if new_key[0] == '_':
@@ -709,13 +709,13 @@ class NexusGrid(Grid):
709
709
  self.__array_functions_df = afo.summarize_model_functions(self.__array_functions_list)
710
710
  self.__array_functions_loaded = True
711
711
 
712
- def get_array_functions_list(self) -> Optional[list[list[str]]]:
712
+ def get_array_functions_list(self) -> list[list[str]] | None:
713
713
  """Returns the grid array functions as a list of function lines."""
714
714
  if not self.__array_functions_loaded:
715
715
  self.load_array_functions()
716
716
  return self.__array_functions_list
717
717
 
718
- def get_array_functions_df(self) -> Optional[pd.DataFrame]:
718
+ def get_array_functions_df(self) -> pd.DataFrame | None:
719
719
  """Returns the grid array functions as a dataframe."""
720
720
  if not self.__array_functions_loaded:
721
721
  self.load_array_functions()
@@ -753,7 +753,7 @@ class NexusGrid(Grid):
753
753
  self.__faults_df = new_df.drop(['TMULT'], axis=1)
754
754
  self.__grid_faults_loaded = True
755
755
 
756
- def get_faults_df(self) -> Optional[pd.DataFrame]:
756
+ def get_faults_df(self) -> pd.DataFrame | None:
757
757
  """Returns the fault definition and transmissility multiplier information as a dataframe."""
758
758
  self.load_grid_properties_if_not_loaded()
759
759
  if not self.__grid_faults_loaded:
@@ -804,7 +804,7 @@ class NexusGrid(Grid):
804
804
  def __extract_multir_tableline(line: str) -> None | NexusMultir:
805
805
  """Takes a single line in a file and extracts a Multir object from it."""
806
806
  stored_values = fo.split_line(line)
807
- if not stored_values:
807
+ if not stored_values or len(stored_values) < 3:
808
808
  return None
809
809
  region_1_str, region_2_str, tmult_str = stored_values[0:3]
810
810
  region_1 = int(region_1_str)
@@ -854,7 +854,7 @@ class NexusGrid(Grid):
854
854
  return None
855
855
 
856
856
  @property
857
- def array_functions(self) -> Optional[list[NexusGridArrayFunction]]:
857
+ def array_functions(self) -> list[NexusGridArrayFunction] | None:
858
858
  """Returns a list of the array functions defined in the structured grid file."""
859
859
  self.load_grid_properties_if_not_loaded()
860
860
  if self.__grid_array_functions is None:
@@ -1814,7 +1814,8 @@ class NexusGrid(Grid):
1814
1814
 
1815
1815
  # add the faults
1816
1816
  faults_df = self.get_faults_df()
1817
- grid_str += NexusGrid.fault_df_to_string(faults_df)
1817
+ if faults_df is not None and not faults_df.empty:
1818
+ grid_str += NexusGrid.fault_df_to_string(faults_df)
1818
1819
 
1819
1820
  if self.array_functions:
1820
1821
  for array_function in self.array_functions:
@@ -8,7 +8,7 @@ from __future__ import annotations
8
8
  import re
9
9
  import warnings
10
10
  from dataclasses import dataclass
11
- from typing import TYPE_CHECKING, Optional, Any, Literal
11
+ from typing import TYPE_CHECKING, Any, Literal
12
12
 
13
13
  import ResSimpy.FileOperations.file_operations as fo
14
14
  from ResSimpy.DataModelBaseClasses.DataObjectMixin import DataObjectMixinDictType
@@ -38,6 +38,8 @@ from ResSimpy.Nexus.DataModels.Network.NexusProc import NexusProc
38
38
  from ResSimpy.Nexus.DataModels.Network.NexusProcs import NexusProcs
39
39
  from ResSimpy.Nexus.DataModels.Network.NexusStation import NexusStation
40
40
  from ResSimpy.Nexus.DataModels.Network.NexusStations import NexusStations
41
+ from ResSimpy.Nexus.DataModels.Network.NexusStreamTracer import NexusStreamTracer
42
+ from ResSimpy.Nexus.DataModels.Network.NexusStreamTracers import NexusStreamTracers
41
43
  from ResSimpy.Nexus.DataModels.Network.NexusTarget import NexusTarget
42
44
  from ResSimpy.Nexus.DataModels.Network.NexusTargets import NexusTargets
43
45
  from ResSimpy.Nexus.DataModels.Network.NexusWellConnection import NexusWellConnection
@@ -48,7 +50,7 @@ from ResSimpy.Nexus.DataModels.Network.NexusWellbores import NexusWellbores
48
50
  from ResSimpy.Nexus.DataModels.Network.NexusWellhead import NexusWellhead
49
51
  from ResSimpy.Nexus.DataModels.Network.NexusWellheads import NexusWellheads
50
52
  from ResSimpy.Nexus.DataModels.NexusFile import NexusFile
51
- from ResSimpy.Nexus.DataModels.NexusWellList import NexusWellList
53
+ from ResSimpy.Nexus.DataModels.Network.NexusWellList import NexusWellList
52
54
  from ResSimpy.Nexus.NexusEnums.ActivationChangeEnum import ActivationChangeEnum
53
55
  from ResSimpy.Nexus.nexus_collect_tables import collect_all_tables_to_objects
54
56
 
@@ -80,6 +82,7 @@ class NexusNetwork(Network):
80
82
  conlists: NexusConLists
81
83
  stations: NexusStations
82
84
  guide_rates: NexusGuideRates
85
+ stream_tracers: NexusStreamTracers
83
86
  _has_been_loaded: bool = False
84
87
 
85
88
  def __init__(self, model: NexusSimulator, assume_loaded: bool = False) -> None:
@@ -109,6 +112,12 @@ class NexusNetwork(Network):
109
112
  self.drills: NexusDrills = NexusDrills(self)
110
113
  self.drill_sites: NexusDrillSites = NexusDrillSites(self)
111
114
  self.guide_rates: NexusGuideRates = NexusGuideRates(self)
115
+ self.stream_tracers: NexusStreamTracers = NexusStreamTracers(self)
116
+
117
+ @property
118
+ def stream_tracer_map(self) -> dict[str, str]:
119
+ """Returns a stream-name to component mapping derived from parsed STREAM_TRACER objects."""
120
+ return self.stream_tracers.component_map
112
121
 
113
122
  @property
114
123
  def model(self) -> NexusSimulator:
@@ -163,9 +172,8 @@ class NexusNetwork(Network):
163
172
  time = self.__model.start_date
164
173
  name_ = None
165
174
  priority_ = None
166
- # initialize an empty proc object, so we can use its staticmethod reset_nexus_proc_function_counts
167
- proc_obj = NexusProc()
168
- nexus_proc_function_counts = proc_obj.reset_nexus_proc_function_counts()
175
+ nexus_proc_function_counts = NexusProc.reset_nexus_proc_function_counts()
176
+ date_format = self.__model.date_format
169
177
 
170
178
  for line in file_contents:
171
179
 
@@ -176,7 +184,8 @@ class NexusNetwork(Network):
176
184
  # check for keyword ENDPROCS to signal end of the procedure
177
185
  if fo.check_token('ENDPROCS', line=line):
178
186
  # create the proc object
179
- proc_obj = NexusProc(contents=proc_contents, date=time, name=name_, priority=priority_)
187
+ proc_obj = NexusProc(contents=proc_contents, date=time, name=name_, priority=priority_,
188
+ date_format=date_format, start_date=self.__model.start_date)
180
189
 
181
190
  # set the proc function counts
182
191
  proc_obj.contents_breakdown = nexus_proc_function_counts
@@ -231,14 +240,15 @@ class NexusNetwork(Network):
231
240
  Table headers with None next to their name are currently skipped awaiting development.
232
241
  """
233
242
 
234
- def type_check_lists(value: Optional[list[Any] | dict[str, list[NexusConstraint]]]) -> Optional[list[Any]]:
243
+ def type_check_lists(value: list[Any] | dict[str, list[NexusConstraint]] | None) -> list[Any] | None:
235
244
  """Guards against dictionaries coming from the dictionary."""
236
245
  if isinstance(value, dict):
237
246
  raise TypeError(f"Expected a list, instead received a dict: {value}")
238
247
  return value
239
248
 
240
- def type_check_dicts(value: Optional[list[Any] | dict[str, list[NexusConstraint]]]) -> \
241
- Optional[dict[str, list[NexusConstraint]]]:
249
+ def type_check_dicts(
250
+ value: list[Any] | dict[str, list[NexusConstraint]] | None
251
+ ) -> dict[str, list[NexusConstraint]] | None:
242
252
  """Guards against dictionaries coming from the dictionary."""
243
253
  if isinstance(value, list):
244
254
  raise TypeError(f"Expected a dict, instead received a list: {value}")
@@ -269,6 +279,7 @@ class NexusNetwork(Network):
269
279
  'STATION': NexusStation,
270
280
  'DRILL': NexusDrill,
271
281
  'DRILLSITE': NexusDrillSite,
282
+ 'STREAM_TRACER': NexusStreamTracer,
272
283
  }
273
284
 
274
285
  for surface in self.__model.model_files.surface_files.values():
@@ -297,6 +308,7 @@ class NexusNetwork(Network):
297
308
  self.drills._add_to_memory(type_check_lists(nexus_obj_dict.get('DRILL')))
298
309
  self.drill_sites._add_to_memory(type_check_lists(nexus_obj_dict.get('DRILLSITE')))
299
310
  self.guide_rates._add_to_memory(type_check_lists(nexus_obj_dict.get('GUIDERATE')))
311
+ self.stream_tracers._add_to_memory(type_check_lists(nexus_obj_dict.get('STREAM_TRACER')))
300
312
 
301
313
  actions_check = type_check_lists(nexus_obj_dict.get('ACTIONS'))
302
314
  if actions_check is not None:
@@ -335,7 +347,9 @@ class NexusNetwork(Network):
335
347
  return activation_changes
336
348
 
337
349
  def __update_well_types(self) -> None:
338
- """Updates the types of all of the wells using information found in the wells table."""
350
+ """Updates the types of all of the wells using information found in the wells table.
351
+ Falls back to the STREAM_TRACER component_map when the stream name is not a standard phase keyword.
352
+ """
339
353
  for connection in self.well_connections.get_all():
340
354
  if connection.name is None or connection.stream is None:
341
355
  # Connection cannot be used to determine well type, so ignore it.
@@ -347,7 +361,8 @@ class NexusNetwork(Network):
347
361
  warnings.warn(UserWarning(f'Cannot find matching well for {connection.name} declared in surface file.'))
348
362
  continue
349
363
 
350
- match connection.stream.upper():
364
+ stream_upper = connection.stream.upper()
365
+ match stream_upper:
351
366
  case 'PRODUCER':
352
367
  well_type = WellType.PRODUCER
353
368
  case 'GAS':
@@ -357,7 +372,18 @@ class NexusNetwork(Network):
357
372
  case 'OIL':
358
373
  well_type = WellType.OIL_INJECTOR
359
374
  case _:
360
- well_type = WellType.PRODUCER
375
+ # Look up the stream name in the STREAM_TRACER component map to resolve
376
+ # custom stream names (e.g. 'SEAWTR', 'TRTWTR', etc.) to
377
+ # their declared COMPONENT and map that to a WellType.
378
+ component = self.stream_tracers.component_map.get(stream_upper)
379
+ if component == 'WATER':
380
+ well_type = WellType.WATER_INJECTOR
381
+ elif component == 'GAS':
382
+ well_type = WellType.GAS_INJECTOR
383
+ elif component == 'OIL':
384
+ well_type = WellType.OIL_INJECTOR
385
+ else:
386
+ well_type = WellType.PRODUCER
361
387
 
362
388
  well_to_modify.well_type = well_type
363
389
 
@@ -14,7 +14,7 @@ from ResSimpy.Nexus.DataModels.Network.NexusConLists import NexusConLists
14
14
  from ResSimpy.Nexus.DataModels.Network.NexusNodeLists import NexusNodeLists
15
15
  from ResSimpy.Nexus.DataModels.Network.NexusConstraint import NexusConstraint
16
16
  from ResSimpy.Nexus.DataModels.Network.NexusWellLists import NexusWellLists
17
- from ResSimpy.Nexus.DataModels.NexusWellList import NexusWellList
17
+ from ResSimpy.Nexus.DataModels.Network.NexusWellList import NexusWellList
18
18
  from ResSimpy.Nexus.NexusEnums.ActivationChangeEnum import ActivationChangeEnum
19
19
  from ResSimpy.Nexus.NexusEnums.DateFormatEnum import DateFormat
20
20
  from ResSimpy.Nexus.nexus_constraint_operations import load_inline_constraints
@@ -7,7 +7,7 @@ import re
7
7
  from ResSimpy.DataModelBaseClasses.DataObjectMixin import DataObjectMixinDictType
8
8
  from ResSimpy.Nexus.DataModels.Network.NexusConstraint import NexusConstraint
9
9
  from ResSimpy.Enums.UnitsEnum import UnitSystem
10
- from ResSimpy.Nexus.DataModels.NexusWellList import NexusWellList
10
+ from ResSimpy.Nexus.DataModels.Network.NexusWellList import NexusWellList
11
11
  from ResSimpy.Nexus.NexusEnums.DateFormatEnum import DateFormat
12
12
  from ResSimpy.Nexus.nexus_file_operations import get_next_value, correct_datatypes
13
13
  from ResSimpy.Utils.invert_nexus_map import nexus_keyword_to_attribute_name