gea-program 0.61.0__tar.gz → 0.62.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.
- {gea_program-0.61.0 → gea_program-0.62.0}/PKG-INFO +4 -2
- {gea_program-0.61.0 → gea_program-0.62.0}/README.md +3 -1
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/__init__.py +1 -1
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/__main__.py +5 -2
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/acceptance_tests.py +140 -2
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/casing_design.py +200 -34
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/declarations.py +6 -3
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/casing.md +4 -4
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/web/app.html +3 -2
- {gea_program-0.61.0 → gea_program-0.62.0}/gea_program.egg-info/PKG-INFO +4 -2
- {gea_program-0.61.0 → gea_program-0.62.0}/pyproject.toml +1 -1
- {gea_program-0.61.0 → gea_program-0.62.0}/LICENSE +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/alerts.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/backup.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/bench.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/blind_harness.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog_map.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/catalog_register.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/certificates.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/cli.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/client_reports.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/collision.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/config_versioning.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/conformance.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/control_room.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/correlation.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/dashboard.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/decline.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/deviation.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/dlis.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/dnp3.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/doctor.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/dossier.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/dossier_verify.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/drill_string.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/earth_model.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/economics.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/ed25519.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/edr.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/elevation.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/etp.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/example_register_map.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/fat_sat.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/files.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/fixtures/README.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/follower.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/forward_model.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/frac_hits.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/friction_priors.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/gamma.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/geodesy.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/geomag.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/hartip.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/IT_SECURITY.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/alarms.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/alerts.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/backup.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/catalog.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/charts.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/collision.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/company-sign-in.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/conformance.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/control-room.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/data-in.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/declare.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/decline.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/dlis.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/doctor.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/dossier.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/drift.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/economics.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/edr.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/etp.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/files.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/frac-hits.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/historian.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/https.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/hydraulics.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/instruments.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/interval.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/invoice-check.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/map.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/month-end.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/notifications.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/opseis.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/osdu.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/pad-summary.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/patches.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/penetrator.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/plan.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/pore-pressure.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/quality.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/report-history.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/rig-time.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/seismic.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/setup.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/simulation.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/site.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/sites.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/slip.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/soak.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/sra.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/start.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/structure.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/tools.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/torque-drag.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/transients.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/vibration.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/well-report.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/help/well3d.md +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/helplib.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/housekeeping.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/hydraulics.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/interval.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/invoice_check.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/jobs.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/live_ports.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/loadtest.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/modbus.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/model_card.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/month_end.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/notify.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/oidc.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/oidc_mock.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/op_seismicity.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/opcua_port.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/operator_app.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/osdu.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/pad_summary.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/patches.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/pdf_report.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/penetrator.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/permits.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/piwebapi.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/pore_pressure.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/ports.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/ppdm.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/project.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/quakeml.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reconciler.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/WMM2025.COF +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/iscwsa_rev4_example.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/iscwsa_rev5_example.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/l0701_sonic_gr.las.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/l0701_sonic_gr.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/mahoning_example.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/mud_motor_specs.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/owsg_tool_models.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/penetrator_ratings.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/seismicity_protocols.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/tool_sources.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/report_history.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/rig_state.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/sample_record.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/sbom.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seedlink.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/segy.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_array.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_film.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_response.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_track.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/seismic_watch.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/series_cache.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/service.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/service_life.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/shapefile.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/shell.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/shut_in.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/simulation.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/site_map.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/sla_report.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/slip.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/soak.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/sra.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/store_forward.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/strata_join.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/structure.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/supervisor.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/survey_view.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/telemetry.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/tls.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/tool_library.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/tool_taxonomy.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/torque_drag.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/transient.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/vibration.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/well3d.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/well_assembler.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/well_report.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/wellplan.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/wellpos.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/wits0.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/witsml.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/workspace.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea/xlsx_read.py +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea_program.egg-info/SOURCES.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.61.0 → gea_program-0.62.0}/setup.cfg +0 -0
- {gea_program-0.61.0 → gea_program-0.62.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.
|
|
3
|
+
Version: 0.62.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
|
|
@@ -689,7 +689,9 @@ Each casing string's burst, collapse and tension ratings by API TR 5C3,
|
|
|
689
689
|
from its size, weight and grade, against the loads the hole can put on it
|
|
690
690
|
- gas to the surface held by the shoe, an emptied string, the buoyed
|
|
691
691
|
weight with overpull - with the smallest safety factor and where, and the
|
|
692
|
-
gas kick each open hole below a shoe can take and still be shut in
|
|
692
|
+
gas kick each open hole below a shoe can take and still be shut in - the
|
|
693
|
+
gas a real gas at the well's pressure and temperature, with a swabbed
|
|
694
|
+
kick beside each. `gea
|
|
693
695
|
casing --example`; declared on the **Casing & kick tolerance** tab, with
|
|
694
696
|
`gea casing --workspace C:\site --well SWD-1 --strings ...`, or in the
|
|
695
697
|
declarations sheet. `gea help casing`.
|
|
@@ -650,7 +650,9 @@ Each casing string's burst, collapse and tension ratings by API TR 5C3,
|
|
|
650
650
|
from its size, weight and grade, against the loads the hole can put on it
|
|
651
651
|
- gas to the surface held by the shoe, an emptied string, the buoyed
|
|
652
652
|
weight with overpull - with the smallest safety factor and where, and the
|
|
653
|
-
gas kick each open hole below a shoe can take and still be shut in
|
|
653
|
+
gas kick each open hole below a shoe can take and still be shut in - the
|
|
654
|
+
gas a real gas at the well's pressure and temperature, with a swabbed
|
|
655
|
+
kick beside each. `gea
|
|
654
656
|
casing --example`; declared on the **Casing & kick tolerance** tab, with
|
|
655
657
|
`gea casing --workspace C:\site --well SWD-1 --strings ...`, or in the
|
|
656
658
|
declarations sheet. `gea help casing`.
|
|
@@ -653,7 +653,9 @@ def main(argv=None) -> int:
|
|
|
653
653
|
p_cs.add_argument("--strings", type=str, default=None, help="shallowest shoe first: 'surface:13-3/8:54.5:J55:0-1500:17.5:9.0; intermediate:9-5/8:47:N80:0-7000:12.25:9.8' (what:od:lb_ft:grade:top-shoe:hole_in:mud_ppg[:wall_in])")
|
|
654
654
|
for k_, h_ in (("td", "the well's TD below the deepest string, ft MD"), ("td-hole", "the hole below the deepest string, in"), ("td-mw", "the mud below the deepest string, ppg"),
|
|
655
655
|
("pp", "a pore pressure for the well when the Pore pressure tab has none, ppg"), ("fg", "a fracture gradient for the well when the Pore pressure tab has none, ppg"),
|
|
656
|
-
("kick", "kick intensity above the mud, ppg (0.5)"), ("gas", "gas gradient, psi/ft
|
|
656
|
+
("kick", "kick intensity above the mud, ppg (0.5)"), ("gas", "a fixed gas gradient, psi/ft, in place of the real gas ('none' for the real gas again)"),
|
|
657
|
+
("gas-sg", "the gas's specific gravity, air 1 (0.65)"), ("surface-temp", "the temperature at the surface, F (70)"),
|
|
658
|
+
("geothermal", "the geothermal gradient, F per 100 ft (1.5)"), ("backup", "burst backup gradient outside, psi/ft (0.465)"),
|
|
657
659
|
("evacuation", "how far the string is emptied for collapse, 0 to 1 (1: to the shoe)"), ("df-burst", "burst design factor (1.1)"),
|
|
658
660
|
("df-collapse", "collapse design factor (1.125)"), ("df-tension", "tension design factor (1.6)"), ("overpull", "overpull, klbf (100)"),
|
|
659
661
|
("bha-od", "BHA outside diameter, in"), ("bha-length", "BHA length, ft"), ("dp-od", "drill pipe outside diameter, in")):
|
|
@@ -2625,7 +2627,8 @@ def main(argv=None) -> int:
|
|
|
2625
2627
|
ws = Workspace(a.workspace) if a.workspace else None
|
|
2626
2628
|
scene = "example" if (a.example or ws is None) else "workspace"
|
|
2627
2629
|
keys_ = {"td": "td_md_ft", "td_hole": "td_hole_in", "td_mw": "td_mw_ppg", "pp": "pp_ppg", "fg": "fg_ppg", "kick": "kick_intensity_ppg",
|
|
2628
|
-
"gas": "gas_gradient_psi_ft", "
|
|
2630
|
+
"gas": "gas_gradient_psi_ft", "gas_sg": "gas_sg", "surface_temp": "surface_temp_f", "geothermal": "geothermal_f_100ft",
|
|
2631
|
+
"backup": "backup_gradient_psi_ft", "evacuation": "evacuation", "df_burst": "df_burst",
|
|
2629
2632
|
"df_collapse": "df_collapse", "df_tension": "df_tension", "overpull": "overpull_klbf", "bha_od": "bha_od_in",
|
|
2630
2633
|
"bha_length": "bha_length_ft", "dp_od": "dp_od_in"}
|
|
2631
2634
|
vals_ = {v: getattr(a, k) for k, v in keys_.items() if getattr(a, k) is not None}
|
|
@@ -13378,7 +13378,8 @@ def section_dd_casing_design(tmp: str) -> None:
|
|
|
13378
13378
|
"match its weight, a string that does not pass through the one above and a short line each answered" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
13379
13379
|
|
|
13380
13380
|
# -- DD2 the loads and the kick tolerance, by hand on the example -------------------------------------------------------------------
|
|
13381
|
-
|
|
13381
|
+
ex0 = CSG.example() # worked by hand with the fixed 0.1 psi/ft gas of the textbook method (section DE: the real gas)
|
|
13382
|
+
ex = CSG.analyse({**ex0["config"], "gas_gradient_psi_ft": 0.1}, lambda md: float(md), CSG.EXAMPLE_WINDOW)
|
|
13382
13383
|
sv, iv_, pv = ex["strings"]
|
|
13383
13384
|
win = CSG.EXAMPLE_WINDOW
|
|
13384
13385
|
|
|
@@ -13439,7 +13440,9 @@ def section_dd_casing_design(tmp: str) -> None:
|
|
|
13439
13440
|
cols_d, cols_l = DC.TABLES["casing_design"]["cols"], DC.TABLES["casing_loads"]["cols"]
|
|
13440
13441
|
rows = [["[casing_design]", *cols_d], ["", "HY-2", "surface", "13-3/8", "54.5", "J55", "0", "1500", "17.5", "9.0", "", "casing tally (test)"],
|
|
13441
13442
|
["", "HY-2", "intermediate", "9.625", "47", "N80", "0", "6000", "12.25", "10", "", "casing tally (test)"],
|
|
13442
|
-
["[casing_loads]", *cols_l], [""
|
|
13443
|
+
["[casing_loads]", *cols_l], [""] + [{"well": "HY-2", "td_md_ft": "10000", "td_hole_in": "8.5", "td_mw_ppg": "11", "pp_ppg": "9.5", "fg_ppg": "14.5",
|
|
13444
|
+
"kick_intensity_ppg": "0.5", "bha_od_in": "6.75", "bha_length_ft": "400", "dp_od_in": "5",
|
|
13445
|
+
"source": "drilling program (test)"}.get(c_, "") for c_ in cols_l]]
|
|
13443
13446
|
import csv as _csv
|
|
13444
13447
|
import io as _io
|
|
13445
13448
|
buf = _io.StringIO(); _csv.writer(buf).writerows(rows); sheet.write_text(buf.getvalue(), encoding="utf-8")
|
|
@@ -13526,6 +13529,140 @@ def section_dd_casing_design(tmp: str) -> None:
|
|
|
13526
13529
|
"RESOLVED and says how far it reaches" + (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
|
|
13527
13530
|
|
|
13528
13531
|
|
|
13532
|
+
def section_de_real_gas(tmp: str) -> None:
|
|
13533
|
+
"""Section DE - the kick and the burst load on a real gas: Sutton's pseudocritical properties and Dranchuk and
|
|
13534
|
+
Abou-Kassem's z against an independent implementation; the gas's density, and a column of it integrated up the well
|
|
13535
|
+
along the geothermal temperature; the kick tolerance with the gas's gradient at the bubble's own pressure and
|
|
13536
|
+
temperature and the volume carried between shoe and bottom by p V / z T, and a swabbed kick beside it; a fixed
|
|
13537
|
+
gradient still taken when declared, and the real gas back with 'none'."""
|
|
13538
|
+
import subprocess as _sp
|
|
13539
|
+
from . import casing_design as CSG
|
|
13540
|
+
from . import declarations as DC
|
|
13541
|
+
from . import helplib as H
|
|
13542
|
+
from .workspace import Workspace
|
|
13543
|
+
pkg = Path(__file__).parent
|
|
13544
|
+
|
|
13545
|
+
# -- DE1 the gas's properties ------------------------------------------------------------------------------------------------
|
|
13546
|
+
# reference values from pyrestoolbox 3.8.9 (gas_z / gas_den, zmethod DAK, cmethod SUT), an independent open-source implementation
|
|
13547
|
+
ref = [(3000, 0.65, 200, 0.9048073771833917, 8.819352273478), (6000, 0.65, 250, 1.0923431854133714, 13.58107045798391),
|
|
13548
|
+
(1000, 0.8, 120, 0.8335178869315637, 4.469708326242926), (10000, 0.7, 300, 1.3920860511301727, 17.868657631013313),
|
|
13549
|
+
(500, 0.6, 80, 0.9330965197803314, 1.6082418312797764)]
|
|
13550
|
+
got = [CSG.gas_state(p_ - CSG.ATM, f_, sg_) for p_, sg_, f_, _, _ in ref]
|
|
13551
|
+
tpc, ppc = CSG.pseudo_critical(0.65)
|
|
13552
|
+
tpc8, ppc8 = CSG.pseudo_critical(0.8)
|
|
13553
|
+
low = CSG.z_factor(1.5, 0.01)
|
|
13554
|
+
c1 = {
|
|
13555
|
+
"sutton": abs(tpc - 365.11) < 0.01 and abs(ppc - 670.129) < 0.01 and abs(tpc8 - 401.44) < 0.01 and abs(ppc8 - 649.696) < 0.01,
|
|
13556
|
+
"z": all(abs(g_["z"] - r_[3]) < 1e-5 for g_, r_ in zip(got, ref)),
|
|
13557
|
+
"density": all(abs(g_["rho_lb_ft3"] - r_[4]) / r_[4] < 1e-5 for g_, r_ in zip(got, ref)),
|
|
13558
|
+
"gradient": all(abs(g_["psi_ft"] - g_["rho_lb_ft3"] / 144.0) < 1e-12 for g_ in got),
|
|
13559
|
+
"ideal_limit": abs(low - 1.0) < 0.005 and CSG.z_factor(1.5, 0.0) == 1.0,
|
|
13560
|
+
"chart_shape": CSG.z_factor(1.5, 2.0) < CSG.z_factor(1.5, 1.0) < 1.0 and CSG.z_factor(1.5, 10.0) > 1.0 and CSG.z_factor(1.2, 2.0) < CSG.z_factor(2.0, 2.0),
|
|
13561
|
+
}
|
|
13562
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
13563
|
+
ok(not failed1,
|
|
13564
|
+
"DE1 the gas: Sutton's pseudocritical temperature and pressure (365.11 R and 670.13 psia for a 0.65 gas), Dranchuk and Abou-Kassem's z and "
|
|
13565
|
+
"the density p M / z R T within 1e-5 of an independent implementation (pyrestoolbox) from 500 to 10,000 psia, 80 to 300 F, gravities 0.6 "
|
|
13566
|
+
"to 0.8; z to 1 as the pressure falls, the Standing-Katz chart's dip and rise" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
13567
|
+
|
|
13568
|
+
# -- DE2 a column of gas up the well ------------------------------------------------------------------------------------------
|
|
13569
|
+
cfg = {**CSG.DEFAULTS}
|
|
13570
|
+
p0 = 0.052 * 11.0 * 10000.0
|
|
13571
|
+
top = CSG.gas_column(cfg, p0, 10000.0, 0.0)
|
|
13572
|
+
p_, z_ = p0, 10000.0 # a fine Euler integration of the same gas, 1 ft at a time
|
|
13573
|
+
while z_ > 0.0:
|
|
13574
|
+
p_ -= CSG.gas_state(p_, CSG.temperature_f(cfg, z_ - 0.5), 0.65)["psi_ft"]
|
|
13575
|
+
z_ -= 1.0
|
|
13576
|
+
hot = CSG.gas_column({**cfg, "geothermal_f_100ft": 2.5}, p0, 10000.0, 0.0)
|
|
13577
|
+
heavy = CSG.gas_column({**cfg, "gas_sg": 0.9}, p0, 10000.0, 0.0)
|
|
13578
|
+
fixed = CSG.gas_column({**cfg, "gas_gradient_psi_ft": 0.1}, p0, 10000.0, 0.0)
|
|
13579
|
+
c2 = {
|
|
13580
|
+
"integrated": abs(top - p_) < 0.5 and abs(top - 4658.6) < 1.0,
|
|
13581
|
+
"hotter_lighter": hot > top and heavy < top,
|
|
13582
|
+
"fixed": abs(fixed - (p0 - 1000.0)) < 1e-9,
|
|
13583
|
+
"temperature": CSG.temperature_f(cfg, 0.0) == 70.0 and abs(CSG.temperature_f(cfg, 10000.0) - 220.0) < 1e-9,
|
|
13584
|
+
}
|
|
13585
|
+
failed2 = [k for k, v in c2.items() if not v]
|
|
13586
|
+
ok(not failed2,
|
|
13587
|
+
"DE2 a column of real gas from 5,720 psi at 10,000 ft (an 11 ppg pore pressure) integrated to the surface along 70 F rising 1.5 F per 100 ft: "
|
|
13588
|
+
"4,659 psi at the surface (an average 0.106 psi/ft), as a 1 ft step integration gives; a hotter well's gas lighter, a heavier gas heavier; a "
|
|
13589
|
+
"declared 0.1 psi/ft taken as it is" + (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
13590
|
+
|
|
13591
|
+
# -- DE3 the kick tolerance and the burst load on the real gas -----------------------------------------------------------------
|
|
13592
|
+
ex = CSG.example()
|
|
13593
|
+
exf = CSG.analyse({**ex["config"], "gas_gradient_psi_ft": 0.1}, lambda md: float(md), CSG.EXAMPLE_WINDOW)
|
|
13594
|
+
k_, kf = ex["kicks"][1], exf["kicks"][1]
|
|
13595
|
+
win = CSG.EXAMPLE_WINDOW
|
|
13596
|
+
fg_s = float(np.interp(7000.0, win["tvd_ft"], win["fg_ppg"]))
|
|
13597
|
+
p_frac, p_bot = 0.052 * fg_s * 7000.0, 0.052 * k_["kick_ppg"] * 10000.0
|
|
13598
|
+
maasp, sidpp = 0.052 * (fg_s - 11.5) * 7000.0, 0.052 * (k_["kick_ppg"] - 11.5) * 10000.0
|
|
13599
|
+
gm = 0.052 * 11.5
|
|
13600
|
+
h_b = (maasp - sidpp) / (gm - k_["gas_gradient_bottom_psi_ft"])
|
|
13601
|
+
st_b = CSG.gas_state(p_bot - k_["gas_gradient_bottom_psi_ft"] * h_b / 2, CSG.temperature_f(ex["config"], 10000.0 - h_b / 2), 0.65)
|
|
13602
|
+
h_s = (maasp - sidpp) / (gm - k_["gas_gradient_shoe_psi_ft"])
|
|
13603
|
+
st_s = CSG.gas_state(p_frac + k_["gas_gradient_shoe_psi_ft"] * h_s / 2, CSG.temperature_f(ex["config"], 7000.0 + h_s / 2), 0.65)
|
|
13604
|
+
carried = k_["volume_at_shoe_bbl"] * (st_s["p_psia"] / (st_s["z"] * st_s["t_r"])) / (st_b["p_psia"] / (st_b["z"] * st_b["t_r"]))
|
|
13605
|
+
sv = ex["strings"][0]
|
|
13606
|
+
top_load = CSG.gas_column(ex["config"], 0.052 * float(np.interp(1500.0, win["tvd_ft"], win["fg_ppg"])) * 1500.0, 1500.0, 0.0)
|
|
13607
|
+
c3 = {
|
|
13608
|
+
"bubble_gradient": abs(k_["gas_gradient_bottom_psi_ft"] - st_b["psi_ft"]) < 1e-5 and abs(k_["gas_gradient_shoe_psi_ft"] - st_s["psi_ft"]) < 1e-5
|
|
13609
|
+
and k_["gas_gradient_bottom_psi_ft"] > k_["gas_gradient_shoe_psi_ft"],
|
|
13610
|
+
"heights": abs(k_["height_ft"] - h_b) < 0.2 and abs(k_["height_shoe_ft"] - h_s) < 0.2,
|
|
13611
|
+
"carried": abs(k_["volume_shoe_as_bottom_bbl"] - carried) < 0.15 and "real-gas law" in k_["carried_by"] and "Boyle" in kf["carried_by"],
|
|
13612
|
+
"z_t": k_["z_bottom"] > 0 and abs(k_["temp_bottom_f"] - CSG.temperature_f(ex["config"], 10000.0 - h_b / 2)) < 0.1,
|
|
13613
|
+
"swabbed": all(k["swabbed"]["kick_ppg"] == k["mw_ppg"] and k["swabbed"]["volume_bbl"] > k["volume_bbl"] for k in ex["kicks"]),
|
|
13614
|
+
"burst_real": abs(sv["rows"][0]["burst_net_psi"] - top_load) <= 1.0 and sv["rows"][0]["burst_limited_by_shoe"]
|
|
13615
|
+
and "real gas" in sv["gas"] and "0.1 psi/ft" in exf["strings"][0]["gas"],
|
|
13616
|
+
}
|
|
13617
|
+
failed3 = [k for k, v in c3.items() if not v]
|
|
13618
|
+
ok(not failed3,
|
|
13619
|
+
"DE3 on the worked example: the gas's gradient in the bubble at its own middle's pressure and temperature, heavier on bottom than at the shoe; "
|
|
13620
|
+
"the bubble's heights from them; the shoe's volume carried to the bottom by p V / z T (Boyle's law with a fixed gradient); a swabbed kick "
|
|
13621
|
+
"(no underbalance) beside each, larger; the burst load at the top the real gas's column from the fracture pressure at the shoe"
|
|
13622
|
+
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
13623
|
+
|
|
13624
|
+
# -- DE4 declared --------------------------------------------------------------------------------------------------------------
|
|
13625
|
+
d = Path(tmp, "realgas"); d.mkdir()
|
|
13626
|
+
wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad 3", actor="tester")
|
|
13627
|
+
wid = ws.add_well_catalog("volve_f12_f14_production_excerpt", "15/9-F-12", 10000.0, actor="tester")["id"]
|
|
13628
|
+
prog = "surface:13-3/8:54.5:J55:0-1500:17.5:9.0; intermediate:9-5/8:47:N80:0-7000:12.25:9.8"
|
|
13629
|
+
run = lambda *a: _sp.run([sys.executable, "-m", "gea", "casing", "--workspace", wsp, "--well", wid, *a], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
13630
|
+
r1 = run("--strings", prog, "--td", "10000", "--td-hole", "8.5", "--td-mw", "11.5", "--pp", "10", "--fg", "15", "--gas-sg", "0.7", "--surface-temp", "80",
|
|
13631
|
+
"--geothermal", "1.2", "--bha-od", "6.5", "--bha-length", "600", "--dp-od", "5", "--source", "test")
|
|
13632
|
+
c_a = CSG.well_config(ws, wid)
|
|
13633
|
+
r2 = run("--gas", "0.1", "--source", "test")
|
|
13634
|
+
c_b = CSG.well_config(ws, wid)
|
|
13635
|
+
r3 = run("--gas", "none", "--source", "test")
|
|
13636
|
+
c_c = CSG.well_config(ws, wid)
|
|
13637
|
+
pr = run()
|
|
13638
|
+
cols = DC.TABLES["casing_loads"]["cols"]
|
|
13639
|
+
sheet = "\n".join([",".join(["[casing_loads]", *cols]), ",".join([""] + [{"well": wid, "gas_sg": "0.75", "surface_temp_f": "60", "geothermal_f_100ft": "1.8",
|
|
13640
|
+
"source": "drilling program (test)"}.get(c_, "") for c_ in cols])])
|
|
13641
|
+
ps = DC.apply(ws, sheet, "tester", str(d), write=True)
|
|
13642
|
+
c_d = CSG.well_config(ws, wid)
|
|
13643
|
+
try:
|
|
13644
|
+
CSG.set_well(ws, "tester", wid, "x", geothermal_f_100ft=9)
|
|
13645
|
+
lim = ""
|
|
13646
|
+
except ValueError as e:
|
|
13647
|
+
lim = str(e)
|
|
13648
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
13649
|
+
help_txt = H.page("casing") or ""
|
|
13650
|
+
c4 = {
|
|
13651
|
+
"cli": r1.returncode == 0 and c_a["gas_sg"] == 0.7 and c_a["surface_temp_f"] == 80.0 and c_a["geothermal_f_100ft"] == 1.2 and c_a["gas_gradient_psi_ft"] is None,
|
|
13652
|
+
"fixed_and_back": r2.returncode == 0 and c_b["gas_gradient_psi_ft"] == 0.1 and r3.returncode == 0 and c_c["gas_gradient_psi_ft"] is None,
|
|
13653
|
+
"printed": pr.returncode == 0 and "specific gravity 0.7 as a real gas" in pr.stdout and "swabbed (no underbalance)" in pr.stdout,
|
|
13654
|
+
"sheet": ps["applied"] and c_d["gas_sg"] == 0.75 and c_d["surface_temp_f"] == 60.0 and c_d["geothermal_f_100ft"] == 1.8,
|
|
13655
|
+
"limits": "geothermal_f_100ft must be between" in lim,
|
|
13656
|
+
"page_help": "name=\"gas_gradient_psi_ft\"" in page_src and "'gas_sg', 'Gas gravity'" in page_src and "Swabbed (bbl)" in page_src
|
|
13657
|
+
and not H.check("casing") and "Dranchuk and Abou-Kassem" in help_txt and "--gas none" in help_txt,
|
|
13658
|
+
}
|
|
13659
|
+
failed4 = [k for k, v in c4.items() if not v]
|
|
13660
|
+
ok(not failed4,
|
|
13661
|
+
"DE4 the gas declared from the command line (its gravity, the surface temperature, the geothermal gradient), a fixed gradient taken in its place "
|
|
13662
|
+
"and the real gas back with 'none'; the declarations sheet's [casing_loads] carries them; out of range answered; the tab, its kick table and "
|
|
13663
|
+
"the help" + (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
|
|
13664
|
+
|
|
13665
|
+
|
|
13529
13666
|
def PR_read_ok(path) -> bool:
|
|
13530
13667
|
from . import pdf_report as PR
|
|
13531
13668
|
try:
|
|
@@ -13645,6 +13782,7 @@ def main() -> int:
|
|
|
13645
13782
|
section_db_declarations_engineering(tmp)
|
|
13646
13783
|
section_dc_every_tab(tmp)
|
|
13647
13784
|
section_dd_casing_design(tmp)
|
|
13785
|
+
section_de_real_gas(tmp)
|
|
13648
13786
|
if _FAILS:
|
|
13649
13787
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
13650
13788
|
for f in _FAILS:
|
|
@@ -15,9 +15,12 @@ outside diameter D, the wall t and the grade's minimum yield Yp:
|
|
|
15
15
|
The loads are the textbook ones (Bourgoyne et al., Applied Drilling Engineering, ch. 7; Rabia, Well Engineering and
|
|
16
16
|
Construction), on the true vertical depth z:
|
|
17
17
|
|
|
18
|
-
- burst: inside, gas to the surface from the deepest pore pressure the hole below the shoe reaches
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
- burst: inside, gas to the surface from the deepest pore pressure the hole below the shoe reaches, no more than the
|
|
19
|
+
fracture pressure at the shoe less the gas column above it when there is open hole below; outside, a backup of
|
|
20
|
+
formation water (0.465 psi/ft unless declared). The gas is a real gas: its density p M / (z R T) at each depth's
|
|
21
|
+
pressure and temperature (the surface temperature and the geothermal gradient), z by Dranchuk and Abou-Kassem's fit
|
|
22
|
+
of the Standing-Katz chart on Sutton's pseudocritical properties for the declared gas gravity, the column integrated
|
|
23
|
+
up the well; a gas gradient declared in psi/ft replaces it;
|
|
21
24
|
- collapse: outside, the mud the string was run in; inside, the string emptied (or emptied to a declared fraction of
|
|
22
25
|
its depth) with the next hole's mud below the level;
|
|
23
26
|
- tension: the string's buoyed weight hanging from its top (the buoyancy factor 1 - MW/65.5), checked against the
|
|
@@ -62,10 +65,11 @@ WALLS: Dict[float, Dict[float, float]] = {
|
|
|
62
65
|
20.0: {94.0: 0.438, 106.5: 0.500, 133.0: 0.635},
|
|
63
66
|
}
|
|
64
67
|
DEFAULTS = {'strings': [], 'td_md_ft': None, 'td_hole_in': None, 'td_mw_ppg': None, 'pp_ppg': None, 'fg_ppg': None, 'kick_intensity_ppg': 0.5,
|
|
65
|
-
'gas_gradient_psi_ft': 0.1, 'backup_gradient_psi_ft': 0.465, 'evacuation': 1.0, 'df_burst': 1.1, 'df_collapse': 1.125, 'df_tension': 1.6,
|
|
68
|
+
'gas_gradient_psi_ft': None, 'gas_sg': 0.65, 'surface_temp_f': 70.0, 'geothermal_f_100ft': 1.5, 'backup_gradient_psi_ft': 0.465, 'evacuation': 1.0, 'df_burst': 1.1, 'df_collapse': 1.125, 'df_tension': 1.6,
|
|
66
69
|
'overpull_klbf': 100.0, 'bha_od_in': None, 'bha_length_ft': None, 'dp_od_in': None, 'step_ft': 100.0}
|
|
67
70
|
LIMITS = {'td_md_ft': (100.0, 40000.0), 'td_hole_in': (2.0, 40.0), 'td_mw_ppg': (6.0, 22.0), 'pp_ppg': (6.0, 22.0), 'fg_ppg': (6.0, 25.0),
|
|
68
|
-
'kick_intensity_ppg': (0.0, 5.0), 'gas_gradient_psi_ft': (0.0, 0.3), '
|
|
71
|
+
'kick_intensity_ppg': (0.0, 5.0), 'gas_gradient_psi_ft': (0.0, 0.3), 'gas_sg': (0.55, 1.5), 'surface_temp_f': (-20.0, 150.0),
|
|
72
|
+
'geothermal_f_100ft': (0.5, 4.0), 'backup_gradient_psi_ft': (0.0, 0.6), 'evacuation': (0.0, 1.0),
|
|
69
73
|
'df_burst': (1.0, 2.0), 'df_collapse': (0.8, 2.0), 'df_tension': (1.0, 3.0), 'overpull_klbf': (0.0, 1000.0), 'bha_od_in': (2.0, 20.0),
|
|
70
74
|
'bha_length_ft': (0.0, 5000.0), 'dp_od_in': (2.0, 10.0), 'step_ft': (20.0, 1000.0)}
|
|
71
75
|
NOT_A_MEASUREMENT = [
|
|
@@ -74,8 +78,8 @@ NOT_A_MEASUREMENT = [
|
|
|
74
78
|
"the loads: the textbook cases on the declared mud and the pore pressure and fracture gradient (the Pore pressure tab's, or declared), "
|
|
75
79
|
"not a well's measured pressures; the temperature and the cement are not in them",
|
|
76
80
|
"tension: the buoyed weight on the measured length, hanging straight; the drag of a deviated hole and the bending in a dogleg are not added",
|
|
77
|
-
"kick tolerance: a single bubble of gas
|
|
78
|
-
"not one it has taken",
|
|
81
|
+
"kick tolerance: a single bubble of gas, a sweet natural gas of the declared gravity (no correction for CO2, H2S or nitrogen), at the "
|
|
82
|
+
"declared geothermal temperature, not the circulating one; the volume a well can take, not one it has taken",
|
|
79
83
|
]
|
|
80
84
|
BBL_PER_IN2_FT = 1.0 / 1029.4 # annular capacity: (D^2 - d^2) / 1029.4 bbl per ft
|
|
81
85
|
|
|
@@ -291,6 +295,120 @@ def set_well(ws, actor: str, well_id: str, source: str = '', strings=None, **val
|
|
|
291
295
|
return well_config(ws, well_id)
|
|
292
296
|
|
|
293
297
|
|
|
298
|
+
# -- the gas: a real gas at the well's pressure and temperature -----------------------------------------------------------------
|
|
299
|
+
SUTTON_TPC = (169.2, 349.5, -74.0) # deg R: Tpc = a + b sg + c sg^2 (Sutton, SPE 14265, 1985)
|
|
300
|
+
SUTTON_PPC = (756.8, -131.0, -3.6) # psia
|
|
301
|
+
DAK = (0.3265, -1.0700, -0.5339, 0.01569, -0.05165, 0.5475, -0.7361, 0.1844, 0.1056, 0.6134, 0.7210) # Dranchuk and Abou-Kassem, 1975
|
|
302
|
+
R_GAS = 10.7316 # psia ft3 / (lb-mol deg R)
|
|
303
|
+
M_AIR = 28.97 # lb / lb-mol
|
|
304
|
+
ATM = 14.696 # psi
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def pseudo_critical(sg: float) -> Tuple[float, float]:
|
|
308
|
+
"""Sutton's pseudocritical temperature (deg R) and pressure (psia) of a sweet natural gas of specific gravity sg."""
|
|
309
|
+
return (SUTTON_TPC[0] + SUTTON_TPC[1] * sg + SUTTON_TPC[2] * sg * sg, SUTTON_PPC[0] + SUTTON_PPC[1] * sg + SUTTON_PPC[2] * sg * sg)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def z_factor(tpr: float, ppr: float) -> float:
|
|
313
|
+
"""The gas deviation factor by Dranchuk and Abou-Kassem's fit of the Standing-Katz chart: the reduced density rho_r
|
|
314
|
+
solving 0 = 1 + C1 rho + C2 rho^2 - C3 rho^5 + C4 (1 + A11 rho^2) rho^2 exp(-A11 rho^2) - 0.27 Ppr / (Tpr rho),
|
|
315
|
+
found by Newton's method from the ideal gas; z = 0.27 Ppr / (Tpr rho_r)."""
|
|
316
|
+
if ppr <= 1e-9:
|
|
317
|
+
return 1.0
|
|
318
|
+
A = DAK
|
|
319
|
+
c1 = A[0] + A[1] / tpr + A[2] / tpr ** 3 + A[3] / tpr ** 4 + A[4] / tpr ** 5
|
|
320
|
+
c2 = A[5] + A[6] / tpr + A[7] / tpr ** 2
|
|
321
|
+
c3 = A[8] * (A[6] / tpr + A[7] / tpr ** 2)
|
|
322
|
+
c4 = A[9] / tpr ** 3
|
|
323
|
+
|
|
324
|
+
def f(r):
|
|
325
|
+
e = math.exp(-A[10] * r * r)
|
|
326
|
+
return 1 + c1 * r + c2 * r * r - c3 * r ** 5 + c4 * (1 + A[10] * r * r) * r * r * e - 0.27 * ppr / (tpr * r)
|
|
327
|
+
|
|
328
|
+
def df(r):
|
|
329
|
+
e = math.exp(-A[10] * r * r)
|
|
330
|
+
return (c1 + 2 * c2 * r - 5 * c3 * r ** 4 + 2 * c4 * r * e * (1 + 2 * A[10] * r * r - A[10] * r * r * (1 + A[10] * r * r))
|
|
331
|
+
+ 0.27 * ppr / (tpr * r * r))
|
|
332
|
+
r = 0.27 * ppr / tpr
|
|
333
|
+
for _ in range(100):
|
|
334
|
+
step = f(r) / df(r)
|
|
335
|
+
nr = r - step
|
|
336
|
+
if nr <= 0:
|
|
337
|
+
nr = r / 2
|
|
338
|
+
if abs(nr - r) < 1e-12:
|
|
339
|
+
r = nr
|
|
340
|
+
break
|
|
341
|
+
r = nr
|
|
342
|
+
if not (math.isfinite(r) and r > 0 and abs(f(r)) < 1e-8):
|
|
343
|
+
lo, hi = 1e-6, 3.0 # the gas root lies where f rises through zero; bisect on it
|
|
344
|
+
for _ in range(200):
|
|
345
|
+
mid = 0.5 * (lo + hi)
|
|
346
|
+
if f(mid) < 0:
|
|
347
|
+
lo = mid
|
|
348
|
+
else:
|
|
349
|
+
hi = mid
|
|
350
|
+
r = 0.5 * (lo + hi)
|
|
351
|
+
return 0.27 * ppr / (tpr * r)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def gas_state(p_psig: float, t_f: float, sg: float) -> dict:
|
|
355
|
+
"""The gas at a gauge pressure and a temperature: z, its density (lb/ft3, ppg) and its gradient (psi/ft)."""
|
|
356
|
+
tpc, ppc = pseudo_critical(sg)
|
|
357
|
+
pa, tr = max(0.0, p_psig) + ATM, t_f + 459.67
|
|
358
|
+
z = z_factor(tr / tpc, pa / ppc)
|
|
359
|
+
rho = pa * M_AIR * sg / (z * R_GAS * tr)
|
|
360
|
+
return {'z': z, 'rho_lb_ft3': rho, 'ppg': rho / 7.48052, 'psi_ft': rho / 144.0, 'p_psia': pa, 't_r': tr}
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def temperature_f(cfg: dict, tvd_ft: float) -> float:
|
|
364
|
+
return float(cfg['surface_temp_f']) + float(cfg['geothermal_f_100ft']) * max(0.0, tvd_ft) / 100.0
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
def real_gas(cfg: dict) -> bool:
|
|
368
|
+
return cfg.get('gas_gradient_psi_ft') in (None, '')
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def gas_column(cfg: dict, p0_psig: float, z0_ft: float, z_ft: float, step_ft: float = 50.0) -> float:
|
|
372
|
+
"""The pressure at z_ft in a column of gas whose pressure at z0_ft is p0_psig: the declared gradient, or the real gas's
|
|
373
|
+
own weight integrated along the geothermal temperature (fourth-order Runge-Kutta, 50 ft steps)."""
|
|
374
|
+
if not real_gas(cfg):
|
|
375
|
+
return p0_psig - float(cfg['gas_gradient_psi_ft']) * (z0_ft - z_ft)
|
|
376
|
+
sg = float(cfg['gas_sg'])
|
|
377
|
+
n = max(1, int(math.ceil(abs(z0_ft - z_ft) / step_ft)))
|
|
378
|
+
h = (z_ft - z0_ft) / n
|
|
379
|
+
|
|
380
|
+
def g(z, p):
|
|
381
|
+
return gas_state(p, temperature_f(cfg, z), sg)['psi_ft']
|
|
382
|
+
z, p = z0_ft, p0_psig
|
|
383
|
+
for _ in range(n):
|
|
384
|
+
k1 = g(z, p); k2 = g(z + h / 2, p + h * k1 / 2); k3 = g(z + h / 2, p + h * k2 / 2); k4 = g(z + h, p + h * k3)
|
|
385
|
+
p += h * (k1 + 2 * k2 + 2 * k3 + k4) / 6
|
|
386
|
+
z += h
|
|
387
|
+
return p
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def _bubble(cfg: dict, gm: float, maasp: float, sidpp: float, p_anchor: float, z_anchor: float, down: bool) -> dict:
|
|
391
|
+
"""A gas bubble whose top (down=True: at the shoe, the anchor) or bottom (down=False: at the bottom of the hole) is at the
|
|
392
|
+
anchor pressure: its height H = (MAASP - SIDPP) / (mud gradient - gas gradient), the gas gradient taken at the bubble's
|
|
393
|
+
middle, found by fixed point; its middle's pressure, temperature and z."""
|
|
394
|
+
gg = float(cfg['gas_gradient_psi_ft']) if not real_gas(cfg) else 0.1
|
|
395
|
+
st = None
|
|
396
|
+
for _ in range(30):
|
|
397
|
+
h = (maasp - sidpp) / (gm - gg) if gm > gg else -1.0
|
|
398
|
+
hm = max(0.0, h) / 2
|
|
399
|
+
zm = z_anchor + hm if down else z_anchor - hm
|
|
400
|
+
pm = p_anchor + gg * hm if down else p_anchor - gg * hm
|
|
401
|
+
if not real_gas(cfg):
|
|
402
|
+
break
|
|
403
|
+
st = gas_state(pm, temperature_f(cfg, zm), float(cfg['gas_sg']))
|
|
404
|
+
if abs(st['psi_ft'] - gg) < 1e-7:
|
|
405
|
+
gg = st['psi_ft']
|
|
406
|
+
break
|
|
407
|
+
gg = st['psi_ft']
|
|
408
|
+
h = (maasp - sidpp) / (gm - gg) if gm > gg else -1.0
|
|
409
|
+
return {'h': h, 'gg': gg, 'mid_p_psig': pm, 'mid_tvd_ft': zm, 'state': st}
|
|
410
|
+
|
|
411
|
+
|
|
294
412
|
# -- the loads -------------------------------------------------------------------------------------------------------------------
|
|
295
413
|
def _section_below(cfg: dict, i: int) -> Optional[dict]:
|
|
296
414
|
"""The hole drilled below string i's shoe: to the next string's shoe (its hole, its mud), or for the deepest to the
|
|
@@ -318,9 +436,28 @@ def _fg(win, tvd: float) -> Optional[float]:
|
|
|
318
436
|
return _at(win, tvd)[1]
|
|
319
437
|
|
|
320
438
|
|
|
439
|
+
def gas_how(cfg: dict) -> str:
|
|
440
|
+
if real_gas(cfg):
|
|
441
|
+
return (f"a natural gas of specific gravity {float(cfg['gas_sg']):g} as a real gas (z by Dranchuk and Abou-Kassem, pseudocritical properties by "
|
|
442
|
+
f"Sutton) at the well's temperature, {float(cfg['surface_temp_f']):g} F at the surface rising {float(cfg['geothermal_f_100ft']):g} F per 100 ft")
|
|
443
|
+
return f"a gas gradient of {float(cfg['gas_gradient_psi_ft']):g} psi/ft as declared"
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def _column_at(cfg: dict, p0: float, z0: float, zs: List[float]) -> List[float]:
|
|
447
|
+
"""The gas column's pressure at each of the TVDs zs (shallower than z0), from p0 at z0: integrated once, upward, through them."""
|
|
448
|
+
order = sorted(range(len(zs)), key=lambda k: -zs[k])
|
|
449
|
+
out = [0.0] * len(zs)
|
|
450
|
+
z, p = z0, p0
|
|
451
|
+
for k in order:
|
|
452
|
+
p = gas_column(cfg, p, z, min(zs[k], z)) if zs[k] < z else p
|
|
453
|
+
z = min(zs[k], z)
|
|
454
|
+
out[k] = p if zs[k] <= z0 else p0
|
|
455
|
+
return out
|
|
456
|
+
|
|
457
|
+
|
|
321
458
|
def string_loads(cfg: dict, i: int, tvd_of, win) -> dict:
|
|
322
459
|
s = cfg['strings'][i]
|
|
323
|
-
|
|
460
|
+
gb = float(cfg['backup_gradient_psi_ft'])
|
|
324
461
|
below = _section_below(cfg, i)
|
|
325
462
|
ds = tvd_of(s['shoe_md_ft'])
|
|
326
463
|
open_below = below is not None
|
|
@@ -341,12 +478,15 @@ def string_loads(cfg: dict, i: int, tvd_of, win) -> dict:
|
|
|
341
478
|
mds = sorted(set([s['top_md_ft'], s['shoe_md_ft']] + [float(x) for x in np.arange(math.ceil(s['top_md_ft'] / step) * step, s['shoe_md_ft'], step)]))
|
|
342
479
|
rows = []
|
|
343
480
|
level = float(cfg['evacuation']) * ds
|
|
344
|
-
for md in mds
|
|
345
|
-
|
|
346
|
-
|
|
481
|
+
zs = [tvd_of(md) for md in mds]
|
|
482
|
+
col_res = _column_at(cfg, p_res, dres, zs)
|
|
483
|
+
col_frac = _column_at(cfg, p_frac, ds, zs) if p_frac is not None else None
|
|
484
|
+
for k, md in enumerate(mds):
|
|
485
|
+
z = zs[k]
|
|
486
|
+
pin_b = col_res[k]
|
|
347
487
|
limited = False
|
|
348
|
-
if
|
|
349
|
-
pin_b, limited =
|
|
488
|
+
if col_frac is not None and col_frac[k] < pin_b:
|
|
489
|
+
pin_b, limited = col_frac[k], True
|
|
350
490
|
pout_b = gb * z
|
|
351
491
|
net_b = pin_b - pout_b
|
|
352
492
|
pout_c = 0.052 * s['mw_ppg'] * z
|
|
@@ -380,6 +520,7 @@ def string_loads(cfg: dict, i: int, tvd_of, win) -> dict:
|
|
|
380
520
|
return {'string': s, 'below': below, 'shoe_tvd_ft': round(ds, 1), 'reservoir_tvd_ft': round(dres, 1), 'pore_ppg': round(pp, 3), 'pore_how': pp_how,
|
|
381
521
|
'fg_shoe_ppg': round(fg_shoe, 3) if fg_shoe is not None else None, 'mud_inside_ppg': mw_in, 'buoyancy_factor': round(bf, 4),
|
|
382
522
|
'rows': rows, 'checks': checks, 'ok': all(c['ok'] for c in checks.values()),
|
|
523
|
+
'gas': gas_how(cfg),
|
|
383
524
|
'burst_case': ('gas to the surface from the pore pressure at the bottom of the hole below (' + pp_how + ')'
|
|
384
525
|
+ (', no more than the fracture pressure at the shoe less the gas above it' if p_frac is not None else '')
|
|
385
526
|
if open_below else 'gas to the surface from the pore pressure at the shoe (' + pp_how + ')'),
|
|
@@ -439,33 +580,46 @@ def kick_tolerance(cfg: dict, i: int, tvd_of, win) -> Optional[dict]:
|
|
|
439
580
|
if fg is None:
|
|
440
581
|
out.update({'status': 'NOT KNOWN', 'detail': 'the fracture gradient at the shoe is not known (the Pore pressure tab, or declare one)'})
|
|
441
582
|
return out
|
|
442
|
-
gm
|
|
583
|
+
gm = 0.052 * mw
|
|
443
584
|
maasp = 0.052 * (fg - mw) * ds
|
|
444
585
|
sidpp = 0.052 * (pp - mw) * dt
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
586
|
+
p_frac, p_bot = 0.052 * fg * ds, 0.052 * pp * dt
|
|
587
|
+
out.update({'maasp_psi': round(maasp), 'sidpp_psi': round(sidpp), 'gas': gas_how(cfg)})
|
|
588
|
+
bot = _bubble(cfg, gm, maasp, sidpp, p_bot, dt, down=False) # the bubble on bottom, as it is shut in
|
|
589
|
+
sho = _bubble(cfg, gm, maasp, sidpp, p_frac, ds, down=True) # the bubble circulated up to the shoe
|
|
590
|
+
out.update({'gas_gradient_bottom_psi_ft': round(bot['gg'], 6), 'gas_gradient_shoe_psi_ft': round(sho['gg'], 6)})
|
|
591
|
+
if real_gas(cfg):
|
|
592
|
+
out.update({'z_bottom': round(bot['state']['z'], 4), 'z_shoe': round(sho['state']['z'], 4),
|
|
593
|
+
'temp_bottom_f': round(temperature_f(cfg, bot['mid_tvd_ft']), 1), 'temp_shoe_f': round(temperature_f(cfg, sho['mid_tvd_ft']), 1)})
|
|
594
|
+
if gm <= max(bot['gg'], sho['gg']):
|
|
595
|
+
out.update({'status': 'NOT KNOWN', 'detail': 'the mud is no heavier than the gas'})
|
|
448
596
|
return out
|
|
449
|
-
h = (maasp - sidpp) / (gm - gg)
|
|
450
597
|
open_h = dt - ds
|
|
451
|
-
|
|
452
|
-
out['
|
|
453
|
-
|
|
598
|
+
hb, hs = min(bot['h'], open_h), min(sho['h'], open_h)
|
|
599
|
+
out['height_ft'] = round(max(0.0, hb), 1)
|
|
600
|
+
out['height_shoe_ft'] = round(max(0.0, hs), 1)
|
|
601
|
+
out['height_capped'] = bot['h'] > open_h
|
|
602
|
+
if bot['h'] <= 0:
|
|
454
603
|
out.update({'volume_bbl': 0.0, 'detail': 'the shoe cannot hold the shut-in pressure of a kick of this intensity: no kick tolerance'})
|
|
455
604
|
return out
|
|
456
605
|
cap = _capacity_profile(cfg, below['hole_in'] or 0.0, md_b)
|
|
457
606
|
if cap is None:
|
|
458
607
|
out.update({'status': 'HEIGHT ONLY', 'detail': 'declare the BHA (outside diameter, length) and the drill pipe (outside diameter) for the volume'})
|
|
459
608
|
return out
|
|
460
|
-
|
|
461
|
-
md_top_bottom = _md_at_tvd(tvd_of, dt - hh, md_s, md_b)
|
|
609
|
+
md_top_bottom = _md_at_tvd(tvd_of, dt - hb, md_s, md_b)
|
|
462
610
|
v_bottom = _volume(cap, tvd_of, md_top_bottom, md_b)
|
|
463
|
-
md_low_shoe = _md_at_tvd(tvd_of, ds +
|
|
611
|
+
md_low_shoe = _md_at_tvd(tvd_of, ds + max(0.0, hs), md_s, md_b)
|
|
464
612
|
v_shoe = _volume(cap, tvd_of, md_s, md_low_shoe)
|
|
465
|
-
|
|
466
|
-
|
|
613
|
+
if real_gas(cfg): # the same moles of gas: p V / (z T) at the shoe's middle and at the bottom's
|
|
614
|
+
sb, ss = bot['state'], sho['state']
|
|
615
|
+
v_shoe_at_bottom = v_shoe * (ss['p_psia'] / (ss['z'] * ss['t_r'])) / (sb['p_psia'] / (sb['z'] * sb['t_r']))
|
|
616
|
+
law = "the real-gas law (p V / z T) from the shoe's conditions to the bottom's"
|
|
617
|
+
else:
|
|
618
|
+
v_shoe_at_bottom = v_shoe * p_frac / p_bot
|
|
619
|
+
law = "Boyle's law (p V) from the fracture pressure at the shoe to the pressure at the bottom"
|
|
467
620
|
out.update({'volume_at_bottom_bbl': round(v_bottom, 1), 'volume_at_shoe_bbl': round(v_shoe, 1), 'volume_shoe_as_bottom_bbl': round(v_shoe_at_bottom, 1),
|
|
468
|
-
'volume_bbl': round(min(v_bottom, v_shoe_at_bottom), 1), '
|
|
621
|
+
'volume_bbl': round(min(v_bottom, v_shoe_at_bottom), 1), 'carried_by': law,
|
|
622
|
+
'governs': 'the bubble at the bottom' if v_bottom <= v_shoe_at_bottom else 'the bubble at the shoe'})
|
|
469
623
|
return out
|
|
470
624
|
|
|
471
625
|
|
|
@@ -474,6 +628,11 @@ def analyse(cfg: dict, tvd_of, win, path_how: str = '', window_how: str = '') ->
|
|
|
474
628
|
raise ValueError('declare the casing strings: what:od:weight:grade:top-shoe:hole:mw for each, shallowest shoe first')
|
|
475
629
|
strings = [string_loads(cfg, i, tvd_of, win) for i in range(len(cfg['strings']))]
|
|
476
630
|
kicks = [k for k in (kick_tolerance(cfg, i, tvd_of, win) for i in range(len(cfg['strings']))) if k]
|
|
631
|
+
if float(cfg['kick_intensity_ppg']) > 0: # a swabbed kick: gas pulled in with no underbalance
|
|
632
|
+
sw = {k['shoe_md_ft']: k for k in (kick_tolerance({**cfg, 'kick_intensity_ppg': 0.0}, i, tvd_of, win) for i in range(len(cfg['strings']))) if k}
|
|
633
|
+
for k in kicks:
|
|
634
|
+
s_ = sw.get(k['shoe_md_ft']) or {}
|
|
635
|
+
k['swabbed'] = {x: s_.get(x) for x in ('kick_ppg', 'kick_how', 'sidpp_psi', 'height_ft', 'volume_bbl', 'status', 'detail', 'governs')}
|
|
477
636
|
return {'strings': strings, 'kicks': kicks, 'ok': all(s['ok'] for s in strings), 'config': cfg, 'path_how': path_how, 'window_how': window_how}
|
|
478
637
|
|
|
479
638
|
|
|
@@ -543,7 +702,7 @@ def text(p: dict) -> str:
|
|
|
543
702
|
r = p.get('result')
|
|
544
703
|
if not r:
|
|
545
704
|
return f"Casing design: {p.get('detail', '')}"
|
|
546
|
-
L = [f"Casing design - {r['display']} ({r['path_how']}; window: {r['window_how']})"]
|
|
705
|
+
L = [f"Casing design - {r['display']} ({r['path_how']}; window: {r['window_how']})", f" the gas: {gas_how(r['config'])}"]
|
|
547
706
|
for s in r['strings']:
|
|
548
707
|
st, c = s['string'], s['checks']
|
|
549
708
|
L.append(f" {st['what']}: {st['od_in']:g} in {st['weight_lbft']:g} lb/ft {st['grade']} to {st['shoe_md_ft']:,.0f} ft MD - burst {st['burst_psi']:,} psi, "
|
|
@@ -551,7 +710,9 @@ def text(p: dict) -> str:
|
|
|
551
710
|
L.append(' ' + '; '.join(f"{k} SF {('%.2f' % v['sf']) if v['sf'] is not None else '-'} (design {v['df']:g}) {'OK' if v['ok'] else 'BELOW'}" for k, v in c.items()))
|
|
552
711
|
for k in r['kicks']:
|
|
553
712
|
if k.get('volume_bbl') is not None:
|
|
554
|
-
|
|
713
|
+
sw = k.get('swabbed') or {}
|
|
714
|
+
L.append(f" kick tolerance below {k['shoe_what']}: {k['volume_bbl']:g} bbl at {k['kick_ppg']:.2f} ppg ({k['governs'] if k.get('governs') else k.get('detail', '')}); "
|
|
715
|
+
f"MAASP {k['maasp_psi']:,} psi" + (f"; swabbed (no underbalance) {sw['volume_bbl']:g} bbl" if sw.get('volume_bbl') is not None else ''))
|
|
555
716
|
else:
|
|
556
717
|
L.append(f" kick tolerance below {k['shoe_what']}: {k['status']} - {k.get('detail', '')}" + (f"; MAASP {k['maasp_psi']:,} psi, height {k.get('height_ft', 0):,.0f} ft" if k.get('maasp_psi') is not None else ''))
|
|
557
718
|
return '\n'.join(L)
|
|
@@ -603,14 +764,19 @@ def build_report(ws, version: str, well: Optional[str] = None, scene: str = 'wor
|
|
|
603
764
|
f"{s['rows'][i]['collapse_rating_psi']:,}", '-' if s['rows'][i]['sf_collapse'] is None else f"{s['rows'][i]['sf_collapse']:.2f}",
|
|
604
765
|
f"{s['rows'][i]['axial_klbf']:,.0f}"] for i in idx]))
|
|
605
766
|
secs.append(sec)
|
|
606
|
-
s4 = CR.Section('4', 'Kick tolerance', [f"A single gas bubble
|
|
607
|
-
f"the tallest bubble H = (MAASP - SIDPP) / (mud gradient - gas gradient)
|
|
608
|
-
f"
|
|
767
|
+
s4 = CR.Section('4', 'Kick tolerance', [f"A single gas bubble: {gas_how(cfg)}. MAASP = 0.052 (FG - MW) D_shoe; SIDPP = 0.052 (kick - MW) D_bottom; "
|
|
768
|
+
f"the tallest bubble H = (MAASP - SIDPP) / (mud gradient - gas gradient), the gas's gradient taken at the bubble's middle on bottom "
|
|
769
|
+
f"and at the shoe; its volume at the bottom and at the shoe "
|
|
770
|
+
f"({'the real-gas law, p V / z T' if real_gas(cfg) else 'Boyle' + chr(39) + 's law'} back to the bottom), the smaller governing; "
|
|
771
|
+
f"and the same for a swabbed kick, gas pulled in with no underbalance. Annulus: BHA {cfg.get('bha_od_in') or '-'} in over "
|
|
609
772
|
f"{cfg.get('bha_length_ft') or '-'} ft, drill pipe {cfg.get('dp_od_in') or '-'} in."], [])
|
|
610
|
-
s4.tables.append(CR.Table(['Below', 'Open hole (ft MD)', 'Mud (ppg)', 'Kick (ppg)', 'FG at shoe (ppg)', 'MAASP (psi)', '
|
|
773
|
+
s4.tables.append(CR.Table(['Below', 'Open hole (ft MD)', 'Mud (ppg)', 'Kick (ppg)', 'FG at shoe (ppg)', 'MAASP (psi)', 'Gas (psi/ft) bottom / shoe', 'Height (ft)',
|
|
774
|
+
'Kick tolerance (bbl)', 'Swabbed (bbl)'],
|
|
611
775
|
[[k['shoe_what'], f"{k['shoe_md_ft']:,.0f}-{k['bottom_md_ft']:,.0f}", f"{k['mw_ppg']:g}", f"{k['kick_ppg']:.2f}",
|
|
612
776
|
'-' if k['fg_shoe_ppg'] is None else f"{k['fg_shoe_ppg']:.2f}", '-' if k.get('maasp_psi') is None else f"{k['maasp_psi']:,}",
|
|
613
|
-
'-' if k.get('
|
|
777
|
+
'-' if k.get('gas_gradient_bottom_psi_ft') is None else f"{k['gas_gradient_bottom_psi_ft']:.3f} / {k['gas_gradient_shoe_psi_ft']:.3f}",
|
|
778
|
+
'-' if k.get('height_ft') is None else f"{k['height_ft']:,.0f}", f"{k['volume_bbl']:g}" if k.get('volume_bbl') is not None else k['status'],
|
|
779
|
+
f"{(k.get('swabbed') or {}).get('volume_bbl'):g}" if (k.get('swabbed') or {}).get('volume_bbl') is not None else '-']
|
|
614
780
|
for k in r['kicks']]))
|
|
615
781
|
secs += [s4, CR.Section('5', 'What this will not call a measurement', ['; '.join(p['not_a_measurement']) + '.'], [])]
|
|
616
782
|
return CR.Document(f"Casing design and kick tolerance - {r['display']}", rid, front, secs,
|
|
@@ -829,10 +829,10 @@ ENG_TABLES: Dict[str, dict] = {
|
|
|
829
829
|
'casing_design': {'cols': ('well', 'what', 'od_in', 'weight_lbft', 'grade', 'top_md_ft', 'shoe_md_ft', 'hole_in', 'mw_ppg', 'wall_in', 'source'),
|
|
830
830
|
'need': ('well', 'what', 'od_in', 'weight_lbft', 'grade', 'shoe_md_ft', 'hole_in', 'mw_ppg', 'source'),
|
|
831
831
|
'about': "the casing program for casing design and kick tolerance: a row per string - its outside diameter (9.625 or 9-5/8), nominal weight (lb/ft), grade (H40 to Q125), top (0 to the surface) and shoe (ft MD), the hole it was run in (in), the mud it was run in (ppg), the wall (in) for a size not in the program's table; a well's rows together replace its program"},
|
|
832
|
-
'casing_loads': {'cols': ('well', 'td_md_ft', 'td_hole_in', 'td_mw_ppg', 'pp_ppg', 'fg_ppg', 'kick_intensity_ppg', 'gas_gradient_psi_ft', '
|
|
833
|
-
'evacuation', 'df_burst', 'df_collapse', 'df_tension', 'overpull_klbf', 'bha_od_in', 'bha_length_ft', 'dp_od_in', 'source'),
|
|
832
|
+
'casing_loads': {'cols': ('well', 'td_md_ft', 'td_hole_in', 'td_mw_ppg', 'pp_ppg', 'fg_ppg', 'kick_intensity_ppg', 'gas_gradient_psi_ft', 'gas_sg',
|
|
833
|
+
'surface_temp_f', 'geothermal_f_100ft', 'backup_gradient_psi_ft', 'evacuation', 'df_burst', 'df_collapse', 'df_tension', 'overpull_klbf', 'bha_od_in', 'bha_length_ft', 'dp_od_in', 'source'),
|
|
834
834
|
'need': ('well', 'source'),
|
|
835
|
-
'about': "the casing loads' terms: the hole below the deepest string (TD ft MD, hole in, mud ppg), a pore pressure and fracture gradient when the Pore pressure tab has none, the kick intensity (ppg), the gas and backup
|
|
835
|
+
'about': "the casing loads' terms: the hole below the deepest string (TD ft MD, hole in, mud ppg), a pore pressure and fracture gradient when the Pore pressure tab has none, the kick intensity (ppg), the gas (its gravity, the surface temperature in F and the geothermal gradient in F per 100 ft; or a fixed gradient in psi/ft in place of the real gas), the backup gradient (psi/ft), the evacuation (0 to 1), the design factors, the overpull (klbf), and the BHA and drill pipe for the kick volume; blank keeps the default"},
|
|
836
836
|
'frac_stages': {'cols': ('well', 'file', 'depth_unit', 'utc_offset_h', 'source'), 'need': ('well', 'file', 'source'),
|
|
837
837
|
'about': "a treatment well's stage table (a path beside this sheet: CSV or Excel, one row per stage with its start and end of pumping), its depth unit (ft or m), the stage clock's hours from UTC, and the report it came from"},
|
|
838
838
|
'frac_monitors': {'cols': ('well', 'channel'), 'need': ('well', 'channel'),
|
|
@@ -1073,6 +1073,9 @@ def _plan_engineering(ws, tables, wells, add, guard, base_dir: str) -> None:
|
|
|
1073
1073
|
for k in CSG.LIMITS:
|
|
1074
1074
|
if k == 'step_ft' or not (rec.get(k) or '').strip():
|
|
1075
1075
|
continue
|
|
1076
|
+
if rec[k].strip().lower() == 'none' and CSG.DEFAULTS.get(k) is None:
|
|
1077
|
+
want[k] = None
|
|
1078
|
+
continue
|
|
1076
1079
|
v = CSG.size_in(rec[k]) if k in ('td_hole_in', 'bha_od_in', 'dp_od_in') else _f(rec.get(k), k, False)
|
|
1077
1080
|
lo, hi = CSG.LIMITS[k]
|
|
1078
1081
|
if not lo <= v <= hi:
|