164 lines
5.8 KiB
Python
164 lines
5.8 KiB
Python
# GrainGen V2.0
|
|
# This script generates idealised and representative meshed micro-structure geometries
|
|
# in 2-D and 3-D through the Abaqus geometry kernel. - J. Grogan, 09/06/2011
|
|
#
|
|
# Import Abaqus and External Modules
|
|
from abaqusConstants import *
|
|
from abaqus import *
|
|
import random
|
|
import subprocess
|
|
import regionToolset
|
|
import mesh
|
|
import step
|
|
import part
|
|
import interaction
|
|
import GeomModules
|
|
#
|
|
# Create Model Database
|
|
VerFile=Mdb(pathName="MStructure")
|
|
VerModel=VerFile.models['Model-1']
|
|
VerAssembly=VerModel.rootAssembly
|
|
#
|
|
# Assign Model Parameters
|
|
shape=4 # 1 - Square, 2- Hex, 3 -Dodec, 4- Voronoi
|
|
part_type=2 # 2 - Shell, 3 - Solid
|
|
dimension=2 # 2 - 2D, 3 - 3D
|
|
rad=0.00595 # Characteristic Dimension (except Voronoi)
|
|
meshsize=0.0005 # Global Mesh Seed Size
|
|
num_high=16 # Number of Grains in X-Dir
|
|
num_wide=6 # Number of Grains in Y-Dir
|
|
num_thick=1 # Number of Grains in Z-Dir
|
|
num_grains=25 # Target Number of Grains (Voronoi Only)
|
|
scalex=1. # Voronoi Part Scale X-Dir (Voronoi Only)
|
|
scaley=3.5 # Voronoi Part Scale Y-Dir (Voronoi Only)
|
|
scalez=1. # Voronoi Part Scale Z-Dir (Voronoi Only)
|
|
ana_type=1 # 1 - Crystal Plasticity, 2 - Corrosion
|
|
hard_rad=0.0 # Hardcore voronoi min. radius (Voronoi Only)
|
|
random_seed=92271 # Random seed for voronoi grain generation or random vector generation
|
|
#
|
|
# Choose Script Function - Set to 1 to activate
|
|
assemble_grains = 1 # Assemble Multiple Grains and Merge Them
|
|
boolean_cut = 1 # Perform Boolean Cut Operation
|
|
mesh_part = 1 # Mesh the Final Geometry
|
|
mat_props = 1 # Assign Material Properties
|
|
bound_conds = 1 # Generate steps and apply BCs
|
|
write_output =1 # Write Output File
|
|
post_proc = 0 # Postprocess INP file (Corrosion Only)
|
|
#
|
|
# For 2-D Solids thickness is set equal to one element
|
|
if dimension==3:
|
|
extrude_depth=rad
|
|
else:
|
|
extrude_depth=meshsize
|
|
num_thick=1
|
|
#
|
|
# Draw a Square Grain
|
|
if shape==1:
|
|
GeomModules.DrawSquare(VerModel,part_type,rad,extrude_depth)
|
|
#
|
|
# Draw a Hexagonal Grain
|
|
if shape==2:
|
|
GeomModules.DrawHexagon(VerModel,part_type,rad,extrude_depth)
|
|
#
|
|
# Draw a Dodecahedral Grain
|
|
if shape==3:
|
|
GeomModules.DrawDodec(VerModel,rad)
|
|
#
|
|
# Draw a Voronoi Tessellation
|
|
if shape==4:
|
|
if dimension==2:
|
|
maxsize=max(scalex,scaley)
|
|
GeomModules.Voronoi2D(VerModel,part_type,extrude_depth,num_grains,maxsize,hard_rad,random_seed)
|
|
else:
|
|
maxsize=max(scalex,scaley,scalez)
|
|
GeomModules.Voronoi3D(VerModel,num_grains,maxsize,hard_rad,random_seed)
|
|
#
|
|
# Assemble Base Parts
|
|
if assemble_grains==1:
|
|
if shape<=3:
|
|
VerPart=VerModel.parts['Base']
|
|
GeomModules.PatternParts(num_high,num_wide,num_thick,VerPart,rad,shape,VerModel)
|
|
#
|
|
# Make a Boolean Template
|
|
if boolean_cut==1:
|
|
if shape>1:
|
|
GeomModules.BooleanPart(VerModel,part_type,rad,extrude_depth,num_high,
|
|
num_wide,num_thick,shape,dimension,scalex,scaley,scalez)
|
|
BoolPart=VerModel.parts['Template']
|
|
#
|
|
#Perform Boolean Cut
|
|
if shape==1:
|
|
VerPart=VerModel.parts['Merged']
|
|
del VerAssembly.instances['Merged-1']
|
|
else:
|
|
VerAssembly.InstanceFromBooleanCut(name='FinalPart',
|
|
instanceToBeCut=VerAssembly.instances['Merged-1'],
|
|
cuttingInstances=(VerAssembly.instances['Template-1'], ),
|
|
originalInstances=DELETE)
|
|
del VerAssembly.instances['FinalPart-1']
|
|
VerPart=VerModel.parts['FinalPart']
|
|
#
|
|
# Mesh Part
|
|
if mesh_part==1:
|
|
if shape<3:
|
|
VerPart.setMeshControls(regions=VerPart.cells, elemShape=HEX, technique=STRUCTURED)
|
|
if shape==3:
|
|
VerPart.setMeshControls(regions=VerPart.cells, elemShape=TET, technique=FREE)
|
|
if shape==4:
|
|
if dimension==2:
|
|
VerPart.setMeshControls(regions=VerPart.cells, elemShape=HEX, technique=SWEEP,
|
|
algorithm=ADVANCING_FRONT)
|
|
else:
|
|
VerPart.setMeshControls(regions=VerPart.cells, elemShape=TET, technique=FREE)
|
|
VerPart.seedPart(size=meshsize)
|
|
VerPart.generateMesh()
|
|
#
|
|
# For Corrosion Analysis Output Part Vertices and Element Connectivity
|
|
if ana_type==2:
|
|
GeomModules.VertsConn(VerPart,dimension)
|
|
ecor=open('ecor.dat','w')
|
|
for eachface in VerPart.faces:
|
|
if len(eachface.getAdjacentFaces())<7.:
|
|
xnor=eachface.getNormal()[0]
|
|
ynor=eachface.getNormal()[1]
|
|
znor=eachface.getNormal()[2]
|
|
if (xnor==0.)and(znor==0.):
|
|
# if (ynor==1.)or(ynor==-1.):
|
|
if (ynor==1.):
|
|
ecor.write("%6.4f %6.4f %6.4f\n"%(xnor,ynor,znor))
|
|
ecor.close()
|
|
#
|
|
#Generate Materials and Sections
|
|
if mat_props==1:
|
|
GeomModules.MatGen(ana_type,VerPart,VerModel,part_type,meshsize,random_seed)
|
|
#
|
|
#Steps and Boundary Conditions
|
|
if bound_conds==1:
|
|
VerModel.ExplicitDynamicsStep(name='Corrode', previous='Initial',
|
|
massScaling=((SEMI_AUTOMATIC, MODEL, AT_BEGINNING, 0.0, 1e-06,
|
|
BELOW_MIN, 0, 0, 0.0, 0.0, 0, None), ))
|
|
VerModel.ExplicitDynamicsStep(name='Load', previous='Corrode',
|
|
timePeriod=1.)
|
|
VerModel.steps['Corrode'].Restart(numberIntervals=2,overlay=OFF,timeMarks=OFF)
|
|
VerModel.steps['Load'].Restart(numberIntervals=2,overlay=OFF, timeMarks=OFF)
|
|
VerModel.FieldOutputRequest(name='F-Output-1',
|
|
createStepName='Corrode', variables=('A', 'CSTRESS', 'LE', 'PE',
|
|
'PEEQ', 'RF', 'S', 'SDV', 'STATUS', 'U','V'), numIntervals=100)
|
|
#
|
|
#Loads and BCs
|
|
VerAssembly.Instance(name='CorPart',part=VerPart, dependent=ON)
|
|
iNodes=VerAssembly.instances['CorPart'].nodes
|
|
# GeomModules.S1BCs(iNodes,VerModel,num_high,num_wide,num_thick,shape,
|
|
# dimension,extrude_depth,rad,scalex,scaley,scalez)
|
|
#
|
|
#VerAssembly.Instance(name='CorPart',part=VerPart, dependent=ON)
|
|
#Create Job and write input file
|
|
if write_output ==1:
|
|
VerFile.Job(name='GeomGenTemp', model='Model-1', type=ANALYSIS,
|
|
explicitPrecision=SINGLE, nodalOutputPrecision=SINGLE,userSubroutine='',
|
|
parallelizationMethodExplicit=DOMAIN,numDomains=1,multiprocessingMode=DEFAULT, numCpus=1)
|
|
VerFile.jobs['GeomGenTemp'].writeInput(consistencyChecking=OFF)
|
|
#
|
|
# Perform Postprocessing for corrosion analysis
|
|
if post_proc ==1:
|
|
retcode=subprocess.call("GeomGenPost2.exe")
|