Vous êtes sur la page 1sur 17

c 

    

Kevin Maxwell
Texas A&M University
August 30, 2006

 
ABAQUS CAE provides a graphical user interface that allows the user to create finite
element models that can then be analyzed in ABAQUS Standard. For every feature in
CAE, there is a corresponding Python script command that the program uses when
creating the model. If the language is understood well enough, an entire model can be
created simply by running a script file.

While one could write an entire script from scratch, ABAQUS provides several easier
methods that autogenerate Python commands. When a model is created in CAE, two
files are automatically created in the work directory. The replay file records every action
that is performed in CAE including camera zoom/panning commands and also any
mistakes that were made and then corrected. This file can be run to ³replay´ all the work
that has been done on the model. The recover file records only the minimum necessary
commands to recreate the model. If an error occurs and CAE closes without saving, the
recover file can be run to recreate the model. When a model is saved, CAE uses the
recover file to write a journal file. The journal file is a comprehensive script that shows
all work saved on the model. Note that the recover file is deleted whenever the model is
saved and all of its commands are transferred to the journal file. The recover and journal
files provide an easy alternative to writing Python scripts from scratch. One can simply
define a model in CAE and then save the Python commands from the recover or journal
files as a separate script file.

There are several valuable sources of information pertaining to scripting in ABAQUS.


The ABAQUS Scripting User¶s Manual and ABAQUS Scripting Reference Manual are
invaluable resources that are included in the ABAQUS documentation. The user¶s
manual gives an overview to scripting while the reference manual provides in-depth
coverage of every scripting command used in ABAQUS. Another source of information
can be found at http://www.python.org . This website contains numerous resources
dealing with the Python language in general.



To illustrate the procedure for auto-generating Python scripts, the cruciform specimen
used for interfacial normal strength testing will be modeled. This specimen is shown in
Figure 1. As can be seen from the figure, symmetry planes were exploited so that only ¼
of the specimen was modeled. The entire 2D model was first created in CAE and the
necessary commands were copied from the recover file. The easiest way to do this is by
splitting the modeling process into smaller segments and copying commands from the
recover or journal file at the end of each segment. The resulting script can then be run in
CAE so that the next segment can be created.
h 
 
  

Before starting the model type the following command into the Python editor box in
CAE:

session.journalOptions.setValues(recoverGeometry=COORDINATE)

This sets the recover and journal files to record geometry commands in the form of
coordinates instead of geometric indices. This step is very helpful if any type of
parameterization will be used with the script.

Next, the part will be sketched and created in CAE. The commands used to sketch the
part in Figure 1 are then copied from the recover or journal file. These commands are
shown below.

mdb.models['Model-1'].ConstrainedSketch(name='__profile__', sheetSize=0.1)
mdb.models['Model-1'].sketches['__profile__'].sketchOptions.setValues(
decimalPlaces=3)
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.0, 0.0), point2=(
0.015, 0.0065))
del mdb.models['Model-1'].sketches['__profile__']
mdb.models['Model-1'].ConstrainedSketch(name='__profile__', sheetSize=0.1)
mdb.models['Model-1'].sketches['__profile__'].sketchOptions.setValues(
decimalPlaces=3)
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.0, 0.0), point2=(
0.015, 0.0))
mdb.models['Model-1'].sketches['__profile__'].HorizontalConstraint(entity=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.0075,
0.0), ))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.015, 0.0), point2=
(0.015, 0.0065))
mdb.models['Model-1'].sketches['__profile__'].VerticalConstraint(entity=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.015,
0.00325), ))
mdb.models['Model-1'].sketches['__profile__'].PerpendicularConstraint(entity1=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.0075,
0.0), ), entity2=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.015,
0.00325), ))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.015, 0.0065),
point2=(0.004, 0.0065))
mdb.models['Model-1'].sketches['__profile__'].HorizontalConstraint(entity=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.0095,
0.0065), ))
mdb.models['Model-1'].sketches['__profile__'].PerpendicularConstraint(entity1=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.015,
0.00325), ), entity2=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.0095,
0.0065), ))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.004, 0.0065),
point2=(0.004, 0.03))
mdb.models['Model-1'].sketches['__profile__'].VerticalConstraint(entity=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.004,
0.01825), ))
mdb.models['Model-1'].sketches['__profile__'].PerpendicularConstraint(entity1=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.0095,
0.0065), ), entity2=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.004,
0.01825), ))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.004, 0.03),
point2=(0.0, 0.03))
mdb.models['Model-1'].sketches['__profile__'].HorizontalConstraint(entity=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.002,
0.03), ))
mdb.models['Model-1'].sketches['__profile__'].PerpendicularConstraint(entity1=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.004,
0.01825), ), entity2=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.002,
0.03), ))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.0, 0.03), point2=(
0.0, 0.0))
mdb.models['Model-1'].sketches['__profile__'].VerticalConstraint(entity=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.0, 0.015),
))
mdb.models['Model-1'].sketches['__profile__'].PerpendicularConstraint(entity1=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.002,
0.03), ), entity2=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.0, 0.015),
))
mdb.models['Model-1'].sketches['__ profile __'].FilletByRadius(curve1=
mdb.models['Model-1'].sketches['__ profile __'].geometry.findAt((0.004,
0.01825), ), curve2=
mdb.models['Model-1'].sketches['__ profile__'].geometry.findAt((0.0095,
0.0065), ), nearPoint1=(0.0040139821358, 0.00947074592113), nearPoint2=(
0.00570417288691, 0.0064547881484), radius=0.006)

Once the commands are copied, they may need to be modified so that the part is more
robustly defined. For instance, instead of using (0, 2.439999) to define a vertex point, it
may need to be changed to (0, 2.44) or even (0, r), where µr¶ is a variable that can be
defined and used to parameterize the model. Also, some of the commands generated can
be completely abandoned. The horizontal, vertical, perpendicular, etc.. constraint
commands sometimes cause problems with scripting, so deleting them is usually a good
idea. The modified version of the generated sketch commands are given below.

mdb.models['Model-1'].ConstrainedSketch(name='__profile__', sheetSize=0.1)
mdb.models['Model-1'].sketches['__profile__'].sketchOptions.setValues(
decimalPlaces=3)
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.0, 0.0), point2=(
0.015, 0.0))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.015, 0.0), point2=
(0.015, h))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.015, h),
point2=(w, h))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(w, h),
point2=(w, 0.03))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(w, 0.03),
point2=(0.0, 0.03))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.0, 0.03), point2=(
0.0, 0.0))
mdb.models['Model-1'].sketches['__profile__'].FilletByRadius(curve1=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.004,
0.01825), ), curve2=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.0095,
0.0065), ), nearPoint1=(w+r, h), nearPoint2=(
w, h+r), radius=r)

The rest of the model and script are then created in CAE using the same steps as above.
Special care must be taken when seeding and meshing the part. This is usually the most
involved part of the process since anything other than trivial geometries requires a
moderate to large amount of modification of the mesh seeds. Once the entire model has
been created it is usually a good idea to run a simple analysis just to check for errors.
The script can then be modified to achieve the task at hand (i.e. parameterization). The
full, parameterized cruciform script is given below. Note that comments in Python are
preceded by µ#¶ and are also highlighted in this document. Also note the part, material,
section, etc« import module commands that precede the script. The recover and journal
files generate these commands and they must be included in the final script.

from part import *


from material import *
from section import *
from assembly import *
from step import *
from interaction import *
from load import *
from mesh import *
from job import *
from sketch import *
from visualization import *
from connectorBehavior import *

#TO VARY A PARAMETER, UNCOMMENT THE LIST VECTOR FOR THE


SPECIFIC PARAMETER (WIDTHS, HEIGHTS, OR RADII) AND COMMENT
#OUT THE CORRESPONDING DUMMY LETTER (W, H, OR R). THEN
UNCOMMENT THE RESPECTIVE FOR LOOP COMMAND.
#THE CURRENT SETUP WILL VARY THE WING HEIGHT FROM 0.003 - 0.009
WHILE
#KEEPING THE LOADING ARM WIDTH AND FILLET RADIUS CONSTANT AT
0.008 AND 0.006 RESPECTIVELY.

w = .008
#widths = [.001,.002,.003,.004,.005,.006,.008]

#h = .002
heights = [.003,.004,.005,.006,.007,.008,.009]

r = .006
#radii = [.003,.004,.005,.006,.007]

i=1
#for w in widths:
#for h in heights:
for r in radii:
#CREATE THE PART SKETCH
mdb.models['Model-1'].ConstrainedSketch(name='__profile__', sheetSize=0.1)
mdb.models['Model-1'].sketches['__profile__'].sketchOptions.setValues(
decimalPlaces=3)
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.0, 0.0), point2=(
0.015, 0.0))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.015, 0.0), point2=
(0.015, h))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.015, h),
point2=(w, h))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(w, h),
point2=(w, 0.03))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(w, 0.03),
point2=(0.0, 0.03))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0.0, 0.03), point2=(
0.0, 0.0))
mdb.models['Model-1'].sketches['__profile__'].FilletByRadius(curve2=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((w,
h*2), ), curve1=
mdb.models['Model-1'].sketches['__profile__'].geometry.findAt((0.0095,
h), ), nearPoint1=(w+r, h), nearPoint2=(
w, h+r), radius=r)

#CREATE THE ACTUAL PART FROM THE PART SKETCH


mdb.models['Model-1'].Part(dimensionality=TWO_D_PLANAR, name='Part-1',
type=DEFORMABLE_BODY)
mdb.models['Model-1'].parts['Part-1'].BaseShell(sketch=
mdb.models['Model-1'].sketches['__profile__'])
del mdb.models['Model-1'].sketches['__profile__']

#CREATE THE EPOXY MATERIAL AND THE MATRIX SECTION


mdb.models['Model-1'].Material(name='Epoxy')
mdb.models['Model-1'].materials['Epoxy'].Elastic(table=((3440000000.0, 0.35),
))
mdb.models['Model-1'].HomogeneousSolidSection(material='Epoxy',
name='Matrix',
thickness=1.0)

#INSTANCE THE PART


mdb.models['Model-1'].rootAssembly.DatumCsysByDefault(CARTESIAN)
mdb.models['Model-1'].rootAssembly.Instance(dependent=OFF, name='Part-1',
part=mdb.models['Model-1'].parts['Part-1'])

#CREATE A NEW STEP


mdb.models['Model-1'].StaticStep(description='Apply load to specimen', name=
'Apply Load Step', previous='Initial')
mdb.models['Model-1'].rootAssembly.regenerate()
#ASSIGN THE MATRIX SECTION
mdb.models['Model-1'].parts['Part-1'].SectionAssignment(offset=0.0, region=
Region(faces=mdb.models['Model-1'].parts['Part-1'].faces.findAt(((0.001,
0.001, 0.0), (0.0, 0.0, 1.0)), )), sectionName='Matrix')
mdb.models['Model-1'].rootAssembly.regenerate()

#CREATE THE SURFACE TRACTION LOAD


mdb.models['Model-1'].SurfaceTraction(createStepName='Apply Load Step',
directionVector=((0.0, 0.0, 0.0), (0.0, 1.0, 0.0)), distributionType=
UNIFORM, field='', localCsys=None, magnitude=100.0, name='Load-1',
region=Region(side1Edges=mdb.models['Model1'].rootAssembly.instances['Part-
1'].edges.findAt(((0.0005, 0.03, 0.0), ), )), traction=GENERAL)

#CREATE THE SYMMETRY BOUNDARY CONDITIONS


mdb.models['Model-1'].XsymmBC(createStepName='Apply Load Step',
name='BC-1',
region=Region(edges=mdb.models['Model1'].rootAssembly.instances['Part-
1'].edges.findAt(((0.0, 0.0225, 0.0), ), )))
mdb.models['Model-1'].YsymmBC(createStepName='Apply Load Step',
name='BC-2', region=Region(edges=mdb.models['Model-
1'].rootAssembly.instances['Part-1'].edges.findAt((
(0.00375, 0.0, 0.0), ), )))

#SEED AND MESH THE PART


mdb.models['Model-1'].rootAssembly.seedPartInstance(deviationFactor=0.1,
regions=(mdb.models['Model-1'].rootAssembly.instances['Part-1'], ), size=
0.0005)
mdb.models['Model-1'].rootAssembly.generateMesh(regions=(
mdb.models['Model-1'].rootAssembly.instances['Part-1'], ))

#CREATE A JOB AND SUBMIT IT


jobname = 'Job-%s' %i
mdb.Job(contactPrint=OFF, description='', echoPrint=OFF, explicitPrecision=
SINGLE, historyPrint=OFF, model='Model-1', modelPrint=OFF,
multiprocessingMode=DEFAULT, name=jobname,
nodalOutputPrecision=SINGLE,
numCpus=1, numDomains=1, parallelizationMethodExplicit=DOMAIN,
preMemory=256.0, scratch='', standardMemory=256.0,
standardMemoryPolicy=MODERATE,
type=ANALYSIS, userSubroutine='')
job = mdb.jobs[jobname]
job.submit()
job.waitForCompletion()
i=i+1
#END OF FOR LOOP
2  


Templates for square and hexagonal composite fiber orientations were created using
Python scripts and ABAQUS. The respective scripts create a model in ABAQUS CAE
and assign a mesh to this model. The fiber volume fraction as well as the global element
size can be specified. Sample meshes for both templates are given in Figure 1 and Figure
2. Note that symmetry planes were exploited in order to model ¼ of the square or
hexagon.

h 

The python scripts used to create these models are included below. Some of the
commands were autogenerated using ABAQUS CAE and the associated recover/journal
files. However, most of the commands were written from scratch in Notepad++, an open
source text editor with multi-language support
(http://notepad-plus.sourceforge.net/uk/site.htm). It can be seen that the commands in the
scripts given below are somewhat simpler than the example above. This is because
repositories were used to store repetitive object paths. For example, the command

sketch1 = mdb.models['Model-1'].sketches['__profile__']

allows the object path


mdb.models['Model-1'].sketches['__profile__']

to be replaced with the variable sketch1. This greatly reduces the amount of typing
needed and also makes the script more readable. Overall, the use of scripting made the
definition of the model geometry much easier to define as well as allowing the
parameterization of the fiber size and mesh.


h  

The mesh was developed so that the elements are most uniform along the fiber matrix
interface. To accomplish this, a small square partition in the lower left of the model and
a circular partition with radius greater than the fiber radius were added to the mesh.
These partitions can be seen in Figure 3 and Figure 4. It should be noted that time
constraints did not allow the meshes for either template to be completely refined. For the
square model, the user can input global element size and the number of seeds along the
fiber matrix interface. For the hexagonal model, the user can input global element size,
interface seed number, and number of seeds along the top edge (this number has to be
specified in order to make this mesh edge symmetric). Options such as biasing the
element size along different directions could be added to the script at a later date. A
method to decrease the element size in the lower left corner of the models would help to
refine the mesh. The mesh might also need to be altered so that all elements have a
reasonable aspect ratio.
h    

h     





from part import *
from material import *
from section import *
from assembly import *
from step import *
from interaction import *
from load import *
from mesh import *
from job import *
from sketch import *
from visualization import *

#Geometry definitions
#Choose values of fiber radius and matrixw
Vf = .4
element_size = .015
interface_seeds = 40

w = 1.0
pi=3.14159
radius = sqrt(4*Vf/pi)
c30 = cos(30*pi/180)
s30 = sin(30*pi/180)
matrixw = w - radius
r1 = .05
r2 = .95

#Create the part sketch


mdb.models['Model-1'].ConstrainedSketch(name='__profile__', sheetSize=20.0)
sketch1 = mdb.models['Model-1'].sketches['__profile__']
sketch1.Line(point1=(0.0, 0.0), point2=(
w, 0.0))
sketch1.HorizontalConstraint(entity=
sketch1.geometry.findAt((w/2, 0.0),
))
sketch1.Line(point1=(w, 0.0), point2=(
w, w))
sketch1.VerticalConstraint(entity=
sketch1.geometry.findAt((w, w/2),
))
sketch1.PerpendicularConstraint(entity1=
sketch1.geometry.findAt((w/2, 0.0), )
, entity2=sketch1.geometry.findAt((
w, w/2), ))
sketch1.Line(point1=(w, w), point2=(
0.0, w))
sketch1.HorizontalConstraint(entity=
sketch1.geometry.findAt((w/2, w),
))
sketch1.PerpendicularConstraint(entity1=
sketch1.geometry.findAt((w, w/2), )
, entity2=sketch1.geometry.findAt((
w/2, w), ))
sketch1.Line(point1=(0.0, w), point2=(
0.0, 0.0))
sketch1.VerticalConstraint(entity=
sketch1.geometry.findAt((0.0, w/2),
))
sketch1.PerpendicularConstraint(entity1=
sketch1.geometry.findAt((w/2, w), )
, entity2=sketch1.geometry.findAt((
0.0, w/2), ))

#Create the part from the sketch


mdb.models['Model-1'].Part(dimensionality=TWO_D_PLANAR, name='Part-1', type=
DEFORMABLE_BODY)
mdb.models['Model-1'].parts['Part-1'].BaseShell(sketch=
sketch1)
del mdb.models['Model-1'].sketches['__profile__']
part1 = mdb.models['Model-1'].parts['Part-1']

#Sketch the partition to make the fiber


mdb.models['Model-1'].ConstrainedSketch(gridSpacing=0.35, name='__profile__',
sheetSize=14.14, transform=
part1.MakeSketchTransform(
sketchPlane=part1.faces.findAt((w/2,
w/2, 0.0), (0.0, 0.0, 1.0)), sketchPlaneSide=SIDE1,
sketchOrientation=RIGHT, origin=(0, 0, 0.0)))
sketch1 = mdb.models['Model-1'].sketches['__profile__']
sketch1.sketchOptions.setValues(
gridSpacing=0.35)
part1.projectReferencesOntoSketch(filter=
COPLANAR_EDGES, sketch=sketch1)
sketch1.ArcByCenterEnds(center=(0,
0), direction=COUNTERCLOCKWISE, point1=(radius,0), point2=(0,radius))
sketch1.CoincidentConstraint(entity1=
sketch1.vertices.findAt((radius, 0),
), entity2=sketch1.geometry.findAt((
radius, 0), ))
sketch1.CoincidentConstraint(entity1=
sketch1.vertices.findAt((0, radius),
), entity2=sketch1.geometry.findAt((
0, radius), ))
part1.PartitionFaceBySketch(faces=
part1.faces.findAt(((w/2, w/2,
0.0), (0.0, 0.0, 1.0)), ), sketch=
sketch1)
del mdb.models['Model-1'].sketches['__profile__']

#Create partition at corner


mdb.models['Model-1'].ConstrainedSketch(gridSpacing=0.03, name='__profile__',
sheetSize=1.51, transform=
part1.MakeSketchTransform(
sketchPlane=part1.faces.findAt((0.353978,
0.030148, 0.0), (0.0, 0.0, 1.0)), sketchPlaneSide=SIDE1,
sketchOrientation=RIGHT, origin=(0, 0, 0.0)))
part1.projectReferencesOntoSketch(filter=
COPLANAR_EDGES, sketch=mdb.models['Model-1'].sketches['__profile__'])
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(r1, 0.0),
point2=(r1,r1))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0, r1),
point2=(r1,r1))
part1.PartitionFaceBySketch(faces=
part1.faces.findAt(((0, 0,
0.0), (0.0, 0.0, 1.0)), ), sketch=
mdb.models['Model-1'].sketches['__profile__'])
del mdb.models['Model-1'].sketches['__profile__']

#Create outer partition


mdb.models['Model-1'].ConstrainedSketch(gridSpacing=0.03, name='__profile__',
sheetSize=1.51, transform=
part1.MakeSketchTransform(
sketchPlane=part1.faces.findAt((1,1,0),(0,0,1)), sketchPlaneSide=SIDE1,
sketchOrientation=RIGHT, origin=(0, 0, 0.0)))
part1.projectReferencesOntoSketch(filter=
COPLANAR_EDGES, sketch=mdb.models['Model-1'].sketches['__profile__'])
mdb.models['Model-1'].sketches['__profile__'].CircleByCenterPerimeter(center=(
0, 0), point1=(r2, 0))
part1.PartitionFaceBySketch(faces=
part1.faces.findAt(((1, 1,
0.0), (0.0, 0.0, 1.0)), ), sketch=
mdb.models['Model-1'].sketches['__profile__'])
del mdb.models['Model-1'].sketches['__profile__']
#Create diagonal partition
part1.PartitionFaceByShortestPath(faces=
part1.faces, point1=
part1.vertices.findAt((0.0, 0.0, 0.0), ),
point2=part1.vertices.findAt((1.0, 1.0,
0.0), ))

#Instance the part


mdb.models['Model-1'].rootAssembly.DatumCsysByDefault(CARTESIAN)
mdb.models['Model-1'].rootAssembly.Instance(dependent=ON, name='Part-1-1',
part=part1)

#Seed and mesh the part


part1.seedPart(deviationFactor=0.1, size=element_size)

part1.seedEdgeByNumber(edges=
part1.edges.findAt(((r2*c30, r2*s30, 0.0), ), ((radius*c30, radius*s30, 0.0), ),
((r2*s30, r2*c30, 0.0), ), ((radius*s30, radius*c30, 0.0), ), ),
number=20,constraint=FINER)

part1.generateMesh()
Hexagon Script:

from part import *


from material import *
from section import *
from assembly import *
from step import *
from interaction import *
from load import *
from mesh import *
from job import *
from sketch import *
from visualization import *
from connectorBehavior import *

#Geometry definitions
#Choose values for fiber volume fraction Vf and global element_size
Vf = .4
element_size = .2
edgeseed = 40

length = 4
pi=3.14159
s30 = sin(30*pi/180)
c30 = cos(30*pi/180)
t30 = tan(30*pi/180)
area = length/2*length*c30 + .5*length*c30*length*s30
fiber_radius = sqrt(4*area*Vf/pi)
matrixw = length*c30 - fiber_radius
r1 = .1*length*c30
r2 = .95*length*c30

#Create the part sketch


mdb.models['Model-1'].ConstrainedSketch(name='__profile__', sheetSize=20.0)
sketch1 = mdb.models['Model-1'].sketches['__profile__']
sketch1.Line(point1=(0.0, 0.0), point2=(
length*c30, 0.0))
sketch1.Line(point1=(length*c30, 0.0), point2=(
length*c30, length/2))
sketch1.Line(point1=(length*c30, length/2), point2=(
0.0, length*s30+length/2))
sketch1.Line(point1=(0.0, length*s30+length/2), point2=(
0.0, 0.0))

#Create the part from the sketch


mdb.models['Model-1'].Part(dimensionality=TWO_D_PLANAR, name='Part-1', type=
DEFORMABLE_BODY)
mdb.models['Model-1'].parts['Part-1'].BaseShell(sketch=
sketch1)
del mdb.models['Model-1'].sketches['__profile__']
part1 = mdb.models['Model-1'].parts['Part-1']

#Create partition at corner


mdb.models['Model-1'].ConstrainedSketch(gridSpacing=0.03, name='__profile__',
sheetSize=1.51, transform=
part1.MakeSketchTransform(
sketchPlane=part1.faces.findAt((0,
0, 0.0), (0.0, 0.0, 1.0)), sketchPlaneSide=SIDE1,
sketchOrientation=RIGHT, origin=(0, 0, 0.0)))
sketch1 = mdb.models['Model-1'].sketches['__profile__']
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(r1, 0.0),
point2=(r1,r1))
mdb.models['Model-1'].sketches['__profile__'].Line(point1=(0, r1),
point2=(r1,r1))
part1.PartitionFaceBySketch(faces=
part1.faces.findAt(((0, 0,
0.0), (0.0, 0.0, 1.0)), ), sketch=
mdb.models['Model-1'].sketches['__profile__'])
del mdb.models['Model-1'].sketches['__profile__']

#Sketch the partition to make the fiber


mdb.models['Model-1'].ConstrainedSketch(gridSpacing=0.35, name='__profile__',
sheetSize=14.14, transform=
part1.MakeSketchTransform(
sketchPlane=part1.faces.findAt((fiber_radius,
fiber_radius, 0.0), (0.0, 0.0, 1.0)), sketchPlaneSide=SIDE1,
sketchOrientation=RIGHT, origin=(0, 0, 0.0)))
sketch1 = mdb.models['Model-1'].sketches['__profile__']
sketch1.sketchOptions.setValues(
gridSpacing=0.35)
part1.projectReferencesOntoSketch(filter=
COPLANAR_EDGES, sketch=sketch1)
sketch1.ArcByCenterEnds(center=(0,
0), direction=COUNTERCLOCKWISE, point1=(fiber_radius,0),
point2=(0,fiber_radius))
sketch1.CoincidentConstraint(entity1=
sketch1.vertices.findAt((fiber_radius, 0),
), entity2=sketch1.geometry.findAt((
fiber_radius, 0), ))
sketch1.CoincidentConstraint(entity1=
sketch1.vertices.findAt((0, fiber_radius),
), entity2=sketch1.geometry.findAt((
0, fiber_radius), ))
part1.PartitionFaceBySketch(faces=
part1.faces.findAt(((fiber_radius, fiber_radius,
0.0), (0.0, 0.0, 1.0)), ), sketch=
sketch1)
del mdb.models['Model-1'].sketches['__profile__']

#Create outer partition


mdb.models['Model-1'].ConstrainedSketch(gridSpacing=0.03, name='__profile__',
sheetSize=1.51, transform=
part1.MakeSketchTransform(
sketchPlane=part1.faces.findAt((length*c30,0,0),(0,0,1)), sketchPlaneSide=SIDE1,
sketchOrientation=RIGHT, origin=(0, 0, 0.0)))
part1.projectReferencesOntoSketch(filter=
COPLANAR_EDGES, sketch=mdb.models['Model-1'].sketches['__profile__'])
mdb.models['Model-1'].sketches['__profile__'].CircleByCenterPerimeter(center=(
0, 0), point1=(r2, 0))
part1.PartitionFaceBySketch(faces=
part1.faces.findAt(((length*c30, 0,
0.0), (0.0, 0.0, 1.0)), ), sketch=
mdb.models['Model-1'].sketches['__profile__'])
del mdb.models['Model-1'].sketches['__profile__']

#Instance the part


mdb.models['Model-1'].rootAssembly.DatumCsysByDefault(CARTESIAN)
mdb.models['Model-1'].rootAssembly.Instance(dependent=ON, name='Part-1-1',
part=part1)

#Seed and mesh the part


part1.seedPart(deviationFactor=0.1, size=element_size)
part1.seedEdgeByNumber(edges=
part1.edges.findAt(((r2*c30, r2*s30, 0.0), ), ((fiber_radius*c30, fiber_radius*s30,
0.0),)
, ),
number=40,constraint=FINER)
part1.seedEdgeByNumber(edges=
part1.edges.findAt(((c30*(length-length/3),
length/2+length/3*s30, 0.0),
), ), number=edgeseed,constraint=FIXED)

part1.setMeshControls(regions=
part1.faces.findAt(((.9*fiber_radius*c30, .9*fiber_radius*s30,
0.0), (0.0, 0.0, 1.0)), ((.9*r2*c30, .9*r2*s30, 0.0), (0.0, 0.0, 1.0)), ((
length*c30, 0, 0.0), (0.0, 0.0, 1.0)), ), technique=STRUCTURED)
part1.generateMesh()