cleanup for the presentation

This commit is contained in:
2025-02-01 18:33:07 +01:00
parent 7db6480e51
commit 37a2687ffe
8 changed files with 904 additions and 638 deletions

View File

@@ -0,0 +1,82 @@
// Helpers for code block displaying
#import "@preview/based:0.2.0": base64
#let code_font_scale = 0.6em
#let cell_matcher(cell, cell_tag) = {
// Matching function to check if a cell has a specific tag
if cell.cell_type != "code" {
return false
}
let metadata = cell.metadata
if metadata.keys().contains("tags") == false {
return false
}
return cell.metadata.tags.contains(cell_tag)
}
#let code_cell(fcontent, cell_tag) = {
// Extract the content of a cell and display it as a code block
let cells = fcontent.cells
let matching_cell = cells.find(x => cell_matcher(x, cell_tag))
let cell_content = matching_cell.source
let single_line = cell_content.fold("", (acc, x) => acc + x)
text(
raw(
single_line,
lang: "python",
block: true
),
size: code_font_scale
)
}
#let image_cell(fcontent, cell_tag) = {
// Extract the output (image) of a cell and display it as an image
let cells = fcontent.cells
let matching_cell = cells.find(x => cell_matcher(x, cell_tag))
let outputs = matching_cell.outputs
for output in outputs {
let image_data = output.at("data", default: (:)).at("image/png", default: none)
if image_data != none {
align(
center,
image.decode(
base64.decode(image_data),
// height: 70% // the height should be set by the caller. This gives the flexibility to adjust the height of the image
)
)
}
}
}
#let code_reference_cell(fcontent, cell_tag) = {
// Extract the output (text) of a cell and display it as a code block
// This is useful for showing the code of imported functions
let cells = fcontent.cells
let matching_cell = cells.find(x => cell_matcher(x, cell_tag))
let outputs = matching_cell.outputs
for output in outputs {
let cell_output = output.at("text", default: (:))
if cell_output != none {
let single_line = cell_output.join("")
text(
raw(
single_line,
lang: "python",
block: true
),
size: code_font_scale
)
}
}
}

Binary file not shown.

View File

@@ -1,7 +1,6 @@
#import "@preview/diatypst:0.2.0": *
#import "@preview/based:0.2.0": base64
#set text(font: "Cantarell")
// #set text(font: "Cantarell")
// #set heading(numbering: (..nums)=>"")
#show: slides.with(
@@ -11,74 +10,25 @@
authors: ("Rémy Moll"),
toc: false,
// layout: "large",
// ratio: 16/9,
)
#import "helpers.typ"
// KINDA COOL:
// _diatypst_ defines some default styling for elements, e.g Terms created with ```typc / Term: Definition``` will look like this
// / *Term*: Definition
// Helpers for code block displaying
#let cell_matcher(cell, cell_tag) = {
if cell.cell_type != "code" {
return false
}
let metadata = cell.metadata
if metadata.keys().contains("tags") == false {
return false
}
return cell.metadata.tags.contains(cell_tag)
}
#let code_cell(fcontent, cell_tag) = {
let cells = fcontent.cells
let matching_cell = cells.find(x => cell_matcher(x, cell_tag))
let cell_content = matching_cell.source
// format the cell content
let single_line = cell_content.fold("", (acc, x) => acc + x)
text(
raw(
single_line,
lang: "python",
block: true
),
size: 0.8em
)
}
#let image_cell(fcontent, cell_tag) = {
let cells = fcontent.cells
let matching_cell = cells.find(x => cell_matcher(x, cell_tag))
let outputs = matching_cell.outputs
for output in outputs {
let image_data = output.at("data", default: (:)).at("image/png", default: none)
if image_data != none {
align(
center,
image.decode(
base64.decode(image_data),
// format: "png",
height: 70%
)
)
}
}
}
// Where is the code?
// Setup of code location
#let t1 = json("../task1.ipynb")
#let t2 = json("../task2-particle-mesh.ipynb")
// Content
// Finally - The real content
= N-body forces and analytical solutions
== Objective
@@ -87,62 +37,188 @@ Implement naive N-body force computation and get an intuition of the challenges:
- computation time
- stability
$=>$ still useful to compute basic quantities of the system, but too limited for large systems or the dynamical evolution of the system
$==>$ still useful to compute basic quantities of the system, but too limited for large systems or the dynamical evolution of the system
== Overview - the system
Get a feel for the particles and their distribution. [Code at @task1:plot_particle_distribution[]]
#image_cell(t1, "plot_particle_distribution")
Get a feel for the particles and their distribution. [#link(<task1:plot_particle_distribution>)[code]]
#code_cell(t1, "plotting")
== Inspecting the data
#code_cell(t2, "plotting")
#image_cell(t2, "plotting")
#columns(2)[
#helpers.image_cell(t1, "plot_particle_distribution")
Note: for visibility the outer particles are not shown.
#colbreak()
The system at hand is characterized by:
- $N ~ 10^4$ stars
- a _spherical_ distribution
$==>$ treat the system as a *globular cluster*
]
== Density
Some images about the density
We compare the computed density with the analytical model provided by the _Hernquist_ model:
#grid(
columns: (1fr, 2fr),
inset: 0.5em,
block[
$
rho(r) = M/(2 pi) a / (r dot (r + a)^3)
$
where we infer $a$ from the half-mass radius:
$
r_"hm" = (1 + sqrt(2)) dot a
$
#text(size: 0.6em)[
Density sampling [#link(<task1:function_density_distribution>)[code]];
]
],
block[
#helpers.image_cell(t1, "plot_density_distribution")
]
)
#block(
height: 1fr,
)
== Force computation
// N Body and variations
#grid(
columns: (2fr, 1fr),
inset: 0.5em,
block[
#helpers.image_cell(t1, "plot_force_radial")
// The radial force is computed as the sum of the forces of all particles in the system.
#text(size: 0.6em)[
Analytical force [#link(<task1:function_analytical_forces>)[code]];
$N^2$ force [#link(<task1:function_n2_forces>)[code]];
$epsilon$ computation [#link(<task1:function_interparticle_distance>)[code]];
]
],
block[
Discussion:
- the analytical method replicates the behavior accurately
- at small softenings the $N^2$ method has noisy artifacts
- a $1 dot epsilon$ softening is a good compromise between accuracy and stability
]
)
== N Body and variations
sdsd
== Relaxation
sd
Relaxation [#link(<task1:compute_relaxation_time>)[code]]:
// #helpers.code_cell(t1, "compute_relaxation_time")
= Default Styling in diatypst
Discussion!
== Terms, Code, Lists
_diatypst_ defines some default styling for elements, e.g Terms created with ```typc / Term: Definition``` will look like this
/ *Term*: Definition
A code block like this
= Particle Mesh
```python
// Example Code
print("Hello World!")
```
Lists have their marker respect the `title-color`
#columns(2)[
- A
- AAA
- B
#colbreak()
1. AAA
2. BBB
3. CCC
== Overview - the system
#page(
columns: 2
)[
#helpers.image_cell(t2, "plot_particle_distribution")
]
== Force computation
#helpers.code_reference_cell(t2, "function_mesh_force")
#helpers.image_cell(t2, "plot_force_radial")
#grid(
columns: (2fr, 1fr),
inset: 0.5em,
block[
#helpers.image_cell(t2, "plot_force_radial_single")
// The radial force is computed as the sum of the forces of all particles in the system.
#text(size: 0.6em)[
$N^2$ force [#link(<task1:function_n2_forces>)[code]];
$epsilon$ computation [#link(<task1:function_interparticle_distance>)[code]];
Mesh force [#link(<task2:function_mesh_force>)[code]];
]
],
block[
Discussion:
- using the (established) baseline of $N^2$ with $1 dot epsilon$ softening
- small grids are stable but inaccurate at the center
- very large grids have issues with overdiscretization
$==> 75 times 75 times 75$ as a good compromise
]
)
== Time integration
=== Runge-Kutta
#helpers.code_reference_cell(t2, "function_runge_kutta")
#pagebreak()
=== Results
#align(center, block(
height: 1fr,
)[
#helpers.image_cell(t2, "plot_system_evolution")
])
== Particle mesh solver
sdlsd
= Appendix - Code <appendix>
= Appendix - Code
== Code
#helpers.code_cell(t1, "plot_particle_distribution")
<task1:plot_particle_distribution>
#code_cell(t1, "plot_particle_distribution")
#pagebreak(weak: true)
#helpers.code_reference_cell(t1, "function_density_distribution")
<task1:function_density_distribution>
#pagebreak(weak: true)
#helpers.code_reference_cell(t1, "function_analytical_forces")
<task1:function_analytical_forces>
#pagebreak(weak: true)
#helpers.code_reference_cell(t1, "function_n2_forces")
<task1:function_n2_forces>
#pagebreak(weak: true)
#helpers.code_reference_cell(t1, "function_interparticle_distance")
<task1:function_interparticle_distance>
#pagebreak(weak: true)
#helpers.code_cell(t1, "compute_relaxation_time")
<task1:compute_relaxation_time>
#pagebreak(weak: true)
#helpers.code_reference_cell(t2, "function_mesh_force")
<task2:function_mesh_force>
#context {
counter(page).update(locate(<appendix>).page())
}