Skip to content

v3: Make dt mandatory in documentation #257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 47 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
0b2b4de
v3: Make dt mandatory in documentation
BenjaminRodenberg Apr 21, 2023
1b159f6
Update read data functions to use relativeReadTime.
BenjaminRodenberg Apr 21, 2023
b2bf7b7
Merge branch 'master' into v3-make-dt-mandatory
BenjaminRodenberg Apr 21, 2023
4027e53
Merge branch 'master' into v3-make-dt-mandatory
BenjaminRodenberg Apr 21, 2023
78f580c
Merge branch 'master' into v3-make-dt-mandatory
BenjaminRodenberg Apr 21, 2023
03746d0
Merge branch 'master' into v3-make-dt-mandatory
BenjaminRodenberg Apr 21, 2023
700a13a
Add missing.
BenjaminRodenberg Apr 21, 2023
33b1d8a
Merge branch 'precice-v3' into v3-make-dt-mandatory
BenjaminRodenberg Apr 24, 2023
9e74c64
Merge branch 'precice-v3' into v3-make-dt-mandatory
BenjaminRodenberg Apr 24, 2023
f44389e
Merge branch 'precice-v3' into v3-make-dt-mandatory
BenjaminRodenberg May 28, 2023
d280ec6
Shorten a bit.
BenjaminRodenberg May 28, 2023
a97b745
Minor follow-up for #258.
BenjaminRodenberg May 28, 2023
fe8db64
Merge branch 'precice-v3' into v3-make-dt-mandatory
BenjaminRodenberg May 28, 2023
680eee7
Add figure.
BenjaminRodenberg May 28, 2023
6727496
Remove outdated note.
BenjaminRodenberg May 28, 2023
0d44cfe
Merge branch 'precice-v3' into v3-make-dt-mandatory
BenjaminRodenberg Jun 1, 2023
3635024
Use dt properly.
BenjaminRodenberg Jun 1, 2023
0809251
Remove unnecessary pdf.
BenjaminRodenberg Jun 1, 2023
4d67208
Partial update of documentation w.r.t breaking changes.
BenjaminRodenberg Nov 11, 2023
02cc542
Redice diff.
BenjaminRodenberg Nov 11, 2023
2151663
Redice diff.
BenjaminRodenberg Nov 11, 2023
ecf9577
Reduce diff.
BenjaminRodenberg Nov 11, 2023
78b625d
Fix some more breaking changes.
BenjaminRodenberg Nov 11, 2023
9003fce
Add how dt is computed. See https://github.com/precice/precice.github…
BenjaminRodenberg Nov 11, 2023
f9e2f25
Merge branch 'update_breaking_changes' into v3-make-dt-mandatory
BenjaminRodenberg Nov 11, 2023
c5b6b0f
Apply suggestions from code review
BenjaminRodenberg Nov 13, 2023
84e9caf
Merge branch 'update_breaking_changes' into v3-make-dt-mandatory
BenjaminRodenberg Nov 13, 2023
ab6a46f
Remove unneeded.
BenjaminRodenberg Nov 13, 2023
eea944b
Merge branch 'update_breaking_changes' into v3-make-dt-mandatory
BenjaminRodenberg Nov 13, 2023
a4950f6
Add pointer to interpolation section.
BenjaminRodenberg Nov 13, 2023
34e7bea
Merge branch 'precice-v3' into update_breaking_changes
BenjaminRodenberg Nov 14, 2023
83878b5
Merge branch 'update_breaking_changes' into v3-make-dt-mandatory
BenjaminRodenberg Nov 14, 2023
64c796c
Merge branch 'precice-v3' into v3-make-dt-mandatory
BenjaminRodenberg Nov 15, 2023
eb4f670
Fix format.
BenjaminRodenberg Nov 22, 2023
6e08569
Merge branch 'precice-v3' into v3-make-dt-mandatory
BenjaminRodenberg Nov 22, 2023
35164be
Add advice on https://github.com/precice/precice/issues/1866.
BenjaminRodenberg Nov 22, 2023
01f1b60
Apply suggestions from code review
BenjaminRodenberg Nov 22, 2023
d828aa9
Merge branch 'precice-v3' into v3-make-dt-mandatory
BenjaminRodenberg Jan 23, 2024
066e694
Update some minor, obviously outdated points.
BenjaminRodenberg Jan 23, 2024
46aebdb
Update png.
BenjaminRodenberg Jan 23, 2024
04101eb
Update pages/docs/couple-your-code/couple-your-code-mesh-and-data-acc…
BenjaminRodenberg Jan 23, 2024
5cf756d
Update heading.
BenjaminRodenberg Jan 23, 2024
5064011
Merge branch 'v3-make-dt-mandatory' of github.com:precice/precice.git…
BenjaminRodenberg Jan 23, 2024
63b8145
Moved changes to #326.
BenjaminRodenberg Jan 23, 2024
85ed50a
Merge branch 'precice-v3' into v3-make-dt-mandatory
BenjaminRodenberg Jan 28, 2024
7dd94f2
Update pages/docs/couple-your-code/couple-your-code-mesh-and-data-acc…
uekerman Feb 8, 2024
e9abc5b
Update pages/docs/couple-your-code/couple-your-code-waveform.md
uekerman Feb 8, 2024
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
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
\documentclass[]{standalone}

\usepackage{tikz}
\usepackage{pgf}
\usepackage{pgfplots}
\usetikzlibrary{positioning, calc, decorations.markings}

\begin{document}

\begin{tikzpicture}[scale=10]
\node[circle, fill=black, label={[xshift=-1em]below right:$\vphantom{\frac{1}{2}}t_{n+1} = t_{n} + \Delta t$}](tnp1) at (1.3,0) {};
\node[circle, fill=black, label={[xshift=-1em]below right:$\vphantom{\frac{1}{2}}\tau_{n}$}](taun) at (0,0) {};
\node[circle, fill=black, label={[xshift=-1em]below right:$\vphantom{\frac{1}{2}}\tau_{n+1} = \tau_n + \delta t$}](taunp1) at (0.35,0) {};

\draw[->](taun) edge[out=30,in=150] node[above, align=left, anchor=south west,xshift=-1cm]{(1) No more substeps: \\ \scriptsize{\texttt{precice.advance(preciceDt)}}}(tnp1);
\draw[->](taun) edge[out=30,in=150] node[right, align=left, anchor=south west,pos=1]{(2) More substeps:\\ \scriptsize{\texttt{precice.advance(solverDt)}}} (taunp1);
\node[above = 3cm of taun, label={[xshift=-1em, align=left]above right:Read interpolated data from current time $\tau_n$:\\ \scriptsize\texttt{precice.readData(relativeReadTime=dt, ...)}}](tau) {};
\draw[->](tau) -- (taun);

\node[below = of taun, label={[xshift=-1em,yshift=0.1cm]below right:\scriptsize\texttt{dt = 0}}](rdt0) {};
\draw[->](rdt0) -- ($(taun)-(0,.2em)$);

\draw[dotted] (taun) -- (taunp1);
\draw[dotted] (taunp1) -- (tnp1);

\node[circle, draw=black, fill=white, label={[xshift=-3.25em]below right:$\frac{1}{2}\left(\tau_n + \tau_{n+1}\right)$}](subcyclingmid) at ($0.5*(taun) + 0.5*(taunp1)$) {};
\node[below = 4.5em of subcyclingmid, label={[xshift=-1em,yshift=0.2cm]below right:{\scriptsize\texttt{dt = 0.5 * solverDt}}}](rdtmid) {};
\draw[->](rdtmid) -- ($(subcyclingmid)-(0,.2em)$);

\node[below = of taunp1, label={[xshift=-1em,yshift=0.2cm]below right:\scriptsize\texttt{dt = solverDt}}](rdt1) {};
\draw[->](rdt1) -- ($(taunp1)-(0,.2em)$);

\node[below = of tnp1, label={[align=center,xshift=-1em,yshift=0.2cm]below right:\scriptsize\texttt{dt = preciceDt}}](rdtend) {};
\draw[->](rdtend) -- ($(tnp1)-(0,.2em)$);


\draw [decorate,decoration={brace,amplitude=2em,mirror}] ($(taun)-(0,.3)$) -- ($(taunp1)-(0,.3)$) node [black,midway,below,yshift=-2em, align=left] {Solver time step size $\delta t$\\ \scriptsize\texttt{solverDt < preciceDt} };

\draw [decorate,decoration={brace,amplitude=2em,mirror}] ($(taun)-(0,.25)$) -- ($(tnp1)-(0,.25)$) node [black,midway,below,yshift=-2em, xshift=5em, align=left] {Complete time window size $\Delta t$ or remainder\\ \scriptsize\texttt{preciceDt = precice.getMaxTimeStepSize()}};
\end{tikzpicture}

\end{document}

Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,18 @@ void Participant::writeData(
precice::span<const double> values)
```

<!-- TODO Also point to section where `relativeReadTime` is explained? We will probably solve this in https://github.com/precice/precice.github.io/pull/257 -->
Similarly, there is a `readData` API function for reading coupling data.
Similarly, there is a `readData` API function for reading coupling data:

```cpp
void readData(
precice::string_view meshName,
precice::string_view dataName,
precice::span<const VertexID> vertices,
double relativeReadTime,
precice::span<double> values) const;
```

The relative read time can be anything from the current point in time (`0`) to the end of the time window (`getMaxTimeStepSize())`. We will talk about the additional argument `relativeReadTime` in detail in [the section on time interpolation](couple-your-code-waveform.html).

Let's define coupling meshes and access coupling data in our example code:

Expand Down
36 changes: 14 additions & 22 deletions pages/docs/couple-your-code/couple-your-code-waveform.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ keywords: api, adapter, time, waveform, subcycling, multirate
summary: "With waveform iteration, you can interpolate coupling data in time for higher-order time stepping and more stable subcycling."
---

{% experimental %}
These API functions are work in progress, experimental, and are not yet released. The API might change during the ongoing development process. Use with care.
{% endexperimental %}

preCICE allows the participants to use subcycling – meaning: to work with individual time step sizes smaller than the time window size. Note that participants always have to synchronize at the end of each *time window*. If you are not sure about the difference between a time window and a time step or you want to know how subcycling works in detail, see ["Step 5 - Non-matching time step sizes" of the step-by-step guide](couple-your-code-time-step-sizes.html). In the following section, we take a closer look at the exchange of coupling data when subcycling and advanced techniques for interpolation of coupling data inside of a time window.
preCICE allows the participants to use subcycling – meaning: to work with individual time step sizes smaller than the time window size. Note that participants always have to synchronize at the end of each *time window*. If you are not sure about the difference between a time window and a time step or you want to know how subcycling works in detail, see ["Step 5 - Non-matching time step sizes" of the step-by-step guide](couple-your-code-time-step-sizes.html). In the following section, we take a closer look at the exchange of coupling data when subcycling and advanced techniques for interpolation of coupling data are used inside of a time window.

## Exchange of coupling data with subcycling

Expand All @@ -35,38 +31,34 @@ Linear interpolation between coupling boundary conditions of the previous and th

If the Dirichlet participant $$\mathcal{D}$$ calls `readData`, it samples the data from a time-dependent function $$c_\mathcal{D}(t)$$. This function is created from linear interpolation of the first and the last sample $$c_{\mathcal{D}0}$$ and $$c_{\mathcal{D}5}$$ created by the Neumann participant $$\mathcal{N}$$ in the current time window. This allows $$\mathcal{D}$$ to sample the coupling condition at arbitrary times $$t$$ inside the current time window.

{% note %}
As soon as time interpolation is used to obtain data for a `relativeReadTime` that does not refer to the end of the current window, the data from the end of the previous window might be used to compute the interpolated value. For the first time window, this means one should provide appropriate initial data, since otherwise preCICE will use zero-valued initial data. There are, however, situations where initial data is not necessarily needed. For example, if one uses zeroth order time interpolation without accessing the data value at the beginning of the time window. It is still recommended to always provide initial data, if available. See ["Step 7 - Data initialization"](couple-your-code-initializing-coupling-data.md) for details on data initialization.
{% endnote %}

## Experimental API for waveform iteration
## Using waveform iteration

<!-- Related to https://github.com/precice/precice.github.io/pull/257 -->
If we want to improve the accuracy by using waveforms, this requires an extension of the existing API, because we need a way to tell preCICE where we want to sample the waveform. For this purpose, preCICE offers an experimental API. Here, `readData` accepts an additional argument `relativeReadTime`. This allows us to choose the time where the waveform should be sampled:
preCICE requires the argument `relativeReadTime` for the `readData` functions:

```cpp
void Participant::readData(
precice::string_view meshName,
precice::string_view dataName,
precice::span<const VertexID> vertices,
double relativeReadTime,
double relativeReadTime,
precice::span<double> values) const
```

`relativeReadTime` describes the time relatively to the beginning of the current time step. This means that `relativeReadTime = 0` gives us access to data at the beginning of the time step. By choosing `relativeReadTime > 0` we can sample data at later points. The maximum allowed `relativeReadTime` corresponds to the remaining time until the end of the current time window. Remember that the remaining time until the end of the time window is always returned when calling `preciceDt = precice.getMaxTimeStepSize()` as `preciceDt`. So `relativeReadTime = preciceDt` corresponds to sampling data at the end of the current time window.
In the previous sections of the step-by-step guide we always used `relativeReadTime = preciceDt` where `preciceDt = precice.getMaxTimeStepSize()` points to the end of the current time window (see, for example ["Step 5 - Non-matching time step sizes"](couple-your-code-time-step-sizes.html)). However, the original purpose of `relativeReadTime` is exactly to offer the user an interface for sampling from waveforms. The figure below illustrates how providing different values `dt` for `relativeReadTime` allows to sample interpolated values at different points in time:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this is a good strategy (see also above): To tell users first how to do it the wrong way, and then the right way. Maybe we need to re-order our steps?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that the waveform API is not experimental anymore but the default, let's put some information from here into "Step 5 - Non-matching time step sizes". I think this section needs some updates and refinement anyway. Additionally, I think that the topics that we currently explain in "Step 5 - Non-matching time step sizes" are definitely more advanced and exotic than some of the basic topics that we explain here. So yes: let's reorder some things.

We should still keep the more advanced background information (interpolation degree, higher-order time stepping) here to not provide too much information too early.


![API for relativeReadTime](images/docs/couple-your-code/couple-your-code-waveform/APIRelativeReadTime.png)

`relativeReadTime` describes the time relatively to the beginning of the current time step starting at $$\tau_n$$. This means that `dt = 0` gives us access to data at the beginning of the time step. By choosing `dt > 0` we can sample data at points in time after $$\tau_n$$. The maximum allowed `dt = preciceDt` corresponds to $$\tau_n$$ plus the remaining time until the end of the current time window (i.e. `preciceDt = precice.getMaxTimeStepSize()`).

If we choose to use a smaller time step size `dt < preciceDt`, we apply subcycling and therefore `relativeReadTime = dt` corresponds to sampling data at the end of the time step. But we can also use smaller values for `relativeReadTime`, as shown in the usage example below. When using subcycling, it is important to note that `relativeReadTime = preciceDt` is the default behavior, if no `relativeReadTime` is provided, because preCICE cannot know the `dt` our solver wants to use. This also means that if subcycling is applied one must use the experimental API and provide `relativeReadTime` to benefit from the higher accuracy waveforms.
If we choose to use a smaller time step size `solverDt < preciceDt`, we apply subcycling and therefore `dt = solverDt` corresponds to sampling data at the end of the time step. But we can also use arbitrary values for `dt`, like `dt = 0.5 * solverDt` to implement, for example, a midpoint rule (see also the usage example below).

The experimental API has to be activated in the configuration file via the `experimental` attribute. This allows us to define the order of the interpolant in the `read-data` tag of the corresponding `participant`. Currently, we support two interpolation schemes: constant and linear interpolation. The interpolant is always constructed using data from the beginning and the end of the window. The default is constant interpolation (`waveform-order="0"`). The following example uses `waveform-order="1"` and, therefore, linear interpolation:
This allows us to define the degree of the interpolant in the `read-data` tag of the corresponding `participant`. Currently, we support two interpolation schemes: constant and linear interpolation. The interpolant is always constructed using data from the beginning and the end of the window. The default is constant interpolation (`waveform-degree="1"`). The following example uses `waveform-degree="3"` and, therefore, cubic interpolation:

```xml
<precice-configuration experimental="true" ... >
<precice-configuration ... >
...
<participant name="FluidSolver">
<provide-mesh name="FluidMesh" />
<write-data name="Forces" mesh="MyMesh"/>
<read-data name="Displacements" mesh="FluidMesh" waveform-order="1"/>
</participant>
<data:vector name="Forces" waveform-degree="3"/>
<data:vector name="Displacements" waveform-degree="3"/>
...
</precice-configuration>
```
Expand Down