Msc.Marc的python开发#2
今天接着上一篇的文章介绍。上一篇说到,利用Msc.Marc的python接口,实现自动定义材料的功能,主要用到的是Marc配置的py_mentat模块,核心思想其实很简单,那就是 一个换了python皮的procedure 文件 ,换句话说,把需要人工输入的命令汇集到python源文件中,并通过命令行和Marc进行交互,向Marc下各种命令,并获得Marc 的数据库中的各种数据。
那么今天我们要用python进行Marc的后处理,用的是py_post模块。这个模块在应用上更接近python的面向对象特点,单元、节点都有自己的类,ID、坐标都成为了类的属性,访问起来更方便更有逻辑。
开发目的
我今天要做的事情是针对一个钢筋混凝土框架,想办法调整配筋数据,使得经过某个地震波的时程分析后,只出现梁端塑性铰,而不出现柱端塑性铰,而且要尽可能接近临界状态,也就是钢筋不能超配太多。我的基础是用PKPM按中国规范分析得出的配筋数据。Marc模型是梁柱纤维梁模型,搭配课题组开发的纤维梁子程序。
流程图
整体结构
单元结构
应用实例
from itertools import islice
import time
import os
from py_post import *
from py_mentat import *
HEIGHT = 4000 # height of a single story(length of a column)
LENGTH = 5000 # length of a beam
all_materials = {}
column_hinges = []
tol = 0.05
class beam_comp(object): # define compona_fiber beam element class
def __init__(self, string):
data = string.split(',')
self.lamb_low = 1.0
self.lamb_high = 5.0
self.lamb_mid = 1.0
self.Nfloor = int(data[0])
self.Nbeam = int(data[1])
self.name = 'F' + data[0] + 'L' + data[1] # name
self.Num_Rc = int(data[2])
self.Num_S = int(data[3])
self.dx = float(data[4])
self.dy = float(data[5])
self.bc = float(data[6])
self.hc = float(data[7])
self.Crt = float(data[8])
self.Crb = float(data[9])
self.Crl = float(data[10])
self.Crr = float(data[11])
self.Art = float(data[12])
self.Arb = float(data[13])
self.Arl = float(data[14])
self.Arr = float(data[15])
self.Ar1 = float(data[16])
self.Ar2 = float(data[17])
self.Ar3 = float(data[18])
self.Ar4 = float(data[19])
self.nf_bc = int(data[20])
self.nf_hc = int(data[21])
self.nrt = int(data[22])
self.nrb = int(data[23])
self.nrl = int(data[24])
self.nrr = int(data[25])
self.fc = float(data[26])
self.kt = float(data[27])
self.frt = float(data[28])
self.frb = float(data[29])
self.frl = float(data[30])
self.frr = float(data[31])
self.fr1 = float(data[32])
self.fr2 = float(data[33])
self.fr3 = float(data[34])
self.fr4 = float(data[35])
self.CFT = int(data[36])
self.Sig_de = float(data[37])
class colm_comp(object): # define compona_fiber beam element class
def __init__(self, string):
data = string.split(',')
self.lamb_low = 1.0
self.lamb_high = 5.0
self.lamb_mid = 1.0
self.Nfloor = int(data[0])
self.Nbeam = int(data[1])
self.name = 'F' + data[0] + 'C' + data[1] # name
self.Num_Rc = int(data[2])
self.Num_S = int(data[3])
self.dx = float(data[4])
self.dy = float(data[5])
self.bc = float(data[6])
self.hc = float(data[7])
self.Crt = float(data[8])
self.Crb = float(data[9])
self.Crl = float(data[10])
self.Crr = float(data[11])
self.Art = float(data[12])
self.Arb = float(data[13])
self.Arl = float(data[14])
self.Arr = float(data[15])
self.Ar1 = float(data[16])
self.Ar2 = float(data[17])
self.Ar3 = float(data[18])
self.Ar4 = float(data[19])
self.nf_bc = int(data[20])
self.nf_hc = int(data[21])
self.nrt = int(data[22])
self.nrb = int(data[23])
self.nrl = int(data[24])
self.nrr = int(data[25])
self.fc = float(data[26])
self.kt = float(data[27])
self.frt = float(data[28])
self.frb = float(data[29])
self.frl = float(data[30])
self.frr = float(data[31])
self.fr1 = float(data[32])
self.fr2 = float(data[33])
self.fr3 = float(data[34])
self.fr4 = float(data[35])
self.CFT = int(data[36])
self.Sig_de = float(data[37])
def initate_mat(all_materials):
with open('section_beam.csv') as file:
for content in islice(file, 1, None):
new_beam_comp = beam_comp(content)
all_materials[new_beam_comp.name] = new_beam_comp
file.close()
with open('section_colu.csv') as file:
for content in islice(file, 1, None):
new_colm_comp = colm_comp(content)
all_materials[new_colm_comp.name] = new_colm_comp
file.close()
return
def initate_from_info():
pass
return
def write_secinfo(all_materials):
with open('secinfo.txt', 'wt') as db:
db.write('%d\n' % len(all_materials))
for i_floor in range(1, 5):
for i_beam in range(1, 25):
name = 'F%dL%d' % (i_floor, i_beam)
db.write(
'%d,%d\n' %
(all_materials[name].Num_Rc, all_materials[name].Num_S))
db.write('%.6f,%.6f\n' %
(all_materials[name].dx, all_materials[name].dy))
db.write('%.6f,%.6f\n' %
(all_materials[name].bc, all_materials[name].hc))
db.write('%.6f,%.6f,%.6f,%.6f\n' %
(all_materials[name].Crt, all_materials[name].Crb,
all_materials[name].Crl, all_materials[name].Crr))
db.write('%.6f,%.6f,%.6f,%.6f\n' %
(all_materials[name].Art, all_materials[name].Arb,
all_materials[name].Arl, all_materials[name].Arr))
db.write('%.6f,%.6f,%.6f,%.6f\n' %
(all_materials[name].Ar1, all_materials[name].Ar2,
all_materials[name].Ar3, all_materials[name].Ar4))
db.write(
'%d,%d\n' %
(all_materials[name].nf_bc, all_materials[name].nf_hc))
db.write('%d,%d,%d,%d\n' %
(all_materials[name].nrt, all_materials[name].nrb,
all_materials[name].nrl, all_materials[name].nrr))
db.write('%.6f,%.6f\n' %
(all_materials[name].fc, all_materials[name].kt))
db.write('%.6f,%.6f,%.6f,%.6f\n' %
(all_materials[name].frt, all_materials[name].frb,
all_materials[name].frl, all_materials[name].frr))
db.write('%.6f,%.6f,%.6f,%.6f\n' %
(all_materials[name].fr1, all_materials[name].fr2,
all_materials[name].fr3, all_materials[name].fr4))
db.write('%d\n' % all_materials[name].CFT)
db.write('%.6f\n' % all_materials[name].Sig_de)
for i_floor in range(1, 5):
for i_column in range(1, 17):
name = 'F%dC%d' % (i_floor, i_column)
db.write(
'%d,%d\n' %
(all_materials[name].Num_Rc, all_materials[name].Num_S))
db.write('%.6f,%.6f\n' %
(all_materials[name].dx, all_materials[name].dy))
db.write('%.6f,%.6f\n' %
(all_materials[name].bc, all_materials[name].hc))
db.write('%.6f,%.6f,%.6f,%.6f\n' %
(all_materials[name].Crt, all_materials[name].Crb,
all_materials[name].Crl, all_materials[name].Crr))
db.write('%.6f,%.6f,%.6f,%.6f\n' %
(all_materials[name].Art, all_materials[name].Arb,
all_materials[name].Arl, all_materials[name].Arr))
db.write('%.6f,%.6f,%.6f,%.6f\n' %
(all_materials[name].Ar1, all_materials[name].Ar2,
all_materials[name].Ar3, all_materials[name].Ar4))
db.write(
'%d,%d\n' %
(all_materials[name].nf_bc, all_materials[name].nf_hc))
db.write('%d,%d,%d,%d\n' %
(all_materials[name].nrt, all_materials[name].nrb,
all_materials[name].nrl, all_materials[name].nrr))
db.write('%.6f,%.6f\n' %
(all_materials[name].fc, all_materials[name].kt))
db.write('%.6f,%.6f,%.6f,%.6f\n' %
(all_materials[name].frt, all_materials[name].frb,
all_materials[name].frl, all_materials[name].frr))
db.write('%.6f,%.6f,%.6f,%.6f\n' %
(all_materials[name].fr1, all_materials[name].fr2,
all_materials[name].fr3, all_materials[name].fr4))
db.write('%d\n' % all_materials[name].CFT)
db.write('%.6f\n' % all_materials[name].Sig_de)
db.close()
return
def get_name_postel(pObj, ind_elem):
# obtain the name 'FXXX' for a post element
element = pObj.element(ind_elem)
nodes = element.items
node1 = pObj.node(nodes[0] - 1)
node2 = pObj.node(nodes[1] - 1)
if (node1.z == node2.z): # it's a beam
# we should allocate ID to the beam according the rule of serial number
# which is
# 1. beams parallel to the x axis come first(left to right)
# 2. then beams parallel to the y axis(left to right)
Nfloor = int(node1.z / HEIGHT)
if (node1.x == node2.x): # if the beam is parallel to the y axis.
Nbeam = 4 + int(node1.x / LENGTH) + int(
(node1.y + node2.y) / (2 * LENGTH)) * 7
else: # if the beam is parallel to the x axis
Nbeam = 1 + int(node1.y / LENGTH) * 7 + int(
(node1.x + node2.x) / (2 * LENGTH))
name = 'F%dL%d' % (Nfloor, Nbeam) # assemble the name of beam element
else: # it's a column
Nfloor = int((node1.z + node2.z) / (2 * HEIGHT)) + 1
Ncolu = int(node1.x / LENGTH) + 4 * int(node1.y / LENGTH) + 1
name = 'F%dC%d' % (Nfloor, Ncolu)
return name
def tell_if_colu(pObj, ind_elem):
element = pObj.element(ind_elem)
nodes = element.items
node1 = pObj.node(nodes[0] - 1)
node2 = pObj.node(nodes[1] - 1)
if (node1.z == node2.z): # it's a beam
return False
else:
return True
def get_last_line(inputfile):
filesize = os.path.getsize(inputfile)
blocksize = 1024
with open(inputfile, 'rb') as f:
last_line = ""
if filesize > blocksize:
maxseekpoint = (filesize // blocksize)
f.seek((maxseekpoint - 1) * blocksize)
elif filesize:
f.seek(0, 0)
lines = f.readlines()
if lines:
linenum = 1
while last_line == "":
last_line = lines[-linenum].strip()
linenum += 1
f.close()
return last_line
def run_job():
py_send('*edit_job Time-history')
py_send('*submit_job 1 *monitor_job')
print('\tjob is running')
time.sleep(420)
while True:
print('looping...')
last_line = get_last_line('model1_Time-history.log')
if last_line[-4:] == '3004':
break
else:
print('\tjob is running')
time.sleep(30)
return 1
def post_extract():
global column_hinges
pObj = post_open("model1_Time-history.t16")
# move to the last increment
ninc = pObj.increments() # the number total increments
pObj.moveto(ninc - 1)
# check each element for the user defined variable 3,
# if it's 1, collect it in a library
nelem = pObj.elements() # the number of total elements
nes = pObj.element_scalars() # number of scalars acquired for each element
for i in range(nes):
if pObj.element_scalar_label(i) == 'User Defined Variable 3':
ind_UDV3 = i
curr_colu_hinges = []
for i_elem in range(nelem):
slist = pObj.element_scalar(i_elem, ind_UDV3)
if (slist[0].value == 1 or slist[1].value == 1):
name = get_name_postel(pObj, i_elem)
if tell_if_colu(pObj, i_elem):
column_hinges.append(name)
curr_colu_hinges.append(name)
column_hinges = undupli(column_hinges)
curr_colu_hinges = undupli(curr_colu_hinges)
pObj.close()
return curr_colu_hinges
def undupli(input_list):
output_list = []
for item in input_list:
if item in output_list:
continue
else:
output_list.append(item)
output_list.sort()
return output_list
def tell_first_floor(column_hinges):
# if all elements in column_hinges are on first floor
# then return true, else return false
logic_flag = True
for name in column_hinges:
logic_flag = logic_flag and (name[1]=='1')
return logic_flag
def adjust_area(all_materials, column_hinges, curr_colu_hinges):
if len(column_hinges) == 0 or tell_first_floor(column_hinges):
return False
else:
for name in column_hinges:
column = all_materials[name]
if abs(column.lamb_high - column.lamb_low) < tol:
lamb_pre = column.lamb_mid
column.lamb_mid = column.lamb_high
# prepare for a restart
column.lamb_high = column.lamb_mid + 1
column.lamb_low = max(column.lamb_mid-1, column.lamb_low)
column.Art = column.lamb_mid/lamb_pre * column.Art
column.Arb = column.lamb_mid/lamb_pre * column.Arb
column.Arl = column.lamb_mid/lamb_pre * column.Arl
column.Arr = column.lamb_mid/lamb_pre * column.Arr
column.Ar1 = column.lamb_mid/lamb_pre * column.Ar1
column.Ar2 = column.lamb_mid/lamb_pre * column.Ar2
column.Ar3 = column.lamb_mid/lamb_pre * column.Ar3
column.Ar4 = column.lamb_mid/lamb_pre * column.Ar4
all_materials[name] = column
column_hinges.remove(name)
else:
if name in curr_colu_hinges:
column.lamb_low = column.lamb_mid
else:
column.lamb_high = column.lamb_mid
lamb_pre = column.lamb_mid
column.lamb_mid = (column.lamb_low + column.lamb_high) / 2.0
column.Art = column.lamb_mid/lamb_pre * column.Art
column.Arb = column.lamb_mid/lamb_pre * column.Arb
column.Arl = column.lamb_mid/lamb_pre * column.Arl
column.Arr = column.lamb_mid/lamb_pre * column.Arr
column.Ar1 = column.lamb_mid/lamb_pre * column.Ar1
column.Ar2 = column.lamb_mid/lamb_pre * column.Ar2
column.Ar3 = column.lamb_mid/lamb_pre * column.Ar3
column.Ar4 = column.lamb_mid/lamb_pre * column.Ar4
all_materials[name] = column
return True
def main():
global all_materials
global column_hinges
log = open('python.log', 'wt')
print('\tlog has been opened')
initate_mat(all_materials)
print('\tmaterials has been initated')
iteration = 1
print('iteration %d' % iteration)
write_secinfo(all_materials)
print('\tsecinfo has been writen')
run_job()
print('\tjob has been run')
curr_colu_hinges = post_extract()
print('\tlenth of column_hinges list: %d' % len(column_hinges))
for name in column_hinges:
log.write('\t%s has lambda %f\n' % (name, all_materials[name].lamb_mid))
print('\t%s has lambda %f' % (name, all_materials[name].lamb_mid))
print('\titeration completed')
while adjust_area(all_materials, column_hinges, curr_colu_hinges):
iteration += 1
print('iteration %d' % iteration)
log.write('\niteration %d\n' % iteration)
write_secinfo(all_materials)
print('\tsecinfo has been writen')
run_job()
print('\tjob has been run')
curr_colu_hinges = post_extract()
print('\tlenth of column_hinges list: %d' % len(column_hinges))
log.write('\ncolumn_hinges\n')
for name in column_hinges:
log.write('\t%s has lambda %f \n' % (name, all_materials[name].lamb_mid))
print('\t%s has lambda %f' % (name, all_materials[name].lamb_mid))
print('\tcurrent_hinges')
log.write('\tcurrent_hinges\n')
for name in curr_colu_hinges:
log.write('\t%s has lambda %f \n' % (name, all_materials[name].lamb_mid))
print('\t%s has lambda %f' % (name, all_materials[name].lamb_mid))
print('\niteration completed\n')
for key in all_materials:
log.write('%s: %f \n' % (all_materials[key].name, all_materials[key].lamb_mid))
print('finish')
log.write('\nfinish\n')
log.close()
return
if __name__ == '__main__':
py_connect("", 40007)
main()
py_disconnect()