Skip to content

Commit 3cd7fd0

Browse files
authored
Merge pull request #16 from hsalehipour/main
modified two benchmark examples and fixed a bug in moving bounce-back
2 parents 4ba5dc3 + 21268fb commit 3cd7fd0

File tree

4 files changed

+91
-62
lines changed

4 files changed

+91
-62
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*zraw
1111
*mhd
1212
*png
13+
*pdf
1314
# Exclusions
1415
!jax-lbm.png
1516
!airfoil.png

examples/CFD/channel3d.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def __init__(self, **kwargs):
6262
def set_boundary_conditions(self):
6363
# top and bottom sides of the channel are no-slip and the other directions are periodic
6464
wall = np.concatenate((self.boundingBoxIndices['bottom'], self.boundingBoxIndices['top']))
65-
self.BCs.append(BounceBack(tuple(wall.T), self.gridInfo, self.precisionPolicy))
65+
self.BCs.append(Regularized(tuple(wall.T), self.gridInfo, self.precisionPolicy, 'velocity', np.zeros((wall.shape[0], 3))))
6666
return
6767

6868
def initialize_macroscopic_fields(self):
@@ -107,8 +107,11 @@ def output_data(self, **kwargs):
107107
dns_dic = get_dns_data()
108108
plt.clf()
109109
plt.semilogx(yplus, uplus,'r.', yplus, uplus_loglaw, 'k:', dns_dic['y+'], dns_dic['Umean'], 'b-')
110-
fname = "uplus_" + str(timestep).zfill(4) + '.png'
111-
plt.savefig(fname)
110+
ax = plt.gca()
111+
ax.set_xlim([0.1, 300])
112+
ax.set_ylim([0, 20])
113+
fname = "uplus_" + str(timestep//10000).zfill(5) + '.pdf'
114+
plt.savefig(fname, format='pdf')
112115
fields = {"rho": rho[..., 0], "u_x": u[..., 0], "u_y": u[..., 1], "u_z": u[..., 2]}
113116
save_fields_vtk(timestep, fields)
114117

@@ -117,17 +120,19 @@ def output_data(self, **kwargs):
117120
if __name__ == "__main__":
118121
precision = "f64/f64"
119122
lattice = LatticeD3Q27(precision)
123+
120124
# h: channel half-width
121-
h = 10
125+
h = 50
126+
122127
# Define channel geometry based on h
123128
nx = 6*h
124129
ny = 3*h
125130
nz = 2*h
126131

127132
# Define flow regime
128133
Re_tau = 180
129-
u_tau = 0.004
130-
# DeltaPlus = Re_tau/h # DeltaPlus = u_tau / nu * Delta where u_tau / nu = Re_tau/h
134+
u_tau = 0.001
135+
DeltaPlus = Re_tau/h # DeltaPlus = u_tau / nu * Delta where u_tau / nu = Re_tau/h
131136
visc = u_tau * h / Re_tau
132137
omega = 1.0 / (3.0 * visc + 0.5)
133138

@@ -146,8 +151,8 @@ def output_data(self, **kwargs):
146151
'ny': ny,
147152
'nz': nz,
148153
'precision': precision,
149-
'io_rate': 20000,
150-
'print_info_rate': 20000
154+
'io_rate': 500000,
155+
'print_info_rate': 100000
151156
}
152157
sim = turbulentChannel(**kwargs)
153-
sim.run(4000000)
158+
sim.run(10000000)

examples/CFD/taylor_green_vortex.py

Lines changed: 62 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@
66

77

88
from src.boundary_conditions import *
9-
from jax.config import config
109
from src.utils import *
1110
import numpy as np
1211
from src.lattice import LatticeD2Q9
1312
from src.models import BGKSim, KBCSim, AdvectionDiffusionBGK
14-
import jax.numpy as jnp
15-
from jax.experimental import mesh_utils
16-
from jax.sharding import PositionalSharding
1713
import os
1814
import matplotlib.pyplot as plt
15+
import json
1916

2017
# Use 8 CPU devices
2118
# os.environ["XLA_FLAGS"] = '--xla_force_host_platform_device_count=8'
@@ -25,8 +22,8 @@
2522
jax.config.update('jax_enable_x64', True)
2623

2724
def taylor_green_initial_fields(xx, yy, u0, rho0, nu, time):
28-
ux = -u0 * np.cos(xx) * np.sin(yy) * np.exp(-2 * nu * time)
29-
uy = u0 * np.sin(xx) * np.cos(yy) * np.exp(-2 * nu * time)
25+
ux = u0 * np.sin(xx) * np.cos(yy) * np.exp(-2 * nu * time)
26+
uy = -u0 * np.cos(xx) * np.sin(yy) * np.exp(-2 * nu * time)
3027
rho = 1.0 - rho0 * u0 ** 2 / 12. * (np.cos(2. * xx) + np.cos(2. * yy)) * np.exp(-4 * nu * time)
3128
return ux, uy, np.expand_dims(rho, axis=-1)
3229

@@ -51,7 +48,7 @@ def initialize_populations(self, rho, u):
5148
ADE = AdvectionDiffusionBGK(**kwargs)
5249
ADE.initialize_macroscopic_fields = self.initialize_macroscopic_fields
5350
print("Initializing the distribution functions using the specified macroscopic fields....")
54-
f = ADE.run(20000)
51+
f = ADE.run(int(20000*32/nx))
5552
return f
5653

5754
def output_data(self, **kwargs):
@@ -64,49 +61,67 @@ def output_data(self, **kwargs):
6461
time = timestep * (kx**2 + ky**2)/2.
6562
ux_th, uy_th, rho_th = taylor_green_initial_fields(xx, yy, vel_ref, 1, visc, time)
6663
vel_err_L2 = np.sqrt(np.sum((u[..., 0]-ux_th)**2 + (u[..., 1]-uy_th)**2) / np.sum(ux_th**2 + uy_th**2))
67-
print("error= {:07.6f}".format(vel_err_L2))
64+
rho_err_L2 = np.sqrt(np.sum((rho - rho_th)**2) / np.sum(rho_th**2))
65+
print("Vel error= {:07.6f}, Pressure error= {:07.6f}".format(vel_err_L2, rho_err_L2))
6866
if timestep == endTime:
6967
ErrL2ResList.append(vel_err_L2)
68+
ErrL2ResListRho.append(rho_err_L2)
7069
# save_image(timestep, u)
7170

7271

7372
if __name__ == "__main__":
74-
precision = "f64/f64"
75-
lattice = LatticeD2Q9(precision)
76-
77-
resList = [32, 64, 128, 256, 512]
78-
ErrL2ResList = []
79-
80-
for nx in resList:
81-
print("Running at nx = ny = {:07.6f}".format(nx))
82-
ny = nx
83-
twopi = 2.0 * np.pi
84-
coord = np.array([(i, j) for i in range(nx) for j in range(ny)])
85-
xx, yy = coord[:, 0], coord[:, 1]
86-
kx, ky = twopi / nx, twopi / ny
87-
xx = xx.reshape((nx, ny)) * kx
88-
yy = yy.reshape((nx, ny)) * ky
89-
90-
Re = 1000.0
91-
vel_ref = 0.04*32/nx
92-
93-
visc = vel_ref * nx / Re
94-
omega = 1.0 / (3.0 * visc + 0.5)
95-
print("omega = ", omega)
96-
os.system("rm -rf ./*.vtk && rm -rf ./*.png")
97-
kwargs = {
98-
'lattice': lattice,
99-
'omega': omega,
100-
'nx': nx,
101-
'ny': ny,
102-
'nz': 0,
103-
'precision': precision,
104-
'io_rate': 500,
105-
'print_info_rate': 500
106-
}
107-
sim = TaylorGreenVortex(**kwargs)
108-
endTime = int(20000*nx/32.0)
109-
sim.run(endTime)
110-
plt.loglog(resList, ErrL2ResList, '-o')
111-
plt.loglog(resList, 1e-3*(np.array(resList)/128)**(-2), '--')
112-
plt.savefig('Error.png'); plt.savefig('Error.pdf', format='pdf')
73+
precision_list = ["f32/f32", "f64/f32", "f64/f64"]
74+
resList = [32, 64, 128, 256, 512, 1024]
75+
result_dict = dict.fromkeys(precision_list)
76+
result_dict['resolution_list'] = resList
77+
78+
for precision in precision_list:
79+
lattice = LatticeD2Q9(precision)
80+
ErrL2ResList = []
81+
ErrL2ResListRho = []
82+
result_dict[precision] = dict.fromkeys(['vel_error', 'rho_error'])
83+
for nx in resList:
84+
print("Running at nx = ny = {:07.6f}".format(nx))
85+
ny = nx
86+
twopi = 2.0 * np.pi
87+
coord = np.array([(i, j) for i in range(nx) for j in range(ny)])
88+
xx, yy = coord[:, 0], coord[:, 1]
89+
kx, ky = twopi / nx, twopi / ny
90+
xx = xx.reshape((nx, ny)) * kx
91+
yy = yy.reshape((nx, ny)) * ky
92+
93+
Re = 1600.0
94+
vel_ref = 0.04*32/nx
95+
96+
visc = vel_ref * nx / Re
97+
omega = 1.0 / (3.0 * visc + 0.5)
98+
print("omega = ", omega)
99+
os.system("rm -rf ./*.vtk && rm -rf ./*.png")
100+
kwargs = {
101+
'lattice': lattice,
102+
'omega': omega,
103+
'nx': nx,
104+
'ny': ny,
105+
'nz': 0,
106+
'precision': precision,
107+
'io_rate': 5000,
108+
'print_info_rate': 1000
109+
}
110+
sim = TaylorGreenVortex(**kwargs)
111+
tc = 2.0/(2. * visc * (kx**2 + ky**2))
112+
endTime = int(0.05*tc)
113+
sim.run(endTime)
114+
result_dict[precision]['vel_error'] = ErrL2ResList
115+
result_dict[precision]['rho_error'] = ErrL2ResListRho
116+
117+
with open('data.json', 'w') as fp:
118+
json.dump(result_dict, fp)
119+
120+
# plt.loglog(resList, ErrL2ResList, '-o')
121+
# plt.loglog(resList, 1e-3*(np.array(resList)/128)**(-2), '--')
122+
# plt.savefig('ErrorVel.png'); plt.savefig('ErrorVel.pdf', format='pdf')
123+
124+
# plt.figure()
125+
# plt.loglog(resList, ErrL2ResListRho, '-o')
126+
# plt.loglog(resList, 1e-3*(np.array(resList)/128)**(-2), '--')
127+
# plt.savefig('ErrorRho.png'); plt.savefig('ErrorRho.pdf', format='pdf')

src/boundary_conditions.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,8 @@ def apply(self, fout, fin, time):
445445
"""
446446
indices, vel = self.update_function(time)
447447
c = jnp.array(self.lattice.c, dtype=self.precisionPolicy.compute_dtype)
448-
cu = 3.0 * jnp.dot(vel, c)
449-
return fout.at[indices].set(fin[indices][..., self.lattice.opp_indices] - 6.0 * self.lattice.w * cu)
448+
cu = 6.0 * self.lattice.w * jnp.dot(vel, c)
449+
return fout.at[indices].set(fin[indices][..., self.lattice.opp_indices] - cu)
450450

451451

452452
class BounceBackHalfway(BoundaryCondition):
@@ -467,13 +467,16 @@ class BounceBackHalfway(BoundaryCondition):
467467
Whether the boundary condition needs extra configuration before it can be applied. For this class, it is True.
468468
isSolid : bool
469469
Whether the boundary condition represents a solid boundary. For this class, it is True.
470+
vel : array-like
471+
The prescribed value of velocity vector for the boundary condition. No-slip BC is assumed if vel=None (default).
470472
"""
471-
def __init__(self, indices, gridInfo, precision_policy):
473+
def __init__(self, indices, gridInfo, precision_policy, vel=None):
472474
super().__init__(indices, gridInfo, precision_policy)
473475
self.name = "BounceBackHalfway"
474476
self.implementationStep = "PostStreaming"
475477
self.needsExtraConfiguration = True
476478
self.isSolid = True
479+
self.vel = vel
477480

478481
def configure(self, boundaryBitmask):
479482
"""
@@ -523,7 +526,12 @@ def apply(self, fout, fin):
523526
nbd = len(self.indices[0])
524527
bindex = np.arange(nbd)[:, None]
525528
fbd = fout[self.indices]
526-
fbd = fbd.at[bindex, self.imissing].set(fin[self.indices][bindex, self.iknown])
529+
if self.vel is not None:
530+
c = jnp.array(self.lattice.c, dtype=self.precisionPolicy.compute_dtype)
531+
cu = 6.0 * self.lattice.w * jnp.dot(self.vel, c)
532+
fbd = fbd.at[bindex, self.imissing].set(fin[self.indices][bindex, self.iknown] - cu[bindex, self.iknown])
533+
else:
534+
fbd = fbd.at[bindex, self.imissing].set(fin[self.indices][bindex, self.iknown])
527535

528536
return fbd
529537

@@ -926,8 +934,8 @@ def configure(self, boundaryBitmask):
926934
927935
Parameters
928936
----------
929-
connectivity_bitmask : np.ndarray
930-
The connectivity bitmask for the lattice.
937+
boundaryBitmask : np.ndarray
938+
The connectivity bitmask for the boundary voxels.
931939
"""
932940
shiftDir = ~boundaryBitmask[:, self.lattice.opp_indices]
933941
idx = np.array(self.indices).T

0 commit comments

Comments
 (0)