def test_spline_distribution_example(self): x_cp = np.linspace(0., 1., 6) y_cp = np.array([5.0, 12.0, 14.0, 16.0, 21.0, 29.0]) n = 20 x = sine_distribution(n, start=0.0, end=1.0, phase=np.pi) prob = om.Problem() comp = om.SplineComp(method='akima', x_cp_val=x_cp, x_interp_val=x) prob.model.add_subsystem('akima1', comp) comp.add_spline(y_cp_name='ycp', y_interp_name='y_val', y_cp_val=y_cp) prob.setup(force_alloc_complex=True) prob.run_model() assert_array_almost_equal( prob['akima1.y_val'], np.array([[ 5., 5.32381994, 6.28062691, 7.79410646, 9.64169506, 11.35166363, 12.26525921, 12.99152288, 13.77257256, 14.58710327, 15.41289673, 16.28341046, 17.96032258, 20.14140712, 22.31181718, 24.40891577, 26.27368825, 27.74068235, 28.67782484, 29. ]]))
def test_sin_distribution(self): calculated = np.array([0. , 0.03015369, 0.11697778, 0.25 , 0.41317591, 0.58682409, 0.75 , 0.88302222, 0.96984631, 1. ]) dist = sine_distribution(10) assert_array_almost_equal(calculated, dist) calculated = np.array([0.14644661, 0.21321178, 0.28869087, 0.37059048, 0.45642213, 0.54357787, 0.62940952, 0.71130913, 0.78678822, 0.85355339]) dist = sine_distribution(10, phase=np.pi/2.0) assert_array_almost_equal(calculated, dist)
def test_bsplines_2to3doc(self): from openmdao.utils.spline_distributions import sine_distribution prob = om.Problem() model = prob.model n_cp = 5 n_point = 10 t = np.linspace(0, 0.5 * np.pi, n_cp) x = np.empty((2, n_cp)) x[0, :] = np.sin(t) x[1, :] = 2.0 * np.sin(t) # In 2.x, the BsplinesComp had a built-in sinusoidal distribution. t_sin = sine_distribution(n_point) * np.pi * 0.5 bspline_options = {'order': 4} comp = om.SplineComp(method='bsplines', x_interp_val=t_sin, num_cp=n_cp, vec_size=2, interp_options=bspline_options) prob.model.add_subsystem('interp', comp) comp.add_spline(y_cp_name='h_cp', y_interp_name='h', y_cp_val=x, y_units='km') prob.setup() prob.run_model() xx = prob['interp.h'] with printoptions(precision=3, floatmode='fixed'): assert_near_equal( x[0, :], np.array([0., 0.38268343, 0.70710678, 0.92387953, 1.]), 1e-5) assert_near_equal( x[1, :], 2.0 * np.array([0., 0.38268343, 0.70710678, 0.92387953, 1.]), 1e-5) assert_near_equal( xx[0, :], np.array([ 0., 0.06687281, 0.23486869, 0.43286622, 0.6062628, 0.74821484, 0.86228902, 0.94134389, 0.98587725, 1. ]), 1e-5) assert_near_equal( xx[1, :], 2.0 * np.array([ 0., 0.06687281, 0.23486869, 0.43286622, 0.6062628, 0.74821484, 0.86228902, 0.94134389, 0.98587725, 1. ]), 1e-5)
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'] x_interp = sine_distribution(num_elements) comp = om.SplineComp(method='bsplines', num_cp=num_cp, x_interp_val=x_interp) comp.add_spline(y_cp_name='h_cp', y_interp_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 = 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, 'stress_comp.displacements_%d' % k, src_indices=np.arange(2 *num_nodes)) if parallel_derivs: color = 'red_%d' % k else: color = None comp = om.KSComp(width=num_elements, upper=max_bending, add_constraint=self.options['ks_add_constraint'], parallel_deriv_color=color) sub.add_subsystem('KS_%d' % k, comp) sub.connect('stress_comp.stress_%d' % k, 'KS_%d.g' % k) if not self.options['ks_add_constraint']: 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('interp.h', 'I_comp.h') self.connect('interp.h', 'volume_comp.h') self.connect('I_comp.I', 'local_stiffness_matrix_comp.I') self.add_design_var('interp.h_cp', lower=1e-2, upper=10.) self.add_objective('volume_comp.volume')
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) x_interp = sine_distribution(num_elements) comp = om.SplineComp(method='bsplines', num_cp=num_cp, x_interp_val=x_interp) comp.add_spline(y_cp_name='h_cp', y_interp_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 = 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, 'compliance_comp.displacements_%d' % k, src_indices=np.arange(2 * num_nodes)) 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')