def test_basic(self): prob = Problem() model = prob.model n_cp = 80 n_point = 160 t = np.linspace(0, 3.0 * np.pi, n_cp) x = np.sin(t) model.add_subsystem('px', IndepVarComp('x', val=x)) model.add_subsystem( 'interp', BsplinesComp(num_control_points=n_cp, num_points=n_point, in_name='h_cp', out_name='h', distribution='uniform')) model.connect('px.x', 'interp.h_cp') prob.setup(check=False) prob.run_model() xx = prob['interp.h'].flatten() tt = np.linspace(0, 3.0 * np.pi, n_point) x_expected = np.sin(tt) delta = xx - x_expected # Here we test that we don't have crazy interpolation error. self.assertLess(max(delta), .15) # And that it gets middle points a little better. self.assertLess(max(delta[15:-15]), .06)
def test_vectorized(self): import numpy as np from openmdao.api import Problem, IndepVarComp from openmdao.components.bsplines_comp import BsplinesComp from openmdao.utils.general_utils import printoptions prob = 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) model.add_subsystem('px', IndepVarComp('x', val=x)) model.add_subsystem( 'interp', BsplinesComp(num_control_points=n_cp, num_points=n_point, vec_size=2, in_name='h_cp', out_name='h')) model.connect('px.x', 'interp.h_cp') prob.setup(check=False) prob.run_model() xx = prob['interp.h'] with printoptions(precision=3, floatmode='fixed'): self.assertEqual('Control Points:', 'Control Points:') assert_rel_error( self, x[0, :], np.array([0., 0.38268343, 0.70710678, 0.92387953, 1.]), 1e-5) assert_rel_error( self, x[1, :], 2.0 * np.array([0., 0.38268343, 0.70710678, 0.92387953, 1.]), 1e-5) self.assertEqual('Output Points:', 'Output Points:') assert_rel_error( self, 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_rel_error( self, 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 test_units(self): n_cp = 5 n_point = 10 interp = BsplinesComp(num_control_points=n_cp, num_points=n_point, in_name='h_cp', out_name='h', units='inch') prob = Problem(model=interp) prob.setup(check=False) prob.run_model() # verify that both input and output of the bsplines comp have proper units inputs = interp.list_inputs(units=True, out_stream=None) self.assertEqual(len(inputs), 1) for var, meta in inputs: self.assertEqual(meta['units'], 'inch') outputs = interp.list_outputs(units=True, out_stream=None) self.assertEqual(len(outputs), 1) for var, meta in outputs: self.assertEqual(meta['units'], 'inch')
def test_vectorized(self): prob = 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) model.add_subsystem('px', IndepVarComp('x', val=x)) model.add_subsystem( 'interp', BsplinesComp(num_control_points=n_cp, num_points=n_point, vec_size=2, in_name='h_cp', out_name='h')) model.connect('px.x', 'interp.h_cp') prob.setup(check=False) prob.run_model() xx = prob['interp.h'] self.assertEqual('Control Points', 'Control Points') assert_rel_error( self, x[0, :], np.array([0., 0.38268343, 0.70710678, 0.92387953, 1.]), 1e-5) assert_rel_error( self, x[1, :], 2.0 * np.array([0., 0.38268343, 0.70710678, 0.92387953, 1.]), 1e-5) self.assertEqual('Output Points', 'Output Points') assert_rel_error( self, 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_rel_error( self, 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 test_distribution_sine(self): prob = Problem() model = prob.model n_cp = 20 n_point = 100 tvec = np.linspace(0, 1.0, n_cp) t = 3.0 * np.pi * 0.5 * (1.0 + np.sin(-0.5 * np.pi + tvec * np.pi)) x = np.sin(t) model.add_subsystem('px', IndepVarComp('x', val=x)) model.add_subsystem( 'interp', BsplinesComp(num_control_points=n_cp, num_points=n_point, in_name='h_cp', out_name='h', distribution='sine')) model.connect('px.x', 'interp.h_cp') prob.setup(check=False) prob.run_model() xx = prob['interp.h'].flatten() ttvec = np.linspace(0, 1.0, n_point) tt = 3.0 * np.pi * 0.5 * (1.0 + np.sin(-0.5 * np.pi + ttvec * np.pi)) x_expected = np.sin(tt) delta = xx - x_expected import matplotlib.pyplot as plt plt.figure(1) plt.plot(tt, xx, "b") plt.plot(t, x, "ro") plt.xlabel("Distance along Beam") plt.ylabel('Design Variable') plt.title("Sine Distribution of Control Points") plt.legend(['Variable', 'Control Points'], loc=4) plt.grid(True) plt.show() assert_rel_error(self, xx[10], 0.09568950, 1e-4)
def test_distribution_uniform(self): from openmdao.api import Problem, IndepVarComp from openmdao.components.bsplines_comp import BsplinesComp prob = Problem() model = prob.model n_cp = 20 n_point = 100 t = np.linspace(0, 3.0 * np.pi, n_cp) x = np.sin(t) model.add_subsystem('px', IndepVarComp('x', val=x)) model.add_subsystem( 'interp', BsplinesComp(num_control_points=n_cp, num_points=n_point, in_name='h_cp', out_name='h', distribution='uniform')) model.connect('px.x', 'interp.h_cp') prob.setup(check=False) prob.run_model() xx = prob['interp.h'].flatten() tt = np.linspace(0, 3.0 * np.pi, n_point) import matplotlib.pyplot as plt plt.plot(tt, xx) plt.plot(t, x, "ro") plt.xlabel("Distance along Beam") plt.ylabel('Design Variable') plt.title("Uniform Distribution of Control Points") plt.legend(['Variable', 'Control Points'], loc=4) plt.grid(True) plt.show()
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 = IndepVarComp() inputs_comp.add_output('h_cp', shape=num_cp) self.add_subsystem('inputs_comp', inputs_comp) comp = 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) comp = GlobalStiffnessMatrixComp(num_elements=num_elements) self.add_subsystem('global_stiffness_matrix_comp', comp) # Parallel Subsystem for load cases. par = self.add_subsystem('parallel', 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, 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('global_stiffness_matrix_comp.K', 'parallel.%s.states_comp.K' % 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 = 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('local_stiffness_matrix_comp.K_local', 'global_stiffness_matrix_comp.K_local') 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 = IndepVarComp() inputs_comp.add_output('h_cp', shape=num_cp) self.add_subsystem('inputs_comp', inputs_comp) comp = 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', 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, 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 = 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')
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 = IndepVarComp() inputs_comp.add_output('h_cp', shape=num_cp) self.add_subsystem('inputs_comp', inputs_comp) comp = 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', 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, 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 = 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')