|
10 | 10 |
|
11 | 11 | if __name__ == '__main__': |
12 | 12 |
|
| 13 | + # most of the code in this file is related to Python matplotlib |
| 14 | + # the most notable ASGarD methods are |
| 15 | + # run_with_args() |
| 16 | + # pde_snapshot() |
| 17 | + # get_aux_field() |
| 18 | + # get_moment() |
| 19 | + # plot_data2d() |
| 20 | + |
13 | 21 | filename = "bgk_run.h5" |
| 22 | + # the "run_with_args" method will the provided executable file with the provided |
| 23 | + # string with arguments and it will also append all arguments used in the call |
| 24 | + # to this python script, e.g., |
| 25 | + # python3 -m bgk.py -m 8 -a 1.E-6 -n 20 |
| 26 | + # will result in a call |
| 27 | + # ./bgk -of bgk_run.h5 -m 8 -a 1.E-6 -n 20 |
| 28 | + # |
| 29 | + # run_with_args() accepts an additional list of arguments, e.g., modified list of sys.argv |
| 30 | + # for example: |
| 31 | + # python3 -m bgk.py run -m 8 |
| 32 | + # then modify the code: |
| 33 | + # mylist = sys.argv |
| 34 | + # mylist.remove("run") if "run" in mylist else None |
| 35 | + # asgard.run_with_args("./bgk", f"-of {filename}", mylist) # runs ./bgk -of bgk_run.h5 -m 8 |
| 36 | + # |
14 | 37 | asgard.run_with_args("./bgk", f"-of {filename}") |
15 | 38 |
|
16 | 39 | snapshot = asgard.pde_snapshot(filename) |
17 | 40 |
|
18 | | - if snapshot.num_dimensions == 2: |
19 | | - # 1x1v case |
| 41 | + # get the boundaries for the domain, this is needed to set the correct size |
| 42 | + # for the matplotlib imshow command |
| 43 | + xmin = snapshot.dimension_min[0] |
| 44 | + ymin = snapshot.dimension_min[1] |
| 45 | + xmax = snapshot.dimension_max[0] |
| 46 | + ymax = snapshot.dimension_max[1] |
| 47 | + |
| 48 | + if "poisson" in snapshot.subtitle: |
| 49 | + # 1x1v case, poisson |
| 50 | + # plotting the initial and final perturbations, i.e., aux fields |
| 51 | + |
| 52 | + # Try running this with the following: |
| 53 | + # python3 bgk.py -poisson -m 9 -a 1.E-6 -t 2 |
| 54 | + |
| 55 | + assert snapshot.num_position == 1 and snapshot.num_velocity == 1 |
| 56 | + |
| 57 | + # the aux fields can be requested either by name or by index, |
| 58 | + # e.g., init_pert = snapshot.get_aux_field(0) |
| 59 | + init_pert = snapshot.get_aux_field("initial perturbation") |
| 60 | + final_pert = snapshot.get_aux_field("final perturbation") |
| 61 | + |
| 62 | + # generating two 2D plots |
| 63 | + z0, x, y = init_pert.plot_data2d(((), ()), num_points = 128) |
| 64 | + z1, x, y = final_pert.plot_data2d(((), ()), num_points = 128) |
| 65 | + |
| 66 | + fig, (ax0, ax1) = plt.subplots(1, 2) |
| 67 | + |
| 68 | + fig.suptitle(snapshot.title) |
| 69 | + |
| 70 | + ax0.set_title(init_pert.title + ", t = 0") |
| 71 | + img0 = ax0.imshow(np.flipud(z0), cmap='turbo', extent=[xmin, xmax, ymin, ymax]) |
| 72 | + ax0.set_xlabel("x", fontsize = 'large') |
| 73 | + ax0.set_ylabel("v", fontsize = 'large') |
| 74 | + fig.colorbar(img0, ax=ax0, orientation='vertical') |
| 75 | + |
| 76 | + ax1.set_title(final_pert.title + f", t = {final_pert.time:.4f}") |
| 77 | + img1 = ax1.imshow(np.flipud(z1), cmap='turbo', extent=[xmin, xmax, ymin, ymax]) |
| 78 | + ax1.set_xlabel("x", fontsize = 'large') |
| 79 | + ax1.set_ylabel("v", fontsize = 'large') |
| 80 | + fig.colorbar(img1, ax=ax1, orientation='vertical') |
| 81 | + |
| 82 | + plt.show() |
| 83 | + |
| 84 | + elif snapshot.num_dimensions == 2: |
| 85 | + # 1x1v case, shock1d |
| 86 | + |
| 87 | + # When using high collision frequency, the density develops a stair-case pattern. |
| 88 | + # |
| 89 | + # Try running this with: |
| 90 | + # python3 bgk.py -shock1d -nu 1000 -m 8 -a 1.E-5 -n 2000 |
| 91 | + |
| 92 | + assert snapshot.num_position == 1 and snapshot.num_velocity == 1 |
| 93 | + |
| 94 | + # obtaining the auxiliary fields associated with the moments |
| 95 | + # the 3 variables are another instances of the snapshot class |
20 | 96 | m0sh = snapshot.get_moment((0, )) |
21 | 97 | m1sh = snapshot.get_moment((1, )) |
22 | 98 | m2sh = snapshot.get_moment((2, )) |
23 | 99 |
|
24 | | - m0, x = m0sh.plot_data1d(((), ), num_points = 64) |
25 | | - m1, x = m1sh.plot_data1d(((), ), num_points = 64) |
26 | | - m2, x = m2sh.plot_data1d(((), ), num_points = 64) |
| 100 | + m0, x = m0sh.plot_data1d(((), ), num_points = 128) |
| 101 | + m1, x = m1sh.plot_data1d(((), ), num_points = 128) |
| 102 | + m2, x = m2sh.plot_data1d(((), ), num_points = 128) |
| 103 | + |
| 104 | + fig, (ax0, ax1) = plt.subplots(1, 2) |
27 | 105 |
|
28 | | - plt.figure(1) |
29 | | - fig, (ax1, ax2) = plt.subplots(1, 2) |
| 106 | + fig.suptitle(snapshot.title + f" ({snapshot.subtitle})") |
30 | 107 |
|
31 | | - ax1.plot(x, m0, 'b', label = 'mass') |
| 108 | + # instead of plotting the "raw" moment, we compute the fluid variables |
| 109 | + # density, velocity and temperature |
| 110 | + ax0.set_title("fluid variables") |
| 111 | + ax0.plot(x, m0, 'b', label = 'density') |
32 | 112 | u = m1 / m0 |
33 | | - ax1.plot(x, u, 'g', label = 'avg. speed') |
34 | | - ax1.plot(x, m2 / m0 - u * u, 'r', label = 'temperature') |
| 113 | + ax0.plot(x, u, 'g:', label = 'avg. velocity') |
| 114 | + ax0.plot(x, m2 / m0 - u * u, 'r-.', label = 'temperature') |
| 115 | + ax0.set_xlabel("x", fontsize = 'large') |
| 116 | + ax0.set_ylabel("value", fontsize = 'large') |
35 | 117 |
|
36 | | - ax1.legend() |
| 118 | + ax0.legend() |
37 | 119 |
|
38 | 120 | z, x, y = snapshot.plot_data2d(((), ()), num_points = 128) |
39 | 121 |
|
40 | | - xmin = snapshot.dimension_min[0] |
41 | | - ymin = snapshot.dimension_min[1] |
42 | | - xmax = snapshot.dimension_max[0] |
43 | | - ymax = snapshot.dimension_max[1] |
| 122 | + ax1.set_title(f"solution at t = {snapshot.time:.4f}") |
| 123 | + img1 = ax1.imshow(np.flipud(z), cmap='viridis', extent=[xmin, xmax, ymin, ymax]) |
| 124 | + ax1.set_xlabel("x", fontsize = 'large') |
| 125 | + ax1.set_ylabel("v", fontsize = 'large') |
| 126 | + fig.colorbar(img1, ax=ax1, orientation='vertical') |
| 127 | + |
| 128 | + plt.show() |
44 | 129 |
|
45 | | - comp = ax2.imshow(np.flipud(z), cmap='turbo', extent=[xmin, xmax, ymin, ymax]) |
| 130 | + elif snapshot.num_dimensions == 4: |
| 131 | + # 2x2v case, shock2d |
| 132 | + |
| 133 | + # This is NOT the proper way to manage the 2D BGK example. |
| 134 | + # Even on a good machine, running the 2D problem can take in order of hours, |
| 135 | + # thus, it is better to separate the running and plotting logic. |
| 136 | + # Such split is beyond the scope of this example, |
| 137 | + # but look at the comment related to run_with_args() and custom arguments. |
| 138 | + |
| 139 | + # example command: |
| 140 | + # python3 bgk.py -shock2d -nu 100 -m 8 -a 5.E-5 -n 2000 |
| 141 | + # |
| 142 | + # This is nice visual example but also takes a while to compute. |
| 143 | + # It requires up to 90 million degrees of freedom and minimum 16GB GPU |
| 144 | + # or 32GB of system RAM. On a workstation Nvidia GPU this takes little over 2 hours. |
| 145 | + |
| 146 | + assert snapshot.num_position == 2 and snapshot.num_velocity == 2 |
| 147 | + |
| 148 | + # the moments are now defined by 2D tuples |
| 149 | + m0sh = snapshot.get_moment((0, 0)) |
| 150 | + m10sh = snapshot.get_moment((1, 0)) |
| 151 | + m01sh = snapshot.get_moment((0, 1)) |
| 152 | + m20sh = snapshot.get_moment((2, 0)) |
| 153 | + m02sh = snapshot.get_moment((0, 2)) |
| 154 | + |
| 155 | + m0, x, y = m0sh.plot_data2d(((), ()), num_points = 128) |
| 156 | + m10, x, y = m10sh.plot_data2d(((), ()), num_points = 128) |
| 157 | + m01, x, y = m01sh.plot_data2d(((), ()), num_points = 128) |
| 158 | + m20, x, y = m20sh.plot_data2d(((), ()), num_points = 128) |
| 159 | + m02, x, y = m02sh.plot_data2d(((), ()), num_points = 128) |
| 160 | + |
| 161 | + |
| 162 | + fig, (ax0, ax1, ax2) = plt.subplots(1, 3) |
| 163 | + |
| 164 | + fig.suptitle(snapshot.title + f" ({snapshot.subtitle})") |
| 165 | + |
| 166 | + # instead of plotting the "raw" moment, we compute the fluid variables |
| 167 | + # density, velocity and temperature |
| 168 | + ax0.set_title("density") |
| 169 | + img0 = ax0.imshow(np.flipud(m0), cmap='viridis', extent=[xmin, xmax, ymin, ymax]) |
| 170 | + fig.colorbar(img0, ax=ax0, orientation='vertical') |
| 171 | + ax0.set_xlabel("x1", fontsize = 'large') |
| 172 | + ax0.set_ylabel("x2", fontsize = 'large') |
| 173 | + |
| 174 | + ax1.set_title("avg. speed") |
| 175 | + u0 = m10 / m0 |
| 176 | + u1 = m01 / m0 |
| 177 | + aspd = np.sqrt(u0 * u0 + u1 * u1) |
| 178 | + img1 = ax1.imshow(np.flipud(aspd), cmap='turbo', extent=[xmin, xmax, ymin, ymax]) |
| 179 | + fig.colorbar(img1, ax=ax1, orientation='vertical') |
| 180 | + ax1.set_xlabel("x1", fontsize = 'large') |
| 181 | + ax1.set_ylabel("x2", fontsize = 'large') |
| 182 | + |
| 183 | + ax2.set_title("temperature") |
| 184 | + temp = 0.5 * (m20 + m02) / m0 - u0 * u0 - u1 * u1 |
| 185 | + img2 = ax2.imshow(np.flipud(temp), cmap='coolwarm', extent=[xmin, xmax, ymin, ymax]) |
| 186 | + fig.colorbar(img2, ax=ax2, orientation='vertical') |
| 187 | + ax2.set_xlabel("x1", fontsize = 'large') |
| 188 | + ax2.set_ylabel("x2", fontsize = 'large') |
46 | 189 |
|
47 | 190 | plt.show() |
48 | 191 |
|
|
0 commit comments