Esempio n. 1
0
def check_lay_up_rules(ss,
                       constraints,
                       no_ipo_check=False,
                       no_bal_check=False,
                       equality_45_135=False,
                       equality_0_90=False,
                       n_plies=None):
    """
    checks the manufacturability of a stacking sequence
    """
    if n_plies is not None and ss.size != n_plies:
        raise Exception("Wrong number of plies")

    if constraints.dam_tol:
        if not is_dam_tol(ss, constraints):
            print_ss(ss)
            raise Exception("Damage tolerance constraint not satisfied")

    if not no_bal_check and constraints.bal:
        if not is_balanced(ss, constraints):
            raise Exception("Balance constraint not satisfied")

    if not no_ipo_check and constraints.ipo:
        lampamA = calc_lampamA(ss, constraints)
        if (abs(lampamA[2:4]) > 1e-10).any():
            print_ss(ss)
            print('lampamA', lampamA)
            #            print('ipo')
            raise Exception("In plane orthotropy constraint not satisfied")

    if constraints.diso:
        if hasattr(constraints, 'dam_tol_rule'):
            if not is_diso_ss(ss, constraints.delta_angle, constraints.dam_tol,
                              constraints.dam_tol_rule):
                raise Exception("Disorientation constraint not satisfied")
        else:
            if not is_diso_ss(ss, constraints.delta_angle, constraints.dam_tol,
                              constraints.n_plies_dam_tol):
                raise Exception("Disorientation constraint not satisfied")

    if constraints.contig:
        if not is_contig(ss, constraints.n_contig):
            raise Exception("Contiguity constraint not satisfied")

    if constraints.rule_10_percent:
        if not is_ten_percent_rule(constraints,
                                   stack=ss,
                                   equality_45_135=equality_45_135,
                                   equality_0_90=equality_0_90):
            raise Exception("10% rule not satisfied")
    return 0
Esempio n. 2
0
def repair_flexural(ss,
                    constraints,
                    out_of_plane_coeffs,
                    parameters,
                    multipanel=None,
                    lampam_target=None,
                    reduced_pdl=None,
                    reduced_sst=None,
                    reduced_lampam=None,
                    reduced_ss=None,
                    mat=None,
                    repair_flexural_for_ref_panel_only=True,
                    count_obj=False):
    """
    repair for flexural properties

    - count_obj: flag to count the number of objective function calls
    """
    n_obj_func_D_calls = 0

    if parameters.repair_flexural_switch \
    and not np.isclose(out_of_plane_coeffs,
                       np.array([0, 0, 0, 0], float)).all():
        if constraints.diso or constraints.contig:

            for ite in range(parameters.n_D3):
                # swap blocks of plies
                ss, n_obj = repair_flexural_1(ss,
                                              out_of_plane_coeffs,
                                              lampam_target,
                                              constraints,
                                              count_obj=True)
                n_obj_func_D_calls += n_obj

                if hasattr(constraints, 'dam_tol_rule'):
                    if constraints.diso and not is_diso_ss(
                            ss,
                            delta_angle=constraints.delta_angle,
                            dam_tol=constraints.dam_tol,
                            dam_tol_rule=constraints.dam_tol_rule):
                        raise Exception('Disorientation rule not satisfied')
                else:
                    if constraints.diso and not is_diso_ss(
                            ss,
                            delta_angle=constraints.delta_angle,
                            dam_tol=constraints.dam_tol,
                            n_plies_dam_tol=constraints.n_plies_dam_tol):
                        raise Exception('Disorientation rule not satisfied')

                if constraints.contig and not is_contig(
                        ss, constraints.n_contig):
                    raise Exception('Contiguity rule not satisfie')

                # changes ply block sizes
                ss, n_obj = repair_flexural_2(ss,
                                              out_of_plane_coeffs,
                                              lampam_target,
                                              constraints,
                                              parameters,
                                              count_obj=True)
                n_obj_func_D_calls += n_obj
        else:
            for ite in range(parameters.n_D3):
                # re-design laminate
                ss, n_obj = repair_flexural_3(ss,
                                              out_of_plane_coeffs,
                                              lampam_target,
                                              constraints,
                                              parameters,
                                              count_obj=True)
                n_obj_func_D_calls += n_obj

        if count_obj:
            return ss, n_obj_func_D_calls
        return ss

    if count_obj:
        return ss, n_obj_func_D_calls
    return ss
Esempio n. 3
0
        percent_45_135=10,
        set_of_angles=[0, 45, -45, 90, 30, -30, 60, -60, 15, -15, 75, -75])
    parameters = Parameters(repair_flexural_switch=True,
                            n_D2=2,
                            constraints=constraints)

    ss = np.array([-60, -45, 90, 75, -75, -45, 0], int)
    if constraints.sym:
        ss = np.hstack((ss, np.flip(ss)))
    if not is_diso_ss(ss,
                      delta_angle=constraints.delta_angle,
                      dam_tol=constraints.dam_tol,
                      dam_tol_rule=constraints.dam_tol_rule):
        raise Exception('Disorientation rule not satisfied initially')

    if not is_contig(ss, constraints.n_contig):
        raise Exception('Contiguity rule not satisfied initially')

    print('\nInitial stacking sequence')
    print_ss(ss, 1000)
    ss_target = 45 * np.ones((1, ), dtype=int)
    lampam_target = calc_lampam(ss_target)
    lampam_target = np.array([
        -0.25662112, -0.01727515, -0.73962959, 0.08359081, 0.43671968,
        -0.7901057, 0.98404481, 0.65070345, 0.97056517, 0.7023994, 0.32539113,
        -0.35851357
    ])
    out_of_plane_coeffs = np.array([1, 1, 1, 1])
    ss = repair_flexural(ss,
                         constraints,
                         out_of_plane_coeffs,
def repair_diso_contig_from_inside_asym(ss, ply_queue, constraints, n_D1):
    """
    attempts at repairing the stacking sequence to satisfy the disorientation
    and contiguity rule for asymmetric laminates with swaps from the inside out
    of the laminates

    INPUTS

    - ss: partially retrieved stacking sequence
    - ply_queue: queue of plies for innermost plies
    - constraints: design and manufacturing constraints
    - n_D1: number of plies in the last permutation
    """
    stack_top, stack, stack_bottom, ind_1, ind_2 = \
    initialise_repair_diso_contig(
        ss, constraints, True, n_D1)
    #    print('ind_1', ind_1)
    #    print('ind_2', ind_2)

    ind_step = -1
    for ind_step, ind_ply_1 in enumerate(ind_1):
        #        print('ind_ply_1', ind_ply_1)

        for ind_ply_2 in ind_2:
            #            print('    ind_ply_2', ind_ply_2)
            angle_found = False

            if ss[ind_ply_2] != 666:

                if ind_step % 2 == 0:
                    stack_test = np.hstack((ss[ind_ply_2], stack))
                    #                print('stack_test', stack_test)
                    if constraints.diso and not is_diso(
                            stack_test[0], stack_test[1],
                            constraints.delta_angle):
                        continue
                    if constraints.contig and not is_contig(
                            stack_test[:2 * constraints.n_contig],
                            constraints.n_contig):
                        continue
                else:
                    stack_test = np.hstack((stack, ss[ind_ply_2]))
                    #                print('stack_test', stack_test)
                    if constraints.diso and not is_diso(
                            stack_test[-1], stack_test[-2],
                            constraints.delta_angle):
                        continue
                    if constraints.contig and not is_contig(
                            stack_test[-2 * constraints.n_contig:],
                            constraints.n_contig):
                        continue
                stack = stack_test
                ind_2 = np.delete(ind_2, np.argwhere(ind_2 == ind_ply_2))
                angle_found = True
                #            print_ss(stack, 13)
                break

            else:  # let's pick a ply from the queue

                if ind_step % 2 == 0:
                    angles_to_test = order_plies_to_test([stack[0]], ply_queue,
                                                         constraints)
                    for angle in angles_to_test:
                        stack_test = np.hstack((angle, stack))
                        #                print('stack_test', stack_test)
                        if constraints.diso and not is_diso(
                                stack_test[0], stack_test[1],
                                constraints.delta_angle):
                            continue
                        if constraints.contig and not is_contig(
                                stack_test[:2 * constraints.n_contig],
                                constraints.n_contig):
                            continue
                        stack = stack_test
                        ind_2 = np.delete(ind_2,
                                          np.argwhere(ind_2 == ind_ply_2)[0])
                        angle_found = True
                        ply_queue.remove(angle)
                        #            print_ss(stack, 13)
                        break
                else:
                    angles_to_test = order_plies_to_test([stack[-1]],
                                                         ply_queue,
                                                         constraints)
                    for angle in angles_to_test:
                        stack_test = np.hstack((stack, angle))
                        #                print('stack_test', stack_test)
                        if constraints.diso and not is_diso(
                                stack_test[-1], stack_test[-2],
                                constraints.delta_angle):
                            continue
                        if constraints.contig and not is_contig(
                                stack_test[-2 * constraints.n_contig:],
                                constraints.n_contig):
                            continue
                        stack = stack_test
                        ind_2 = np.delete(ind_2,
                                          np.argwhere(ind_2 == ind_ply_2)[0])
                        angle_found = True
                        ply_queue.remove(angle)
                        #            print_ss(stack, 13)
                        break

                if angle_found:
                    break

        if not angle_found:
            # return semi-repaired stacking sequence
            for ind in ind_2:
                ind_step += 1
                if ind_step % 2 == 0:
                    if ss[ind] != 666:
                        stack = np.hstack((ss[ind], stack))
                    else:
                        stack = np.hstack((ply_queue.pop(0), stack))
                else:
                    if ss[ind] != 666:
                        stack = np.hstack((stack, ss[ind]))
                    else:
                        stack = np.hstack((stack, ply_queue.pop(0)))
            stack = np.hstack((stack_top, stack, stack_bottom))
            if stack.size != ss.size:
                raise Exception('This should not happen')
            return stack, False

    if stack_bottom.size + stack_top.size  + stack.size \
    < ss.size - n_D1:
        # return semi-repaired stacking sequence
        raise Exception('This should not happen anymore')

#    print('stack', stack)
#    print('stack_top', stack_top)
#    print('stack_bottom', stack_bottom)

# plies at the centre all designed simultaneously
    ind_2_before = np.copy(ind_2)
    ply_queue_ini = ply_queue[:]
    ind_2 = np.sort(ind_2)
    good_permut = []
    real_n_D1 = ind_2.size
    remaining_plies = np.empty((real_n_D1, ), int)
    for counter, ind in enumerate(ind_2):
        if ss[ind] != 666:
            remaining_plies[counter] = ss[ind]
        else:
            remaining_plies[counter] = ply_queue.pop(0)
#    print('remaining_plies', remaining_plies)

    for elem in itertools.permutations(range(real_n_D1)):
        #        print('elem', elem)
        ss_group = remaining_plies[np.array(elem, int)]
        if constraints.dam_tol:
            stack_test = np.hstack(
                (stack_top[-1], ss_group[:real_n_D1 // 2], stack,
                 ss_group[real_n_D1 // 2:], stack_bottom[0]))
        else:
            stack_test = np.hstack(
                (ss_group[:real_n_D1 // 2], stack, ss_group[real_n_D1 // 2:]))
#        print('stack_test', stack_test)
        stack_test_1 = stack_test[:3 + real_n_D1 + constraints.n_contig]
        if constraints.diso and not is_diso_ss(
                stack_test_1, constraints.delta_angle, dam_tol=False):
            continue
        if constraints.contig and not is_contig(stack_test_1,
                                                constraints.n_contig_c):
            continue
        number = stack_test.size - 4 - real_n_D1 \
        - constraints.n_contig
        if number > 0:
            stack_test_2 = stack_test[number:]
            if constraints.diso and not is_diso_ss(
                    stack_test_2, constraints.delta_angle, dam_tol=False):
                continue
            if constraints.contig and not is_contig(stack_test_2,
                                                    constraints.n_contig_c):
                continue
        good_permut.append(np.array(elem, int))


#    print('good_permut', good_permut)

    good_permut = smallest_row(good_permut)
    if good_permut is None:
        # return semi-repaired stacking sequence
        for ind in ind_2_before:
            ind_step += 1
            if ind_step % 2 == 0:
                if ss[ind] != 666:
                    stack = np.hstack((ss[ind], stack))
                else:
                    stack = np.hstack((ply_queue_ini.pop(0), stack))
            else:
                if ss[ind] != 666:
                    stack = np.hstack((stack, ss[ind]))
                else:
                    stack = np.hstack((stack, ply_queue_ini.pop(0)))
        stack = np.hstack((stack_top, stack, stack_bottom))
        if stack.size != ss.size:
            raise Exception('This should not happen')
        return stack, False

    ss_group = remaining_plies[good_permut]
    stack = np.hstack((stack_top, ss_group[:real_n_D1 // 2], stack,
                       ss_group[real_n_D1 // 2:], stack_bottom))
    if stack.size != ss.size:
        raise Exception('This should not happen')
    return stack, True
Esempio n. 5
0
def repair_flexural_2(
        ss_ini, out_of_plane_coeffs, lampam_target, constraints,
        parameters, count_obj=False):
    """
    repair for flexural properties only accounting for one panel by
    changing ply block sizes to improve the out-of-plane lamination
    parameters' convergence.

    This repair step is required because despite the preference of modifying
    inner plies rather than outer plies during the repair strategy, the
    out-of-plane lamination parameters matching with their targets might have
    been reduced by the first steps of the repair process. The design
    guidelines remain satisfied by the laminates during this repair step.

    INPUTS

    - ss_ini: stacking sequence (array)
    - out_of_plane_coeffs: coefficients in the out-of-plane objective function
    - lampam_target: lamination parameter targets
    - constraints: design and manufacturing constraints
    - parameters.n_D2: number of ply shifts tested at each step of the process
    - count_obj: flag to count the number of objective function calls
    """
    n_obj_func_D_calls = 0

    ss = np.copy(ss_ini)
    if constraints.sym:
        if constraints.dam_tol:
            if hasattr(constraints, 'dam_tol_rule') \
            and constraints.dam_tol_rule in {2, 3}:
                ind_2 = np.arange(2, ss.size // 2)
            elif not hasattr(constraints, 'dam_tol_rule') and \
            constraints.n_plies_dam_tol == 2:
                ind_2 = np.arange(2, ss.size // 2)
            else:
                ind_2 = np.arange(1, ss.size // 2)
        else:
            ind_2 = np.arange(0, ss.size // 2)
    else:
        indices = np.arange(ss.size)
        beginning = np.copy(indices[0:indices.size // 2])
        ending = np.copy(indices[indices.size // 2:ss.size][::-1])
        ind_2 = np.zeros((ss.size,), int)
        ind_2[::2] = ending
        ind_2[1::2] = beginning
        if constraints.dam_tol:
            if hasattr(constraints, 'dam_tol_rule') \
            and constraints.dam_tol_rule in {2, 3}:
                ind_2 = ind_2[4:]
            elif not hasattr(constraints, 'dam_tol_rule') and \
            constraints.n_plies_dam_tol == 2:
                ind_2 = ind_2[4:]
            else:
                ind_2 = ind_2[2:]
#    print('ind_2', ind_2)

    if constraints.sym:
        n_plies_here = ss.size // 2
        if ss.size % 2:
            index_ply = ss.size // 2
            norm_pos_top = 1 - (2 / ss.size) * (index_ply)
            norm_pos_bot =  1 - (2 / ss.size) * (index_ply + 1)
            sec_mom_areas_mid = (norm_pos_top**3 - norm_pos_bot**3) / 2
            delta_lampam_mid = sec_mom_areas_mid * constraints.cos_sin[
                    constraints.ind_angles_dict[ss[index_ply]]].reshape((4,))
        else:
            delta_lampam_mid = np.zeros((4,), float)
    else:
        n_plies_here = ss.size
        delta_lampam_mid = np.zeros((4,), float)

    cos_sin = np.zeros((n_plies_here, 4), float)
    sec_mom_areas = np.zeros((n_plies_here,), float)

    for index_ply in range(n_plies_here):
        cos_sin[index_ply] = constraints.cos_sin[
            constraints.ind_angles_dict[ss[index_ply]]].reshape((4,))
        norm_pos_top = 1 - (2 / ss.size) * (index_ply)
        norm_pos_bot =  1 - (2 / ss.size) * (index_ply + 1)
        sec_mom_areas[index_ply] = (norm_pos_top**3 - norm_pos_bot**3)

    if not constraints.sym:
        sec_mom_areas /= 2

    lampamD = np.matmul(sec_mom_areas, cos_sin) + delta_lampam_mid
    objD = sum(out_of_plane_coeffs*((lampamD - lampam_target[8:12])**2))
    n_obj_func_D_calls += 1

    best_objD = objD
#    print('best_objD', best_objD)
#    print('sec_mom_areas', sec_mom_areas, sum(sec_mom_areas))
#    print('cos_sin', cos_sin)
#    print('lampamD', lampamD)
#    print_ss(ss)
#    print('objD', objD)

    ind_step = 0
    for index, ind_ply_1 in enumerate(ind_2[:-1]):
#        print('ind_ply_1', ind_ply_1)

        objD = 1e10 * np.ones((parameters.n_D2 - 1,), float)

        for ind_loc, ind_ply_2 \
        in enumerate(ind_2[index + 1:index + parameters.n_D2]):

#            print('    ind_ply_2', ind_ply_2)

            if not constraints.sym and ind_step % 2 == 0:

                ss_mod = np.copy(ss)
                ss_mod[ind_ply_2:ind_ply_1 + 1] = np.hstack((
                    ss_mod[ind_ply_2 + 1:ind_ply_1 + 1],
                    ss_mod[ind_ply_2]))
#                print_ss(ss_mod)

                if constraints.diso:
                    if ind_ply_2 > 0 and not is_diso(
                            ss_mod[ind_ply_2], ss_mod[ind_ply_2 - 1],
                            constraints.delta_angle):
                        continue
                    if not is_diso(
                            ss_mod[ind_ply_2], ss_mod[ind_ply_2 + 1],
                            constraints.delta_angle):
                        continue
                    if not is_diso(
                            ss_mod[ind_ply_1], ss_mod[ind_ply_1 - 1],
                            constraints.delta_angle):
                        continue
                    if ind_ply_1 < ss.size - 1 \
                    and not is_diso(
                            ss_mod[ind_ply_1], ss_mod[ind_ply_1 + 1],
                            constraints.delta_angle):
                        continue

                if constraints.contig:
                    mini = max(0, ind_ply_1 - constraints.n_contig)
                    maxi = ind_ply_1 + constraints.n_contig
                    if not is_contig(ss_mod[mini:maxi + 1],
                                     constraints.n_contig):
                        continue
                    mini = max(0, ind_ply_2 - constraints.n_contig)
                    maxi = ind_ply_2 + constraints.n_contig
                    if not is_contig(ss_mod[mini:maxi + 1],
                                     constraints.n_contig):
                        continue


                # change
                cos_sin[ind_ply_2:ind_ply_1 + 1, :] = np.vstack((
                    cos_sin[ind_ply_2 +1:ind_ply_1 + 1, :],
                    cos_sin[ind_ply_2, :]))

                lampamD = np.matmul(sec_mom_areas, cos_sin) + delta_lampam_mid
                objD[ind_loc] = sum(out_of_plane_coeffs*((
                    lampamD - lampam_target[8:12])**2))
                n_obj_func_D_calls += 1

                # revert change
                cos_sin[ind_ply_2:ind_ply_1 + 1, :] = np.vstack((
                    cos_sin[ind_ply_1, :],
                    cos_sin[ind_ply_2:ind_ply_1, :]))

            else:
                if constraints.sym:
                    ss_mod = np.copy(ss[:ss.size//2])
                    ss_mod[ind_ply_1:ind_ply_2 + 1] = np.hstack((
                        ss_mod[ind_ply_2], ss_mod[ind_ply_1:ind_ply_2]))
#                    print_ss(ss_mod)

                    if constraints.diso:
                        if ind_ply_1 > 0 and not is_diso(
                                ss_mod[ind_ply_1], ss_mod[ind_ply_1 - 1],
                                constraints.delta_angle):
                            continue
                        if not is_diso(
                                ss_mod[ind_ply_1], ss_mod[ind_ply_1 + 1],
                                constraints.delta_angle):
                            continue
                        if not is_diso(
                                ss_mod[ind_ply_2], ss_mod[ind_ply_2 - 1],
                                constraints.delta_angle):
                            continue
                        if ss.size % 2 == 1 and ind_ply_2 == ss.size//2 - 1 \
                        and not is_diso(
                                ss_mod[ind_ply_2], ss[ind_ply_2 + 1],
                                constraints.delta_angle):
                            continue
                        if ind_ply_2 < ss.size//2 - 1\
                        and not is_diso(
                                ss_mod[ind_ply_2], ss_mod[ind_ply_2 + 1],
                                constraints.delta_angle):
                            continue

#                    print('diso ok')

                    if constraints.contig:
                        mini = max(0, ind_ply_1 - constraints.n_contig)
                        maxi = ind_ply_1 + constraints.n_contig
#                        print('mini', mini, 'maxi', maxi)

                        if maxi >= ss.size // 2 - 1:
                            if ss.size % 2 == 1:
                                ss_mod = np.hstack((
                                    ss_mod, ss[ss.size//2], np.flip(ss_mod)))
                            else:
                                ss_mod = np.hstack((ss_mod, np.flip(ss_mod)))
#                            print('SS_mod here', ss_mod)
                            maxi = ss.size - mini - 1
                            if not is_contig(ss_mod[mini:maxi + 1],
                                         constraints.n_contig):
                                continue
                        else:
                            if not is_contig(ss_mod[mini:maxi + 1],
                                         constraints.n_contig):
                                continue

                            mini = max(0, ind_ply_2 - constraints.n_contig)
                            maxi = ind_ply_2 + constraints.n_contig
                            if maxi >= ss.size // 2 -1:
                                if ss.size % 2 == 1:
                                    ss_mod = np.hstack((
                                        ss_mod, ss[ss.size//2],
                                        np.flip(ss_mod)))
                                else:
                                    ss_mod = np.hstack((
                                        ss_mod, np.flip(ss_mod)))
#                                print('SS_mod there', ss_mod)
                                maxi = ss.size - mini - 1
                            if not is_contig(ss_mod[mini:maxi + 1],
                                             constraints.n_contig):
                                continue
#                    print('contig ok')

                else:
                    ss_mod = np.copy(ss)
                    ss_mod[ind_ply_1:ind_ply_2 + 1] = np.hstack((
                        ss_mod[ind_ply_2], ss_mod[ind_ply_1:ind_ply_2]))
#                    print_ss(ss_mod)

                    if constraints.diso:
                        if ind_ply_1 > 0 and not is_diso(
                                ss_mod[ind_ply_1], ss_mod[ind_ply_1 - 1],
                                constraints.delta_angle):
                            continue
                        if not is_diso(
                                ss_mod[ind_ply_1], ss_mod[ind_ply_1 + 1],
                                constraints.delta_angle):
                            continue
                        if not is_diso(
                                ss_mod[ind_ply_2], ss_mod[ind_ply_2 - 1],
                                constraints.delta_angle):
                            continue
                        if ind_ply_2 < ss.size - 1\
                        and not is_diso(
                                ss_mod[ind_ply_2], ss_mod[ind_ply_2 + 1],
                                constraints.delta_angle):
                            continue

#                    print('diso ok')

                    if constraints.contig:
                        mini = max(0, ind_ply_1 - constraints.n_contig)
                        maxi = ind_ply_1 + constraints.n_contig
                        if not is_contig(ss_mod[mini:maxi + 1],
                                         constraints.n_contig):
                            continue
                        mini = max(0, ind_ply_2 - constraints.n_contig)
                        maxi = ind_ply_2 + constraints.n_contig
                        if not is_contig(ss_mod[mini:maxi + 1],
                                         constraints.n_contig):
                            continue

#                    print('contig ok')

                # change
                cos_sin[ind_ply_1:ind_ply_2 + 1, :] = np.vstack((
                    cos_sin[ind_ply_2, :],
                    cos_sin[ind_ply_1:ind_ply_2, :]))

                lampamD = np.matmul(sec_mom_areas, cos_sin) + delta_lampam_mid
                objD[ind_loc] = sum(out_of_plane_coeffs*((
                    lampamD - lampam_target[8:12])**2))
                n_obj_func_D_calls += 1

                # revert change
                cos_sin[ind_ply_1:ind_ply_2 + 1, :] = np.vstack((
                    cos_sin[ind_ply_1 +1:ind_ply_2 + 1, :],
                    cos_sin[ind_ply_1, :]))

        if min(objD) + 1e-20 < best_objD:

            best_objD = min(objD)
            ind_min = np.argmin(objD)
            ind_ply_2 = ind_2[index + 1:][ind_min]

#            print('CHANGE')
#            print('objD', objD)
#            print('ind_min', ind_min, 'ind_ply_2', ind_ply_2)

            if not constraints.sym and ind_step % 2 == 0:
                ss[ind_ply_2:ind_ply_1 + 1] = np.hstack((
                    ss[ind_ply_2 +1:ind_ply_1 + 1], ss[ind_ply_2]))

                cos_sin[ind_ply_2:ind_ply_1 + 1, :] = np.vstack((
                    cos_sin[ind_ply_2 +1:ind_ply_1 + 1, :],
                    cos_sin[ind_ply_2, :]))
            else:
                ss[ind_ply_1:ind_ply_2 + 1] = np.hstack((
                    ss[ind_ply_2], ss[ind_ply_1:ind_ply_2]))

                cos_sin[ind_ply_1:ind_ply_2 + 1, :] = np.vstack((
                    cos_sin[ind_ply_2, :], cos_sin[ind_ply_1:ind_ply_2, :]))

#        print()
#        print('after iteration')
#        print_ss(ss)
#        print('best_objD', best_objD)
#        print('objD', objD)

        ind_step += 1

#    print_ss(ss)
#    print('objD', objD)

    if constraints.sym:
        ss[ss.size // 2 + ss.size % 2:] = np.flip(ss[:ss.size // 2])

    if count_obj:
        return ss, n_obj_func_D_calls
    return ss
def repair_diso_contig_from_outside_asym(ss, ply_queue, constraints, n_D1):
    """
    attempts at repairing the stacking sequence to satisfy the disorientation
    and contiguity rule for asymmetric laminates with swaps performed inwardly
    in the laminates

    INPUTS

    - ss: partially retrieved stacking sequence
    - ply_queue: queue of plies for innermost plies
    - constraints: design and manufacturing constraints
    - n_D1: number of plies in the last permutation
    """
    stack_top, stack_bottom, ind_1, ind_2 = initialise_repair_diso_contig(
        ss, constraints, from_inside=False, n_D1=n_D1)
    #    print('ind_1', ind_1)
    #    print('ind_2', ind_2)

    ind_step = -1
    for ind_step, ind_ply_1 in enumerate(ind_1):
        ind_2_mod = modify_indices(ind_2, ind_ply_1, bottom=ind_step % 2 == 0)
        #        print('ind_ply_1', ind_ply_1)
        #        print('ind_2_mod', ind_2_mod)
        angle_found = False

        for ind_ply_2 in ind_2_mod:
            #            print('    ind_ply_2', ind_ply_2)

            if ss[ind_ply_2] != 666:

                if ind_step % 2 == 0:
                    stack_test = np.hstack((ss[ind_ply_2], stack_bottom))
                    #                    print('stack_test', stack_test)
                    if constraints.diso and not is_diso(
                            stack_test[0], stack_test[1],
                            constraints.delta_angle):
                        continue
                    if constraints.contig and not is_contig(
                            stack_test[:2 * constraints.n_contig],
                            constraints.n_contig):
                        continue
                    stack_bottom = stack_test
#                    print('stack_bottom', end='')
#                    print_ss(stack_bottom)
                else:
                    stack_test = np.hstack((stack_top, ss[ind_ply_2]))
                    #                    print('stack_test', stack_test)
                    if constraints.diso and not is_diso(
                            stack_test[-1], stack_test[-2],
                            constraints.delta_angle):
                        continue
                    if constraints.contig and not is_contig(
                            stack_test[-2 * constraints.n_contig:],
                            constraints.n_contig):
                        continue
                    stack_top = stack_test
#                    print('stack_top', end='')
#                    print_ss(stack_top)
                ind_2 = np.delete(ind_2, np.argwhere(ind_2 == ind_ply_2))
                angle_found = True
                break

            else:  # let's pick a ply from the queue

                if ind_step % 2 == 0:
                    angles_to_test = order_plies_to_test([stack_bottom[0]],
                                                         ply_queue,
                                                         constraints)
                    for angle in angles_to_test:
                        stack_test = np.hstack((angle, stack_bottom))
                        #                        print('stack_test', stack_test)
                        if constraints.diso and not is_diso(
                                stack_test[0], stack_test[1],
                                constraints.delta_angle):
                            continue
                        if constraints.contig and not is_contig(
                                stack_test[:2 * constraints.n_contig],
                                constraints.n_contig):
                            continue
                        stack_bottom = stack_test
                        #                        print('stack_bottom', end='')
                        #                        print_ss(stack_bottom)
                        angle_found = True
                        ind_2 = np.delete(ind_2,
                                          np.argwhere(ind_2 == ind_ply_2)[0])
                        ply_queue.remove(angle)
                        break
                else:
                    angles_to_test = order_plies_to_test([stack_top[-1]],
                                                         ply_queue,
                                                         constraints)
                    for angle in angles_to_test:
                        stack_test = np.hstack((stack_top, angle))
                        #                        print('stack_test', stack_test)
                        if constraints.diso and not is_diso(
                                stack_test[-1], stack_test[-2],
                                constraints.delta_angle):
                            continue
                        if constraints.contig and not is_contig(
                                stack_test[-2 * constraints.n_contig:],
                                constraints.n_contig):
                            continue
                        stack_top = stack_test
                        #                        print('stack_top', end='')
                        #                        print_ss(stack_top)
                        angle_found = True
                        ind_2 = np.delete(ind_2,
                                          np.argwhere(ind_2 == ind_ply_2)[0])
                        ply_queue.remove(angle)
                        break

                if angle_found:
                    break

        if not angle_found:
            # return semi-repaired stacking sequence
            for ind in ind_2:
                if ss[ind] != 666:
                    stack_top = np.hstack((stack_top, ss[ind]))
                else:
                    stack_top = np.hstack((stack_top, ply_queue.pop(0)))
            stack = np.hstack((stack_top, stack_bottom))
            return stack, False

    if stack_bottom.size + stack_top.size \
    < ss.size - n_D1:
        # return semi-repaired stacking sequence
        raise Exception('This should not happen anymore')

#    print('stack_bottom', end='')
#    print_ss(stack_bottom)
#    print('stack_top', end='')
#    print_ss(stack_top)

# plies at the centre all designed simultaneously
    good_permut = []
    real_n_D1 = ind_2.size
    remaining_plies = np.empty((real_n_D1, ), int)
    for counter, ind in enumerate(ind_2):
        if ss[ind] != 666:
            remaining_plies[counter] = ss[ind]
        else:
            remaining_plies[counter] = ply_queue.pop(0)
#    print('remaining_plies', remaining_plies)

    if constraints.dam_tol:
        if hasattr(constraints, 'dam_tol_rule') \
        and constraints.dam_tol_rule in {2, 3}:
            mini_bottom = max(1, stack_bottom.size - real_n_D1 - 1)
            mini_top = min(stack_bottom.size - 1, real_n_D1 + 1)
        if not hasattr(constraints, 'dam_tol_rule') and \
        constraints.n_plies_dam_tol == 2:
            mini_bottom = max(1, stack_bottom.size - real_n_D1 - 1)
            mini_top = min(stack_bottom.size - 1, real_n_D1 + 1)
        else:
            mini_bottom = max(0, stack_bottom.size - real_n_D1 - 1)
            mini_top = min(stack_bottom.size, real_n_D1 + 1)
    else:
        mini_bottom = max(0, stack_bottom.size - real_n_D1 - 1)
        mini_top = min(stack_bottom.size, real_n_D1 + 1)

    ind_2 = np.sort(ind_2)
    for elem in itertools.permutations(range(real_n_D1)):
        #        print('elem', elem)
        ss_group = remaining_plies[np.array(elem, int)]
        stack_test = np.hstack(
            (stack_top[mini_bottom:], ss_group, stack_bottom[:mini_top]))
        #        print('stack_test', stack_test)
        if constraints.diso and not is_diso_ss(
                stack_test, constraints.delta_angle, dam_tol=False):
            continue
        if constraints.contig and not is_contig(stack_test,
                                                constraints.n_contig_c):
            continue
        good_permut.append(np.array(elem, int))
#        print('stack_test', stack_test, elem)
#    print('good_permut', good_permut)

    good_permut = smallest_row(good_permut)
    #    print('good_permut', good_permut)

    if good_permut is None:
        # return semi-repaired stacking sequence
        stack = np.hstack((stack_top, remaining_plies, stack_bottom))
        return stack, False


#    remaining_plies = remaining_plies[good_permut]
    stack = np.hstack((stack_top, remaining_plies[good_permut], stack_bottom))

    if stack.size != ss.size:
        raise Exception('This should not happen')
    return stack, True
Esempio n. 7
0
def repair_diso_contig_from_inside_sym(ss, ply_queue, constraints, n_D1):
    """
    attempts at repairing the stacking sequence to satisfy the disorientation
    and contiguity rule for symmetric laminates with swaps from the inside out
    of the laminates

    INPUTS

    - ss: partially retrieved stacking sequence
    - ply_queue: queue of plies for innermost plies
    - constraints: design and manufacturing constraints
    - n_D1: number of plies in the last permutation
    """
    stack_dam_tol, stack, ind_1, ind_2 = \
    initialise_repair_diso_contig(
        ss, constraints, from_inside=True,
        n_D1=n_D1)
    #    print('ind_1', ind_1)
    #    print('ind_2', ind_2)

    for ind_ply_1 in ind_1:
        #        print('ind_ply_1', ind_ply_1)
        angle_found = False

        for ind_ply_2 in ind_2:
            #            print('    ind_ply_2', ind_ply_2)

            if ss[ind_ply_2] != 666:
                stack_test = np.hstack((ss[ind_ply_2], stack, ss[ind_ply_2]))
                #                print('stack_test', stack_test)
                if constraints.diso and not is_diso(
                        stack_test[0], stack_test[1], constraints.delta_angle):
                    continue
                if constraints.contig and not is_contig(
                        stack_test[:2 * constraints.n_contig],
                        constraints.n_contig):
                    continue
                stack = stack_test
                ind_2 = np.delete(ind_2, np.argwhere(ind_2 == ind_ply_2))
                angle_found = True
                #                print_ss(stack, 13)
                break

            else:  # let's pick a ply from the queue
                angles_to_test = order_plies_to_test([stack[-1]], ply_queue,
                                                     constraints)
                for angle in angles_to_test:
                    stack_test = np.hstack((angle, stack, angle))
                    #                    print('stack_test', stack_test)
                    if constraints.diso and not is_diso(
                            stack_test[0], stack_test[1],
                            constraints.delta_angle):
                        continue
                    if constraints.contig and not is_contig(
                            stack_test[:2 * constraints.n_contig],
                            constraints.n_contig):
                        continue
                    stack = stack_test
                    ind_2 = np.delete(ind_2,
                                      np.argwhere(ind_2 == ind_ply_2)[0])
                    ply_queue.remove(angle)
                    angle_found = True
                    print_ss(stack, 13)
                    break

                if angle_found:
                    break

        if not angle_found:
            # return semi-repaired stacking sequence
            for ind_ply_2 in ind_2:
                if ss[ind_ply_2] != 666:
                    angle = ss[ind_ply_2]
                else:
                    angle = ply_queue.pop(0)
                stack = np.hstack((angle, stack, angle))
            stack = np.hstack((stack_dam_tol, stack, np.flip(stack_dam_tol)))
            return stack, False

    if stack.size + 2*stack_dam_tol.size \
    < ss.size - 2*n_D1:
        # return semi-repaired stacking sequence
        raise Exception('This should not happen anymore')

#    print_ss(stack)

# plies at the centre all designed simultaneously
    good_permut = []
    real_n_D1 = ind_2.size
    remaining_plies = np.empty((real_n_D1, ), int)
    for counter, ind in enumerate(ind_2):
        if ss[ind] != 666:
            remaining_plies[counter] = ss[ind]
        else:
            remaining_plies[counter] = ply_queue.pop(0)
#    print('remaining_plies', remaining_plies)

    for elem in itertools.permutations(range(real_n_D1)):
        ss_group = remaining_plies[np.array(elem, int)]
        if constraints.dam_tol:
            stack_test = np.hstack((stack_dam_tol[-1], ss_group))
        else:
            stack_test = ss_group
        stack_test = np.hstack((stack_test, stack, np.flip(stack_test)))
        stack_test = stack_test[:2 + 2 * constraints.n_contig \
                                + real_n_D1]
        #        print('stack_test', stack_test)
        if constraints.diso and not is_diso_ss(
                stack_test, constraints.delta_angle, dam_tol=False):
            continue
        if constraints.contig and not is_contig(stack_test,
                                                constraints.n_contig_c):
            continue
        good_permut.append(np.array(elem, int))


#    print('good_permut', good_permut)

    good_permut = smallest_row(good_permut)
    if good_permut is None:
        # return semi-repaired stacking sequence
        stack = np.hstack((np.flip(remaining_plies), stack, remaining_plies))
        stack = np.hstack((stack_dam_tol, stack, np.flip(stack_dam_tol)))
        return stack, False

    stack = np.hstack(
        (stack_dam_tol, remaining_plies[good_permut], stack,
         np.flip(remaining_plies[good_permut]), np.flip(stack_dam_tol)))
    if stack.size != ss.size:
        raise Exception('This should not happen')
    return stack, True
Esempio n. 8
0
def repair_diso_contig_from_outside_sym(ss, ply_queue, constraints, n_D1):
    """
    attempts at repairing the stacking sequence to satisfy the disorientation
    and contiguity rule for symmetric laminates with swaps performed inwardly
    in the laminates

    INPUTS

    - ss: partially retrieved stacking sequence
    - ply_queue: queue of plies for innermost plies
    - constraints: design and manufacturing constraints
    - n_D1: number of plies in the last permutation
    """
    #    print(constraints)
    #    print('n_D1', n_D1)
    #    print_ss(ss)
    #    print('ply_queue', ply_queue)

    stack, ind_1, ind_2 = initialise_repair_diso_contig(ss,
                                                        constraints,
                                                        from_inside=False,
                                                        n_D1=n_D1)
    #    print('ind_1', ind_1)
    #    print('ind_2', ind_2)

    for ind_ply_1 in ind_1:
        #        print('ind_ply_1', ind_ply_1)
        angle_found = False

        for ind_ply_2 in ind_2:
            #            print('    ind_ply_2', ind_ply_2)

            if ss[ind_ply_2] != 666:
                stack_test = np.hstack((stack, ss[ind_ply_2]))
                #                print('stack_test', stack_test)
                if constraints.diso and not is_diso(stack_test[-1],
                                                    stack_test[-2],
                                                    constraints.delta_angle):
                    continue

                if constraints.dam_tol:
                    if hasattr(constraints, 'dam_tol_rule') \
                    and constraints.dam_tol_rule in {2, 3}:
                        mini = max(1,
                                   stack_test.size - constraints.n_contig - 1)
                    if not hasattr(constraints, 'dam_tol_rule') and \
                    constraints.n_plies_dam_tol == 2:
                        mini = max(1,
                                   stack_test.size - constraints.n_contig - 1)
                    else:
                        mini = max(0,
                                   stack_test.size - constraints.n_contig - 1)
                else:
                    mini = max(0, stack_test.size - constraints.n_contig - 1)

                if constraints.contig and not is_contig(
                        stack_test[mini:], constraints.n_contig):
                    continue
                stack = stack_test
                ind_2 = np.delete(ind_2, np.argwhere(ind_2 == ind_ply_2))
                angle_found = True
                #                print_ss(stack, 13)
                break

            else:  # let's pick a ply from the queue
                angles_to_test = order_plies_to_test([stack[-1]], ply_queue,
                                                     constraints)
                for angle in angles_to_test:
                    stack_test = np.hstack((stack, angle))
                    #                    print('stack_test', stack_test)
                    if constraints.diso and not is_diso(
                            stack_test[-1], stack_test[-2],
                            constraints.delta_angle):
                        continue

                    if constraints.dam_tol:
                        if hasattr(constraints, 'dam_tol_rule') \
                        and constraints.dam_tol_rule in {2, 3}:
                            mini = max(
                                1, stack_test.size - constraints.n_contig - 1)
                        if not hasattr(constraints, 'dam_tol_rule') and \
                        constraints.n_plies_dam_tol == 2:
                            mini = max(
                                1, stack_test.size - constraints.n_contig - 1)
                        else:
                            mini = max(
                                0, stack_test.size - constraints.n_contig - 1)
                    else:
                        mini = max(0,
                                   stack_test.size - constraints.n_contig - 1)

                    if constraints.contig and not is_contig(
                            stack_test[mini:], constraints.n_contig):
                        continue
                    stack = stack_test
                    ind_2 = np.delete(ind_2,
                                      np.argwhere(ind_2 == ind_ply_2)[0])
                    ply_queue.remove(angle)
                    #                    print_ss(stack, 13)
                    angle_found = True
                    break

                if angle_found:
                    break

        if not angle_found:
            # return semi-repaired stacking sequence
            for ind in ind_2:
                if ss[ind] != 666:
                    stack = np.hstack((stack, ss[ind]))
                else:
                    stack = np.hstack((stack, ply_queue.pop(0)))
            if ss.size % 2:
                stack = np.hstack((stack, ss[ss.size // 2], np.flip(stack)))
            else:
                stack = np.hstack((stack, np.flip(stack)))
            return stack, False

    if stack.size < ss.size // 2 - n_D1:
        # return semi-repaired stacking sequence
        raise Exception('This should not happen anymore')

#    print_ss(stack)

# plies at the centre all designed simultaneously
    good_permut = []
    real_n_D1 = ind_2.size
    remaining_plies = np.empty((real_n_D1, ), int)
    for counter, ind in enumerate(ind_2):
        if ss[ind] != 666:
            remaining_plies[counter] = ss[ind]
        else:
            remaining_plies[counter] = ply_queue.pop(0)
#    print('remaining_plies', remaining_plies)

    if constraints.dam_tol:
        if hasattr(constraints, 'dam_tol_rule') \
        and constraints.dam_tol_rule in {2, 3}:
            mini = max(1, stack.size - real_n_D1 - 1)
        if not hasattr(constraints, 'dam_tol_rule') and \
        constraints.n_plies_dam_tol == 2:
            mini = max(1, stack.size - real_n_D1 - 1)
        else:
            mini = max(0, stack.size - real_n_D1 - 1)
    else:
        mini = max(0, stack.size - real_n_D1 - 1)

    for elem in itertools.permutations(range(real_n_D1)):
        ss_group = remaining_plies[np.array(elem, int)]

        stack_test = np.hstack((stack[mini:], ss_group))
        if ss.size % 2:
            stack_test = np.hstack((stack_test, ss[ss.size // 2],
                                    np.flip(stack_test[-real_n_D1:])))
        else:
            stack_test = np.hstack(
                (stack_test, np.flip(stack_test[-real_n_D1:])))
        if constraints.diso and not is_diso_ss(
                stack_test, constraints.delta_angle, dam_tol=False):
            continue
        if constraints.contig and not is_contig(stack_test,
                                                constraints.n_contig_c):
            continue
        good_permut.append(np.array(elem, int))


#    print('good_permut', good_permut)

    good_permut = smallest_row(good_permut)
    if good_permut is None:
        # return semi-repaired stacking sequence
        stack = np.hstack((stack, remaining_plies))
        if ss.size % 2:
            stack = np.hstack((stack, ss[ss.size // 2]))
        stack = np.hstack((stack, np.flip(stack)))
        if ss.size % 2:
            stack = np.delete(stack, np.s_[ss.size // 2])
        return stack, False

    stack = np.hstack((stack, remaining_plies[good_permut]))
    if ss.size % 2:
        stack = np.hstack((stack, ss[ss.size // 2], np.flip(stack)))
    else:
        stack = np.hstack((stack, np.flip(stack)))
    if stack.size != ss.size:
        raise Exception('This should not happen')
    return stack, True
    popu.loc[ind, 'diso'] = is_diso_ss(stack,
                                       delta_angle=constraints.delta_angle,
                                       dam_tol=constraints.dam_tol,
                                       dam_tol_rule=constraints.dam_tol_rule)

    if (abs(lampam[2:4]) > 1e-10).any():
        popu.loc[ind, 'ipo'] = False
    else:
        popu.loc[ind, 'ipo'] = True

    if is_balanced(stack, constraints):
        popu.loc[ind, 'balance'] = True
    else:
        popu.loc[ind, 'balance'] = False

    if is_contig(stack, constraints.n_contig):
        popu.loc[ind, 'contig'] = True
    else:
        popu.loc[ind, 'contig'] = False

    if is_ten_percent_rule(constraints, stack=stack):
        popu.loc[ind, 'rule_10_percent'] = True
    else:
        popu.loc[ind, 'rule_10_percent'] = False

save_constraints_LAYLA(filename, constraints)
save_materials(filename, mat_prop)
append_df_to_excel(filename, popu, 'stacks', index=True, header=True)
autofit_column_widths(filename)
Esempio n. 10
0
def generate_ss_LAYLA(n_plies, constraints, not_constraints):
    """
    randomly generates lamination parameters and retrieves stacking sequences
    satisfying the design guidelines using LAYLA

    Args:
        n_plies (scalar): number of plies in the laminate
        constraints (instance of the class Constraints): set of constraints
            that must be satisfied
        not_constraints (instance of the class Constraints): set of constraints
            that must not be satisfied

    Returns:
        a manufacturable stacking sequence and its lamination parameters
        created by the optimiser LAYLA aiming at matching lamination parameter
        targets randomly generated
    """
    if constraints.diso and not_constraints.diso:
        raise Exception("""
Decide whether or not the stacking sequences must satisfy disorientation""")
    if constraints.contig and not_constraints.contig:
        raise Exception("""
Decide whether or not the stacking sequences must satisfy contiguity""")
    if constraints.ipo and not_constraints.ipo:
        raise Exception("""
Decide whether or not the stacking sequences must satisfy balance""")
    if constraints.rule_10_percent and not_constraints.rule_10_percent:
        raise Exception("""
Decide whether or not the stacking sequences must satisfy 10% rule""")

    #==========================================================================
    # LAYLA parameters
    #==========================================================================
    n_outer_step = 1

    first_outer_loop_assumption = 'layerwise_QI'

    method = 'beam_search'  # with beam search
    global_node_limit = 20
    local_node_limit = 10
    global_node_limit_p = 20

    pseudo = True

    repair_membrane_switch = True
    repair_flexural_switch = True

    penalty_10_pc_switch = False
    penalty_10_lampam_switch = False
    penalty_ipo_switch = True
    penalty_bal_switch = False
    balanced_scheme = False

    coeff_10 = 1
    coeff_bal_ipo = 1
    coeff_oopo = 1

    p_A = 100
    n_D1 = 6
    n_D2 = 10

    group_size_min = 5
    group_size_max = np.array([1000, 12, 12, 12, 12])

    if constraints.set_of_angles is np.array([-45, 0, 45, 90], int):
        lampam_to_be_optimised = np.array([1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0])
    else:
        lampam_to_be_optimised = np.array([1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1])

    first_level_sensitivities = np.ones((12, ), float)

    while True:

        lampam_target = 2 * np.random.random_sample((12, )) - 1
        #        lampam_target = np.array([
        #            -0.25662112, -0.01727515, -0.73962959, 0.08359081,
        #            0.43671968, -0.7901057, 0.98404481, 0.65070345,
        #            0.97056517, 0.7023994, 0.32539113, -0.35851357])
        #        print('lampam_target', lampam_target)

        parameters = Parameters(
            constraints=constraints,
            lampam_target=lampam_target,
            coeff_10=coeff_10,
            coeff_bal_ipo=coeff_bal_ipo,
            coeff_oopo=coeff_oopo,
            p_A\
            =p_A,
            n_D1=n_D1,
            n_D2=n_D2,
            n_outer_step=n_outer_step,
            group_size_min=group_size_min,
            group_size_max=group_size_max,
            first_level_sensitivities=first_level_sensitivities,
            lampam_to_be_optimised=lampam_to_be_optimised,
            method=method,
            first_outer_loop_assumption=first_outer_loop_assumption,
            global_node_limit=global_node_limit,
            local_node_limit=local_node_limit,
            global_node_limit_p=global_node_limit_p,
            pseudo=pseudo,
            repair_membrane_switch=repair_membrane_switch,
            repair_flexural_switch=repair_flexural_switch,
            penalty_10_lampam_switch=penalty_10_lampam_switch,
            penalty_10_pc_switch=penalty_10_pc_switch,
            penalty_ipo_switch=penalty_ipo_switch,
            penalty_bal_switch=penalty_bal_switch,
            balanced_scheme=balanced_scheme)

        try:
            result = optimisation(parameters,
                                  constraints,
                                  np.copy(lampam_target),
                                  n_plies,
                                  not_constraints=not_constraints)
        except SystemExit:
            break

        ss = result[0]  # solution stacking sequence
        lampam = result[1]  # solution lamination parameters

        if not ss.size == n_plies:
            raise Exception('Wrong laminate ply count')

        try:
            check_lay_up_rules(ss, constraints)
        except:
            continue

        if hasattr(constraints, 'dam_tol_rule'):
            if not_constraints.diso and is_diso_ss(
                    ss,
                    not_constraints.delta_angle,
                    dam_tol=constraints.dam_tol,
                    dam_tol_rule=constraints.dam_tol_rule):
                continue
        else:
            if not_constraints.diso and is_diso_ss(
                    ss,
                    not_constraints.delta_angle,
                    dam_tol=constraints.dam_tol,
                    n_plies_dam_tol=constraints.n_plies_dam_tol):
                continue

        if not_constraints.contig and is_contig(ss, not_constraints.n_contig):
            continue

        if not_constraints.rule_10_percent \
        and is_ten_percent_rule(not_constraints, stack=ss):
            continue

        if not_constraints.ipo \
        and abs(lampam[2]) < 1e-10 and abs(lampam[3]) < 1e-10:
            continue


#
#        if is_ten_percent_rule(not_constraints, stack=ss) \
#        and abs(lampam[2]) < 1e-10 and abs(lampam[3]) < 1e-10:
#            continue

        break

    return ss, lampam
Esempio n. 11
0
def generate_ss_randomly(n_plies, constraints, not_constraints):
    """
    randomly generates stacking sequences satisfying the design guidelines

    INPUTS

    n_plies: number of plies in the laminate
    constraints: set of constraints that must be satisfied
    not_constraints: set of constraints that must not be satisfied
    """
    if constraints.diso and not_constraints.diso:
        raise Exception("""
Decide whether or not the stacking sequences must satisfy disorientation""")
    if constraints.contig and not_constraints.contig:
        raise Exception("""
Decide whether or not the stacking sequences must satisfy contiguity""")
    if constraints.ipo and not_constraints.ipo:
        raise Exception("""
Decide whether or not the stacking sequences must satisfy balance""")
    if constraints.rule_10_percent and not_constraints.rule_10_percent:
        raise Exception("""
Decide whether or not the stacking sequences must satisfy 10% rule""")

    if constraints.dam_tol and constraints.dam_tol_rule not in {1, 2}:
        raise Exception("""
Only coded for damage tolerance rules 0, 1 and 2.""")

    if not_constraints.rule_10_percent:
        n_plies_0_lim = ma.ceil(not_constraints.percent_0 * n_plies)
        n_plies_90_lim = ma.ceil(not_constraints.percent_90 * n_plies)
        n_plies_45_lim = ma.ceil(not_constraints.percent_45 * n_plies)
        n_plies_135_lim = ma.ceil(not_constraints.percent_135 * n_plies)
        n_plies_45_135_lim = ma.ceil(not_constraints.percent_45_135 * n_plies)
        if constraints.sym:
            n_plies_0_lim = ma.ceil(n_plies_0_lim / 2)
            n_plies_90_lim = ma.ceil(n_plies_90_lim / 2)
            n_plies_45_lim = ma.ceil(n_plies_45_lim / 2)
            n_plies_135_lim = ma.ceil(n_plies_135_lim / 2)
            n_plies_45_135_lim = ma.ceil(n_plies_45_135_lim / 2)
#    print('n_plies_0_lim', n_plies_0_lim)
#    print('n_plies_45_lim', n_plies_45_lim)

    while True:

        ss = np.array((), int)
        n0 = 0
        n90 = 0

        if not_constraints.rule_10_percent:
            random_for_10 = random.randint(0, 4)

        if constraints.dam_tol:

            if constraints.dam_tol_rule == 1:

                reduced_n_plies = n_plies - 2

                if random.randint(0, 1):
                    ss = np.array(([45]), int)
                    if constraints.sym:
                        n45 = 2
                        n135 = 0
                    else:
                        n45 = 4
                        n135 = 0
                else:
                    ss = np.array(([-45]), int)
                    if constraints.sym:
                        n45 = 0
                        n135 = 2
                    else:
                        n45 = 0
                        n135 = 4

            elif constraints.dam_tol_rule == 2:

                reduced_n_plies = n_plies - 4

                if random.randint(0, 1):
                    ss = np.array(([45, -45]), int)
                else:
                    ss = np.array(([-45, 45]), int)
                if constraints.sym:
                    n45 = 2
                    n135 = 2
                else:
                    n45 = 4
                    n135 = 4

        else:
            reduced_n_plies = n_plies
            n45 = 0
            n135 = 0

        if constraints.sym:
            reduced_n_plies //= 2

        if constraints.dam_tol and constraints.dam_tol_rule == 2:
            ss = ss[1:]

        for ind in range(reduced_n_plies):

            angle_added = False

            for angle in np.random.permutation(constraints.set_of_angles):

                ss_test = np.hstack((ss, angle))
                #                print_ss(ss_test)

                if internal_diso_contig(ss_test, constraints)[0].size == 0:
                    continue

                if not_constraints.rule_10_percent:
                    if random_for_10 == 0 and n0 + 1 >= n_plies_0_lim:
                        continue
                    if random_for_10 == 1 and n90 + 1 >= n_plies_90_lim:
                        continue
                    if random_for_10 == 2 and n45 + 1 >= n_plies_45_lim:
                        continue
                    if random_for_10 == 3 and n135 + 1 >= n_plies_135_lim:
                        continue
                    if random_for_10 == 4 \
                    and n45 + n135 + 1 >= n_plies_45_135_lim:
                        continue

                angle_added = True
                if angle == 0:
                    n0 += 1
                elif angle == 90:
                    n90 += 1
                elif angle == 45:
                    n45 += 1
                elif angle == -45:
                    n135 += 1
                ss = ss_test

                #                print_ss(ss)
                break

            if not angle_added:
                break

        if not angle_added:
            continue

        if constraints.dam_tol and constraints.dam_tol_rule == 2:
            ss = ss = np.hstack((-np.array(ss[0]), ss))

        if constraints.sym:
            if n_plies % 2:
                if random.randint(0, 1):
                    ss = np.hstack((ss, 0, np.flip(ss)))
                    n0 += 1
                else:
                    ss = np.hstack((ss, 90, np.flip(ss)))
                    n90 += 1
            else:
                ss = np.hstack((ss, np.flip(ss)))
        else:
            if constraints.dam_tol:
                if random.randint(0, 1):
                    ss = np.hstack((ss, 45, -45))
                else:
                    ss = np.hstack((ss, -45, 45))

        if not ss.size == n_plies:
            raise Exception('Wrong laminate ply count')

        try:
            check_lay_up_rules(ss, constraints)
        except:
            continue

        if hasattr(constraints, 'dam_tol_rule'):
            if not_constraints.diso and is_diso_ss(
                    ss,
                    not_constraints.delta_angle,
                    dam_tol=constraints.dam_tol,
                    dam_tol_rule=constraints.dam_tol_rule):
                continue
        else:
            if not_constraints.diso and is_diso_ss(
                    ss,
                    not_constraints.delta_angle,
                    dam_tol=constraints.dam_tol,
                    n_plies_dam_tol=constraints.n_plies_dam_tol):
                continue

        if not_constraints.contig and is_contig(ss, not_constraints.n_contig):
            continue

        if not_constraints.rule_10_percent \
        and is_ten_percent_rule(not_constraints, stack=ss):
            continue

        lampam = calc_lampam(ss)

        if not_constraints.bal \
        and abs(lampam[2]) < 1e-10 and abs(lampam[3]) < 1e-10:
            continue

        break

    return ss, lampam