


Implementation of closed-form analytical models for the analysis of dry-snow slab avalanche release.
View the demo ·
Report a bug ·
Request a feature ·
Read the docs ·
Cite the software
WEAC implements closed-form analytical models for the mechanical analysis of dry-snow slabs on compliant weak layers, the prediction of anticrack onset, and, in particular, allows for the analysis of stratified snow covers. The model covers propagation saw tests (a), and uncracked (b) or cracked (c) skier-loaded buried weak layers.
Cite the repository as:
Rosendahl, P. L., Schneider, J., & Weissgraeber, P. (2022). Weak Layer Anticrack Nucleation Model (WEAC). Zenodo. https://doi.org/10.5281/zenodo.5773113
Read the 📄 white paper for model derivations, illustrations, dimensions, material properties, and kinematics:
- Weißgraeber, P. & Rosendahl, P. L. (2023). A closed-form model for layered snow slabs. The Cryosphere, 17(4), 1475–1496. https://doi.org/10.5194/tc-17-1475-2023
For more background info, please refer to the companion papers:
- Rosendahl, P. L. & Weißgraeber, P. (2020). Modeling snow slab avalanches caused by weak-layer failure – Part 1: Slabs on compliant and collapsible weak layers. The Cryosphere, 14(1), 115–130. https://doi.org/10.5194/tc-14-115-2020
- Rosendahl, P. L. & Weißgraeber, P. (2020). Modeling snow slab avalanches caused by weak-layer failure – Part 2: Coupled mixed-mode criterion for skier-triggered anticracks. The Cryosphere, 14(1), 131–145. https://doi.org/10.5194/tc-14-131-2020
Written in 🐍 Python and built with 💻 Visual Studio Code, 🐙 GitKraken, and 🪐 Jupyter. Note that release v1.0 was written and built in 🌋 MATLAB.
Install globally using the pip
Package Installer for Python
pip install -U weac
or clone the repo
git clone https://github.com/2phi/weac
for local use.
Needs (runtime dependencies are declared in pyproject.toml):
The following describes the basic usage of WEAC. Please refer to the demo for more examples and read the documentation for details.
Load the module.
import weac
Choose a snow profile from the preconfigured profiles (see dummy_profiles
in demo) or create your own using the Layer
Pydantic class. One row corresponds to one layer counted from top (below surface) to bottom (above weak layer).
from weac.components import Layer
layers = [
Layer(rho=170, h=100), # (1) surface layer
Layer(rho=190, h=40), # (2)
Layer(rho=230, h=130), # :
Layer(rho=250, h=20),
Layer(rho=210, h=70),
Layer(rho=380, h=20), # :
Layer(rho=280, h=100) # (N) last slab layer above weak layer
]
Create a WeakLayer instance that lies underneath the slab.
from weac.components import WeakLayer
weak_layer = WeakLayer(rho=125, h=20)
Create a Scenario that defines the environment and setup that the slab and weak layer will be evaluated in.
from weac.components import ScenarioConfig, Segment
# Example 1: SKIER
skier_config = ScenarioConfig(
system_type='skier',
phi=30,
)
skier_segments = [
Segment(length=5000, has_foundation=True, m=0),
Segment(length=0, has_foundation=False, m=80),
Segment(length=0, has_foundation=False, m=0),
Segment(length=5000, has_foundation=True, m=0),
] # Scenario is a skier of 80 kg standing on a 10 meter long slab at a 30 degree angle
# Exampel 2: PST
pst_config = ScenarioConfig(
system_type='pst-', # Downslope cut
phi=30, # (counterclockwise positive)
cut_length=300,
)
pst_segments = [
Segment(length=5000, has_foundation=True, m=0),
Segment(length=300, has_foundation=False, m=0), # Crack Segment
] # Scenario is Downslope PST with a 300mm cut
Create a SystemModel instance that combines the inputs and handles system solving and field-quantity extraction.
from weac.components import Config, ModelInput
from weac.core.system_model import SystemModel
# Example: build a model for the skier scenario defined above
model_input = ModelInput(
weak_layer=weak_layer,
scenario_config=skier_config,
layers=custom_layers,
segments=skier_segments,
)
system_config = Config(
touchdown=True
)
skier_system = SystemModel(
model_input=model_input,
config=system_config,
)
Unknown constants are cached_properties; calling skier_system.unknown_constants
solves the system of linear equations and extracts the constants.
C = skier_system.unknown_constants
Analyzer handles rasterization + computation of involved slab and weak-layer properties Sxx
, Sxz
, etc.
Prepare the output by rasterizing the solution vector at all horizontal positions xsl
(slab). The result is returned in the form of the ndarray z
. We also get xwl
(weak layer) that only contains x-coordinates that are supported by a foundation.
from weac.analysis.analyzer import Analyzer
skier_analyzer = Analyzer(skier_system)
xsl_skier, z_skier, xwl_skier = skier_analyzer.rasterize_solution(mode="cracked")
Gdif, GdifI, GdifII = skier_analyzer.differential_ERR()
Ginc, GincI, GincII = skier_analyzer.incremental_ERR()
# and Sxx, Sxz, Tzz, principal stress, incremental_potential, ...
Visualize the results.
from weac.analysis.plotter import Plotter
plotter = Plotter()
# Visualize slab profile
fig = plotter.plot_slab_profile(
weak_layers=weak_layer,
slabs=skier_system.slab,
)
# Visualize deformations as a contour plot
fig = plotter.plot_deformed(
xsl_skier, xwl_skier, z_skier, skier_analyzer, scale=200, window=200, aspect=2, field="Sxx"
)
# Plot slab displacements (using x-coordinates of all segments, xsl)
plotter.plot_displacements(skier_analyzer, x=xsl_skier, z=z_skier)
# Plot weak-layer stresses (using only x-coordinates of bedded segments, xwl)
plotter.plot_stresses(skier_analyzer, x=xwl_skier, z=z_skier)
Compute output/field quantities for exporting or plotting.
# Compute stresses in kPa in the weaklayer
tau = skier_system.fq.tau(Z=z_skier, unit='kPa')
sig = skier_system.fq.sig(Z=z_skier, unit='kPa')
w = skier_system.fq.w(Z=z_skier, unit='um')
# Example evaluation vertical displacement at top/mid/bottom of the slab
u_top = skier_system.fq.u(Z=z_skier, h0=top, unit='um')
u_mid = skier_system.fq.u(Z=z_skier, h0=mid, unit='um')
u_bot = skier_system.fq.u(Z=z_skier, h0=bot, unit='um')
psi = skier_system.fq.psi(Z=z_skier, unit='deg')
See the open issues for a list of proposed features and known issues.
- Change to scenario & scenario_config: InfEnd/Cut/Segment/Weight
- Complex terrain through the addition of out-of-plane tilt
- Up, down, and cross-slope cracks
- Improved CriteriaEvaluator Optimization (x2 time reduction)
- Refactored the codebase for improved structure and maintainability
- Added property caching for improved efficiency
- Added input validation
- Adopted a new, modular, and object-oriented design
- Introduced test suite
- Mitraged from
setup.cfg
topyproject.toml
- Added parametrization for collaps heights
- Analyze slab touchdown in PST experiments by setting
touchdown=True
- Completely redesigned and significantly improved API documentation
- Choose between slope-normal (
'-pst'
,'pst-'
) or vertical ('-vpst'
,'vpst-'
) PST boundary conditions
- Stress plots on deformed contours
- PSTs now account for slab touchdown
- Sign of inclination
phi
consistent with the coordinate system (positive counterclockwise) - Dimension arguments to field-quantity methods added
- Improved aspect ratio of profile views and contour plots
- Improved plot labels
- Convenience methods for the export of weak-layer stresses and slab deformations provided
- Wrapper for (re)calculation of the fundamental system added
- Now allows for distributed surface loads
- Consistent use of coordinate system with downward pointing z-axis
- Consitent top-to-bottom numbering of slab layers
- Implementation of PSTs cut from either left or right side
- Completely rewritten in 🐍 Python
- Coupled bending-extension ODE solver implemented
- Stress analysis of arbitrarily layered snow slabs
- FEM validation of
- displacements
- weak-layer stresses
- energy release rates in weak layers
- Documentation
- Demo and examples
- Written in 🌋 MATLAB
- Deformation analysis of homogeneous snow labs
- Weak-layer stress prediction
- Energy release rates of cracks in weak layers
- Finite fracture mechanics implementation
- Prediction of anticrack nucleation
-
Fork the project
-
Initialize submodules
git submodule update --init --recursive
-
Create your feature branch (
git checkout -b feature/amazingfeature
) -
Commit your changes (
git commit -m 'Add some amazing feature'
) -
Push to the branch (
git push origin feature/amazingfeature
) -
Open a pull request
WEAC is licensed under CC BY-NC-SA 4.0
You are free to:
- Share — copy and redistribute the material in any medium or format
- Adapt — remix, transform, and build upon the material for any purpose, even commercially.
Under the following terms:
-
Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
-
NonCommercial — You may not use the material for commercial purposes.
-
ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
E-mail: mail@2phi.de · Web: https://2phi.de · Project Link: https://github.com/2phi/weac · Project DOI: http://dx.doi.org/10.5281/zenodo.5773113

Leave a Reply