from part import *
from step import *
from connectorBehavior import *
from interaction import *
from job import *
from material import *
import odbAccess
import pickle
import numpy as np
import Pabq.common_tools.abq_tools as at
# session.journalOptions.setValues(replayGeometry=COORDINATE, recoverGeometry=COORDINATE)
[docs]def set_connector(
bolt_diam=None,
bolt_grade=None,
grip_length=None,
threaded_grip_length=None
):
"""
Creates a dictionary with the description of a connector.
This object can be given as input to the modeler.
Parameters
----------
Return
------
dict
"""
cnctr_dict = {
"elasticity": {
"table": (
(
791752,
3690,
3690,
3997000,
20786700,
20786700
),
),
"independentComponents": (),
"components": (1, 2, 3, 4, 5, 6)
},
"plasticity": {
"isotropicTable": (
(
127000.0,
0.0,
0.0
),
(
143000.0,
0.021,
0.0
),
(
148000.0,
0.068,
0.0
),
(
151000.0,
0.18,
0.0
),
(
153000.0,
0.288,
0.0
),
(
155000.0,
0.45,
0.0
),
(
156000.0,
0.59,
0.0
),
(
156100.0,
1.0,
0.0
),
),
"kinematicTable": (),
"components": (1,)
},
"failure": {
"maxMotion": 5.0,
"components": (1, )
}
}
return cnctr_dict
[docs]def set_timehist():
"""Create a dictionary with the time history description of the displacements"""
time_hist = {
"data": (
(0.0, 0.0),
(10.0, 5.0),
# (2.0, 0.0),
# (3.0, -5.0),
# (4.0, 0),
# (5.0, 5)
),
"timeSpan": STEP,
}
return time_hist
[docs]def modeler(
name=None,
add=False,
cnctr_dict=None,
disp_control=True,
smooth_amp=False,
submit=True,
):
"""Create an Abaqus model with one connector"""
if name is None:
name = 'connector'
if add:
mdb.Model(name)
else:
# Start new model database.
Mdb()
# Change the pre-existing model name.
mdb.models.changeKey(
fromName='Model-1',
toName=name
)
if cnctr_dict is None:
cnctr_dict = set_connector()
# Names given to various objects throughout the model
names = {
"model": name,
"job": name + "_job",
"step1": "displacement_step",
"step2": "release_step",
"amplitude": "sequence_amp"
}
# Assign model object to a variable.
mdl = mdb.models[name]
# Create part
point_part = mdl.Part(
dimensionality=THREE_D,
name='point',
type=DISCRETE_RIGID_SURFACE
)
# Create a reference point
rp_1 = point_part.ReferencePoint(
point=(0.0, 0.0, 0.0)
)
# Create a set with the reference point
rp1_set = point_part.Set(
name='point_set',
referencePoints=(
point_part.referencePoints[1],
)
)
# Assign inertia to the point
point_mass = 1e-3
inertia = point_part.engineeringFeatures.PointMassInertia(
alpha=0.0,
composite=0.0,
i11=1.0,
i22=1.0,
i33=1.0,
mass=point_mass,
name='inertia_feature',
region=rp1_set
)
# Get the time history of the applied displacement
history_amp = set_timehist()
# Fetch the last timestamp on the given displacement amplitude history
tot_time = history_amp["data"][-1][0]
# Create an explicit step
step1 = mdl.ExplicitDynamicsStep(
timeIncrementationMethod=FIXED_USER_DEFINED_INC,
timePeriod=tot_time,
userDefinedInc=0.01,
name=names["step1"],
previous='Initial'
)
# Assign the root assebly object to a variable.
assembly = mdl.rootAssembly
# Set the global coordinate system to "cartesian"
assembly.DatumCsysByDefault(CARTESIAN)
# Create instances of the points at two ends of the connector in the assembly
point1_inst = assembly.Instance(
dependent=ON,
name='point-1',
part=point_part
)
point2_inst = assembly.Instance(
dependent=ON,
name='point-2',
part=point_part
)
# Move the second point.
assembly.translate(
instanceList=('point-2', ),
vector=(1.0, 0.0, 0.0)
)
# Grab the reference points created in the assembly for the two instances.
point1_rp = point1_inst.referencePoints[1]
point2_rp = point2_inst.referencePoints[1]
# Create a "wire" feature on which the connector properties will be assigned
cnctr_wire = assembly.WirePolyLine(
mergeType=IMPRINT,
meshable=OFF,
points=((
point1_rp,
point2_rp),
))
# Create a set for the wire.
assembly.Set(
edges=assembly.edges.getSequenceFromMask(('[#1 ]', ), ),
name='wire_set'
)
# Create and modify a connector section property
cnctr_section = mdl.ConnectorSection(
assembledType=BUSHING,
name='connector_section'
)
# Assign the connector properties as given from 'set_connector()'.
cnctr_section.setValues(
behaviorOptions=(
ConnectorElasticity(**cnctr_dict["elasticity"]),
ConnectorPlasticity(**cnctr_dict["plasticity"]),
ConnectorFailure(**cnctr_dict["failure"])
)
)
# Create a datum coord-sys to be used for the connector's "interaction" property orientation
cnctr_csys = assembly.DatumCsysByThreePoints(
coordSysType=CARTESIAN,
line1=(1.0, 0.0, 0.0),
line2=(0.0, 1.0, 0.0),
name='connector_csys',
origin=(0.0, 0.0, 0.0)
)
# Assign the connector section property to the wire
assembly.SectionAssignment(
region=assembly.sets['wire_set'],
sectionName='connector_section'
)
# Assign the datum object of the coordinate system to a variable
cnctr_dcsys_idx = int([i[0] for i in assembly.datums.summary() if i[1] == 'connector_csys'][0])
cnctr_dcsys = assembly.datums[cnctr_dcsys_idx]
# Assign orientation to the connector property
cnctr_orient = assembly.ConnectorOrientation(
localCsys1=cnctr_dcsys,
region=assembly.allSets['wire_set']
)
# Create boundary conditions at the two ends
disp_bc = mdl.DisplacementBC(
amplitude=UNSET,
createStepName='Initial',
distributionType=UNIFORM,
fieldName='',
localCsys=None,
name='BC-1',
region=point1_inst.sets['point_set'],
u1=SET,
u2=SET,
u3=SET,
ur1=SET,
ur2=SET,
ur3=SET
)
mdl.DisplacementBC(
amplitude=UNSET,
createStepName='Initial',
distributionType=UNIFORM,
fieldName='',
localCsys=None,
name='BC-2',
region=point2_inst.sets['point_set'],
u1=SET,
u2=SET,
u3=SET,
ur1=SET,
ur2=SET,
ur3=SET
)
# Create a smooth ramp for the displacement
if smooth_amp:
mdl.SmoothStepAmplitude(
name=names["amplitude"],
**history_amp
)
else:
mdl.TabularAmplitude(
name=names["amplitude"],
**history_amp
)
# Modify the boundary condition to apply the displacement/force
if disp_control:
mdl.boundaryConditions['BC-2'].setValuesInStep(
amplitude=names["amplitude"],
stepName=names["step1"],
u1=1.0
)
else:
mdl.boundaryConditions['BC-2'].setValuesInStep(
stepName=names["step1"],
u1=FREED
)
# Apply load if the displacement control method is set to False
if not disp_control:
mdl.ConcentratedForce(
cf1=1700000.0,
createStepName='displacement_step',
distributionType=UNIFORM,
field='',
localCsys=None,
name='pull_load',
region=point2_inst.sets['point_set'],
amplitude=names["amplitude"],
)
rp_out = mdl.HistoryOutputRequest(
createStepName=names["step1"],
name='rp_out',
rebar=EXCLUDE,
region=assembly.allInstances['point-2'].sets['point_set'],
sectionPoints=DEFAULT,
variables=(
'U1',
'U2',
'U3',
'UR1',
'UR2',
'UR3',
'RF1',
'RF2',
'RF3',
'RM1',
'RM2',
'RM3',
'CF1',
'CF2',
'CF3',
'CM1',
'CM2',
'CM3'
)
)
connector_out = mdl.HistoryOutputRequest(
createStepName=names["step1"],
name='connector_out',
rebar=EXCLUDE,
region=assembly.sets['wire_set'],
sectionPoints=DEFAULT,
variables=(
'CEF1',
'CEF2',
'CEF3',
'CEM1',
'CEM2',
'CEM3',
'CVF1',
'CVF2',
'CVF3',
'CVM1',
'CVM2',
'CVM3',
'CRF1',
'CRF2',
'CRF3',
'CRM1',
'CRM2',
'CRM3',
'CP1',
'CP2',
'CP3',
'CPR1',
'CPR2',
'CPR3',
'CU1',
'CU2',
'CU3',
'CUR1',
'CUR2',
'CUR3',
'CUE1',
'CUE2',
'CUE3',
'CURE1',
'CURE2',
'CURE3',
'CV1',
'CV2',
'CV3',
'CVR1',
'CVR2',
'CVR3',
'CA1',
'CA2',
'CA3',
'CAR1',
'CAR2',
'CAR3',
)
)
cnctr_job = mdb.Job(
activateLoadBalancing=False,
atTime=None,
contactPrint=OFF,
description='',
echoPrint=OFF,
explicitPrecision=SINGLE,
historyPrint=OFF,
memory=90,
memoryUnits=PERCENTAGE,
model=name,
modelPrint=OFF,
multiprocessingMode=DEFAULT,
name=names["job"],
nodalOutputPrecision=SINGLE,
numCpus=1,
numDomains=1,
parallelizationMethodExplicit=DOMAIN,
queue=None,
resultsFormat=ODB,
scratch='',
type=ANALYSIS,
userSubroutine='',
waitHours=0,
waitMinutes=0
)
if submit:
cnctr_job.submit(consistencyChecking=OFF)
cnctr_job.waitForCompletion()
mdb.saveAs(pathName=name+'.cae')
[docs]def export_results(name=None):
"""
Get results from connector odb.
Parameters
----------
modelname : str
Model base name (before the "_"). The results will be exported to a pickle file with the name
"modelname"_results.pkl
Returns
-------
tuple
"""
if name is None:
name = "connector"
odb = odbAccess.openOdb(name+"_job.odb")
timedisp = np.r_[[at.fetch_hist(odb, 'displacement_step', 'Node POINT-2.1', 'U1')]][0].transpose()
time, disp = (timedisp[0], timedisp[1])
load = np.r_[[at.fetch_hist(odb, 'displacement_step', 'Node POINT-2.1', 'RF1')]][0, :, 1]
time = time.tolist()
disp = disp.tolist()
load = load.tolist()
with open(name + "_results.pkl", "wb") as fh:
pickle.dump((time, disp, load), fh)
return time, disp, load
[docs]def main(**kargs):
# Assign the default name for the model
print("Pabaqus: CREATING MODEL WITH BASENAME 'connector'")
modelname = "connector"
# Build the model and execute the analysis
modeler(name=modelname, **kargs)
print("Pabaqus: MODEL EXECUTED")
# Export the results to a pickle file
export_results(name=modelname)
print("Pabaqus: RESULTS EXPORTED")
if __name__ == "__main__":
main()