def addFaceTraction(order, forest, attr, assembler, tr): trac = [] for findex in range(6): trac.append(elements.Traction3D(order, findex, tr[0], tr[1], tr[2])) # Retrieve octants from the forest octants = forest.getOctants() face_octs = forest.getOctsWithAttribute(attr) aux = TACS.AuxElements() for i in range(len(face_octs)): aux.addElement(face_octs[i].tag, trac[face_octs[i].info]) return aux
def compute3DTractionLoad(name, forest, assembler, tr): """ Add a constant surface traction to all octants that touch a face or edge with the given name. Args: forest (QuadForest or OctForest): Forest for the finite-element mesh name (str): Name of the surface where the traction will be added assembler (Assembler): TACSAssembler object for the finite-element problem tr (list): The 3D components of the traction. Returns: Vec: A force vector containing the traction """ order = forest.getMeshOrder() trac = [] for findex in range(6): trac.append(elements.Traction3D(order, findex, tr[0], tr[1], tr[2])) return computeTractionLoad(name, forest, assembler, trac)
def createAssembler(tacs_comm): # Set constitutive properties rho = 4540.0 # density, kg/m^3 E = 118e9 # elastic modulus, Pa 118e9 nu = 0.325 # poisson's ratio ys = 1050e6 # yield stress, Pa kappa = 6.89 specific_heat = 463.0 # Set the back-pressure for the traction load pb = 654.9 #10.0 # A value for the surface pressure # Load in the mesh mesh = TACS.MeshLoader(tacs_comm) mesh.scanBDFFile('tacs_aero.bdf') # Get the number of components set in the mesh. Each component is num_components = mesh.getNumComponents() # Each domain consists of the union of two components. The component # corresponding to the surface traction and the component corresponding # to remaining plate elements. There is one design variable associated # with each domain that shares a common (x,z) coordinate num_domains = num_components // 2 # Create the constitutvie propertes and model props_plate = constitutive.MaterialProperties(rho=rho, specific_heat=specific_heat, kappp=kappa, E=E, nu=nu, ys=ys) # Create the basis class basis = elements.LinearHexaBasis() element_list = [] for k in range(num_domains): # Create the elements in an element list con = constitutive.SolidConstitutive(props_plate, t=1.0, tNum=k) phys_model = elements.LinearThermoelasticity3D(con) # Create the element element_list.append(elements.Element3D(phys_model, basis)) varsPerNode = phys_model.getVarsPerNode() # Set the face index for the side of the element where the traction # will be applied. The face indices are as follows for the hexahedral # basis class: # -x: 0, +x: 1, -y: 2, +y: 3, -z: 4, +z: 5 faceIndex = 4 # Set the wedge angle - 5 degrees theta = np.radians(5.0) # Compute the outward normal components for the face nx = np.sin(theta) nz = -np.cos(theta) # Set the traction components tr = [-pb * nx, 0.0, -pb * nz, 0.0] # Create the traction class traction = elements.Traction3D(varsPerNode, faceIndex, basis, tr) # Set the elements corresponding to each component number num_components = mesh.getNumComponents() for k in range(num_components): mesh.setElement(k, element_list[k % num_domains]) # Create the assembler object assembler = mesh.createTACS(varsPerNode) # Set the traction load into the assembler object aux = TACS.AuxElements(assembler) for k in range(num_domains, num_components): mesh.addAuxElement(aux, k, traction) assembler.setAuxElements(aux) return assembler, num_domains