{"submission_id":"4c4d7e9b-41b1-44df-8766-4bf35728f03e","submission_revision_id":"254b8158-5105-4380-9ce8-cb6fdce2e93a","revision_version":3,"submission_status":"submitted","submitted_at":"2026-08-17T01:39:13.320876Z","submitter_name":"Haoxuan Chen","submitter_email":"haoxuan@alumni.caltech.edu","task":{"status":"submitted","version":3,"extra_fields":{},"submitted_at":"2026-08-17T01:39:13.320876+00:00","industry_domain":"Numerical Analysis and Scientific Computing","task_short_name":"Alternating-Direction Implicit (ADI) method in Scientific Computing","operating_system":"Linux","task_description":"You are working on a Linux coding task about alternating-direction-implicit\nfinite-difference methods for parabolic PDEs with a mixed second derivative.\n\n**Task directory:** `base`\n\n**Visible input files:**\n- Problem specification: `base/input/problem_spec.md`\n- Python runtime manifest: `base/input/runtime_env/pyproject.toml`\n- Python lockfile: `base/input/runtime_env/uv.lock`\n- Canonical Python wrapper: `base/software/python.sh`\n\n**Recommended workflow:**\n1. Change into `base`.\n2. Read `base/input/problem_spec.md` in full before coding.\n3. Use `\"base/software/python.sh\" your_script.py` or\n   `\"base/software/python.sh\" -c \"...\"` to run Python with the staged\n   NumPy/SciPy environment.\n4. Implement your solver and save it to `base/output/adi_solver.py`.\n5. Run the solver and write every required artifact under `base/output`.\n\n**Required outputs under `base/output`:** `adi_solver.py`,\n`reference_arrays.npz`, `results.json`.\n\n**Objective:** Implement a stable, **second-order ADI** (Alternating Direction\nImplicit) finite-difference solver for a 2D parabolic PDE that contains a\n**mixed derivative**, `u_t = a·u_xx + 2c·u_xy + b·u_yy` on `(0,1)²` to `T = 1`,\nwith SPD diffusion matrix `[[1.0, 0.5], [0.5, 0.8]]`. Demonstrate second-order\nconvergence against a manufactured exact solution (a sum of three rotated\ndecaying waves). This is the model operator behind correlated-diffusion problems\n(it arises, for example, in computational finance).\n\n**Instructions & Rules:**\n1. Implement the solver in `base/output/adi_solver.py` using **Python + NumPy +\n   SciPy only** — no PDE/FEM/FDM library; write the tridiagonal solves yourself.\n2. The mixed term `2c·u_xy` is the crux. A directional ADI sweep cannot make it\n   implicit; you must use a scheme that incorporates the mixed term and is\n   **both** second order **and** stable on this mesh sequence. Selecting the\n   scheme and any parameter it carries so that both properties hold with a mixed\n   derivative present is part of the task. **Any** qualifying ADI scheme is\n   accepted — you are not being asked to reproduce a particular published method.\n3. Only 1-D tridiagonal sweeps may be solved implicitly; do not assemble and\n   invert the full 2-D operator directly. Every linear solve on an `m×m` grid\n   must have dimension `O(m)`, not `O(m²)`.\n4. `adi_solver.py` must be importable without side effects and expose\n   `solve(h, T=1.0, problem=None) -> (X, Y, U)`, returning `(m+1, m+1)` arrays\n   built with `indexing='ij'`. `problem` supplies arbitrary SPD coefficients and\n   callables for the initial and boundary data; the grader calls `solve()` on a\n   problem of its own choosing, so the solver must be general rather than\n   specialised to the manufactured solution.\n5. **Tier 1 (validation):** solve at `h = 0.1`, report a finite max-norm error.\n6. **Tier 2 (convergence, core):** for `h = 0.1·2^-p`, `p = 0..4`, build the\n   `(h, e_h, order_h)` table with `order_h = log2(e_2h/e_h)`; the order must\n   approach 2. (A solver that mishandles the mixed term plateaus at order ≈ 0.)\n7. **Tier 3 (artifacts):** on the finest mesh `h = 0.00625` (161×161), save the\n   numerical solution, exact solution, and error surface at `T = 1`.\n8. Write `reference_arrays.npz` and a consistent `results.json`. Keep every saved\n   value truthful; if Tier 3 can't be completed, still emit honest Tier 1 /\n   Tier 2 outputs rather than fabricating arrays.\n9. Do not modify files outside `base/output`.","software_licensing":"Free/Open Source","evaluation_criteria":null,"verification_method":"An automated grader (`evaluation/grade.py`, provided) applies **strict, objective**\nrules. It knows the diffusion matrix and the exact solution, recomputes the exact\nsolution analytically, recomputes every order of convergence from the submitted\narrays, **and re-runs the submitted solver in an isolated subprocess** — so\ndropping the mixed term, using a first-order or unstable scheme, bypassing ADI\nwith a monolithic 2-D solve, or fabricating metrics all fail.\n\n**Scoring**\n- `1.0` — Tier 1 + Tier 2 + Tier 3 all pass.\n- `0.5` — Tier 1 + Tier 2 and all provenance checks pass, Tier 3 missing/fails.\n- `0.0` — required files missing (including `adi_solver.py`), array schema\n  violations, `results.json` inconsistent with the arrays, wrong mesh sequence,\n  non-finite errors (instability), a disallowed dependency, a linear solve too\n  large to be a 1-D sweep, a solver that cannot reproduce its own submitted\n  numbers, or Tier 1 / Tier 2 fail.\n\n**Objective thresholds.** The acceptance criteria are **published verbatim in\n`problem_spec.md`**, so nothing is a hidden band and no scheme is privileged:\n- Tier 1: `e_h(0.1)` finite and `< 1.0` — a nonsense guard, not a discriminator.\n  (Magnitude on the coarsest mesh genuinely cannot discriminate: a dropped mixed\n  term scores `2.40e-3` there, *better* than the admissible MCS at θ=0.8.)\n- Tier 2: errors strictly decreasing; total reduction `e(0.1)/e(0.00625) ≥ 100×`;\n  least-squares fitted order over the five meshes in `[1.70, 2.30]`; both of the\n  two finest experimental orders in `[1.60, 2.60]`; finest error `< 1e-2`.\n- Tier 3: `X_finest`/`Y_finest` equal to the true 161×161 grid; `U_exact_finest`\n  equal to the analytic solution; `error_finest == U_finest − U_exact_finest`;\n  exact Dirichlet data on the boundary; `max_norm_errors[4]` equal to the error\n  recomputed from `U_finest`, proving the table's last row and the Tier 3\n  surfaces come from the same run; the finest meshes regenerated from the\n  submitted solver; **and `U_finest` matching the regenerated finest numerical\n  field pointwise** (`rtol=1e-10`, `atol=1e-12`).\n- Provenance: `adi_solver.py` present, importable, exposing\n  `solve(h, T=1.0, problem=None)`,\n  importing nothing outside stdlib + NumPy + SciPy, and regenerating `e_h` to\n  within `1e-6` relative of the submitted values. All five meshes must be\n  regenerated for a 1.0; the coarse three are required even for a 0.5. A\n  regenerated *error* that disagrees with the table is a provenance failure\n  (0.0); a regenerated finest *field* that disagrees with `U_finest` pointwise\n  is a Tier 3 failure (0.5).\n- Hidden instance: `solve()` is called on an undisclosed problem (different SPD\n  coefficients, a non-separable initial state with no closed form) and must\n  converge to a reference the grader computes with its own independent solver.\n  This is what makes the ADI requirement enforceable: a solver that makes one\n  legal tridiagonal call, discards it, and returns the manufactured analytic\n  field passes every other check with a textbook order of 2, and fails here.\n- Causal sweep audit: on one hidden mesh, every intercepted linear-solve result\n  is poisoned. If the returned field remains finite and unchanged to pointwise\n  `atol=1e-12` (`rtol=0`), the calls were discarded and the submission receives\n  0.0. A hand-written solver with no observable calls is routed to the documented\n  manual-review path.\n- ADI structure: the grader instruments every linear-solve entry point at run\n  time — including low-level LAPACK — and records both the dimension and the\n  bandwidth of each system. On an `m×m` grid no solve may exceed dimension\n  `2(m+1)` or half-bandwidth 1 (at `h = 0.1`: a genuine sweep is 9, the limit 22,\n  the forbidden monolithic solve 81).\n- Consistency: `results.json` must agree with `reference_arrays.npz` on the whole\n  convergence table (including the `p` indices), the orders, the diffusion\n  matrix, the time-step rule, and the finest mesh.\n\n`evaluation/scheme_survey.py` is included as reproducible evidence for the exact\ncoverage claim: the criteria accept **MCS for θ ∈ [1/3, 8], Craig–Sneyd at\nθ = 1/2 (its only second-order parameter), and Hundsdorfer–Verwer for\nθ ∈ [1/2, 8]**, and reject the failure modes (Douglas → first order, CS away from\nθ = 1/2 → order ≈ 1.2, CS at θ=1/3 → unstable, mixed term dropped → order 0).\nSchemes whose parameter is so large that they no longer exhibit second-order\nconvergence *on this mesh sequence* (MCS at θ ≥ 10, whose total error\nreduction is only 79.9×) are rejected on the task's own\nstated terms — the instruction requires the observed order to approach 2 on\n`h = 0.1·2^-p`, `p = 0..4`.\n\nThe concrete reference error magnitudes and the specific gold scheme are kept out of this field and placed only in the uploaded evaluation dependencies, so no\nanswer-key information reaches the solving agent even if this text is surfaced to\nit. No acceptance threshold is derived from the reference implementation's own\nerror values.","software_and_version":"Python >=3.11 and <3.14, NumPy 2.4.6, SciPy 1.17.1","specific_requirements":null,"expected_completion_time":null},"files":[{"file_id":"232fdafc-fabd-40d5-9896-1d8f6cd48558","filename":"problem_spec.md","category":"input_materials","content_type":"text/markdown","size_bytes":14527},{"file_id":"f4b406c9-b771-4ca6-b37a-371aa1b57c14","filename":"python.sh","category":"input_materials","content_type":"application/x-sh","size_bytes":2143},{"file_id":"80f79a2e-5d48-44ca-98d3-58f0b3a9f285","filename":"pyproject.toml","category":"input_materials","content_type":"application/octet-stream","size_bytes":248},{"file_id":"080cdfb1-9724-41f6-af84-71d40bee0677","filename":"uv.lock","category":"input_materials","content_type":"application/octet-stream","size_bytes":29651},{"file_id":"f3b73992-6e24-45c0-a887-e550494e4afa","filename":"reference_arrays.npz","category":"reference_output","content_type":"application/octet-stream","size_bytes":518954},{"file_id":"2c9420d6-ee2e-4025-9e27-5b31325ef067","filename":"adi_solver.py","category":"reference_output","content_type":"text/x-python-script","size_bytes":8037},{"file_id":"b3f3155d-7f0a-4b08-9fa1-d076e1cf3df6","filename":"results.json","category":"reference_output","content_type":"application/json","size_bytes":1144},{"file_id":"0e813b52-ce7c-4472-943d-cbe0b8c97580","filename":"EVALUATION.md","category":"reference_output","content_type":"text/markdown","size_bytes":14438},{"file_id":"2a519e70-b581-4129-bb2f-9d739f9a7e9e","filename":"scheme_survey.py","category":"reference_output","content_type":"text/x-python-script","size_bytes":11409},{"file_id":"fc583952-b92c-4cf4-bf2b-7be02dfcb2ce","filename":"grade.py","category":"reference_output","content_type":"text/x-python-script","size_bytes":57213}],"deep_review":{"overall_verdict":"Strong Accept","review_text":"**Overall Verdict:** Strong Accept — The submission is complete, internally consistent, professionally scoped, and supports an objective end-to-end implementation and evaluation workflow.\n\n**Completeness Check:**\n- Instruction: Complete — The PDE, coefficients, boundary and initial data, discretization, solver interface, ADI constraints, mesh sequence, artifacts, and acceptance thresholds are explicit.\n- Inputs: Complete — The specification and runtime materials provide all numerical parameters, call signatures, dependency versions, and staging conventions needed to implement the solver.\n- Toolchain: Complete — Python 3.11–3.13 with pinned NumPy 2.4.6 and SciPy 1.17.1 is legally obtainable on Linux; the wrapper provides a locked-environment path and a clearly disclosed fallback.\n- Reference output: Complete — The reference solver, JSON results, and eight-array NPZ are present and coherent. The arrays use little-endian float64 with the required `(5,)` and `(161,161)` shapes; the grid, analytic solution, error surface, boundary values, convergence errors, and sidecar values agree numerically.\n- Rubric: Complete — The grader defines unambiguous 1.0, 0.5, and 0.0 outcomes and checks schema, convergence, hidden-instance generality, provenance, pointwise field reproduction, dependency restrictions, causal use of solves, and ADI solve structure.\n\n**File and Task Reachability:**\nAttachment classification: reachable. Task classification: reachable. The inspected files were `problem_spec.md`, `python.sh`, `pyproject.toml`, `uv.lock`, `reference_arrays.npz`, `adi_solver.py`, `results.json`, `EVALUATION.md`, `scheme_survey.py`, and `grade.py`; no manifested attachment was left unreviewed. All byte counts matched the manifest. The NPZ was valid, unencrypted, free of unsafe paths, and passed container integrity checks. Its reported errors decrease by approximately 208.7×, have fitted order 1.929, and match the exact finest-grid error.\n\nUploaded programs were inspected statically and not executed, as required by the safety policy. This did not prevent verification of their structure or the numerical artifacts. Solver-visible inputs are clearly separated from protected reference and evaluator assets. A contributor can implement the solver using the pinned environment, emit the three required outputs, and be evaluated through deterministic public-grid checks plus protected hidden-instance and causal-sweep checks on an ordinary single machine.\n\nLicense keys, accounts, tokens, and other credentials are not required from the contributor. Confidential, proprietary, or internal material may be evaluated as submitted evidence without requiring additional disclosure.\n\n**Special Screening:**\nNone. No affirmative evidence supports an `ai_synthetic`, `public_benchmark`, or `synthetic_defect_fixture` label. Public identifiability was not externally verified because approved search was unavailable.\n\n**Recommended Changes:**\nThe submission already provides a rigorous implementation contract, truthful reference artifacts, and unusually thorough anti-shortcut evaluation coverage. No changes are required.","reviewed_at":"2026-08-17T01:47:40.194317Z"},"claim":null}