def convective_deriv(a, b=None, bnd=True): r"""Compute (a \dot \nabla) b for vector fields a and b""" # [(B \dot \nabla) B]_j = B_i \partial_i B_j # FIXME: this is a lot of temporary arrays if bnd: if b is None: b = viscid.extend_boundaries(a, order=0, crd_order=0) else: b = viscid.extend_boundaries(b, order=0, crd_order=0) else: if b is None: b = a a = a['x=1:-1, y=1:-1, z=1:-1'] if b.nr_comps > 1: diBj = [[None, None, None], [None, None, None], [None, None, None]] for j, jcmp in enumerate('xyz'): g = grad(b[jcmp], bnd=False) for i, icmp in enumerate('xyz'): diBj[i][j] = g[icmp] dest = viscid.zeros(a.crds, nr_comps=3) for i, icmp in enumerate('xyz'): for j, jcmp in enumerate('xyz'): dest[jcmp][...] += a[icmp] * diBj[i][j] else: dest = dot(a, grad(b, bnd=False)) return dest
def grad(fld, bnd=True): """2nd order centeral diff, 1st order @ boundaries if bnd""" # vx, vy, vz = fld.component_views() if bnd: fld = viscid.extend_boundaries(fld, order=0, crd_order=0) if fld.iscentered("Cell"): crdx, crdy, crdz = fld.get_crds_cc(shaped=True) # divcenter = "Cell" # divcrds = coordinate.NonuniformCartesianCrds(fld.crds.get_clist(np.s_[1:-1])) # divcrds = fld.crds.slice_keep(np.s_[1:-1, 1:-1, 1:-1]) elif fld.iscentered("Node"): crdx, crdy, crdz = fld.get_crds_nc(shaped=True) # divcenter = "Node" # divcrds = coordinate.NonuniformCartesianCrds(fld.crds.get_clist(np.s_[1:-1])) # divcrds = fld.crds.slice_keep(np.s_[1:-1, 1:-1, 1:-1]) else: raise NotImplementedError("Can only do cell and node centered gradients") v = fld.data g = viscid.zeros(fld['x=1:-1, y=1:-1, z=1:-1'].crds, nr_comps=3) xp, xm = crdx[2:, :, :], crdx[:-2, : , : ] # pylint: disable=bad-whitespace yp, ym = crdy[ :, 2:, :], crdy[: , :-2, : ] # pylint: disable=bad-whitespace zp, zm = crdz[ :, :, 2:], crdz[: , : , :-2] # pylint: disable=bad-whitespace vxp, vxm = v[2: , 1:-1, 1:-1], v[ :-2, 1:-1, 1:-1] # pylint: disable=bad-whitespace vyp, vym = v[1:-1, 2: , 1:-1], v[1:-1, :-2, 1:-1] # pylint: disable=bad-whitespace vzp, vzm = v[1:-1, 1:-1, 2: ], v[1:-1, 1:-1, :-2] # pylint: disable=bad-whitespace g['x'].data[...] = ne.evaluate("(vxp-vxm)/(xp-xm)") g['y'].data[...] = ne.evaluate("(vyp-vym)/(yp-ym)") g['z'].data[...] = ne.evaluate("(vzp-vzm)/(zp-zm)") return g
def div_fc(fc, force_numpy=False, bnd=True): """Calculate cell centered divergence of face centered field""" fc = fc.atleast_3d() fc = make_ecfc_field_leading(fc) # FIXME: maybe it's possible to do the boundary correctly here without # just faking it with a 0 order hold before returning s0, sm, sp = _prep_slices(fc) s0vec = list(s0) s0vec.insert(fc.nr_comp, slice(0, 1)) div_cc = viscid.zeros_like(fc[s0vec], center="cell") x, y, z = fc.get_crds_nc('xyz', shaped=True) if True: # x, y, z = x[1:, :, :], y[:, 1:, :], z[:, :, 1:] x, y, z = x[:-1, :, :], y[:, :-1, :], z[:, :, :-1] else: raise NotImplementedError() # x, y, z = fc.get_crds_cc('xyz', shaped=True) xm, xp = x[sm[0], :, :], x[sp[0], :, :] ym, yp = y[:, sm[1], :], y[:, sp[1], :] zm, zp = z[:, :, sm[2]], z[:, :, sp[2]] fcx0, fcx1 = (fc['x', sm[0], s0[1], s0[2]].data, fc['x', sp[0], s0[1], s0[2]].data) fcy0, fcy1 = (fc['y', s0[0], sm[1], s0[2]].data, fc['y', s0[0], sp[1], s0[2]].data) fcz0, fcz1 = (fc['z', s0[0], s0[1], sm[2]].data, fc['z', s0[0], s0[1], sp[2]].data) # xp, yp, zp = xm + 1.0, ym + 1.0, zm + 1.0 if _HAS_NUMEXPR and not force_numpy: div_cc[:, :, :] = ne.evaluate("((fcx1 - fcx0) / (xp - xm)) + " "((fcy1 - fcy0) / (yp - ym)) + " "((fcz1 - fcz0) / (zp - zm))") else: div_cc[:, :, :] = (((fcx1 - fcx0) / (xp - xm)) + ((fcy1 - fcy0) / (yp - ym)) + ((fcz1 - fcz0) / (zp - zm))) if bnd: # FIXME: this is really just faking the bnd so there aren't shape # errors when doing math with the result div_cc = viscid.extend_boundaries(div_cc, nl=1, nh=1, order=0, crd_order=1) div_cc.name = "div " + fc.name div_cc.pretty_name = "Div " + fc.pretty_name return div_cc
def ec2cc(ec, force_numpy=False, bnd=True): """Average an edge centered field to cell centers""" ec = ec.atleast_3d() ec = make_ecfc_field_leading(ec) s0, sm, sp = _prep_slices(ec) s0vec = list(s0) s0vec.insert(ec.nr_comp, slice(None)) cc = viscid.zeros_like(ec[s0vec]) cc.center = "Cell" ecx0, ecx1, ecx2, ecx3 = (ec['x', s0[0], sm[1], sm[2]].data, ec['x', s0[0], sm[1], sp[2]].data, ec['x', s0[0], sp[1], sm[2]].data, ec['x', s0[0], sp[1], sp[2]].data) ecy0, ecy1, ecy2, ecy3 = (ec['y', sm[0], s0[1], sm[2]].data, ec['y', sm[0], s0[1], sp[2]].data, ec['y', sp[0], s0[1], sm[2]].data, ec['y', sp[0], s0[1], sp[2]].data) ecz0, ecz1, ecz2, ecz3 = (ec['z', sm[0], sm[1], s0[2]].data, ec['z', sm[0], sp[1], s0[2]].data, ec['z', sp[0], sm[1], s0[2]].data, ec['z', sp[0], sp[1], s0[2]].data) if _HAS_NUMEXPR and not force_numpy: quarter = np.array([0.25], dtype=ec.dtype)[0] # pylint: disable=unused-variable s = "quarter * (a + b + c + d)" a, b, c, d = ecx0, ecx1, ecx2, ecx3 # pylint: disable=unused-variable cc['x'] = ne.evaluate(s) a, b, c, d = ecy0, ecy1, ecy2, ecy3 cc['y'] = ne.evaluate(s) a, b, c, d = ecz0, ecz1, ecz2, ecz3 cc['z'] = ne.evaluate(s) else: cc['x'] = 0.25 * (ecx0 + ecx1 + ecx2 + ecx3) cc['y'] = 0.25 * (ecy0 + ecy1 + ecy2 + ecy3) cc['z'] = 0.25 * (ecz0 + ecz1 + ecz2 + ecz3) if bnd: # FIXME: this is really just faking the bnd so there aren't shape # errors when doing math with the result cc = viscid.extend_boundaries(cc, nl=1, nh=1, order=0, crd_order=1) cc.name = ec.name cc.pretty_name = ec.pretty_name return cc
def _curl_np(fld, bnd=True): """2nd order centeral diff, 1st order @ boundaries if bnd""" if bnd: fld = viscid.extend_boundaries(fld, order=0, crd_order=0) vx, vy, vz = fld.component_views() if fld.iscentered("Cell"): crdx, crdy, crdz = fld.get_crds_cc(shaped=True) curlcenter = "cell" # curlcrds = coordinate.NonuniformCartesianCrds(fld.crds.get_clist(np.s_[1:-1])) curlcrds = fld.crds.slice_keep(np.s_[1:-1, 1:-1, 1:-1]) elif fld.iscentered("Node"): crdx, crdy, crdz = fld.get_crds_nc(shaped=True) curlcenter = "node" # curlcrds = coordinate.NonuniformCartesianCrds(fld.crds.get_clist(np.s_[1:-1])) curlcrds = fld.crds.slice_keep(np.s_[1:-1, 1:-1, 1:-1]) else: raise NotImplementedError("Can only do cell and node centered divs") xp, xm = crdx[2:, :, :], crdx[:-2, :, :] # pylint: disable=bad-whitespace yp, ym = crdy[:, 2:, :], crdy[:, :-2, :] # pylint: disable=bad-whitespace zp, zm = crdz[:, :, 2:], crdz[:, :, :-2] # pylint: disable=bad-whitespace vxpy, vxmy = vx[1:-1, 2:, 1:-1], vx[1:-1, :-2, 1:-1] # pylint: disable=bad-whitespace vxpz, vxmz = vx[1:-1, 1:-1, 2:], vx[1:-1, 1:-1, :-2] # pylint: disable=bad-whitespace vypx, vymx = vy[2:, 1:-1, 1:-1], vy[:-2, 1:-1, 1:-1] # pylint: disable=bad-whitespace vypz, vymz = vy[1:-1, 1:-1, 2:], vy[1:-1, 1:-1, :-2] # pylint: disable=bad-whitespace vzpx, vzmx = vz[2:, 1:-1, 1:-1], vz[:-2, 1:-1, 1:-1] # pylint: disable=bad-whitespace vzpy, vzmy = vz[1:-1, 2:, 1:-1], vz[1:-1, :-2, 1:-1] # pylint: disable=bad-whitespace curl_x = (vzpy - vzmy) / (yp - ym) - (vypz - vymz) / (zp - zm) curl_y = -(vzpx - vzmx) / (xp - xm) + (vxpz - vxmz) / (zp - zm) curl_z = (vypx - vymx) / (xp - xm) - (vxpy - vxmy) / (yp - ym) return field.wrap_field([curl_x, curl_y, curl_z], curlcrds, name="curl " + fld.name, fldtype="Vector", center=curlcenter, time=fld.time, parents=[fld])
def curl(fld, bnd=True): """2nd order centeral diff, 1st order @ boundaries if bnd""" if bnd: fld = viscid.extend_boundaries(fld, order=0, crd_order=0) vx, vy, vz = fld.component_views() if fld.iscentered("Cell"): crdx, crdy, crdz = fld.get_crds_cc(shaped=True) curlcenter = "cell" # curlcrds = coordinate.NonuniformCartesianCrds(fld.crds.get_clist(np.s_[1:-1])) curlcrds = fld.crds.slice_keep(np.s_[1:-1, 1:-1, 1:-1]) elif fld.iscentered("Node"): crdx, crdy, crdz = fld.get_crds_nc(shaped=True) curlcenter = "node" # curlcrds = coordinate.NonuniformCartesianCrds(fld.crds.get_clist(np.s_[1:-1])) curlcrds = fld.crds.slice_keep(np.s_[1:-1, 1:-1, 1:-1]) else: raise NotImplementedError("Can only do cell and node centered divs") xp, xm = crdx[2:, :, :], crdx[:-2, : , : ] # pylint: disable=C0326 yp, ym = crdy[ :, 2:, :], crdy[: , :-2, : ] # pylint: disable=C0326 zp, zm = crdz[ :, :, 2:], crdz[: , : , :-2] # pylint: disable=C0326 vxpy, vxmy = vx[1:-1, 2: , 1:-1], vx[1:-1, :-2, 1:-1] # pylint: disable=C0326 vxpz, vxmz = vx[1:-1, 1:-1, 2: ], vx[1:-1, 1:-1, :-2] # pylint: disable=C0326 vypx, vymx = vy[2: , 1:-1, 1:-1], vy[ :-2, 1:-1, 1:-1] # pylint: disable=C0326 vypz, vymz = vy[1:-1, 1:-1, 2: ], vy[1:-1, 1:-1, :-2] # pylint: disable=C0326 vzpx, vzmx = vz[2: , 1:-1, 1:-1], vz[ :-2, 1:-1, 1:-1] # pylint: disable=C0326 vzpy, vzmy = vz[1:-1, 2: , 1:-1], vz[1:-1, :-2, 1:-1] # pylint: disable=C0326 curl_x = ne.evaluate("(vzpy-vzmy)/(yp-ym) - (vypz-vymz)/(zp-zm)") curl_y = ne.evaluate("-(vzpx-vzmx)/(xp-xm) + (vxpz-vxmz)/(zp-zm)") curl_z = ne.evaluate("(vypx-vymx)/(xp-xm) - (vxpy-vxmy)/(yp-ym)") return field.wrap_field([curl_x, curl_y, curl_z], curlcrds, name="curl " + fld.name, fldtype="Vector", center=curlcenter, time=fld.time, parents=[fld])
def _div_np(fld, bnd=True): """2nd order centeral diff, 1st order @ boundaries if bnd""" if fld.iscentered("Face"): # dispatch fc div immediately since that does its own pre-processing return viscid.div_fc(fld, bnd=bnd) if bnd: fld = viscid.extend_boundaries(fld, order=0, crd_order=0) vx, vy, vz = fld.component_views() if fld.iscentered("Cell"): crdx, crdy, crdz = fld.get_crds_cc(shaped=True) divcenter = "Cell" # divcrds = coordinate.NonuniformCartesianCrds(fld.crds.get_clist(np.s_[1:-1])) divcrds = fld.crds.slice_keep(np.s_[1:-1, 1:-1, 1:-1]) elif fld.iscentered("Node"): crdx, crdy, crdz = fld.get_crds_nc(shaped=True) divcenter = "Node" # divcrds = coordinate.NonuniformCartesianCrds(fld.crds.get_clist(np.s_[1:-1])) divcrds = fld.crds.slice_keep(np.s_[1:-1, 1:-1, 1:-1]) else: raise NotImplementedError("Can only do cell and node centered divs") xp, xm = crdx[2:, :, :], crdx[:-2, :, :] # pylint: disable=bad-whitespace yp, ym = crdy[:, 2:, :], crdy[:, :-2, :] # pylint: disable=bad-whitespace zp, zm = crdz[:, :, 2:], crdz[:, :, :-2] # pylint: disable=bad-whitespace vxp, vxm = vx[2:, 1:-1, 1:-1], vx[:-2, 1:-1, 1:-1] # pylint: disable=bad-whitespace vyp, vym = vy[1:-1, 2:, 1:-1], vy[1:-1, :-2, 1:-1] # pylint: disable=bad-whitespace vzp, vzm = vz[1:-1, 1:-1, 2:], vz[1:-1, 1:-1, :-2] # pylint: disable=bad-whitespace div_arr = ((vxp - vxm) / (xp - xm) + (vyp - vym) / (yp - ym) + (vzp - vzm) / (zp - zm)) return field.wrap_field(div_arr, divcrds, name="div " + fld.name, center=divcenter, time=fld.time, parents=[fld])
def fc2cc(fc, force_numpy=False, bnd=True): """Average a face centered field to cell centers""" fc = fc.atleast_3d() fc = make_ecfc_field_leading(fc) s0, sm, sp = _prep_slices(fc) s0vec = list(s0) s0vec.insert(fc.nr_comp, slice(None)) cc = viscid.zeros_like(fc[s0vec]) cc.center = "Cell" fcx0, fcx1 = (fc['x', sm[0], s0[1], s0[2]].data, fc['x', sp[0], s0[1], s0[2]].data) fcy0, fcy1 = (fc['y', s0[0], sm[1], s0[2]].data, fc['y', s0[0], sp[1], s0[2]].data) fcz0, fcz1 = (fc['z', s0[0], s0[1], sm[2]].data, fc['z', s0[0], s0[1], sp[2]].data) if _HAS_NUMEXPR and not force_numpy: half = np.array([0.5], dtype=fc.dtype)[0] # pylint: disable=unused-variable s = "half * (a + b)" a, b = fcx0, fcx1 # pylint: disable=unused-variable cc['x'] = ne.evaluate(s) a, b = fcy0, fcy1 cc['y'] = ne.evaluate(s) a, b = fcz0, fcz1 cc['z'] = ne.evaluate(s) else: cc['x'] = 0.5 * (fcx0 + fcx1) cc['y'] = 0.5 * (fcy0 + fcy1) cc['z'] = 0.5 * (fcz0 + fcz1) if bnd: # FIXME: this is really just faking the bnd so there aren't shape # errors when doing math with the result cc = viscid.extend_boundaries(cc, nl=1, nh=1, order=0, crd_order=1) cc.name = fc.name cc.pretty_name = fc.pretty_name return cc
def div(fld, bnd=True): """2nd order centeral diff, 1st order @ boundaries if bnd""" if fld.iscentered("Face"): # dispatch fc div immediately since that does its own pre-processing return viscid.div_fc(fld, bnd=bnd) if bnd: fld = viscid.extend_boundaries(fld, order=0, crd_order=0) vx, vy, vz = fld.component_views() if fld.iscentered("Cell"): crdx, crdy, crdz = fld.get_crds_cc(shaped=True) divcenter = "Cell" # divcrds = coordinate.NonuniformCartesianCrds(fld.crds.get_clist(np.s_[1:-1])) divcrds = fld.crds.slice_keep(np.s_[1:-1, 1:-1, 1:-1]) elif fld.iscentered("Node"): crdx, crdy, crdz = fld.get_crds_nc(shaped=True) divcenter = "Node" # divcrds = coordinate.NonuniformCartesianCrds(fld.crds.get_clist(np.s_[1:-1])) divcrds = fld.crds.slice_keep(np.s_[1:-1, 1:-1, 1:-1]) else: raise NotImplementedError("Can only do cell and node centered divs") xp, xm = crdx[2:, :, :], crdx[:-2, : , : ] # pylint: disable=bad-whitespace yp, ym = crdy[ :, 2:, :], crdy[: , :-2, : ] # pylint: disable=bad-whitespace zp, zm = crdz[ :, :, 2:], crdz[: , : , :-2] # pylint: disable=bad-whitespace vxp, vxm = vx[2: , 1:-1, 1:-1], vx[ :-2, 1:-1, 1:-1] # pylint: disable=bad-whitespace vyp, vym = vy[1:-1, 2: , 1:-1], vy[1:-1, :-2, 1:-1] # pylint: disable=bad-whitespace vzp, vzm = vz[1:-1, 1:-1, 2: ], vz[1:-1, 1:-1, :-2] # pylint: disable=bad-whitespace div_arr = ne.evaluate("(vxp-vxm)/(xp-xm) + (vyp-vym)/(yp-ym) + " "(vzp-vzm)/(zp-zm)") return field.wrap_field(div_arr, divcrds, name="div " + fld.name, center=divcenter, time=fld.time, parents=[fld])