Instructions to use lowdown-labs/fela-pde with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use lowdown-labs/fela-pde with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-to-image", model="lowdown-labs/fela-pde", trust_remote_code=True)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("lowdown-labs/fela-pde", trust_remote_code=True, dtype="auto") - Notebooks
- Google Colab
- Kaggle
- DISCLAIMER
- FELA PDE: on device 2D thermal field surrogate for battery packs
- What goes in, what comes out
- Building an input (for battery and BMS engineers)
- Why we built it this way
- Architecture
- Training data
- How to run it
- Serving artifacts
- Intended use, limitations, and safety
- Acknowledgements and references
- Model family
- License
DISCLAIMER
This model is a research preview. Lowdown Labs has put together this model in the interest of advancing public science.
FELA PDE: on device 2D thermal field surrogate for battery packs
Give FELA PDE the layout of a battery pack, its heat load, and how it is being cooled, and it tells you where the pack runs hot. It returns the full steady state temperature map in one fast pass, standing in for a slower finite volume solve. It runs on a plain CPU with no GPU, so it can sit inside a battery management tool, a design loop, or an on premises engineering app and flag hot spots without a cloud round trip.
What ships in this repo is the small web lite version: 892,545 parameters, about 7.1 MB in fp32. The larger validated teacher is a separate line and is not shipped here.
What goes in, what comes out
- Input: an 8 channel physics field on a 96x96 grid, shape
(1, 8, 96, 96). The channels, in order, aremask(pack solid region),q_source(volumetric heat source, the hot spot),k_field(thermal conductivity),h_conv(convective heat transfer coefficient),T_amb(ambient temperature),x_coord,y_coord(normalized 0..1 coordinates), andlog_domain_L(log of the physical domain size). Each channel is standardized with the training statistics that ship inconfig.json;modeling.preprocessdoes this for you. - Output: a 1 channel normalized temperature field, shape
(1, 1, 96, 96).modeling.denormalizeconverts it to degrees Celsius using the training y statistics (Y_degC = Ynorm * y_std + y_mean). - In plain terms: give it the pack geometry, the heat load, and the cooling conditions, and it returns the predicted temperature map so an engineer can see where the pack runs hot.
Building an input (for battery and BMS engineers)
You do not hand build the 8 channel tensor. input_builder.py (an add on shipped in this repo)
builds it from ordinary pack parameters, matching the exact encoding the model was trained on
(the coordinate planes, log_domain_L, and the per channel standardization from config.json).
Two of the channels and log_domain_L are model conventions, not physics you supply. The
physical channels and their units are:
| Channel | Meaning | Units | Typical range |
|---|---|---|---|
| mask | 1 inside a cell, 0 in the coolant | none | 0 or 1 |
| q_source | heat source density in the cells | W/m3 | derived from current, SoC, R0 |
| k_field | thermal conductivity | W/(m K) | cell 1 to 30, coolant 0.1 to 1.5 |
| h_conv | convective heat transfer coefficient | W/(m2 K) | 5 to 200 |
| T_amb | ambient temperature | degC | 15 to 40 |
| x_coord | normalized column position (the builder sets this) | none | 0 to 1 |
| y_coord | normalized row position (the builder sets this) | none | 0 to 1 |
| log_domain_L | natural log of the physical pack size (the builder sets this) | ln(m) | pack 0.02 to 0.12 m |
The model was trained on this distribution; inputs well outside these ranges are not characterized.
The BMS path: from_pack
Give it a cell layout and pack parameters. It computes the heat source
(P = current^2 * R0 * (1 + beta * (1 - SoC)^2), spread over the cell area), the conductivity map,
and the rest, then returns a ready to run (1, 8, 96, 96) tensor:
import torch
from input_builder import from_pack, cylinder_mask
from modeling import load_model, denormalize
model = load_model(".")
mask = cylinder_mask(rows=3, cols=4, radius_frac=0.4) # a 3 by 4 cylindrical cell pack
x = from_pack(
mask,
current_A=40.0, soc=0.3, R0_ohm=0.02,
k_cell_W_mK=20.0, k_coolant_W_mK=0.6,
h_conv_W_m2K=80.0, T_amb_degC=25.0, domain_L_m=0.08,
)
with torch.no_grad():
T = denormalize(model(x))[0, 0] # a 96 by 96 temperature map in degC
print("peak", float(T.max()), "degC")
cylinder_mask(rows, cols, radius_frac) and rect_mask(aspect, fill) build the geometry mask.
example.py runs this end to end and prints the peak temperature and hottest cell.
The field path: from_fields
If you already have physical field maps (say from your own thermal model), pass them directly instead of pack parameters:
from input_builder import from_fields
x = from_fields(mask, q_source_W_m3, k_field_W_mK, h_conv_W_m2K, T_amb_degC, domain_L_m)
Each argument is a 96 by 96 array or a scalar (scalars are broadcast). The builder grids each to 96 by 96, adds the coordinate and size channels, standardizes, and returns the model ready tensor. It is verified to reproduce the training encoding exactly.
From a file: from_csv and from_json
If your pack parameters live in a file, point the builder at it. pack.csv (a header row plus one
values row) or pack.json (a flat object) use the same field names as from_pack, plus a geometry
(rows, cols, radius_frac for a cylindrical pack, or aspect, fill for a prismatic block):
import torch
from input_builder import from_csv
from modeling import load_model, denormalize
x = from_csv("pack.csv") # from_json("pack.json") works the same way
with torch.no_grad():
T = denormalize(load_model(".")(x))[0, 0]
Example pack.csv and pack.json ship in this repo.
NB - real battery data comes in many shapes this repo does not read yet, such as
vendor spreadsheets with their own columns, CAD geometry like STEP or STL, and simulation exports
from tools like COMSOL or ANSYS. from_csv and from_json handle the flat parameter case, which
is the common one. If you already have a geometry or a field as numbers, load it into a 96 by 96
array yourself and pass it to from_fields.
Why we built it this way
A temperature field is smooth and slowly varying, so we mix information in the frequency domain rather than pixel by pixel. That is what a Fourier Neural Operator does, it learns filters that act on the field's frequencies (an FFT, a learned filter, an inverse FFT), which suits a smooth solution field well. The model is small and has no all pairs attention. One forward pass produces the whole 96x96 map on a plain CPU, far faster than solving the same field directly with a finite volume method.
Architecture
- 2D FNO: a lifting
Conv2d(8 -> 32, 1x1), then 3 spectral plus pointwise residual blocks (SpectralConv2dkeeping 12x12 low and high Fourier modes plus aConv2d(32,32,1x1)skip, GELU residual), then a projection headConv2d(32 -> 128, 1x1) -> GELU -> Conv2d(128 -> 1, 1x1). - 892,545 parameters. The full architecture is in
modeling.py; the arch dims and normalization statistics are inconfig.json.
Training data
- Self generated. Every training, validation, and test sample is produced on CPU by a
deterministic steady state heat equation finite volume solver (pure NumPy and SciPy). No external
dataset is downloaded, scraped, or redistributed. The PDE, the geometry parameterization, and
the input and target encoding are reproduced in
train.py(--smokeregenerates the split and asserts the sizes). Full details, seeds, and the split are intrain.py. - License: none required. The generator is our own code; the finite volume method and the Fourier Neural Operator (Li et al., ICLR 2021) are published methods, not licensed data. Commercially clean.
The shipped train.py reproduces the primary battery 2D training recipe (a larger FNO2dV32
teacher with a length scale channel and an energy balance peak prior). The weights shipped here
are the distilled web lite student described above.
How to run it
from huggingface_hub import hf_hub_download
import modeling
path = hf_hub_download("lowdown-labs/fela-pde", "model.safetensors")
model = modeling.load_model(path) # or load_model("/path/to/weights_dir")
# raw_field: an (8, 96, 96) physics field in physical units
x = modeling.preprocess(raw_field) # standardizes and validates shape
import torch
with torch.no_grad():
y_norm = model(x) # (1, 1, 96, 96) normalized temperature
y_degc = modeling.denormalize(y_norm) # degrees Celsius
verify.py runs a fixed sample input and checks the output shape and a verification value.
Serving artifacts
model.safetensorsplusconfig.jsonfor the safetensors load path (fp32).verify.pyruns a fixed sample input and checks the output shape and a verification value.
Intended use, limitations, and safety
- This is a surrogate, not a certified thermal safety tool. Use its output as a fast screening and design aid, not as the sole basis for a safety critical decision. Validate against a full solver on your own configurations before relying on it.
- Trained and evaluated only on the self generated battery thermal distribution described above. Geometries, materials, and boundary conditions outside that distribution are not characterized here.
- This is the distilled web lite student. The larger validated checkpoints (battery and heatsink, 2D and 3D) are a separate line.
Acknowledgements and references
- Fourier Neural Operator: Li, Z., Kovachki, N., Azizzadenesheli, K., et al. (2021). Fourier Neural Operator for Parametric Partial Differential Equations. ICLR. https://arxiv.org/abs/2010.08895
- Finite volume heat transfer: Patankar, S. V. (1980). Numerical Heat Transfer and Fluid Flow.
- SciPy: Virtanen, P., et al. (2020). Nature Methods 17, 261-272.
- PyTorch: Paszke, A., et al. (2019). NeurIPS. https://arxiv.org/abs/1912.01703
Model family
This is part of the FELA family from Lowdown Labs: one Fourier Neural Operator architecture
across many modalities, all CPU native and subquadratic. Sibling repos are independently
trained per modality and share no weights, so none carries a base_model link.
License
Released under the Lowdown Labs Lovely License 1.0 (CC BY-NC 4.0 plus Hippocratic License 3.0). See LICENSE. For most LL models, a commercial license may be available; contact Lowdown Labs.
- Downloads last month
- 1