PyMPDATA_examples.utils.nondivergent_vector_field_2d

 1import numpy as np
 2
 3from PyMPDATA import VectorField
 4from PyMPDATA.boundary_conditions import Periodic
 5
 6
 7def nondivergent_vector_field_2d(grid, size, dt, stream_function: callable, halo):
 8    dx = size[0] / grid[0]
 9    dz = size[1] / grid[1]
10    dxX = 1 / grid[0]
11    dzZ = 1 / grid[1]
12
13    xX, zZ = x_vec_coord(grid)
14    rho_velocity_x = (
15        -(stream_function(xX, zZ + dzZ / 2) - stream_function(xX, zZ - dzZ / 2)) / dz
16    )
17
18    xX, zZ = z_vec_coord(grid)
19    rho_velocity_z = (
20        stream_function(xX + dxX / 2, zZ) - stream_function(xX - dxX / 2, zZ)
21    ) / dx
22
23    GC = [rho_velocity_x * dt / dx, rho_velocity_z * dt / dz]
24
25    # CFL condition
26    for val in GC:
27        np.testing.assert_array_less(np.abs(val), 1)
28
29    result = VectorField(GC, halo=halo, boundary_conditions=(Periodic(), Periodic()))
30
31    # nondivergence (of velocity field, hence dt)
32    assert np.amax(abs(result.div((dt, dt)).get())) < 5e-9
33
34    return result
35
36
37def x_vec_coord(grid):
38    nx = grid[0] + 1
39    nz = grid[1]
40    xX = np.repeat(np.linspace(0, grid[0], nx).reshape((nx, 1)), nz, axis=1) / grid[0]
41    assert np.amin(xX) == 0
42    assert np.amax(xX) == 1
43    assert xX.shape == (nx, nz)
44    zZ = (
45        np.repeat(np.linspace(1 / 2, grid[1] - 1 / 2, nz).reshape((1, nz)), nx, axis=0)
46        / grid[1]
47    )
48    assert np.amin(zZ) >= 0
49    assert np.amax(zZ) <= 1
50    assert zZ.shape == (nx, nz)
51    return xX, zZ
52
53
54def z_vec_coord(grid):
55    nx = grid[0]
56    nz = grid[1] + 1
57    xX = (
58        np.repeat(np.linspace(1 / 2, grid[0] - 1 / 2, nx).reshape((nx, 1)), nz, axis=1)
59        / grid[0]
60    )
61    assert np.amin(xX) >= 0
62    assert np.amax(xX) <= 1
63    assert xX.shape == (nx, nz)
64    zZ = np.repeat(np.linspace(0, grid[1], nz).reshape((1, nz)), nx, axis=0) / grid[1]
65    assert np.amin(zZ) == 0
66    assert np.amax(zZ) == 1
67    assert zZ.shape == (nx, nz)
68    return xX, zZ
def nondivergent_vector_field_2d(grid, size, dt, stream_function: <built-in function callable>, halo):
 8def nondivergent_vector_field_2d(grid, size, dt, stream_function: callable, halo):
 9    dx = size[0] / grid[0]
10    dz = size[1] / grid[1]
11    dxX = 1 / grid[0]
12    dzZ = 1 / grid[1]
13
14    xX, zZ = x_vec_coord(grid)
15    rho_velocity_x = (
16        -(stream_function(xX, zZ + dzZ / 2) - stream_function(xX, zZ - dzZ / 2)) / dz
17    )
18
19    xX, zZ = z_vec_coord(grid)
20    rho_velocity_z = (
21        stream_function(xX + dxX / 2, zZ) - stream_function(xX - dxX / 2, zZ)
22    ) / dx
23
24    GC = [rho_velocity_x * dt / dx, rho_velocity_z * dt / dz]
25
26    # CFL condition
27    for val in GC:
28        np.testing.assert_array_less(np.abs(val), 1)
29
30    result = VectorField(GC, halo=halo, boundary_conditions=(Periodic(), Periodic()))
31
32    # nondivergence (of velocity field, hence dt)
33    assert np.amax(abs(result.div((dt, dt)).get())) < 5e-9
34
35    return result
def x_vec_coord(grid):
38def x_vec_coord(grid):
39    nx = grid[0] + 1
40    nz = grid[1]
41    xX = np.repeat(np.linspace(0, grid[0], nx).reshape((nx, 1)), nz, axis=1) / grid[0]
42    assert np.amin(xX) == 0
43    assert np.amax(xX) == 1
44    assert xX.shape == (nx, nz)
45    zZ = (
46        np.repeat(np.linspace(1 / 2, grid[1] - 1 / 2, nz).reshape((1, nz)), nx, axis=0)
47        / grid[1]
48    )
49    assert np.amin(zZ) >= 0
50    assert np.amax(zZ) <= 1
51    assert zZ.shape == (nx, nz)
52    return xX, zZ
def z_vec_coord(grid):
55def z_vec_coord(grid):
56    nx = grid[0]
57    nz = grid[1] + 1
58    xX = (
59        np.repeat(np.linspace(1 / 2, grid[0] - 1 / 2, nx).reshape((nx, 1)), nz, axis=1)
60        / grid[0]
61    )
62    assert np.amin(xX) >= 0
63    assert np.amax(xX) <= 1
64    assert xX.shape == (nx, nz)
65    zZ = np.repeat(np.linspace(0, grid[1], nz).reshape((1, nz)), nx, axis=0) / grid[1]
66    assert np.amin(zZ) == 0
67    assert np.amax(zZ) == 1
68    assert zZ.shape == (nx, nz)
69    return xX, zZ