Skip to content

Commit cadd3d2

Browse files
committed
Cleanup and update doc
1 parent 902082a commit cadd3d2

6 files changed

Lines changed: 264 additions & 226 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ To enable, set `do_coalesced_comms=true` in the `<parthenon/mesh>` block of the
2626
by adding an optional string as last argument to any `ParameterInput` `Get` or `GetOrAdd` call.
2727

2828
### Added (new features/APIs/variables/...)
29+
- [[PR 162]](https://github.com/parthenon-hpc-lab/athenapk/pull/162) Add pgen for cloud shattering setup
2930
- [[PR 158]](https://github.com/parthenon-hpc-lab/athenapk/pull/158) Update particle id handling (now automated `uint64`). Extend particle history lookback in turbulence pgen and include in turbulence test
3031
- [[PR 157]](https://github.com/parthenon-hpc-lab/athenapk/pull/157) Support injection of blobs with density/temp contrast in turbulence simulations
3132

docs/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ The documentation currently includes
1212
- [An extended overview of various conventions for optically thin cooling implementations](cooling_notes.md)
1313
- [Notebooks to calculate cooling tables from literature](cooling)
1414
- [Brief notes on developing code for AthenaPK](development.md)
15-
- [How to add a custom/user problem generator](pgen.md)
15+
- [How to add a custom/user problem generator](user_pgen.md)
1616
- [Units](units.md)
17+
- [Standard problem generators](pgen.md)
1718
- Detailed descriptions of more complex problem generators
1819
- [Galaxy Cluster and Cluster-like Problem Setup](cluster.md)
1920
- [Driven turbulence](turbulence.md)

docs/pgen.md

Lines changed: 26 additions & 205 deletions
Original file line numberDiff line numberDiff line change
@@ -1,217 +1,38 @@
1-
# Custom problem generators
1+
# Standard problem generators
22

3-
Different simulation setups in AthenaPK are controlled via the so-called problem generators.
4-
New problem generators can easily be added and we are happy to accept and merge contibuted problem
5-
generators by any user via pull requests.
3+
## Multi cloud shattering (`job/problem_id=shattering`)
64

7-
## Addding a new problem generator
5+
This problem generator implements the basic multi cloud shattering setup
6+
following [Gronke & Oh 2020](https://doi.org/10.1093/mnrasl/slaa033G).
87

9-
In general, four small steps are required:
8+
The initial conditions are currently hardcoded to a unit cube (though
9+
physical dimensions have to be assigned via units) with initially
10+
unit density (in code units) for the hot phase.
1011

11-
### 1. Add a new source file to the `src/pgen` folder
12+
In addition to specifying units, the problem generator can be configured via
1213

13-
The file shoud includes at least the `void ProblemGenerator(Mesh *pmesh, ParameterInput *pin, MeshData<Real> *md)`
14-
function, which is used to initialize the data at the beginning of the simulation.
15-
Alternatively, the `MeshBlock` version (`void ProblemGenerator(MeshBlock *pmb, ParameterInput *pin)`) can be used that
16-
operates on a single block at a time rather than on a collection of blocks -- though this is not recommended from a performance point of view.
17-
18-
The function (and all other functions in that file) should be encapsulated in their own namespace (that, ideally, is named
19-
identical to the file itself) so that the functions name are unique across different problem generators.
20-
21-
Tip: Do not write the problem generator file from scratch but mix and match from existing ones,
22-
e.g., start with a simple one like [orszag_tang.cpp](../src/pgen/orszag_tang.cpp).
23-
24-
### 2. Add new function(s) to `pgen.hpp`
25-
26-
All callback functions, i.e., at least the `ProblemGenerator` plus additional optional ones (see step 5 below),
27-
need to be added to [pgen.hpp](../src/pgen/pgen.hpp).
28-
Again, just follow the existing pattern in the file and add the new function declarations with the appropriate namespace.
29-
30-
### 3. Add callbacks to `main.cpp`
31-
32-
All problem specific callback functions need to be enrolled in the [`main.cpp`](../src/main.cpp) file.
33-
The selection (via the input file) is controlled by the `problem_id` string in the `<job>` block.
34-
Again, for consistency it is recommended to pick a string that matches the namespace and problem generator file.
35-
36-
### 4. Ensure new problem generator is compiled
37-
38-
Add the new source file to [src/pgen/CMakeLists.txt](../src/pgen/CMakeLists.txt) so that it will be compiled
39-
along all other problem generators.
40-
41-
### 5. (Optional) Add more additional callback
42-
43-
In addition to the `ProblemGenerator` that initializes the data, other callback functions exists
44-
that allow to modify the behavior of AthenaPK on a problem specific basis.
45-
See [Callback functions](#Callback-functions)] below for available options.
46-
47-
### 6. (Optional but most likely required) Write an input file
48-
49-
In theory, one can hardcode all paramters in the source file (like in the
50-
[orszag_tang.cpp](../src/pgen/orszag_tang.cpp) problem generator) but it
51-
prevents modification of the problem setup once the binary is compiled.
52-
53-
The more common usecase is to create an input file that contains a problem specific
54-
input block.
55-
The convention here is to have a block named `<problem/NAME>` where `NAME` is the name
56-
of the problem generator (or namespace used).
57-
For example, the Sod shock tube problem generator processes the input file with lines like
58-
```
59-
Real rho_l = pin->GetOrAddReal("problem/sod", "rho_l", 1.0);
60-
```
61-
to set the density on the left hand side of the domain.
62-
63-
## Callback functions
64-
65-
### Source functions
66-
67-
Additional (physical) source terms (e.g., the ones typically on the right hand side of
68-
system of equations) can be added in various ways from an algorithmic point of view.
69-
70-
#### Unsplit
71-
72-
Unsplit sources are added at each stage of the (multi-stage) integration after the
73-
(conserved) fluxes are calculated.
74-
Therefore, the "conserved" variables should be updated using the "primitive" ones
75-
and by taking into account the corresponding `dt` (more specifically the `beta*dt`
76-
of the particular stage), see, for example, the `DednerSource` function in
77-
[dedner_source.cpp](../src/hydro/glmmhd/dedner_source.cpp).
78-
79-
Users can enroll a custom source function
80-
```c++
81-
void MyUnsplitSource(MeshData<Real> *md, const Real beta_dt);
82-
```
83-
by implementing a function with that signature and assigning it to the
84-
`Hydro::ProblemSourceUnsplit` callback (currently in `main.cpp`).
85-
86-
Note, there is no requirement to call the function `MyUnsplitSource`.
87-
88-
#### Split first order (generally not recommended)
89-
90-
If for special circumstances sources need to be added in a fully operator split way,
91-
i.e., the source function is only called *after* the full hydro (or MHD) integration,
92-
a custom function
93-
```c++
94-
void MyFirstOrderSource(MeshData<Real> *md, const parthenon::SimTime &tm);
95-
```
96-
can be enrolled to the `Hydro::ProblemSourceFirstOrder` callback (currently in `main.cpp`).
97-
The current `dt` can be accessed through `tm.dt`.
98-
99-
Note, as the name suggests, this method is only first order accurate (while there
100-
is no requirement to call the function `MyFirstOrderSource`).
101-
102-
103-
#### Split second order (Strang splitting)
104-
105-
Strang splitting achieves second order by interleaving the main hydro/MHD update
106-
with a source update.
107-
In practice, AthenaPK calls Strang split source with `0.5*dt` before the first stage of
108-
each integrator and with `0.5*dt` after the last stage of the integrator.
109-
Note that for consistency, a Strang split source terms should update both conserved
110-
and primitive variables in all zones (i.e., also in the ghost zones as those
111-
are currently not updated after calling a source function).
112-
113-
Users can enroll a custom source function
114-
```c++
115-
void MyStrangSplitSource(MeshData<Real> *md, const Real beta_dt);
116-
```
117-
by implementing a function with that signature and assigning it to the
118-
`Hydro::ProblemSourceStrangSplit` callback (currently in `main.cpp`).
119-
120-
Note, there is no requirement to call the function `MyStrangSplitSource`.
121-
122-
123-
### Timestep restrictions
124-
125-
If additional problem specific physics are implemented (e.g., through the source
126-
functions above) that require a custom timestep, it can be added via the
127-
`ProblemEstimateTimestep` callback with the following signature
128-
```c++
129-
Real ProblemEstimateTimestep(MeshData<Real> *md);
13014
```
131-
132-
The return value is expected to be the minimum value over all blocks in the
133-
contained in the `MeshData` container, cf., the hydro/mhd `EstimateTimestep` function.
134-
Note, that the hyperbolic CFL value is currently applied after the function call, i.e.,
135-
it is also applied to the problem specific function.
136-
137-
### Additional initialization on startup (adding variables/fields, custom history output, ...)
138-
139-
Sometimes a problem generator requires a more general processing of the input file
140-
and/or needs to make certain global adjustments (e.g., adding a custom callback function
141-
for the history output or adding a new field).
142-
This can be achieved via modifying the AthenaPK "package" (currently called
143-
`parthenon::StateDescriptor`) through the following function.
144-
```c++
145-
void ProblemInitPackageData(ParameterInput *pin, parthenon::StateDescriptor *pkg)
15+
<problem/shattering>
16+
chi_i = 100 # initial overdensity
17+
T_cloud = 4e5 # initial temperature
18+
#reset_times = true # set by default
14619
```
14720

148-
For example, the [src/pgen/turbulence.cpp](../[src/pgen/turbulence.cpp]) problem generator
149-
add an additional field (here for an acceleration field) by calling
150-
```c++
151-
Metadata m({Metadata::Cell, Metadata::Derived, Metadata::OneCopy},
152-
std::vector<int>({3}));
153-
pkg->AddField("acc", m);
154-
```
155-
in the `ProblemInitPackageData`.
21+
which sets initial overdensity and temperature of the clouds, which
22+
are initialized in pressure equilibrium with the hot phase.
23+
By default, following the paper the simulation times
24+
(i.e., `tlim` and the `dt` for outputs) are rescaled with respect to
25+
the relevant dynamical timescale (e.g., cooling timescales or sound crossing timescale),
26+
which is also reported on terminal upon simulation startup.
15627

157-
### Additional initialization on mesh creation/remeshing/load balancing
28+
Moreover, following details are currently hardcoded (following the choices in
29+
the paper), but can easily be modified in the code when needed:
30+
- the individual cloud radii are fixed to 0.125 (i.e., 1/8 of the box)
31+
- four clouds are seeded at positions `{0.5, 0.5, 0.5}, {0.45, 0.5, 0.55}, {0.5, 0.47, 0.42}, {0.53, 0.56, 0.5}`
32+
- initial perturpations are using a normal distribution with standard deviation of 0.01
15833

159-
For some problem generators it is required to initialize data on "new" blocks.
160-
These new blocks can, for example, be created during mesh refinement
161-
(or derefinement) and this data is typically not active data (like
162-
conserved or primitive variables as those are handled automatically)
163-
but more general data.
164-
Once example is the phase information in the turbulence driver that
165-
does not vary over time but spatially (and therefore at a per block level).
16634

167-
The appropriate callback to enroll is
168-
```c++
169-
void InitMeshBlockUserData(MeshBlock *pmb, ParameterInput *pin)
170-
```
35+
# More complex problem generators
17136

172-
### UserWorkAfterLoop
173-
174-
If additional work is required once the main loop finishes (i.e., once the
175-
simulation reaches its final time) computations can be done inside the
176-
```c++
177-
void UserWorkAfterLoop(Mesh *mesh, ParameterInput *pin, parthenon::SimTime &tm)
178-
```
179-
callback function.
180-
This is, for example, done in the linear wave problem generator to calculate the
181-
error norms for convergence tests.
182-
183-
### MeshBlockUserWorkBeforeOutput
184-
185-
Sometimes it is desirable to further process data before an output file is written.
186-
For this the
187-
```c++
188-
void UserWorkBeforeOutput(MeshBlock *pmb, ParameterInput *pin)
189-
```
190-
callback is available, that is called once every time right before a data output
191-
(hdf5 or restart) is being written.
192-
193-
### Particles
194-
195-
#### Tracers
196-
197-
In order to allow custom seeding of tracer particles (per problem generator), the
198-
`ProblemSeedInitialTracers` function can be defined.
199-
```c++
200-
void ProblemSeedInitialTracers(Mesh *pmesh, ParameterInput *pin, parthenon::SimTime &tm);
201-
```
202-
It is executed once when a simulation is started the very first time (i.e., it
203-
is not called on subsequent restarts).
204-
See the standard tracer seeding implementation[`SeedInitialTracers`](https://github.com/parthenon-hpc-lab/athenapk/blob/main/src/tracers/tracers.cpp) for reference on how to deposit particles.
205-
206-
207-
To allow adding additional fields, the
208-
```c++
209-
void ProblemInitTracerData(ParameterInput * pin, parthenon::StateDescriptor *tracer_pkg);```
210-
callback is available.
211-
It is called at the end of the tracer package initialization and can be defined at the per-problem-generator level, see, e.g., the turbulence driver as an example.
212-
213-
Similarly, a callback is available to fill those new fields (or more) via
214-
```c++
215-
TaskStatus ProblemFillTracers(MeshData<Real> *md, parthenon::SimTime &tm, const Real dt);
216-
```
217-
It is called right after the default `FillTracers` task in the driver.
37+
- [Galaxy Cluster and Cluster-like Problem Setup](cluster.md)
38+
- [Driven turbulence](turbulence.md)

0 commit comments

Comments
 (0)