I'm Building an Open-Source Python FEM Solver — Here's Where QF Solver 0.2.7 Stands
For some time now, I've been working on a personal project called QF Solver.
It's an open-source finite-element solver written in Python, mainly focused on structural mechanics and dynamics.
I'm not going to pretend that it is ready to replace Code_Aster, CalculiX, Abaqus, or every other FEM solver out there.
It isn't.
But the project has reached a point where I think it's interesting enough to start showing it publicly, explaining what I'm trying to build, what already works, and also what still needs a lot of work.
So... here it is.
Please keep in mind that this is still a relatively young solver. I'm trying to make it serious and reproducible, but I'm also learning a lot while building it.
Why am I building another FEM solver?
The short answer is: because I like understanding what actually happens inside a solver.
A lot of engineering software gives you something like:
result = solve(model)
and then you get displacements, stresses, eigenfrequencies, etc.
That's obviously useful.
But personally, I wanted something where it was easier to answer questions like:
- Which formulation is actually being used?
- Which solver backend solved the system?
- What tolerance was used?
- What was the final residual?
- Was equilibrium checked?
- Can I reproduce the same result?
- Which parts of the solver are actually validated?
- Which parts are still experimental?
That is basically the philosophy behind QF Solver.
I'm trying to keep the numerical methods relatively visible instead of hiding everything behind a black box.
Installation
QF Solver is available on PyPI:
pip install qf-solver
Repository:
https://github.com/emptiesvoid-cloud/QF_solver
Documentation:
https://emptiesvoid-cloud.github.io/QF_solver/
PyPI:
https://pypi.org/project/qf-solver/
Where the project currently stands
The current version is QF Solver 0.2.7.
At the moment, the solver covers several areas of structural finite-element analysis, including:
- linear static analysis;
- TET4, TET10, HEX8 and HEX20 solid elements;
- small-strain J2 plasticity for selected elements;
- modal analysis;
- Newmark time integration;
- harmonic analysis;
- linear buckling;
- selected frictionless contact capabilities;
- experimental WEDGE6 support;
- PETSc/MPI routes for selected large models.
One thing I'm trying to be careful about is not treating every implemented feature as equally mature.
Some routes are much better tested than others.
Some are intentionally labelled as experimental or supported with limitations.
I'd rather write:
this works within this tested scope
than:
this solver supports everything
when that isn't actually true.
Verification is probably the part I care about the most
Writing an FEM element is one thing.
Trusting it is another.
So a fairly large part of the project is now dedicated to verification and validation.
I try to keep records of:
- numerical residuals;
- equilibrium errors;
- energy checks;
- deterministic replays;
- reference cases;
- solver configuration;
- execution environment;
- limitations;
- resource failures.
There are also machine-readable qualification records in the repository.
It probably looks a little excessive for a personal open-source project, but I actually enjoy this part.
And in my opinion, numerical software becomes much more interesting once you can start answering:
Why should I trust this result?
instead of only:
Did the code run?
Trying larger model
Another area I've been experimenting with is larger finite-element systems using PETSc and MPI.
Again, I want to be careful with the wording here.
These are not claims that QF Solver can magicallie solve every multi-million-DOF FEM problem.
They are recorded results for specific structured TET4 linear-static workloads, using specific solver configurations.
The current public evidence includes approximately:
| Model size | Recorded result |
|---|---|
| 1,029,000 DOF | Two stable PETSc replays |
| 3,000,000 DOF | Two Silver replays plus bounded Gold Compute evidence |
| 5,012,640 DOF | Two Silver replays |
| 10M scale | Bounded evidence only |
The 10M case especially should not be interpreted as:
QF Solver fully supports arbitrary 10-million-DOF models.
That's not what I'm claiming.
The 5 million DOF case
The largest result I currently feel comfortable describing in more detail is the 5M Silver workload.
I don't know why, but I really like the terms "Silver" and "Gold" 😅 I guess I'll probably replace them with better metrics in the future.
The recorded model contains:
- 5,012,640 degrees of freedom
- 9,773,946 TET4 elements
- 1,243 solver iterations
- free residual around
9.85e-11 - equilibrium error around
1.39e-9 - energy error below
2e-14
Two recorded runs took approximately:
- 4,428 seconds
- 4,379 seconds
This was a PETSc/MPI workload under a recorded environment and solver configuration.
I really want to emphasize this:
these numbers are not a universal QF Solver performance benchmark.
Change the mesh topology, element type, conditioning, preconditioner, hardware, material model or solver configuration and the behaviour can change completely.
For now, I'm mostly using these cases to answer a simpler question:
Can I reproduce a stable solution of this particular problem at this scale?
I also keep the failures
One thing I've tried not to do is quietly delete results that are inconvenient.
For example, an earlier matrix-free campaign successfully solved structured models up to roughly 750k DOF, while an attempt around 1M DOF reached its resource/time limit.
Later PETSc work managed to go significantly further.
But that doesn't mean the older 1M experiment suddenly becomes a successful result.
It stays recorded as a limited attempt.
Maybe this sounds obvious, but I think it matters.
Especially in performance work, it's very easy to only keep the nice numbers.
Is QF Solver better than SfePy, scikit-fem, CalculiX or Code_Aster?
I don't think that's really the right question.
They are different tools.
SfePy and scikit-fem have their own philosophies and ecosystems.
CalculiX and Code_Aster are much more mature projects with years of development behind them.
QF Solver is much younger.
What I'm currently trying to build is something that is:
- easy to inspect;
- Python-friendly;
- useful for experimenting with FEM methods;
- explicit about numerical limitations;
- backed by reproducible verification records.
I've started writing some comparison pages here:
https://emptiesvoid-cloud.github.io/QF_solver/comparisons/
The goal isn't to write:
QF Solver wins.
It's more:
If you have this type of problem, which tool makes the most sense?
The benchmark and reproducibility page
I recently created a more readable public summary of the current performance and verification evidence:
https://emptiesvoid-cloud.github.io/QF_solver/benchmarks/
The much more detailed verification records are also available directly in the repository:
https://github.com/emptiesvoid-cloud/QF_solver/tree/main/docs/verification/0_2_7
And the machine-readable qualification data is here:
https://github.com/emptiesvoid-cloud/QF_solver/tree/main/qualification/0_2_7
What's next?
I'm now starting to think about QF Solver 0.2.8.
There is still a lot I want to improve.
Some capabilities need to become more mature.
Some solver routes need better performance.
Some parts of the API still need cleanup.
And there are definitely still things in the codebase that I will probably look at in six months and wonder why I wrote them that way.
That's part of the process.
For now, I'm mostly trying to build each release on top of the previous one without pretending the project is more mature than it actually is.
Why am I posting this now?
Mostly because I've been working on the project for a while without really talking about it publicly.
I figured it was probably time to stop keeping everything inside the repository.
I'm interested in FEM, numerical methods, solver architecture and scientific computing, so if anyone working in those areas happens to look at the project, feedback is welcome.
And yes, if you open the code and immediately find something questionable... be little kind 😄
It's still a work in progress.
But constructive criticism is exactly the kind of thing that can make the solver better.
Links
GitHub
https://github.com/emptiesvoid-cloud/QF_solver
Documentation
https://emptiesvoid-cloud.github.io/QF_solver/
Benchmarks and reproducibility
https://emptiesvoid-cloud.github.io/QF_solver/benchmarks/
FEM solver comparisons
https://emptiesvoid-cloud.github.io/QF_solver/comparisons/
PyPI
https://pypi.org/project/qf-solver/
Thanks for reading.
I'll probably write another update once QF Solver 0.2.8 is in a state worth showing.
Small AI disclosure: I used AI to help me with the English and wording of this article because English isn't my strongest language. The project, technical work, results, and ideas are my own.
Top comments (0)