Autor
|
Thema: Materialorientierung in einem Python Script definieren (4967 mal gelesen)
|
Jeremy Mitglied
Beiträge: 129 Registriert: 04.02.2009
|
erstellt am: 04. Feb. 2009 11:04 <-- editieren / zitieren --> Unities abgeben:
Hallo Forum, ich arbeite an meiner Diplomarbeit und schreibe ein Python Script für Abaqus um mehrere Bauteile in einem Assembly zusammenzubauen (damit soll das Gefüge eines Werkstoffs auf seine Spannungsverteilung und später auf Rissentstehung untersucht werden). Mein bisheriges Vorgehen: die Parts (Körner der Mikrostruktur) werden zunächst einzeln erstellt und bekommen ihre Materialeigenschaften. Im nächsten Schritt erstelle ich über "merge/cut instances" im Assembly-Module ein neues Part, das alle anderen enthält. Dieses soll dann vernetzt und analysiert werden. Da die Körner eines Gefüges keinen isotropen Materialeigenschaften haben, müssen zur Materialorietierung lokale Koordinatensystem (KS) vorgegeben werden (Funktion: "MaterialOrientation" oder "assignMaterialOrientation"). Die Erstellung der lokalten KS funktioniert. Mein Problem ist jetzt: Wie verknüpfe ich die lokalen KS mit der Funktion "MaterialOrientation"? Wenn ich die Zuweisung "von Hand" mache, befinden sich im aufgezeichneten Makro folgende Zeilen (nur für das erste von 3 Part): Code: 1 p = mdb.models['Gefuegemodell'].parts['Mikrostruktur'] 2 f = p.faces 3 faces = f.getSequenceFromMask(mask=('[#4 ]', ), ) 4 region = regionToolset.Region(faces=faces) 5 p = mdb.models['Gefuegemodell'].parts['Mikrostruktur'] 6 datums = p.datums[5] 7 p.MaterialOrientation(region=region, orientationType=SYSTEM, localCsys=datums)
a) Was genau sagt mir die Zeile 6? Was verbirgt sich hinter dem Speicherkonstukt "p.datums"? b) Wie kann ich zuverlässig eine Teilfläche eines Parts ansprechen? Ist Zeile 2 mit "getSequenceFromMask" dafür überhaupt geeignet oder ist "p.faces.findAt(coordinates =(x,y,z))" besser? Das sind jetzt mehrere Fragen auf einmal. Ich hoffe sehr, dass mir jemand weiter helfen kann. MfG Jeremy
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KubaG Mitglied
Beiträge: 165 Registriert: 18.11.2002
|
erstellt am: 04. Feb. 2009 11:18 <-- editieren / zitieren --> Unities abgeben: Nur für Jeremy
Hallo Jeremy, zu a) hier wird eine von Dir erzeugte Bezugsgröße (Punkt, Linie, Ebene oder Koordinatensytem) in die Variable datum geschrieben (alle Bezüge sind im Modellobjekt p im datum-array abgelegt; hier wird das sechste Element aus dem Array geholt und der Variable datum zugewiesen). zu b) alle parts in Deinem Assembly sind strukturiert in Zellen-, Flächen, Kurven- und Punktarrays. Über den Index sind z.B. die einzelnen Flächen eines parts ansprechbar. Unglücklicherweise ist der Array unstrukturiert, d.h. bei Änderungen am Part können sich die Indizes der bestehenden Flächen ändern. Am besten schaust Du mal in die Scripting-Manuals. Hoffe, das war hilfreich.
Gruß KubaG
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Jeremy Mitglied
Beiträge: 129 Registriert: 04.02.2009
|
erstellt am: 04. Feb. 2009 11:30 <-- editieren / zitieren --> Unities abgeben:
Hallo KuBaG, zu a) wenn ich dem zweiten Part (angenommen sind ingesamt 2 im Assembly vorhanden) die MaterialOrientierung selbst zuweise, und schon zweit KS bestehen, ist der Index i in datum = p.datums[i] nicht 6 wie ich erwartet habe, sondern 7, er steigt immer um 2 - warum eine Erhöhung um 2? zu b) mit welchem Befehl kann man sich das Array anzeigen lassen? Wenn ich z.B. schreibe "print p.datums" bekomme ich eine Fehlermeldung, dass der Key fehlt. (Das Array sollte ja kontinuierlich aufgefüllt werden. Folglich müsste eine Index i = 0 existieren, den gibt es aber nicht - warum nicht?) Gruß Jeremy Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
KubaG Mitglied
Beiträge: 165 Registriert: 18.11.2002
|
erstellt am: 04. Feb. 2009 13:39 <-- editieren / zitieren --> Unities abgeben: Nur für Jeremy
Hallo Jeremy, Du solltest >>print p.datums[0] tippen, um das erste Bezugselement anzeigen zu lassen (Achtung eckige Klammern!). Warum um 2 erhöht wird ist mir gerade nicht einsichtig. Hatte angenommen, daß jedes Bezugselement einen Platz im Array zugeteilt bekommt. Gruß KubaG
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Mustaine Ehrenmitglied V.I.P. h.c.
Beiträge: 3554 Registriert: 04.08.2005 Abaqus
|
erstellt am: 04. Feb. 2009 16:59 <-- editieren / zitieren --> Unities abgeben: Nur für Jeremy
Wie bereits erwähnt ist das p.datums[x] der Eintrag x aus der Liste der Hilfsobjekte (datum geometry). Wie da Dinge eingetragen werden weiß ich nicht. Das findAt() solltest du verwenden, wenn du später ggf. die Geometrie ändern möchtest. Dann kannst du bei findAt() gleich die Koordinaten mitändern lassen und bekommst so immer eine bestimmte Fläche.
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Jeremy Mitglied
Beiträge: 129 Registriert: 04.02.2009
|
erstellt am: 05. Feb. 2009 15:57 <-- editieren / zitieren --> Unities abgeben:
Hallo Mustaine, mit der Funktion myPart.faces.finAt() finde ich eine Fläche an bestimmen Koordinaten. Dieser Fläche ist ein Material zugeordnet (LAMINA) und es braucht noch eine lokale Materialorientierung. Wenn ich über den Script-Befehl myPart.MaterialOrientation(region = ..., orientationType = ..., localCsys = ...) gehe, wird nach einer Region gefragt. Wie kann man eine Fläche (face)in eine region umwandeln? Mit regionToolset.Region bekomme ich eine Fehlermeldung ("TypeError: faces; found Face, expecting GeomSequence"). Gruß Jeremy Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Jeremy Mitglied
Beiträge: 129 Registriert: 04.02.2009
|
erstellt am: 06. Feb. 2009 08:52 <-- editieren / zitieren --> Unities abgeben:
Eine Frage stellt sich mir noch. In p.datums werden die Bezugselemente gespeichert - datums ist übrigends keine Liste sondern ein Dictionary und die Einträge werden über den Key angesprochen. Gibt es einen Erklärungsansatz, warum die Keys mal aufeinanderfolgende Zahlen (also so: {5: 'DatumCsys object', 6: 'DatumCsys object'} ) sind und mal dien Abstand von 2 haben ( {5: 'DatumCsys object', 7: 'DatumCsys object'} )? Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Mustaine Ehrenmitglied V.I.P. h.c.
Beiträge: 3554 Registriert: 04.08.2005 Abaqus
|
erstellt am: 06. Feb. 2009 13:38 <-- editieren / zitieren --> Unities abgeben: Nur für Jeremy
Ich weiß nicht wie die Zahlen generiert werde, aber du kannst mit etwas Aufwand über alle datums iterieren und diese nach bestimmten Kriterien prüfen und dann ggf verwenden oder ignorieren. Hier ein Beispiel. Man hat in Model-1 als Part-1 eine Fläche, welche mit findAt() bei 0,0,0 gesucht wird. Dieser Fläche wird die Section-1 zugewiesen. Dann wird über alle datums ein csys gesucht, welches den Ursprung bei 0,0,0 hat. Dieses csys (bzw. das Letzte, falls es mehrere in 0,0,0 gibt) wird dann für die Orientierung verwendet. Code:
from abaqus import * from abaqusConstants import * from caeModules import * p = mdb.models['Model-1'].parts['Part-1'] userface=p.faces.findAt((0,0,0),) userregion=p.faces[userface.index:userface.index+1] region = regionToolset.Region(faces=userregion)
p.SectionAssignment(region=region, sectionName='Section-1', offset=0.0, offsetType=MIDDLE_SURFACE, offsetField='')
for i in range(len(p.datums)): try: if p.datums[p.datums.keys()[i]].origin.pointOn==(0,0,0): orientation=p.datums[p.datums.keys()[i]] except: print 'The item datum['+str(i)+'] is no csys'
mdb.models['Model-1'].parts['Part-1'].MaterialOrientation(region=region, orientationType=SYSTEM, localCsys=orientation, fieldName='', axis=AXIS_3, additionalRotationType=ROTATION_NONE, angle=0.0, additionalRotationField='')
[Diese Nachricht wurde von Mustaine am 06. Feb. 2009 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Oberjonny Mitglied Student
Beiträge: 24 Registriert: 18.05.2010
|
erstellt am: 07. Jan. 2011 16:56 <-- editieren / zitieren --> Unities abgeben: Nur für Jeremy
Hallo, ich habe eine Frage zu dem oben beschriebenen Lösungsweg. Ich versuche verschieden Flächen unterschiedliche Materialien zuzuordnen, wobei die Geometrie abhängig von dem Wert n_quadrat ist. Somit lässt sich die ganze Sache über eine Schleife automatisieren. Wenn ich den Lösungsvorschlag außerhalb einer Schleife benutze, bekomme ich keine Fehlermeldung: face_region = [] face = part.faces.findAt((1.0/8.0,1.0/8.0,0.0),) face_region += part.faces[face.index:face.index+1] Sobals ich allerdings die Befehle in eine Schleife einbaue, bekomme ich die folgende Fehlermeldung: TypeError: unsupported operand type(s) for +: 'AbaqusMethod' and 'int' Code: face_region = [] zaehler = 1 for i in range(1.0,n_quadrat+1.0,2.0): zaehler += 1 if (zaehler) % 2.0 == 0.0: for j in range(1.0,(n_quadrat)*2.0,4.0): face = part.faces.findAt(((((j*2.0)/(n_quadrat*2.0)), ((i*2.0)/(n_quadrat*2.0)), 0.0),)) face_region += part.faces[face.index:face.index+1] region=regionToolset.Region(faces=face_region) chess_part.SectionAssignment(region=region, sectionName='Test', offset=0.0, offsetType=MIDDLE_SURFACE) In der Hilfe steht unter 6.5.14 Basich geometry commands - Face object - Members, dass .index einen int-Wert zurückgibt. Allerdings steht in der Fehlermeldung, dass ich AbaqusMethod mit int addieren will. Wenn ich die "+1" in ein "+1.0" ändere steht in der Fehlermeldung, dass ich eine AbaqusMethod mit float kombinieren will, somit ist eindeutig, dass face.index hier nicht als int interpetriert wird. Kann mir jemand den Grund für den Fehler nennen? Ich benutze 6.10 Vielen Dank, Oberjonny [Diese Nachricht wurde von Oberjonny am 07. Jan. 2011 editiert.]
[Diese Nachricht wurde von Oberjonny am 07. Jan. 2011 editiert.] [Diese Nachricht wurde von Oberjonny am 07. Jan. 2011 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Oberjonny Mitglied Student
Beiträge: 24 Registriert: 18.05.2010
|
erstellt am: 10. Jan. 2011 11:00 <-- editieren / zitieren --> Unities abgeben: Nur für Jeremy
ich habe meinen Fehler jetzt selber gefunden, das Problem war, dass man die Werte face_a, face_region_a vorher einmal erstellt haben muss. Dies klingt für mich eigentlich auch logisch, aber kann ich das nicht irgendwie eleganter lösen, indem ich die Variablen vorher ohne Inhalt erstelle?Das Modell sieht aus wie ein Schachbrettmuster mit den Seitenlängen 1, wobei die Anzahl der einzelnen Muster durch den Wert n_quadrat variabel ist. Mit face_region_a und face_region_m erstelle ich regions und definiere so später unterschiedlich Materialien # looking for faces and regions in loops# zaehler = 1.0 # defining first a face face_a = chess_part.faces.findAt((1.0/(n_quadrat*2),1.0/(n_quadrat*2),0),) face_region_a = chess_part.faces[face_a.index:face_a.index+1] # defining first m face face_m = chess_part.faces.findAt((1.0/(n_quadrat*2),3.0/(n_quadrat*2),0),) face_region_m = chess_part.faces[face_m.index:face_m.index+1] # looking for the other faces with loops for i in range(1.0,n_quadrat*2.0,2.0): # defining faces in n_quadrat different lines zaehler += 1.0 # first line has an even number if (zaehler % 2.0 == 0.0): # even row for j in range(1.0,(n_quadrat*2.0),4.0): face_a = chess_part.faces.findAt((j/(n_quadrat*2),i/(n_quadrat*2),0),) face_region_a += chess_part.faces[face_a.index:face_a.index+1] face_m = chess_part.faces.findAt(((j+2)/(n_quadrat*2),i/(n_quadrat*2),0),) face_region_m += chess_part.faces[face_m.index:face_m.index+1] else: # uneven row for j in range(1.0,(n_quadrat*2.0),4.0): face_m = chess_part.faces.findAt((j/(n_quadrat*2),i/(n_quadrat*2),0),) face_region_m += chess_part.faces[face_m.index:face_m.index+1] face_a = chess_part.faces.findAt(((j+2)/(n_quadrat*2),i/(n_quadrat*2),0),) face_region_a += chess_part.faces[face_a.index:face_a.index+1]
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|