fd.SetNumberOfTuples(11) fd.FillComponent(0, 5) fd.SetName("field array") output.GetFieldData().AddArray(fd) g2 = vtk.vtkMultiBlockDataGroupFilter() g2.AddInputData(output) g2.AddInputData(output) g2.Update() sphere = dsa.CompositeDataSet(g2.GetOutput()) vn = algs.vertex_normal(sphere) assert algs.all(algs.mag(vn) - 1 < 1E-6) sn = algs.surface_normal(sphere) assert algs.all(algs.mag(sn) - 1 < 1E-6) dot = algs.dot(vn, vn) assert dot.DataSet is sphere assert algs.all(dot == 1) assert algs.all(algs.cross(vn, vn) == [0, 0, 0]) fd = sphere.FieldData['field array'] assert algs.all(fd == 5) assert algs.shape(fd) == (22, ) assert vn.DataSet is sphere
fd.SetNumberOfTuples(11) fd.FillComponent(0, 5) fd.SetName("field array") output.GetFieldData().AddArray(fd) g2 = vtk.vtkMultiBlockDataGroupFilter() g2.AddInputData(output) g2.AddInputData(output) g2.Update() sphere = dsa.CompositeDataSet(g2.GetOutput()) vn = algs.vertex_normal(sphere) compare(algs.mag(vn) - 1, 1E-6) sn = algs.surface_normal(sphere) compare(algs.mag(sn) - 1, 1E-6) dot = algs.dot(vn, vn) assert dot.DataSet is sphere compare(dot - 1, 1E-6) assert algs.all(algs.cross(vn, vn) == [0, 0, 0]) fd = sphere.FieldData['field array'] assert algs.all(fd == 5) assert algs.shape(fd) == (22,) assert vn.DataSet is sphere
"VelCylMean": VelMeanVec, "VelCylRMSE": VelRMSEVec } VectorCylDict = {} for key in VectorDict.keys(): VectorCylDict[key] = algs.make_vector( algs.dot(VectorDict[key], radVec), algs.dot(VectorDict[key], thetaVec), algs.dot(VectorDict[key], zVec)) ########################################### # SPECIALIZED DATA OUTPUT ########################################### # Dynamic Pressure DynPres = algs.mag(VelocityVec)**2 * 0.5 * input0.PointData['Density'].Arrays[0] ########################################### # OUTPUTING DATA ########################################### # Cylindrical Coordinate Points output.PointData.append(radius, "r") output.PointData.append(theta, "theta") output.PointData.append(z, 'z') # Cylindrical Direction Vectors output.PointData.append(radVec, 'rVec') output.PointData.append(zVec, 'zVec') output.PointData.append(thetaVec, 'thetaVec')
fd.SetNumberOfTuples(11) fd.FillComponent(0, 5) fd.SetName("field array") output.GetFieldData().AddArray(fd) g2 = vtk.vtkMultiBlockDataGroupFilter() g2.AddInputData(output) g2.AddInputData(output) g2.Update() sphere = dsa.CompositeDataSet(g2.GetOutput()) vn = algs.vertex_normal(sphere) assert algs.all(algs.mag(vn) - 1 < 1E-6) sn = algs.surface_normal(sphere) assert algs.all(algs.mag(sn) - 1 < 1E-6) dot = algs.dot(vn, vn) assert dot.DataSet is sphere assert algs.all(dot == 1) assert algs.all(algs.cross(vn, vn) == [0, 0, 0]) fd = sphere.FieldData['field array'] assert algs.all(fd == 5) assert algs.shape(fd) == (22,) assert vn.DataSet is sphere
def make_features_inv(rans_vtk, Ls=1, Us=1, ros=1, nondim='local'): from cfd2ml.utilities import eijk small = np.finfo(float).tiny rans_nnode = rans_vtk.number_of_points # Wrap vista object in dsa wrapper rans_dsa = dsa.WrapDataObject(rans_vtk) print('Feature:') # nfeat = 21 nfeat = 50 q = np.empty([rans_nnode, nfeat]) feature_labels = np.empty(nfeat, dtype='object') # strain and vorticity ############################## print('Constructing strain and vorticity tensor') # Velocity vector U = rans_dsa.PointData[ 'U'] # NOTE - Getting variables from dsa obj not vtk obj as want to use algs etc later # Velocity gradient tensor and its transpose # J[:,i-1,j-1] is dUidxj # Jt[:,i-1,j-1] is dUjdxi Jt = algs.gradient(U) # Jt is this one as algs uses j,i ordering J = algs.apply_dfunc(np.transpose, Jt, (0, 2, 1)) # Strain and vorticity tensors Sij = 0.5 * (J + Jt) Oij = 0.5 * (J - Jt) # Frob. norm of Sij and Oij (Snorm and Onorm are actually S^2 and O^2, sqrt needed to get norms) Snorm = algs.sum(2.0 * Sij**2, axis=1) # sum i axis Snorm = algs.sum(Snorm, axis=1) # sum previous summations i.e. along j axis Onorm = algs.sum(2.0 * Oij**2, axis=1) # sum i axis Onorm = algs.sum(Onorm, axis=1) # sum previous summations i.e. along j axis Snorm = algs.sqrt(Snorm) Onorm = algs.sqrt(Onorm) ######################################## # Calculating pressure and tke gradients ######################################## print('Calculating pressure and tke gradients') tke = rans_dsa.PointData['k'] dkdx = algs.gradient(tke) dpdx = algs.gradient(rans_dsa.PointData['p']) ################################################# # Non-dim everything here. Either local or global ################################################# if nondim == 'local': # Non-dim Sij by eps/k w = rans_dsa.PointData['w'] #/0.09 eps = w * tke Sij_h = Sij / w # Non-dim Oij by Onorm Oij_h = Oij / Onorm # Non-dim pressure gradient ro = rans_dsa.PointData['ro'] DUDt = U[:, 0] * J[:, :, 0] + U[:, 1] * J[:, :, 1] + U[:, 2] * J[:, :, 2] dpdx_h = dpdx / ro * algs.mag(DUDt) # Non-dim tke gradient dkdx_h = dkdx / (eps / algs.sqrt(tke)) # Global non-dim on top Ps = ros * Us**2 Sij_h = Sij_h / (Us / Ls) Oij_h = Oij_h / (Us / Ls) dpdx_h = dpdx_h / (Ps / Ls) dkdx_h = dkdx_h / (Us**2 / Ls) # q[:,0] = Sij_h[:,0,0] # q[:,1] = Sij_h[:,1,1] # q[:,2] = Sij_h[:,2,2] # q[:,3] = Sij_h[:,0,1] # q[:,4] = Sij_h[:,0,2] # q[:,5] = Sij_h[:,1,2] # q[:,6] = Oij_h[:,0,0] # q[:,7] = Oij_h[:,1,1] # q[:,8] = Oij_h[:,2,2] # q[:,9] = Oij_h[:,0,1] # q[:,10] = Oij_h[:,0,2] # q[:,11] = Oij_h[:,1,2] # q[:,12] = dpdx_h[:,0] # q[:,13] = dpdx_h[:,1] # q[:,14] = dpdx_h[:,2] # q[:,15] = dkdx_h[:,0] # q[:,16] = dkdx_h[:,1] # q[:,17] = dkdx_h[:,2] # feature_labels[0] = 'S11' # feature_labels[1] = 'S22' # feature_labels[2] = 'S33' # feature_labels[3] = 'S12' # feature_labels[4] = 'S13' # feature_labels[5] = 'S23' # feature_labels[6] = 'O11' # feature_labels[7] = 'O22' # feature_labels[8] = 'O33' # feature_labels[9] = 'O12' # feature_labels[10] = 'O13' # feature_labels[11] = 'O23' # feature_labels[12] = 'dpdx' # feature_labels[13] = 'dpdy' # feature_labels[14] = 'dpdz' # feature_labels[15] = 'dkdx' # feature_labels[16] = 'dkdy' # feature_labels[17] = 'dkdz' # feat = 18 # Transform dpdx into ani-symmetric tensor Ap=-I x dpdx Ap = np.zeros([rans_nnode, 3, 3]) I = np.eye(3) for a in range(3): for b in range(3): for c in range(3): for d in range(3): Ap[:, a, b] -= eijk(b, c, d) * I[a, c] * dpdx_h[:, d] # Transform dkdx into ani-symmetric tensor Ak=-I x dkdx Ak = np.zeros([rans_nnode, 3, 3]) for a in range(3): for b in range(3): for c in range(3): for d in range(3): Ak[:, a, b] -= eijk(b, c, d) * I[a, c] * dkdx_h[:, d] # Construct all invariant bases ############################### # Use numpy matmul to construct S^2, S^3 etc as we use these alot # (matmul can be used as for arrays of dim>2 as "it is treated as a stack of matrices residing in the last two indexes and is broadcast accordingly") S = Sij_h O = Oij_h S2 = np.matmul(S, S) S3 = np.matmul(S2, S) O2 = np.matmul(O, O) Ap2 = np.matmul(Ap, Ap) Ak2 = np.matmul(Ak, Ak) # 1-2 q[:, 0] = algs.trace(S2) feature_labels[0] = 'S2' q[:, 1] = algs.trace(S3) feature_labels[1] = 'S3' # 3-5 q[:, 2] = algs.trace(O2) feature_labels[2] = 'O2' q[:, 3] = algs.trace(Ap2) feature_labels[3] = 'Ap2' q[:, 4] = algs.trace(Ak2) feature_labels[4] = 'Ak2' # 6-14 q[:, 5] = algs.trace(np.matmul(O2, S)) feature_labels[5] = 'O2*S' q[:, 6] = algs.trace(np.matmul(O2, S2)) feature_labels[6] = 'O2*S2' q[:, 7] = algs.trace(np.matmul(np.matmul(O2, S), np.matmul(O, S2))) feature_labels[7] = 'O2*S*O*S2' q[:, 8] = algs.trace(np.matmul(Ap2, S)) feature_labels[8] = 'Ap2*S' q[:, 9] = algs.trace(np.matmul(Ap2, S2)) feature_labels[9] = 'Ap2*S2' q[:, 10] = algs.trace(np.matmul(np.matmul(Ap2, S), np.matmul(Ap, S2))) feature_labels[10] = 'Ap2*S*Ap*S2' q[:, 11] = algs.trace(np.matmul(Ak2, S)) feature_labels[11] = 'Ak2*S' q[:, 12] = algs.trace(np.matmul(Ak2, S2)) feature_labels[12] = 'Ak2*S2' q[:, 13] = algs.trace(np.matmul(np.matmul(Ak2, S), np.matmul(Ak, S2))) feature_labels[13] = 'Ak2*S*Ak*S2' # 15-17 q[:, 14] = algs.trace(np.matmul(O, Ap)) feature_labels[14] = 'O*Ap' q[:, 15] = algs.trace(np.matmul(Ap, Ak)) feature_labels[15] = 'Ap*Ak' q[:, 16] = algs.trace(np.matmul(O, Ak)) feature_labels[16] = 'O*Ak' # 18-41 q[:, 17] = algs.trace(np.matmul(O, np.matmul(Ap, S))) feature_labels[17] = 'O*Ap*S' q[:, 18] = algs.trace(np.matmul(O, np.matmul(Ap, S2))) feature_labels[18] = 'O*Ap*S2' q[:, 19] = algs.trace(np.matmul(O2, np.matmul(Ap, S))) feature_labels[19] = 'O2*Ap*S' q[:, 20] = algs.trace(np.matmul(Ap2, np.matmul(O, S))) feature_labels[20] = 'Ap2*O*S' q[:, 21] = algs.trace(np.matmul(O2, np.matmul(Ap, S2))) feature_labels[21] = 'O2*Ap*S2' q[:, 22] = algs.trace(np.matmul(Ap2, np.matmul(O, S2))) feature_labels[22] = 'Ap2*O*S2' q[:, 23] = algs.trace(np.matmul(np.matmul(O2, S), np.matmul(Ap, S2))) feature_labels[23] = 'O2*S*Ap*S2' q[:, 24] = algs.trace(np.matmul(np.matmul(Ap2, S), np.matmul(O, S2))) feature_labels[24] = 'Ap2*S*O*S2' q[:, 25] = algs.trace(np.matmul(O, np.matmul(Ak, S))) feature_labels[25] = 'O*Ak*S' q[:, 26] = algs.trace(np.matmul(O, np.matmul(Ak, S2))) feature_labels[26] = 'O*Ak*S2' q[:, 27] = algs.trace(np.matmul(O2, np.matmul(Ak, S))) feature_labels[27] = 'O2*Ak*S' q[:, 28] = algs.trace(np.matmul(Ak2, np.matmul(O, S))) feature_labels[28] = 'Ak2*O*S' q[:, 29] = algs.trace(np.matmul(O2, np.matmul(Ak, S2))) feature_labels[29] = 'O2*Ak*S2' q[:, 30] = algs.trace(np.matmul(Ak2, np.matmul(O, S2))) feature_labels[30] = 'Ak2*O*S2' q[:, 31] = algs.trace(np.matmul(np.matmul(O2, S), np.matmul(Ak, S2))) feature_labels[31] = 'O2*S*Ak*S2' q[:, 32] = algs.trace(np.matmul(np.matmul(Ak2, S), np.matmul(O, S2))) feature_labels[32] = 'Ak2*S*O*S2' q[:, 33] = algs.trace(np.matmul(Ap, np.matmul(Ak, S))) feature_labels[33] = 'Ap*Ak*S' q[:, 34] = algs.trace(np.matmul(Ap, np.matmul(Ak, S2))) feature_labels[34] = 'Ap*Ak*S2' q[:, 35] = algs.trace(np.matmul(Ap2, np.matmul(Ak, S))) feature_labels[35] = 'Ap2*Ak*S' q[:, 36] = algs.trace(np.matmul(Ak2, np.matmul(Ap, S))) feature_labels[36] = 'Ak2*Ap*S' q[:, 37] = algs.trace(np.matmul(Ap2, np.matmul(Ak, S2))) feature_labels[37] = 'Ap2*Ak*S2' q[:, 38] = algs.trace(np.matmul(Ak2, np.matmul(Ap, S2))) feature_labels[38] = 'Ak2*Ap*S2' q[:, 39] = algs.trace(np.matmul(np.matmul(Ap2, S), np.matmul(Ak, S2))) feature_labels[39] = 'Ap2*S*Ak*S2' q[:, 40] = algs.trace(np.matmul(np.matmul(Ak2, S), np.matmul(Ap, S2))) feature_labels[40] = 'Ak2*S*Ap*S2' # # 42 q[:, 41] = algs.trace(np.matmul(O, np.matmul(Ap, Ak))) feature_labels[41] = 'O*Ap*Ak' # # 43-47 q[:, 42] = algs.trace(np.matmul(np.matmul(O, Ap), np.matmul(Ak, S))) feature_labels[42] = 'O*Ap*Ak*S' q[:, 43] = algs.trace(np.matmul(np.matmul(O, Ak), np.matmul(Ap, S))) feature_labels[43] = 'O*Ak*Ap*S' q[:, 44] = algs.trace(np.matmul(np.matmul(O, Ap), np.matmul(Ak, S2))) feature_labels[44] = 'O*Ap*Ak*S2' q[:, 45] = algs.trace(np.matmul(np.matmul(O, Ak), np.matmul(Ap, S2))) feature_labels[45] = 'O*Ak*Ap*S2' q[:, 46] = algs.trace( np.matmul(np.matmul(np.matmul(O, Ap), np.matmul(S, Ak)), S2)) feature_labels[46] = 'O*Ap*S*Ak*S2' feat = 47 # Supplementary features ######################## print('Calculating supplementary features: ') # Wall distanced based Re print('Turbulence Reynolds number') nu = rans_dsa.PointData['mu_l'] / rans_dsa.PointData['ro'] Red = (algs.sqrt(tke) * rans_dsa.PointData['d']) / (50.0 * nu) q[:, feat] = algs.apply_dfunc(np.minimum, Red, 2.0) feature_labels[feat] = 'Turbulence Re' feat += 1 # Turbulence intensity print('Turbulence intensity') UiUi = algs.mag(U)**2.0 q[:, feat] = tke / (0.5 * UiUi + tke + small) feature_labels[feat] = 'Turbulence intensity' feat += 1 # Ratio of turb time scale to mean strain time scale print('Ratio of turb time scale to mean strain time scale') A = 1.0 / rans_dsa.PointData[ 'w'] #Turbulent time scale (eps = k*w therefore also A = k/eps) B = 1.0 / Snorm q[:, feat] = A / (A + B + small) feature_labels[feat] = 'turb/strain time-scale' feat += 1 return q, feature_labels
def make_features(rans_vtk, Ls=1, Us=1, ros=1, nondim='local'): from cfd2ml.utilities import build_cevm small = np.cbrt(np.finfo(float).tiny) Ps = 0.5 * ros * Us**2 rans_nnode = rans_vtk.number_of_points delij = np.zeros([rans_nnode, 3, 3]) for i in range(0, 3): delij[:, i, i] = 1.0 # Wrap vista object in dsa wrapper rans_dsa = dsa.WrapDataObject(rans_vtk) print('Feature:') nfeat = 15 feat = 0 q = np.empty([rans_nnode, nfeat]) feature_labels = np.empty(nfeat, dtype='object') # Feature 1: non-dim Q-criterion ################################ print('1: non-dim Q-criterion...') # Velocity vector U = rans_dsa.PointData[ 'U'] # NOTE - Getting variables from dsa obj not vtk obj as want to use algs etc later # Velocity gradient tensor and its transpose # J[:,i-1,j-1] is dUidxj # Jt[:,i-1,j-1] is dUjdxi Jt = algs.gradient(U) # Jt is this one as algs uses j,i ordering J = algs.apply_dfunc(np.transpose, Jt, (0, 2, 1)) # Strain and vorticity tensors Sij = 0.5 * (J + Jt) Oij = 0.5 * (J - Jt) # Frob. norm of Sij and Oij (Snorm and Onorm are actually S^2 and O^2, sqrt needed to get norms) Snorm = algs.sum(2.0 * Sij**2, axis=1) # sum i axis Snorm = algs.sum(Snorm, axis=1) # sum previous summations i.e. along j axis Onorm = algs.sum(2.0 * Oij**2, axis=1) # sum i axis Onorm = algs.sum(Onorm, axis=1) # sum previous summations i.e. along j axis # Store q1 q[:, feat] = (Onorm - 0.5 * Snorm) / (Onorm + 0.5 * Snorm + small) feature_labels[feat] = 'Normalised strain' feat += 1 # clean up Snorm = algs.sqrt(Snorm) #revert to revert to real Snorm for use later Onorm = algs.sqrt(Onorm) #revert to revert to real Onorm for use later # Feature 2: Turbulence intensity ################################# print('2: Turbulence intensity') tke = rans_dsa.PointData['k'] UiUi = algs.mag(U)**2.0 # q[:,feat] = tke/(0.5*UiUi+tke+small) q[:, feat] = tke / (0.5 * UiUi + small) feature_labels[feat] = 'Turbulence intensity' feat += 1 # Feature 3: Turbulence Reynolds number ####################################### print('3: Turbulence Reynolds number') nu = rans_dsa.PointData['mu_l'] / rans_dsa.PointData['ro'] Red = (algs.sqrt(tke) * rans_dsa.PointData['d']) / (50.0 * nu) q[:, feat] = algs.apply_dfunc(np.minimum, Red, 2.0) #Red = 0.09**0.25*algs.sqrt(tke)*rans_dsa.PointData['d']/nu #q[:,feat] = algs.apply_dfunc(np.minimum, Red, 100.0) feature_labels[feat] = 'Turbulence Re' feat += 1 # Feature 4: Pressure gradient along streamline ############################################### print('4: Stream-wise pressure gradient') A = np.zeros(rans_nnode) B = np.zeros(rans_nnode) dpdx = algs.gradient(rans_dsa.PointData['p']) ro = rans_dsa.PointData['ro'] Umag = algs.mag(U) for k in range(0, 3): A += U[:, k] * dpdx[:, k] if nondim == 'global': A = A / Umag q[:, feat] = A * Ls / Ps elif nondim == 'local': for i in range(0, 3): for j in range(0, 3): B += U[:, i] * U[:, i] * dpdx[:, j] * dpdx[:, j] q[:, feat] = A / (algs.sqrt(B) + algs.abs(A) + small) feature_labels[feat] = 'Stream-wise Pgrad' feat += 1 # Feature 5: Ratio of turb time scale to mean strain time scale ############################################################### print('5: Ratio of turb time scale to mean strain time scale') # A = 1.0/rans_dsa.PointData['w'] #Turbulent time scale (eps = k*w therefore also A = k/eps) # B = 1.0/Snorm # q[:,feat] = A/(A+B+small) q[:, feat] = Snorm / (rans_dsa.PointData['w'] + small) feature_labels[feat] = 'turb/strain time-scale' feat += 1 # Feature 6: Viscosity ratio ############################ print('6: Viscosity ratio') nu_t = rans_dsa.PointData['mu_t'] / ro # q[:,feat] = nu_t/(100.0*nu + nu_t) q[:, feat] = nu_t / (nu + small) feature_labels[feat] = 'Viscosity ratio' feat += 1 # Feature 7: Vortex stretching ############################## print('7: Vortex stretching') A = np.zeros(rans_nnode) B = np.zeros(rans_nnode) vortvec = algs.vorticity(U) for j in range(0, 3): for i in range(0, 3): for k in range(0, 3): A += vortvec[:, j] * J[:, i, j] * vortvec[:, k] * J[:, i, k] B = Snorm # q[:,feat] = algs.sqrt(A)/(algs.sqrt(A)+B+small) q[:, feat] = algs.sqrt(A) #/(algs.sqrt(A)+B+small) feature_labels[feat] = 'Vortex stretching' feat += 1 # Feature 8: Marker of Gorle et al. (deviation from parallel shear flow) ######################################################################## print('8: Marker of Gorle et al. (deviation from parallel shear flow)') if nondim == 'global': g = np.zeros([rans_nnode, 3]) m = np.zeros(rans_nnode) s = U / Umag for j in range(3): for i in range(3): g[:, j] += s[:, i] * J[:, i, j] m += g[:, j] * s[:, j] m = np.abs(m) q[:, feat] = m * Ls / Us elif nondim == 'local': A = np.zeros(rans_nnode) B = np.zeros(rans_nnode) for i in range(0, 3): for j in range(0, 3): A += U[:, i] * U[:, j] * J[:, i, j] for n in range(0, 3): for i in range(0, 3): for j in range(0, 3): for m in range(0, 3): B += U[:, n] * U[:, n] * U[:, i] * J[:, i, j] * U[:, m] * J[:, m, j] q[:, feat] = algs.abs(A) / (algs.sqrt(B) + algs.abs(A) + small) feature_labels[feat] = 'Deviation from parallel shear' feat += 1 # Feature 9: Ratio of convection to production of k #################################################### print('9: Ratio of convection to production of k') uiuj = (2.0 / 3.0) * tke * delij - 2.0 * nu_t * Sij dkdx = algs.gradient(tke) A = np.zeros(rans_nnode) B = np.zeros(rans_nnode) for i in range(0, 3): A += U[:, i] * dkdx[:, i] for j in range(0, 3): for l in range(0, 3): B += uiuj[:, j, l] * Sij[:, j, l] q[:, feat] = A / (algs.abs(B) + small) feature_labels[feat] = 'Convection/production of k' feat += 1 # Feature 10: Ratio of total Reynolds stresses to normal Reynolds stresses ########################################################################## print('10: Ratio of total Reynolds stresses to normal Reynolds stresses') # Frob. norm of uiuj A = algs.sum(uiuj**2, axis=1) # sum i axis A = algs.sum(A, axis=1) # sum previous summations i.e. along j axis A = algs.sqrt(A) B = tke q[:, feat] = A / (B + small) feature_labels[feat] = 'total/normal stresses' feat += 1 # Feature 11: Cubic eddy viscosity comparision ############################################## print('11: Cubic eddy viscosity comparision') # Add quadratic and cubic terms to linear evm cevm_2nd, cevm_3rd = build_cevm(Sij, Oij) uiujSij = np.zeros(rans_nnode) for i in range(0, 3): for j in range(0, 3): uiujSij += uiuj[:, i, j] * Sij[:, i, j] uiujcevmSij = uiujSij + (cevm_2nd / tke) * nu_t**2.0 + ( cevm_3rd / tke**2.0) * nu_t**3.0 q[:, feat] = (uiujcevmSij - uiujSij) / (0.5 * (np.abs(uiujcevmSij) + np.abs(uiujSij)) + small) feature_labels[feat] = 'CEV comparison' feat += 1 # Feature 12: Streamline normal pressure gradient ################################################# print('12: Stream-normal pressure gradient') A = algs.cross(U, dpdx) A = np.sqrt(A[:, 0]**2 + A[:, 1]**2 + A[:, 2]**2) if nondim == 'global': A = A / Umag q[:, feat] = A * Ls / Ps elif nondim == 'local': B = np.zeros(rans_nnode) for i in range(0, 3): for j in range(0, 3): B += U[:, i] * U[:, i] * dpdx[:, j] * dpdx[:, j] q[:, feat] = A / (A + algs.sqrt(B) + small) feature_labels[feat] = 'Stream-normal Pgrad' feat += 1 # Feature 13: Streamline curvature ################################## print('13: Streamline curvature') # A = np.zeros([rans_nnode,3]) # # # Gradient of Gamma # Gamma = U#/algs.mag(U) # dGammadx = algs.gradient(Gamma) # # for i in range(0,3): # for j in range(0,3): # A[:,i] += U[:,j]*dGammadx[:,j,i] # A = algs.mag(A/algs.mag(U)*algs.mag(U)) # # q[:,feat] = A # feature_labels[feat] = 'Streamline curvature' # feat += 1 D2 = 0.5 * (Snorm**2 + Onorm**2) # cr1 = 1.0 # cr2 = 12.0 # cr3 = 1.0 cr2 = 12 cr3 = 1 / np.pi rstar = Snorm / (Onorm + small) dSijdx1 = algs.gradient(Sij[:, :, 0]) dSijdx2 = algs.gradient(Sij[:, :, 1]) dSijdx3 = algs.gradient(Sij[:, :, 2]) DSijDt = np.zeros([rans_nnode, 3, 3]) for i in range(3): for j in range(3): DSijDt[:, i, j] = U[:, 0] * dSijdx1[:, j, i] + U[:, 1] * dSijdx2[:, j, i] + U[:, 2] * dSijdx3[:, j, i] rhat = np.zeros(rans_nnode) for i in range(3): for j in range(3): for k in range(3): rhat += (2 * Oij[:, i, k] * Sij[:, j, k] / D2**2) * DSijDt[:, i, j] # fr1 = -((2*rstar)/(1+rstar))*(cr3*algs.arctan(cr2*rhat)) # fr1 = ( (1+cr1)*((2*rstar)/(1+rstar))*(1-cr3*algs.arctan(cr2*rhat)) ) - cr1 rhathat = algs.arctan(0.25 * rhat) * 2 / np.pi q[:, feat] = rhathat #fr1 feature_labels[feat] = 'Streamline curvature' feat += 1 # Feature 14: Anisotropy of pressure hessian ############################################ print('14: Anisotropy of pressure hessian') # Calculate pressure hessian Hij = algs.gradient(dpdx) Hij = algs.apply_dfunc(np.transpose, Hij, (0, 2, 1)) aniso = np.zeros(rans_nnode) iso = np.zeros(rans_nnode) # Frob. norm of Hij for i in range(3): for j in range(3): aniso += (Hij[:, i, j] - Hij[:, i, j] * delij[:, i, j])**2 iso += Hij[:, i, i]**2 aniso = np.sqrt(aniso) iso = np.sqrt(iso) q[:, feat] = (aniso) / (iso + small) feature_labels[feat] = 'Anisotropy of pressure hessian' feat += 1 # Feature 15: White noise ######################### print('15: White noise') q[:, feat] = np.random.uniform(low=-1.0, high=1.0, size=rans_nnode) feature_labels[feat] = 'White noise' feat += 1 return q, feature_labels