def __init__(self, comm, tacs_comm, model, n_tacs_procs): super(wedgeTACS,self).__init__(comm, tacs_comm, model) assembler = None mat = None pc = None gmres = None self.T_ref = 300.0 if comm.Get_rank() < n_tacs_procs: # Set constitutive properties rho = 4540.0 # density, kg/m^3 E = 118e9 # elastic modulus, Pa nu = 0.325 # poisson's ratio ys = 1050e6 # yield stress, Pa kappa = 6.89 specific_heat=463.0 thickness = 0.015 volume = 25 # need tacs volume for TACSAverageTemperature function # Create the constitutvie propertes and model props = constitutive.MaterialProperties(rho=4540.0, specific_heat=463.0, kappa = 6.89, E=118e9, nu=0.325, ys=1050e6) con = constitutive.SolidConstitutive(props, t=1.0, tNum=0) # Set the model type = linear thermoelasticity elem_model = elements.LinearThermoelasticity3D(con) # Create the basis class basis = elements.LinearHexaBasis() # Create the element element = elements.Element3D(elem_model, basis) varsPerNode = elem_model.getVarsPerNode() # Load in the mesh mesh = TACS.MeshLoader(tacs_comm) mesh.scanBDFFile('tacs_aero.bdf') # Set the element mesh.setElement(0, element) # Create the assembler object assembler = mesh.createTACS(varsPerNode) # Create the preconditioner for the corresponding matrix mat = assembler.createSchurMat() pc = TACS.Pc(mat) # Create GMRES object for structural adjoint solves nrestart = 0 # number of restarts before giving up m = 30 # size of Krylov subspace (max # of iterations) gmres = TACS.KSM(mat, pc, m, nrestart) self._initialize_variables(assembler, mat, pc, gmres) self.initialize(model.scenarios[0], model.bodies) return
def __init__(self, tacs, f5): # Set the communicator pointer self.comm = MPI.COMM_WORLD self.rank = self.comm.Get_rank() self.size = self.comm.Get_size() self.nvars = num_components / self.size if num_components % self.size != 0 and self.rank == self.size - 1: self.nvars += num_components % self.size self.ncon = 1 # Initialize the base class super(CRMSizing, self).__init__(self.comm, self.nvars, self.ncon) self.tacs = tacs self.f5 = f5 self.res = self.tacs.createVec() self.ans = self.tacs.createVec() self.mat = self.tacs.createFEMat() self.pc = TACS.Pc(self.mat) # Create list of required TACS functions (mass, ksfailure) self.mass = functions.StructuralMass(self.tacs) ksweight = 50.0 alpha = 1.0 self.ksfailure = functions.KSFailure(self.tacs, ksweight, alpha) self.ksfailure.setLoadFactor(1.5) self.funclist = [self.mass, self.ksfailure] self.svsens = self.tacs.createVec() self.adj = self.tacs.createVec() self.adjSensProdArray = np.zeros(num_components) self.tempdvsens = np.zeros(num_components) # Get initial mass for scaling self.initmass = self.tacs.evalFunctions([self.funclist[0]]) self.xscale = 0.0025 # Keep track of the number of gradient evaluations self.gevals = 0 return
def setAssembler(self, assembler, ksfunc): # Create tacs assembler object from mesh loader self.assembler = assembler # Create the list of functions self.funcs = [functions.StructuralMass(self.assembler), ksfunc] # Set up the solver self.ans = self.assembler.createVec() self.res = self.assembler.createVec() self.adjoint = self.assembler.createVec() self.dfdu = self.assembler.createVec() self.mat = self.assembler.createFEMat() self.pc = TACS.Pc(self.mat) self.gmres = TACS.KSM(self.mat, self.pc, 10) # For visualization flag = (TACS.ToFH5.NODES | TACS.ToFH5.DISPLACEMENTS | TACS.ToFH5.STRAINS | TACS.ToFH5.EXTRAS) self.f5 = TACS.ToFH5(self.assembler, TACS.PY_PLANE_STRESS, flag) return
# Create tacs assembler object tacs = struct_mesh.createTACS(6) res = tacs.createVec() ans = tacs.createVec() mat = tacs.createFEMat() # Create distributed node vector from TACS Assembler object and extract the # nodes struct_X_vec = tacs.createNodeVec() tacs.getNodes(struct_X_vec) struct_X = struct_X_vec.getArray() struct_nnodes = len(struct_X) / 3 # Create the preconditioner for the corresponding matrix pc = TACS.Pc(mat) # Set design variables (thicknesses of components) x = np.loadtxt('sizing.dat', dtype=TACS.dtype) tacs.setDesignVars(x) # Assemble the Jacobian alpha = 1.0 beta = 0.0 gamma = 0.0 tacs.assembleJacobian(alpha, beta, gamma, res, mat) pc.factor() """ -------------------------------------------------------------------------------- Set up MELD and transfer loads --------------------------------------------------------------------------------
def __init__(self, comm, bdf_name): self.comm = comm struct_mesh = TACS.MeshLoader(self.comm) struct_mesh.scanBDFFile(bdf_name) # Set constitutive properties rho = 2500.0 # density, kg/m^3 E = 70e9 # elastic modulus, Pa nu = 0.3 # poisson's ratio kcorr = 5.0 / 6.0 # shear correction factor ys = 350e6 # yield stress, Pa min_thickness = 0.002 max_thickness = 0.20 thickness = 0.02 # Loop over components, creating stiffness and element object for each num_components = struct_mesh.getNumComponents() for i in range(num_components): descriptor = struct_mesh.getElementDescript(i) # Set the design variable index design_variable_index = i stiff = constitutive.isoFSDT(rho, E, nu, kcorr, ys, thickness, design_variable_index, min_thickness, max_thickness) element = None # Create the element object if descriptor in ["CQUAD", "CQUADR", "CQUAD4"]: element = elements.MITCShell(2, stiff, component_num=i) struct_mesh.setElement(i, element) # Create tacs assembler object from mesh loader self.assembler = struct_mesh.createTACS(6) # Create the KS Function ksWeight = 50.0 self.funcs = [ functions.StructuralMass(self.assembler), functions.KSFailure(self.assembler, ksWeight) ] # Create the forces self.forces = self.assembler.createVec() force_array = self.forces.getArray() force_array[2::6] += 100.0 # uniform load in z direction self.assembler.applyBCs(self.forces) # Set up the solver self.ans = self.assembler.createVec() self.res = self.assembler.createVec() self.adjoint = self.assembler.createVec() self.dfdu = self.assembler.createVec() self.mat = self.assembler.createFEMat() self.pc = TACS.Pc(self.mat) subspace = 100 restarts = 2 self.gmres = TACS.KSM(self.mat, self.pc, subspace, restarts) # Scale the mass objective so that it is O(10) self.mass_scale = 1e-3 # Scale the thickness variables so that they are measured in # mm rather than meters self.thickness_scale = 1000.0 # The number of thickness variables in the problem self.nvars = num_components # The number of constraints (1 global stress constraint that # will use the KS function) self.ncon = 1 # Initialize the base class - this will run the same problem # on all processors super(uCRM_VonMisesMassMin, self).__init__(MPI.COMM_SELF, self.nvars, self.ncon) # Set the inequality options for this problem in ParOpt: # The dense constraints are inequalities c(x) >= 0 and # use both the upper/lower bounds self.setInequalityOptions(dense_ineq=True, use_lower=True, use_upper=True) # For visualization flag = (TACS.ToFH5.NODES | TACS.ToFH5.DISPLACEMENTS | TACS.ToFH5.STRAINS | TACS.ToFH5.EXTRAS) self.f5 = TACS.ToFH5(self.assembler, TACS.PY_SHELL, flag) self.iter_count = 0 return
def __init__(self, comm, tacs_comm, model, n_tacs_procs): super(wedgeTACS, self).__init__(comm, tacs_comm, model) self.tacs_proc = False if comm.Get_rank() < n_tacs_procs: self.tacs_proc = True #mesh = TACS.MeshLoader(tacs_comm) #mesh.scanBDFFile("tacs_aero.bdf") # Set constitutive properties T_ref = 300.0 rho = 4540.0 # density, kg/m^3 E = 118e9 # elastic modulus, Pa nu = 0.325 # poisson's ratio ys = 1050e6 # yield stress, Pa kappa = 6.89 specific_heat = 463.0 thickness = 0.015 volume = 25 # need tacs volume for TACSAverageTemperature function # Create the constitutvie propertes and model props_plate = constitutive.MaterialProperties(rho=4540.0, specific_heat=463.0, kappa=6.89, E=118e9, nu=0.325, ys=1050e6) #con_plate = constitutive.ShellConstitutive(props_plate,thickness,1,0.01,0.10) #model_plate = elements.ThermoelasticPlateModel(con_plate) con_plate = constitutive.PlaneStressConstitutive(props_plate, t=1.0, tNum=0) model_plate = elements.HeatConduction2D(con_plate) # Create the basis class quad_basis = elements.LinearQuadBasis() # Create the element #element_shield = elements.Element2D(model_shield, quad_basis) #element_insulation = elements.Element2D(model_insulation, quad_basis) element_plate = elements.Element2D(model_plate, quad_basis) varsPerNode = model_plate.getVarsPerNode() # Load in the mesh mesh = TACS.MeshLoader(tacs_comm) mesh.scanBDFFile('tacs_aero.bdf') # Set the element mesh.setElement(0, element_plate) # Create the assembler object #varsPerNode = heat.getVarsPerNode() assembler = mesh.createTACS(varsPerNode) res = assembler.createVec() ans = assembler.createVec() mat = assembler.createSchurMat() # Create distributed node vector from TACS Assembler object and # extract the node locations nbodies = 1 struct_X = [] struct_nnodes = [] for body in range(nbodies): self.struct_X_vec = assembler.createNodeVec() assembler.getNodes(self.struct_X_vec) struct_X.append(self.struct_X_vec.getArray()) struct_nnodes.append(len(struct_X) / 3) assembler.setNodes(self.struct_X_vec) # Create the preconditioner for the corresponding matrix pc = TACS.Pc(mat) alpha = 1.0 beta = 0.0 gamma = 0.0 assembler.assembleJacobian(alpha, beta, gamma, res, mat) pc.factor() # Create GMRES object for structural adjoint solves nrestart = 0 # number of restarts before giving up m = 30 # size of Krylov subspace (max # of iterations) gmres = TACS.KSM(mat, pc, m, nrestart) # Initialize member variables pertaining to TACS self.T_ref = T_ref self.vol = volume self.assembler = assembler self.res = res self.ans = ans self.mat = mat self.pc = pc self.struct_X = struct_X self.struct_nnodes = struct_nnodes self.gmres = gmres self.svsens = assembler.createVec() self.struct_rhs_vec = assembler.createVec() self.psi_T_S_vec = assembler.createVec() psi_T_S = self.psi_T_S_vec.getArray() self.psi_T_S = np.zeros((psi_T_S.size, self.nfunc), dtype=TACS.dtype) self.ans_array = [] self.svsenslist = [] self.dvsenslist = [] for func in range(self.nfunc): self.svsenslist.append(self.assembler.createVec()) self.dvsenslist.append(self.assembler.createDesignVec()) for scenario in range(len(model.scenarios)): self.ans_array.append(self.ans.getArray().copy()) self.initialize(model.scenarios[0], model.bodies)
def _initialize_variables(self, assembler=None, mat=None, pc=None, gmres=None, struct_id=None, thermal_index=0): """ Initialize the variables required for analysis and optimization using TACS. This initialization takes in optional TACSMat, TACSPc and TACSKsm objects for the solution procedure. The assembler object must be defined on the subset of structural processors. On all other processors it must be None. """ self.tacs_proc = False self.assembler = None self.res = None self.ans = None self.ext_force = None self.update = None self.mat = None self.pc = None self.gmres = None self.thermal_index = thermal_index self.struct_id = struct_id self.struct_X_vec = None self.struct_nnodes = None self.struct_X = None self.dvsenslist = [] self.svsenslist = [] self.xptsenslist = [] self.struct_rhs_vec = None self.psi_S = None self.ans_array = None self.func_grad = None self.vol = 1.0 if assembler is not None: self.tacs_proc = True self.mat = mat self.pc = pc self.gmres = gmres if mat is None: self.mat = assembler.createSchurMat() self.pc = TACS.Pc(self.mat) self.gmres = TACS.KSM(self.mat, self.pc, 30) elif pc is None: self.mat = mat self.pc = TACS.Pc(self.mat) self.gmres = TACS.KSM(self.mat, self.pc, 30) elif gmres is None: self.mat = mat self.pc = pc self.gmres = TACS.KSM(self.mat, self.pc, 30) self.assembler = assembler self.res = assembler.createVec() self.ans = assembler.createVec() self.ext_force = assembler.createVec() self.update = assembler.createVec() # Get and set the structural node locations self.struct_X_vec = assembler.createNodeVec() assembler.getNodes(self.struct_X_vec) self.struct_nnodes = len(self.struct_X_vec.getArray()) // 3 self.struct_X = np.zeros(3 * self.struct_nnodes, dtype=TACS.dtype) self.struct_X[:] = self.struct_X_vec.getArray()[:] self.dvsenslist = [] self.svsenslist = [] self.xptsenslist = [] for i in range(self.nfunc): self.dvsenslist.append(assembler.createDesignVec()) self.svsenslist.append(assembler.createVec()) self.xptsenslist.append(assembler.createNodeVec()) self.struct_rhs_vec = assembler.createVec() self.psi_S = [] for ifunc in range(self.nfunc): self.psi_S.append(self.assembler.createVec()) self.ans_array = assembler.createVec() self.func_grad = None # required for AverageTemp function, not sure if needed on # body level self.vol = 1.0 return
left_mapping = [] left_f_mapping = [] # if you change the meshes, make sure you change the values here so # that the mapping locates the correct nodes for i in range(len(left_pts_array) // 3): if left_pts_array[3 * i] == 1.0: left_surface.extend(left_pts_array[3 * i:3 * i + 3]) left_mapping.append(i) if left_pts_array[3 * i] < 1.0 and left_pts_array[3 * i] > 0.989: left_f_mapping.append(i) # Create the vectors/matrices l_res = l_assembler.createVec() l_ans = l_assembler.createVec() l_mat = l_assembler.createSchurMat() l_pc = TACS.Pc(l_mat) # Assemble the heat conduction matrix l_assembler.assembleJacobian(1.0, 0.0, 0.0, l_res, l_mat) l_pc.factor() l_gmres = TACS.KSM(l_mat, l_pc, 20) # Now initialize TACS for right plate in the same way # Create the constitutvie propertes and model right_kappa = 230.0 props = constitutive.MaterialProperties(kappa=right_kappa) con = constitutive.PlaneStressConstitutive(props) heat = elements.HeatConduction2D(con) # Create the basis class quad_basis = elements.LinearQuadBasis()
descriptor = struct_mesh.getElementDescript(i) stiff = constitutive.isoFSDT(rho, E, nu, kcorr, ys, thickness, i, min_thickness, max_thickness) element = None if descriptor in ["CQUAD", "CQUADR", "CQUAD4"]: element = elements.MITCShell(2, stiff, component_num=i) struct_mesh.setElement(i, element) # Create tacs assembler object from mesh loader assembler = struct_mesh.createTACS(6) # Solve the eigenvalue problem M = assembler.createFEMat() K = assembler.createFEMat() pc = TACS.Pc(K) subspace = 100 restarts = 2 gmres = TACS.KSM(K, pc, subspace, restarts) # Guess for the lowest natural frequency sigma_hz = 1.0 sigma = 2.0 * np.pi * sigma_hz # Create the frequency analysis object num_eigs = 5 freq = TACS.FrequencyAnalysis(assembler, sigma, M, K, gmres,
def __init__(self, comm, props, tacs, const, num_materials, xpts=None, conn=None, m_fixed=1.0, min_mat_fraction=-1.0): ''' Analysis problem ''' # Keep the communicator self.comm = comm # Set the TACS object and the constitutive list self.props = props self.tacs = tacs self.const = const # Set the material information self.num_materials = num_materials self.num_elements = self.tacs.getNumElements() # Keep the pointer to the connectivity/positions self.xpts = xpts self.conn = conn # Set the target fixed mass self.m_fixed = m_fixed # Set a fixed material fraction self.min_mat_fraction = min_mat_fraction # Set the number of constraints self.ncon = 1 if self.min_mat_fraction > 0.0: self.ncon += self.num_materials # Set the number of design variables nwblock = 1 self.num_design_vars = (self.num_materials + 1) * self.num_elements # Initialize the super class super(TACSAnalysis, self).__init__(comm, self.num_design_vars, self.ncon, self.num_elements, nwblock) # Set the size of the design variable 'blocks' self.nblock = self.num_materials + 1 # Create the state variable vectors self.res = tacs.createVec() self.u = tacs.createVec() self.psi = tacs.createVec() self.mat = tacs.createFEMat() # Create the preconditioner for the corresponding matrix self.pc = TACS.Pc(self.mat) # Create the KSM object subspace_size = 20 nrestart = 0 self.ksm = TACS.KSM(self.mat, self.pc, subspace_size, nrestart) self.ksm.setTolerances(1e-12, 1e-30) # Set the block size self.nwblock = self.num_materials + 1 # Allocate a vector that stores the gradient of the mass self.gmass = np.zeros(self.num_design_vars) # Create the mass function and evaluate the gradient of the # mass. This is assumed to remain constatnt throughout the # optimization. self.mass_func = functions.StructuralMass(self.tacs) self.tacs.evalDVSens(self.mass_func, self.gmass) # Set the initial variable values self.xinit = np.ones(self.num_design_vars) # Set the initial design variable values xi = self.m_fixed / np.dot(self.gmass, self.xinit) self.xinit[:] = xi # Set the penalization tval = xi * self.num_materials self.xinit[::self.nblock] = tval # Create a temporary vector for the hessian-vector products self.hvec_tmp = np.zeros(self.xinit.shape) # Set the initial linearization/point self.RAMP_penalty = 0.0 self.setNewInitPointPenalty(self.xinit) # Set the number of function/gradient/hessian-vector # evaluations to zero self.fevals = 0 self.gevals = 0 self.hevals = 0 # Evaluate the objective at the initial point self.obj_scale = 1.0 fail, obj, con = self.evalObjCon(self.xinit) self.obj_scale = obj_scale_factor * obj print('objective scaling = ', self.obj_scale) # Create the FH5 file object flag = (TACS.ToFH5.NODES | TACS.ToFH5.DISPLACEMENTS | TACS.ToFH5.STRAINS) self.f5 = TACS.ToFH5(self.tacs, TACS.PY_PLANE_STRESS, flag) return
def __init__(self,comm,tacs_comm,model,n_tacs_procs): super(CRMtacs,self).__init__(comm,tacs_comm,model) self.tacs_proc = False if comm.Get_rank() < n_tacs_procs: self.tacs_proc = True struct_mesh = TACS.MeshLoader(tacs_comm) struct_mesh.scanBDFFile("CRM_box_2nd.bdf") # Set constitutive properties rho = 2500.0 # density, kg/m^3 E = 70.0e9 # elastic modulus, Pa nu = 0.3 # poisson's ratio kcorr = 5.0 / 6.0 # shear correction factor ys = 350e6 # yield stress, Pa min_thickness = 0.001 max_thickness = 0.100 thickness = 0.015 spar_thick = 0.015 # Loop over components in mesh, creating stiffness and element # object for each map = np.zeros(240,dtype=int) num_components = struct_mesh.getNumComponents() for i in range(num_components): descript = struct_mesh.getElementDescript(i) comp = struct_mesh.getComponentDescript(i) if 'SPAR' in comp: t = spar_thick else: t = thickness stiff = constitutive.isoFSDT(rho, E, nu, kcorr, ys, t, i, min_thickness, max_thickness) element = None if descript in ["CQUAD", "CQUADR", "CQUAD4"]: element = elements.MITCShell(2,stiff,component_num=i) struct_mesh.setElement(i, element) # Create map if 'LE_SPAR' in comp: segnum = int(comp[-2:]) map[i] = segnum if 'TE_SPAR' in comp: segnum = int(comp[-2:]) map[i] = segnum + 48 if 'IMPDISP' in comp: map[i] = i elif 'RIB' in comp: segnum = int(comp[-9:-7]) - 1 if segnum > 3: segnum -= 1 map[i] = segnum + 188 if 'U_SKIN' in comp: segnum = int(comp[-9:-7]) - 1 map[i] = segnum + 92 if 'L_SKIN' in comp: segnum = int(comp[-9:-7]) - 1 map[i] = segnum + 140 self.dof = 6 # Create tacs assembler object tacs = struct_mesh.createTACS(self.dof) res = tacs.createVec() ans = tacs.createVec() mat = tacs.createFEMat() # Create distributed node vector from TACS Assembler object and # extract the node locations nbodies = 1 struct_X = [] struct_nnodes = [] for body in range(nbodies): self.struct_X_vec = tacs.createNodeVec() tacs.getNodes(self.struct_X_vec) struct_X.append(self.struct_X_vec.getArray()) struct_nnodes.append(len(struct_X) / 3) tacs.setNodes(self.struct_X_vec) # Create the preconditioner for the corresponding matrix pc = TACS.Pc(mat) alpha = 1.0 beta = 0.0 gamma = 0.0 tacs.assembleJacobian(alpha,beta,gamma,res,mat) pc.factor() # Create GMRES object for structural adjoint solves nrestart = 0 # number of restarts before giving up m = 30 # size of Krylov subspace (max # of iterations) gmres = TACS.KSM(mat, pc, m, nrestart) # Initialize member variables pertaining to TACS self.tacs = tacs self.res = res self.ans = ans self.mat = mat self.pc = pc self.struct_X = struct_X self.struct_nnodes = struct_nnodes self.gmres = gmres self.svsens = tacs.createVec() self.struct_rhs_vec = tacs.createVec() self.psi_S_vec = tacs.createVec() psi_S = self.psi_S_vec.getArray() self.psi_S = np.zeros((psi_S.size,self.nfunc),dtype=TACS.dtype) self.ans_array = [] for scenario in range(len(model.scenarios)): self.ans_array.append(self.ans.getArray().copy()) self.initialize(model.scenarios[0],model.bodies)
def __init__(self, comm, tacs_comm, model, n_tacs_procs): super(wedgeTACS, self).__init__(comm, tacs_comm, model) self.tacs_proc = False if comm.Get_rank() < n_tacs_procs: # set refrence values here T_ref = 300.0 volume = 0.01 # need tacs volume for TACSAverageTemperature function self.tacs_proc = True assembler, num_domains = createAssembler(tacs_comm) res = assembler.createVec() ans = assembler.createVec() mat = assembler.createSchurMat(TACS.ND_ORDER) # Create distributed node vector from TACS Assembler object and # extract the node locations nbodies = 1 struct_X = [] struct_nnodes = [] for body in range(nbodies): self.struct_X_vec = assembler.createNodeVec() assembler.getNodes(self.struct_X_vec) struct_X.append(self.struct_X_vec.getArray()) struct_nnodes.append(len(struct_X) / 3) assembler.setNodes(self.struct_X_vec) # Create the preconditioner for the corresponding matrix pc = TACS.Pc(mat) alpha = 1.0 beta = 0.0 gamma = 0.0 assembler.assembleJacobian(alpha, beta, gamma, res, mat) pc.factor() # Create GMRES object for structural adjoint solves nrestart = 0 # number of restarts before giving up m = 30 # size of Krylov subspace (max # of iterations) gmres = TACS.KSM(mat, pc, m, nrestart) # Initialize member variables pertaining to TACS self.T_ref = T_ref self.vol = volume self.assembler = assembler self.res = res self.ans = ans self.ext_force = assembler.createVec() self.update = assembler.createVec() self.mat = mat self.pc = pc self.struct_X = struct_X self.struct_nnodes = struct_nnodes self.gmres = gmres self.svsens = assembler.createVec() self.struct_rhs_vec = assembler.createVec() self.psi_S_vec = assembler.createVec() psi_S = self.psi_S_vec.getArray() self.psi_S = np.zeros((psi_S.size, self.nfunc), dtype=TACS.dtype) self.psi_T_S_vec = assembler.createVec() psi_T_S = self.psi_T_S_vec.getArray() self.psi_T_S = np.zeros((psi_T_S.size, self.nfunc), dtype=TACS.dtype) self.ans_array = [] self.svsenslist = [] self.dvsenslist = [] for func in range(self.nfunc): self.svsenslist.append(self.assembler.createVec()) self.dvsenslist.append(self.assembler.createDesignVec()) for scenario in range(len(model.scenarios)): self.ans_array.append(self.ans.getArray().copy()) self.initialize(model.scenarios[0], model.bodies)