Nonuniform rectilinear grids - vonkarmaninstitute/pantera-pic-dsmc GitHub Wiki

It is possible to use nonuniform rectilinear grids in Pantera. These are structured Cartesian grids where the spacing between nodes is allowed to change.

Format of the grid file

The grid file should be formatted as follows:

[number of cells in X]
[array of X coordinates of nodes]
[number of cells in Y]
[array of Y coordinates of nodes]
[number of cells in Z (= 1)]
[array of Z coordinates of nodes]

Note that the node coordinates should be listed in increasing value and not repeated.

For example:

4
0.0 0.1 0.15 0.18 0.2
2
-1.0 0.0 1.0
1
-0.5 0.5

Grid generation

It is up to the user to generate a grid file. The following Python script can be used as a guide. It will generate a file called chamber.grid, which should be used with the Grid_file: command in the input script.

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import least_squares

def prog_inc(inf, includeinf, sup, includesup, divisions, increment):
    coords = [0, 1]
    for i in range(divisions-1):
        coords.append( coords[-1] + (coords[-1]-coords[-2])*increment )

    coords = np.array(coords)/coords[-1]
    coords = inf + np.array(coords)*(sup-inf)
    if (not includeinf):
        coords = coords[1:]
    if (not includesup):
        coords = coords[:-1]
    return coords

def prog_dec(inf, includeinf, sup, includesup, divisions, increment):
    coords = [0, 1]
    for i in range(divisions-1):
        coords.append( coords[-1] + (coords[-1]-coords[-2])*increment )

    coords = 1-np.flip(coords)/coords[-1]
    coords = inf + np.array(coords)*(sup-inf)
    if (not includeinf):
        coords = coords[1:]
    if (not includesup):
        coords = coords[:-1]
    return coords

def comp_increment_old(mindim, maxdim, divisions):
    return np.exp(np.log(maxdim/mindim)/(divisions-1))

def fun_opt(r, length, mindim, N):
    return length-mindim*(r**N-1.)/(r-1.)

def comp_increment(mindim, length, divisions):
    r = 1.1
    res = least_squares(fun_opt, r, args = (length, mindim, divisions))
    return float(res.x)
    

def mirror(side):
    return np.concatenate((np.flip(-side)[:-1], side))

# Build z
z = [-np.pi, np.pi]

# Build x
x1 = np.linspace(0, 0.1, 11)
x2 = prog_dec(0.1, False, 0.2, True, 20, comp_increment(1e-3, 0.1, 20))
x3 = prog_inc(0.2, False, 0.9, True, 270, comp_increment(1e-3, 0.7, 270))
x = np.concatenate((x1, x2, x3))




# Build y
y1 = np.linspace(0, 0.015, 51)
y2 = prog_inc(0.015, False, 0.05, True, 50, comp_increment((y1[-1]-y1[-2]), 0.035, 50))
y3 = prog_inc(0.05, False, 0.3, True, 50, comp_increment((y2[-1]-y2[-2]), 0.25, 50))
y = np.concatenate((y1, y2, y3))

#y = mirror(y3)

# Plot
for xcoord in x:
    plt.plot([xcoord, xcoord], [y[0], y[-1]], color = 'k', lw = 0.5)

for ycoord in y:
    plt.plot([x[0], x[-1]], [ycoord, ycoord], color = 'k', lw = 0.5)

left = 10
right = 30
down = 0
up = 100

for i, xcoord in enumerate(x):
    for j, ycoord in enumerate(y):
        if ( ((i==left or i == right) and j>=down and j <=up) or  ((j==down or j==up) and i>=left and i<=right) ):
            color = 'r'
            if (i==right and j<=50): color = 'b'
            plt.plot(xcoord, ycoord, marker = 'x', color = color)
plt.axis('equal')
plt.show(block=False)


print('Total number of cells: {}'.format((len(x)-1)*(len(y)-1)))
print('x-cells: {}'.format(len(x)) )
print('y-cells: {}'.format(len(y)) )

# Save to file
f = open('chamber.grid', 'w')
f.write(str(len(x)-1) + '\n')
for xcoord in x:
    f.write(str(xcoord) + ' ')

f.write('\n')
f.write(str(len(y)-1) + '\n')
for ycoord in y:
    f.write(str(ycoord) + ' ')

f.write('\n')
f.write('1\n' + str(z[0]) + ' ' + str(z[1]))
f.close()