Skip to content

Feat/Split WL and Layer + Feat/Add Schöttner E(ρ) elasticity + Chore/Test Suite to Pytest - #54

Merged
pillowbeast merged 7 commits into
mainfrom
feat/weak-layer-elasticity
Aug 6, 2026
Merged

Feat/Split WL and Layer + Feat/Add Schöttner E(ρ) elasticity + Chore/Test Suite to Pytest#54
pillowbeast merged 7 commits into
mainfrom
feat/weak-layer-elasticity

Conversation

@pillowbeast

@pillowbeast pillowbeast commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Split WeakLayer into weac.components.weak_layer, keeping slab layers in Layer
  • Derive weak-layer Young's modulus from the Schöttner FC&DH density law (E_method="schottner_fc_dh")
  • Lower weak-layer preset densities to 100/150/200 kg/m³ so named presets stay within the Schöttner ≤250 kg/m³ range
  • Migrate the test suite from unittest to pytest (CI + pyproject.toml)

Summary by CodeRabbit

  • New Features

    • Added a dedicated weak-layer model with improved material-property and collapse-height calculations.
    • Added support for faceted-crystal and depth-hoar modulus parameterization.
    • Updated weak-layer presets with strength-specific densities.
  • Documentation

    • Added API documentation for weak-layer functionality.
    • Updated README with v3.2 release notes and current test instructions.
  • Chores

    • Migrated the test suite to pytest for more consistent test execution.

pillowbeast and others added 6 commits July 27, 2026 10:55
- Extracted `WeakLayer` into `weac.components.weak_layer`, leaving slab layers in `layer`.
- Replaced the weak-layer Young's modulus with Schottner's density-dependent formulation and matching constants.
- Updated imports, docs, and tests for the split and new elasticity law.
- Replaced unittest with pytest in all test files for consistency and improved functionality.
- Added pytest configuration in pyproject.toml and updated test paths.
- Removed the legacy test runner script and adjusted test execution commands in CI workflows.
- Enhanced existing tests to utilize pytest assertions for better readability and maintainability.
Keep Schöttner E(ρ) within its intended ≤250 kg/m³ range for the named presets.

Co-authored-by: Cursor <cursoragent@cursor.com>
Bring in lowered weak-layer preset densities (100/150/200 kg/m³).

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI lite review requested due to automatic review settings August 5, 2026 15:40
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@pillowbeast, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a5002edb-5636-4f2e-97a2-51f878a47794

📥 Commits

Reviewing files that changed from the base of the PR and between 9a1cc49 and 74150f7.

📒 Files selected for processing (10)
  • README.md
  • src/weac/components/layer.py
  • src/weac/components/weak_layer.py
  • tests/analysis/test_criteria_evaluator.py
  • tests/components/test_configs.py
  • tests/components/test_layer.py
  • tests/core/test_eigensystem.py
  • tests/core/test_field_quantities.py
  • tests/core/test_scenario.py
  • tests/test_regression_simulation.py
📝 Walkthrough

Walkthrough

The change separates WeakLayer into its own module, updates weak-layer defaults and presets, adds pytest tooling, migrates the test suite from unittest, updates regression baselines, and documents the new module.

Changes

WeakLayer separation and model updates

Layer / File(s) Summary
Dedicated WeakLayer model and integration
src/weac/components/*, src/weac/constants.py, src/weac/analysis/plotter.py, src/weac/core/slab_touchdown.py
Adds the validated WeakLayer model, modulus and collapse-height calculations, compatibility exports, new constants, updated imports, and revised weak-layer defaults and presets.

Pytest migration and project support

Layer / File(s) Summary
Pytest tooling and documentation
.github/workflows/tests.yml, pyproject.toml, tests/conftest.py, README.md, TODO.md, docs/sphinx/*, .gitignore
Configures pytest in development and CI, removes the legacy test command, documents the new module, and updates project notes.
Analysis test migration
tests/analysis/*
Converts analyzer, criteria evaluator, and tensile comparison tests to pytest fixtures, parametrization, and assertions.
Component test migration
tests/components/*
Converts configuration and layer tests to pytest while retaining validation, physical consistency, and modulus coverage.
Core test migration
tests/core/*
Converts eigensystem, field, scenario, slab, touchdown, and system-model tests to pytest fixtures and assertions.
Regression and utility test migration
tests/test_*.py, tests/utils/*
Converts regression and utility tests to pytest and updates numerical regression baselines.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • 2phi/weac#48: Directly overlaps in WeakLayer, presets, and related tests.
  • 2phi/weac#34: Also changes weak-layer handling in plotter.py.
  • 2phi/weac#52: Overlaps in the analysis test modules.

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically summarizes the three main changes: weak-layer/layer component split, Schöttner elasticity addition, and test suite migration to pytest.
Docstring Coverage ✅ Passed Docstring coverage is 99.60% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/weak-layer-elasticity

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/weac/components/weak_layer.py`:
- Around line 129-133: Update WeakLayer.model_post_init to enforce the
schottner_fc_dh density limit before deriving E: when E is zero or unset, reject
rho values above 250 with a validation error, while allowing rho=250 and
preserving caller-supplied E or other methods. Add boundary tests covering
rho=250 and rho=251.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 15e44f5f-fa5e-4bab-91cc-465a34b28c9b

📥 Commits

Reviewing files that changed from the base of the PR and between 206e897 and 9a1cc49.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (33)
  • .github/workflows/tests.yml
  • .gitignore
  • README.md
  • TODO.md
  • docs/sphinx/weac.components.rst
  • docs/sphinx/weac.components.weak_layer.rst
  • pyproject.toml
  • src/weac/analysis/plotter.py
  • src/weac/components/__init__.py
  • src/weac/components/layer.py
  • src/weac/components/model_input.py
  • src/weac/components/presets.py
  • src/weac/components/weak_layer.py
  • src/weac/constants.py
  • src/weac/core/slab_touchdown.py
  • tests/analysis/test_analyzer.py
  • tests/analysis/test_criteria_evaluator.py
  • tests/analysis/test_slab_tensile_comparisons.py
  • tests/components/test_configs.py
  • tests/components/test_layer.py
  • tests/conftest.py
  • tests/core/test_eigensystem.py
  • tests/core/test_field_quantities.py
  • tests/core/test_scenario.py
  • tests/core/test_slab.py
  • tests/core/test_slab_touchdown.py
  • tests/core/test_system_model.py
  • tests/run_tests.py
  • tests/test_comparison_results.py
  • tests/test_regression_simulation.py
  • tests/utils/test_json_helpers.py
  • tests/utils/test_misc.py
  • tests/utils/test_snowpilot_parser.py
💤 Files with no reviewable changes (1)
  • tests/run_tests.py

Comment thread src/weac/components/weak_layer.py

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors WEAC’s component model boundaries by extracting WeakLayer into its own module, introduces a Schöttner FC&DH density-based elasticity option for the weak layer, and migrates the Python test suite + CI execution from unittest to pytest.

Changes:

  • Split weak-layer modeling into weac.components.weak_layer while keeping slab layers in Layer, updating imports/presets/defaults accordingly.
  • Add Schöttner FC&DH density-law Young’s modulus support (E_method="schottner_fc_dh") and adjust weak-layer preset densities to stay within the stated applicability range.
  • Convert the full test suite + CI runner from unittest (custom runner) to pytest (fixtures/parametrization, pyproject.toml + workflow updates).

Reviewed changes

Copilot reviewed 32 out of 34 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
uv.lock Adds pytest and its dependencies to the locked environment.
TODO.md Updates roadmap items; removes now-completed “Swap to Pytest” note and adds new modeling TODOs.
tests/utils/test_snowpilot_parser.py Migrates SnowPilot parser tests from unittest to pytest fixtures/asserts.
tests/utils/test_misc.py Migrates misc utility tests to pytest and updates skip behavior.
tests/utils/test_json_helpers.py Converts JSON helper tests to pytest; adds parametrized cases.
tests/test_regression_simulation.py Migrates regression suite to pytest and updates numeric baselines.
tests/test_comparison_results.py Migrates integration comparison tests to pytest assertions/approximations.
tests/run_tests.py Removes legacy unittest-based test runner script.
tests/core/test_system_model.py Refactors SystemModel tests to pytest fixtures and helper builder.
tests/core/test_slab.py Migrates slab tests to pytest and approx-based float checks.
tests/core/test_slab_touchdown.py Converts touchdown tests to pytest fixtures and assertions.
tests/core/test_scenario.py Migrates Scenario tests to pytest fixtures and pytest.raises.
tests/core/test_field_quantities.py Converts extensive FieldQuantities suite to pytest fixtures.
tests/core/test_eigensystem.py Migrates eigensystem tests to pytest fixtures and assertions.
tests/conftest.py Adds pytest-wide logging setup.
tests/components/test_layer.py Updates layer/weak-layer tests for the split + Schöttner modulus; migrates to pytest.
tests/components/test_configs.py Migrates config/scenario/criteria/segment/model-input tests to pytest.
tests/analysis/test_slab_tensile_comparisons.py Uses pytest fixture + parametrization for ordering comparisons.
tests/analysis/test_analyzer.py Migrates Analyzer tests to pytest fixtures and assertions.
src/weac/core/slab_touchdown.py Updates WeakLayer import to new module path.
src/weac/constants.py Introduces Schöttner-law constants (CS0, CS1).
src/weac/components/weak_layer.py New WeakLayer model with Schöttner FC&DH elasticity method + stiffness derivations.
src/weac/components/presets.py Updates WeakLayer presets (densities) to align with Schöttner range and derived E.
src/weac/components/model_input.py Updates WeakLayer import and default weak-layer factory (now density-law derived).
src/weac/components/layer.py Removes embedded WeakLayer implementation and re-exports WeakLayer for compatibility.
src/weac/components/init.py Updates exports to import WeakLayer from the new module.
src/weac/analysis/plotter.py Updates WeakLayer import to new module path.
README.md Updates test-running docs to use uv run pytest; adds v3.2 release notes for the refactor.
pyproject.toml Adds pytest dev dependency and pytest config (testpaths).
docs/sphinx/weac.components.weak_layer.rst Adds Sphinx automodule docs for the new weak-layer module.
docs/sphinx/weac.components.rst Includes the new weak-layer module in the components documentation.
.gitignore Adds todo/ directory to ignored local-dev artifacts.
.github/workflows/tests.yml Updates CI to install dev extras and run pytest directly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/weac/components/weak_layer.py Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PR Quality Assessment — PR #54

Reviewed the diff for WeakLayer module split, Schöttner FC&DH elasticity (E_method="schottner_fc_dh"), preset/default changes, and pytest migration.

Outcome: 1 medium-severity finding. No high/critical bugs or security vulnerabilities identified.

Validated areas

  • Schöttner formula constants and unit tests match paper benchmarks (~1.5 MPa @ 150 kg/m³, ~24 MPa @ 250 kg/m³)
  • WeakLayer module split + lazy re-export from layer.py works at runtime
  • Preset density/E derivation tests pass; 232/234 tests pass locally (2 test_comparison_results failures are reference-env setup, not PR logic; CI is green)
  • collapse_height >= h validation raises as expected
  • No injection/auth/network attack surface in modified code

Top finding

  • Schöttner density extrapolation (Medium): Default schottner_fc_dh silently extrapolates beyond the documented ≤250 kg/m³ range, producing materially wrong E/kn/kt (e.g. ρ=300 → E≈65 MPa)

Prior threads

  • No prior automation review threads from this workflow to reconcile.
  • CodeRabbit/Copilot threads on this PR are outside this automation's scope.
Open in Web View Automation 

Sent by Cursor Automation: Check PR


model_config = ConfigDict(
frozen=True,
extra="forbid",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Category: Bug / Test Coverage Gap
Severity: Medium

Issue & Impact: With the new default E_method="schottner_fc_dh", E is derived from density without enforcing the documented ≤250 kg/m³ calibration range (v3.2 release notes). Callers that omit E can silently extrapolate outside the validated window — e.g. WeakLayer(rho=300, h=10) yields E≈65 MPa (vs ~24 MPa at ρ=250), which also skews derived G, kn, and kt. The same path is reachable via weak_layer_from_preset(..., rho=300).

Remediation: When E_method == "schottner_fc_dh" and E is unset/zero, reject rho > 250 with a ValueError (allow ρ=250), or require an explicit E / alternate E_method. Add boundary tests for rho=250 (accepted) and rho=251 (rejected).

@pillowbeast
pillowbeast merged commit 31854b7 into main Aug 6, 2026
4 checks passed
@pillowbeast
pillowbeast deleted the feat/weak-layer-elasticity branch August 6, 2026 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants