|
5 | 5 |
|
6 | 6 | import yt |
7 | 7 | from yt.data_objects.selection_objects.region import YTRegion |
| 8 | +from yt.loaders import load_particles |
8 | 9 | from yt.testing import ( |
9 | 10 | assert_rel_equal, |
10 | 11 | cubicspline_python, |
@@ -306,6 +307,78 @@ def makemasses(i, j, k): |
306 | 307 | assert_rel_equal(baseimg_wtd.v, testimg_wtd.v, 1) |
307 | 308 |
|
308 | 309 |
|
| 310 | +def test_massconservation_pixave(): |
| 311 | + bbox = np.array([[0., 3.], [0., 3.], [0., 3.]]) |
| 312 | + pz = 1.5 |
| 313 | + periodic = True |
| 314 | + periods = 3. |
| 315 | + nrandom = 50 |
| 316 | + |
| 317 | + # random centers, three pixel size + hsml sets |
| 318 | + # test three cases in the backend routine |
| 319 | + rng = np.random.default_rng() |
| 320 | + pxs = rng.uniform(0., 3., nrandom) |
| 321 | + pys = rng.uniform(0., 3., nrandom) |
| 322 | + # particles < pixels: overlap 1, 2x1, or 2x2 pixels |
| 323 | + hsmls1 = rng.uniform(0.01, 0.05, nrandom) |
| 324 | + outsize1 = (7, 7) |
| 325 | + # particles ~ pixels: typical 2x2 overlaps |
| 326 | + hsmls2 = rng.uniform(0.1, 0.25, nrandom) |
| 327 | + outsize2 = (7, 7) |
| 328 | + # particles > pixels: |
| 329 | + hsmls3 = rng.uniform(0.07, 0.8, nrandom) |
| 330 | + outsize3 = (50, 50) |
| 331 | + |
| 332 | + for i, (hsmls, outsize) in enumerate([(hsmls1, outsize1), |
| 333 | + (hsmls2, outsize2), |
| 334 | + (hsmls3, outsize3), |
| 335 | + ]): |
| 336 | + |
| 337 | + masses_rel = [] |
| 338 | + for i in range(nrandom): |
| 339 | + data = { |
| 340 | + "particle_position_x": (np.array([pxs[i]]), "cm"), |
| 341 | + "particle_position_y": (np.array([pys[i]]), "cm"), |
| 342 | + "particle_position_z": (np.array([pz]), "cm"), |
| 343 | + "particle_mass": (np.array([1.]), "g"), |
| 344 | + "particle_velocity_x": (np.zeros(1), "cm/s"), |
| 345 | + "particle_velocity_y": (np.zeros(1), "cm/s"), |
| 346 | + "particle_velocity_z": (np.zeros(1), "cm/s"), |
| 347 | + "smoothing_length": (np.ones(1) * hsmls[i], "cm"), |
| 348 | + "density": (np.array([1.5]), "g/cm**3"), |
| 349 | + } |
| 350 | + ds = load_particles( |
| 351 | + data=data, |
| 352 | + bbox=bbox, |
| 353 | + periodicity=(periodic,) * 3, |
| 354 | + length_unit=1.0, |
| 355 | + mass_unit=1.0, |
| 356 | + time_unit=1.0, |
| 357 | + velocity_unit=1.0, |
| 358 | + ) |
| 359 | + ds.kernel_name = "cubic" |
| 360 | + |
| 361 | + proj = ds.proj(("gas", "density"), 2) |
| 362 | + frb = proj.to_frb( |
| 363 | + width=(3., "cm"), |
| 364 | + resolution=outsize, |
| 365 | + height=(3., "cm"), |
| 366 | + center=np.array([1.5, 1.5, 1.5]), |
| 367 | + periodic=True, |
| 368 | + pixelmeaning="pixelave", |
| 369 | + ) |
| 370 | + out = frb.get_image(("gas", "density")) |
| 371 | + mass_in = 1. |
| 372 | + mass_out = np.sum(out.v) * periods**2 / np.prod(outsize) |
| 373 | + masses_rel.append(mass_out / mass_in - 1.) |
| 374 | + masses_rel = np.array(masses_rel) |
| 375 | + minrel = np.min(masses_rel) |
| 376 | + maxrel = np.max(masses_rel) |
| 377 | + print(f"Mass conservation test pixel/hsml set {i}:" |
| 378 | + " mass conservation deviations fractions" |
| 379 | + f" {minrel:.2e} -- {maxrel:.2e} ") |
| 380 | + assert np.all(np.abs(masses_rel) < 1e-4) |
| 381 | + |
309 | 382 | @pytest.mark.parametrize("periodic", [True, False]) |
310 | 383 | @pytest.mark.parametrize("shiftcenter", [False, True]) |
311 | 384 | @pytest.mark.parametrize("zoff", [0.0, 0.1, 0.5, 1.0]) |
|
0 commit comments