Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1f68e18
initial commit
NiklasVin Feb 10, 2026
2447f25
add cleaning scripts
NiklasVin Feb 19, 2026
7c29e80
change perm
NiklasVin Feb 19, 2026
8cec8b9
follow naming convention
NiklasVin Feb 19, 2026
870335b
precommit changes
NiklasVin Feb 19, 2026
752e663
update participant config files
NiklasVin Mar 13, 2026
7296df8
add changelog entry, minor changes in readme and clean scripts
NiklasVin Mar 16, 2026
cd720e6
Update changelog-entries/714.md
MakisH Jun 11, 2026
e522a46
Merge branch 'develop' into partitioned-heat-conduction-3d
MakisH Jun 11, 2026
aee2cb0
Add metadata.yaml
MakisH Jun 11, 2026
c0d23c9
Update handling of venv in run.sh scripts
MakisH Jun 11, 2026
fcd3656
Merge branch 'develop' into partitioned-heat-conduction-3d
MakisH Jun 11, 2026
02d3f4e
Merge branch 'develop' into partitioned-heat-conduction-3d
MakisH Jun 11, 2026
c0cb137
Further updates in venv/shell
MakisH Jun 11, 2026
100cbcc
Merge branch 'develop' into partitioned-heat-conduction-3d
MakisH Jun 12, 2026
fbda434
Add to the system tests
MakisH Jun 12, 2026
24667d5
Fix inconsistencies in venv
MakisH Jun 12, 2026
f71f769
Merge branch 'develop' into partitioned-heat-conduction-3d
MakisH Jun 12, 2026
25b3da3
Update partitioned-heat-conduction-3d/solver-fenicsx/requirements.txt
MakisH Jun 12, 2026
d7cda3c
Update partitioned-heat-conduction-3d/precice-config.xml
MakisH Jun 12, 2026
b85261f
Move gmsh dependencies to the base Docker stage
MakisH Jun 12, 2026
8ec6ac2
Set max_time to 0.3 for the test
MakisH Jun 12, 2026
a6dc439
Fix image paths, add config visualization
MakisH Jun 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog-entries/714.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- add FEniCSx-based solver for the 3D partitioned heat conduction tutorial
Comment thread
MakisH marked this conversation as resolved.
Outdated
57 changes: 57 additions & 0 deletions partitioned-heat-conduction-3d/README.md
Comment thread
MakisH marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: 3D partitioned heat conduction
permalink: tutorials-partitioned-heat-conduction-3d.html
keywords: FEniCSx, Heat conduction
summary: We solve a simple heat equation on a 3D domain. The domain is partitioned and the coupling is established in a Dirichlet-Neumann fashion.
---

{% note %}
Get the [case files of this tutorial](https://github.com/precice/tutorials/tree/develop/partitioned-heat-conduction-3d), as continuously rendered here, or see the [latest released version](https://github.com/precice/tutorials/tree/master/partitioned-heat-conduction-3d) (if there is already one). Read how in the [tutorials introduction](https://precice.org/tutorials.html).
{% endnote %}

## Setup

We solve a partitioned heat equation. For information on the two dimensional non-partitioned case, please refer to [1, p.37ff]. In this tutorial the computational domain is partitioned and coupled via preCICE. The coupling roughly follows the approach described in [2].

![Case setup of partitioned-heat-conduction case](images/tutorials-partitioned-heat-conduction-setup.png)

The computational domain can be seen in the picture above. To get a better overview of the domain, the domains of the participants are translated.
The domain of the Neumann participant is the small box, and the Dirichlet participant's domain is the rest. In the simulation, the small box is fully contained in the Dirichlet domain. This means, the coupling interface consists of five sides of the box.

## Configuration

preCICE configuration (image generated using the [precice-config-visualizer](https://precice.org/tooling-config-visualization.html)):

![preCICE configuration visualization](images/tutorials-partitioned-heat-conduction-precice-config.png)

## Available solvers and dependencies

You can either couple a solver with itself or different solvers with each other. In any case you will need to have preCICE and the python bindings installed on your system.

* FEniCSx. Install [FEniCS](https://fenicsproject.org/download/) and the [FEniCSx-adapter](https://github.com/precice/fenicsx-adapter). The code is adapted from the existing [fenics-tutorial](https://github.com/hplgit/fenics-tutorial/blob/master/pub/python/vol1/ft03_heat.py) from [1].

## Running the simulation

You can find the corresponding `run.sh` script for running the case in the folders corresponding to the participant you want to use:

```bash
cd dirichlet-fenicsx
./run.sh
```

and

```bash
cd neumann-fenicsx
./run.sh
```

## Visualization

Output is written into the folders of the FEniCSx solvers (`neumann-fenicsx/output-neumann.bp` and `dirichlet-fenicsx/output-dirichlet.bp`).

It is sufficient to import the folders to ParaView to get the visualization of the simulation.

## References

[1] Hans Petter Langtangen and Anders Logg. "Solving PDEs in Minutes-The FEniCS Tutorial Volume I." (2016). [pdf](https://fenicsproject.org/pub/tutorial/pdf/fenics-tutorial-vol1.pdf)
10 changes: 10 additions & 0 deletions partitioned-heat-conduction-3d/clean-tutorial.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env sh
set -e -u

# shellcheck disable=SC1091
. ../tools/cleaning-tools.sh

clean_tutorial .
clean_precice_logs .
rm -fv ./*.log

6 changes: 6 additions & 0 deletions partitioned-heat-conduction-3d/dirichlet-fenicsx/clean.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env sh
set -e -u

. ../../tools/cleaning-tools.sh

clean_fenicsx .
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"participant_name": "Dirichlet",
"precice_config_file_path": "../precice-config.xml",
"interfaces": [
{
"mesh_name": "Dirichlet-Mesh",
"write_data": [
{
"name": "Heat-Flux"
}
],
"read_data": [
{
"name": "Temperature"
}
]
}
]
}
8 changes: 8 additions & 0 deletions partitioned-heat-conduction-3d/dirichlet-fenicsx/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/sh
set -e -u

python3 -m venv --system-site-packages .venv
. .venv/bin/activate
pip install -r ../solver-fenicsx/requirements.txt

python3 ../solver-fenicsx/heat.py Dirichlet --error-tol 10e-3
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions partitioned-heat-conduction-3d/neumann-fenicsx/clean.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env sh
set -e -u

. ../../tools/cleaning-tools.sh

clean_fenicsx .
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"participant_name": "Neumann",
"precice_config_file_path": "../precice-config.xml",
"interfaces": [
{
"mesh_name": "Neumann-Mesh",
"write_data": [
{
"name": "Temperature"
}
],
"read_data": [
{
"name": "Heat-Flux"
}
]
}
]
}
7 changes: 7 additions & 0 deletions partitioned-heat-conduction-3d/neumann-fenicsx/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh
set -e -u

python3 -m venv --system-site-packages .venv
Comment thread
MakisH marked this conversation as resolved.
Outdated
. .venv/bin/activate
pip install -r ../solver-fenicsx/requirements.txt
python3 ../solver-fenicsx/heat.py Neumann --error-tol 10e-3
80 changes: 80 additions & 0 deletions partitioned-heat-conduction-3d/precice-config.xml
Comment thread
MakisH marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" ?>
<precice-configuration experimental="false">
<log>
<sink
filter="%Severity% > debug and %Rank% = 0"
format="---[precice] %ColorizedSeverity% %Message%"
enabled="true" />
</log>

<data:scalar name="Temperature" waveform-degree="1" />
<data:vector name="Heat-Flux" waveform-degree="1" />

<mesh name="Dirichlet-Mesh" dimensions="3">
<use-data name="Temperature" />
<use-data name="Heat-Flux" />
</mesh>

<mesh name="Neumann-Mesh" dimensions="3">
<use-data name="Temperature" />
<use-data name="Heat-Flux" />
</mesh>

<participant name="Dirichlet">
<provide-mesh name="Dirichlet-Mesh" />
<receive-mesh name="Neumann-Mesh" from="Neumann" api-access="false" />
<write-data name="Heat-Flux" mesh="Dirichlet-Mesh" />
<read-data name="Temperature" mesh="Dirichlet-Mesh" />
<mapping:rbf-pum-direct
direction="read"
from="Neumann-Mesh"
to="Dirichlet-Mesh"
constraint="consistent"
project-to-input="false"
relative-overlap="0.75"
vertices-per-cluster="90"
polynomial="separate">
<basis-function:compact-polynomial-c8 support-radius="2.0" />
</mapping:rbf-pum-direct>
</participant>

<participant name="Neumann">
<provide-mesh name="Neumann-Mesh" />
<receive-mesh name="Dirichlet-Mesh" from="Dirichlet" api-access="false" />
<write-data name="Temperature" mesh="Neumann-Mesh" />
<read-data name="Heat-Flux" mesh="Neumann-Mesh" />
<mapping:nearest-neighbor
direction="read"
from="Dirichlet-Mesh"
to="Neumann-Mesh"
constraint="consistent" />
</participant>

<m2n:sockets acceptor="Dirichlet" connector="Neumann" exchange-directory=".." />

<coupling-scheme:serial-implicit>
<participants first="Dirichlet" second="Neumann" />
<max-time value="1.0" />
<time-window-size value="0.1" />
<max-iterations value="200" />
Comment thread
MakisH marked this conversation as resolved.
Outdated
<exchange
data="Heat-Flux"
mesh="Dirichlet-Mesh"
from="Dirichlet"
to="Neumann"
initialize="true"
substeps="true" />
<exchange
data="Temperature"
mesh="Neumann-Mesh"
from="Neumann"
to="Dirichlet"
initialize="true"
substeps="true" />
<relative-convergence-measure data="Heat-Flux" mesh="Dirichlet-Mesh" limit="1e-10" />
<relative-convergence-measure data="Temperature" mesh="Neumann-Mesh" limit="1e-10" />
<acceleration:constant>
<relaxation value="0.2" />
</acceleration:constant>
</coupling-scheme:serial-implicit>
</precice-configuration>
6 changes: 6 additions & 0 deletions partitioned-heat-conduction-3d/solver-fenicsx/clean.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh
set -e -u

. ../../tools/cleaning-tools.sh

clean_fenicsx .
21 changes: 21 additions & 0 deletions partitioned-heat-conduction-3d/solver-fenicsx/errorcomputation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from dolfinx import fem
import numpy as np
from mpi4py import MPI
import ufl


def compute_errors(u_approx, u_ref, total_error_tol=10 ** -7):
mesh = u_ref.function_space.mesh
# Compute L2 error and error at nodes
error_L2 = np.sqrt(mesh.comm.allreduce(fem.assemble_scalar(fem.form((u_approx - u_ref)**2 * ufl.dx)), op=MPI.SUM))
if mesh.comm.rank == 0:
print(f"L2-error: {error_L2:.2e}")

# Compute values at mesh vertices
error_max = mesh.comm.allreduce(np.max(np.abs(u_approx.x.array - u_ref.x.array)), op=MPI.MAX)
if mesh.comm.rank == 0:
print(f"Error_max: {error_max:.2e}")

assert (error_L2 < total_error_tol)

return (error_L2, error_max)
Loading
Loading