def test_raises_uequal_shapes_circ(): with slippy.OverRideCuda(): im = e_im('zz', (128, 128), (0.01, 0.01), 200e9, 0.3) load_shapes = [(128, 129), (128, 129), (129, 128), (129, 128)] circulars = [True, (False, True), True, (True, False)] for l_s, circ in zip(load_shapes, circulars): with npt.assert_raises(AssertionError): loads = np.zeros(l_s) _ = c.plan_convolve(loads, im, circular=circ)
def test_hertz_agreement_static_load_fftw(): """ Test that the load controlled static step gives approximately the same answer as the analytical hertz solver """ try: import pyfftw # noqa: F401 except ImportError: warnings.warn( "Could not import pyfftw, could not test the fftw backend") return with slippy.OverRideCuda(): # make surfaces flat_surface = s.FlatSurface(shift=(0, 0)) round_surface = s.RoundSurface((1, 1, 1), extent=(0.006, 0.006), shape=(255, 255), generate=True) # set materials steel = c.Elastic('Steel', {'E': 200e9, 'v': 0.3}) aluminum = c.Elastic('Aluminum', {'E': 70e9, 'v': 0.33}) flat_surface.material = aluminum round_surface.material = steel # create model my_model = c.ContactModel('model-1', round_surface, flat_surface) # set model parameters total_load = 100 my_step = c.StaticStep('contact', normal_load=total_load) my_model.add_step(my_step) out = my_model.solve(skip_data_check=True) final_load = sum(out['loads'].z.flatten() * round_surface.grid_spacing**2) # check the converged load is the same as the set load npt.assert_approx_equal(final_load, total_load, 3) # get the analytical hertz result a_result = c.hertz_full([1, 1], [np.inf, np.inf], [200e9, 70e9], [0.3, 0.33], 100) # check max pressure npt.assert_approx_equal(a_result['max_pressure'], max(out['loads'].z.flatten()), 2) # check contact area found_area = round_surface.grid_spacing**2 * sum( out['contact_nodes'].flatten()) npt.assert_approx_equal(a_result['contact_area'], found_area, 2) # check deflection npt.assert_approx_equal(a_result['total_deflection'], out['interference'], 4)
def test_non_circ_convolve_vs_scipy(): with slippy.OverRideCuda(): for im_s, l_s in zip(im_shapes, loads_shapes): # generate an influence matrix, pick a component which is not symmetric! im = e_im('zx', im_s, (0.01, 0.01), 200e9, 0.3) loads = 1000 * np.random.rand(*l_s) scipy_result = fftconvolve(loads, im, mode='same') conv_func = c.plan_convolve(loads, im) slippy_result = conv_func(loads) err_msg = f'Non circular convolution did not match scipy output for loads shape: {l_s} and IM shape: {im_s}' npt.assert_allclose(slippy_result, scipy_result, err_msg=err_msg)
def test_hertz_agreement_static_interference_fftw(): try: import pyfftw # noqa: F401 slippy.CUDA = False except ImportError: warnings.warn( "Could not import pyfftw, could not test the fftw backend") return with slippy.OverRideCuda(): """Tests that the static normal interference step agrees with the analytical hertz solution""" flat_surface = s.FlatSurface(shift=(0, 0)) round_surface = s.RoundSurface((1, 1, 1), extent=(0.006, 0.006), shape=(255, 255), generate=True) # set materials steel = c.Elastic('Steel', {'E': 200e9, 'v': 0.3}) aluminum = c.Elastic('Aluminum', {'E': 70e9, 'v': 0.33}) flat_surface.material = aluminum round_surface.material = steel # create model my_model = c.ContactModel('model-1', round_surface, flat_surface) set_load = 100 a_result = c.hertz_full([1, 1], [np.inf, np.inf], [200e9, 70e9], [0.3, 0.33], set_load) my_step = c.StaticStep('step', interference=a_result['total_deflection']) my_model.add_step(my_step) final_state = my_model.solve() # check that the solution gives the set interference npt.assert_approx_equal(final_state['interference'], a_result['total_deflection']) # check that the load converged to the correct results num_total_load = round_surface.grid_spacing**2 * sum( final_state['loads'].z.flatten()) npt.assert_approx_equal(num_total_load, set_load, significant=4) # check that the max pressure is the same npt.assert_approx_equal(a_result['max_pressure'], max(final_state['loads'].z.flatten()), significant=2) # check that the contact area is in line with analytical solution npt.assert_approx_equal(a_result['contact_area'], round_surface.grid_spacing**2 * sum(final_state['contact_nodes'].flatten()), significant=2)
def test_dont_raise_equal_shapes_circ(): with slippy.OverRideCuda(): im = e_im('zz', (128, 128), (0.01, 0.01), 200e9, 0.3) load_shapes = [(128, 128), (128, 64), (64, 64), (64, 128)] circulars = [True, (True, False), False, (False, True)] for l_s, circ in zip(load_shapes, circulars): loads = np.zeros(l_s) try: _ = c.plan_convolve(loads, im, circular=circ) except: # noqa: E722 raise AssertionError( f"Plan convolve raised wrong error for mixed " f"convolution load shape: {l_s}, circ: {circ}")
def test_circ_convolve_location(): with slippy.OverRideCuda(): for im_s, l_s in zip(shapes_circ, shapes_circ): # generate an influence matrix, pick a component which is not symmetric! im = e_im('zz', im_s, (0.01, 0.01), 200e9, 0.3) loads = np.zeros(l_s) loads[64, 64] = 1000 conv_func = c.plan_convolve(loads, im, circular=True) slippy_result = conv_func(loads) loc_load = np.argmax(loads) loc_result = np.argmax(slippy_result) err_msg = f'Circular convolution, location of load dosn\'t match displacement' \ f'for loads shape: {l_s} and IM shape: {im_s} \n ' \ f'expected: {np.unravel_index(loc_load,l_s)}, found: {np.unravel_index(loc_result,l_s)}' assert loc_load == loc_result, err_msg
def test_mixed_convolve(): with slippy.OverRideCuda(): for circ in [[True, False], [False, True]]: im = e_im('zz', (128, 128), (0.01, 0.01), 200e9, 0.3) loads = np.zeros([128, 128]) loads[64, 64] = 1000 conv_func = c.plan_convolve(loads, im, circular=circ) slippy_result = conv_func(loads) loc_load = np.argmax(loads) loc_result = np.argmax(slippy_result) err_msg = f'Mixed circular convolution, location of load dosn\'t match displacement' \ f'for circular: {circ} \n ' \ f'expected: {np.unravel_index(loc_load, loads.shape)}, ' \ f'found: {np.unravel_index(loc_result, loads.shape)}' assert loc_load == loc_result, err_msg