# -*- coding: utf-8 -*-
from abaqus import mdb
from abaqusConstants import *
import mesh

MODEL = 'BlastNoSlip'
JOB = 'BlastNoSlipJob'

if MODEL in mdb.models:
    del mdb.models[MODEL]

m = mdb.Model(name=MODEL,
              modelType=STANDARD_EXPLICIT)

def addMat(name, rho, E, nu):
    q = m.Material(name=name)
    q.Density(table=((rho,),))
    q.Elastic(table=((E, nu),))

addMat('Soil', 1800., 30e6, 0.25)
addMat('Concrete', 2400., 35e9, 0.20)

for sec, mat in [('SoilSec','Soil'),
                 ('ConcreteSec','Concrete')]:
    m.HomogeneousSolidSection(name=sec,
                              material=mat)

def makeBlock(name, size, sec):
    x,y,z = size
    p = m.Part(name=name,
               dimensionality=THREE_D,
               type=DEFORMABLE_BODY)

    s = m.ConstrainedSketch(name=name+'_S',
                            sheetSize=100.)
    s.rectangle(point1=(-x/2.,-y/2.),
                point2=(x/2.,y/2.))

    p.BaseSolidExtrude(sketch=s,
                       depth=z)

    p.Set(name='ALL',
          cells=p.cells[:])

    p.SectionAssignment(region=p.sets['ALL'],
                        sectionName=sec)

    p.seedPart(size=0.5)
    p.setElementType(
        regions=(p.cells[:],),
        elemTypes=(mesh.ElemType(
            elemCode=C3D8R,
            elemLibrary=EXPLICIT),))
    p.generateMesh()

    return p

soil = makeBlock('Ground',
                 (20.,20.,20.),
                 'SoilSec')

building = makeBlock('Building',
                     (4.,8.,6.),
                     'ConcreteSec')

blast = building.faces.getByBoundingBox(
    xMin=-3., xMax=3.,
    yMin=-5., yMax=5.,
    zMin=5.9, zMax=6.1)

if len(blast) == 0:
    blast = building.faces[:]

building.Surface(name='BlastSurface',
                 side1Faces=blast)

a = m.rootAssembly
a.DatumCsysByDefault(CARTESIAN)

for p in [soil, building]:
    a.Instance(name=p.name,
               part=p,
               dependent=ON)

a.translate(instanceList=('Building',),
            vector=(0.,0.,10.))

# 仅法向接触，不调用 TangentialBehavior
prop = m.ContactProperty('HardContact')
prop.NormalBehavior(pressureOverclosure=HARD)

contact = m.ContactExp(name='Contact',
                       createStepName='Initial')

contact.includedPairs.setValuesInStep(
    stepName='Initial',
    useAllstar=ON)

contact.contactPropertyAssignments.appendInStep(
    stepName='Initial',
    assignments=((GLOBAL,
                  SELF,
                  'HardContact'),))

m.ExplicitDynamicsStep(name='Blast',
                       previous='Initial',
                       timePeriod=0.5)

rp = a.ReferencePoint(point=(0.,-6.,13.))
src = a.Set(name='BlastSource',
            referencePoints=(a.referencePoints[rp.id],))

m.IncidentWaveProperty(name='TNT100',
                       definition=AIR_BLAST,
                       massTNT=100.)

m.IncidentWave(name='BlastLoad',
               createStepName='Blast',
               definition=CONWEP,
               sourcePoint=src,
               surface=a.instances['Building'].surfaces['BlastSurface'],
               interactionProperty='TNT100',
               detonationTime=0.)

m.fieldOutputRequests['F-Output-1'].setValues(
    variables=('S','U','V','A'))

job = mdb.Job(name=JOB,
              model=MODEL,
              type=ANALYSIS,
              numCpus=4,
              numDomains=4)

job.writeInput(consistencyChecking=ON)
print('SOUTHWEITION_JOB_PREPARED')
import os as _sw_os
try:
    print('SOUTHWEITION_CWD ' + _sw_os.getcwd())
    def _sw_job_model(_job):
        _model = getattr(_job, 'model', '')
        try:
            return str(_model.name)
        except Exception:
            return str(_model or '')
    _sw_models = list(mdb.models.keys())
    _sw_latest_model = _sw_models[-1] if _sw_models else ''
    _sw_name = ''
    for _cand in reversed(list(mdb.jobs.keys())):
        if _sw_latest_model and _sw_job_model(mdb.jobs[_cand]) == _sw_latest_model:
            _sw_name = str(_cand)
            break
    if not _sw_name:
        _sw_names = list(mdb.jobs.keys())
        if _sw_names:
            _sw_name = str(_sw_names[-1])
    if _sw_name:
        try:
            mdb.jobs[_sw_name].setValues(numCpus=4, numDomains=4)
        except Exception:
            pass
        mdb.jobs[_sw_name].writeInput(consistencyChecking=OFF)
        print('SOUTHWEITION_JOB ' + str(_sw_name))
        print('SOUTHWEITION_MODEL ' + str(_sw_latest_model))
        print('SOUTHWEITION_INP ' + _sw_os.path.abspath(str(_sw_name) + '.inp'))
    print('SOUTHWEITION_JOB_PREPARED')
except Exception:
    print('SOUTHWEITION_JOB_PREPARED')

