Hello all
I’ve added a passive scalar to PyFR and now I am looking to create periodic flow b.c. with inlet-outlet conditions for the passive scalar. Is there a simple way to achieve such a thing?
Any help would be appreciated
Eitan
Hello all
I’ve added a passive scalar to PyFR and now I am looking to create periodic flow b.c. with inlet-outlet conditions for the passive scalar. Is there a simple way to achieve such a thing?
Any help would be appreciated
Eitan
I think this is quite challenging.
I think you would need to make sure that elements got added to both the interaface list and the bc int list and that any MPI communication also happened. You would then need to add some dependencies in the graph so that there isn’t a race condition on setting those interface points.
This will of course be dependent on how you implement the passives, but when I recently did this I added some optional buffers call pasv_upts, pasv_fpts, and pasv_qpts. This methodology would work for that approach.
It can be done with moderate complexity.
First, mark the boundaries as being periodic in your mesh generation software and give them an appropriate name. Next, use the latest development version of PyFR which preserves periodic information in the mesh file and ensures that periodic interfaces always end up on the same MPI rank. Then, in the internal interfaces class split apart the periodic faces into their own list. This is relatively simple to do since PyFR tags which internal interfaces are periodic. Finally, have the common flux for these interfaces computed by a custom kernel which does whatever you need to the passive scalar on the left- and right-hand sides.
Regards, Freddie.
Thank you.
I will give it a try…
I was able to get this working in v2.1, but I’m not sure how to access the periodic boundary information in the solvers/base/system.py file in v3.0.
In v2.1, I mapped the periodic face pairs like so:
key = f'con_p{rallocs.prank}'
lhs, rhs = mesh[key].astype('U4,i4,i1,i2').tolist()
# Strip periodic BC indices
pidxs = list(mesh[key, 'periodic_0'])
new_lhs = [v for i, v in enumerate(lhs) if i in pidxs]
new_rhs = [v for i, v in enumerate(rhs) if i in pidxs]
pint_inters = self.pintinterscls(self.backend, new_lhs, new_rhs, elemap,
self.cfg)
Which I found in @tdzanic ‘s repo Comparing PyFR:develop...tarikdzanic:feature/rot_periodic · PyFR/PyFR · GitHub
However, in v3.0, I only seem to be able to find the periodic BC info in the raw mesh data (mesh.raw), and I haven’t been able to figure out how to create a map from it. I would really appreciate any tips ![]()
Thanks,
Fred
As you noted the only way to access the periodic data is via .raw. This is on account of the fact that there are currently no consumers of this data in PyFR. Nevertheless, we decided to keep the capability when designing the new file format under the hope that it would be useful in the future. To understand the format it is worth reading through:
then, given an interface list you’ll need to go from etype/fidx to a cidx and from a local element number—eidx—to a global element number (or, alternatively, iterate through the periodic data and convert that to etype/fidx/eidx triples).
Also, note that when partitioning PyFR ensures that both sides of a periodic interface will end up on the same rank.
Regards, Freddie.
Thank you very much! I was able to get this working after some familiarizing with the mesh object and mesh file format. Here is my solution for posterity (I hard-coded hexes into it since that’s what I use, but it could be modified for other mesh types):
def _load_int_inters(self, mesh, elemap):
# Generate lhs and rhs lists of periodic face pairs (cidx, off)
pfaces = mesh.raw['periodic']['0']
p_lhs = [tuple(i) for i, k in pfaces]
p_rhs = [tuple(k) for i, k in pfaces]
# Decrement to get fidx and swap indices
p_lhs = [('hex', int(i[1]), int(i[0]-1)) for i in p_lhs]
p_rhs = [('hex', int(i[1]), int(i[0]-1)) for i in p_rhs]
# Strip periodic BC indices
lhs = [i for i in mesh.con[0] if i not in p_lhs + p_rhs]
rhs = [i for i in mesh.con[1] if i not in p_lhs + p_rhs]
int_inters = self.intinterscls(self.backend, lhs, rhs, elemap,
self.cfg)
return [int_inters]
def _load_pint_inters(self, mesh, elemap):
# Generate lhs and rhs lists of periodic face pairs (cidx, off)
pfaces = mesh.raw['periodic']['0']
p_lhs = [tuple(i) for i, k in pfaces]
p_rhs = [tuple(k) for i, k in pfaces]
# Decrement to get fidx and swap indices
p_lhs = [('hex', int(i[1]), int(i[0]-1)) for i in p_lhs]
p_rhs = [('hex', int(i[1]), int(i[0]-1)) for i in p_rhs]
pint_inters = self.pintinterscls(self.backend, p_lhs, p_rhs, elemap,
self.cfg)
return [pint_inters]
The rest of the changes are similar to those Tarik’s repo (keeping in mind some updates from v2 to v3).
Cheers,
Fred