'''
-----------------------------------------------------------------------------
 Two dimensional sub model of an axisymmetric penny shaped crack
 in a round bar modeled using axisymmetric quadrilateral elements (CAX8).

 First the global model job is completed. The *.odb file from the global
 model is used to drive this submodel.

 Global model scripts to be run:
 2DAxPennyCrackGlCAX8_model.py and 2DAxPennyCrackGlCAX8_job.py
-----------------------------------------------------------------------------
'''

from abaqus import *
import testUtils
testUtils.setBackwardCompatibility()
from abaqusConstants import *

import part, material, section, assembly, step, interaction
import regionToolset, displayGroupMdbToolset as dgm, mesh, load, job 

#----------------------------------------------------------------------------

# Copy the global model into a new model

Mdb()
globalModelName = '2DAxPennyCrackGlCAX8'
openMdb(globalModelName)
subModelName = '2DAxPennyCrackSubCAX8'
mySubModel = mdb.Model(name=subModelName)

mySubModel = (mdb.Model(name=subModelName,
    objectToCopy=mdb.models[globalModelName]))
    
# Create a new viewport in which to display the model
# and the results of the analysis.

myAssembly = mySubModel.rootAssembly
myViewport = session.viewports['Viewport: 1']
myViewport.setValues(displayedObject=myAssembly)
myViewport.makeCurrent()
myViewport.maximize()

#---------------------------------------------------------------------------

# Edit the model attributes to refer to the global model ODB file
# to drive the sub model.

mySubModel.setValues(description='Submodel of an axisymmetric penny crack', 
    globalJob='2DAxPennyCrackGlCAX8')

#---------------------------------------------------------------------------

# Create the sub model section of the global model

# Create a sketch for the base feature

myRoundBar = mySubModel.parts['AxiRoundBar']
myViewport.setValues(displayedObject=myRoundBar)

mySubSketch = mySubModel.Sketch(name='roundBarProfile',sheetSize=200.0)
mySubSketch.sketchOptions.setValues(viewStyle=AXISYM)
mySubSketch.setPrimaryObject(option=STANDALONE)

mySubSketch.ObliqueConstructionLine(point1=(0.0, -100.0),
    point2=(0.0, 100.0))
mySubSketch.ArcByCenterEnds(center=(10.0, 0.0), point1=(14.5, 0.0),
    point2=(5.5, 0.0), direction=COUNTERCLOCKWISE)
mySubSketch.Line(point1=(5.5, 0.0), point2=(14.5, 0.0))

mySubRoundBar = mySubModel.Part(name='subBlock', 
    dimensionality=AXISYMMETRIC, type=DEFORMABLE_BODY)
mySubRoundBar.BaseShell(sketch=mySubSketch)
mySubSketch.unsetPrimaryObject()
del mySubModel.sketches['roundBarProfile']

myViewport.setValues(displayedObject=mySubRoundBar)

# Create a set referring to the whole part

faces = mySubRoundBar.faces.findAt(((10,2.5,0),))
mySubRoundBar.Set(faces=faces, name='subAll')

#---------------------------------------------------------------------------

# Assign material properties

region = mySubRoundBar.sets['subAll']
mySubRoundBar.SectionAssignment(region=region,
    sectionName='SolidHomogeneous')

#---------------------------------------------------------------------------

# Create an assembly
# Place the plate created above at the same position as in the
# global model. Then the instance of the full plate is deleted.

myViewport.setValues(displayedObject=myAssembly)
myAssembly.Instance(name='subBlock-1', part=mySubRoundBar, dependent=OFF)
mySubRoundBarInstance = myAssembly.instances['subBlock-1']
del myAssembly.features['AxiRoundBar-1']

# Delete the existing sets/loads/BCs/crack properties

del myAssembly.sets['XAxis']
del myAssembly.sets['YAxis']
del myAssembly.sets['crackFront']
del myAssembly.sets['topEdge']
del mySubModel.steps['LoadRoundBar']
del myAssembly.surfaces['topSurf']
del myAssembly.engineeringFeatures.cracks['Crack']

# Partition the edge at t=0.5

pickedEdges = mySubRoundBarInstance.edges.findAt((9,0,0))
myAssembly.PartitionEdgeByParam(edges=pickedEdges, parameter=0.5)

# Create a set for the crack tip

verts1 = mySubRoundBarInstance.vertices
v1 = mySubRoundBarInstance.vertices.findAt((10,0,0))
verts1 = verts1[v1.index:(v1.index+1)]
myAssembly.Set(vertices=verts1, name='subCrackTip')

# Create a set for the driven boundary

edges1 = mySubRoundBarInstance.edges
e1 = mySubRoundBarInstance.edges.findAt((10,4.5,0))
edges1 = edges1[e1.index:(e1.index+1)]
myAssembly.Set(edges=edges1, name='drivenBoundary')

# Create a set for the edge to be fixed

edges1 = mySubRoundBarInstance.edges
e1 = mySubRoundBarInstance.edges.findAt((12.25,0,0))
edges1 = edges1[e1.index:(e1.index+1)]
myAssembly.Set(edges=edges1, name='subXEdge')

#---------------------------------------------------------------------------

# Create a step for the sub model

mySubModel.StaticStep(name='subApplyLoad', 
    previous='Initial', description='Submodel step')

#---------------------------------------------------------------------------

# Create interaction properties

# Create the contour integral definition for the crack

crackFront = crackTip = myAssembly.sets['subCrackTip']
verts = mySubRoundBarInstance.vertices
v1 = mySubRoundBarInstance.vertices.findAt((10,0,0))
v2 = mySubRoundBarInstance.vertices.findAt((14.5,0,0))
myAssembly.engineeringFeatures.ContourIntegral(name='subCrack',
    symmetric=ON, crackFront=crackFront, crackTip=crackTip,
    extensionDirectionMethod=Q_VECTORS, qVectors=((v1,v2),),
    midNodePosition=0.25, collapsedElementAtTip=SINGLE_NODE)

#---------------------------------------------------------------------------

# Create loads and boundary conditions

# Create a boundary condition for the edge to be fixed

region = myAssembly.sets['subXEdge']
mySubModel.DisplacementBC(name='subEdgeFixed', 
    createStepName='Initial', region=region, u2=SET,
    distributionType=UNIFORM, localCsys=None)

# Create the sub modeling boundary condition

region = myAssembly.sets['drivenBoundary']
mySubModel.SubmodelBC(name='submodelBC', createStepName='subApplyLoad',
    region=region, globalStep='1', globalIncrement=0,
    timeScale=OFF, dof=(1, 2), globalDrivingRegion='', absoluteExteriorTolerance=0.0, exteriorTolerance=0.05)

#---------------------------------------------------------------------------

# Create a mesh 

# Seed all the edges

pickedEdges1 = mySubRoundBarInstance.edges.findAt(((10.5,0,0),),)
pickedEdges2 = mySubRoundBarInstance.edges.findAt(((9.5,0,0),),)
myAssembly.seedEdgeByBias(end1Edges=pickedEdges1,
    end2Edges=pickedEdges2, ratio=3.0, number=6,
    constraint=FIXED)

# Assign meshing controls to the respective regions

faces = mySubRoundBarInstance.faces
f1 = mySubRoundBarInstance.faces.findAt((10,2.5,0))
pickedRegions = faces[f1.index:(f1.index+1)]
myAssembly.setMeshControls(regions=pickedRegions, elemShape=QUAD_DOMINATED,
    technique=SWEEP)

elemType1 = mesh.ElemType(elemCode=CAX8, elemLibrary=STANDARD)
elemType2 = mesh.ElemType(elemCode=CAX6M, elemLibrary=STANDARD)
faces1 = mySubRoundBarInstance.faces
pickedRegions =(faces1, )
myAssembly.setElementType(regions=pickedRegions,
    elemTypes=(elemType1, elemType2))
partInstances =(mySubRoundBarInstance, )
myAssembly.generateMesh(regions=partInstances)

#---------------------------------------------------------------------------

# Request history output for the crack

mySubModel.historyOutputRequests.changeKey(
    fromName='H-Output-1', toName='JInt')
mySubModel.historyOutputRequests['JInt'].setValues(
    contourIntegral='subCrack', numberOfContours=5)

#---------------------------------------------------------------------------

# Create the job 

myJob = mdb.Job(name=subModelName, model=subModelName,
    description='Contour integral analysis')
mdb.saveAs(pathName=subModelName)

#---------------------------------------------------------------------------

