task2 cleanup - final adjustments
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								nbody/presentation/Computational astrophysics - presentation.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								nbody/presentation/Computational astrophysics - presentation.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -26,15 +26,6 @@ | |||||||
| // Finally - The real content | // Finally - The real content | ||||||
| = N-body forces and analytical solutions | = N-body forces and analytical solutions | ||||||
|  |  | ||||||
| // == Objective |  | ||||||
| // Implement naive N-body force computation and get an intuition of the challenges: |  | ||||||
| // - accuracy |  | ||||||
| // - 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 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| == Overview - the system | == Overview - the system | ||||||
| Get a feel for the particles and their distribution | Get a feel for the particles and their distribution | ||||||
| #columns(2)[ | #columns(2)[ | ||||||
| @@ -49,14 +40,6 @@ Get a feel for the particles and their distribution | |||||||
|   #footnote[Unit handling [#link(<task1:function_apply_units>)[code]]] |   #footnote[Unit handling [#link(<task1:function_apply_units>)[code]]] | ||||||
| ] | ] | ||||||
|  |  | ||||||
| // It is a small globular cluster with |  | ||||||
| // - 5*10^4 stars => m in terms of msol |  | ||||||
| // - radius - 10 pc |  | ||||||
| // Densities are now expressed in M_sol / pc^3 |  | ||||||
| // Forces are now expressed  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| == Density | == Density | ||||||
| Compare the computed density | Compare the computed density | ||||||
| #footnote[Density sampling [#link(<task1:function_density_distribution>)[code]]] | #footnote[Density sampling [#link(<task1:function_density_distribution>)[code]]] | ||||||
| @@ -79,8 +62,6 @@ with the analytical model provided by the _Hernquist_ model: | |||||||
|   ] |   ] | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Note that by construction, the first shell contains no particles |  | ||||||
| // => the numerical density is zero there |  | ||||||
| // Having more bins means to have shells that are nearly empty | // Having more bins means to have shells that are nearly empty | ||||||
| // => the error is large, NBINS = 30 is a good compromise | // => the error is large, NBINS = 30 is a good compromise | ||||||
|  |  | ||||||
| @@ -107,9 +88,6 @@ with the analytical model provided by the _Hernquist_ model: | |||||||
|   ] |   ] | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // basic $N^2$ matches analytical solution without dropoff. but: noisy data from "bad" samples |  | ||||||
| // $N^2$ with softening matches analytical solution but has a dropoff. No noisy data. |  | ||||||
| // => softening $\approx 1 \varepsilon$ is a sweet spot since the dropoff is "late" |  | ||||||
|  |  | ||||||
|  |  | ||||||
| == Relaxation | == Relaxation | ||||||
| @@ -135,21 +113,6 @@ We find a relaxation of $approx 30 "Myr"$ ([#link(<task1:compute_relaxation_time | |||||||
|   ] |   ] | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // The estimate for $n_{relax}$ comes from the contribution of each star-star encounter to the velocity dispersion. This depends on the perpendicular force |  | ||||||
|  |  | ||||||
| // $\implies$ a bigger softening length leads to a smaller $\delta v$. |  | ||||||
|  |  | ||||||
| // Using $n_{relax} = \frac{v^2}{\delta v^2}$, and knowing that the value of $v^2$ is derived from the Virial theorem (i.e. unaffected by the softening length), we can see that $n_{relax}$ should increase with $\varepsilon$. |  | ||||||
|  |  | ||||||
| // === Effect |  | ||||||
| // - The relaxation time **increases** with increasing softening length |  | ||||||
| // - From the integration over all impact parameters $b$ even $b_{min}$ is chosen to be larger than $\varepsilon$ $\implies$ expect only a small effect on the relaxation time |  | ||||||
|  |  | ||||||
| // **In other words:** |  | ||||||
| // The softening dampens the change of velocity => time to relax is longer |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| = Particle Mesh | = Particle Mesh | ||||||
|  |  | ||||||
| @@ -191,20 +154,10 @@ We find a relaxation of $approx 30 "Myr"$ ([#link(<task1:compute_relaxation_time | |||||||
|   ] |   ] | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // Some other comments: |  | ||||||
| // - see the artifacts because of the even grid numbers (hence the switch to 75) |  | ||||||
| // overdiscretization for large grids -> vertical spread even though r is constant |  | ||||||
| // this becomes even more apparent when looking at the data without noise - the artifacts remain |  | ||||||
| //  |  | ||||||
| // We can not rely on the interparticle distance computation for a disk! |  | ||||||
| // Given softening length 0.037 does not match the mean interparticle distance 0.0262396757880128 |  | ||||||
| //  |  | ||||||
| // Discussion of the discrepancies |  | ||||||
| // TODO |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #helpers.image_cell(t2, "plot_force_computation_time") | #helpers.image_cell(t2, "plot_force_computation_time") | ||||||
| // Computed for 10^4 particles => mesh will scale better for larger systems |  | ||||||
|  |  | ||||||
| == Time integration | == Time integration | ||||||
| *Integration step* | *Integration step* | ||||||
| @@ -213,11 +166,9 @@ We find a relaxation of $approx 30 "Myr"$ ([#link(<task1:compute_relaxation_time | |||||||
| *Timesteps* | *Timesteps* | ||||||
| Chosen such that displacement is small (compared to the inter-particle distance) [#link(<task2:integration_timestep>)[code]]: | Chosen such that displacement is small (compared to the inter-particle distance) [#link(<task2:integration_timestep>)[code]]: | ||||||
| $ | $ | ||||||
|   op(d)t = 10^(-4) dot S / v_"part" |   op(d)t = 10^(-3) dot S / v_"part" | ||||||
| $ | $ | ||||||
|  |  | ||||||
| // too large timesteps lead to instable systems <=> integration not accurate enough |  | ||||||
|  |  | ||||||
| *Full integration* | *Full integration* | ||||||
|  |  | ||||||
| [#link(<task2:function_time_integration>)[code]] | [#link(<task2:function_time_integration>)[code]] | ||||||
| @@ -244,7 +195,11 @@ $ | |||||||
| == Particle mesh solver | == Particle mesh solver | ||||||
| #helpers.image_cell(t2, "plot_pm_solver_integration") | #helpers.image_cell(t2, "plot_pm_solver_integration") | ||||||
|  |  | ||||||
| #helpers.image_cell(t2, "plot_pm_solver_stability") | #page( | ||||||
|  |   columns: 2 | ||||||
|  | )[ | ||||||
|  |   #helpers.image_cell(t2, "plot_pm_solver_stability") | ||||||
|  | ] | ||||||
|  |  | ||||||
|  |  | ||||||
| = Appendix - Code <appendix> | = Appendix - Code <appendix> | ||||||
|   | |||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 403 KiB After Width: | Height: | Size: 404 KiB | 
| @@ -40,7 +40,7 @@ def n_body_forces(particles: np.ndarray, G: float = 1, softening: float = 0): | |||||||
|         r_adjusted[i] = 1 |         r_adjusted[i] = 1 | ||||||
|         num[i] = 0 |         num[i] = 0 | ||||||
|  |  | ||||||
|         f = - np.sum((num.T / r_adjusted**1.5).T, axis=0) * m_current |         f = np.sum((num.T / r_adjusted**1.5).T, axis=0) * m_current | ||||||
|         forces[i] = f |         forces[i] = f | ||||||
|  |  | ||||||
|         if i!= 0 and i % 5000 == 0: |         if i!= 0 and i % 5000 == 0: | ||||||
|   | |||||||
| @@ -40,10 +40,9 @@ def kwargs_to_str(kwargs: dict): | |||||||
|     """ |     """ | ||||||
|     base_str = "" |     base_str = "" | ||||||
|     for k, v in kwargs.items(): |     for k, v in kwargs.items(): | ||||||
|         print(type(v)) |  | ||||||
|         if type(v) == float: |         if type(v) == float: | ||||||
|             base_str += f"{k}_{v:.3f}" |             base_str += f"{k}_{v:.3f}" | ||||||
|         elif type(v) == callable: |         elif callable(v): | ||||||
|             base_str += f"{k}_{v.__name__}" |             base_str += f"{k}_{v.__name__}" | ||||||
|         else: |         else: | ||||||
|             base_str += f"{k}_{v}" |             base_str += f"{k}_{v}" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user