Overview
Every Veydra model is a standalone Python project hosted on GitHub. You can clone any model repository and run it locally with standard Python tooling — no special platform or runtime required. This page walks through the repository structure, setup, execution, and testing workflow that all models follow.Quick Start
1
Clone the Repository
Each model lives in its own GitHub repo. Clone it to your machine:
2
Create a Virtual Environment
3
Install Dependencies
4
Run the Model
Requirements
Python 3.11+
A local Python installation. Any recent 3.11+ version works.
pip
Used to install dependencies from
requirements.txt.Dependencies
All models declare their dependencies inrequirements.txt. A typical model requires:
Repository Structure
Every model repository follows the same layout:Key Files
main.py
main.py
The command-line entry point. Initializes the model, runs a default simulation, then runs an interactive simulation with the same defaults to validate the full pipeline.
src/model.py
src/model.py
Contains the master orchestrator class (inherits from
VeydraModelStandard) and the two contract functions — initialize_model() and run_interactive_simulation(). This is where submodels are wired together, derivatives are computed, and the ODE solver is invoked.config/outputs.json
config/outputs.json
Controls which stocks and flows are included in simulation results. All variables are computed internally, but only those listed here are returned.
config/presets.json
config/presets.json
Defines named scenarios with specific parameter overrides. Each preset has an
id, a description, and a variables dict of parameter values.config/model-parameters.json
config/model-parameters.json
Full metadata for every parameter: label, min/max, step, default, units, category, and namespace. Generated automatically by the Veydra AST analysis pipeline.
The Model Contract
Every VMS-compliant model exposes two functions fromsrc/model.py:
initialize_model()— creates the model instance, runs a simulation with default parameters, and returns both the instance and the default results dict.run_interactive_simulation()— takes an existing model instance and a dict of parameter overrides, re-runs the simulation, and returns updated results. Passreturn_json=Trueto get a JSON string instead of a Python dict.
Results Format
Both functions return a results dictionary with this shape:submodel.variable_name).
Running Simulations
Default Run
Custom Parameters
You can override parameters programmatically by passing a dictionary torun_interactive_simulation():
Running Presets
Presets fromconfig/presets.json can be loaded and passed directly:
Testing
All models ship with two test files:Smoke Tests
Full Test Suite
- Default parameters — model runs and returns valid numeric results
- All presets — every preset from
config/presets.jsonis run and validated automatically
Model Architecture
Submodels
Models are decomposed into submodels — one per domain (e.g.,population_submodel.py, resource_submodel.py). Each submodel:
- Defines its own
VARIABLESdict with parameter metadata - Inherits from the
Submodelbase class inveydra_model_standard.py - Implements a
calculate_derivatives_and_flows()method
src/model.py wires all submodels together, collects their derivatives, and passes them to SciPy’s ODE solver (solve_ivp).
Parameter Namespacing
All parameters use asubmodel.variable_name naming convention to avoid collisions:
Simulation Variables
In addition to submodel parameters, every model has a set ofsimulation.* variables controlling execution:

