import itertools
from abaqus import *
from abaqusConstants import *
from interaction import *
from SpindleAssembly import AddComponents as ah
from SpindleAssembly.AddComponents import return_assembly
[docs]def generate_connector_positions( pos1, pos2, MTtype, **kwargs ):
"""
Generate random points along the connection region of two ipMTs
:param pos1: (x, y, zBeginPos, zEndPos, l) -> coordinates of the free end of first ipMT
:param pos2: (x, y, zBeginPos, zEndPos, l) -> coordinates of the free end of the second ipMT
:param MTtype: 'parallel' or 'antiparallel' -> defines if the MT pair is parallel or antiparallel
:param kwargs: dictionary -> keyword arguments
:return: numpy array of connector positions along z coordinate
"""
import random
# Calculate the extent of connectors positioning
interval = abs(abs(pos1[3]) - abs(pos2[3]))
# Return an array with random z positions for the connectors
z = [random.uniform(0, interval) for n in range(kwargs['Nconnectors'])]
if MTtype == 'antiparallel':
# Calculate positions of connectors on ipMT-1
z1 = sorted([pos1[4] - zi for zi in z])
# Calculate position of connectors on ipMT-2
z2 = sorted([pos2[4] - interval + zi for zi in z])
# Calculate connector positions in global coordinates
z1_global = sorted([pos1[3] - zi for zi in z])
z2_global = sorted([pos2[3] - interval + zi for zi in z])
elif MTtype == 'parallel':
# Calculate positions of connectors on ipMT-1
z1 = sorted([pos1[3] - zi for zi in z])
# Calculate position of connectors on ipMT-2
z2 = sorted([pos2[3] - zi for zi in z])
else:
raise ValueError('Unsupported MT orientation type')
return z1, z2, z1_global, z2_global
[docs]def generate_partition_points(z, MTname, **kwargs):
"""
Partition individual ipMT with points corresponding to connector positions
:param z: numpy array of connector positions along z coordinate
:param MTname: name of the ipMT to be partitioned
:param kwargs: dictionary -> keyword arguments
:return: list -> partition names
"""
modelname = kwargs['modelname']
# Loop over connector position array and partition ipMT
for index, zcord in enumerate(z):
# Create datum points
p = mdb.models[modelname].parts[MTname]
p.DatumPointByCoordinate(coords=(zcord, 0, 0))
# Partition by datum point
p = mdb.models[modelname].parts[MTname]
e, v, d = p.edges, p.vertices, p.datums
p.PartitionEdgeByPoint(edge=e[index], point=d[4+2*index])
[docs]def position_connectors(pos1, pos2, z, connectornames, alpha, **kwargs):
"""
Position connectors on the associated ipMT by z coordinate
:param pos1: (x, y, zBeginPos, zEndPos, l) -> coordinates of the first mt of the pair
:param pos2: (x, y, zBeginPos, zEndPos, l) -> coordinates of the second mt of the pair
:param z: list connector positions
:param connectornames: list connector names
:param alpha: float orientation of connectors
:param kwargs: dictionary -> keyword arguments
:return: global coordinates of connectors between a pair of ipMTs
"""
a = ah.return_assembly(**kwargs)
# Position connectors
x0 = pos1[0]
x1 = pos2[0]
y0 = pos1[1]
z_global = [zi + pos1[3] - pos1[4] for zi in z]
for index, connectorname in enumerate(connectornames):
if x1 - x0 > 0:
angle = alpha
elif x1 - x0 < 0:
angle = 180 + alpha
else:
alpha = 0
a.rotate(instanceList=(connectorname, ),
axisPoint=(0.0, 0.0, 0.0),
axisDirection=(0.0, 0.0, 1.0),
angle=-90)
a.rotate(instanceList=(connectorname, ),
axisPoint=(0.0, 0.0, 0.0),
axisDirection=(0.0, 0.0, 1.0),
angle=angle)
a.translate(instanceList=(connectorname, ), vector=(x0, y0, z_global[index]))
return z_global
[docs]def pick_vertices(mtname, data, **kwargs):
"""
Pick the connecting ends of all connectors associated with the current ipMT
:param mtname: string name of the ipMT
:param data: list containing all ipMTs and connectors of the model
:param kwargs: dictionary -> keyword arguments
:return: list -> connecting vertices that belong to connectors associated with the current ipMT
"""
a = return_assembly(**kwargs)
# Store name, end_id and position of connectors attached to each ipMT
connector_data = []
for sublist in data:
if mtname == sublist[0]:
connector_data.append([a.instances[sublist[1]].vertices,
sublist[3],
a.instances[sublist[1]].vertices[sublist[3]].pointOn,
sublist[1]])
# Sort connectors by position
if int(mtname[-1]) % 2 == 0: # if ipMT is right
connector_data.sort(key=lambda tup: tup[2])
else: # else ipMT is left
connector_data.sort(key=lambda tup: tup[2], reverse=True)
return connector_data
[docs]def attach_connectors(data, **kwargs):
"""
Create attachment wire between two vertexes and define the properties of connection
:param data: list containing all ipMTs and connectors of the model
:param kwargs: dictionary -> keyword arguments
:return: Null
"""
a = return_assembly(**kwargs)
a.regenerate()
# Create connector section
modelname = kwargs['modelname']
# Iterate through unique ipMT names
mt_names = [sublist[0] for sublist in data]
mt_names = set(mt_names)
for mtname in mt_names:
for sublist in data:
if mtname == sublist[0]:
connector_end = sublist[3]
connector_name = sublist[1]
# Link points of ipMT with connector ends
end = a.instances[connector_name].vertices[connector_end].pointOn
masterPoint = a.instances[connector_name].vertices.findAt(end,)
masterName = 'master-'+connector_name+'-'+str(connector_end)
masterRegion = a.Set(vertices=masterPoint,
name=masterName)
slaveEdge = a.instances[mtname].edges
slaveName = 'slave-'+mtname
slaveRegion = a.Set(edges=slaveEdge, name=slaveName)
mdb.models[modelname].Coupling(name=masterName+slaveName,
controlPoint=masterRegion,
surface=slaveRegion,
influenceRadius=0.2,
couplingType=DISTRIBUTING,
weightingMethod=LINEAR,
localCsys=None, u1=ON, u2=ON, ur3=ON,
adjust=False)