Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 43 additions & 4 deletions docs/PAPER_OCP_VALIDATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ units throughout. The Pyomo benchmark itself does not depend on GEKKO or
MATLAB. GEKKO is available in the repo-local Pixi environment for upstream
policy-segment verification.

Problem 2 is now available as a second paper-reference OCP:
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nonblocking: Since this doc now says Problem 2 is available, the package README should be kept in sync. lyopronto/pyomo_models/README.md still lists only the Problem 1 paper OCP functions and describes classify_paper_policies() as inferring Policy 1/Policy 2 regions. Please update that section to mention the Problem 2 model, initializer, solver, and Policy 3 support.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 1788e7f. Updated lyopronto/pyomo_models/README.md to list the Problem 2 model, initializer, solver, and Policy 3 classification support.


- primary drying only, using the same moving-boundary model;
- shelf temperature as the optimized control;
- objective: minimize drying time;
- constraints: product temperature at or below 240 K, interface velocity at or
below `2.8e-7 m/s`, and shelf temperature between 228 K and 260 K;
- expected qualitative policy sequence: interface-velocity tracking, maximum
heat input, then product-temperature tracking.

## Validation Strategy

The benchmark has two layers:
Expand Down Expand Up @@ -136,18 +146,47 @@ All rows use `nfe=12`, `ncp=3`, `LAGRANGE-RADAU`, the policy initializer, and a
| `n_z=5` | optimal | ~6.19 h | Policy 1 -> Policy 2 |
| `n_z=20` | optimal/acceptable | ~6.19 h | Policy 1 -> Policy 2 |

## Problem 2 First-Pass Tolerances

The Problem 2 validation is intentionally coarse at this stage. The paper
reports switch times near 2.0 h and 3.9 h, with drying complete around 8.9 h.
The slow test therefore accepts broad first-pass tolerances on the coarse
`n_z=5`, `nfe=12`, `ncp=3` mesh:

- terminal interface gap at or below `1e-7 m`;
- product-temperature violation at or below `1e-3 K`;
- post-initial interface-velocity violation at or below `5e-10 m/s`;
- shelf-temperature bound violations at or below `1e-6 K`;
- drying time within `0.7 h` of the paper value;
- first two policy switches within `0.8 h` of the paper values.

The velocity constraint is skipped at the initial collocation point because the
paper explicitly reports an initial velocity excursion before Policy 3 quickly
brings `dS/dt` to its setpoint. Metrics still report the initial velocity
separately, while path-constraint checks use the post-initial trajectory.

Known limitations:

- The Problem 2 initializer is a deterministic policy-sequenced warm start, not
a full reproduction of the upstream high-index GEKKO Policy 3 solve.
- The first validated solve is coarse. A refined `n_z=20` Problem 2 solve and a
MATLAB/GEKKO upstream export should be added once the upstream reference
tooling is extended beyond Problem 1.

## Future Work

Next steps are tracked in GitHub issues:

1. #28 - Prepare the first Paper Problem 1 validation PR.
2. #29 - Add Problem 2 with the interface-velocity constraint and expected
Policy 3 -> Policy 1 -> Policy 2 sequence.
3. #30 - Compare the paper-reference transcription against LyoPRONTO's existing
2. #30 - Compare the paper-reference transcription against LyoPRONTO's existing
quasi-steady Pyomo and scipy optimizers.
4. #31 - If the benchmark is credible, add a LyoPRONTO-facing experimental
3. #31 - If the benchmark is credible, add a LyoPRONTO-facing experimental
policy API with the same rich result format.

#26 is addressed by the bottom-node temperature constraint alignment, the
smaller expression-based NLP for vapor pressure/resistance/flux/interface
velocity, constraint scaling, and the `n_z=20` slow validation test.

#29 is addressed by the Problem 2 config defaults, velocity path constraint,
Policy 3 classifier support, policy-sequenced initializer, coarse slow solve,
and first-pass tolerance documentation.
21 changes: 15 additions & 6 deletions lyopronto/pyomo_models/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,28 @@ drying OCP in Srisuma and Braatz, arXiv:2509.10826v1.

**Key functions:**
- `create_paper_problem1_model()` - Build the orthogonal-collocation Pyomo model
- `create_paper_problem2_model()` - Build Problem 2 with the interface-velocity constraint
- `solve_paper_problem1()` - Solve Paper Problem 1 with IPOPT
- `solve_paper_problem2()` - Solve Paper Problem 2 with IPOPT
- `generate_problem1_policy_initialization()` - Build a policy-based warm start
- `generate_problem2_policy_initialization()` - Build the Problem 2 Policy 3 -> Policy 1 -> Policy 2 warm start
- `initialize_paper_problem1_from_trajectory()` - Seed a model from a trajectory
- `load_upstream_matlab_trajectory()` - Read upstream MATLAB output saved to `.mat`
- `compare_paper_problem1_trajectories()` - Compare Pyomo and upstream metrics
- `classify_paper_policies()` - Infer active Policy 1/Policy 2 regions
- `classify_paper_policies()` - Infer active Policy 1/Policy 2/Policy 3 regions

This module uses SI/Kelvin units from the paper/upstream code and is separate
from LyoPRONTO's cm/Torr/degC production APIs. The validated default solve uses
a coarse `n_z=5` mesh, and the upstream paper's `n_z=20` spatial mesh is covered
by a slow validation test using IPOPT acceptable termination
(`acceptable_tol=1e-3`, `acceptable_iter=5`). Both reproduce the expected
Policy 1 -> Policy 2 sequence near the paper's reported switch time.
from LyoPRONTO's cm/Torr/degC production APIs. Problem 1 validates the
temperature-constrained drying-time objective and reproduces the expected
Policy 1 -> Policy 2 sequence near the paper's reported switch time. Problem 2
adds the 240 K product-temperature limit, 260 K shelf-temperature upper bound,
and `2.8e-7 m/s` interface-velocity path constraint; the coarse validation
tracks the expected Policy 3 -> Policy 1 -> Policy 2 sequence.

The validated default solves use a coarse `n_z=5` mesh. For Problem 1, the
upstream paper's `n_z=20` spatial mesh is also covered by a slow validation test
using IPOPT acceptable termination (`acceptable_tol=1e-3`,
`acceptable_iter=5`).

Regenerate the full upstream Problem 1 reference with:

Expand Down
6 changes: 6 additions & 0 deletions lyopronto/pyomo_models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,13 @@ def _is_pyomo_available() -> bool:
classify_paper_policies,
compare_paper_problem1_trajectories,
create_paper_problem1_model,
create_paper_problem2_model,
generate_problem1_policy_initialization,
generate_problem2_policy_initialization,
initialize_paper_problem1_from_trajectory,
load_upstream_matlab_trajectory,
solve_paper_problem1,
solve_paper_problem2,
)
from .single_step import (
create_single_step_model,
Expand All @@ -75,11 +78,14 @@ def _is_pyomo_available() -> bool:
"PaperPrimaryDryingConfig",
"PaperDiscretization",
"create_paper_problem1_model",
"create_paper_problem2_model",
"generate_problem1_policy_initialization",
"generate_problem2_policy_initialization",
"initialize_paper_problem1_from_trajectory",
"load_upstream_matlab_trajectory",
"compare_paper_problem1_trajectories",
"solve_paper_problem1",
"solve_paper_problem2",
"classify_paper_policies",
]

Expand Down
Loading
Loading