-
-
Notifications
You must be signed in to change notification settings - Fork 64
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
Changes from 17 commits
0b2b4de
1b159f6
b2bf7b7
4027e53
78f580c
03746d0
700a13a
33b1d8a
9e74c64
f44389e
d280ec6
a97b745
fe8db64
680eee7
6727496
0d44cfe
3635024
0809251
4d67208
02cc542
2151663
ecf9577
78b625d
9003fce
f9e2f25
c5b6b0f
84e9caf
ab6a46f
eea944b
a4950f6
34e7bea
83878b5
64c796c
eb4f670
6e08569
35164be
01f1b60
d828aa9
066e694
46aebdb
04101eb
5cf756d
5064011
63b8145
85ed50a
7dd94f2
e9abc5b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't get this from the picture, seems like you use
This should be |
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.readBlockVectorData(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 |
---|---|---|
|
@@ -4,6 +4,7 @@ permalink: couple-your-code-waveform.html | |
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 %} | ||
|
@@ -37,25 +38,21 @@ Linear interpolation between coupling boundary conditions of the previous and th | |
|
||
If the Dirichlet participant $$\mathcal{D}$$ calls `readBlockVectorData`, 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 | ||
|
||
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, `readBlockVectorData` accepts an additional argument `relativeReadTime`. This allows us to choose the time where the waveform should be sampled: | ||
preCICE offers the argument `relativeReadTime` for all read data functions of the API: | ||
|
||
```cpp | ||
// stable API with constant data in time window | ||
void readBlockVectorData(int dataID, int size, const int* valueIndices, double* values) const; | ||
|
||
// experimental API for waveform iteration | ||
void readBlockVectorData(int dataID, int size, const int* valueIndices, double relativeReadTime, 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: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
|
||
 | ||
|
||
`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()`). | ||
uekerman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
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: | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.