def get_link_geo(s2k_data, nodes_instances, s2k_to_rmk_nd, get_rmk_link_props, mmbr_no): """ Converts the s2k links connectivity to member geometry """ raw_strct_link_geo = {} links_instances = {} # {unique height : a Links instance} # Organize the local axes assignment for use later s2k_loc_axs = data_retriever(s2k_data, cfg.title_link_lcl_axs) get_loc_axs = {line[cfg.link_axs] : line[cfg.angle] for line in s2k_loc_axs} # Organize the link connectivity for use later s2k_link_conn = data_retriever(s2k_data, cfg.title_link_conn) # Converts the member geometry (links) from s2k to rmk format for line in s2k_link_conn: # Group the members in terms of their storey or as column nd_k = s2k_to_rmk_nd[line[cfg.joint_i]] nd_l = s2k_to_rmk_nd[line[cfg.joint_j]] prop_no = get_rmk_link_props[line[cfg.link_conn]] if line[cfg.link_conn] in get_loc_axs.keys(): # Get the local axis 2 angle if local axis 2 is rotated angle = int(get_loc_axs[line[cfg.link_conn]]) else: angle = 0 for height, stry_nds_inst in nodes_instances.items(): # Find which storey joints i and j belongs to stry_ndl_data = stry_nds_inst.stry_data if nd_k in stry_ndl_data.keys(): if height not in links_instances.keys(): # Self update the StoreyBeams instances container links_instances.update({height : Links(height)}) # Set the member data of this beam member if nd_l not in stry_ndl_data.keys(): links_instances[height].set_mmbr_data(line[cfg.link_conn], prop_no, angle, nd_k, stry_ndl_data[nd_k], nd_l, stry_ndl_data[nd_k]) else: links_instances[height].set_mmbr_data(line[cfg.link_conn], prop_no, angle, nd_k, stry_ndl_data[nd_k], nd_l, stry_ndl_data[nd_l]) # Generate the rmk_link_geo and updates mmbr_no for stry_link_inst in links_instances.values(): mmbr_no = stry_link_inst.refine_mmbr_data(mmbr_no) raw_strct_link_geo.update(stry_link_inst.rmk_stry_link_geo) return raw_strct_link_geo, mmbr_no, links_instances
def convert(s2k_data): """ Converts the s2k joint coordinates to rmk nodal definitions. This is the main function of this module which executes the other functions. """ nodes_instances = {} # {unique height : a StoreyNodes instance} raw_strct_ndl_pnt = {} # {s2k joint ID : storey rmk_ndl_pnt} stry_data = {} # {rmk node no. : {x-coord, y-coord, z-coord}} # Organize the joint restraints for use later s2k_jnt_rstrt = data_retriever(s2k_data, cfg.title_joint_restraint) jnts_to_rstrt = {line[cfg.jnt_rstrt]: line for line in s2k_jnt_rstrt} # Organize the joint coordinates for use later s2k_jnt_coords = data_retriever(s2k_data, cfg.title_joint_coordinates) # {joint vertical position : corresponding s2k_jnt_coords line} rfd_jnt = {} for line in s2k_jnt_coords: # Group the joints in terms of their vertical position rfd_jnt = entry_cnstrt_sorter(rfd_jnt, line[cfg.z], line) # Obtain the unique heights of every joints unq_heights = list(rfd_jnt.keys()) unq_heights.sort() # Set the node no. and node coords for height in unq_heights: # Create an instance of StoreyNodes to service each unique height nodes_instances.update({height: StoreyNodes(height)}) raw_strct_ndl_pnt, stry_data = nodes_instances[height].set_nd_coords( raw_strct_ndl_pnt, stry_data, rfd_jnt[height], jnts_to_rstrt, (2 * len(unq_heights) - 2)) # Apply rigid diaphragm effect and body constraints raw_strct_ndl_pnt, weight_instances = constrainer(s2k_data, raw_strct_ndl_pnt, stry_data) # Create a printable outputs in rmk format for raw_strct_ndl_pnt rmk_ndl_pnt_txt = txt_format(raw_strct_ndl_pnt) return rmk_ndl_pnt_txt, nodes_instances, weight_instances
def get_link_mmbr_props(s2k_data, raw_strct_mmbr_props): """ Converts the s2k 1-joint link sections to rmk member properties. """ get_rmk_link_props = {} # {s2k link_1 no. : rmk props no.} # Organize the link section assignment for use later s2k_sec_ass = data_retriever(s2k_data, cfg.title_link_prop) for line in s2k_sec_ass: link_no = line[cfg.link] prop_no = len(raw_strct_mmbr_props) + 1 sec_id = line[cfg.prop_link].strip('"') rmk_line_1 = { 'N': prop_no, 'MYTYPE': 'SPRING', 'LABEL': '"{}"'.format(sec_id) } rmk_line_2 = { 'ITYPE': 1, 'IHYST': 0, 'ILOS': 0, 'IDAMG': 0, 'INCOND': 0, 'ITRUSS': 0, 'SL': 0, 'Y0': 0, 'Z0': 0, 'ISTOP': 0 } rmk_line_3 = { 'K1': 0, 'K2': 0, 'K3': 0, 'K4': 0, 'K5': 0, 'K6': 0, 'WGT': 0, 'RF': 0, 'RT': 0 } if rmk_line_1['LABEL'] not in raw_strct_mmbr_props.keys(): raw_strct_mmbr_props.update( {rmk_line_1['LABEL']: [rmk_line_1, rmk_line_2, rmk_line_3]}) else: prop_no = raw_strct_mmbr_props[rmk_line_1['LABEL']][0]['N'] get_rmk_link_props.update({link_no: prop_no}) return raw_strct_mmbr_props, get_rmk_link_props
def get_partial_fixity(self): txt_form = '{0}\t\t\t\t\t{1}\t{2}\t\t\t\t\t{3}\t{4}'.format( self.frame_id, self.M2I, self.M3I, self.M2J, self.M3J) return txt_form s2k_file_path = 'Apartment Building Model - 25d.s2k' # Get the raw s2k file (s2k_raw) and its associated table of contents with open(s2k_file_path, 'r') as s2k_file: s2k_data = get_s2k_data(s2k_file) # Frame ID -> Length s2k_frm_conn = data_retriever(s2k_data, cfg.title_frame_conn) get_frm_len = {line[cfg.frame_conn]: line[cfg.length] for line in s2k_frm_conn} # Section name -> I33 s2k_sec_def = data_retriever(s2k_data, cfg.title_frame_sec_def) get_sec_I33 = {} get_sec_I22 = {} for line in s2k_sec_def: get_sec_I33.update({line[cfg.sec_name]: line[cfg.sec_Izz]}) get_sec_I22.update({line[cfg.sec_name]: line[cfg.sec_Iyy]}) # Frame ID -> section name s2k_sec_ass = data_retriever(s2k_data, cfg.title_frame_sec_ass) get_sec_name = { line[cfg.frame_sec]: line[cfg.sect_name] for line in s2k_sec_ass
def get_frm_mmbr_props(s2k_data, raw_strct_mmbr_props): """ Converts the s2k frame sections to rmk member properties. """ get_rmk_frm_props = {} # {s2k frame no. : rmk props no.} # Organize the material mechanical properties s2k_mat_mech = data_retriever(s2k_data, cfg.title_mat_mech) get_mat_mech = { line[cfg.material]: { 'E': line[cfg.E], 'G': line[cfg.G] } for line in s2k_mat_mech if {cfg.E, cfg.G}.issubset(line.keys()) } # Organize the frame section definition for use later s2k_sec_def = data_retriever(s2k_data, cfg.title_frame_sec_def) get_sec_def_data = {line[cfg.sec_name]: line for line in s2k_sec_def} # Organize the frame section assignment for use later s2k_sec_ass = data_retriever(s2k_data, cfg.title_frame_sec_ass) # Organize the frame release assignment for use later s2k_frm_rel = data_retriever(s2k_data, cfg.title_frame_release) get_frm_rel = {line[cfg.frame_rel]: line for line in s2k_frm_rel} # Organize the frame partial fixity assignment for use later s2k_part_fix = data_retriever(s2k_data, cfg.title_partial_fix) get_part_fix = {line[cfg.frame_rel]: line for line in s2k_part_fix} # Organize the frame offset assignment for use later s2k_frm_off = data_retriever(s2k_data, cfg.title_frame_offset) get_frm_off = { line[cfg.frame_off]: line for line in s2k_frm_off if {cfg.off_y, cfg.off_z}.issubset(line.keys()) } for line in s2k_sec_ass: frm_no = line[cfg.frame_sec] prop_no = len(raw_strct_mmbr_props) + 1 sec_id = line[cfg.sect_name].strip('"') sec_def_data = get_sec_def_data[line[cfg.sect_name]] mat_id = sec_def_data[cfg.sec_material] rmk_line_1 = { 'N': prop_no, 'MYTYPE': 'FRAME', 'LABEL': '"{}'.format(sec_id) } rmk_line_2 = { 'ITYPE': 1, 'IPINZ': 0, 'IPINY': 0, 'ICOND': 0, 'IHYST': 0, 'ILOS': 0, 'IDAMG': 0, 'IGA': 0, 'IDUCT': 0 } rmk_line_3 = { 'E': get_mat_mech[mat_id]['E'], 'G': get_mat_mech[mat_id]['G'], 'A': sec_def_data[cfg.sec_area], 'Jxx': sec_def_data[cfg.sec_Jxx], 'Izz': sec_def_data[cfg.sec_Izz], 'Iyy': sec_def_data[cfg.sec_Iyy], 'Asz': sec_def_data[cfg.sec_Asz], 'Asy': sec_def_data[cfg.sec_Asy], 'Sy': 0, 'Sz': 0, 'WGT': 0 } rmk_line_4 = { 'END1z': 0, 'END2z': 0, 'END1y': 0, 'END2y': 0, 'FJ1z': 0, 'FJ2z': 0, 'FJ1y': 0, 'FJ2y': 0, 'Y0': 0, 'Z0': 0 } if frm_no in get_part_fix.keys(): part_fix_line = get_part_fix[frm_no] rmk_line_4, add_sec_id = process_part_fix(part_fix_line, rmk_line_4) rmk_line_1['LABEL'] += add_sec_id elif frm_no in get_frm_rel.keys(): frm_rel_line = get_frm_rel[frm_no] rmk_line_2, add_sec_id = process_frm_release( frm_rel_line, rmk_line_2) rmk_line_1['LABEL'] += add_sec_id if frm_no in get_frm_off.keys(): frm_off_line = get_frm_off[frm_no] rmk_line_4, add_sec_id = process_frm_offset( frm_off_line, rmk_line_4) rmk_line_1['LABEL'] += add_sec_id rmk_line_1['LABEL'] += '"' if rmk_line_1['LABEL'] not in raw_strct_mmbr_props.keys(): raw_strct_mmbr_props.update({ rmk_line_1['LABEL']: [rmk_line_1, rmk_line_2, rmk_line_3, rmk_line_4] }) else: prop_no = raw_strct_mmbr_props[rmk_line_1['LABEL']][0]['N'] get_rmk_frm_props.update({frm_no: prop_no}) return raw_strct_mmbr_props, get_rmk_frm_props
def constrainer(s2k_data, raw_strct_ndl_pnt, stry_data): """ This function produces the constraint data (body constraint and rigid diaphragm constrain) for all the nodes in raw_strct_ndl_pnt. It then updates the boundary_cnstrt code for all DoFs and master node no. of raw_strct_ndl_pnt. """ # Organize the joint to be constrained and constraint definitions for use later s2k_jnt_cnstrt = data_retriever(s2k_data, cfg.title_joint_constraint) s2k_cnstrt_def = data_retriever(s2k_data, cfg.title_constraint_definitions) # {constraint title : [[joints to constraint], {constraint data}]} rfd_body = {} # {constraint title : [joints to constraint]} rfd_diaph = {} for line in s2k_jnt_cnstrt: # Separate values for rfd_body and rfd_diaph from s2k_jnt_cnstrt if line[cfg.typ] == cfg.body: rfd_body = entry_cnstrt_sorter(rfd_body, line[cfg.cnstrt], line[cfg.jnt_cnstrt]) elif line[cfg.typ] == cfg.diaph: rfd_diaph = entry_cnstrt_sorter(rfd_diaph, line[cfg.cnstrt], line[cfg.jnt_cnstrt]) for line in s2k_cnstrt_def: # Append the constraint data from s2k_cnstrt_def to rfd_body try: rfd_body[line[cfg.name]].append(line) except KeyError: continue # Get the centre of mass and assign it as the master node of the # diaphragm constraint weight_instances, raw_strct_ndl_pnt, get_com = lumped_weights.get_com( s2k_data, rfd_diaph, stry_data, raw_strct_ndl_pnt) # Apply the rigid diaphragm constraints and update the raw_strct_ndl_pnt for diaph_id, group in rfd_diaph.items(): # Iterate through rfd_diaph.values() mstr_nd = get_com[diaph_id] for jnt_id in group: # Set rigid diaphragm raw_strct_ndl_pnt[jnt_id]['N1'] = 2 raw_strct_ndl_pnt[jnt_id]['N3'] = 2 raw_strct_ndl_pnt[jnt_id]['N5'] = 2 raw_strct_ndl_pnt[jnt_id]['KUP1'] = mstr_nd # Apply the body constraints and update the raw_strct_ndl_pnt for group in rfd_body.values(): # Iterate through rfd_body.values() ordered_nodes = list(map(int, group[0:-1])) ordered_nodes.sort() ordered_nodes = list(map(str, ordered_nodes)) mstr_nd = ordered_nodes[ 0] # Master node is the first entry_cnstrt (random) # of the rfd_body.values() list cnstrt_def = group[-1] for jnt_id in ordered_nodes[1:]: # Constraint the DoFs of a node based on the s2k definition master_1 = [] if cnstrt_def[cfg.ux_cnstrt] == cfg.yes: raw_strct_ndl_pnt[jnt_id]['N1'] = 3 master_1.append(raw_strct_ndl_pnt[jnt_id]['N1']) if cnstrt_def[cfg.uz_cnstrt] == cfg.yes: raw_strct_ndl_pnt[jnt_id]['N2'] = 3 master_1.append(raw_strct_ndl_pnt[jnt_id]['N2']) if cnstrt_def[cfg.uy_cnstrt] == cfg.yes: raw_strct_ndl_pnt[jnt_id]['N3'] = 3 # NOTE: Ruaumoko swaps the y-axis and z-axis master_1.append(raw_strct_ndl_pnt[jnt_id]['N3']) if cnstrt_def[cfg.rx_cnstrt] == cfg.yes: raw_strct_ndl_pnt[jnt_id]['N4'] = 3 master_1.append(raw_strct_ndl_pnt[jnt_id]['N4']) if cnstrt_def[cfg.rz_cnstrt] == cfg.yes: raw_strct_ndl_pnt[jnt_id]['N5'] = 3 master_1.append(raw_strct_ndl_pnt[jnt_id]['N5']) if cnstrt_def[cfg.ry_cnstrt] == cfg.yes: raw_strct_ndl_pnt[jnt_id]['N6'] = 3 # NOTE: Ruaumoko swaps the y-axis and z-axis master_1.append(raw_strct_ndl_pnt[jnt_id]['N6']) if 2 not in master_1: # If all the DoFs are slaved to a node, then change the 3 to 2 if raw_strct_ndl_pnt[jnt_id]['N1'] == 3: raw_strct_ndl_pnt[jnt_id]['N1'] -= 1 if raw_strct_ndl_pnt[jnt_id]['N2'] == 3: raw_strct_ndl_pnt[jnt_id]['N2'] -= 1 if raw_strct_ndl_pnt[jnt_id]['N3'] == 3: raw_strct_ndl_pnt[jnt_id]['N3'] -= 1 if raw_strct_ndl_pnt[jnt_id]['N4'] == 3: raw_strct_ndl_pnt[jnt_id]['N4'] -= 1 if raw_strct_ndl_pnt[jnt_id]['N5'] == 3: raw_strct_ndl_pnt[jnt_id]['N5'] -= 1 if raw_strct_ndl_pnt[jnt_id]['N6'] == 3: raw_strct_ndl_pnt[jnt_id]['N6'] -= 1 raw_strct_ndl_pnt[jnt_id]['KUP1'] = ( raw_strct_ndl_pnt[mstr_nd]['N']) else: raw_strct_ndl_pnt[jnt_id]['KUP2'] = ( raw_strct_ndl_pnt[mstr_nd]['N']) return raw_strct_ndl_pnt, weight_instances
def get_beam_col_geo(s2k_data, nodes_instances, s2k_to_rmk_nd, get_rmk_frm_props, mmbr_no): """ Converts the s2k frames connectivity to beams and columns geometry """ raw_strct_beam_col_geo = {} beams_instances = {} # {unique height : a StoreyBeams instance} cols_instances = {} # {unique coords : a Columns instance} # Organize the local axes assignment for use later s2k_loc_axs = data_retriever(s2k_data, cfg.title_frm_lcl_axs) get_loc_axs = {line[cfg.frame_axs] : line[cfg.angle] for line in s2k_loc_axs} # Organize the frame connectivity for use later s2k_frm_conn = data_retriever(s2k_data, cfg.title_frame_conn) # Converts the member geometry (beams and columns) from s2k to rmk format for line in s2k_frm_conn: # Group the members in terms of their storey or as column nd_k = s2k_to_rmk_nd[line[cfg.joint_i]] # Joint i (origin) nd_l = s2k_to_rmk_nd[line[cfg.joint_j]] # Joint j prop_no = get_rmk_frm_props[line[cfg.frame_conn]] if line[cfg.frame_conn] in get_loc_axs.keys(): # Get the local axis 2 angle if local axis 2 is rotated angle = int(get_loc_axs[line[cfg.frame_conn]]) else: angle = 0 for height, stry_nds_inst in nodes_instances.items(): # Find which storey joints i and j belongs to stry_ndl_data = stry_nds_inst.stry_data if nd_k in stry_ndl_data.keys() and nd_l in stry_ndl_data.keys(): # Following lines deal with beam members if height not in beams_instances.keys(): # Self update the StoreyBeams instances container beams_instances.update({height : StoreyBeams(height)}) # Set the member data of this beam member beams_instances[height].set_mmbr_data(line[cfg.frame_conn], prop_no, angle, nd_k, stry_ndl_data[nd_k], nd_l, stry_ndl_data[nd_l]) elif nd_k in stry_ndl_data.keys(): # Following lines deal with column members # Get horizontal coords of the column: (x,z) col_coords = (stry_ndl_data[nd_k]['X'], stry_ndl_data[nd_k]['Z']) if col_coords not in cols_instances.keys(): # Self update the Columns instance container cols_instances.update({col_coords : Columns(col_coords)}) # Set the member data of this column member cols_instances[col_coords].set_mmbr_data(line[cfg.frame_conn], prop_no, angle, nd_k, nd_l, height) # Generate the rmk_beam_geo and updates mmbr_no for stry_beam_inst in beams_instances.values(): mmbr_no = stry_beam_inst.refine_mmbr_data(mmbr_no) raw_strct_beam_col_geo.update(stry_beam_inst.raw_stry_beam_geo) # Generate the rmk_col_geo and updates mmbr_no for col_inst in cols_instances.values(): mmbr_no = col_inst.refine_mmbr_data(mmbr_no) raw_strct_beam_col_geo.update(col_inst.rmk_col_geo) return raw_strct_beam_col_geo, mmbr_no, beams_instances, cols_instances