"""
Abaqus Example Manaual script to create the model and the and optimization 
attributes for the shape optimization of a connecting rod.The script is run
using File -> Run Script in Abaqus/CAE. 
In order to successfully run conrod_shape_optimization.py the user must have
conRod.inp in the working directory.
"""

from abaqus import *
from abaqusConstants import *
import regionToolset



#Define the current viewport
#
curViewportName=session.currentViewportName
curViewport=session.viewports[curViewportName]


#Import of the model input file
#
try:
	mdb.ModelFromInputFile(name='connecting_rod', inputFileName='connecting_rod.inp')
except:
	msg = "The input file (conRod.inp) was not found in the working directiory."
	raise ValueError, msg

#model, part, assembly and part instance assignment
#
model=mdb.models['connecting_rod']
assembly = model.rootAssembly
part1 = model.parts['PART-1']
instance=assembly.instances['PART-1-1']

#Use of the element set 'SOLID_ELEMENTS' with all the elements in the model
#
partElements = part1.elements

#Creation of an elastic material
#
model.Material(name='Elastic_Mat')
model.materials['Elastic_Mat'].Density(table=((7.81e-09, ), ))
model.materials['Elastic_Mat'].Elastic(table=((210000.0, 0.3), ))


#Creation of a homogeneous solid section
#
model.HomogeneousSolidSection(name='Section-1_Solid', 
    material='Elastic_Mat', thickness=None)


#Creation of the solid section assignment
#
solidElementRegion = part1.sets['SOLID_ELEMENTS']

part1.SectionAssignment(region=solidElementRegion, sectionName='Section-1_Solid', offset=0.0, 
    offsetType=MIDDLE_SURFACE, offsetField='', 
    thicknessAssignment=FROM_SECTION)

#Part and assembly regeneration
#
part1.regenerate()
assembly.regenerate()


#Creation of a set 'ControlPt1' using the center node at the small end.
#
assembNodes = instance.nodes

#Creation of constraints (kinematic couplings) at the small end and big end.
#
region1=assembly.sets['CONTROLPT1']

region2=assembly.surfaces['SURF_1_SMALL_END']
model.Coupling(name='Constraint-1', 
    controlPoint=region1, surface=region2, influenceRadius=WHOLE_SURFACE, 
    couplingType=KINEMATIC, localCsys=None, u1=ON, u2=ON, u3=ON, ur1=ON, 
    ur2=ON, ur3=ON)


#Creation of constraints (kinematic couplings) at the big end.
#
region1=assembly.sets['CONTROLPT2']

region2=assembly.surfaces['SURF_2_BIG_END']
model.Coupling(name='Constraint-2', 
    controlPoint=region1, surface=region2, influenceRadius=WHOLE_SURFACE, 
    couplingType=KINEMATIC, localCsys=None, u1=ON, u2=ON, u3=ON, ur1=ON, 
    ur2=ON, ur3=ON)



#Creation of Loads: 'Load-1' is created at the center node of the small end
#'Load-2' is created at the center node of the big end.
#
region = assembly.sets['CONTROLPT1']
model.ConcentratedForce(name='Load-1', 
    createStepName='Step-1', region=region, cf3=25000.0, 
    distributionType=UNIFORM, field='', localCsys=None)

#region = assembly.sets['CONTROLPT1']
model.ConcentratedForce(name='Load-3', 
    createStepName='Step-2', region=region, cf3=-2000.0, 
    distributionType=UNIFORM, field='', localCsys=None)

region = assembly.sets['CONTROLPT2']
model.ConcentratedForce(name='Load-2', 
    createStepName='Step-2', region=region, cf2=1750.0, 
    distributionType=UNIFORM, field='', localCsys=None)




#Creation of Displacement/Rotation Boundary conditions.
#

#For Step-1
#
nodes1 = assembNodes.getSequenceFromMask(mask=('[#0:631 #3000000 ]', ), )
region = regionToolset.Region(nodes=nodes1)
model.DisplacementBC(name='BC-1', 
    createStepName='Step-1', region=region, u1=0.0, u2=0.0, u3=UNSET, 
    ur1=UNSET, ur2=0.0, ur3=0.0, amplitude=UNSET, fixed=OFF, 
    distributionType=UNIFORM, fieldName='', localCsys=None)


nodes1 = assembNodes.getSequenceFromMask(mask=('[#0:631 #1000000 ]', ), )
region = regionToolset.Region(nodes=nodes1)

model.DisplacementBC(name='BC-2',createStepName='Step-1', region=region, u1=UNSET, u2=UNSET, u3=0.0, 
    ur1=UNSET, ur2=UNSET, ur3=UNSET, amplitude=UNSET, fixed=OFF, 
    distributionType=UNIFORM, fieldName='', localCsys=None)
    

#For Step-2
#

model.loads['Load-1'].deactivate('Step-2')
model.boundaryConditions['BC-1'].deactivate('Step-2')
model.boundaryConditions['BC-2'].deactivate('Step-2')


nodes1 = assembNodes.getSequenceFromMask(mask=('[#0:631 #3000000 ]', ), )
region = regionToolset.Region(nodes=nodes1)
model.DisplacementBC(name='BC-3', 
    createStepName='Step-2', region=region, u1=0.0, u2=UNSET, u3=UNSET, 
    ur1=UNSET, ur2=0.0, ur3=0.0, amplitude=UNSET, fixed=OFF, 
    distributionType=UNIFORM, fieldName='', localCsys=None)

nodes1 = assembNodes.getSequenceFromMask(mask=('[#0:631 #2000000 ]', ), )
region = regionToolset.Region(nodes=nodes1)
model.DisplacementBC(name='BC-4', 
    createStepName='Step-2', region=region, u1=UNSET, u2=0.0, u3=UNSET, 
    ur1=UNSET, ur2=UNSET, ur3=UNSET, amplitude=UNSET, fixed=OFF, 
    distributionType=UNIFORM, fieldName='', localCsys=None)

nodes1 = assembNodes.getSequenceFromMask(mask=('[#0:631 #1000000 ]', ), )
region = regionToolset.Region(nodes=nodes1)

model.DisplacementBC(name='BC-5',createStepName='Step-2', region=region, u1=UNSET, u2=UNSET, u3=0.0, 
    ur1=0.004, ur2=UNSET, ur3=UNSET, amplitude=UNSET, fixed=OFF, 
    distributionType=UNIFORM, fieldName='', localCsys=None)


#An elset selected asa region for Mesh Smoothing in Edit Optimization Task dialog
#
regionElset=assembly.sets['MESH_SMOOTH_ELEMENTS']

#A node set selected as design area region for the shape optimization region. 
#
designNodesRegion=assembly.sets['DESIGN_NODES']

#Creation of a shape optimization task
#
model.ShapeTask(name='conrodShapeOptimizaton', 
    region=designNodesRegion, freezeBoundaryConditionRegions=ON, 
    frozenBoundaryConditionRegion=MODEL, smoothingRegion=regionElset)



#Mises stress is selected as a design response for the design area nodes, which will be used
#in the objective function.
#
shapeOptimizationTask=model.optimizationTasks['conrodShapeOptimizaton']
shapeOptimizationTask.SingleTermDesignResponse(
    name='misesStress1', region=designNodesRegion, identifier='SIG_MISES', 
    drivingRegion=None, operation=MAXIMUM, shellLayer=MAXIMUM, stepOperation=MAXIMUM, stepOptions=(('Step-1', '', ALL, ALL), ))
    
shapeOptimizationTask.SingleTermDesignResponse(
    name='misesStress2', region=designNodesRegion, identifier='SIG_MISES', 
    drivingRegion=None, operation=MAXIMUM, shellLayer=MAXIMUM, stepOperation=MAXIMUM, stepOptions=(('Step-2', '', ALL, ALL), ))    

#Use of an element set 'ALL_SOLID_ELEMENTS' to be used as a region for the 
#Volume design response.
#
volConstRegion= assembly.sets['ALL_SOLID_ELEMENTS']

#Creation of the volume design response using the all solid elements (volConstRegion)
#
shapeOptimizationTask.SingleTermDesignResponse(
    name='volume', region=volConstRegion, identifier='VOLUME', drivingRegion=None, 
    operation=SUM, stepOptions=())

#Creation of the optimization constraint using Volume desgin response.
#
shapeOptimizationTask.OptimizationConstraint(
    name='volume', designResponse='volume', restrictionMethod=RELATIVE_EQUAL, 
    restrictionValue=1.0)

#Vector definition to be used in the Demolding restriction.
#
negDemoldVector=((0.0, 0.0, 0.0), (-1.0, 0.0, 0.0))

#A region used for Demolding restriction, 'demoldControlNeg'
#
negDemoldRegion = assembly.sets['SURF_DEMOLD_NEG']


#Creation of Demold Control, Geometric Restriction using negDemoldRegion
#
shapeOptimizationTask.ShapeDemoldControl(
    name='demoldControlNeg', masterPointDetermination=MAXIMUM, region=negDemoldRegion, 
    collisionCheckRegion=negDemoldRegion, masterPoint=None, csys=None, 
    pullDirection=negDemoldVector, tolerance1=0.01, tolerance2=0.01, tolerance3=0.01, 
    drawAngle=0.0, undercutTolerance=0.0, presumeFeasibleRegionAtStart=True)

#Vector definition to be used in the Demolding restriction.
#
posDemoldVector=((0.0, 0.0, 0.0), (1.0, 0.0, 0.0))

#A region used for Demolding restriction, 'demoldControlPos'
#
posDemoldRegion = assembly.sets['SURF_DEMOLD_POS']

#Creation of Demold Control, Geometric Restriction using posDemoldRegion
#
shapeOptimizationTask.ShapeDemoldControl(
    name='demoldControlPos', masterPointDetermination=MAXIMUM, region=posDemoldRegion, 
    collisionCheckRegion=posDemoldRegion, masterPoint=None, csys=None, 
    pullDirection=posDemoldVector, tolerance1=0.01, tolerance2=0.01, tolerance3=0.01, 
    drawAngle=0.0, undercutTolerance=0.0, presumeFeasibleRegionAtStart=True)


#Creation of the Objective Function to minimize the maximum desgin response (Mises Stress)
#


shapeOptimizationTask.ObjectiveFunction(
    name='minimizeMaxStress', target=MINIMIZE_MAXIMUM, objectives=((OFF, 'misesStress1', 1.0, 
    DEFAULT, ''), (OFF, 'misesStress2', 1.0, DEFAULT, '')))


#Creation of the Shape Optimization process of the model, conrodShapeOpt2.
#
mdb.OptimizationProcess(name='Shape-Opt-Process-1', model='connecting_rod', 
    task='conrodShapeOptimizaton', 
    description='Connecting rod shape optimization process', 
    prototypeJob='Shape-Opt-Process-1-Job', maxDesignCycle=15, 
    odbMergeFrequency=2, dataSaveFrequency=OPT_DATASAVE_FIRST_AND_LAST_CYCLE)

#Creation of the job of the Shape Optimization process,'Shape-Opt-Process-1'
#
mdb.optimizationProcesses['Shape-Opt-Process-1'].Job(
    name='Shape-Opt-Process-1-Job', model='connecting_rod', atTime=None, 
    waitMinutes=0, waitHours=0, queue=None, memory=50, memoryUnits=PERCENTAGE, 
    getMemoryFromAnalysis=True, explicitPrecision=SINGLE, 
    nodalOutputPrecision=SINGLE, multiprocessingMode=DEFAULT, numCpus=1)



#Display the model assembly
#

curViewport.setValues(displayedObject=assembly)

