"""
Abaqus Example Manaual script to create the model and the and optimization 
attributes for the topology optimization of a control arm.The script is run
using File -> Run Script in Abaqus/CAE. 
In order to successfully run control_arm_topology_optimization.py the user must have
control_arm.inp in the working directory.
"""

from abaqus import*
from abaqusConstants import *

#Importing input file as a model
#
mdb.ModelFromInputFile(name='control_arm', inputFileName='control_arm.inp')

model= mdb.models['control_arm']
assembly = model.rootAssembly
part= model.parts['PART-1']


#Define the current viewport
#
curViewportName=session.currentViewportName
curViewport=session.viewports[curViewportName]


#Creation of an elastic material
#
model.Material(name='Elastic_Material')
model.materials['Elastic_Material'].Elastic(table=((
    210000.0, 0.3), ))

#Creation of a solid section
#
model.HomogeneousSolidSection(name='Solid_Section', 
    material='Elastic_Material', thickness=None)

sectionRegion = part.sets['ALL_SOLID_ELEMENTS']


#Creation of a section assignment
#
part.SectionAssignment(region=sectionRegion, sectionName='Solid_Section', offset=0.0, 
    offsetType=MIDDLE_SURFACE, offsetField='', 
    thicknessAssignment=FROM_SECTION)

assembly.regenerate()



#Creating a load
#
loadRegion = assembly.sets['CONTROLPT']
model.ConcentratedForce(name='Load-1', 
    createStepName='Step-1', region=loadRegion, cf1=70000.0, cf2=-70000.0, 
    distributionType=UNIFORM, field='', localCsys=None)

constraint1Region=assembly.sets['CONTROLPT']

constraint1Surface=assembly.sets['CONSTR1_SURF']

#Creation of the first kinematic coupling constraint
#
model.Coupling(name='Constraint-1', controlPoint=constraint1Region, 
    surface=constraint1Surface, influenceRadius=WHOLE_SURFACE, couplingType=KINEMATIC, 
    localCsys=None, u1=ON, u2=ON, u3=ON, ur1=OFF, ur2=OFF, ur3=OFF)


constraint2Region=assembly.sets['CONTROLPT']

constraint2Surface=assembly.sets['CONSTR2_SURF']

#Creation of the second kinematic coupling constraint
#
model.Coupling(name='Constraint-2', controlPoint=constraint2Region, 
    surface=constraint2Surface, influenceRadius=WHOLE_SURFACE, couplingType=KINEMATIC, 
    localCsys=None, u1=ON, u2=ON, u3=OFF, ur1=OFF, ur2=OFF, ur3=OFF)



#Creation of Topology optimization task
#
designRegion = assembly.sets['DESIGN_ELEMENTS']
topolgyOptimTask=model.TopologyTask(algorithm=STIFFNESS_OPTIMIZATION, name=
    'controlArmTopologyOptimization', region = designRegion)


#Creation of Strain Energy design respone that is used in the objective function
#
topolgyOptimTask.SingleTermDesignResponse(identifier='STRAIN_ENERGY', name='strainEnergy', 
    operation=SUM, region=MODEL, stepOptions=())    
topolgyOptimTask.ObjectiveFunction(name=
    'minimizeStrainEnergy', target= MINIMIZE, objectives=((OFF, 'strainEnergy', 1.0, 0.0, ''), ))


#Creation of Volume Design Response that is used as the optimization constraint
#

topolgyOptimTask.SingleTermDesignResponse(identifier='VOLUME', name='volume', operation=SUM
    , region=MODEL, stepOptions=())    
topolgyOptimTask.OptimizationConstraint(
    designResponse='volume', name='volumeConstraint', restrictionMethod=
    RELATIVE_EQUAL, restrictionValue=0.57)


#Creation of Frozen Area Geometry Restriction
#
frozenRegion=assembly.sets['FROZEN_AREA']
topolgyOptimTask.FrozenArea(
    name='frozenAreaRestriction', region=frozenRegion)

#Creation of Demolod Control Geometry Restriction
#
topolgyOptimTask.TopologyDemoldControl(
    collisionCheckRegion = designRegion, 
    draftAngle=0.0, name='demoldControlRestriction', pointRegion=None, 
    pullDirection=((0.0, 0.0, 0.0), (0.0, 0.0, 1.0)), region=designRegion, technique=
    NONE)

#Creation of an optimization process with 17 design cycles
#
mdb.OptimizationProcess(dataSaveFrequency=OPT_DATASAVE_FIRST_AND_LAST_CYCLE, 
    description='', maxDesignCycle=17, model='control_arm', name=
    'Topo-Opt-Process-1', odbMergeFrequency=2, prototypeJob='Topo-Opt-Process-1-Job', 
    task='controlArmTopologyOptimization')
mdb.optimizationProcesses['Topo-Opt-Process-1'].Job(atTime=None, explicitPrecision=
    SINGLE, getMemoryFromAnalysis=True, memory=50, memoryUnits=PERCENTAGE, 
    model='control_arm', multiprocessingMode=DEFAULT, name='Topo-Opt-Process-1-Job'
    , nodalOutputPrecision=SINGLE, numCpus=1, queue=None, waitHours=0, 
    waitMinutes=0)

#Display of the model assembly
#
curViewport.setValues(displayedObject=assembly)

