Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations MintJulep on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to select a closed loop of edges for SolidLoft() 3

Status
Not open for further replies.

Erikka

Geotechnical
Dec 10, 2009
7
Hi everyone,
I’m trying to write a python script to build a solid using the method SolidLoft(). The solid should be created by lofting between three sections (three closed loops of edges). Each section lies on a plane parallel to the xy plane (three different z) and it is made of a spline and a polyline.
I’m brand new to python and what I’ve done for now includes three lines of script to create the Splines plus three lines to create the Polylines, selecting the points with same z from txt files (x,y,z):

Splines:
mdb.models['importDPxyz'].parts['DPxyz'].WireSpline(points=(sorted([elem for elem in myPointsListS if elem[2] == 8],key=itemgetter(1))))
mdb.models['importDPxyz'].parts['DPxyz'].WireSpline(points=(sorted([elem for elem in myPointsListS if elem[2] == 4],key=itemgetter(1))))
mdb.models['importDPxyz'].parts['DPxyz'].WireSpline(points=(sorted([elem for elem in myPointsListS if elem[2] == 0],key=itemgetter(1))))

polylines:
mdb.models['importDPxyz'].parts['DPxyz'].WirePolyLine(points=([elem for elem in myPointsListPL if elem[2] == 8]))
mdb.models['importDPxyz'].parts['DPxyz'].WirePolyLine(points=([elem for elem in myPointsListPL if elem[2] == 4]))
mdb.models['importDPxyz'].parts['DPxyz'].WirePolyLine(points=([elem for elem in myPointsListPL if elem[2] == 0]))

How can I create the sequence of the edges that lies on a plane (i.e. z=0)? All the edges created in the same plane are a close loop, so they are the a good section for the creation of the solid loft.
I would like to create a loop to speed up the creation of many splines picking the points with different z from a bigger txt file (every z+1). I can copy and paste the same line, changing the z value, as I already did, but I think it is quite time consuming and quite stupid.

Thanks in advance,

Erika
 
Replies continue below

Recommended for you

I'm sorry, I forgot to post what I've already tryied in order to get the edges:

p=mdb.models['importDPxyz'].parts['DPxyz']
e=p.edges
pts=e.pointsOn
>>> print pts
(((1.75, 8.0, 4.0),), ((5.003389, 1.922384, 4.0),), ((4.5, 0.0, 4.0),), ((0.0, 2.0, 4.0),), ((1.25, 8.0, 8.0),), ((3.003389, 1.922384, 8.0),), ((3.0, 0.0, 8.0),), ((0.0, 2.0, 8.0),), ((2.25, 8.0, 0.0),), ((7.003389, 1.922384, 0.0),), ((6.0, 0.0, 0.0),), ((0.0, 2.0, 0.0),))

I have the points, I would like to group them in 3 groups with z=0, Z=4, Z=8 to be able to use them with the e.findAt()
Example, for z=0 I was thinking about something that looks like:

pts0=(elem for elem in pointsOn if elem[2]==0)
edges0=e.findAt(pts0)

but it doesn't work, the Abaqus aswer is:
TypeError: arg1; found 'generator', expecting a recognized type
>>> print pts0
<generator object at 0xFFAAFD00>

I would be great if someone could help me!!
Thank you and I apologize for the double posting.

Erika




 
Hello Erika,

When you are using list comprehensions you must write syntax in square brackets []. Round brackets () mean tuple which is immutable and you can not change them.
Please notice that list of points is sequence of sequence.
The good idea is to compare always data of the same type (integer to integer, real to real).

So following command:
pts0=(elem for elem in pointsOn if elem[2]==0)
should look:
pts0=[elem for elem in pointsOn if elem[0][2]==0.0]

Regards,
Barten
 
Hello Barten,

thank you for yor help! You're right, with the command you gave me I could extract the points in lists.
What happens now is that the method findAt() needs a tuple to find the edges and, obviously, if I try to use the list of points I extracted Abaqus says:

TypeError: arg1; too many arguments; expected 1, got 4

Do you know how can I solve this problem?

Thanks a lot for your help.

Erika
 

pts0=[elem for elem in pointsOn if elem[0][2]==0.0]
gives:
[((2.25, 8.0, 0.0),), ((7.003389, 1.922384, 0.0),), ((6.0, 0.0, 0.0),), ((0.0, 2.0, 0.0),)]

I tried to create a tuple from the above list with tuple(pts0), but I cannot use it as argument of findAt(). Again the abaqus message is:
TypeError: arg1; too many arguments; expected 1, got 4

It works copying and paste the tuple in this way,

e.findAt(((2.25, 8.0, 0.0),), ((7.003389, 1.922384, 0.0),), ((6.0, 0.0, 0.0),), ((0.0, 2.0, 0.0),))

but I'm looking for a better system, I cannot copy and paste many numbers. Sorry for the ridiculous method :)

Could you help me?

Erika
 
Hello Erika,

Instead of finding egdes for sequences of points, you can try to find edge for one point and the resuls (sequence of only one edge) append to additional list.
Syntax can look be similar to:

...
pts0=[elem for elem in pointsOn if elem[0][2]==0.0]
edgesFindAt = [e.findAt(point) for point in pts0]
...

Plase be aware that each element of list "edgesFindAt" is one element sequence with edge object. So to get access to the edge object you need to use index (e.g. edgesFindAt[0]).

Regards,
Bartosz
 
Hello Bartosz,

thank you! I'm learning a lot from the posts! I understand what you mean and I'm sure I'll use it in my script, but know I have to do a step backward. In the script I'm writing I wrote this thing:

mdb.models['importDPxyz'].parts['DPxyz'].WireSpline(points=(sorted([elem for elem in myPointsListS if elem[2] == 8 and elem is not None],key=itemgetter(1))))
mdb.models['importDPxyz'].parts['DPxyz'].WireSpline(points=(sorted([elem for elem in myPointsListS if elem[2] == 4 and elem is not None],key=itemgetter(1))))
mdb.models['importDPxyz'].parts['DPxyz'].WireSpline(points=(sorted([elem for elem in myPointsListS if elem[2] == 0 and elem is not None],key=itemgetter(1))))

from the input file (x,y,z points) it selects the points that have the same Z (in the above case the three values of Z are known), it sorts them by Y and it does the WireSpline along the points.
I'm trying to write a loop to do the same things for a more general case, in which I don't know the values of Z.

Do you have any advise? I tried many loops but none of them seem to be reasonable, I totally got lost.

Thanks,

Erika
 
Hi Erika,

Please try following simple script:

...
# create empty dictionary and list
zCoordDict = {}
tempSortList = []
# build up dictionary with sorted points respect to z-coord
for point in inList:
currentZCoord = point[2]
if not zCoordDict.has_key(currentZCoord): zCoordDict[currentZCoord] = []
zCoordDict[currentZCoord].append(point)
# sorting respect to y-coord
for key in zCoordDict.keys():
# build temporary list in format [y,(z,y,z)]
for point in zCoordDict[key]:
tempSortList.append([point[1],point])
# sort list respect to y
tempSortList.sort()
# overwrite dictionary values with sorted values
zCoordDict[key] = []
for point in tempSortList:
zCoordDict[key].append(point[1])
tempSortList = []
...

inList - tuple or list with points definitions in format ((x1,y1,z1),(x2,y2,z2),...)
zCoordDict - dictionary with sorted points. Each key is z-coordinate, each value is list with points for specified z-coord sorted respect to y-coord.

I hope it will help you.

Regards,
Barten
 
Hi Barten,

than you for your help and for you patience. Finally I was able to close the loop in this way :)

groupI=2
sortI=1

zlist=sorted(elem[groupI] for elem in myPointsListPL)
print zlist

MyLoftSign=[]
MyLoftSign.extend([0])
MyLoftSign[0]=zlist[0]
print MyLoftSign[0]
n=0
for i in range(len(zlist)):
z=zlist
if z!= MyLoftSign[n]:
n=n+1
MyLoftSign.extend([n])
MyLoftSign[n]=z

print MyLoftSign

#--filter points for wire spline for each z found, sort by y
MyLoftS=[]
for i in range(len(MyLoftSign)):
MyLoftS.extend()
MyLoftS= mdb.models['importDPxyz'].parts['DPxyz'].WireSpline(points=(sorted([elem for elem in myPointsListS if elem[groupI] == MyLoftSign],key=itemgetter(sortI))))
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor