def rostrain(src, dst, key, par, gd, l1, l2, m1, m2, n1, n2, nghost): if key == "fvisc": n1shift,n2shift,m1shift,m2shift,l1shift,l2shift=der_limits( n1,n2,m1,m2,l1,l2,nghost) if par.nu > 0: uu = np.array([ src["data/ux"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift], src["data/uy"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift], src["data/uz"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift] ]) #viscous forces th2 = 2./3 th1 = 1./3 fvisc = np.zeros_like(uu) del2u = np.zeros_like(uu) for j in range(0,3): del2u[j] = del2(uu[j],gd.dx,gd.dy,gd.dz,x=gd.x[l1shift:l2shift],y=gd.y[m1shift:m2shift],coordinate_system=par.coord_system) fvisc += param.nu*del2u del(del2u) divu = div(uu,grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) graddivu = grad(divu,grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) fvisc += th1*par.nu*graddivu del(graddivu) if "rho" in src["data"].keys(): lnrho = np.log(src["data/rho"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift]) lrho = True elif "lnrho" in src["data"].keys(): lnrho = src["data/lnrho"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift] lrho = True else: lrho = False if lrho: tmp0 = grad(uu[0],grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) tmp1 = grad(uu[1],grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) tmp2 = grad(uu[2],grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) gradlnrho = grad(lnrho,grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) Sglnrho = np.zeros_like(uu) Sglnrho[0] = dot(tmp0,gradlnrho) +\ (tmp0[0]+tmp1[0]+tmp2[0]-th2*divu)*gradlnrho[0] Sglnrho[1] = dot(tmp1,gradlnrho) +\ (tmp0[1]+tmp1[1]+tmp2[1]-th2*divu)*gradlnrho[1] Sglnrho[2] = dot(tmp2,gradlnrho) +\ (tmp0[2]+tmp1[2]+tmp2[2]-th2*divu)*gradlnrho[2] fvisc += par.nu*Sglnrho del(gradlnrho,Sglnrho) del(divu) n1r,m1r,l1r = under_limits(n1,m1,l1,n1shift,m1shift,l1shift,nghost) return fvisc[:,n1r:n2-n1+n1r,m1r:m2-m1+m1r,l1r:l2-l1+l1r]
def heatcond(src, dst, key, par, gd, l1, l2, m1, m2, n1, n2, nghost): if key == "hcond": n1shift,n2shift,m1shift,m2shift,l1shift,l2shift=der_limits( n1,n2,m1,m2,l1,l2,nghost) if "tt" in dst["data"].keys(): tt = dst["data/tt"][n1shift,n2shift,m1shift,m2shift,l1shift,l2shift] else: calc_derived_data(src["data"], dst["data"], "tt", par, gd, l1, l2, m1, m2, n1, n2, nghost) tt = dst["data/tt"][n1shift,n2shift,m1shift,m2shift,l1shift,l2shift] lntt = np.log(dst["data/tt"][n1shift,n2shift,m1shift,m2shift,l1shift,l2shift]) gradlnT = grad(lntt,grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) del2T = del2(tt,grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) if "rho" in src["data"].keys(): lnrho = np.log(src["rho"][n1shift,n2shift,m1shift,m2shift,l1shift,l2shift]) gradlnrho = grad(lnrho,grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) lrho = True elif "lnrho" in src["data"].keys(): lnrho = src["lnrho"][n1shift,n2shift,m1shift,m2shift,l1shift,l2shift] gradlnrho = grad(lnrho,grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) lrho = True else: lrho = False var = par.cp*par.chi*del2T/tt if lrho: var += par.cp*par.chi*dot(gradlnrho,gradlnT) n1r,m1r,l1r = under_limits(n1,m1,l1,n1shift,m1shift,l1shift,nghost) return var[n1r:n2-n1+n1r,m1r:m2-m1+m1r,l1r:l2-l1+l1r]
def advec_heat(src, dst, key, par, gd, l1, l2, m1, m2, n1, n2, nghost): if key == "hadvec": n1shift,n2shift,m1shift,m2shift,l1shift,l2shift=der_limits( n1,n2,m1,m2,l1,l2,nghost) uu = np.array([ src["data/ux"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift], src["data/uy"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift], src["data/uz"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift] ]) if "ss" in dst["data"].keys(): ss = src["ss"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift] sgrad = grad(ss,grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) if "tt" in dst["data"].keys(): tt = dst["tt"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift] else: calc_derived_data(src["data"], dst["data"], "tt", par, gd, l1, l2, m1, m2, n1, n2, nghost) tt = dst["data/tt"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift] if "rho" in dst["data"].keys(): rho = src["data/rho"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift] elif "lnrho" in dst["data"].keys(): rho = np.exp(src["data/lnrho"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift]) else: rho=1 advec = -dot(uu,sgrad)/(rho*tt) n1r,m1r,l1r = under_limits(n1,m1,l1,n1shift,m1shift,l1shift,nghost) return advec[n1r:n2-n1+n1r,m1r:m2-m1+m1r,l1r:l2-l1+l1r]
def advec_force(src, dst, key, par, gd, l1, l2, m1, m2, n1, n2, nghost): if key == "uadvec": n1shift,n2shift,m1shift,m2shift,l1shift,l2shift=der_limits( n1,n2,m1,m2,l1,l2,nghost) uu = np.array([ src["data/ux"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift], src["data/uy"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift], src["data/uz"][n1shift:n2shift,m1shift:m2shift,l1shift:l2shift] ]) tmp0 = grad(uu[0],grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) tmp1 = grad(uu[1],grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) tmp2 = grad(uu[2],grid.dx,grid.dy,grid.dz,x=grid.x[l1shift:l2shift],y=grid.y[m1shift:m2shift],coordinate_system=param.coord_system) advec = np.zeros_like(uu) advec[0] = -dot(uu,tmp0) advec[1] = -dot(uu,tmp1) advec[2] = -dot(uu,tmp2) del(tmp0,tmp1,tmp2) n1r,m1r,l1r = under_limits(n1,m1,l1,n1shift,m1shift,l1shift,nghost) return advec[:,n1r:n2-n1+n1r,m1r:m2-m1+m1r,l1r:l2-l1+l1r]
def mag_helicity(src, dst, par, gd, l1, l2, m1, m2, n1, n2, nghost): aa = np.array([ src['ax'][n1:n2, m1:m2, l1:l2], src['ay'][n1:n2, m1:m2, l1:l2], src['az'][n1:n2, m1:m2, l1:l2] ]) if 'bb' in dst.keys(): bb = dst['bb'][:, n1:n2, m1:m2, l1:l2] else: bb = bfield(src, dst, par, gd, l1, l2, m1, m2, n1, n2, nghost) var = dot(aa, bb) return var
def kin_helicity(src, dst, par, gd, l1, l2, m1, m2, n1, n2, nghost): uu = np.array([ src['ux'][n1:n2, m1:m2, l1:l2], src['uy'][n1:n2, m1:m2, l1:l2], src['uz'][n1:n2, m1:m2, l1:l2] ]) if 'vort' in dst.keys(): oo = dst['vort'][:, n1:n2, m1:m2, l1:l2] else: oo = vorticity(src, dst, par, gd, l1, l2, m1, m2, n1, n2, nghost) var = dot(uu, oo) return var
def mag_helicity(src, dst, key, par, gd, l1, l2, m1, m2, n1, n2, nghost): if key == "ab": aa = np.array([ src["ax"][n1:n2, m1:m2, l1:l2], src["ay"][n1:n2, m1:m2, l1:l2], src["az"][n1:n2, m1:m2, l1:l2], ]) if "bb" in dst.keys(): bb = dst["bb"][:, n1:n2, m1:m2, l1:l2] else: bb = bfield(src, dst, "bb", par, gd, l1, l2, m1, m2, n1, n2, nghost) var = dot(aa, bb) return var
def kin_helicity(src, dst, key, par, gd, l1, l2, m1, m2, n1, n2, nghost): if key == "ou": uu = np.array([ src["ux"][n1:n2, m1:m2, l1:l2], src["uy"][n1:n2, m1:m2, l1:l2], src["uz"][n1:n2, m1:m2, l1:l2], ]) if "vort" in dst.keys(): oo = dst["vort"][:, n1:n2, m1:m2, l1:l2] else: oo = vorticity(src, dst, "vort", par, gd, l1, l2, m1, m2, n1, n2, nghost) var = dot(uu, oo) return var
def bcurletadel2a(src, dst, key, par, gd, l1, l2, m1, m2, n1, n2, nghost): if key == "bcurletadel2a": if "curletadel2a" in dst["calc"].keys(): tmp = dst["calc/curletadel2a"][:,n1:n2, m1:m2, l1:l2] else: tmp = curletadel2a(src, dst, "curletadel2a", par, gd, n1, n2, m1, m2, l1, l2, nghost) if "bb" in dst["data"].keys(): bb = dst["data/bb"][:,n1:n2,m1:m2,l1:l2] else: calc_derived_data(src["data"], dst["data"], "bb", par, gd, l1, l2, m1, m2, n1, n2, nghost) bb = dst["data/bb"][:,n1:n2,m1:m2,l1:l2] var = dot(bb,tmp) return var
def mean_mag_helicity(src, dst, key, par, gd, lindx, lindy, lindz, nghost, sigma, typ, mode): if key == "meanab": if 'ab' in dst.keys(): ab = load_dataset(dst, 'ab', lindx, lindy, lindz, nghost) else: ax = load_dataset(src, 'ax', lindx, lindy, lindz, nghost) ay = load_dataset(src, 'ay', lindx, lindy, lindz, nghost) az = load_dataset(src, 'az', lindx, lindy, lindz, nghost) aa = np.array([ax, ay, az]) if "bb" in dst.keys(): bb = load_dataset(dst, 'bb', lindx, lindy, lindz, nghost) else: bb = curl(aa, gd.dx, gd.dy, gd.dz) ab = dot(aa, bb) var = gauss_3Dsmooth(ab, sigma=sigma, typ=typ, mode=mode) return var
def mean_kin_helicity(src, dst, key, par, gd, lindx, lindy, lindz, nghost, sigma, typ, mode): if key == "meanou": if 'ou' in dst.keys(): ou = load_dataset(dst, 'ou', lindx, lindy, lindz, nghost) else: ux = load_dataset(src, 'ux', lindx, lindy, lindz, nghost) uy = load_dataset(src, 'uy', lindx, lindy, lindz, nghost) uz = load_dataset(src, 'uz', lindx, lindy, lindz, nghost) uu = np.array([ux, uy, uz]) if 'vort' in dst.keys(): vort = load_dataset(dst, 'vort', lindx, lindy, lindz, nghost) else: vort = curl(uu, gd.dx, gd.dy, gd.dz) ou = dot(vort, uu) var = gauss_3Dsmooth(ou, sigma=sigma, typ=typ, mode=mode) return var
def mean_cur_helicity(src, dst, key, par, gd, lindx, lindy, lindz, nghost, sigma, typ, mode): if key == "meanjb": if 'jb' in dst.keys(): jb = load_dataset(dst, 'jb', lindx, lindy, lindz, nghost) else: if "bb" in dst.keys(): bb = load_dataset(dst, 'bb', lindx, lindy, lindz, nghost) else: ax = load_dataset(src, 'ax', lindx, lindy, lindz, nghost) ay = load_dataset(src, 'ay', lindx, lindy, lindz, nghost) az = load_dataset(src, 'az', lindx, lindy, lindz, nghost) aa = np.array([ax, ay, az]) bb = curl(aa, gd.dx, gd.dy, gd.dz) if "jj" in dst.keys(): jj = load_dataset(dst, 'jj', lindx, lindy, lindz, nghost) else: jj = curl(bb, gd.dx, gd.dy, gd.dz) jb = dot(jj, bb) var = gauss_3Dsmooth(jb, sigma=sigma, typ=typ, mode=mode) return var
def fluid_reynolds(uu, param, grid, lnrho=list(), shock=list(), nghost=3, lmix=True, quiet=True): """ Computes the fluid Reynolds number from the advective and effective viscous expressions in the momentum equation. call signature: fluid_reynolds(uu, ivisc, grid, rho=None, shock=None, nghost=3) Keyword arguments: *uu*: The velocity field [3,mz,my,mx] from the simulation data *param*: The Param simulation object with viscosity data information *grid*: The Grid simulation object *lnrho*: The log density field if it is non-uniform *shock*: The shock variable if shock viscosity is applied *nghost*: The number of ghost zones appropriate to the order of accuracy *lmix*: Option not to include hyper values when Laplacian values present """ #viscous forces th2 = 2. / 3 th1 = 1. / 3 fvisc = np.zeros_like(uu) #molecular viscosity contribution ldel2, lshock, lhyper3 = False, False, False for ivisc in param.ivisc: if not 'shock' in ivisc and not 'hyper' in ivisc\ and not '\n' in ivisc: ldel2 = True if 'shock' in ivisc: lshock = True if 'hyper3' in ivisc: lhyper3 = True if ldel2: if lhyper3: lhyper3 = lhyper3 == lmix del2u = np.zeros_like(uu) for j in range(0, 3): del2u[j] = del2(uu[j], grid.dx, grid.dy, grid.dz, x=grid.x, y=grid.y, coordinate_system=param.coord_system) del2u[j, :nghost, nghost:-nghost, nghost:-nghost] = del2u[j, -2 * nghost:-nghost, nghost:-nghost, nghost:-nghost] del2u[j, -nghost:, nghost:-nghost, nghost:-nghost] = del2u[j, nghost:2 * nghost, nghost:-nghost, nghost:-nghost] del2u[j, nghost:-nghost, :nghost, nghost:-nghost] = del2u[j, nghost:-nghost, -2 * nghost:-nghost, nghost:-nghost] del2u[j, nghost:-nghost, -nghost:, nghost:-nghost] = del2u[j, nghost:-nghost, nghost:2 * nghost, nghost:-nghost] del2u[j, nghost:-nghost, nghost:-nghost, :nghost] = del2u[j, nghost:-nghost, nghost:-nghost, -2 * nghost:-nghost] del2u[j, nghost:-nghost, nghost:-nghost, -nghost:] = del2u[j, nghost:-nghost, nghost:-nghost, nghost:2 * nghost] for ivisc in param.ivisc: ivisc = str.strip(ivisc, '\n') if 'nu-const' not in ivisc and 'shock' not in ivisc\ and 'hyper' not in ivisc and len(ivisc) > 0: print( 'fluid_reynolds WARNING: ' + ivisc + ' not implemented\n' + 'terms may be missing from the standard rate of strain tensor' ) fvisc = fvisc + param.nu * del2u del (del2u) tmp0 = grad(uu[0], grid.dx, grid.dy, grid.dz, x=grid.x, y=grid.y, coordinate_system=param.coord_system) for j in range(0, 3): tmp0[j, :nghost, nghost:-nghost, nghost:-nghost] = tmp0[j, -2 * nghost:-nghost, nghost:-nghost, nghost:-nghost] tmp0[j, -nghost:, nghost:-nghost, nghost:-nghost] = tmp0[j, nghost:2 * nghost, nghost:-nghost, nghost:-nghost] tmp0[j, nghost:-nghost, :nghost, nghost:-nghost] = tmp0[j, nghost:-nghost, -2 * nghost:-nghost, nghost:-nghost] tmp0[j, nghost:-nghost, -nghost:, nghost:-nghost] = tmp0[j, nghost:-nghost, nghost:2 * nghost, nghost:-nghost] tmp0[j, nghost:-nghost, nghost:-nghost, :nghost] = tmp0[j, nghost:-nghost, nghost:-nghost, -2 * nghost:-nghost] tmp0[j, nghost:-nghost, nghost:-nghost, -nghost:] = tmp0[j, nghost:-nghost, nghost:-nghost, nghost:2 * nghost] tmp1 = grad(uu[1], grid.dx, grid.dy, grid.dz, x=grid.x, y=grid.y, coordinate_system=param.coord_system) for j in range(0, 3): tmp1[j, :nghost, nghost:-nghost, nghost:-nghost] = tmp1[j, -2 * nghost:-nghost, nghost:-nghost, nghost:-nghost] tmp1[j, -nghost:, nghost:-nghost, nghost:-nghost] = tmp1[j, nghost:2 * nghost, nghost:-nghost, nghost:-nghost] tmp1[j, nghost:-nghost, :nghost, nghost:-nghost] = tmp1[j, nghost:-nghost, -2 * nghost:-nghost, nghost:-nghost] tmp1[j, nghost:-nghost, -nghost:, nghost:-nghost] = tmp1[j, nghost:-nghost, nghost:2 * nghost, nghost:-nghost] tmp1[j, nghost:-nghost, nghost:-nghost, :nghost] = tmp1[j, nghost:-nghost, nghost:-nghost, -2 * nghost:-nghost] tmp1[j, nghost:-nghost, nghost:-nghost, -nghost:] = tmp1[j, nghost:-nghost, nghost:-nghost, nghost:2 * nghost] tmp2 = grad(uu[2], grid.dx, grid.dy, grid.dz, x=grid.x, y=grid.y, coordinate_system=param.coord_system) for j in range(0, 3): tmp2[j, :nghost, nghost:-nghost, nghost:-nghost] = tmp2[j, -2 * nghost:-nghost, nghost:-nghost, nghost:-nghost] tmp2[j, -nghost:, nghost:-nghost, nghost:-nghost] = tmp2[j, nghost:2 * nghost, nghost:-nghost, nghost:-nghost] tmp2[j, nghost:-nghost, :nghost, nghost:-nghost] = tmp2[j, nghost:-nghost, -2 * nghost:-nghost, nghost:-nghost] tmp2[j, nghost:-nghost, -nghost:, nghost:-nghost] = tmp2[j, nghost:-nghost, nghost:2 * nghost, nghost:-nghost] tmp2[j, nghost:-nghost, nghost:-nghost, :nghost] = tmp2[j, nghost:-nghost, nghost:-nghost, -2 * nghost:-nghost] tmp2[j, nghost:-nghost, nghost:-nghost, -nghost:] = tmp2[j, nghost:-nghost, nghost:-nghost, nghost:2 * nghost] #effect of compressibility if len(lnrho) > 0: divu = div(uu, grid.dx, grid.dy, grid.dz, x=grid.x, y=grid.y, coordinate_system=param.coord_system) divu[:nghost, nghost:-nghost, nghost:-nghost] = divu[-2 * nghost:-nghost, nghost:-nghost, nghost:-nghost] divu[-nghost:, nghost:-nghost, nghost:-nghost] = divu[nghost:2 * nghost, nghost:-nghost, nghost:-nghost] divu[nghost:-nghost, :nghost, nghost:-nghost] = divu[nghost:-nghost, -2 * nghost:-nghost, nghost:-nghost] divu[nghost:-nghost, -nghost:, nghost:-nghost] = divu[nghost:-nghost, nghost:2 * nghost, nghost:-nghost] divu[nghost:-nghost, nghost:-nghost, :nghost] = divu[nghost:-nghost, nghost:-nghost, -2 * nghost:-nghost] divu[nghost:-nghost, nghost:-nghost, -nghost:] = divu[nghost:-nghost, nghost:-nghost, nghost:2 * nghost] gradlnrho = grad(lnrho, grid.dx, grid.dy, grid.dz, x=grid.x, y=grid.y, coordinate_system=param.coord_system) for j in range(0, 3): gradlnrho[j, :nghost, nghost:-nghost, nghost:-nghost] = gradlnrho[j, -2 * nghost:-nghost, nghost:-nghost, nghost:-nghost] gradlnrho[j, -nghost:, nghost:-nghost, nghost:-nghost] = gradlnrho[j, nghost:2 * nghost, nghost:-nghost, nghost:-nghost] gradlnrho[j, nghost:-nghost, :nghost, nghost:-nghost] = gradlnrho[j, nghost:-nghost, -2 * nghost:-nghost, nghost:-nghost] gradlnrho[j, nghost:-nghost, -nghost:, nghost:-nghost] = gradlnrho[j, nghost:-nghost, nghost:2 * nghost, nghost:-nghost] gradlnrho[j, nghost:-nghost, nghost:-nghost, :nghost] = gradlnrho[j, nghost:-nghost, nghost:-nghost, -2 * nghost:-nghost] gradlnrho[j, nghost:-nghost, nghost:-nghost, -nghost:] = gradlnrho[j, nghost:-nghost, nghost:-nghost, nghost:2 * nghost] Sglnrho = np.zeros_like(uu) Sglnrho[0] = dot(tmp0,gradlnrho) +\ (tmp0[0]+tmp1[0]+tmp2[0]-th2*divu)*gradlnrho[0] Sglnrho[1] = dot(tmp1,gradlnrho) +\ (tmp0[1]+tmp1[1]+tmp2[1]-th2*divu)*gradlnrho[1] Sglnrho[2] = dot(tmp2,gradlnrho) +\ (tmp0[2]+tmp1[2]+tmp2[2]-th2*divu)*gradlnrho[2] graddivu = grad(divu, grid.dx, grid.dy, grid.dz, x=grid.x, y=grid.y, coordinate_system=param.coord_system) for j in range(0, 3): graddivu[j, :nghost, nghost:-nghost, nghost:-nghost] = graddivu[j, -2 * nghost:-nghost, nghost:-nghost, nghost:-nghost] graddivu[j, -nghost:, nghost:-nghost, nghost:-nghost] = graddivu[j, nghost:2 * nghost, nghost:-nghost, nghost:-nghost] graddivu[j, nghost:-nghost, :nghost, nghost:-nghost] = graddivu[j, nghost:-nghost, -2 * nghost:-nghost, nghost:-nghost] graddivu[j, nghost:-nghost, -nghost:, nghost:-nghost] = graddivu[j, nghost:-nghost, nghost:2 * nghost, nghost:-nghost] graddivu[j, nghost:-nghost, nghost:-nghost, :nghost] = graddivu[j, nghost:-nghost, nghost:-nghost, -2 * nghost:-nghost] graddivu[j, nghost:-nghost, nghost:-nghost, -nghost:] = graddivu[j, nghost:-nghost, nghost:-nghost, nghost:2 * nghost] fvisc = fvisc + param.nu * (th1 * graddivu + Sglnrho) del (Sglnrho) elif param.ldensity: print('fluid_reynolds WARNING: no lnrho provided\n' + 'rate of strain tensor likely incomplete') #shock contribution if lshock: if len(shock) == 0: print('fluid_reynolds WARNING: no shock provided\n' + 'rate of strain tensor likely incomplete') else: shock[:nghost, nghost:-nghost, nghost:-nghost] = shock[-2 * nghost:-nghost, nghost:-nghost, nghost:-nghost] shock[-nghost:, nghost:-nghost, nghost:-nghost] = shock[nghost:2 * nghost, nghost:-nghost, nghost:-nghost] shock[nghost:-nghost, :nghost, nghost:-nghost] = shock[nghost:-nghost, -2 * nghost:-nghost, nghost:-nghost] shock[nghost:-nghost, -nghost:, nghost:-nghost] = shock[nghost:-nghost, nghost:2 * nghost, nghost:-nghost] shock[nghost:-nghost, nghost:-nghost, :nghost] = shock[nghost:-nghost, nghost:-nghost, -2 * nghost:-nghost] shock[nghost:-nghost, nghost:-nghost, -nghost:] = shock[nghost:-nghost, nghost:-nghost, nghost:2 * nghost] divugradlnrho = np.zeros_like(uu) gradshock = grad(shock, grid.dx, grid.dy, grid.dz, x=grid.x, y=grid.y, coordinate_system=param.coord_system) for j in range(0, 3): gradshock[j, :nghost, nghost:-nghost, nghost:-nghost] = gradshock[j, -2 * nghost:-nghost, nghost:-nghost, nghost:-nghost] gradshock[j, -nghost:, nghost:-nghost, nghost:-nghost] = gradshock[j, nghost:2 * nghost, nghost:-nghost, nghost:-nghost] gradshock[j, nghost:-nghost, :nghost, nghost:-nghost] = gradshock[j, nghost:-nghost, -2 * nghost:-nghost, nghost:-nghost] gradshock[j, nghost:-nghost, -nghost:, nghost:-nghost] = gradshock[j, nghost:-nghost, nghost:2 * nghost, nghost:-nghost] gradshock[j, nghost:-nghost, nghost:-nghost, :nghost] = gradshock[j, nghost:-nghost, nghost:-nghost, -2 * nghost:-nghost] gradshock[j, nghost:-nghost, nghost:-nghost, -nghost:] = gradshock[j, nghost:-nghost, nghost:-nghost, nghost:2 * nghost] for j in range(0, 3): divugradlnrho[j] = param.nu_shock*divu*gradshock[j] +\ param.nu_shock*shock*(divu*gradlnrho[j] + graddivu[j]) del (divu, gradshock, gradlnrho, graddivu) fvisc = fvisc + divugradlnrho del (divugradlnrho) if lhyper3: #deluij5 = np.zeros_like([uu,uu,uu]) #uij5glnrho to be included del6u = np.zeros_like(uu) for j in range(0, 3): del6u[j] = del6(uu[j], grid.dx, grid.dy, grid.dz) del6u[j, :nghost, nghost:-nghost, nghost:-nghost] = del6u[j, -2 * nghost:-nghost, nghost:-nghost, nghost:-nghost] del6u[j, -nghost:, nghost:-nghost, nghost:-nghost] = del6u[j, nghost:2 * nghost, nghost:-nghost, nghost:-nghost] del6u[j, nghost:-nghost, :nghost, nghost:-nghost] = del6u[j, nghost:-nghost, -2 * nghost:-nghost, nghost:-nghost] del6u[j, nghost:-nghost, -nghost:, nghost:-nghost] = del6u[j, nghost:-nghost, nghost:2 * nghost, nghost:-nghost] del6u[j, nghost:-nghost, nghost:-nghost, :nghost] = del6u[j, nghost:-nghost, nghost:-nghost, -2 * nghost:-nghost] del6u[j, nghost:-nghost, nghost:-nghost, -nghost:] = del6u[j, nghost:-nghost, nghost:-nghost, nghost:2 * nghost] #del6 for non-cartesian tba #del6u[j] = del6(uu[j],grid.dx,grid.dy,grid.dz,x=grid.x,y=grid.y, # coordinate_system=param.coord_system) fvisc = fvisc + param.nu_hyper3 * del6u del (del6u) fvisc2 = np.sqrt(dot2(fvisc)) #advective forces advec = np.zeros_like(uu) advec[0] = dot(uu, tmp0) advec[1] = dot(uu, tmp1) advec[0] = dot(uu, tmp2) del (tmp0, tmp1, tmp2) advec2 = np.sqrt(dot2(advec)) del (advec) #avoid division by zero if fvisc2.max() > 0: fvisc2[np.where(fvisc2 == 0)] = fvisc2[np.where(fvisc2 > 0)].min() Re = advec2 / fvisc2 #set minimum floor to exclude zero-valued Re Re[np.where(Re == 0)] = Re[np.where(Re > 0)].min() else: Re = advec2 print('Re undefined') return Re
def helmholtz_fft( tot_field, grid, params, nghost=3, pot=True, rot=True, lno_mean=False, nonperi_bc=None, field_scalar=[], s=None, quiet=True, ): """ helmholz_fft(field, grid, params) Creates the decomposition vector pair for the supplied vector field. Parameters ---------- tot_field : ndarray Vector field of dimension [3, mz, my, mx], which is decomposed. grid: obj Grid object with grid spacing dx, dy, dz. params : obj Simulation Params object with domain dimensions Lx, Ly and Lz. nghost : int Number of ghost zones to exclude from the fft. lno_mean : float Exclude any mean flow from the decomposition - should drop anyway. nonperi_bc : string String if not None with boundary condition label. How to apply the bc needs to be implemented as required. field_scalar : ndarray Scalar field (density) as debug tool for energy comparison. s : list of int List of three integers if not None for fft dimension. If none the dimension of the field [nz,ny,nx] is used. Returns ------- ndarray with decomposed field. """ if lno_mean: # Exclude volume mean flows. field = np.zeros_like(tot_field) for j in range(0, 3): field[j] = tot_field[j] - tot_field[j].mean() else: field = tot_field # Use mean speed and grid spacing in normalization of div/curl check. amp_field_1 = 1.0 / np.sqrt(dot2(field)).mean() nz, ny, nx = ( field[:, nghost:-nghost, nghost:-nghost, nghost:-nghost].shape[-3], field[:, nghost:-nghost, nghost:-nghost, nghost:-nghost].shape[-2], field[:, nghost:-nghost, nghost:-nghost, nghost:-nghost].shape[-1], ) invs = [nz, ny, nx] if not s: s = [nz, ny, nx] knz, kny, knx = s[0], s[1], s[2] nz2, ny2, nx2 = int(knz / 2), int(kny / 2), int(knx / 2) # Derive wavenumbers k scaled to dimension of simulation domain. kk = np.empty(shape=[3, s[0], s[1], s[2]]) k0 = np.arange(knx) k0[nx2:] = -k0[nx2 - 1::-1] - 1 k1 = np.arange(kny) k1[ny2:] = -k1[ny2 - 1::-1] - 1 k2 = np.arange(knz) k2[nz2:] = -k2[nz2 - 1::-1] - 1 for j in range(0, k0.size): kk[0, :, :, j] = k0[j] * 2 * np.pi / params.lxyz[0] for j in range(0, k1.size): kk[1, :, j, :] = k1[j] * 2 * np.pi / params.lxyz[1] for j in range(0, k2.size): kk[2, j, :, :] = k2[j] * 2 * np.pi / params.lxyz[2] knorm = dot2(kk) # Apply fast Fourier transform to the vector field. kfield = np.empty(shape=[3, s[0], s[1], s[2]], dtype=complex) for j in range(0, 3): kfield[j] = np.fft.fftn(field[j, nghost:-nghost, nghost:-nghost, nghost:-nghost], s=s) if pot: # Reverse fft to obtain the scalar potential. pfield = -1j * dot(kk, kfield) pfield[np.where(knorm == 0)] = 0.0 if rot: # Reverse fft to obtain the vector potential. rfield = 1j * cross(kk, kfield) for j in range(3): rfield[j][np.where(knorm == 0)] = 0.0 # Avoid division by zero. knorm[np.where(knorm == 0)] = 1.0 if pot: pfield /= knorm pot_field = np.zeros_like(field) if rot: for j in range(3): rfield[j] /= knorm rot_field = np.zeros_like(field) if nonperi_bc: print( "Please implement new nonperi_bc not yet implemented.\n", "Applying periodic boundary conditions for now.", ) for j in range(0, 3): if pot: pot_field[j, nghost:-nghost, nghost:-nghost, nghost:-nghost] = np.fft.ifftn(1j * pfield * kk[j], s=invs).real if rot: rot_field[j, nghost:-nghost, nghost:-nghost, nghost:-nghost] = np.fft.ifftn(cross(1j * kk, rfield)[j], s=invs).real # Apply the periodic boundary conditions for the ghost zones. for j in range(0, 3): if pot: pot_field[j, :nghost, :, :] = pot_field[j, -2 * nghost:-nghost, :, :] pot_field[j, -nghost:, :, :] = pot_field[j, nghost:2 * nghost, :, :] pot_field[j, :, :nghost, :] = pot_field[j, :, -2 * nghost:-nghost, :] pot_field[j, :, -nghost:, :] = pot_field[j, :, nghost:2 * nghost, :] pot_field[j, :, :, :nghost] = pot_field[j, :, :, -2 * nghost:-nghost] pot_field[j, :, :, -nghost:] = pot_field[j, :, :, nghost:2 * nghost] if rot: rot_field[j, :nghost, :, :] = rot_field[j, -2 * nghost:-nghost, :, :] rot_field[j, -nghost:, :, :] = rot_field[j, nghost:2 * nghost, :, :] rot_field[j, :, :nghost, :] = rot_field[j, :, -2 * nghost:-nghost, :] rot_field[j, :, -nghost:, :] = rot_field[j, :, nghost:2 * nghost, :] rot_field[j, :, :, :nghost] = rot_field[j, :, :, -2 * nghost:-nghost] rot_field[j, :, :, -nghost:] = rot_field[j, :, :, nghost:2 * nghost] # Compare internal energy of original and sum of decomposed vectors. if pot: pot2 = dot2(pot_field)[nghost:-nghost, nghost:-nghost, nghost:-nghost] if rot: rot2 = dot2(rot_field)[nghost:-nghost, nghost:-nghost, nghost:-nghost] field2 = dot2(field)[nghost:-nghost, nghost:-nghost, nghost:-nghost] if len(field_scalar) > 0: # Compare kinetic energy of original and sum of decomposed vectors. field2 *= field_scalar[nghost:-nghost, nghost:-nghost, nghost:-nghost] if pot: pot2 *= field_scalar[nghost:-nghost, nghost:-nghost, nghost:-nghost] if rot: rot2 *= field_scalar[nghost:-nghost, nghost:-nghost, nghost:-nghost] if rot and not pot: if not quiet: print( "mean total field energy {} mean rotational energy {}".format( np.mean(field2), np.mean(rot2))) elif pot and not rot: if not quiet: print("mean total field energy {} mean irrotational energy {}". format(np.mean(field2), np.mean(pot2))) elif rot and pot: if not quiet: print("mean total field energy {} mean summed component energy {}". format(np.mean(field2), np.mean(rot2 + pot2))) # Check div and curl approximate/equal zero. if pot: if not quiet: print("Max {} and mean {} of abs(curl(pot field))".format( max(grid.dx, grid.dy, grid.dz) * amp_field_1 * np.sqrt(dot2(curl(pot_field, grid.dx, grid.dy, grid.dz)))[nghost:-nghost, nghost:-nghost, nghost:-nghost].max(), max(grid.dx, grid.dy, grid.dz) * amp_field_1 * np.sqrt(dot2(curl(pot_field, grid.dx, grid.dy, grid.dz)))[nghost:-nghost, nghost:-nghost, nghost:-nghost].mean(), )) if rot: if not quiet: print("Max {} and mean {} of abs(div(rot field))".format( max(grid.dx, grid.dy, grid.dz) * amp_field_1 * np.abs(div(rot_field, grid.dx, grid.dy, grid.dz))[nghost:-nghost, nghost:-nghost, nghost:-nghost].max(), max(grid.dx, grid.dy, grid.dz) * amp_field_1 * np.abs(div(rot_field, grid.dx, grid.dy, grid.dz))[nghost:-nghost, nghost:-nghost, nghost:-nghost].mean(), )) if rot and not pot: ret_opt = rot_field elif pot and not rot: ret_opt = pot_field elif rot and pot: ret_opt = [rot_field, pot_field] else: print("pot and/or rot must be True, returning ones") ret_opt = np.ones_like(tot_field) return ret_opt
def var2vtk(var_file='var.dat', datadir='data', proc=-1, variables=None, b_ext=False, magic=[], destination='work', quiet=True, trimall=True, ti=-1, tf=-1): """ Convert data from PencilCode format to vtk. call signature:: var2vtk(var_file='', datadir='data', proc=-1, variables='', b_ext=False, destination='work', quiet=True, trimall=True, ti=-1, tf=-1) Read *var_file* and convert its content into vtk format. Write the result in *destination*. Keyword arguments: *var_file*: The original var_file. *datadir*: Directory where the data is stored. *proc*: Processor which should be read. Set to -1 for all processors. *variables*: List of variables which should be written. If None all. *b_ext*: Add the external magnetic field. *destination*: Destination file. *quiet*: Keep quiet when reading the var files. *trimall*: Trim the data cube to exclude ghost zones. *ti, tf*: Start and end index for animation. Leave negative for no animation. Overwrites variable var_file. """ import numpy as np import sys from pencil import read from pencil import math # Determine of we want an animation. if ti < 0 or tf < 0: animation = False else: animation = True # If no variables specified collect all by default if not variables: variables = [] indx = read.index() for key in indx.__dict__.keys(): if 'keys' not in key: variables.append(key) if 'uu' in variables: magic.append('vort') variables.append('vort') if 'rho' in variables or 'lnrho' in variables: if 'ss' in variables: magic.append('tt') variables.append('tt') magic.append('pp') variables.append('pp') if 'aa' in variables: magic.append('bb') variables.append('bb') magic.append('jj') variables.append('jj') variables.append('ab') variables.append('b_mag') variables.append('j_mag') else: # Convert single variable string into length 1 list of arrays. if (len(variables) > 0): if (len(variables[0]) == 1): variables = [variables] if 'tt' in variables: magic.append('tt') if 'pp' in variables: magic.append('pp') if 'bb' in variables: magic.append('bb') if 'jj' in variables: magic.append('jj') if 'vort' in variables: magic.append('vort') if 'b_mag' in variables and not 'bb' in magic: magic.append('bb') if 'j_mag' in variables and not 'jj' in magic: magic.append('jj') if 'ab' in variables and not 'bb' in magic: magic.append('bb') for t_idx in range(ti, tf + 1): if animation: var_file = 'VAR' + str(t_idx) # Read the PencilCode variables and set the dimensions. var = read.var(var_file=var_file, datadir=datadir, proc=proc, magic=magic, trimall=True, quiet=quiet) grid = read.grid(datadir=datadir, proc=proc, trim=trimall, quiet=True) params = read.param(quiet=True) # Add external magnetic field. if (b_ext == True): B_ext = np.array(params.b_ext) var.bb[0, ...] += B_ext[0] var.bb[1, ...] += B_ext[1] var.bb[2, ...] += B_ext[2] dimx = len(grid.x) dimy = len(grid.y) dimz = len(grid.z) dim = dimx * dimy * dimz dx = (np.max(grid.x) - np.min(grid.x)) / (dimx - 1) dy = (np.max(grid.y) - np.min(grid.y)) / (dimy - 1) dz = (np.max(grid.z) - np.min(grid.z)) / (dimz - 1) # Write the vtk header. if animation: fd = open(destination + str(t_idx) + '.vtk', 'wb') else: fd = open(destination + '.vtk', 'wb') fd.write('# vtk DataFile Version 2.0\n'.encode('utf-8')) fd.write('VAR files\n'.encode('utf-8')) fd.write('BINARY\n'.encode('utf-8')) fd.write('DATASET STRUCTURED_POINTS\n'.encode('utf-8')) fd.write('DIMENSIONS {0:9} {1:9} {2:9}\n'.format(dimx, dimy, dimz).encode('utf-8')) fd.write('ORIGIN {0:8.12} {1:8.12} {2:8.12}\n'.format( grid.x[0], grid.y[0], grid.z[0]).encode('utf-8')) fd.write('SPACING {0:8.12} {1:8.12} {2:8.12}\n'.format( dx, dy, dz).encode('utf-8')) fd.write('POINT_DATA {0:9}\n'.format(dim).encode('utf-8')) # Write the data. for v in variables: print('Writing {0}.'.format(v)) # Prepare the data to the correct format. if v == 'ab': data = math.dot(var.aa, var.bb) elif v == 'b_mag': data = np.sqrt(math.dot2(var.bb)) elif v == 'j_mag': data = np.sqrt(math.dot2(var.jj)) else: data = getattr(var, v) if sys.byteorder == 'little': data = data.astype(np.float32).byteswap() else: data = data.astype(np.float32) # Check if we have vectors or scalars. if data.ndim == 4: data = np.moveaxis(data, 0, 3) fd.write('VECTORS {0} float\n'.format(v).encode('utf-8')) else: fd.write('SCALARS {0} float\n'.format(v).encode('utf-8')) fd.write('LOOKUP_TABLE default\n'.encode('utf-8')) fd.write(data.tobytes()) del (var) fd.close()