{"id":50415149,"url":"https://github.com/felipearocha/integrity-code-series-week9-cui","last_synced_at":"2026-05-31T05:30:18.228Z","repository":{"id":354450257,"uuid":"1223675673","full_name":"felipearocha/integrity-code-series-week9-cui","owner":"felipearocha","description":"Coupled thermohygro-electrochemical CUI simulator with DFOS-informed inverse problem (Integrity Code Series, Week 9). Three-PDE physics, Strang splitting, 154 tests, full CI/CD.","archived":false,"fork":false,"pushed_at":"2026-04-28T15:20:55.000Z","size":67,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-28T17:18:28.727Z","etag":null,"topics":["api-579","api-rp-583","butler-volmer","corrosion-under-insulation","cui","dfos","fitness-for-service","inverse-problem","monte-carlo","philip-de-vries","physics-simulation","pipeline-integrity","scientific-python","strang-splitting"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/felipearocha.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-28T14:46:56.000Z","updated_at":"2026-04-28T15:23:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/felipearocha/integrity-code-series-week9-cui","commit_stats":null,"previous_names":["felipearocha/integrity-code-series-week9-cui"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/felipearocha/integrity-code-series-week9-cui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felipearocha%2Fintegrity-code-series-week9-cui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felipearocha%2Fintegrity-code-series-week9-cui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felipearocha%2Fintegrity-code-series-week9-cui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felipearocha%2Fintegrity-code-series-week9-cui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/felipearocha","download_url":"https://codeload.github.com/felipearocha/integrity-code-series-week9-cui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felipearocha%2Fintegrity-code-series-week9-cui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33720897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-579","api-rp-583","butler-volmer","corrosion-under-insulation","cui","dfos","fitness-for-service","inverse-problem","monte-carlo","philip-de-vries","physics-simulation","pipeline-integrity","scientific-python","strang-splitting"],"created_at":"2026-05-31T05:30:17.638Z","updated_at":"2026-05-31T05:30:18.222Z","avatar_url":"https://github.com/felipearocha.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ICS2 Week 9 — CUI Coupled Thermohygro-Electrochemical Simulation\n\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.20172508.svg)](https://doi.org/10.5281/zenodo.20172508)\n\n[![CI](https://github.com/felipearocha/integrity-code-series-week9-cui/actions/workflows/ci.yml/badge.svg)](https://github.com/felipearocha/integrity-code-series-week9-cui/actions/workflows/ci.yml)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/)\n[![Tests](https://img.shields.io/badge/tests-151%20passing-brightgreen.svg)](#testing)\n[![License](https://img.shields.io/badge/license-Research--Educational-lightgrey.svg)](LICENSE)\n\nThree-way coupled physics-first simulator for **Corrosion Under Insulation (CUI)**\non insulated carbon-steel process piping. Simulates moisture ingress through a\ncladding holiday, hygrothermal transport to the hot pipe surface, and Butler-\nVolmer corrosion kinetics — all solved together via Strang operator splitting.\nIncludes a DFOS-informed inverse problem to recover holiday source magnitude\nfrom outer-cladding temperature observations.\n\n## Integrity Code Series\n\nPart of an ongoing series of physics-first integrity simulators by Felipe Rocha:\n\n| # | Repo | Domain |\n|---|---|---|\n| Week 3 | [Integrity-code-series-3](https://github.com/felipearocha/Integrity-code-series-3) | F1 lap simulation (six coupled ODEs) |\n| Week 6 | [Integrity-code-series-week6-smartphone-galvanic](https://github.com/felipearocha/Integrity-code-series-week6-smartphone-galvanic) | Smartphone galvanic corrosion (Laplace + Butler-Volmer) |\n| Week 7 | [integrity_code_series_week7_h2_lferw](https://github.com/felipearocha/integrity_code_series_week7_h2_lferw) | LF-ERW H2 conversion (B31.12 + NACE TM0316) |\n| Week 8 | [integrity-code-series-week8-creep-fatigue-heater](https://github.com/felipearocha/integrity-code-series-week8-creep-fatigue-heater) | Creep-fatigue 9Cr-1Mo (Norton/Omega + Coffin-Manson) |\n| Week 9 | [integrity-code-series-week9-cui](https://github.com/felipearocha/integrity-code-series-week9-cui) | CUI thermohygro-electrochemical (3 PDEs, Strang) |\n| Week 10 | [integrity-code-series-week-10_nnph_scc](https://github.com/felipearocha/integrity-code-series-week-10_nnph_scc) | NNpHSCC full-physics (Chen-Sutherby-Xing + BS 7910) |\n| Bonus | [Vibration-Accelerated-Corrosion-Coupled-Mechano-Electrochemical-Simulation](https://github.com/felipearocha/Vibration-Accelerated-Corrosion-Coupled-Mechano-Electrochemical-Simulation) | Vibration-accelerated corrosion (SDOF + Butler-Volmer + Archard) |\n| Bonus | [synthetic-integrity-digital-twin-piml](https://github.com/felipearocha/synthetic-integrity-digital-twin-piml) | Physics-informed neural-network surrogate |\n| Bonus | [integrity-data-foundation](https://github.com/felipearocha/integrity-data-foundation) | Engineering data validation baseline |\n\n## Quickstart\n\n```bash\ngit clone https://github.com/felipearocha/integrity-code-series-week9-cui.git\ncd REPO\npython -m venv .venv \u0026\u0026 source .venv/bin/activate   # Windows: .venv\\Scripts\\activate\npip install -r requirements.txt\npython run_all.py        # ~70 s on a laptop; produces 7 figures + 1 GIF + audit_chain.json\npytest tests/ -v         # 151 tests\npython validation/benchmarks.py   # 5 analytical benchmarks\n```\n\n## Problem Statement\n\nCorrosion Under Insulation (CUI) on carbon steel process piping causes ~60% of pipe\nleaks in documented refinery case studies (AMPP 2022). It progresses unseen beneath\ninsulation systems for years. PHMSA Docket 2026-1520 (April 24, 2026) places external\ncorrosion threats on hazardous liquid pipelines under active regulatory scrutiny.\nAPI RP 583 identifies 50-175 C as the critical temperature window for CUI on carbon steel.\n\nThis package simulates three-way coupled physics: heat conduction through the insulation\nannulus, hygrothermal moisture transport driven by capillary and thermal gradients, and\nButler-Volmer electrochemical corrosion at the steel surface — all solved together via\nStrang operator splitting. A DFOS-informed inverse problem recovers moisture source\nlocations from outer cladding temperature measurements.\n\n---\n\n## Governing Equations\n\n### Field 1 — Fourier Heat Conduction (Eq. 1)\n\n```\nrho_eff(theta_w)*cp_eff(theta_w)*dT/dt = div(lambda_eff(theta_w)*grad(T)) + Q_corr\n```\n\nBoundary conditions:\n```\nT(r_i) = T_process                                      (1a) inner wall Dirichlet\n-lambda*dT/dr|_outer = h_conv*(T-T_inf) + eps*sigma*(T^4-T_inf^4)  (1b) Robin outer\ndT/dz|_ends = 0                                         (1c) adiabatic axial ends\n```\n\n### Field 2 — Philip-de Vries Hygrothermal Moisture Transport (Eq. 2)\n\n```\nd(theta_w)/dt = div(D_theta(theta_w)*grad(theta_w)) + div(D_T(theta_w,T)*grad(T))\n```\n\nWhere:\n```\nD_theta(theta_w) = D_theta0 * exp(beta_theta * theta_w)             (2a)\nD_T(theta_w, T)  = D_vap_atm * xi(theta_w) * f(theta_w, T)          (2b)\ntheta_w|_holiday = f * THETA_SAT + (1 - f) * THETA_INIT             (2c) partial-holiday Dirichlet\n                   with f = min(S_mag / S_ref, 1)\nJ_w.n|_intact    = 0                                                (2d) zero-flux\ntheta_w|_t=0     = THETA_INIT [ASSUMED]                             (2e)\n```\n\nThe partial-holiday BC (2c) models the cladding defect as a fraction `f`\nof the outer circumference at saturation; `S_mag = S_ref` (default\n`S_REF_DEFAULT = 1e-6 m^3/m^3/s`) is a fully wet holiday, `S_mag = 0` is\nintact cladding. Above `S_ref` the BC saturates and S_mag is non-\nidentifiable from T_clad alone, so the inverse problem (Eq. 6) is\nrestricted to the unique-recovery range `S ∈ [0, S_ref]`.\n\n### Field 3 — Butler-Volmer Electrochemical Kinetics (Eq. 3)\n\n```\ni_corr = i0(T) * [exp(alpha_a*F*eta/(RT)) - exp(-alpha_c*F*eta/(RT))]  if theta_w \u003e theta_crit\n       = 0                                                                 if theta_w \u003c= theta_crit\n\ni0(T) = i0_ref * exp(-Ea/R * (1/T - 1/T_ref))                   (3a)\n```\n\n### Wall Loss — Faraday's Law (Eq. 4)\n\n```\ndWT/dt = -M_Fe/(n*F*rho_steel) * i_corr(T, theta_w)\n```\n\n### Strang Operator Splitting (Eq. 5)\n\n```\nu^{n+1} = L_EC(dt/2) o L_HY(dt/2) o L_TH(dt) o L_HY(dt/2) o L_EC(dt/2) u^n\n```\n\n### Tikhonov Inverse Problem (Eq. 6)\n\n```\nmin_S J(S) = (T_obs - T_model(S))^2 + lambda_reg * S^2     S in [0, S_ref]\n```\n\nSingle-parameter 1D inverse for `S_mag`, solved by golden-section line\nsearch on `J(S)` in `src/inverse_problem.py`. Recovery error is \u0026lt;1% on\nthe identifiable range `S in [0, S_ref]` for synthetic DFOS cases with\n0.03 K measurement noise (see `[6/9]` in `run_all.py`). Above S_ref the\nmodel BC saturates and the inverse is non-injective by construction.\nA full adjoint formulation is out of scope.\n\n### Monte Carlo / PoF (Eq. 9-10)\n\n```\nxi = {S_mag, theta_crit, i0_ref, E_a, lambda_eff, L_defect}  N_MC = 10,000 (LHS)\nPoF(t*) = (1/N) * sum( 1[WT_k(t*) \u003e 0.20 * t_nom] )\n```\n\n### FAD — API 579-1 Level 2 Option B (Eq. 12-13)\n\n```\nf(Lr) = [1 + 0.5*Lr^2]^(-1/2) * [0.3 + 0.7*exp(-0.65*Lr^6)]\nLr_max = 0.5*(1 + UTS/SMYS)\n```\n\n---\n\n## Repository Structure\n\n```\nintegrity_code_series_week9_cui_thermohygro/\n├── run_all.py\n├── requirements.txt\n├── README.md\n├── EXECUTION_ORDER.md\n├── conftest.py\n├── src/\n│   ├── constants.py          Physical constants, [ASSUMED] flags\n│   ├── geometry.py           2D axisymmetric FDM mesh\n│   ├── thermal_field.py      Fourier PDE solver (Crank-Nicolson)\n│   ├── moisture_field.py     Philip-de Vries solver (explicit, sub-stepped)\n│   ├── electrochemistry.py   Butler-Volmer + Faraday wall loss\n│   ├── coupled_solver.py     Strang operator splitting, baseline runner\n│   ├── inverse_problem.py    Tikhonov inverse, DFOS synthetic tests\n│   ├── monte_carlo.py        LHS sampling, MC propagation, Spearman\n│   ├── surrogate_gbr.py      GBR surrogate, parity metrics\n│   ├── fad_assessment.py     API 579-1 Level 2 FAD\n│   └── audit_chain.py        SHA-256 hash-linked run log\n├── validation/\n│   └── benchmarks.py\n├── visualization/\n│   ├── plot_fields.py\n│   ├── plot_mc_dist.py\n│   ├── plot_analysis.py\n│   └── generate_gif.py\n├── tests/\n│   ├── test_geometry_thermal.py\n│   ├── test_moisture_electrochemistry.py\n│   └── test_remaining.py\n├── assets/figures/           8 static PNG panels (300 DPI)\n├── assets/animations/        cui_moisture_front.gif\n├── assets/audit_chain.json\n└── notebooks/\n```\n\n---\n\n## [ASSUMED] Parameter Flags\n\n| Parameter | Value | Basis |\n|-----------|-------|-------|\n| D_theta0 (mineral wool) | 6.0e-11 m^2/s | Literature porous media, mineral wool [ASSUMED] |\n| beta_theta | 5.0 | D_theta exponential slope [ASSUMED] |\n| theta_crit | 0.05 vol fraction | API RP 583 qualitative guidance [ASSUMED] |\n| i0_ref at 25 C | 1.0e-5 A/m^2 | General Fe dissolution literature [ASSUMED] |\n| E_a Fe dissolution | 50 kJ/mol | General electrochemistry literature [ASSUMED] |\n| eta_mixed | 0.15 V | Mixed potential anodic overpotential [ASSUMED] |\n| K_mat X52 | 70 MPa sqrt(m) | Sweet service estimate [ASSUMED] |\n| D_T coupling | 0.05 * D_theta0 * theta_w * T_norm | Philip-de Vries simplified [ASSUMED] |\n| Holiday source S | 1.0e-6 m^3/m^3/s | Continuous wetting rate [ASSUMED] |\n\n---\n\n## Escalation Table (vs. Week 8)\n\n| Dimension | Week 8 | Week 9 |\n|-----------|--------|--------|\n| PDE count | 1 (PR EOS + chemistry, algebraic) | 3 coupled PDEs (Fourier + PdV + BV) |\n| Geometry | 1D spatial pipeline | 2D axisymmetric annulus |\n| Inverse problem | None | DFOS-informed Tikhonov inversion |\n| Operator method | Sequential | Strang splitting (2nd order) |\n| Sensor integration | None | DFOS noise model + synthetic tests |\n\n---\n\n## Cybersecurity Summary\n\nSTRIDE threat model applied to DFOS sensor network feeding inverse solver:\n\n| Threat | Mitigation |\n|--------|-----------|\n| Spoofing (DFOS fiber injection) | Cryptographic signing at acquisition unit |\n| Tampering (inverse solver input) | Hash-verified I/O; audit_chain.json |\n| Repudiation | Immutable SHA-256 chain per run |\n| Information Disclosure | OT-segment VLAN for DFOS network |\n| Denial of Service | Rate limiting + GBR surrogate fallback |\n| Elevation of Privilege | Surrogate out-of-bounds triggers human review |\n| Data Poisoning | Physics residual validation before GBR retraining |\n\n---\n\n## License\n\nResearch and educational use only. Not for operational fitness-for-service decisions\nwithout independent engineering review and site-specific validation.\nAPI RP 583, API 579-1, PHMSA regulations take precedence over model output.\n[ASSUMED] parameters must be validated against site-specific inspection data.\n\n---\n\nIntegrity Code Series — ICS2 | Week 9 | Physics-first. Verification over visibility.\n---\n\n## How to Cite\n\nIf this software contributes to your work, please cite both the software (this repository) and the underlying methods it implements.\n\n**Software (archived release):**\n\n\u003e Rocha, F. (2026). *Integrity Code Series - Week 9 - CUI Coupled Thermohygro-Electrochemical Simulation* (Version 1.1.1) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.20172508\n\n**BibTeX:**\n\n```bibtex\n@software{rocha_2026_week9,\n  author       = {Rocha, Felipe},\n  title        = {{Integrity Code Series - Week 9 - CUI Coupled Thermohygro-Electrochemical Simulation}},\n  year         = 2026,\n  publisher    = {Zenodo},\n  version      = {v1.1.1},\n  doi          = {10.5281/zenodo.20172508},\n  url          = {https://doi.org/10.5281/zenodo.20172508}\n}\n```\n\nThe two DOIs Zenodo provides are:\n\n| DOI                                  | What it points to                                                  |\n|--------------------------------------|--------------------------------------------------------------------|\n| `10.5281/zenodo.20172508` (concept)   | Always resolves to the latest version - use this for citation.     |\n| `10.5281/zenodo.20172509` (version)   | Pinned to v1.1.1 specifically - use when reproducibility matters.  |\n\nA machine-readable citation file is also available in [`CITATION.cff`](CITATION.cff) - GitHub will display a \"Cite this repository\" widget at the top right of the repo page that exports BibTeX / APA / RIS automatically.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelipearocha%2Fintegrity-code-series-week9-cui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffelipearocha%2Fintegrity-code-series-week9-cui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelipearocha%2Fintegrity-code-series-week9-cui/lists"}