Example #1
0
def check_exists(key, user_input, else_quit=False):
    """Checks if the variable was defined by user, i.e., if it's in the
    global variables"""
    if key not in user_input and else_quit is True:
        exit_program("variable '{}' not defined".format(key))
    else:
        return user_input[key]
Example #2
0
def get_sim_specific_input(user_input):
    """returns additional simulation-specific required and optional user
    input variables"""
    simulation_type = user_input['simulation_type']
    required_user_input = {}
    optional_user_input = {}
    if simulation_type == SimType.cyl_rol_bearing.value:
        required_user_input = {'length_cb1': VarType.real_number,
                               'e_cb3': VarType.real_number,
                               'ny_cb3': VarType.real_number,
                               'diameter_cb3': VarType.real_number,
                               'type_profile_cb1': VarType.string,
                               'type_profile_cb2': VarType.string,
                               'type_profile_cb3': VarType.string,
                               'number_rollers': VarType.integer,
                               'diameter_cb2': VarType.real_number}
        optional_user_input = {'radial_clearance': VarType.real_number,
                               'res_pol': VarType.integer,
                               'rot_velocity2': VarType.real_number,
                               'rms_roughness_cb3': VarType.real_number}
    elif simulation_type == SimType.deep_gro_ball_bearing.value:
        pass
    elif simulation_type == SimType.cyl_rol_thrust_bearing.value:
        required_user_input = {'length_cb1': VarType.real_number,
                               'e_cb3': VarType.real_number,
                               'ny_cb3': VarType.real_number,
                               'mean_diameter': VarType.real_number,
                               'type_profile_cb1': VarType.string,
                               'number_rollers': VarType.integer}
        optional_user_input = {'rot_velocity2': VarType.real_number}
    elif simulation_type == SimType.ball_on_disk.value:
        required_user_input = {'number_balls': VarType.integer,
                               'sliding_diameter': VarType.real_number,
                               'diameter_cb2': VarType.real_number,
                               'rot_velocity2': VarType.real_number}
    elif simulation_type == SimType.pin_on_disk.value:
        check_vars({'diameter_cb1': user_input['diameter_cb1'],
                    'type_profile_cb1': user_input['type_profile_cb1']})
        if user_input[
            'type_profile_cb1'] is Profiles.Circle.value and check_exists(
                'profile_radius_cb1') is True and \
                        user_input['diameter_cb1'] != 2 * user_input[
                    'profile_radius_cb1']:
            required_user_input.update({'length_cb1': VarType.real_number})
        required_user_input.update({'number_pins': VarType.integer,
                                    'sliding_diameter': VarType.real_number})
    elif simulation_type == SimType.four_ball.value:
        required_user_input = {'diameter_cb2': VarType.real_number}
    elif simulation_type == SimType.ball_on_three_plates.value:
        optional_user_input = {'plate_angle': VarType.real_number}
    elif simulation_type == SimType.ring_on_ring.value:
        required_user_input = {'length_cb1': VarType.real_number,
                               'type_profile_cb1': VarType.string,
                               'type_profile_cb2': VarType.string,
                               'number_planets': VarType.integer,
                               'rot_velocity2': VarType.real_number}
    else:
        exit_program(
            "'simulation_type' option '{}' not defined".format(simulation_type))
    return required_user_input, optional_user_input
Example #3
0
def check_all_required(user_input, required_inputs):
    """checks if all calculation-specific (mandatory) variables are defined"""
    for key, value in required_inputs.items():
        if key not in user_input:
            exit_program(
                "variable '{}' not defined in input file".format(key))
    required_inputs.update(get_sim_specific_input(user_input)[0])
    check_vars(user_input)
Example #4
0
def validate_file_path(path_variable):
    """Validates file path"""
    if os.path.isfile(path_variable) is False:
        exit_program("cannot find file '" + eval(path_variable) + "'"
                     "\nplease specify a valid file path (including file "
                     "extension) in variable '" + path_variable + "'" +
                     "\nthe file path needs to be defined relative to "
                     "'the input file'")
Example #5
0
def check_base_required(user_input):
    """checks if all basic (mandatory) variables are defined"""
    required_inputs = copy.deepcopy(VarDicts.required_user_input.value)
    for key, value in required_inputs.items():
        if key not in user_input:
            exit_program(
                "variable '{}' not defined in input file".format(key))
    check_vars(user_input)
    return required_inputs
Example #6
0
def check_bool(key, value, isbool=True):
    """Checks if the variable is boolean"""
    if isinstance(value, bool) is not True and isbool is True:
        exit_program(
            "variable '{}' with value '{}' should be of type boolean".format(
                key, value))
    elif isinstance(value, bool) is True and isbool is False:
        exit_program(
            "variable '{}' with value '{}' (boolean) should not "
            "be of type boolean".format(key, value))
Example #7
0
def check_odd_even(key, value, should_be_odd_or_even=OddEvenCheck.Undefined):
    """Checks if the variable is odd or even"""
    if should_be_odd_or_even.value == OddEvenCheck.Odd.value or \
                    should_be_odd_or_even.value == OddEvenCheck.Even.value:
        if value % 2 == OddEvenCheck.Odd.value and \
                        should_be_odd_or_even.value != OddEvenCheck.Odd.value:
            exit_program("variable '" + value + "' should be an even number")
        elif value % 2 == OddEvenCheck.Even.value and \
                        should_be_odd_or_even.value != OddEvenCheck.Even.value:
            exit_program("variable '{}' should be an odd number".format(key))
Example #8
0
def check_sign(key, value, sign_var):
    """checks if the sign of a numeric variable is as expected"""
    if (isinstance(value, int) and not isinstance(value, bool)) is False \
            and isinstance(value, float) is False:
        exit_program(
            "variable '{}' with value '{}' should not be of type {}"
            .format(key, value, type(value)))
    if np.sign(value) != sign_var:
        exit_program("variable '{}' with value '{}' should be {} 0"
                     .format(key, value, {1.0: '<', -1.0: '>'}[np.sign(value)]))
Example #9
0
def check_alpha(key, value):
    """Checks if the string has only alphanumeric characters, except for '_'
    and '-' """
    try:
        if value[0].isalnum() is False or value[-1].isalnum() is False:
            if value[0] == '-' or value[-1] == '-':
                exit_program(
                    "variable '" + key +
                    "' should not start or end with a hyphen '-' ")
            else:
                exit_program(
                    "variable '{}' with value '{}' should only contain "
                    "alphanumeric characters and hyphens '-'"
                    .format(key, value))
    except TypeError:
        exit_program(
            "variable '{}' with value '{}' should be of type string. strings "
            "need to be enclosed in quotes.".
            format(key, value))
    for character in value:
        if character.isalnum() is False and character != '-':
            exit_program(
                "variable '{}' with value '{}' should only contain "
                "alphanumeric characters and hyphens '-'".
                format(key, value))
Example #10
0
def setup_ball_on_disk(ui):
    """Not currently implemented"""
    exit_program("simulation_type '4' currently not implemented completely.")
    """
    ball = Ball('pin', ui['e_cb1'], ui['ny_cb1'], ui['diameter_cb1'],
                rms_rough=in_d('rms_roughness_cb1', ui))
    ball.make_profile(ui['res_x'], ui['res_y'],
                      ui['global_force'] / ui['number_balls'])
    disk = Disk('disk', ui['e_cb2'], ui['ny_cb2'], diameter=ui['diameter_cb2'],
                rot_vel='rot_velocity2',
                rms_rough=in_d('rms_roughness_cb2', ui))
    disk.make_slave_to(ball)
    tribo_system = BallOnDisk(ui['number_balls'], ui['sliding_diameter'], ball,
                              disk, ui['global_force'],
                              in_d('tribo_system_name', ui))   
    return ball, disk, tribo_system
    """
    pass
Example #11
0
def import_user_input(in_file):
    """read file input file line by line and try to extract user input.
    return dictionary with user input"""
    user_input = {}
    invalid_input = {}
    try:
        with open(in_file) as user_input_file:
            for line in user_input_file:
                # if line not empty
                if line.strip():
                    # if line is comment, ignore
                    if line.strip()[0] == '#':
                        continue
                    else:
                        # remove trailing comments and whitespace
                        value_pair = line.split('#')[0].strip(' ')
                        # split at '=' and remove whitespace
                        key = value_pair.split('=')[0].strip(' ')
                        value = value_pair.split('=')[1].strip('\n').strip(' ')
                        # value = value.strip("'").strip('"').strip("'")
                        user_input.update({key: value})
                        if value.startswith("'") or value.startswith('"'):
                            value = value[1:-1]
                            if re.search('[a-zA-Z]', value):
                                user_input.update({key: value})
                        elif value == 'True':
                            user_input.update({key: True})
                            if key == 'auto_print':
                                user_input.update({'AUTO_PRINT': 'True'})
                        elif value == 'False':
                            user_input.update({key: False})
                            if key == 'auto_print':
                                user_input.update({'AUTO_PRINT': 'False'})
                        else:
                            try:
                                user_input.update({key: float(value)})
                                if int(user_input[key]) == user_input[key]:
                                    user_input[key] = int(value)
                            except ValueError:
                                invalid_input.update({key: value})
        return user_input, invalid_input
    except FileNotFoundError:
        exit_program("can't find file {}".format(in_file))
Example #12
0
    def calc_kinematics(self, rot_vel1, rot_vel2, ui=None, res_dir=None):
        """Calculate tribosystem kinematics based on rotational velocities of
        sun and planet(s)"""
        print_it("calculating kinematics")
        self.sun.rot_vel = rot_vel1
        self.planet.rot_vel = rot_vel2
        self.sun.omega = self.sun.rot_vel / 60
        self.planet.omega = self.planet.rot_vel / 60
        self.sun.vel = self.sun.diameter * math.pi * self.sun.omega
        self.planet.vel = self.planet.diameter * math.pi * self.planet.omega
        self.slip = (self.sun.vel - self.planet.vel) / self.sun.vel
        self.rel_vel = np.ones(self.sun.res_x) * (
        self.sun.vel - self.planet.vel)

        self.sun.footpr_vel = \
            2 * math.pi * self.sun.diameter / 2 * self.sun.omega
        self.planet.footpr_vel = \
            2 * math.pi * self.planet.diameter / 2 * self.planet.omega
        try:
            self.sun.overroll_t_incr = self.sun.delta_y / self.sun.footpr_vel
            self.planet.overroll_t_incr = \
                self.planet.delta_y / self.planet.footpr_vel
        except ZeroDivisionError:
            exit_program(
                'rotational velocities of sun and planet must not be 0')

        self.press_zone_len = (self.sun.press > 0).sum(1) * self.sun.delta_y
        self.sun.overroll_t = np.divide(self.press_zone_len,
                                        self.sun.footpr_vel)
        self.planet.overroll_t = np.divide(self.press_zone_len,
                                           self.planet.footpr_vel)
        self.sun.no_overroll_t = np.divide(
            (2 * math.pi * (self.sun.diameter / 2) - self.num_planets *
             self.press_zone_len) / self.num_planets, self.sun.footpr_vel)
        self.planet.no_overroll_t = np.divide(
            (2 * math.pi * (self.planet.diameter / 2) - self.press_zone_len),
            self.planet.footpr_vel)
Example #13
0
def validate_contact_body(user_input):
    """Checks if the user's contact body definition is consistent"""
    bodies_to_validate = {SimType.cyl_rol_bearing.value: ['cb1', 'cb2', 'cb3'],
                          SimType.cyl_rol_thrust_bearing.value: ['cb1'],
                          SimType.pin_on_disk.value: ['cb1'],
                          SimType.ring_on_ring.value: ['cb1', 'cb2']}
    for contact_body in bodies_to_validate.get(user_input['simulation_type'],
                                               []):
        type_profile = "type_profile_{}".format(contact_body)
        if user_input[type_profile] == Profiles.NoProfile.value:
            pass
        elif user_input[type_profile] == Profiles.ISO.value:
            check_vars({"length_" + contact_body: user_input[
                "length_" + contact_body]})
        elif user_input[type_profile] == Profiles.Circle.value:
            check_vars(
                {"length_" + contact_body: user_input["length_" + contact_body],
                 "profile_radius_" + contact_body: user_input[
                     "profile_radius_" + contact_body]})
        elif user_input[type_profile] == Profiles.File.value:
            validate_file_path(user_input["path_profile_" + contact_body])
        else:
            exit_program("'type_profile' option '{}' is undefined".format(
                user_input[type_profile]))
Example #14
0
def check_python_environment():
    """Check if all required python environments are installed before actual
    calculation is started"""
    print_it('python: {}'.format(sys.version.replace('\n', ' ')),
             PrintOpts.lvl1.value)
    try:
        import matplotlib as mpl
        print_it('matplotlib: {}'.format(mpl.__version__),
                 PrintOpts.lvl1.value)
    except ImportError:
        print_import_error('matplotlib', PrintOpts.lvl1.value)
        exit_program('module not found')
    try:
        import numexpr
        print_it('numexpr: {}'.format(numexpr.__version__),
                 PrintOpts.lvl1.value)
    except ImportError:
        print_import_error('numexpr', PrintOpts.lvl1.value)
        exit_program('module not found')
    try:
        import numpy
        print_it('numpy: {}'.format(numpy.__version__), PrintOpts.lvl1.value)
    except ImportError:
        print_import_error('numpy', PrintOpts.lvl1.value)
        exit_program('module not found')
    try:
        import scipy
        print_it('scipy: {}'.format(scipy.__version__), PrintOpts.lvl1.value)
    except ImportError:
        print_import_error('scipy', PrintOpts.lvl1.value)
        exit_program('module not found')
    try:
        import jinja2
        print_it('jinja2: {}'.format(jinja2.__version__), PrintOpts.lvl1.value)
    except ImportError:
        print_import_error('jinja2', PrintOpts.lvl1.value)
        print_it('this will cause an error if auto_report is True')
Example #15
0
def setup_deep_gro_ball_bearing(ui):
    """Not currently implemented"""
    exit_program("simulation_type '2' currently undefined")
Example #16
0
def check_int(key, value):
    """Checks if the variable is int"""
    if isinstance(value, int) is not True:
        exit_program(
            "variable '{}' with value '{}' should be of type int".format(key,
                                                                         value))
Example #17
0
def create_2d_profile2(diameter,
                       length,
                       type_profile,
                       x_axis,
                       res_x,
                       path_profile=None,
                       circle_radius=None):
    """creates a 2d profile along x-axis (body length) based on user input"""
    x_profile = np.zeros(res_x)
    file_x_axis = None
    file_x_profile = None
    if type_profile == Profiles.ISO.value:
        # problem is that ISO profile is not defined at the end points of the
        # roller, hence the profile at the end points is calculated based on a
        # slightly shorter x_axis here.
        x_axis_slightly_shorter = copy.deepcopy(x_axis)
        x_axis_slightly_shorter[[0, -1]] = np.multiply([x_axis[0], x_axis[-1]],
                                                       0.99999999)
        x_profile = -0.00035 * diameter * np.log(1 / (1 - np.power(
            ((2 * x_axis_slightly_shorter) / length), 2)))
        # x_profile[0] = x_profile[1] * 1.5
        # x_profile[-1] = x_profile[-2] * 1.5

    elif type_profile == Profiles.Circle.value:
        x_profile = np.array(
            abs(circle_radius) -
            np.sqrt(np.power(circle_radius, 2) - np.power(x_axis, 2)))
        sign_circle_radius = np.sign(circle_radius)
        x_profile = -np.multiply(x_profile, sign_circle_radius)

    elif type_profile == Profiles.File.value:
        content_text_file = []
        try:
            content_text_file = np.loadtxt(path_profile, delimiter="\t")
        except ValueError:
            exit_program(
                "\nexpecting the file '{}' to be a two column tab-delimited "
                ".txt-file"
                "\nwith first column corresponding to length of body and "
                "second column corresponding to "
                "profile data".format(path_profile))

        # get original x-axis and profile data from file and normalize it
        x_axis = np.array(
            content_text_file[:,
                              0]) - max(np.array(content_text_file[:, 0])) / 2
        file_x_axis = x_axis
        x_profile = np.array(content_text_file[:, 1]) - min(
            content_text_file[:, 1])
        file_x_profile = (x_profile - max(x_profile)) / 1000
        x_profile = x_profile - max(x_profile)
        step = max(1, round(len(content_text_file) / 15000))

        # deactivate filter warnings for polynomial fits
        warnings.simplefilter('ignore', np.RankWarning)

        try:
            print_it("fitting measured profile with 3rd grade polynomial",
                     PrintOpts.lvl1.value)
            start_point_left, start_point_right = fit_profile(
                x_axis, x_profile, step, 3)
            x_axis_new = np.array(
                content_text_file[start_point_left:-start_point_right + 1, 0])
            x_profile_new = np.array(
                x_profile[start_point_left:-start_point_right + 1])
            x_axis_new = x_axis_new - min(x_axis_new)
            x_axis_new -= max(x_axis_new) / 2
            print_it("3rd grade polynomial fit successful",
                     PrintOpts.lvl1.value)
        except ValueError:
            print_it("3rd grade polynomial fit failed", PrintOpts.lvl1.value)
            print_it("fitting measured profile with 2nd grade polynomial",
                     PrintOpts.lvl1.value)
            start_point_left, start_point_right = fit_profile(
                x_axis, x_profile, step, 2)
            x_axis_new = np.array(
                content_text_file[start_point_left:-start_point_right + 1, 0])
            x_profile_new = np.array(
                x_profile[start_point_left:-start_point_right + 1])
            x_axis_new = x_axis_new - min(x_axis_new)
            x_axis_new -= max(x_axis_new) / 2
            print_it("2nd grade polynomial fit successful",
                     PrintOpts.lvl1.value)
        warnings.simplefilter('always', np.RankWarning)

        # generate profile representation and corresponding x-axis based on
        # polynomial fit
        short_x_axis = np.linspace(x_axis_new[0], x_axis_new[-1], res_x)
        z = np.polyfit(x_axis_new, x_profile_new,
                       find_poly(x_axis_new, x_profile_new))
        p = np.poly1d(z)
        interpolated_x_profile = p(short_x_axis)
        x_axis = short_x_axis

        # normalize profile and convert units to millimeter
        x_profile = (interpolated_x_profile - min(interpolated_x_profile))
        x_profile = (x_profile - max(x_profile)) / 1000

    delta_x = abs(x_axis[0] - x_axis[1])
    return x_axis, x_profile, file_x_axis, file_x_profile, delta_x
Example #18
0
def p3can(in_file='USER_INPUT.py', out_dir=None):
    """

    Start a P3CAN simulation run.

    Parameters
    ----------
    in_file: str, optional
        The file path of the P3CAN input file. The default value is
        `USER_INPUT.py`. You can generate `in_file` templates for different
        tribological systems using the `generate_input_file` function.
    out_dir: str
        The directory in which output files will be stored. A folder named
        `results` will be created in `out_dir`. The `results` folder then
        contains a simulation-specific folder containing all outputs. Default
        is the current working directory.

    Returns
    -------
    sim.res_dir: str
        The path to the simulation-specific results folder. The path is:

        `out_dir`/results/<unique simulation name>

        The unique simulation name is automatically generated by P3CAN.

    """

    if not out_dir:
        out_dir = os.getcwd()

    # set-up a simulation
    sim = Sim(in_file, out_dir)
    sim.mk_uniq_parameter_id()
    sim.infl_db_file_hand = make_infl_mat_db(os.path.dirname(sim.res_dir))
    tribo_system = None

    # generate a tribosystem based on user input
    print_it('initialising contact bodies')
    if sim.simulation_type == SimType.cyl_rol_bearing.value:
        roller, ring1, ring2, tribo_system = setup_cyl_rol_bearing(sim.ui)
    elif sim.simulation_type == SimType.deep_gro_ball_bearing.value:
        setup_deep_gro_ball_bearing(sim.ui)
    elif sim.simulation_type == SimType.cyl_rol_thrust_bearing.value:
        roller, ring1, ring2, tribo_system = setup_cyl_rol_thrust_bearing(
            sim.ui)
    elif sim.simulation_type == SimType.ball_on_disk.value:
        ball, disk, tribo_system = setup_ball_on_disk(sim.ui)
    elif sim.simulation_type == SimType.pin_on_disk.value:
        pin, disk, tribo_system = setup_pin_on_disk(sim.ui)
    elif sim.simulation_type == SimType.four_ball.value:
        rot_ball, stat_ball, tribo_system = setup_four_ball(sim.ui)
    elif sim.simulation_type == SimType.ball_on_three_plates.value:
        ball, plate, tribo_system = setup_ball_on_three_plates(sim.ui)
    elif sim.simulation_type == SimType.ring_on_ring.value:
        sun, planet, tribo_system = setup_ring_on_ring(sim.ui)
    else:
        exit_program("'simulation_type' option '{}'not defined".format(
            sim.simulation_type))

    # simulate tribosystem
    tribo_system.calc_load_distribution(sim.ui, sim.res_dir)
    tribo_system.calc_contact_pressure(sim.ui, sim.res_dir)
    tribo_system.calc_kinematics(in_d('rot_velocity1', sim.ui, 0),
                                 in_d('rot_velocity2', sim.ui, 0), sim.ui,
                                 sim.res_dir)
    tribo_system.calc_pv(sim.ui, sim.res_dir)
    tribo_system.calc_e_akin(sim.ui, sim.res_dir)

    # generate output plots and pdf report
    if sim.auto_plot is True:
        tribo_system.plot_it(sim.ui, sim.res_dir)
    if sim.auto_report is True:
        generate_latex_output(sim, tribo_system, sim.ui, sim.res_dir)

    # manage the influence matrix cache
    manage_influ_mat_cache(sim.res_dir)

    # finish simulation
    sim.finished()
    return sim.res_dir