gea-program 0.57.0__tar.gz → 0.58.0__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 (370) hide show
  1. {gea_program-0.57.0/gea_program.egg-info → gea_program-0.58.0}/PKG-INFO +12 -1
  2. {gea_program-0.57.0 → gea_program-0.58.0}/README.md +11 -0
  3. {gea_program-0.57.0 → gea_program-0.58.0}/gea/__init__.py +1 -1
  4. {gea_program-0.57.0 → gea_program-0.58.0}/gea/__main__.py +58 -0
  5. {gea_program-0.57.0 → gea_program-0.58.0}/gea/acceptance_tests.py +182 -0
  6. {gea_program-0.57.0 → gea_program-0.58.0}/gea/dossier.py +12 -1
  7. gea_program-0.58.0/gea/help/hydraulics.md +19 -0
  8. {gea_program-0.57.0 → gea_program-0.58.0}/gea/helplib.py +2 -1
  9. gea_program-0.58.0/gea/hydraulics.py +739 -0
  10. {gea_program-0.57.0 → gea_program-0.58.0}/gea/service.py +17 -0
  11. {gea_program-0.57.0 → gea_program-0.58.0}/gea/web/app.html +78 -1
  12. {gea_program-0.57.0 → gea_program-0.58.0/gea_program.egg-info}/PKG-INFO +12 -1
  13. {gea_program-0.57.0 → gea_program-0.58.0}/gea_program.egg-info/SOURCES.txt +2 -0
  14. {gea_program-0.57.0 → gea_program-0.58.0}/pyproject.toml +1 -1
  15. {gea_program-0.57.0 → gea_program-0.58.0}/LICENSE +0 -0
  16. {gea_program-0.57.0 → gea_program-0.58.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
  17. {gea_program-0.57.0 → gea_program-0.58.0}/gea/accuracy_statement.py +0 -0
  18. {gea_program-0.57.0 → gea_program-0.58.0}/gea/alarm_engine.py +0 -0
  19. {gea_program-0.57.0 → gea_program-0.58.0}/gea/alerts.py +0 -0
  20. {gea_program-0.57.0 → gea_program-0.58.0}/gea/backup.py +0 -0
  21. {gea_program-0.57.0 → gea_program-0.58.0}/gea/bench.py +0 -0
  22. {gea_program-0.57.0 → gea_program-0.58.0}/gea/blind_harness.py +0 -0
  23. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
  24. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
  25. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
  26. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
  27. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
  28. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
  29. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
  30. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
  31. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
  32. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
  33. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
  34. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
  35. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
  36. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
  37. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
  38. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
  39. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
  40. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
  41. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
  42. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
  43. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
  44. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
  45. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
  46. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
  47. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
  48. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
  49. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
  50. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
  51. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
  52. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
  53. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
  54. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
  55. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
  56. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
  57. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
  58. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
  59. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
  60. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
  61. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
  62. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
  63. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
  64. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
  65. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
  66. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
  67. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
  68. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
  69. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
  70. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
  71. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
  72. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
  73. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
  74. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
  75. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
  76. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
  77. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
  78. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
  79. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
  80. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
  81. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
  82. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
  83. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
  84. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
  85. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
  86. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
  87. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
  88. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
  89. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
  90. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/med_160_sapropels.txt +0 -0
  91. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
  92. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
  93. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
  94. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
  95. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
  96. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
  97. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
  98. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
  99. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
  100. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
  101. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
  102. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
  103. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
  104. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
  105. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
  106. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
  107. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
  108. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
  109. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
  110. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
  111. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
  112. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
  113. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
  114. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
  115. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
  116. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
  117. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
  118. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
  119. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
  120. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
  121. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
  122. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
  123. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
  124. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
  125. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
  126. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
  127. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog_map.py +0 -0
  128. {gea_program-0.57.0 → gea_program-0.58.0}/gea/catalog_register.py +0 -0
  129. {gea_program-0.57.0 → gea_program-0.58.0}/gea/certificates.py +0 -0
  130. {gea_program-0.57.0 → gea_program-0.58.0}/gea/cli.py +0 -0
  131. {gea_program-0.57.0 → gea_program-0.58.0}/gea/client_reports.py +0 -0
  132. {gea_program-0.57.0 → gea_program-0.58.0}/gea/collision.py +0 -0
  133. {gea_program-0.57.0 → gea_program-0.58.0}/gea/config_versioning.py +0 -0
  134. {gea_program-0.57.0 → gea_program-0.58.0}/gea/conformance.py +0 -0
  135. {gea_program-0.57.0 → gea_program-0.58.0}/gea/control_room.py +0 -0
  136. {gea_program-0.57.0 → gea_program-0.58.0}/gea/correlation.py +0 -0
  137. {gea_program-0.57.0 → gea_program-0.58.0}/gea/dashboard.py +0 -0
  138. {gea_program-0.57.0 → gea_program-0.58.0}/gea/declarations.py +0 -0
  139. {gea_program-0.57.0 → gea_program-0.58.0}/gea/decline.py +0 -0
  140. {gea_program-0.57.0 → gea_program-0.58.0}/gea/deviation.py +0 -0
  141. {gea_program-0.57.0 → gea_program-0.58.0}/gea/dlis.py +0 -0
  142. {gea_program-0.57.0 → gea_program-0.58.0}/gea/dnp3.py +0 -0
  143. {gea_program-0.57.0 → gea_program-0.58.0}/gea/doctor.py +0 -0
  144. {gea_program-0.57.0 → gea_program-0.58.0}/gea/dossier_verify.py +0 -0
  145. {gea_program-0.57.0 → gea_program-0.58.0}/gea/downhole_engine.py +0 -0
  146. {gea_program-0.57.0 → gea_program-0.58.0}/gea/drift_monitor.py +0 -0
  147. {gea_program-0.57.0 → gea_program-0.58.0}/gea/drill_string.py +0 -0
  148. {gea_program-0.57.0 → gea_program-0.58.0}/gea/earth_model.py +0 -0
  149. {gea_program-0.57.0 → gea_program-0.58.0}/gea/economics.py +0 -0
  150. {gea_program-0.57.0 → gea_program-0.58.0}/gea/ed25519.py +0 -0
  151. {gea_program-0.57.0 → gea_program-0.58.0}/gea/edr.py +0 -0
  152. {gea_program-0.57.0 → gea_program-0.58.0}/gea/elevation.py +0 -0
  153. {gea_program-0.57.0 → gea_program-0.58.0}/gea/etp.py +0 -0
  154. {gea_program-0.57.0 → gea_program-0.58.0}/gea/etp12_schemas.json +0 -0
  155. {gea_program-0.57.0 → gea_program-0.58.0}/gea/example_register_map.json +0 -0
  156. {gea_program-0.57.0 → gea_program-0.58.0}/gea/fat_sat.py +0 -0
  157. {gea_program-0.57.0 → gea_program-0.58.0}/gea/files.py +0 -0
  158. {gea_program-0.57.0 → gea_program-0.58.0}/gea/fixtures/README.md +0 -0
  159. {gea_program-0.57.0 → gea_program-0.58.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
  160. {gea_program-0.57.0 → gea_program-0.58.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
  161. {gea_program-0.57.0 → gea_program-0.58.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
  162. {gea_program-0.57.0 → gea_program-0.58.0}/gea/fixtures/ne_110m_coastline.json +0 -0
  163. {gea_program-0.57.0 → gea_program-0.58.0}/gea/follower.py +0 -0
  164. {gea_program-0.57.0 → gea_program-0.58.0}/gea/forward_model.py +0 -0
  165. {gea_program-0.57.0 → gea_program-0.58.0}/gea/frac_hits.py +0 -0
  166. {gea_program-0.57.0 → gea_program-0.58.0}/gea/friction_priors.py +0 -0
  167. {gea_program-0.57.0 → gea_program-0.58.0}/gea/gamma.py +0 -0
  168. {gea_program-0.57.0 → gea_program-0.58.0}/gea/gauge_aging.py +0 -0
  169. {gea_program-0.57.0 → gea_program-0.58.0}/gea/gauge_specs.py +0 -0
  170. {gea_program-0.57.0 → gea_program-0.58.0}/gea/geodesy.py +0 -0
  171. {gea_program-0.57.0 → gea_program-0.58.0}/gea/geomag.py +0 -0
  172. {gea_program-0.57.0 → gea_program-0.58.0}/gea/gravity_reference.py +0 -0
  173. {gea_program-0.57.0 → gea_program-0.58.0}/gea/hartip.py +0 -0
  174. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/IT_SECURITY.md +0 -0
  175. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/TESTER_GUIDE.md +0 -0
  176. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/alarms.md +0 -0
  177. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/alerts.md +0 -0
  178. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/audit-update.md +0 -0
  179. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/backup.md +0 -0
  180. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/catalog.md +0 -0
  181. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/charts.md +0 -0
  182. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/collision.md +0 -0
  183. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/company-sign-in.md +0 -0
  184. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/conformance.md +0 -0
  185. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/control-room.md +0 -0
  186. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/data-in.md +0 -0
  187. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/declare.md +0 -0
  188. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/decline.md +0 -0
  189. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/dlis.md +0 -0
  190. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/doctor.md +0 -0
  191. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/dossier.md +0 -0
  192. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/drift.md +0 -0
  193. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/drillstring.md +0 -0
  194. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/economics.md +0 -0
  195. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/edr.md +0 -0
  196. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/etp.md +0 -0
  197. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/field-ports.md +0 -0
  198. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/files.md +0 -0
  199. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/frac-hits.md +0 -0
  200. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/historian.md +0 -0
  201. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/https.md +0 -0
  202. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/instruments.md +0 -0
  203. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/interval.md +0 -0
  204. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/invoice-check.md +0 -0
  205. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/map.md +0 -0
  206. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/month-end.md +0 -0
  207. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/notifications.md +0 -0
  208. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/opseis.md +0 -0
  209. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/osdu.md +0 -0
  210. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/pad-summary.md +0 -0
  211. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/patches.md +0 -0
  212. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/penetrator.md +0 -0
  213. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/plan.md +0 -0
  214. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/pore-pressure.md +0 -0
  215. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/ppdm.md +0 -0
  216. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/quakeml.md +0 -0
  217. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/quality.md +0 -0
  218. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/report-history.md +0 -0
  219. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/rig-time.md +0 -0
  220. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/seedlink.md +0 -0
  221. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/seismic.md +0 -0
  222. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/setup.md +0 -0
  223. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/simulation.md +0 -0
  224. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/site.md +0 -0
  225. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/sites.md +0 -0
  226. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/slip.md +0 -0
  227. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/soak.md +0 -0
  228. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/sra.md +0 -0
  229. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/start.md +0 -0
  230. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/structure.md +0 -0
  231. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/tools.md +0 -0
  232. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/torque-drag.md +0 -0
  233. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/transients.md +0 -0
  234. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/upkeep.md +0 -0
  235. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/vibration.md +0 -0
  236. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/well-report.md +0 -0
  237. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/well-tests.md +0 -0
  238. {gea_program-0.57.0 → gea_program-0.58.0}/gea/help/well3d.md +0 -0
  239. {gea_program-0.57.0 → gea_program-0.58.0}/gea/housekeeping.py +0 -0
  240. {gea_program-0.57.0 → gea_program-0.58.0}/gea/interval.py +0 -0
  241. {gea_program-0.57.0 → gea_program-0.58.0}/gea/inverse_engine.py +0 -0
  242. {gea_program-0.57.0 → gea_program-0.58.0}/gea/invoice_check.py +0 -0
  243. {gea_program-0.57.0 → gea_program-0.58.0}/gea/jobs.py +0 -0
  244. {gea_program-0.57.0 → gea_program-0.58.0}/gea/live_ports.py +0 -0
  245. {gea_program-0.57.0 → gea_program-0.58.0}/gea/loadtest.py +0 -0
  246. {gea_program-0.57.0 → gea_program-0.58.0}/gea/matplotlib_demo.py +0 -0
  247. {gea_program-0.57.0 → gea_program-0.58.0}/gea/modbus.py +0 -0
  248. {gea_program-0.57.0 → gea_program-0.58.0}/gea/modbus_rtu.py +0 -0
  249. {gea_program-0.57.0 → gea_program-0.58.0}/gea/model_card.py +0 -0
  250. {gea_program-0.57.0 → gea_program-0.58.0}/gea/month_end.py +0 -0
  251. {gea_program-0.57.0 → gea_program-0.58.0}/gea/mqtt_port.py +0 -0
  252. {gea_program-0.57.0 → gea_program-0.58.0}/gea/notify.py +0 -0
  253. {gea_program-0.57.0 → gea_program-0.58.0}/gea/oidc.py +0 -0
  254. {gea_program-0.57.0 → gea_program-0.58.0}/gea/oidc_mock.py +0 -0
  255. {gea_program-0.57.0 → gea_program-0.58.0}/gea/op_seismicity.py +0 -0
  256. {gea_program-0.57.0 → gea_program-0.58.0}/gea/opcua_port.py +0 -0
  257. {gea_program-0.57.0 → gea_program-0.58.0}/gea/operator_app.py +0 -0
  258. {gea_program-0.57.0 → gea_program-0.58.0}/gea/osdu.py +0 -0
  259. {gea_program-0.57.0 → gea_program-0.58.0}/gea/pad_summary.py +0 -0
  260. {gea_program-0.57.0 → gea_program-0.58.0}/gea/patches.py +0 -0
  261. {gea_program-0.57.0 → gea_program-0.58.0}/gea/pdf_report.py +0 -0
  262. {gea_program-0.57.0 → gea_program-0.58.0}/gea/penetrator.py +0 -0
  263. {gea_program-0.57.0 → gea_program-0.58.0}/gea/permits.py +0 -0
  264. {gea_program-0.57.0 → gea_program-0.58.0}/gea/piwebapi.py +0 -0
  265. {gea_program-0.57.0 → gea_program-0.58.0}/gea/pore_pressure.py +0 -0
  266. {gea_program-0.57.0 → gea_program-0.58.0}/gea/ports.py +0 -0
  267. {gea_program-0.57.0 → gea_program-0.58.0}/gea/ppdm.py +0 -0
  268. {gea_program-0.57.0 → gea_program-0.58.0}/gea/profile_catalog.py +0 -0
  269. {gea_program-0.57.0 → gea_program-0.58.0}/gea/project.py +0 -0
  270. {gea_program-0.57.0 → gea_program-0.58.0}/gea/qt6_downhole_app.py +0 -0
  271. {gea_program-0.57.0 → gea_program-0.58.0}/gea/quakeml.py +0 -0
  272. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reconciler.py +0 -0
  273. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
  274. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
  275. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/WMM2025.COF +0 -0
  276. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
  277. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/eia_prices.provenance.json +0 -0
  278. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
  279. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/iscwsa_rev4_example.json +0 -0
  280. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/iscwsa_rev5_example.json +0 -0
  281. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/l0701_sonic_gr.las.gz +0 -0
  282. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/l0701_sonic_gr.provenance.json +0 -0
  283. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/libmseed_steim.provenance.json +0 -0
  284. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
  285. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
  286. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
  287. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/mahoning_example.json +0 -0
  288. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/mud_motor_specs.json +0 -0
  289. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/owsg_tool_models.json +0 -0
  290. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/penetrator_ratings.json +0 -0
  291. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/seismicity_protocols.json +0 -0
  292. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/tool_sources.json +0 -0
  293. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/us_outline.json +0 -0
  294. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/us_outline.provenance.json +0 -0
  295. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_3d.provenance.json +0 -0
  296. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
  297. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
  298. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
  299. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_surfaces.json.gz +0 -0
  300. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
  301. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
  302. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
  303. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
  304. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
  305. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
  306. {gea_program-0.57.0 → gea_program-0.58.0}/gea/reference/volve_well_picks.csv.gz +0 -0
  307. {gea_program-0.57.0 → gea_program-0.58.0}/gea/report_history.py +0 -0
  308. {gea_program-0.57.0 → gea_program-0.58.0}/gea/rig_state.py +0 -0
  309. {gea_program-0.57.0 → gea_program-0.58.0}/gea/rock_inventory.py +0 -0
  310. {gea_program-0.57.0 → gea_program-0.58.0}/gea/sample_record.py +0 -0
  311. {gea_program-0.57.0 → gea_program-0.58.0}/gea/sample_well_profile.csv +0 -0
  312. {gea_program-0.57.0 → gea_program-0.58.0}/gea/sbom.py +0 -0
  313. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seedlink.py +0 -0
  314. {gea_program-0.57.0 → gea_program-0.58.0}/gea/segy.py +0 -0
  315. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic.py +0 -0
  316. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_array.py +0 -0
  317. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_assoc.py +0 -0
  318. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_detect.py +0 -0
  319. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_film.py +0 -0
  320. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_harmonic.py +0 -0
  321. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_qc.py +0 -0
  322. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_response.py +0 -0
  323. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_signature.py +0 -0
  324. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_track.py +0 -0
  325. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_uncertainty.py +0 -0
  326. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_unlisted.py +0 -0
  327. {gea_program-0.57.0 → gea_program-0.58.0}/gea/seismic_watch.py +0 -0
  328. {gea_program-0.57.0 → gea_program-0.58.0}/gea/sensor_swap.py +0 -0
  329. {gea_program-0.57.0 → gea_program-0.58.0}/gea/series_cache.py +0 -0
  330. {gea_program-0.57.0 → gea_program-0.58.0}/gea/service_life.py +0 -0
  331. {gea_program-0.57.0 → gea_program-0.58.0}/gea/setup_checklist.py +0 -0
  332. {gea_program-0.57.0 → gea_program-0.58.0}/gea/shapefile.py +0 -0
  333. {gea_program-0.57.0 → gea_program-0.58.0}/gea/shell.py +0 -0
  334. {gea_program-0.57.0 → gea_program-0.58.0}/gea/shut_in.py +0 -0
  335. {gea_program-0.57.0 → gea_program-0.58.0}/gea/simulation.py +0 -0
  336. {gea_program-0.57.0 → gea_program-0.58.0}/gea/site_map.py +0 -0
  337. {gea_program-0.57.0 → gea_program-0.58.0}/gea/sla_report.py +0 -0
  338. {gea_program-0.57.0 → gea_program-0.58.0}/gea/slip.py +0 -0
  339. {gea_program-0.57.0 → gea_program-0.58.0}/gea/soak.py +0 -0
  340. {gea_program-0.57.0 → gea_program-0.58.0}/gea/sra.py +0 -0
  341. {gea_program-0.57.0 → gea_program-0.58.0}/gea/store_forward.py +0 -0
  342. {gea_program-0.57.0 → gea_program-0.58.0}/gea/strata_join.py +0 -0
  343. {gea_program-0.57.0 → gea_program-0.58.0}/gea/structure.py +0 -0
  344. {gea_program-0.57.0 → gea_program-0.58.0}/gea/supervisor.py +0 -0
  345. {gea_program-0.57.0 → gea_program-0.58.0}/gea/survey_cmd.py +0 -0
  346. {gea_program-0.57.0 → gea_program-0.58.0}/gea/survey_view.py +0 -0
  347. {gea_program-0.57.0 → gea_program-0.58.0}/gea/telemetry.py +0 -0
  348. {gea_program-0.57.0 → gea_program-0.58.0}/gea/tls.py +0 -0
  349. {gea_program-0.57.0 → gea_program-0.58.0}/gea/tool_catalog.py +0 -0
  350. {gea_program-0.57.0 → gea_program-0.58.0}/gea/tool_library.py +0 -0
  351. {gea_program-0.57.0 → gea_program-0.58.0}/gea/tool_taxonomy.py +0 -0
  352. {gea_program-0.57.0 → gea_program-0.58.0}/gea/torque_drag.py +0 -0
  353. {gea_program-0.57.0 → gea_program-0.58.0}/gea/transient.py +0 -0
  354. {gea_program-0.57.0 → gea_program-0.58.0}/gea/vibration.py +0 -0
  355. {gea_program-0.57.0 → gea_program-0.58.0}/gea/well3d.py +0 -0
  356. {gea_program-0.57.0 → gea_program-0.58.0}/gea/well_assembler.py +0 -0
  357. {gea_program-0.57.0 → gea_program-0.58.0}/gea/well_report.py +0 -0
  358. {gea_program-0.57.0 → gea_program-0.58.0}/gea/well_test_validation.py +0 -0
  359. {gea_program-0.57.0 → gea_program-0.58.0}/gea/wellplan.py +0 -0
  360. {gea_program-0.57.0 → gea_program-0.58.0}/gea/wellpos.py +0 -0
  361. {gea_program-0.57.0 → gea_program-0.58.0}/gea/wits0.py +0 -0
  362. {gea_program-0.57.0 → gea_program-0.58.0}/gea/witsml.py +0 -0
  363. {gea_program-0.57.0 → gea_program-0.58.0}/gea/workspace.py +0 -0
  364. {gea_program-0.57.0 → gea_program-0.58.0}/gea/xlsx_read.py +0 -0
  365. {gea_program-0.57.0 → gea_program-0.58.0}/gea_program.egg-info/dependency_links.txt +0 -0
  366. {gea_program-0.57.0 → gea_program-0.58.0}/gea_program.egg-info/entry_points.txt +0 -0
  367. {gea_program-0.57.0 → gea_program-0.58.0}/gea_program.egg-info/requires.txt +0 -0
  368. {gea_program-0.57.0 → gea_program-0.58.0}/gea_program.egg-info/top_level.txt +0 -0
  369. {gea_program-0.57.0 → gea_program-0.58.0}/setup.cfg +0 -0
  370. {gea_program-0.57.0 → gea_program-0.58.0}/tests/test_acceptance.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gea-program
3
- Version: 0.57.0
3
+ Version: 0.58.0
4
4
  Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
5
5
  Author: Daniel T. Murphy
6
6
  License: MPL-2.0
@@ -659,6 +659,17 @@ EIA) or a declared price, with the net revenue interest, severance tax and
659
659
  operating cost declared. A forecast is not a reserves report, and the page
660
660
  says so. The **Decline curves** tab, `gea decline`, `gea help decline`.
661
661
 
662
+ ### Hydraulics and ECD
663
+
664
+ The pressures the mud makes while it circulates, from the six-speed
665
+ viscometer (the API RP 13D power law: the pipe from 600/300, the annulus
666
+ from 100/3): the standpipe pressure part by part - surface lines, string,
667
+ motor and MWD, bit, annulus - the bit's hydraulics, the ECD at every depth
668
+ against the pore pressure and fracture gradient, surge and swab and the
669
+ fastest safe trip at each bit depth, and the standpipe pressure the rig
670
+ measured against the model. The **Hydraulics & ECD** tab, `gea hydraulics`,
671
+ `gea help hydraulics`.
672
+
662
673
  ### Torque and drag
663
674
 
664
675
  The hook load and torque the drill string should take at each bit depth, by
@@ -620,6 +620,17 @@ EIA) or a declared price, with the net revenue interest, severance tax and
620
620
  operating cost declared. A forecast is not a reserves report, and the page
621
621
  says so. The **Decline curves** tab, `gea decline`, `gea help decline`.
622
622
 
623
+ ### Hydraulics and ECD
624
+
625
+ The pressures the mud makes while it circulates, from the six-speed
626
+ viscometer (the API RP 13D power law: the pipe from 600/300, the annulus
627
+ from 100/3): the standpipe pressure part by part - surface lines, string,
628
+ motor and MWD, bit, annulus - the bit's hydraulics, the ECD at every depth
629
+ against the pore pressure and fracture gradient, surge and swab and the
630
+ fastest safe trip at each bit depth, and the standpipe pressure the rig
631
+ measured against the model. The **Hydraulics & ECD** tab, `gea hydraulics`,
632
+ `gea help hydraulics`.
633
+
623
634
  ### Torque and drag
624
635
 
625
636
  The hook load and torque the drill string should take at each bit depth, by
@@ -123,7 +123,7 @@ from .profile_catalog import (
123
123
  read_pangaea_txt,
124
124
  )
125
125
 
126
- __version__ = "0.57.0"
126
+ __version__ = "0.58.0"
127
127
  __all__ = [
128
128
  "aging_rate", "rate_psi_yr", "accuracy_psi",
129
129
  "Sensor", "SimulatorConfig", "DownholeEngine",
@@ -646,6 +646,24 @@ def main(argv=None) -> int:
646
646
  p_dc.add_argument("--actor", type=str, default="cli")
647
647
  p_dc.add_argument("--json", action="store_true")
648
648
 
649
+ p_hy = sub.add_parser("hydraulics", help="the pressures the mud makes while it circulates - the standpipe, the bit, the annulus, the ECD against the pore pressure and fracture gradient, surge and swab - and the standpipe pressure the rig measured")
650
+ p_hy.add_argument("--workspace", type=str, default=None)
651
+ p_hy.add_argument("--well", type=str, default=None)
652
+ p_hy.add_argument("--example", action="store_true", help="the worked example (Volve 15/9-F-10 with an example mud, string and hole)")
653
+ p_hy.add_argument("--string", type=str, default=None, help="sections from the bit up: 'BHA:350:6.75:2.875; drill pipe::5:4.276' (what:length_ft:od_in:id_in)")
654
+ p_hy.add_argument("--hole", type=str, default=None, help="sections from the surface down: '9-5/8 casing:3500:8.681; open hole::8.75' (what:bottom_md_ft:id_in)")
655
+ p_hy.add_argument("--fann", type=str, default=None, help="the viscometer dial: '600=60 300=38 200=30 100=21 6=7 3=6'")
656
+ p_hy.add_argument("--nozzles", type=str, default=None, help="nozzle sizes in 32nds of an inch: '14 14 14 14 14'")
657
+ for k_, h_ in (("mw", "mud weight, ppg"), ("flow", "pump rate, gal/min"), ("bit", "bit diameter, in"), ("surface", "surface lines' pressure loss, psi"),
658
+ ("surface-ref", "the rate (gal/min) the surface loss was declared at"), ("tools", "motor and MWD pressure drop, psi"),
659
+ ("trip", "average stand speed tripping, ft/min"), ("pp", "a pore pressure for the hole when the Pore pressure tab has none, ppg"),
660
+ ("fg", "a fracture gradient for the hole when the Pore pressure tab has none, ppg")):
661
+ p_hy.add_argument("--" + k_, type=str, default=None, help=h_)
662
+ p_hy.add_argument("--source", type=str, default="", help="where the mud, string and hole figures came from")
663
+ p_hy.add_argument("--write", action="store_true")
664
+ p_hy.add_argument("--actor", type=str, default="cli")
665
+ p_hy.add_argument("--json", action="store_true")
666
+
649
667
  p_td = sub.add_parser("torque-drag", help="the hook load and torque the string should take at each bit depth (soft-string model), the broomstick, and the friction factors that fit the rig's own trips")
650
668
  p_td.add_argument("--workspace", type=str, default=None)
651
669
  p_td.add_argument("--well", type=str, default=None)
@@ -2577,6 +2595,46 @@ def main(argv=None) -> int:
2577
2595
  raise SystemExit(f"decline: {e.args[0] if e.args else e}")
2578
2596
  print(_json.dumps(r, default=str) if a.json else _DCA.text(r))
2579
2597
  return 0
2598
+ elif a.cmd == "hydraulics":
2599
+ import json as _json
2600
+ from . import hydraulics as _HYD
2601
+ from .cli import _safe_stdout
2602
+ from .workspace import Workspace, WorkspaceError
2603
+ _safe_stdout()
2604
+ try:
2605
+ ws = Workspace(a.workspace) if a.workspace else None
2606
+ scene = "example" if (a.example or ws is None) else "workspace"
2607
+ keys_ = {"mw": "mw_ppg", "flow": "flow_gpm", "bit": "bit_in", "surface": "surface_psi", "surface_ref": "surface_ref_gpm", "tools": "tools_psi",
2608
+ "trip": "trip_ft_min", "pp": "pp_ppg", "fg": "fg_ppg"}
2609
+ vals_ = {v: getattr(a, k) for k, v in keys_.items() if getattr(a, k) is not None}
2610
+ if ws is not None and (vals_ or any(x is not None for x in (a.string, a.hole, a.fann, a.nozzles))):
2611
+ if not a.well:
2612
+ raise ValueError("--well is needed")
2613
+ fann_ = None
2614
+ if a.fann is not None:
2615
+ fann_ = {}
2616
+ for p_ in a.fann.replace(",", " ").split():
2617
+ k_, _, v_ = p_.partition("=")
2618
+ if not v_:
2619
+ raise ValueError(f"--fann takes SPEED=DIAL pairs, e.g. 600=60 300=38, not {p_!r}")
2620
+ fann_[k_.strip()] = v_.strip()
2621
+ c_ = _HYD.set_well(ws, a.actor, a.well, a.source, a.string, a.hole, fann_, a.nozzles, **vals_)
2622
+ print(f"{a.well}: mud {c_['mw_ppg']:g} ppg, {c_['flow_gpm']:g} gpm; string {len(c_.get('string') or [])} section(s), hole {len(c_.get('hole') or [])} section(s); "
2623
+ f"viscometer {' '.join(f'{k}={v:g}' for k, v in (c_.get('fann') or {}).items()) or 'not declared'}")
2624
+ return 0
2625
+ if a.write:
2626
+ if ws is None:
2627
+ raise ValueError("--write needs --workspace")
2628
+ r_ = _HYD.write_report(ws, __version__, a.well, a.actor, scene)
2629
+ print(f"wrote {r_['report_id']}: {r_['paths']['html']}")
2630
+ if r_['paths'].get('pdf'):
2631
+ print(f" printable: {r_['paths']['pdf']}")
2632
+ return 0
2633
+ r = _HYD.page(ws, scene, a.well)
2634
+ except (KeyError, ValueError, OSError, WorkspaceError) as e:
2635
+ raise SystemExit(f"hydraulics: {e.args[0] if e.args else e}")
2636
+ print(_json.dumps(r, default=str) if a.json else _HYD.text(r))
2637
+ return 0
2580
2638
  elif a.cmd == "torque-drag":
2581
2639
  import json as _json
2582
2640
  from . import torque_drag as _TND
@@ -12821,6 +12821,187 @@ def section_cz_it_review(tmp: str) -> None:
12821
12821
  "SECURITY.md says how to report a vulnerability" + (f" - failed: {failed3}" if failed3 else ""))
12822
12822
 
12823
12823
 
12824
+ def section_da_hydraulics(tmp: str) -> None:
12825
+ """Section DA - hydraulics and ECD: the power law's losses against their closed forms (Hagen-Poiseuille, the slot,
12826
+ Blasius) and API RP 13D's field-unit forms, the bit against its classic formula; a record whose standpipe pressure is
12827
+ the model's plus a known amount, read back; the worked example's ECD against its window, surge and swab; the API, the
12828
+ CLI, the report, the dossier, the tab and the help."""
12829
+ import http.cookiejar
12830
+ import math as _m
12831
+ import subprocess as _sp
12832
+ import urllib.request
12833
+ import urllib.error
12834
+ import zipfile as _zf
12835
+ from . import __version__ as _ver
12836
+ from . import dossier as DZ
12837
+ from . import helplib as H
12838
+ from . import hydraulics as HY
12839
+ from . import well3d as W
12840
+ from .workspace import Workspace
12841
+ from .service import Service, Users
12842
+ pkg = Path(__file__).parent
12843
+ d = Path(tmp, "hydraulics"); d.mkdir()
12844
+
12845
+ # -- DA1 by hand --------------------------------------------------------------------------------------------------------
12846
+ mu, q = 0.03, 50.0
12847
+ lp = HY.pipe_loss(q, 4.0, 1000.0, 8.33, 1.0, mu)
12848
+ Q, D = q * HY.GPM, 4.0 * HY.IN
12849
+ V = Q / (_m.pi * D * D / 4.0)
12850
+ hp = 32.0 * mu * V * 1000.0 * HY.FT / D ** 2 / HY.PSI
12851
+ la = HY.annulus_loss(q, 8.5, 5.0, 1000.0, 8.33, 1.0, mu)
12852
+ Va = q * HY.GPM / (_m.pi * ((8.5 * HY.IN) ** 2 - (5.0 * HY.IN) ** 2) / 4.0)
12853
+ slot = 48.0 * mu * Va * 1000.0 * HY.FT / (3.5 * HY.IN) ** 2 / HY.PSI
12854
+ f_t = HY.friction(1e5, 1.0, 16.0)[0]
12855
+ rh = HY.rheology({"600": 56, "300": 36, "200": 28, "100": 20, "6": 6, "3": 5})
12856
+ n, K = rh["n_pipe"], rh["K_pipe"]
12857
+ api = HY.pipe_loss(550.0, 4.276, 1000.0, 10.5, n, K)
12858
+ Vf = 24.51 * 550.0 / 4.276 ** 2 # ft/min
12859
+ mu_api = 100.0 * (5.11 * 56 / 1022 ** n) * (1.6 * Vf / 4.276) ** (n - 1) * ((3 * n + 1) / (4 * n)) ** n
12860
+ re_api = 15.467 * Vf * 4.276 * 10.5 / mu_api
12861
+ dp_api = 1.076 * 10.5 * Vf ** 2 * api["f"] / 1e5 / 4.276 * 1000.0
12862
+ bt = HY.bit(550.0, 10.5, [13] * 6, 8.5)
12863
+ refused = []
12864
+ for bad in ({"600": 56}, {"600": 30, "300": 36}, {"600": 56, "300": 36, "450": 40}, {"600": 400, "300": 36}):
12865
+ try:
12866
+ HY.rheology(bad); refused.append(False)
12867
+ except ValueError:
12868
+ refused.append(True)
12869
+ for fn, arg in ((HY.check_string, [{"what": "x", "length_ft": 100, "od_in": 5, "id_in": 6}]), (HY.check_hole, [{"what": "a", "bottom_md_ft": 1000, "id_in": 8},
12870
+ {"what": "b", "bottom_md_ft": 500, "id_in": 8}, {"what": "c", "id_in": 8}]),
12871
+ (HY.parse_sections, "BHA:300:6.75"), (HY.annulus_loss, None)):
12872
+ try:
12873
+ fn(arg, "string") if fn is HY.parse_sections else (HY.annulus_loss(500, 5.0, 6.0, 100, 10, 0.5, 0.5) if fn is HY.annulus_loss else fn(arg))
12874
+ refused.append(False)
12875
+ except ValueError:
12876
+ refused.append(True)
12877
+ c1 = {
12878
+ "newtonian": abs(lp["psi"] / hp - 1) < 1e-4 and lp["regime"] == "laminar" and abs(la["psi"] / slot - 1) < 1e-9 and abs(f_t / (0.0791 / 1e5 ** 0.25) - 1) < 0.01,
12879
+ "rheology": rh["pv_cp"] == 20 and rh["yp_lbf_100ft2"] == 16 and abs(rh["n_pipe"] - _m.log2(56 / 36)) < 1e-4 and abs(rh["n_ann"] - _m.log(20 / 5) / _m.log(170.2 / 5.11)) < 1e-4
12880
+ and rh["tau0_lbf_100ft2"] == 4 and rh["annulus_from"] == "100 and 3 rpm",
12881
+ "api_forms": abs(api["v_ft_min"] / Vf - 1) < 1e-3 and abs(api["mu_cp"] / mu_api - 1) < 1e-3 and abs(api["re"] / re_api - 1) < 2e-3 and abs(api["psi"] / dp_api - 1) < 1e-3,
12882
+ "bit": abs(bt["psi"] / (156.5 * 10.5 * 550.0 ** 2 / (6 * 13 ** 2) ** 2) - 1) < 1e-3 and abs(bt["tfa_in2"] - 6 * _m.pi / 4 * (13 / 32) ** 2) < 1e-3
12883
+ and abs(bt["hhp"] - bt["psi"] * 550 / 1714) < 0.1,
12884
+ "refused": all(refused) and len(refused) == 8,
12885
+ }
12886
+ failed1 = [k for k, v in c1.items() if not v]
12887
+ ok(not failed1,
12888
+ "DA1 the losses by hand: a Newtonian fluid's laminar loss in a pipe is Hagen-Poiseuille's and in the annulus the slot's, exactly; its turbulent "
12889
+ "friction factor Blasius's to 1 %; the viscometer's PV, YP, the pipe's n from 600/300 and the annulus's from 100/3; the velocity, effective "
12890
+ "viscosity, Reynolds number and loss equal to API RP 13D's field-unit forms; the bit's loss the classic 156.5 rho Q^2 / (sum d^2)^2; readings "
12891
+ "missing, falling or out of range, a bore wider than the pipe, a hole out of order, a short section and a pipe wider than its hole refused"
12892
+ + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
12893
+
12894
+ # -- DA2 a record made by the model, read back ---------------------------------------------------------------------------
12895
+ f = HY.selftest_files(str(d))
12896
+ wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad 3", actor="tester")
12897
+ wid = ws.add_well_file(f["record"], display="HY-1", actor="tester")["id"]
12898
+ ws.set_well(wid, surface={"lat": 31.42, "lon": -104.10, "datum": "NAD83", "elevation": {"ft": 3000.0, "datum": "KB", "source": "test plat"}}, actor="tester")
12899
+ no_survey = HY.page(ws, "workspace", wid)["detail"]
12900
+ W.attach_trajectory(ws, wid, "s.csv", Path(f["survey"]).read_bytes(), "tester", "true", "ft", None, None, None, "test survey")
12901
+ no_decl = HY.page(ws, "workspace", wid)["detail"]
12902
+ c = f["config"]
12903
+ HY.set_well(ws, "tester", wid, "mud report (test)", string=c["string"], hole=c["hole"], fann=c["fann"], nozzles_32=c["nozzles_32"], mw_ppg=c["mw_ppg"],
12904
+ flow_gpm=500, bit_in=8.75, tools_psi=400, pp_ppg=9.5, fg_ppg=14.5)
12905
+ r = HY.page(ws, "workspace", wid)["result"]
12906
+ rc = r["record"]
12907
+ cc = r["circulating"]
12908
+ c2 = {
12909
+ "needs": "survey" in no_survey and "string" in no_decl and "viscometer" in no_decl,
12910
+ "record": rc and rc["bins"] >= 20 and abs(rc["median_difference_psi"] - f["offset_psi"]) <= 10.0 and rc["spread_psi"] < 30.0,
12911
+ "parts": abs(sum(cc["parts"].values()) - cc["spp_psi"]) < 1.0 and cc["parts"]["tools"] == 400.0 and cc["parts"]["surface"] == 0.0,
12912
+ "ecd": cc["ecd_bit_ppg"] > c["mw_ppg"] and all(e_ >= c["mw_ppg"] for e_ in r["ecd"]["ecd_ppg"])
12913
+ and abs(cc["ecd_bit_ppg"] - (c["mw_ppg"] + cc["parts"]["annulus"] / (0.052 * cc["tvd_bit_ft"]))) < 0.002,
12914
+ "window": r["window_how"].startswith("declared") and r["min_fg_margin"]["ppg"] == min(x for x in r["ecd"]["margin_fg_ppg"] if x is not None),
12915
+ }
12916
+ failed2 = [k for k, v in c2.items() if not v]
12917
+ ok(not failed2,
12918
+ "DA2 a drilling record made by the model - drilling from 4,000 to 10,000 ft at 500 gpm and circulating at 350 gpm, its standpipe pressure the "
12919
+ "model's plus 120 psi and noise - read back while pumping: the median difference 120 psi to within 10 over 20 or more depth bins; the standpipe "
12920
+ "pressure the sum of its parts; the ECD at the bit the mud weight plus the annular loss over 0.052 TVD; a well without a survey or its "
12921
+ "declarations says what it needs" + (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
12922
+
12923
+ # -- DA3 the worked example ----------------------------------------------------------------------------------------------
12924
+ ex = HY.example()
12925
+ t = ex["trips"]
12926
+ s_hi = HY.surge_swab(ex["config"], ex["rheology"], ex["td_ft"], 180.0, lambda z: ex["tvd_td_ft"] * z / ex["td_ft"])
12927
+ s_lo = HY.surge_swab(ex["config"], ex["rheology"], ex["td_ft"], 90.0, lambda z: ex["tvd_td_ft"] * z / ex["td_ft"])
12928
+ rates = ex["by_rate"]
12929
+ c3 = {
12930
+ "example": ex["well"] == "15/9-F-10" and abs(ex["td_ft"] - 5300.07 / 0.3048) < 5.0 and "not from Volve" in ex["config"]["source"]
12931
+ and 2000 < ex["circulating"]["spp_psi"] < 5000 and ex["circulating"]["ecd_bit_ppg"] > ex["config"]["mw_ppg"],
12932
+ "rates": all(b["spp_psi"] > a["spp_psi"] and b["ecd_bit_ppg"] >= a["ecd_bit_ppg"] for a, b in zip(rates, rates[1:])),
12933
+ "surge": all(su > ex["config"]["mw_ppg"] > sw for su, sw in zip(t["surge_ppg"], t["swab_ppg"])) and s_hi["psi"] > s_lo["psi"] > 0,
12934
+ "speeds": all(v is not None and v > 0 for v in t["run_max_ft_min"] + t["pull_max_ft_min"])
12935
+ and HY.surge_swab(ex["config"], ex["rheology"], ex["td_ft"], t["run_max_ft_min"][-1], lambda z: ex["tvd_td_ft"] * z / ex["td_ft"])["surge_ppg"] <= 14.0 + 0.02,
12936
+ }
12937
+ failed3 = [k for k, v in c3.items() if not v]
12938
+ ok(not failed3,
12939
+ "DA3 the worked example, Volve 15/9-F-10's survey to its 5,300 m TD with a mud, string and hole declared for the example: the standpipe pressure "
12940
+ "and the ECD rising with the rate; surge above and swab below the mud weight at every bit depth, more at a faster trip; the fastest run keeping "
12941
+ "the surge within the declared fracture gradient" + (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
12942
+
12943
+ # -- DA4 the API, the CLI, the report, the dossier, the tab and the help -------------------------------------------------
12944
+ Users(str(Path(wsp, "users.json"))).add("v", "viewer-pass-1", "viewer"); Users(str(Path(wsp, "users.json"))).add("op", "op-pass-123", "operator")
12945
+ svc = Service(wsp, port=0, scheduler=False).start()
12946
+ base_url = svc.url.rstrip("/")
12947
+
12948
+ def opener(name, pw_):
12949
+ o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
12950
+ rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
12951
+ rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
12952
+ return o
12953
+
12954
+ def call(o, method, path, body=None):
12955
+ rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
12956
+ if method == "POST":
12957
+ rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
12958
+ try:
12959
+ with o.open(rq, timeout=120) as rr_:
12960
+ return rr_.status, json.loads(rr_.read())
12961
+ except urllib.error.HTTPError as e:
12962
+ return e.code, json.loads(e.read())
12963
+ try:
12964
+ V_, O_ = opener("v", "viewer-pass-1"), opener("op", "op-pass-123")
12965
+ s_vg, vg = call(V_, "GET", "/api/hydraulics?well=" + wid)
12966
+ s_ve, ve = call(V_, "GET", "/api/hydraulics?scene=example")
12967
+ s_vs, _ = call(V_, "POST", "/api/hydraulics/settings", {"well_id": wid, "mw_ppg": 11.2, "source": "x"})
12968
+ s_os, os_ = call(O_, "POST", "/api/hydraulics/settings", {"well_id": wid, "mw_ppg": "11.2", "r600": "62", "r300": "40", "r100": "22", "r3": "6",
12969
+ "nozzles_32": "13 13 13 13 13", "hole": "9-5/8 casing:3500:8.681; open hole::8.75", "source": "mud report (test)"})
12970
+ s_bf, _ = call(O_, "POST", "/api/hydraulics/settings", {"well_id": wid, "r600": "30", "r300": "40", "source": "x"})
12971
+ s_bh, _ = call(O_, "POST", "/api/hydraulics/settings", {"well_id": wid, "flow_gpm": 9000, "source": "x"})
12972
+ s_ns, _ = call(O_, "POST", "/api/hydraulics/settings", {"well_id": wid, "mw_ppg": 12})
12973
+ s_vw, _ = call(V_, "POST", "/api/hydraulics/write", {"well_id": wid})
12974
+ s_ow, ow = call(O_, "POST", "/api/hydraulics/write", {"well_id": wid})
12975
+ finally:
12976
+ svc.stop()
12977
+ cli_x = _sp.run([sys.executable, "-m", "gea", "hydraulics", "--example"], capture_output=True, text=True, cwd=str(pkg.parent))
12978
+ cli_s = _sp.run([sys.executable, "-m", "gea", "hydraulics", "--workspace", wsp, "--well", wid, "--flow", "450", "--fann", "600=60 300=38 100=21 3=6",
12979
+ "--source", "mud report (test)"], capture_output=True, text=True, cwd=str(pkg.parent))
12980
+ cli_b = _sp.run([sys.executable, "-m", "gea", "hydraulics", "--workspace", wsp, "--well", wid, "--fann", "600:60", "--source", "x"], capture_output=True, text=True, cwd=str(pkg.parent))
12981
+ cli_t = _sp.run([sys.executable, "-m", "gea", "hydraulics", "--workspace", wsp, "--well", wid], capture_output=True, text=True, cwd=str(pkg.parent))
12982
+ dz = DZ.build(ws, "tester", _ver, None)
12983
+ names = _zf.ZipFile(Path(ws.reports_dir, dz["path"])).namelist()
12984
+ audit = Path(ws.audit_path).read_text(encoding="utf-8")
12985
+ page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
12986
+ c4 = {
12987
+ "api": s_vg == 200 and vg["result"]["record"]["bins"] >= 20 and s_ve == 200 and ve["result"]["well"] == "15/9-F-10" and s_vs == 403 and s_os == 200
12988
+ and os_["fann"] == {"600": 62.0, "300": 40.0, "100": 22.0, "3": 6.0} and os_["nozzles_32"] == [13.0] * 5 and os_["mw_ppg"] == 11.2
12989
+ and s_bf == 400 and s_bh == 400 and s_ns == 400 and s_vw == 403 and s_ow == 200 and ow["report_id"].startswith("HYD-"),
12990
+ "cli": cli_x.returncode == 0 and "standpipe" in cli_x.stdout and "ECD at the bit" in cli_x.stdout and cli_s.returncode == 0 and "450 gpm" in cli_s.stdout
12991
+ and cli_b.returncode != 0 and "SPEED=DIAL" in (cli_b.stderr + cli_b.stdout) and cli_t.returncode == 0 and "against the record" in cli_t.stdout,
12992
+ "report": PR_read_ok(Path(ws.reports_dir, "wells", wid, "hydraulics.pdf")) and all(x in audit for x in ("hydraulics.declare", "report.hydraulics")),
12993
+ "dossier": "declarations/drillstring/hydraulics.json" in names and f"results/hydraulics/{wid}.json" in names,
12994
+ "page": all(x in page_src for x in ("VIEWS.hydraulics", "['#/hydraulics', 'Hydraulics & ECD']", "/api/hydraulics/settings", "hyChart", "hySppChart")),
12995
+ "help": not H.check("hydraulics") and H.VIEW_TOPIC.get("hydraulics") == "hydraulics",
12996
+ }
12997
+ failed4 = [k for k, v in c4.items() if not v]
12998
+ ok(not failed4,
12999
+ "DA4 the tab's data for a viewer (the well, the worked example); the declarations by an operator only, with a source, readings and rates in "
13000
+ "range; `gea hydraulics` prints the example and a well and declares the viscometer as SPEED=DIAL; the report with its PDF, audited; the "
13001
+ "signed dossier carries the declarations and the result; the tab and the help page"
13002
+ + (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
13003
+
13004
+
12824
13005
  def PR_read_ok(path) -> bool:
12825
13006
  from . import pdf_report as PR
12826
13007
  try:
@@ -12936,6 +13117,7 @@ def main() -> int:
12936
13117
  section_cx_https(tmp)
12937
13118
  section_cy_company_sign_in(tmp)
12938
13119
  section_cz_it_review(tmp)
13120
+ section_da_hydraulics(tmp)
12939
13121
  if _FAILS:
12940
13122
  print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
12941
13123
  for f in _FAILS:
@@ -278,7 +278,7 @@ def _gather(ws, well_id: Optional[str]) -> Dict[str, List[tuple]]:
278
278
  ('economics', 'invoices', 'terms.json'), ('economics', 'invoices', 'files.json'), ('drillstring', 'rig_time.json'),
279
279
  ('drillstring', 'casing.json'), ('wellpath', 'collision.json'), ('wellpath', 'survey_program.json'),
280
280
  ('completion', 'frac', 'stages.json'), ('completion', 'frac', 'settings.json'), ('geomech', 'pore_pressure.json'),
281
- ('drillstring', 'torque_drag.json'), ('economics', 'production', 'production.json')):
281
+ ('drillstring', 'torque_drag.json'), ('economics', 'production', 'production.json'), ('drillstring', 'hydraulics.json')):
282
282
  p = os.path.join(ws.path, *rel)
283
283
  if os.path.isfile(p):
284
284
  out_list.append((p, 'declarations/' + '/'.join(rel)))
@@ -351,6 +351,17 @@ def _results(ws, well_id: Optional[str]) -> List[tuple]:
351
351
  indent=1, sort_keys=True, default=str).encode('utf-8')))
352
352
  except Exception as e:
353
353
  out.append(('results/decline_not_run.txt', f'the decline curves did not run: {type(e).__name__}: {e}\n'.encode('utf-8')))
354
+ try:
355
+ from . import hydraulics as HYD
356
+ declared = (HYD._load(ws).get('wells') or {})
357
+ for wid in wells:
358
+ if wid in declared:
359
+ r = HYD.page(ws, 'workspace', wid).get('result')
360
+ if r:
361
+ out.append((f'results/hydraulics/{wid}.json', json.dumps({k: v for k, v in r.items() if k != 'measured'}, indent=1, sort_keys=True,
362
+ default=str).encode('utf-8')))
363
+ except Exception as e:
364
+ out.append(('results/hydraulics_not_run.txt', f'the hydraulics model did not run: {type(e).__name__}: {e}\n'.encode('utf-8')))
354
365
  try:
355
366
  from . import torque_drag as TND
356
367
  declared = (TND._load(ws).get('wells') or {})
@@ -0,0 +1,19 @@
1
+ # Hydraulics and ECD
2
+
3
+ > The pressures the mud makes while it circulates: the standpipe pressure part by part (surface lines, string, motor and MWD, bit, annulus), the bit's hydraulics, the equivalent circulating density at every depth against the pore pressure and fracture gradient, the surge and swab of a trip and the fastest a stand may be run or pulled, and the standpipe pressure the rig measured against the model.
4
+
5
+ **The command**: the **Hydraulics & ECD** tab: the standpipe pressure, the ECD at the bit, the smallest margin to the fracture gradient, the bit's horsepower per square inch, and the rig against the model; where the pressure goes, at the declared rate and at three others; the ECD, pore pressure and fracture gradient by depth with the surge and swab of a trip; the standpipe pressure the rig measured beside the model; the annulus section by section; the declarations (the operator role); **Write the report**. The worked example (Volve 15/9-F-10) is under Scene. From a terminal: `gea hydraulics --example`; `gea hydraulics --workspace C:\site --well SWD-1` prints a well; `--string "BHA:350:6.75:2.875; drill pipe::5:4.276" --hole "9-5/8 casing:3500:8.681; open hole::8.75" --fann "600=60 300=38 200=30 100=21 6=7 3=6" --mw 11 --flow 500 --nozzles "14 14 14 14 14" --bit 8.75 --tools 400 --source "mud report 2026-06-14, BHA report run 3"` declares it; `--write` writes the report.
6
+
7
+ **What it needs**: a directional survey (for the true vertical depths); the string from the bit up, each section with its length, outside diameter and bore; the hole from the surface down, each casing string's inside diameter to its shoe (9-5/8 in 47 lb/ft: 8.681 in; 7 in 29 lb/ft: 6.184 in; 13-3/8 in 72 lb/ft: 12.347 in) and then the open hole (the bit size, or the caliper's); the mud weight and the six-speed viscometer's dial (600 and 300 rpm at least; 100 and 3 for the annulus); the pump rate; the nozzles in 32nds of an inch; the pressure drop of the motor and MWD and of the surface lines (at a stated rate) where they are known. The window is the Pore pressure tab's for the well, or one pore pressure and one fracture gradient declared for the hole. The drilling record's standpipe pressure and pump rate, while pumping, are set against the model.
8
+
9
+ **How it is read**: the mud is a power-law fluid as API RP 13D reads it: in the pipe from the 600 and 300 readings, in the annulus from the 100 and 3. Each length of pipe and of annulus has its velocity, its effective viscosity (Metzner-Reed in the pipe, the slot in the annulus), its Reynolds number and its Fanning friction factor - laminar (16/Re in the pipe, 24/Re in the annulus), transitional from the critical Reynolds number 3470 - 1370 n, turbulent (Dodge and Metzner), blended as Churchill's method joins them - and loses 2 f rho V^2 L / D. The bit loses rho Q^2 / (2 Cd^2 A^2) with Cd 0.95 over the nozzles' total flow area. The ECD at a depth is the mud weight plus the annular loss above it over 0.052 times the true vertical depth. Surge and swab: the string closed at the bottom, the mud pushed at the pipe's peak speed (1.5 times the stand's average) times the clinging constant 0.45 plus the pipe's share of the annulus (Burkhardt); the fastest speeds keep the surge at the bit at or below the fracture gradient and the swab at or above the pore pressure. Against the rig: the median standpipe pressure and pump rate of each 250 ft of bit depth while pumping, and the model at that rate and depth; the median difference is what the declarations leave out (surface lines, a motor, a worn nozzle, the cuttings, a different mud).
10
+
11
+ **What it writes**: the declarations in `drillstring\hydraulics.json` (audit line `hydraulics.declare`), the audit line `report.hydraulics`, and the report `reports\wells\<well>\hydraulics.*` (PDF, HTML, markdown, JSON); `reports\hydraulics_example.*` for the worked example. The signed dossier carries the declarations and each declared well's result.
12
+
13
+ **The number to check**: the standpipe pressure the rig reads at the declared rate against the model's, and the difference that stays when the surface lines and the motor are declared; the ECD against a downhole pressure-while-drilling tool's where the string carries one.
14
+
15
+ **What this page will not call a measurement**: the ECD - computed from the declared mud and geometry, not read by a downhole tool; the cuttings' weight in the annulus - not added; the pipe centred in the hole and its tool joints left out; surge and swab - the steady-flow estimate at the pipe's peak speed, not the mud's gel or inertia when the pipe starts and stops.
16
+
17
+ **Sources**: API RP 13D, Rheology and Hydraulics of Oil-well Fluids (the power-law method, the pipe's and the annulus's readings, the critical Reynolds number); Zamora, Roy and Slater, "Comparing a Basic Set of Drilling Fluid Pressure-Loss Relationships to Flow-Loop and Field Data", AADE-05-NTCE-27 (the friction factor's blending); Dodge and Metzner, AIChE Journal 1959 (turbulent friction of power-law fluids); Burkhardt, "Wellbore Pressure Surges Produced by Pipe Movement", JPT, June 1961 (the clinging constant); Bourgoyne, Millheim, Chenevert and Young, Applied Drilling Engineering, SPE Textbook Series 2, 1986 (the bit's hydraulics).
18
+
19
+ Related: `gea help pore-pressure`, `gea help torque-drag`, `gea help rig-time`.
@@ -59,6 +59,7 @@ INDEX: List[tuple] = [
59
59
  ('frac-hits', 'Frac hits', "what each fracturing stage did to the pressure in the wells around it - none, poroelastic, mixed or a frac hit - the first response and the fluid pumped by then, the distance and the earthquakes beside each stage"),
60
60
  ('pore-pressure', 'Pore pressure', "the mud-weight window from a well's logs or its drilling record: the overburden, the pore pressure by Eaton from the sonic, the resistivity or the d-exponent against a normal compaction trend, the fracture gradient, against measured pressures and the mud used; L07-01 as the worked example"),
61
61
  ('torque-drag', 'Torque and drag', "the hook load and torque the drill string should take at each bit depth by the soft-string model, the broomstick of friction factors, and the friction factors that fit the rig's own trips and off-bottom rotation; Volve 15/9-F-10 as the worked example"),
62
+ ('hydraulics', 'Hydraulics and ECD', "the pressures the mud makes while it circulates - the standpipe pressure part by part, the bit, the annulus - the ECD at every depth against the pore pressure and fracture gradient, surge and swab and the fastest safe trip, and the standpipe pressure the rig measured; Volve 15/9-F-10 as the worked example"),
62
63
  ('decline', 'Decline curves', "each well's monthly production fitted by Arps's curves (the modified hyperbolic), forecast to its economic limit and valued at the SEC 12-month average price or a declared one: the EUR and the discounted cash flow"),
63
64
  ('rig-time', 'Rig time', "what the rig did each second of the drilling record - drilling, the slips, tripping, circulating - its connections timed weight to weight, its trips by speed, and the time lost against the pad's own best quarter"),
64
65
  ('invoice-check', 'The invoice cross-check', "the drilling contractor's daywork invoice, day by day, against the daily drilling reports and the drilling record at the contract's terms: hours, rates, standby, the repair allowance, depth and footage, with the dollars each difference puts in question"),
@@ -94,7 +95,7 @@ REQUIRED_LINES = ('**The command**', '**What it writes**', '**The number to chec
94
95
  VIEW_TOPIC: Dict[str, str] = {
95
96
  'home': 'start', 'wells': 'data-in', 'well': 'drift', 'live': 'patches', 'patch': 'patches', 'files': 'files', 'alarms': 'alarms',
96
97
  'approvals': 'well-tests', 'config': 'site', 'reports': 'drift', 'verify': 'start', 'survey': 'data-in', 'jobs': 'site',
97
- 'admin': 'site', 'prefs': 'site', 'search': 'start', 'welcome': 'start', 'seismic': 'seismic', 'seismic_station': 'seismic', 'track': 'seismic', 'sar': 'seismic', 'sites': 'sites', 'setup': 'setup', 'map': 'map', '3d': 'well3d', 'simulation': 'simulation', 'drillstring': 'drillstring', 'completion': 'penetrator', 'opseis': 'opseis', 'economics': 'economics', 'invoices': 'invoice-check', 'rigtime': 'rig-time', 'collision': 'collision', 'plan': 'plan', 'frac': 'frac-hits', 'porepressure': 'pore-pressure', 'torquedrag': 'torque-drag', 'decline': 'decline', 'control': 'control-room', 'wall': 'control-room', 'audit': 'audit-update', 'tools': 'tools', 'catalog': 'catalog',
98
+ 'admin': 'site', 'prefs': 'site', 'search': 'start', 'welcome': 'start', 'seismic': 'seismic', 'seismic_station': 'seismic', 'track': 'seismic', 'sar': 'seismic', 'sites': 'sites', 'setup': 'setup', 'map': 'map', '3d': 'well3d', 'simulation': 'simulation', 'drillstring': 'drillstring', 'completion': 'penetrator', 'opseis': 'opseis', 'economics': 'economics', 'invoices': 'invoice-check', 'rigtime': 'rig-time', 'collision': 'collision', 'plan': 'plan', 'frac': 'frac-hits', 'porepressure': 'pore-pressure', 'torquedrag': 'torque-drag', 'hydraulics': 'hydraulics', 'decline': 'decline', 'control': 'control-room', 'wall': 'control-room', 'audit': 'audit-update', 'tools': 'tools', 'catalog': 'catalog',
98
99
  }
99
100
 
100
101