Article Directory
python Development for Msc.Marc#1
Msc.Marc is a practical finite element calculation software, but its own Mentat preprocessing is very difficult to use.Of course, we can choose the Patan pre-processing program launched by Msc, but there is still some learning curve requirements after all, and I do not want to change it for the time being.So how can you improve the modeling efficiency of the existing crappy Mentat?
In fact, the procedure file that comes with Mentat can be used to record a lot of basic, repetitive work.However, the procedure file cannot have complex selections or loops, which limits the power of the procedure file.
Marc's developers have long thought about this, and like other large software, Marc has left out the python interface for us to batch with python.
Pre-Configuration
I'm using the Marc2015 + Visual studio 2012 + Intel visual fortran 2013 configuration
IVF was used because one of the subroutines I used needed to be developed in Fortran and plugged into the Ubeam interface provided by Marc.
The Python on a PC was originally 3.8, which is well packaged to keep up with the times. However, the python interface on Marc has its own python.exe, or version 2.X (which I haven't looked at yet) which makes Python on a PC unusable and all kinds of packages useless.I was in a hurry to install the package where Marc's Core Python interface module py_mentat is located, but bug s continue due to version compatibility issues.I had to temporarily discard my habitual bag and go to battle lightly, using only the python body.Fortunately, the current problem is relatively simple, and python ontology can solve it.
Core Ideas
The core idea of Marc's Python interface is that it's a procedure file with Python skin replaced.Or, gather commands that require manual input into a python source file, interact with Marc from the command line, submit commands to Marc, and obtain data from Marc's database.
Core Interaction Functions and Database Functions
Core Interaction Functions:
- py_send() #A function that sends commands to Marc, typically with a string starting with * representing different operations.For example:
- py_send("*new_mater standard *mater_option general:state:solid *mater_option general:skip_structural:off")
- py_send("*mater_name %s" % name)
- py_send("*mater_param general:mass_density 2.5e-9")
- py_send("*mater_option structural:type:elast_plast_ortho")
- py_send("*mater_option structural:type:hypo_elast")
- py_send("*mater_option structural:hypoelastic_method:ubeam")
- py_send("*mater_option structural:damping:on")
- py_send("*mater_param structural:rayleigh_damping_stiff_mult 0.0136764")
The code above sets up the necessary operating instructions for building a material, including building a new material, setting the type of material to standard, entering the name of the material, setting the density, setting the symmetry, elastic behavior, connecting to the ubeam subprogram interface, opening the damp switch, and setting the damp factor.You might ask, Marc has tens of millions of instructions, how do I remember the code for each one?It's easy to think about these instructions by first using the mouse on Marc and then finding the corresponding instructions in the procedure file.
- The functions py_get_int() and py_get_float() #are used to extract data from Marc's database.Parentheses are extraction parameters, such as
- n = py_get_int("nelements()") #Get the total number of cells in the model
- node1.x=py_get_float("node_x(%d)"%node1.ID) #Gets the overall x-coordinate of the specified node
Database functions:
- nnodes( ) #Number of nodes in database
- node_id(ARG1) #ID of ARG1-th node in database
- max_node_id( ) #Largest node ID in database
- node_x(arg1) #Global X-coordinate of node arg1
- node_y(arg1) #Global Y-coordinate of node arg1
- node_z(arg1) #Global Z-coordinate of node arg1
- nelements( ) Number of elements in database
- element_id(ARG1) ID of ARG1-th element in database
- max_element_id( ) Largest element id in database
- element_node_id(arg1,ARG2) ID of ARG2-th node of element arg1
More functions can be referenced Marc®Python 2015: Tutorial and Reference Manual
Application Instances
The code below reads in the properties of a section from a csv file, names each material, establishes them sequentially in entat, and assigns the corresponding properties.Material and units are then matched according to certain rules
from py_mentat import * # import the py_mentat module, which is foundamental class beam(object): def __init__(self, string): data = string.split(',') self.Nfloor = int(data[0]) self.Nbeam = int(data[1]) self.name = 'F'+data[0]+'L'+data[1] class column(object): def __init__(self, string): data = string.split(',') self.Nfloor = int(data[0]) self.Ncolu = int(data[1]) self.name = 'F'+data[0]+'C'+data[1] class node(object): ID=0 x=0.0 y=0.0 z=0.0 def add_matl(name): py_send("*new_mater standard *mater_option general:state:solid *mater_option general:skip_structural:off") py_send("*mater_name %s" % name) py_send("*mater_param general:mass_density 2.5e-9") py_send("*mater_option structural:type:elast_plast_ortho") py_send("*mater_option structural:type:hypo_elast") py_send("*mater_option structural:hypoelastic_method:ubeam") py_send("*mater_option structural:damping:on") py_send("*mater_param structural:rayleigh_damping_stiff_mult 0.0136764") return def beam_add(beams): # add elements for all materials # take-in parameter:beams, a list containing all the beam elements in order node_beams = {} # beam dictionary takes 'FXLX' as key for i in range(len(beams)): node_beams[beams[i].name]=[] py_send("*renumber_all") n = py_get_int("nelements()") for i in range(1,n+1): # acquire the ID of the nodes linked by one element, and do this procedure for each element node1=node() node1.ID=py_get_int("element_node_id(%d,%d)"%(i,1)) node2=node() node2.ID=py_get_int("element_node_id(%d,%d)"%(i,2)) node1.x=py_get_float("node_x(%d)"%node1.ID) node1.y=py_get_float("node_y(%d)"%node1.ID) node1.z=py_get_float("node_z (%d)"%node1.ID) node2.x=py_get_float("node_x(%d)"%node2.ID) node2.y=py_get_float("node_y(%d)"%node2.ID) node2.z=py_get_float("node_z (%d)"%node2.ID) if (node1.z ==node2.z):# it's a beam Nfloor = int(node1.z/4000) if(node1.x==node2.x): Nbeam = 4 + int(node1.x/5000) + int((node1.y+node2.y)/10000)*7 else: Nbeam = 1 + int(node1.y/5000)*7 + int((node1.x+node2.x)/10000) name="F%dL%d"%(Nfloor,Nbeam) node_beams[name].append(i) for key in node_beams: py_send("*edit_mater %s"%key) py_send("*add_mater_elements") for j in range(len(node_beams[key])): str = "%d " % node_beams[key][j] py_send(str) py_send(" # ") return def colu_add(columns): # add elements for all materials # take-in parameter:columns, a list containing all the column elements in order node_columns = {} # beam dictionary takes 'FXCX' as key for i in range(len(columns)): node_columns[columns[i].name]=[] py_send("*renumber_all") n = py_get_int("nelements()") for i in range(1,n+1): node1=node() node1.ID=py_get_int("element_node_id(%d,%d)"%(i,1)) node2=node() node2.ID=py_get_int("element_node_id(%d,%d)"%(i,2)) node1.x=py_get_float("node_x(%d)"%node1.ID) node1.y=py_get_float("node_y(%d)"%node1.ID) node1.z=py_get_float("node_z (%d)"%node1.ID) node2.x=py_get_float("node_x(%d)"%node2.ID) node2.y=py_get_float("node_y(%d)"%node2.ID) node2.z=py_get_float("node_z (%d)"%node2.ID) if ((node1.x==node2.x)and(node1.y == node2.y)):# it's a column Nfloor = int((node1.z+node2.z)/8000)+1 Ncolu = int(node1.x/5000)+4*int(node1.y/5000)+1 name="F%dC%d"%(Nfloor,Ncolu) node_columns[name].append(i) for key in node_columns: py_send("*edit_mater %s"%key) py_send("*add_mater_elements") for j in range(len(node_columns[key])): str = "%d " % node_columns[key][j] py_send(str) py_send(" # ") return def main(): beams = [] with open('E:\\02_research\\06_firstblood\\01_model_PKPM\\ExportExcel\\section_beam.csv') as file: for content in file: list = content.split(',') if list[0] == 'Nfloor': continue new_beam = beam(content) beams.append(new_beam) file.close() for i in range(len(beams)): add_matl(beams[i].name) beam_add(beams) columns = [] with open('E:\\02_research\\06_firstblood\\01_model_PKPM\\ExportExcel\\section_colu.csv') as file: for content in file: list = content.split(',') if list[0] == 'Nfloor': continue new_column = column(content) columns.append(new_column) for i in range(len(columns)): add_matl(columns[i].name) colu_add(columns) return if __name__ == '__main__': py_connect("", 40007) main() py_disconnect()