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, parameters=parameters, lampam_target=lampam_target) print('\nFinal stacking sequence') print_ss(ss, 1000) if not is_diso_ss(ss,
if ss.ndim == 2: ss = np.hstack((ss, np.flip(ss, axis=1))) else: ss = np.hstack((ss, np.flip(ss, axis=0))) # Storage of the stacking sequence ss = np.ravel(ss) N0 = sum(ss == 0) N90 = sum(ss==90) N45 = sum(ss==45) N135 = sum(ss==-45) ss = ss.astype(int) #print(ipop, N0, N90, N45, N135) lampam = calc_lampam(ss, constraints) Pop.loc[ipop, 'ply_counts'] = n_plies_in_panels Pop.loc[ipop, 'lampam[1]'] = lampam[0] Pop.loc[ipop, 'lampam[2]'] = lampam[1] Pop.loc[ipop, 'lampam[3]'] = lampam[2] Pop.loc[ipop, 'lampam[4]'] = lampam[3] Pop.loc[ipop, 'lampam[5]'] = lampam[4] Pop.loc[ipop, 'lampam[6]'] = lampam[5] Pop.loc[ipop, 'lampam[7]'] = lampam[6] Pop.loc[ipop, 'lampam[8]'] = lampam[7] Pop.loc[ipop, 'lampam[9]'] = lampam[8] Pop.loc[ipop, 'lampam[10]'] = lampam[9] Pop.loc[ipop, 'lampam[11]'] = lampam[10] Pop.loc[ipop, 'lampam[12]'] = lampam[11]
def repair_ss(ss, constraints, parameters, targets, obj_no_constraints=None, count_obj=False): """ repairs stacking sequences to meet design and manufacturing guidelines and evaluates the performance of the repaired stacking sequence The repair process is deterministic and attempts at conducting minimal modification of the original stacking sequence with a preference for modifying outer plies that have the least influence on out-of-plane properties. step 1: repair for the 10% rule and balance step 2: refinement for in-plane lamination parameter convergence step 3: repair for disorientation and contiguity step 4: refinement for out-of-plane lamination parameter convergence (step 5: attribute a poor objective function value to unrepaired layups) OUTPUTS - INPUTS - ss: stacking sequence of the laminate - lampam_target: lamination parameter targets - constraints: instance of the class Constraints - parameters: instance of the class Parameters - count_obj: flag to count the number of objective function calls (- obj_no_constraints: objective function value of the initial stacking sequence with no consideration of design and manufacturing constraints) """ ss_ini = np.copy(ss) mini_10 = calc_mini_10(constraints, ss.size) # print('before repair') # print_ss(ss_ini) #-------------------------------------------------------------------------- # step 1 / repair for the 10% rule and balance #-------------------------------------------------------------------------- ss, ply_queue = repair_10_bal(ss, mini_10, constraints) # print('after repair 10 and balance') # print_ss(ss) # print(ply_queue) #-------------------------------------------------------------------------- # step 2 / improvement of the in-plane lamination parameter convergence #-------------------------------------------------------------------------- ss_list, ply_queue_list, _ = repair_membrane( ss=ss, ply_queue=ply_queue, mini_10=mini_10, in_plane_coeffs=parameters.weighting_finalA, parameters=parameters, constraints=constraints, lampam_target=targets.lampam) # print('after repair for membrane properties') # for ind in range(len(ss_list)): # print('ind', ind) # print('ss_list[ind]', ss_list[ind]) # print('ply_queue_list[ind]', ply_queue_list[ind]) # if not is_ten_percent_rule(constraints, stack=ss_list[ind], # ply_queue=ply_queue_list[ind]): # print('lampam_target', lampam_target[0:4]) # raise Exception('10% rule not satisfied membrane') # print('ss_list[0]') # print_ss(ss_list[0]) # print('ply_queue_list[0]', ply_queue_list[0]) #-------------------------------------------------------------------------- # step 3 / repair for disorientation and contiguity #-------------------------------------------------------------------------- ss, completed_inward, completed_outward, ind = repair_diso_contig_list( ss_list, ply_queue_list, constraints, parameters.n_D1) # print('completed_inward, completed_outward, ind', # completed_inward, completed_outward, ind) if not completed_outward: # print('unsuccessful repair for disorientation and/or contiguity') if obj_no_constraints is None: if count_obj: return ss_ini, False, 0 else: return ss_ini, False if count_obj: return ss_ini, False, 1e10, 0 else: return ss_ini, False, 1e10 # print('successful repair for disorientation and/or contiguity') # print_ss(ss) #-------------------------------------------------------------------------- # step 4 / improvement of the out-of-plane lamination parameter convergence #-------------------------------------------------------------------------- ss = repair_flexural(ss=ss, out_of_plane_coeffs=parameters.weighting_finalD, lampam_target=targets.lampam, constraints=constraints, parameters=parameters, count_obj=count_obj) if count_obj: ss, n_obj_func_D_calls = ss # print(' after repair') # print_ss(ss) # print('lampam_target', lampam_target) if obj_no_constraints is None: if count_obj: return ss, True, n_obj_func_D_calls else: return ss, True #-------------------------------------------------------------------------- # step 5 / #-------------------------------------------------------------------------- obj_no_constraints = objectives( lampam=calc_lampam(ss, constraints), targets=targets, lampam_weightings=parameters.lampam_weightings_final, constraints=constraints, parameters=parameters) if count_obj: return ss, True, 1e10, n_obj_func_D_calls else: return ss, True, 1e10
print( 'Result:', calc_delta_lampamD_swap(angle_first=45, angle_second=-45, pos_first=np.array([26], int), pos_second=np.array([22], int), n_plies=30, constraints=constraints)) print('\n*** Test for the function calc_delta_lampamD_swap_1 ***\n') print('Inputs:') ss_ini = np.array([0, 0, 0, 0, 0, 90, 45, 45, 45, 90, 90, 90], int) print('Initial stacking sequence') print_ss(ss_ini, 40) ss = np.array([45, 45, 45, 0, 0, 90, 0, 0, 0, 90, 90, 90], int) print('Final stacking sequence') print_ss(ss, 40) print('Expected result:', (calc_lampam(ss, constraints) - calc_lampam(ss_ini))[8:12]) angle_first = 0 angle_second = 45 n_first_ply = 1 n_second_ply = 7 n_plies = 12 n_plies_group = 3 constraints = Constraints(sym=False) print( 'Result:', calc_delta_lampamD_swap_1(angle_first, angle_second, n_first_ply, n_second_ply, n_plies_group, n_plies, constraints))
A = A_from_lampam(lampam, mat) B = B_from_lampam(lampam, mat, sym) D = D_from_lampam(lampam, mat) d = np.linalg.inv(D - B @ (np.linalg.inv(A)) @ B) return d if __name__ == "__main__": print('*** Test for the functions of the module ABD ***\n') import sys sys.path.append(r'C:\LAYLA') from src.CLA.lampam_functions import calc_lampam from src.LAYLA_V02.materials import Material ss = np.array([0, 45, 45, -45, -45, 90, 0, 90]) ss = np.hstack((ss, np.flip(ss, axis=0))) lampam = calc_lampam(ss) E11 = 130e9 E22 = 9e9 nu12 = 0.3 G12 = 4e9 threshold = 0.01 mat = Material(E11=E11, E22=E22, G12=G12, nu12=nu12) sym = False A = A_from_lampam(lampam, mat) B = B_from_lampam(lampam, mat, sym) D = D_from_lampam(lampam, mat) filter_ABD(A, B, D, sym=sym, ply_t=0.0002) a = a_from_lampam(lampam, mat, sym) d = d_from_lampam(lampam, mat, sym) a2, d2 = ad_from_lampam(lampam, mat, sym) print('A = ', A)
ss = np.array([ 45, 0, 45, 0, -45, 45, 45, 0, 45, 0, -45, 45, 45, -45, -45, -45, 45, -45, 45, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 45, -45, 45, -45, -45, -45, 45, 45, -45, 0, 45, 0, 45, 45, -45, 0, 45, 0, 45 ], int) ply_queue = [90, 90, 90, -45, -45, -45, 90, 90, 90, -45, -45, -45] n_plies = ss.size lampamA = calc_lampamA_ply_queue(ss, n_plies, ply_queue, constraints) ss = np.array([ 45, 0, 45, 0, -45, 45, 45, 0, 45, 0, -45, 45, 45, -45, -45, -45, 45, -45, 45, 90, 90, 90, -45, -45, -45, 90, 90, 90, -45, -45, -45, 45, -45, 45, -45, -45, -45, 45, 45, -45, 0, 45, 0, 45, 45, -45, 0, 45, 0, 45 ], int) lampamA_check = calc_lampam(ss, constraints)[0:4] print('lampamA', lampamA) print('lampamA_check', lampamA_check) print() constraints = Constraints(sym=True, set_of_angles=[0, 45, 30, -30, -45, 60, -60, 90]) ss = np.array([ 45, 0, 45, 0, -45, 45, 45, 0, 45, 0, -45, 45, 45, -45, -45, -45, 45, -45, 45, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, 45, -45, 45, -45, -45, -45, 45, 45, -45, 0, 45, 0, 45, 45, -45, 0, 45, 0, 45 ], int) ply_queue = [90, 90, 90, -45, -45, -45] n_plies = ss.size lampamA = calc_lampamA_ply_queue(ss, n_plies, ply_queue, constraints)
for ind, stack in enumerate( itertools.product(constraints.set_of_angles, repeat=n_plies)): if not ind % 100: print('ind', ind) popu.loc[ind, 'ply_count'] = 2 * n_plies ss_flatten = np.array(stack, dtype=str) ss_flatten = ' '.join(ss_flatten) popu.loc[ind, 'half_stack'] = ss_flatten stack = np.hstack((stack, np.flip(stack))) lampam = calc_lampam(stack, constraints) popu.loc[ind, 'lampam1'] = lampam[0] popu.loc[ind, 'lampam2'] = lampam[1] popu.loc[ind, 'lampam3'] = lampam[2] popu.loc[ind, 'lampam4'] = lampam[3] popu.loc[ind, 'lampam5'] = lampam[4] popu.loc[ind, 'lampam6'] = lampam[5] popu.loc[ind, 'lampam7'] = lampam[6] popu.loc[ind, 'lampam8'] = lampam[7] popu.loc[ind, 'lampam9'] = lampam[8] popu.loc[ind, 'lampam10'] = lampam[9] popu.loc[ind, 'lampam11'] = lampam[10] popu.loc[ind, 'lampam12'] = lampam[11] A = A_from_lampam(lampam, mat_prop)
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
#============================================================================== n_values = 100 theta = np.linspace(-90, 90, n_values, endpoint=True) lampam = np.zeros((n_values, 12), float) D11 = np.zeros((n_values, ), float) D22 = np.zeros((n_values, ), float) D12 = np.zeros((n_values, ), float) D66 = np.zeros((n_values, ), float) buck = np.zeros((n_values, ), float) for index in range(n_values): ss = np.zeros((1, ), float) ss[0] = theta[index] lampam[index] = calc_lampam(ss) D = D_from_lampam(lampam[index], mat) D11[index] = D[0, 0] D22[index] = D[1, 1] D12[index] = D[0, 1] D66[index] = D[2, 2] buck[index] = buckling_factor(lampam[index], mat, n_plies=1, N_x=10, N_y=10, length_x=0.1, length_y=0.1) fig, ax = plt.subplots(1, 1, sharex=True, figsize=(8, 5.8)) # sharex=True to align x-axes of the graphs