StroemungsRaum: add heat equation examples using FEniCS#598
StroemungsRaum: add heat equation examples using FEniCS#598Ouardghi wants to merge 1 commit intoParallel-in-Time:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds Heat Equation examples using FEniCS for the StroemungsRaum research project, which focuses on parallel-in-time methods and space-time parallelization for CFD simulations. The implementation introduces problem classes, test files, accuracy analysis scripts, and plotting utilities for solving 2D heat equations with different boundary conditions using the FEniCS finite element framework.
Changes:
- Added three problem classes for 2D heat equation solving with varying boundary condition treatments
- Implemented test suite with problem class tests, plotting tests, and accuracy convergence tests
- Created accuracy analysis scripts for 3rd and 5th order convergence studies
- Added environment configuration and project README documentation
Reviewed changes
Copilot reviewed 14 out of 20 changed files in this pull request and generated 55 comments.
Show a summary per file
| File | Description |
|---|---|
| test_problem_class_heat_equation_FEniCS.py | Basic problem class test with incorrect import path |
| test_plots_heat_equation_FEniCS.py | Tests for visualization output generation |
| test_accuracy_heat_equations_FEniCS.py | Convergence tests with commented-out 5th order test |
| run_heat_equation_FEniCS.py | Main simulation runner with data export functionality |
| run_accuracy_3rd_order_heat_equation_FEniCS.py | 3rd order convergence analysis with plotting |
| run_accuracy_5th_order_heat_equation_FEniCS.py | 5th order convergence analysis (not tested) |
| HeatEquation_2D_FEniCS.py | Three problem classes with comprehensive docstrings |
| plots_heat_equation_FEniCS.py | Visualization utilities for solutions and cross-sections |
| environment.yml | Conda environment with FEniCS dependencies |
| README.rst | Project documentation and funding information |
| data/*.json, *.xdmf, *.png | Generated test data and output files |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import subprocess | ||
| import os | ||
| import warnings |
There was a problem hiding this comment.
Several imports are not used in this test file: subprocess, os, and warnings. These should be removed to keep the code clean.
| import subprocess | |
| import os | |
| import warnings |
| import subprocess | ||
| import os | ||
| import warnings |
There was a problem hiding this comment.
Several imports are not used in this test file: subprocess, os, and warnings. These should be removed to keep the code clean.
| import subprocess | |
| import os | |
| import warnings | |
| import os |
| from mpl_toolkits.mplot3d import Axes3D | ||
|
|
||
|
|
||
| def run_simulation(ml=None, mass=None): |
There was a problem hiding this comment.
The unused parameter 'ml' in the function signature should be removed as it's not used in the function body and is not documented.
| def run_simulation(ml=None, mass=None): | |
| def run_simulation(mass=None): |
There was a problem hiding this comment.
Why don't you call this function from the scripts that compute the order? Why do you have a seemingly same function thrice?
| Args: | ||
| t0 (float): initial time | ||
| ml (bool): use single or multiple levels |
There was a problem hiding this comment.
The 'ml' parameter in the docstring is mentioned but not present in the actual function signature. The docstring should be updated to remove this parameter or the parameter should be added if it's actually needed.
| ml (bool): use single or multiple levels |
| # mesh = df.UnitIntervalMesh(c_nvars) | ||
|
|
||
| mesh = df.UnitSquareMesh(c_nvars, c_nvars) | ||
|
|
||
| # for _ in range(refinements): | ||
| # mesh = df.refine(mesh) | ||
|
|
There was a problem hiding this comment.
Commented-out code on lines 106-107 should be removed. If mesh refinement is needed in the future, it can be retrieved from version control history.
| # mesh = df.UnitIntervalMesh(c_nvars) | |
| mesh = df.UnitSquareMesh(c_nvars, c_nvars) | |
| # for _ in range(refinements): | |
| # mesh = df.refine(mesh) | |
| mesh = df.UnitSquareMesh(c_nvars, c_nvars) |
|
|
||
| import dolfin as df | ||
| import matplotlib.pyplot as plt | ||
| import matplotlib.tri as mtri |
There was a problem hiding this comment.
Import of 'mtri' is not used.
| import matplotlib.tri as mtri |
| import dolfin as df | ||
| import matplotlib.pyplot as plt | ||
| import matplotlib.tri as mtri | ||
| import matplotlib.cm as cm |
There was a problem hiding this comment.
Import of 'cm' is not used.
| import matplotlib.cm as cm |
| import matplotlib.pyplot as plt | ||
| import matplotlib.tri as mtri | ||
| import matplotlib.cm as cm | ||
| from mpl_toolkits.mplot3d import Axes3D |
There was a problem hiding this comment.
Import of 'Axes3D' is not used.
| from mpl_toolkits.mplot3d import Axes3D |
| xdmffile_u = df.XDMFFile(path + 'heat_equation_FEniCS_Temperature.xdmf') | ||
|
|
||
| # load parameters | ||
| parameters = json.load(open(path + "heat_equation_FEniCS_parameters.json", 'r')) |
There was a problem hiding this comment.
File is opened but is not closed.
| parameters = json.load(open(path + "heat_equation_FEniCS_parameters.json", 'r')) | |
| with open(path + "heat_equation_FEniCS_parameters.json", 'r') as f: | |
| parameters = json.load(f) |
| parameters = description['problem_params'] | ||
| parameters.update(description['level_params']) | ||
| parameters['Tend'] = Tend | ||
| json.dump(parameters, open(path + "heat_equation_FEniCS_parameters.json", 'w')) |
There was a problem hiding this comment.
File is opened but is not closed.
| json.dump(parameters, open(path + "heat_equation_FEniCS_parameters.json", 'w')) | |
| with open(path + "heat_equation_FEniCS_parameters.json", 'w') as f: | |
| json.dump(parameters, f) |
brownbaerchen
left a comment
There was a problem hiding this comment.
Thanks for the PR! The long awaited Stroemungsraum stuff is finally here!
Big PR, big number of comments. In the future, please separate your PRs into small chunks.
For instance, merge the heat equation implementation that the others derive from with a test and then do the others. This way, when you copy paste, you copy paste a version that is ready to be merged and you don't get the same comments every time.
This makes it easier for people to review your PR and improves quality of the review because the reviewers only have so much time. Also, it makes it easier for you because you can build on what you have. Getting something merged is like checking it off your todo list. It's done and doesn't get lost somewhere on your laptop.
Otherwise, please try to keep code duplication to a minimum, write more meaningful tests and only check in code.
There was a problem hiding this comment.
We don't usually check in plots to the repository. Please remove.
There was a problem hiding this comment.
We also don't check in output files like this. Especially because the size is quite large at 6MB. Please remove.
| .. math:: | ||
| u(x, y, t) = \sin(\pi x)\sin(\pi y)\cos(t) + c. | ||
|
|
||
| In this class the problem is implemented in the way that the spatial part is solved using ``FEniCS`` [1]_. Hence, the problem |
There was a problem hiding this comment.
| In this class the problem is implemented in the way that the spatial part is solved using ``FEniCS`` [1]_. Hence, the problem | |
| In this class the spatial part is solved using ``FEniCS`` [1]_. Hence, the problem |
| C. Richardson, J. Ring, M. E. Rognes, G. N. Wells. Archive of Numerical Software (2015). | ||
| .. [2] Automated Solution of Differential Equations by the Finite Element Method. A. Logg, K.-A. Mardal, G. N. | ||
| Wells and others. Springer (2012). | ||
| """ |
There was a problem hiding this comment.
Since I see the docstring was originally copy-pasted, is it still up to date?
| dtype_f = rhs_fenics_mesh | ||
|
|
||
| def __init__(self, c_nvars=64, t0=0.0, family='CG', order=2, refinements=1, nu=0.1, c=0.0): | ||
| """Initialization routine""" |
There was a problem hiding this comment.
| """Initialization routine""" |
| @pytest.mark.fenics | ||
| @pytest.mark.mpi4py | ||
| @pytest.mark.parametrize('mass', [True]) | ||
| def test_plot(mass): |
There was a problem hiding this comment.
We have decided not to test plotting. Please add # pragma: no cover to tell coverage to exclude your plotting function from the report. In particular, you do:
def plot_stuff(): # pragma: no cover
...
BUT: only exclude pure plotting functions! Do not exclude functions that do analysis or run a simulation. That is our current convention of coverage rules.
| assert os.path.isfile('data/heat_equation_FEniCS_Temperature.xdmf'), 'ERROR: Temperature.xdmf does not exist' | ||
| assert os.path.isfile('data/heat_equation_FEniCS_Temperature.h5'), 'ERROR: Temperature.h5 does not exist' | ||
|
|
||
| from pySDC.projects.StroemungsRaum.plotting.plots_heat_equation_FEniCS import plot_solutions |
There was a problem hiding this comment.
Also remove / change this test.
| def test_problem_class(mass): | ||
| from pySDC.projects.FluidFlow.run_heat_equation_FEniCS import run_simulation | ||
|
|
||
| run_simulation(mass=mass) |
There was a problem hiding this comment.
Again, please don't just do a smoke test. You know the exact solution, so here you can even just compare the two.
What I like to do is define an input where I know the output and call the right hand side evaluation and solve functions on that. For instance, the second derivative of a sine wave is again a sine wave. Maybe this is difficult with the way dirichlet boundary conditions are handled in FEM, I don't know. But please try to come up with some simple tests.
| ------- | ||
| Funded by the **German Federal Ministry of Education and Research (BMBF)** under | ||
| grant number **16ME0708**. | ||
|
|
There was a problem hiding this comment.
Maybe you want to add how to reproduce the results in your paper here?
| from mpl_toolkits.mplot3d import Axes3D | ||
|
|
||
|
|
||
| def run_simulation(ml=None, mass=None): |
There was a problem hiding this comment.
Why don't you call this function from the scripts that compute the order? Why do you have a seemingly same function thrice?
This PR introduces the Heat Equation examples using FEniCS for the StroemungsRaum project.
The implementation is self-contained and does not affect existing projects.