def setup(self): E = self.options['E'] L = self.options['L'] b = self.options['b'] volume = self.options['volume'] num_elements = self.options['num_elements'] num_nodes = num_elements + 1 num_cp = self.options['num_cp'] num_load_cases = self.options['num_load_cases'] inputs_comp = om.IndepVarComp() inputs_comp.add_output('h_cp', shape=num_cp) self.add_subsystem('inputs_comp', inputs_comp) comp = om.BsplinesComp(num_control_points=num_cp, num_points=num_elements, in_name='h_cp', out_name='h') self.add_subsystem('interp', comp) I_comp = MomentOfInertiaComp(num_elements=num_elements, b=b) self.add_subsystem('I_comp', I_comp) comp = LocalStiffnessMatrixComp(num_elements=num_elements, E=E, L=L) self.add_subsystem('local_stiffness_matrix_comp', comp) # Parallel Subsystem for load cases. par = self.add_subsystem('parallel', om.ParallelGroup()) # Determine how to split cases up over the available procs. nprocs = self.comm.size divide = divide_cases(num_load_cases, nprocs) obj_srcs = [] for j, this_proc in enumerate(divide): num_rhs = len(this_proc) name = 'sub_%d' % j sub = par.add_subsystem(name, om.Group()) # Load is a sinusoidal distributed force of varying spatial frequency. force_vector = np.zeros((2 * num_nodes, num_rhs)) for i, k in enumerate(this_proc): end = 1.5 * np.pi if num_load_cases > 1: end += k * 0.5 * np.pi / (num_load_cases - 1) x = np.linspace(0, end, num_nodes) f = -np.sin(x) force_vector[0:-1:2, i] = f comp = MultiStatesComp(num_elements=num_elements, force_vector=force_vector, num_rhs=num_rhs) sub.add_subsystem('states_comp', comp) comp = MultiDisplacementsComp(num_elements=num_elements, num_rhs=num_rhs) sub.add_subsystem('displacements_comp', comp) comp = MultiComplianceComp(num_elements=num_elements, force_vector=force_vector, num_rhs=num_rhs) sub.add_subsystem('compliance_comp', comp) self.connect('local_stiffness_matrix_comp.K_local', 'parallel.%s.states_comp.K_local' % name) for k in range(num_rhs): sub.connect('states_comp.d_%d' % k, 'displacements_comp.d_%d' % k) sub.connect('displacements_comp.displacements_%d' % k, 'compliance_comp.displacements_%d' % k) obj_srcs.append('parallel.%s.compliance_comp.compliance_%d' % (name, k)) comp = VolumeComp(num_elements=num_elements, b=b, L=L) self.add_subsystem('volume_comp', comp) comp = om.ExecComp([ 'obj = ' + ' + '.join(['compliance_%d' % i for i in range(num_load_cases)]) ]) self.add_subsystem('obj_sum', comp) for j, src in enumerate(obj_srcs): self.connect(src, 'obj_sum.compliance_%d' % j) self.connect('inputs_comp.h_cp', 'interp.h_cp') self.connect('interp.h', 'I_comp.h') self.connect('I_comp.I', 'local_stiffness_matrix_comp.I') self.connect('interp.h', 'volume_comp.h') self.add_design_var('inputs_comp.h_cp', lower=1e-2, upper=10.) self.add_constraint('volume_comp.volume', equals=volume) self.add_objective('obj_sum.obj')
def setup(self): E = self.options['E'] L = self.options['L'] b = self.options['b'] volume = self.options['volume'] max_bending = self.options['max_bending'] num_elements = self.options['num_elements'] num_nodes = num_elements + 1 num_cp = self.options['num_cp'] num_load_cases = self.options['num_load_cases'] parallel_derivs = self.options['parallel_derivs'] inputs_comp = om.IndepVarComp() inputs_comp.add_output('h_cp', shape=num_cp) self.add_subsystem('inputs_comp', inputs_comp) comp = om.BsplinesComp(num_control_points=num_cp, num_points=num_elements, in_name='h_cp', out_name='h') self.add_subsystem('interp', comp) I_comp = MomentOfInertiaComp(num_elements=num_elements, b=b) self.add_subsystem('I_comp', I_comp) comp = LocalStiffnessMatrixComp(num_elements=num_elements, E=E, L=L) self.add_subsystem('local_stiffness_matrix_comp', comp) # Parallel Subsystem for load cases. par = self.add_subsystem('parallel', om.ParallelGroup()) # Determine how to split cases up over the available procs. nprocs = self.comm.size divide = divide_cases(num_load_cases, nprocs) for j, this_proc in enumerate(divide): num_rhs = len(this_proc) name = 'sub_%d' % j sub = par.add_subsystem(name, om.Group()) # Load is a sinusoidal distributed force of varying spatial frequency. force_vector = np.zeros((2 * num_nodes, num_rhs)) for i, k in enumerate(this_proc): end = 1.5 * np.pi if num_load_cases > 1: end += k * 0.5 * np.pi / (num_load_cases - 1) x = np.linspace(0, end, num_nodes) f = -np.sin(x) force_vector[0:-1:2, i] = f comp = MultiStatesComp(num_elements=num_elements, force_vector=force_vector, num_rhs=num_rhs) sub.add_subsystem('states_comp', comp) comp = MultiDisplacementsComp(num_elements=num_elements, num_rhs=num_rhs) sub.add_subsystem('displacements_comp', comp) comp = MultiStressComp(num_elements=num_elements, E=E, num_rhs=num_rhs) sub.add_subsystem('stress_comp', comp) self.connect('local_stiffness_matrix_comp.K_local', 'parallel.%s.states_comp.K_local' % name) for k in range(num_rhs): sub.connect('states_comp.d_%d' % k, 'displacements_comp.d_%d' % k) sub.connect('displacements_comp.displacements_%d' % k, 'stress_comp.displacements_%d' % k) comp = om.KSComp(width=num_elements) comp.options['upper'] = max_bending sub.add_subsystem('KS_%d' % k, comp) sub.connect('stress_comp.stress_%d' % k, 'KS_%d.g' % k) if parallel_derivs: color = 'red_%d' % k else: color = None sub.add_constraint('KS_%d.KS' % k, upper=0.0, parallel_deriv_color=color) comp = VolumeComp(num_elements=num_elements, b=b, L=L) self.add_subsystem('volume_comp', comp) self.connect('inputs_comp.h_cp', 'interp.h_cp') self.connect('interp.h', 'I_comp.h') self.connect('I_comp.I', 'local_stiffness_matrix_comp.I') self.connect('interp.h', 'volume_comp.h') self.add_design_var('inputs_comp.h_cp', lower=1e-2, upper=10.) self.add_objective('volume_comp.volume')