[docs]classVonMisesTube(om.ExplicitComponent):"""Compute the von Mises stress in each element. parameters ---------- nodes[ny, 3] : numpy array Flattened array with coordinates for each FEM node. radius[ny-1] : numpy array Radii for each FEM element. disp[ny, 6] : numpy array Displacements of each FEM node. Returns ------- vonmises[ny-1, 2] : numpy array von Mises stress magnitudes for each FEM element. """definitialize(self):self.options.declare("surface",types=dict)defsetup(self):self.surface=surface=self.options["surface"]ny=self.ny=surface["mesh"].shape[1]self.add_input("nodes",val=np.zeros((ny,3)),units="m")self.add_input("radius",val=np.zeros((ny-1)),units="m")self.add_input("disp",val=np.zeros((ny,6)),units="m")self.add_output("vonmises",val=np.zeros((ny-1,2)),units="N/m**2")self.E=surface["E"]self.G=surface["G"]row=np.concatenate([np.zeros(6),np.ones(6)])rows=np.tile(row,ny-1)+np.repeat(2*np.arange(ny-1),12)col=np.tile(np.arange(6),2)cols=np.tile(col,ny-1)+np.repeat(3*np.arange(ny-1),12)self.declare_partials("*","nodes",rows=rows,cols=cols)rows=np.arange(2*(ny-1))cols=np.repeat(np.arange(ny-1),2)self.declare_partials("*","radius",rows=rows,cols=cols)row=np.concatenate([np.zeros(12),np.ones(12)])rows=np.tile(row,ny-1)+np.repeat(2*np.arange(ny-1),24)col=np.tile(np.arange(12),2)cols=np.tile(col,ny-1)+np.repeat(6*np.arange(ny-1),24)self.declare_partials("*","disp",rows=rows,cols=cols)defcompute(self,inputs,outputs):dtype=floatifself.under_complex_step:dtype=complexself.T=np.zeros((3,3),dtype=dtype)self.x_gl=np.array([1,0,0],dtype=dtype)radius=inputs["radius"]disp=inputs["disp"]nodes=inputs["nodes"]T=self.TE=self.EG=self.Gx_gl=self.x_glnum_elems=self.ny-1forieleminrange(num_elems):P0=nodes[ielem,:]P1=nodes[ielem+1,:]L=norm(P1-P0)x_loc=unit(P1-P0)y_loc=unit(np.cross(x_loc,x_gl))z_loc=unit(np.cross(x_loc,y_loc))T[0,:]=x_locT[1,:]=y_locT[2,:]=z_locu0x,u0y,u0z=T.dot(disp[ielem,:3])r0x,r0y,r0z=T.dot(disp[ielem,3:])u1x,u1y,u1z=T.dot(disp[ielem+1,:3])r1x,r1y,r1z=T.dot(disp[ielem+1,3:])tmp=np.sqrt((r1y-r0y)**2+(r1z-r0z)**2)sxx0=E*(u1x-u0x)/L+E*radius[ielem]/L*tmpsxx1=E*(u0x-u1x)/L+E*radius[ielem]/L*tmpsxt=G*radius[ielem]*(r1x-r0x)/Loutputs["vonmises"][ielem,0]=np.sqrt(sxx0**2+3*sxt**2)outputs["vonmises"][ielem,1]=np.sqrt(sxx1**2+3*sxt**2)defcompute_partials(self,inputs,partials):radius=inputs["radius"]disp=inputs["disp"]nodes=inputs["nodes"]T=self.TE=self.EG=self.Gx_gl=self.x_glnum_elems=self.ny-1forieleminrange(num_elems):# Compute the coordinate delta between the two element end pointsP0=nodes[ielem,:]P1=nodes[ielem+1,:]dP=P1-P0# Compute the derivative of element lengthL=norm(dP)dLddP=norm_d(dP)# unit function converts a vector to a unit vector# calculate the transormation to the local element frame.# We use x_gl to provide a reference axis to referencex_loc=unit(dP)dxdP=unit_d(dP)y_loc=unit(np.cross(x_loc,x_gl))dtmpdx,_=cross_d(x_loc,x_gl)dydtmp=unit_d(np.cross(x_loc,x_gl))dydP=dydtmp.dot(dtmpdx).dot(dxdP)z_loc=unit(np.cross(x_loc,y_loc))dtmpdx,dtmpdy=cross_d(x_loc,y_loc)dzdtmp=unit_d(np.cross(x_loc,y_loc))dzdP=dzdtmp.dot(dtmpdx).dot(dxdP)+dzdtmp.dot(dtmpdy).dot(dydP)T[0,:]=x_locT[1,:]=y_locT[2,:]=z_locu0x=x_loc.dot(disp[ielem,:3])r0x,r0y,r0z=T.dot(disp[ielem,3:])u1x=x_loc.dot(disp[ielem+1,:3])r1x,r1y,r1z=T.dot(disp[ielem+1,3:])# #$$$$$$$$$$$$$$$$$$$$$$$$$$# The derivatives of the above code wrt displacement all boil down to sections of the T matrixdxddisp=T[0,:]dyddisp=T[1,:]dzddisp=T[2,:]# The derivatives of the above code wrt T all boil down to sections of the #displacement vectordu0dloc=disp[ielem,:3]dr0dloc=disp[ielem,3:]du1dloc=disp[ielem+1,:3]dr1dloc=disp[ielem+1,3:]# $$$$$$$$$$$$$$$$$$$$$$$$$$# Original code# $$$$$$$$$$$$tmp=np.sqrt((r1y-r0y)**2+(r1z-r0z)**2)+1e-50# added eps to avoid 0 disp singularitysxx0=E*(u1x-u0x)/L+E*radius[ielem]/L*tmpsxx1=E*(u0x-u1x)/L+E*radius[ielem]/L*tmpsxt=G*radius[ielem]*(r1x-r0x)/L# $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$dtmpdr0y=1/tmp*(r1y-r0y)*-1dtmpdr1y=1/tmp*(r1y-r0y)dtmpdr0z=1/tmp*(r1z-r0z)*-1dtmpdr1z=1/tmp*(r1z-r0z)# Combine all of the derivtives for tmpdtmpdDisp=np.zeros(12)dr0xdDisp=np.zeros(12)dr1xdDisp=np.zeros(12)# r0 termdr0xdDisp[3:6]=dxddispdr1xdDisp[9:12]=dxddispdtmpdDisp[3:6]=dtmpdr0y*dyddispdtmpdDisp[3:6]+=dtmpdr0z*dzddispdtmpdDisp[9:12]=dtmpdr1y*dyddispdtmpdDisp[9:12]+=dtmpdr1z*dzddisp# x_loc, y_loc and z_loc terms# (dttmpx_loc is zeros, so don't compute with it)dtmpdy_loc=dtmpdr0y*dr0dloc+dtmpdr1y*dr1dlocdtmpdz_loc=dtmpdr0z*dr0dloc+dtmpdr1z*dr1dlocdtmpdP=dtmpdy_loc.dot(dydP)+dtmpdz_loc.dot(dzdP)dsxx0dtmp=E*radius[ielem]/Ldsxx0du0x=-E/Ldsxx0du1x=E/Ldsxx0dL=-E*(u1x-u0x)/(L*L)-E*radius[ielem]/(L*L)*tmpdsxx1dtmp=E*radius[ielem]/Ldsxx1du0x=E/Ldsxx1du1x=-E/Ldsxx1dL=-E*(u0x-u1x)/(L*L)-E*radius[ielem]/(L*L)*tmpdsxx0dP=(dsxx0dtmp*dtmpdP+dsxx0du0x*du0dloc.dot(dxdP)+dsxx0du1x*du1dloc.dot(dxdP)+dsxx0dL*dLddP)dsxx1dP=(dsxx1dtmp*dtmpdP+dsxx1du0x*du0dloc.dot(dxdP)+dsxx1du1x*du1dloc.dot(dxdP)+dsxx1dL*dLddP)# Combine sxx0 and sxx1 terms# Start with the tmp termdsxx0dDisp=dsxx0dtmp*dtmpdDispdsxx1dDisp=dsxx1dtmp*dtmpdDisp# Now add the direct u depdsxx0dDisp[0:3]=dsxx0du0x*dxddispdsxx0dDisp[6:9]=dsxx0du1x*dxddispdsxx1dDisp[0:3]=dsxx1du0x*dxddispdsxx1dDisp[6:9]=dsxx1du1x*dxddisp# Combine sxt termdsxtdr0x=-G*radius[ielem]/Ldsxtdr1x=G*radius[ielem]/LdsxtdL=-G*radius[ielem]*(r1x-r0x)/(L*L)dsxtdP=dsxtdr0x*(dr0dloc.dot(dxdP))+dsxtdr1x*(dr1dloc.dot(dxdP))+dsxtdL*dLddP# dispdsxtdDisp=dsxtdr0x*dr0xdDisp+dsxtdr1x*dr1xdDisp# radius derivativesdsxxdrad=E/L*tmpdsxtdrad=G*(r1x-r0x)/Lfact=1.0/(np.sqrt(sxx0**2+3*sxt**2))dVm0dsxx0=sxx0*factdVm0dsxt=3*sxt*factfact=1.0/(np.sqrt(sxx1**2+3*sxt**2))dVm1dsxx1=sxx1*factdVm1dsxt=3*sxt*factii=2*ielempartials["vonmises","radius"][ii]=dVm0dsxx0*dsxxdrad+dVm0dsxt*dsxtdradpartials["vonmises","radius"][ii+1]=dVm1dsxx1*dsxxdrad+dVm1dsxt*dsxtdradii=24*ielempartials["vonmises","disp"][ii:ii+12]=dVm0dsxx0*dsxx0dDisp+dVm0dsxt*dsxtdDisppartials["vonmises","disp"][ii+12:ii+24]=dVm1dsxx1*dsxx1dDisp+dVm1dsxt*dsxtdDisp# Compute terms for the nodesii=12*ielemdVm0_dnode=dVm0dsxx0*dsxx0dP+dVm0dsxt*dsxtdPpartials["vonmises","nodes"][ii:ii+3]=-dVm0_dnodepartials["vonmises","nodes"][ii+3:ii+6]=dVm0_dnodedVM1_dnode=dVm1dsxx1*dsxx1dP+dVm1dsxt*dsxtdPpartials["vonmises","nodes"][ii+6:ii+9]=-dVM1_dnodepartials["vonmises","nodes"][ii+9:ii+12]=dVM1_dnode