def calc_kinematics(self, rot_vel1, rot_vel2, ui=None, res_dir=None): """Calculate bearing kinematics based on rotational velocities of contact bodies""" print_it("calculating kinematics") self.rot_vel1 = rot_vel1 self.rot_vel2 = rot_vel2 self.ring1.omega = rot_vel1 / 60 self.ring2.omega = rot_vel2 / 60 self.eff_rot_vel = self.rot_vel1 - self.rot_vel2 self.eff_omega = self.eff_rot_vel / 60 self.eff_omega_cage = self.eff_omega / 2 self.ring1.eff_raceway_vel = self.ring1.diameter * math.pi * \ self.eff_omega self.ring2.eff_raceway_vel = 0 self.eff_vel_cage = (self.ring1.eff_raceway_vel + self.ring2.eff_raceway_vel) / 2 self.roller.eff_raceway_vel = \ math.pi * self.roller.diameter * ( self.mean_diameter / self.roller.diameter) * self.eff_omega / 2 self.roller.actual_raceway_vel = np.zeros( (self.res_pol, self.roller.res_x)) self.roller.rel_vel = np.zeros((self.res_pol, self.roller.res_x)) if self.path_roller_slip is None: self.roller.actual_raceway_vel[:, :] = self.roller.eff_raceway_vel else: self.calc_slip_data() self.calc_overroll_times()
def calc_e_akin(self, ui=None, res_dir=None): """"Calculate the kinetic friction energy accumulation in W per m^2""" print_it("calculating e_a,kin") pv_local = np.multiply(self.rot_ball.press.sum(1), self.rel_vel) self.e_akin = np.absolute( np.divide(np.multiply(pv_local, self.overroll_t_incr), self.no_overroll_t)) / 1000
def calc_e_akin(self, ui=None, res_dir=None): """"Calculate the kinetic friction energy accumulation in W per m^2""" print_it("calculating e_a,kin") pv_loc_ring1 = np.multiply(self.ring1.press_pol.sum(1), self.roller.rel_vel.transpose()) pv_loc_ring2 = np.multiply(self.ring2.press_pol.sum(1), self.roller.rel_vel.transpose()) if self.rot_vel2 == 0: self.ring2.e_akin = np.absolute( np.divide( np.multiply(pv_loc_ring2, self.ring2.overroll_t_incr), self.ring2.no_overroll_t)) / 1000 else: self.ring2.e_akin = np.absolute( np.divide( np.multiply(pv_loc_ring2.sum(1), self.ring2.overroll_t_incr), self.ring2.no_overroll_t.sum(1))) / 1000 if self.rot_vel1 == 0: self.ring1.e_akin = np.absolute( np.divide( np.multiply(pv_loc_ring1, self.ring2.overroll_t_incr), self.ring1.no_overroll_t)) / 1000 else: self.ring1.e_akin = np.absolute( np.divide( np.multiply(pv_loc_ring1.sum(1), self.ring1.overroll_t_incr), self.ring1.no_overroll_t.sum(1))) / 1000
def calc_load_distribution(self, ui=None, res_dir=None): """Calculate load distribution""" print_it("calculating 1 load distribution") self.roller.norm_forces = \ np.multiply(np.ones(self.num_rollers), self.global_force / self.num_rollers) self.uniq_norm_forces = self.roller.norm_forces[0]
def plot_it(self, ui=None, res_dir=None): """Orchestrate output plot generation""" print_it("plotting results") plt_profiles(res_dir) print_it("plotting other", PrintOpts.lvl1.value) plt_contact(self.pin, self.disk, PltOpts.DD.value, res_dir, SubDir.contacts.value) plt_contact(self.pin, self.disk, PltOpts.DDD.value, res_dir, SubDir.contacts.value) plt_3d(self.pin.x_axis, self.pin.y_axis, self.pin.press, self.pin.x_label, self.pin.y_label, 'pressure in MPa', 'contact_pressure_pin', res_dir, SubDir.pressures.value, 'contact_pressure') plt_2d(self.pin.x_axis, self.pin.rel_vel, self.pin.x_label, 'rel vel', 'rel vel', res_dir, SubDir.energy.value, 'rel_vel') plt_2d(self.pin.x_axis, self.pv, self.pin.x_label, 'pv_rel in {}'.format(Unit.pvrel.value), 'pv_rel', res_dir, SubDir.energy.value, 'pv_rel') plt_2d_scatt_line(self.pin.x_axis, self.e_akin, self.pin.x_axis, self.e_akin, self.pin.x_label, 'e_akin in W $m^{-2}$', 'e_akin', res_dir, SubDir.energy.value, 'e_akin') plt_2d_2y_ax(self.pin.x_axis, self.e_akin, self.pin.x_axis, self.pv, self.pin.x_label, 'e_akin vs pv_rel', 'e_akin in {}'.format(Unit.eakin.value), 'pv_rel in {}'.format(Unit.eakin.value), res_dir, SubDir.energy.value, 'e_akin_vs_pv_rel') plt_cum_dist(self.pin.press, 'pressure in {}'.format(Unit.press.value), res_dir, SubDir.pressures.value, 'cumulative pressure distribution')
def plot_it(self, ui=None, res_dir=None): """Orchestrate output plot generation""" print_it("plotting results and finishing up") plt_profile(self.ball, PltOpts.DD.value, res_dir, SubDir.profiles.value) plt_profile(self.ball, PltOpts.DDD.value, res_dir, SubDir.profiles.value) plt_profile(self.plate, PltOpts.DD.value, res_dir, SubDir.profiles.value) plt_profile(self.plate, PltOpts.DDD.value, res_dir, SubDir.profiles.value) plt_profile_approx(res_dir, SubDir.profiles.value) plt_contact(self.ball, self.plate, PltOpts.DD.value, res_dir, SubDir.contacts.value) plt_contact(self.ball, self.plate, PltOpts.DDD.value, res_dir, SubDir.contacts.value) plt_3d(self.ball.x_axis, self.ball.y_axis, self.ball.press, self.ball.x_label, self.ball.y_label, 'pressure in MPa', 'contact pressure', res_dir, SubDir.pressures.value, 'contact-pressure') plt_2d(self.ball.x_axis, self.pv, self.ball.x_label, 'pv_rel in {}'.format(Unit.pvrel.value), 'pv_rel', res_dir, SubDir.energy.value, 'pv_rel') plt_2d_scatt_line(self.ball.x_axis, self.e_akin, self.ball.x_axis, self.e_akin, self.ball.x_label, 'e_akin in {}'.format(Unit.eakin.value), 'e_akin', res_dir, SubDir.energy.value, 'e_akin') plt_2d_2y_ax(self.ball.x_axis, self.e_akin, self.ball.x_axis, self.pv, self.ball.x_label, 'e_akin vs pv_rel', 'e_akin in {}'.format(Unit.eakin.value), 'pv_rel in {}'.format(Unit.pvrel.value), res_dir, SubDir.energy.value, 'e_akin_vs_pv_rel')
def plot_it(self, ui=None, res_dir=None): """Orchestrate output plot generation""" print_it("plotting results") plt_profile(self.sun, PltOpts.DD.value, res_dir, SubDir.profiles.value) plt_profile(self.sun, PltOpts.DDD.value, res_dir, SubDir.profiles.value) plt_profile(self.planet, PltOpts.DD.value, res_dir, SubDir.profiles.value) plt_profile(self.planet, PltOpts.DDD.value, res_dir, SubDir.profiles.value) plt_profile_approx(res_dir, SubDir.profiles.value) plt_contact(self.sun, self.planet, PltOpts.DD.value, res_dir, SubDir.contacts.value) plt_contact(self.sun, self.planet, PltOpts.DDD.value, res_dir, SubDir.contacts.value) plt_3d(self.sun.x_axis, self.sun.y_axis, self.sun.press, self.sun.x_label, self.sun.y_label, 'pressure in MPa', 'contact_pressure_sun', res_dir, SubDir.pressures.value, 'contact_pressure_sun') plt_2d_scatt_line(self.sun.x_axis, self.pv, self.sun.x_axis, self.pv, self.sun.x_label, 'pv_rel in {}'.format(Unit.pvrel.value), 'pv_rel', res_dir, SubDir.energy.value, 'pv_rel') plt_2d_scatt_line(self.sun.x_axis, self.sun.e_akin, self.sun.x_axis, self.sun.e_akin, self.sun.x_label, 'e_akin in {}'.format(Unit.eakin.value), 'e_akin', res_dir, SubDir.energy.value, 'sun.e_akin') plt_2d_scatt_line(self.planet.x_axis, self.planet.e_akin, self.planet.x_axis, self.planet.e_akin, self.planet.x_label, 'e_akin in {}'.format(Unit.eakin.value), 'e_akin', res_dir, SubDir.energy.value, 'planet.e_akin') plt_energy_ring_on_ring(self, res_dir, SubDir.energy.value, 'e-akin-vs-pv-rel')
def plt_profiles(res_dir): """plot profiles of all contact bodies using python's garbage collector to find all objects of type ContactBody""" print_it("plotting profiles", PrintOpts.lvl1.value) num_cbs = list(isinstance(obj, ContactBody) for obj in gc.get_objects()).count(True) counter = 0 for body in gc.get_objects(): if isinstance(body, ContactBody): if body.type_profile == "File": fname = "profile-approximation-{}".format(body.name) plt_2d_scatt_line(body.file_x_axis, body.file_x_profile, body.x_axis, body.x_profile, body.x_label, body.z_label, fname, res_dir, SubDir.profiles.value, fname) if body.roughness_mat is not None: fname = "surface-roughness-{}".format(body.name) plt_3d(body.x_axis, body.y_axis, body.roughness_mat, body.x_label, body.y_label, 'roughness height in mm', 'surface roughness {}'.format(body.name), res_dir, sub_dir=SubDir.profiles.value, fname=fname) plt_profile(body, PltOpts.DD.value, res_dir, SubDir.profiles.value) plt_profile(body, PltOpts.DDD.value, res_dir, SubDir.profiles.value) counter = print_progress(counter, num_cbs)
def calc_load_distribution(self, ui=None, res_dir=None): """Calculate load distribution""" print_it("calculating load distribution") self.init_force = self.global_force / 3 / math.cos( self.plate_angle / 2) self.ball.norm_forces = np.ones(3) * self.init_force self.sliding_diam = 2 * self.ball.diameter / 2 * math.sin( (math.pi - self.plate_angle) / 2)
def plot_it(self, ui=None, res_dir=None): """Orchestrate output plot generation""" print_it("plotting results and finishing up") self.plt_profiles_and_contacts(res_dir) self.plt_pol_slip(res_dir) self.plt_pres(res_dir) self.plt_pv(res_dir) self.plt_eakin(res_dir)
def calc_pv(self, ui=None, res_dir=None): """Calculate product of local maximum pressure and local maximum relative velocity""" print_it("calculating pv_rel") self.pv = np.multiply(abs(self.rel_vel), self.sun.max_press) / 1000 dat_dict = dict(x_axis=self.sun.x_axis, pv_rel=self.pv) save_to_matlab(dat_dict, res_dir, 'pv-rel')
def plt_eakin(self, res_dir): """Plot kinetic friction energy accumulation""" print_it("plotting energy figures", PrintOpts.lvl1.value) # e_a,kin plt_ax_pol = np.linspace(-math.pi, math.pi - 2 * math.pi / self.res_pol, int(self.res_pol)) if self.rot_vel1 == 0: plot_data = np.concatenate( (self.ring1.e_akin.transpose()[round(self.res_pol / 2) - 1:-1, :], self.ring1.e_akin.transpose()[0:round(self.res_pol / 2), :]), axis=0) plt_3d(plt_ax_pol, self.roller.x_axis, plot_data, 'polar ring coordinate', 'roller length in mm', 'e_a,kin in {}'.format(Unit.eakin.value), 'e_a,kin inner ring', res_dir, SubDir.energy.value, 'e-a-kin-inner-ring', None, PltOpts.azim.value) polplt_line(plt_ax_pol, plot_data[:, round(self.roller.res_x / 2) - 1], 'e_a,kin_rel max in {}'.format(Unit.eakin.value), 'e_a,kin max inner ring', res_dir, SubDir.energy.value, 'max-e-a-kin-inner-ring') else: plt_2d_scatt_line(self.roller.x_axis, self.ring1.e_akin, self.roller.x_axis, self.ring1.e_akin, self.roller.x_label, 'average e_a,kin in {}'.format(Unit.eakin.value), 'average e_a,kin inner ring', res_dir, SubDir.energy.value, 'average-e-a-kin-inner-ring') if self.rot_vel2 == 0: plot_data = np.concatenate( (self.ring2.e_akin.transpose()[round(self.res_pol / 2) - 1:-1, :], self.ring2.e_akin.transpose()[0:round(self.res_pol / 2), :]), axis=0) plt_3d(plt_ax_pol, self.roller.x_axis, plot_data, 'polar ring coordinate', 'roller length in mm', 'e_a,kin in {}'.format(Unit.eakin.value), 'e_a,kin outer ring', res_dir, SubDir.energy.value, 'e-a-kin-outer-ring', None, PltOpts.azim.value) polplt_line(plt_ax_pol, plot_data[:, round(self.roller.res_x / 2) - 1], 'e_a,kin_rel max in {}'.format(Unit.eakin.value), 'e_a,kin max outer ring', res_dir, SubDir.energy.value, 'max-e-a-kin-outer-ring') else: plt_2d_scatt_line(self.roller.x_axis, self.ring2.e_akin, self.roller.x_axis, self.ring2.e_akin, self.roller.x_label, 'average e_a,kin in {}'.format(Unit.eakin.value), 'average e_a,kin outer ring', res_dir, SubDir.energy.value, 'average-e-a-kin-outer-ring')
def get_grid_size(self, ui=None, res_dir=None): """Determine grid size by running (quick) simulation with simplified contact bodies""" print_it('determining grid size', PrintOpts.lvl1.value) self.pin.simple_clone() self.pin.clone.make_profile(PreSol.res_x.value, PreSol.res_y.value, self.init_force) self.disk.simple_clone() self.disk.clone.make_slave_to(self.pin.clone) init_displ = hertz_displ( self.pin.clone.e, self.disk.clone.e, self.pin.clone.ny, self.disk.clone.ny, self.pin.clone.r_hertz_x, self.pin.clone.r_hertz_y, self.disk.clone.r_hertz_x, self.disk.clone.r_hertz_y, self.norm_forces[0]) contact_delta = 1 contact_width = 0.025 while contact_delta != 0: if type(self.pin).__name__ == "Ring": self.pin.clone.make_profile(self.pin.clone.res_x, self.pin.clone.res_y, self.init_force, contact_width=contact_width) elif type(self.pin).__name__ == "Ball": self.pin.clone.make_profile(PreSol.res_x.value, PreSol.res_y.value, self.init_force, contact_width=contact_width) self.disk.make_slave_to(self.pin) pressure, init_displ = \ pre_solve_half_space(self.pin.clone.profile, self.disk.clone.profile, self.pin.clone.x_axis, self.pin.clone.y_axis, self.pin.clone.res_x, self.pin.clone.res_y, self.pin.clone.delta_x, self.pin.clone.delta_y, self.pin.clone.e, self.disk.clone.e, self.pin.clone.ny, self.disk.clone.ny, self.norm_forces[0], init_displ=init_displ) pressure_elements = sum( pressure[math.floor(self.pin.clone.res_y / 2), :] > 0) contact_delta = pressure_elements + 2 - self.pin.clone.res_y contact_width += np.sign(contact_delta) * contact_width / 25 if type(self.pin).__name__ == "Ring": self.pin.make_profile(self.pin.res_x, self.pin.res_y, self.init_force, contact_width=contact_width) elif type(self.pin).__name__ == "Ball": self.pin.make_profile(self.pin.res_x, self.pin.res_y, self.init_force, contact_width=contact_width) self.disk.make_slave_to(self.pin) return init_displ
def get_grid_size(self, ui, res_dir, uniq_norm_force): """Determine grid size by running (quick) simulation with simplified contact bodies. Calculate pressure only for contact between outer ring and roller since the contact area will be larger than for the case of inner ring and roller.""" print_it('determining grid size', PrintOpts.lvl1.value) self.roller.simple_clone() self.roller.clone.make_profile(PreSol.res_x.value, PreSol.res_y.value, self.init_force) self.ring2.simple_clone() self.ring2.clone.make_slave_to(self.roller.clone) init_displ = hertz_displ(self.roller.clone.e, self.ring2.clone.e, self.roller.clone.ny, self.ring2.clone.ny, self.roller.clone.r_hertz_x, self.roller.clone.r_hertz_y, self.ring2.clone.r_hertz_x, self.ring2.clone.r_hertz_y, uniq_norm_force) too_many_elements_in_contact = 1 contact_width = 0.05 while too_many_elements_in_contact != 0: self.roller.clone.make_profile(self.roller.clone.res_x, self.roller.clone.res_y, self.init_force, contact_width=contact_width) self.ring2.clone.make_slave_to(self.roller.clone) pressure, init_displ = \ pre_solve_half_space(self.roller.clone.profile, self.ring2.clone.profile, self.roller.clone.x_axis, self.roller.clone.y_axis, self.roller.clone.res_x, self.roller.clone.res_y, self.roller.clone.delta_x, self.roller.clone.delta_y, self.roller.clone.e, self.ring2.clone.e, self.roller.clone.ny, self.ring2.clone.ny, uniq_norm_force, init_displ=init_displ, print_prog=False) pressure_elements = sum( pressure[math.floor(self.roller.clone.res_y / 2), :] > 0) too_many_elements_in_contact = self.roller.clone.res_y - \ pressure_elements - 2 contact_width += -np.sign( too_many_elements_in_contact) * contact_width / 25 self.roller.make_profile(self.roller.res_x, self.roller.res_y, self.init_force, contact_width=contact_width) self.ring1.make_slave_to(self.roller) self.ring2.make_slave_to(self.roller) return init_displ
def calc_load_distribution(self, ui=None, res_dir=None): """Calculate load distribution""" print_it("calculating load distribution") r1 = self.rot_ball.diameter / 2 r2 = self.stat_ball.diameter / 2 r_circum_circle = math.sqrt(3) / 3 * 2 * r2 contact_angle = math.acos(r_circum_circle / (r1 + r2)) lever_arm = r_circum_circle - r2 * math.cos(contact_angle) self.sliding_diam = 2 * lever_arm self.init_force = self.global_force / math.sin(contact_angle) / 3 self.rot_ball.norm_forces = np.ones(3) * self.init_force
def plt_profiles_contacts(self, res_dir): """Generate plots of profiles and contacts""" print_it("plotting contacts", PrintOpts.lvl1.value) plt_contact(self.roller, self.ring1, PltOpts.DD.value, res_dir, SubDir.contacts.value) plt_contact(self.roller, self.ring1, PltOpts.DDD.value, res_dir, SubDir.contacts.value) plt_contact(self.roller, self.ring2, PltOpts.DD.value, res_dir, SubDir.contacts.value) plt_contact(self.roller, self.ring2, PltOpts.DDD.value, res_dir, SubDir.contacts.value)
def plot_it(self, ui=None, res_dir=None): """Orchestrate output plot generation""" print_it("plotting results and finishing up") plt_profiles(res_dir) self.plt_profiles_contacts(res_dir) self.plt_pol_slip(res_dir) self.plt_load_distr(res_dir) self.plt_pres(res_dir) self.plt_pv(res_dir) self.plt_eakin(res_dir) self.generate_summary_figure(res_dir)
def manage_influ_mat_cache(res_dir): """Check if the influence matrix cache size exceeds the size limit. If yes, remove oldest influence matrix files from cache until size limit is no longer exceeded""" print_it('clearing influence matrix cache') infl_mat_folder = os.sep.join( [os.path.dirname(res_dir), SubDir.infl_mat_db_folder.value]) infl_data_dict_path = os.sep.join( [infl_mat_folder, NpDBs.infl_mat_db.value]) size_cache = 0 deletable_files = [] # get size of cache for f in sorted(glob.iglob('{}{}*'.format(infl_mat_folder, os.sep)), key=os.path.getctime): size_cache += os.path.getsize(f) if f != os.sep.join([infl_mat_folder, NpDBs.infl_mat_db.value]): deletable_files.extend(f) counter = 0 # remove file from cache if cache size limit is exceeded if size_cache / 1024 ** 2 < NpDBs.max_cache_size.value: print_it('cache size smaller than cache size limit ({} MB)'.format( NpDBs.max_cache_size.value), PrintOpts.lvl1.value) print_it('nothing to clear'.format(NpDBs.max_cache_size.value), PrintOpts.lvl1.value) else: print_it('cache size larger than cache size limit ({} MB)'.format( NpDBs.max_cache_size.value), PrintOpts.lvl1.value) while size_cache / 1024 ** 2 > NpDBs.max_cache_size.value: print_it( 'deleting influence matrix {}'.format(deletable_files[counter]), PrintOpts.lvl1.value) os.remove(str(deletable_files[counter])) with open(infl_data_dict_path, 'rb') as handle: infl_data_dict = pickle.load(handle) del infl_data_dict[os.path.basename(str(deletable_files[counter]))] with open(infl_data_dict_path, 'wb') as handle: pickle.dump(infl_data_dict, handle, protocol=pickle.HIGHEST_PROTOCOL) size_cache = 0 for f in sorted(glob.iglob('{}{}*'.format(infl_mat_folder, os.sep)), key=os.path.getctime): size_cache += os.path.getsize(f) if f != NpDBs.infl_mat_db.value: deletable_files.append(f) counter += 1
def calc_load_distribution(self, ui=None, res_dir=None): """Calculate the load distribution for all roller positions by calling the function 'load_distr_cyl_rol_bear' while changing the polar position of the rollers with respect to the inner/outer ring""" print_it('calculating {} load distributions'.format( self.num_roller_pos)) # initialise variables count = 0 x_profile = abs(self.roller.x_profile + self.ring1.x_profile) self.roller_norm_forces = np.zeros( (self.num_roller_pos, self.num_rollers)) self.roller_norm_displ = np.zeros( (self.num_roller_pos, self.num_rollers)) # get all load distributions for all roller positions for roller_pos in range(self.num_roller_pos): self.roller_norm_forces[roller_pos, :], self.roller_norm_displ[ roller_pos, :] = \ load_distr_cyl_rol_bear(self.phi_mat[roller_pos, :], self.num_rollers, self.roller.length, self.roller.res_x, x_profile, self.roller.x_axis, self.rad_clear, self.init_force) count = print_progress(count, self.num_roller_pos) self.normal_forces = np.transpose(self.roller_norm_forces).reshape( (self.roller_norm_forces.size, 1)) self.norm_displ = np.transpose(self.roller_norm_displ).reshape( (self.roller_norm_displ.size, 1)) # get unique normal forces and unique normal displacements self.uniq_norm_forces, self.uniq_force_idx = np.unique( np.round(self.roller_norm_forces), return_inverse=True) uniq_norm_displ = np.zeros(len(self.uniq_norm_forces)) for i in range(len(self.uniq_norm_forces)): uniq_norm_displ[i] = np.mean( self.norm_displ[self.uniq_force_idx == i]) self.uniq_norm_displ = sorted(np.absolute(uniq_norm_displ) / 10) # save load distribution data to matlab database dat_dict = { 'roller_positions': self.num_roller_pos, 'rollers': self.num_rollers, 'roller_normal_forces': self.roller_norm_forces, 'uniq_norm_forces': self.uniq_norm_forces, 'normal_forces': self.normal_forces, 'polar_coordinates': self.phi_mat } save_to_matlab(dat_dict, res_dir, 'load-distribution')
def calc_pv(self, ui=None, res_dir=None): """Calculate product of local maximum pressure and local maximum relative velocity""" print_it("calculating pv_rel") self.ring1.pv = np.absolute( np.multiply(self.ring1.max_press, self.roller.rel_vel) / 1000) self.ring2.pv = np.absolute( np.multiply(self.ring2.max_press, self.roller.rel_vel) / 1000) dat_dict = dict(x_axis=self.roller.x_axis, pv_rel_ir_3d=self.ring1.pv, pv_rel_ir_2d=np.amax(self.ring1.pv, axis=1), pv_rel_or_3d=self.ring2.pv, pv_rel_or_2d=np.amax(self.ring2.pv, axis=1), axis_pol=self.pol_ax) save_to_matlab(dat_dict, res_dir, 'pv_rel_ring2')
def calc_kinematics(self, rot_vel1, rot_vel2, ui=None, res_dir=None): """Calculate bearing kinematics based on rotational velocities of rotating balls""" print_it("calculating kinematics") self.effective_omega = rot_vel1 / 60 self.raceway_vel = self.effective_omega * self.sliding_diam # neglecting sliding speed differences along ball contact area self.rel_vel = np.ones(self.rot_ball.res_x) * self.raceway_vel self.footpr_vel = self.raceway_vel self.overroll_t_incr = np.divide(self.rot_ball.delta_y, self.footpr_vel) self.press_zone_len = (self.rot_ball.press > 0).sum( 1) * self.rot_ball.delta_y self.overroll_t = np.divide(self.press_zone_len, self.footpr_vel) self.no_overroll_t = np.divide((2 * math.pi * ( self.sliding_diam / 2) - 3 * self.press_zone_len) / 3, self.footpr_vel)
def calc_kinematics(self, rot_vel1, rot_vel2, ui=None, res_dir=None): """Calculate bearing kinematics based on rotational velocity of disk""" print_it("calculating kinematics") self.rot_vel1 = rot_vel1 self.effective_rot_velocity = self.rot_vel1 self.effective_omega = self.effective_rot_velocity / 60 self.pin.rel_vel = np.add(-self.pin.x_axis, self.sliding_diameter) * \ math.pi * self.effective_omega self.press_zone_len = (self.pin.press > 0).sum(1) * self.pin.delta_y self.footpr_vel = self.pin.rel_vel self.overroll_t_incr = self.pin.delta_y / self.footpr_vel self.overroll_t = np.divide(self.press_zone_len, self.footpr_vel) self.no_overroll_t = np.divide( (2 * math.pi * (self.sliding_diameter / 2) - self.num_pins * self.press_zone_len) / self.num_pins, self.footpr_vel)
def calc_contact_pressure(self, ui=None, res_dir=None): """Calculate contact pressure distribution between pin and disk""" print_it('calculating 1 pressure distribution') init_displ = self.get_grid_size(ui, res_dir) [self.influ_mat_db_1] = load_influ_mat(ui, res_dir, 1) print_it('solving first half space', PrintOpts.lvl1.value) self.pin.press, self.influ_mat_db_1 = \ solve_half_space(self.pin.profile, self.disk.profile, self.pin.x_axis, self.pin.y_axis, self.pin.res_x, self.pin.res_y, self.pin.delta_x, self.pin.delta_y, self.pin.e, self.disk.e, self.pin.ny, self.disk.ny, self.norm_forces[0], res_dir, init_displ=init_displ, influ_mat_db=self.influ_mat_db_1) cache_influ_mat(ui, [self.influ_mat_db_1], res_dir) self.pin.max_press = np.amax(self.pin.press, axis=1) self.save_pressure_to_matlab(res_dir)
def check_lapack(): """Check if BLAS/LAPACK distribution is installed""" import numpy as np if not np.__config__.lapack_opt_info or not np.__config__.blas_opt_info: print_it( 'could not find BLAS/LAPACK install\n' 'install BLAS/LAPACK to improve p3can performance', PrintOpts.lvl1.value) print_it('did not check for ATLAS', PrintOpts.lvl1.value) else: print_it('found BLAS/LAPACK install', PrintOpts.lvl1.value) print_it('did not check for ATLAS', PrintOpts.lvl1.value)
def load_influ_mat(ui, res_dir, number_matrices): """Load cached influence matrix and copy it to the current results folder""" infl_mat_folder = os.sep.join( [os.path.dirname(res_dir), SubDir.infl_mat_db_folder.value]) infl_data_dict_path = os.sep.join( [infl_mat_folder, NpDBs.infl_mat_db.value]) with open(infl_data_dict_path, 'rb') as handle: infl_data_dict = pickle.load(handle) key_list = number_matrices * ['empty'] for i in range(number_matrices): for key, value in infl_data_dict.items(): if '{}{}'.format(ui['parameter_id'], i * '-') == value: print_it("loading cached influence matrix '{}'".format(key), PrintOpts.lvl1.value) make_directory(res_dir, SubDir.np_db.value) shutil.copy(os.sep.join([infl_mat_folder, key]), os.sep.join([res_dir, SubDir.np_db.value, key])) key_list[i] = key return key_list
def calc_polar_coordinates(self): """Set-up a polar coordinate system for the inner/outer ring""" if (self.res_pol % self.num_rollers) is not 0: self.res_pol = int( math.ceil(self.res_pol / self.num_rollers) * self.num_rollers) print_it( "polar resolution ('res_pol') changed to {}".format( self.res_pol), PrintOpts.lvl1.value) self.pol_ax = np.linspace(0, 2 * math.pi - 2 * math.pi / self.res_pol, self.res_pol) self.num_roller_pos = int(self.res_pol / self.num_rollers) self.d_phi = 2 * math.pi / self.num_rollers self.dd_phi = 2 * math.pi / self.res_pol self.phi_mat = np.zeros((self.num_roller_pos, self.num_rollers)) for i in range(self.num_roller_pos): self.phi_mat[i, :] = np.linspace( i * self.dd_phi, 2 * math.pi - self.d_phi + i * self.dd_phi, self.num_rollers)
def calc_contact_pressure(self, ui=None, res_dir=None): """Calculate contact pressure distribution between washer(s) and roller""" print_it('calculating 1 pressure distribution') init_displ = self.get_grid_size(ui, res_dir) [self.influ_mat_db_1] = load_influ_mat(ui, res_dir, 1) print_it('solving first half space', PrintOpts.lvl1.value) self.roller.press, self.influ_mat_db_1 = \ solve_half_space(self.roller.profile, self.ring1.profile, self.roller.x_axis, self.roller.y_axis, self.roller.res_x, self.roller.res_y, self.roller.delta_x, self.roller.delta_y, self.roller.e, self.ring1.e, self.roller.ny, self.ring1.ny, self.roller.norm_forces[0], res_dir, init_displ=init_displ, influ_mat_db=self.influ_mat_db_1) self.roller.max_press = np.amax(self.roller.press, axis=1) self.ring1.press = copy.copy(self.roller.press) self.ring1.max_press = copy.copy(self.roller.max_press) cache_influ_mat(ui, [self.influ_mat_db_1], res_dir)
def calc_kinematics(self, rot_vel1, rot_vel2, ui=None, res_dir=None): """Calculate bearing kinematics based on rotational velocities of washer disks""" print_it("calculating kinematics") self.rot_vel1 = rot_vel1 self.rot_vel2 = rot_vel2 self.eff_rot_velocity = self.rot_vel1 - self.rot_vel2 self.eff_omega = self.eff_rot_velocity / 60 self.eff_omega_cage = self.eff_omega / 2 self.roller.eff_omega = self.mean_diameter / self.roller.diameter * \ self.eff_omega_cage self.footpr_vel = 2 * math.pi * \ (self.mean_diameter / 2 + self.roller.x_axis) * \ self.eff_omega / 2 self.overroll_t_incr = self.roller.delta_y / self.footpr_vel self.press_zone_len = (self.ring1.press > 0).sum(1) * self.ring1.delta_y self.overrolling_duration = np.divide(self.press_zone_len, self.footpr_vel) self.non_overroll_t = np.divide( (2 * math.pi * (self.mean_diameter / 2 + self.roller.x_axis) - self.num_rollers * self.press_zone_len) / self.num_rollers, self.footpr_vel) self.ring1.eff_raceway_vel = 2 * math.pi * ( self.mean_diameter / 2 + self.roller.x_axis) * self.eff_omega self.ring2.eff_raceway_vel = 0 self.roller.actual_raceway_vel = 2 * math.pi * ( self.mean_diameter / 2 + self.roller.x_axis) * \ self.eff_omega_cage + math.pi * \ self.roller.diameter * \ self.roller.eff_omega self.roller.eff_raceway_vel = self.roller.actual_raceway_vel self.roller.rel_vel = math.pi * self.roller.diameter * \ self.roller.eff_omega - 2 * math.pi * \ (self.mean_diameter / 2 + self.roller.x_axis) * \ self.eff_omega_cage self.roller.slip = np.divide(self.roller.rel_vel, 2 * math.pi * (self.mean_diameter / 2 + self.roller.x_axis) * self.eff_omega_cage)
def solve_half_space(profile1, profile2, x_axis, y_axis, res_x, res_y, delta_x, delta_y, e1, e2, ny1, ny2, normal_load, res_dir, influ_mat_db='empty', print_prog=True, init_displ=0.0005): """Orchestrate half space calculation and influence matrix generation/retrieval""" influ_mat_path = os.sep.join([res_dir, SubDir.np_db.value, influ_mat_db]) if os.path.exists(influ_mat_path): red_influ_mat = np.load(influ_mat_path) else: print_it('calculating influence matrix', PrintOpts.lvl1.value) red_influ_mat = calc_reduced_influence_matrix(x_axis, y_axis, res_x, res_y, delta_x, delta_y, e1, e2, ny1, ny2, print_prog=True) print_it('saving influence matrix', PrintOpts.lvl1.value) np_db_directory = make_directory(res_dir, SubDir.np_db.value) influ_mat_db = 'influence-matrix-{}.npy'.format(uuid.uuid4()) np.save(os.sep.join([np_db_directory, influ_mat_db]), red_influ_mat) print_it('solving first half space', PrintOpts.lvl1.value) pressure, resulting_force, init_displ = \ solve_for_pressure(profile1, profile2, normal_load, red_influ_mat, init_displ, delta_x, delta_y, print_prog) return pressure, influ_mat_db
def plt_load_distr(self, res_dir): """Generate plots of load distribution""" print_it("plotting load distributions", PrintOpts.lvl1.value) for roller_position in range(self.num_roller_pos): roller_forces = self.roller_norm_forces[roller_position, :] roller_forces_for_plot = np.append(roller_forces, roller_forces[0]) phi_plot = np.append(self.phi_mat[roller_position, :], self.phi_mat[roller_position, 0]) polplt_scatt_line( phi_plot, roller_forces_for_plot, phi_plot, roller_forces_for_plot, 'normal force in N', ('load distribution position ' + str(roller_position)), res_dir, SubDir.load_distr.value, ('load_distribution_position_' + str(roller_position)), self.roller_norm_forces[0, 0] * 1.1) print_progress(roller_position, self.num_roller_pos) polplt_scatt_line(self.pol_ax, self.normal_forces, self.pol_ax, self.normal_forces, 'normal force in N', 'roller normal force', res_dir, SubDir.load_distr.value, 'normal-force-over-position')