├── AUTHORS ├── ChangeLog ├── gewichtung.so ├── gewichtung.dll ├── docs ├── abapysscripting.pdf ├── pilejackingexample.pdf ├── abapys.bodendatenbank.html ├── abapys.zahnrad.html ├── abapys.beautify.html ├── abapys.html ├── abapys.zeichnung.html ├── abapys.erstellung.html ├── abapys.hilfen.html ├── abapys.punktinelement.html ├── abapys.auswahl.html ├── abapys.grundkoerper.html ├── abapys.uebertragung.html ├── abapys.boden.html └── abapys.ausgabe.html ├── Materialdatenbank_202302.xlsx ├── MANIFEST.in ├── utils └── Makefile ├── abapys ├── __init__.py ├── zahnrad.py ├── zeichnung.py ├── erstellung.py ├── bodendatenbank.py ├── beautify.py ├── hilfen.py ├── auswahl.py └── grundkoerper.py └── README.md /AUTHORS: -------------------------------------------------------------------------------- 1 | Dominik Zobel 2 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | abapys 0.6.4 (2020-11-14) 2 | 3 | - Initial test release 4 | -------------------------------------------------------------------------------- /gewichtung.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d-zo/abapys/HEAD/gewichtung.so -------------------------------------------------------------------------------- /gewichtung.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d-zo/abapys/HEAD/gewichtung.dll -------------------------------------------------------------------------------- /docs/abapysscripting.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d-zo/abapys/HEAD/docs/abapysscripting.pdf -------------------------------------------------------------------------------- /docs/pilejackingexample.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d-zo/abapys/HEAD/docs/pilejackingexample.pdf -------------------------------------------------------------------------------- /Materialdatenbank_202302.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/d-zo/abapys/HEAD/Materialdatenbank_202302.xlsx -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS 2 | include ChangeLog 3 | include CONTRIBUTING.md 4 | include LICENSE 5 | include README.md 6 | -------------------------------------------------------------------------------- /utils/Makefile: -------------------------------------------------------------------------------- 1 | SOURCE_DIR = ../abapys 2 | TEMP_DIR = temp_work_dir 3 | LIB_DIR = ../ 4 | DOC_DIR = ../docs 5 | 6 | DOC_BLACKLIST = __init__ 7 | 8 | .PHONY: all compile pycdoc 9 | 10 | pycdoc: $(DOC_DIR)/abapys.html 11 | 12 | all: pycdoc compile 13 | 14 | compile: $(LIB_DIR)/gewichtung.so 15 | 16 | $(LIB_DIR)/gewichtung.so: $(LIB_DIR)/gewichtung.cpp 17 | g++ -std=c++11 -fPIC $^ -o $@ -shared; 18 | 19 | $(DOC_DIR)/abapys.html: $(SOURCE_DIR)/*.py 20 | mkdir -p $(TEMP_DIR)/abapys; 21 | cp -r $(SOURCE_DIR)/* $(TEMP_DIR)/abapys/; 22 | cd $(TEMP_DIR); \ 23 | pydoc2.7 -w abapys; \ 24 | sed -i 's:::' abapys.html; \ 25 | for pyfile in $(basename $(notdir $^)); do \ 26 | pydoc2.7 -w abapys.$$pyfile; \ 27 | sed -i "s:index.*.py::g" abapys.$$pyfile.html; \ 28 | done; \ 29 | for blacklisted in $(DOC_BLACKLIST); do \ 30 | sed -i "s:$$blacklisted
:$$blacklisted
:" abapys.html; \ 31 | rm abapys.$$blacklisted.html; \ 32 | done; 33 | mv $(TEMP_DIR)/*.html $(DOC_DIR)/; 34 | rm -r $(TEMP_DIR); 35 | -------------------------------------------------------------------------------- /abapys/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | .-. 4 | | | v0.6.6 5 | _ _| | _ _ _ _ _ _ _____ 6 | `' | ' `. `' | ' `| | / / _| 7 | | () | () | () | () | |/ /\_ `. 8 | . | . | | ' / _) ) 9 | \_,|_|_|\_/ \_,|_| |\_,| / |___/ 10 | | | / / 11 | D.Zobel 2017-2023 |_| /_/ 12 | 13 | Abaqus-Python Skriptsammlung 14 | """ 15 | 16 | # Copyright 2020-2023 Dominik Zobel. 17 | # All rights reserved. 18 | # 19 | # This file is part of the abapys library. 20 | # abapys is free software: you can redistribute it and/or modify 21 | # it under the terms of the GNU General Public License as published by 22 | # the Free Software Foundation, either version 3 of the License, or 23 | # (at your option) any later version. 24 | # 25 | # abapys is distributed in the hope that it will be useful, 26 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | # GNU General Public License for more details. 29 | # 30 | # You should have received a copy of the GNU General Public License 31 | # along with abapys. If not, see . 32 | 33 | 34 | from beautify import * 35 | from erstellung import * 36 | from ausgabe import * 37 | from bohrprofil import * 38 | from zahnrad import * 39 | from punktinelement import * 40 | from uebertragung import * 41 | from boden import * 42 | from bodendatenbank import * 43 | from grundkoerper import * 44 | from zeichnung import * 45 | from auswahl import * 46 | # Letzter Import, da hier vorangegangene/eingebaute Funktionen ueberschrieben werden 47 | from hilfen import * 48 | 49 | 50 | __author__ = 'Dominik Zobel'; 51 | __version__ = '0.6.6'; 52 | __package__ = 'abapys'; 53 | -------------------------------------------------------------------------------- /docs/abapys.bodendatenbank.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.bodendatenbank 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.bodendatenbank
13 |

bodendatenbank.py   v1.0 (2020-09)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Functions
       
Bodenparameter(name, stoffgesetz, bezeichnung='labor')
Lade fuer den Boden name die Bodenparameter nach dem stoffgesetz. Die in der dazugehoerigen
22 | Materialdatenbank gespeicherten Eintraege koennen mithilfe ihres Namens - und optional bei
23 | mehreren gleichnamigen Eintraegen mit einer zusaetzlichen bezeichnung - geladen werden.
24 | Gibt die dazugehoerigen bodenparameter zurueck.
25 |
26 | -------------------------------------------------------------------------------- /docs/abapys.zahnrad.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.zahnrad 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.zahnrad
13 |

zahnrad.py   v0.8 (2019-08)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Functions
       
Zahnrad_zylindernuten(modell, name, dicke, r_innen, r_aussen, r_zylinder, numZylinder, r_aussparung=0.0)
Erzeuge im modell ein Zahnrad (Part) name mit gegebener dicke, Innen- und Aussendurchmesser
22 | r_innen und r_aussen sowie numZylinder zylindrischen Aussparungen (und Zaehnen). Der Radius der
23 | Aussparungen betraegt r_zylinder. Optional kann eine eine zylindrische Aussparung mit Radius
24 | r_aussparung hinzugefuegt werden. Gibt [part<name>, inst<name>] zurueck.
25 |
26 | -------------------------------------------------------------------------------- /docs/abapys.beautify.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.beautify 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.beautify
13 |

beatify.py   v0.65 (2020-11)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Functions
       
ViewportVerschoenern(session, neuerHintergrund=True, saubererViewport=True, saubereLegende=True, evfSchnitt=False, minimaleKanten=True, farbspektrum='Viridis', diskreteFarben=True, ausgabeVerschmieren=True, zeigeMarkierungen=True, exportiereHintergrund=False, Standardansicht=False)
Wende die in dieser Funktion gespeicherten Standardwerte fuer die Ansicht des aktiven
22 | Viewports der session an. Optional koennen verschiedene Effekte aktiviert oder deaktiviert
23 | werden. Fuer farbspektrum sind die folgenden Spektren definiert: abpViridis, abpCubeHelix,
24 | abpRainbow und abpMoreland sowie deren Inverse (abpViridisINV, abpCubeHelixINV, abpRainbowINV und
25 | abpMorelandINV). Gibt einen Verweis auf den viewport zurueck.
26 |
27 | -------------------------------------------------------------------------------- /docs/abapys.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: package abapys 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys (version 0.6.6)
13 |

       .-.
14 |        | |  v0.6.6
15 |    _  _| | _   _  _ _  _  _   _____
16 |     `' | '  `.  `' | '  `| | / /  _|
17 |  | ()  |  () | ()  |  () | |/ /\_ `.
18 |  .     |     .     |     | ' /  _) )
19 |   \_,|_|_|\_/ \_,|_| |\_,|  /  |___/
20 |                    | |   / /
21 |  D.Zobel 2017-2023 |_|  /_/
22 |  
23 | Abaqus-Python Skriptsammlung

24 |

25 | 26 | 27 | 29 | 30 | 31 |
 
28 | Package Contents
       
ausgabe
32 | auswahl
33 | beautify
34 | boden
35 |
bodendatenbank
36 | bohrprofil
37 | erstellung
38 | grundkoerper
39 |
hilfen
40 | punktinelement
41 | uebertragung
42 | zahnrad
43 |
zeichnung
44 |

45 | 46 | 47 | 49 | 50 | 51 |
 
48 | Data
       __author__ = 'Dominik Zobel'
52 | __version__ = '0.6.6'
53 | abapys_tol = 1e-06
54 | g = 9.81
55 | grad2rad = 0.017453292519943295

56 | 57 | 58 | 60 | 61 | 62 |
 
59 | Author
       Dominik Zobel
63 | 64 | -------------------------------------------------------------------------------- /docs/abapys.zeichnung.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.zeichnung 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.zeichnung
13 |

zeichnung.py   v0.75 (2019-08)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Functions
       
Kreis(zeichnung, mittelpunkt, radius, bemasst=True)
Erstelle in der zeichnung einen Kreis mit gegebenem mittelpunkt und radius. Optional kann die
22 | Bemassung mit bemasst=False deaktiviert werden.
23 |
KreisbogenPunkte(zeichnung, mittelpunkt, punkt1, punkt2, richtung, bemasst=True)
Erstelle in der zeichnung einen Kreisbogen mit gegebenem mittelpunkt und radius von punkt1
24 | nach punkt2 in gegebener richtung (Abaqus-Konstante CLOCKWISE oder COUNTERCLOCKWISE).
25 | Optional kann die Bemassung mit bemasst=False deaktiviert werden.
26 |
KreisbogenWinkel(zeichnung, mittelpunkt, radius, startwinkel, endwinkel, richtung, bemasst=True)
Erstelle in der zeichnung einen Kreisbogen mit gegebenem mittelpunkt und radius. Startpunkt
27 | und Endpunkt sind ueber startwinkel, endwinkel (in Grad) und richtung definiert (richtung mit
28 | Abaqus-Konstante CLOCKWISE oder COUNTERCLOCKWISE). Optional kann die Bemassung mit bemasst=False
29 | deaktiviert werden.
30 |
Linie(zeichnung, punkt1, punkt2, bemasst=True)
Erstelle in der zeichnung eine gerade Linie von punkt1 zu punkt2. Optional kann die Bemassung
31 | mit bemasst=False deaktiviert werden.
32 |
Linienzug(zeichnung, punkte, geschlossen=False, bemasst=True)
Erstelle in der zeichnung einen Linienzug von/durch alle punkte. Optional kann der Linienzug
33 | geschlossen werden (erste Punkt wird mit letztem verbunden). Optional kann ausserdem die
34 | Bemassung mit bemasst=False deaktiviert werden.
35 |
Rechteck(zeichnung, punkt1, punkt2, bemasst=True)
Erstelle in der zeichnung ein Rechteck von punkt1 zu punkt2. Optional kann die Bemassung mit
36 | bemasst=False deaktiviert werden.
37 |
38 | -------------------------------------------------------------------------------- /abapys/zahnrad.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | zahnrad.py v0.8 (2019-08) 4 | """ 5 | 6 | # Copyright 2020-2021 Dominik Zobel. 7 | # All rights reserved. 8 | # 9 | # This file is part of the abapys library. 10 | # abapys is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # abapys is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with abapys. If not, see . 22 | 23 | 24 | # ------------------------------------------------------------------------------------------------- 25 | def Zahnrad_zylindernuten(modell, name, dicke, r_innen, r_aussen, r_zylinder, numZylinder, 26 | r_aussparung=0.0): 27 | """Erzeuge im modell ein Zahnrad (Part) name mit gegebener dicke, Innen- und Aussendurchmesser 28 | r_innen und r_aussen sowie numZylinder zylindrischen Aussparungen (und Zaehnen). Der Radius der 29 | Aussparungen betraegt r_zylinder. Optional kann eine eine zylindrische Aussparung mit Radius 30 | r_aussparung hinzugefuegt werden. Gibt [part, inst] zurueck. 31 | """ 32 | from math import sin, cos, acos, atan, sqrt 33 | import sketch 34 | import part 35 | import assembly 36 | from abaqusConstants import ON, CLOCKWISE, COUNTERCLOCKWISE, THREE_D, DEFORMABLE_BODY 37 | from zeichnung import KreisbogenPunkte, Kreis 38 | from hilfen import grad2rad, Log 39 | # 40 | # Ueberpruefungen 41 | mitSpitze = False; 42 | mitEvolventenwand = True; 43 | # 44 | winkel = 360.0/numZylinder*grad2rad; 45 | phi = winkel/2.0; 46 | zylindermpabstand = 2.0 * (r_innen+r_zylinder)*sin(phi); 47 | # 48 | r_spitze = (r_innen+r_zylinder)*cos(phi) + \ 49 | sqrt((zylindermpabstand-r_zylinder)**2 - (zylindermpabstand/2.0)**2); 50 | if (r_aussen > r_spitze): 51 | Log('Warnung: r_aussen zu gross, verkuerze auf r_spitze'); 52 | r_aussen = r_spitze; 53 | beta = 0.0; 54 | mitSpitze = True; 55 | else: 56 | beta = acos((r_aussen**2 + (r_innen + r_zylinder)**2 - (zylindermpabstand-r_zylinder)**2)/ \ 57 | (2.0*r_aussen*(r_innen + r_zylinder))) - phi; 58 | # 59 | r_kontaktloesung = sqrt(((r_innen+r_zylinder)*cos(phi))**2 + (zylindermpabstand/2.0-r_zylinder)**2); 60 | if (r_aussen < r_kontaktloesung): 61 | # Zahn wird naeher am Mittelpunkt abgeschnitten als Verbindungsgerade der Zylindermittelpunkte 62 | la = (r_innen + r_zylinder)/2.0 + (r_zylinder**2 - r_aussen**2)/(2.0*(r_innen + r_zylinder)); 63 | psi_kontakt = acos(la/r_zylinder); 64 | # 65 | l_red = r_zylinder*sin(90*grad2rad-phi-psi_kontakt); 66 | h_red = zylindermpabstand/2.0-r_zylinder*cos(90*grad2rad-phi-psi_kontakt); 67 | beta = atan(h_red/((r_innen+r_zylinder)*cos(phi)-l_red)); 68 | mitEvolventenwand = False; 69 | else: 70 | psi_kontakt = 90*grad2rad - phi; 71 | # 72 | modell.ConstrainedSketch(name='__profile__', sheetSize=2.0*r_aussen); 73 | zeichnung = modell.sketches['__profile__']; 74 | for idxBereich in range(numZylinder): 75 | bemasst = False; 76 | if (idxBereich == 0): 77 | bemasst = True; 78 | # 79 | offsetwinkel = (idxBereich+0.5)*winkel; 80 | # Jeder Bereich wird in vier Teilstrecken unterteilt, um die Kontur zu zeichnen 81 | mittelpunkt_aktuell = ((r_innen+r_zylinder)*sin(offsetwinkel), 82 | (r_innen+r_zylinder)*cos(offsetwinkel)); 83 | mittelpunkt_naechster = ((r_innen+r_zylinder)*sin(offsetwinkel+winkel), 84 | (r_innen+r_zylinder)*cos(offsetwinkel+winkel)); 85 | # 1) Auflageflaeche der Zylinder am Zahnrad 86 | punkta = (mittelpunkt_aktuell[0] - r_zylinder*sin(offsetwinkel+psi_kontakt), 87 | mittelpunkt_aktuell[1] - r_zylinder*cos(offsetwinkel+psi_kontakt)); 88 | punktb = (mittelpunkt_aktuell[0] - r_zylinder*sin(offsetwinkel-psi_kontakt), 89 | mittelpunkt_aktuell[1] - r_zylinder*cos(offsetwinkel-psi_kontakt)); 90 | KreisbogenPunkte(zeichnung=zeichnung, mittelpunkt=mittelpunkt_aktuell, 91 | punkt1=punkta, punkt2=punktb, richtung=COUNTERCLOCKWISE, bemasst=bemasst); 92 | # 2) Erste Evolventenwand, falls vorhanden 93 | if (mitEvolventenwand): 94 | punkta = punktb; 95 | punktb = ((r_aussen)*sin(offsetwinkel+phi-beta), (r_aussen)*cos(offsetwinkel+phi-beta)); 96 | KreisbogenPunkte(zeichnung=zeichnung, mittelpunkt=mittelpunkt_naechster, 97 | punkt1=punkta, punkt2=punktb, richtung=CLOCKWISE, bemasst=bemasst); 98 | # 3) Aussenlaeche, falls keine Spitze 99 | if (not mitSpitze): 100 | punkta = punktb; 101 | punktb = ((r_aussen)*sin(offsetwinkel+phi+beta), (r_aussen)*cos(offsetwinkel+phi+beta)); 102 | KreisbogenPunkte(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), 103 | punkt1=punkta, punkt2=punktb, richtung=CLOCKWISE, bemasst=bemasst); 104 | # 4) Zweite Evolventenwand, falls vorhanden 105 | if (mitEvolventenwand): 106 | punkta = punktb; 107 | punktb = (mittelpunkt_naechster[0] - r_zylinder*sin(offsetwinkel+winkel+psi_kontakt), 108 | mittelpunkt_naechster[1] - r_zylinder*cos(offsetwinkel+winkel+psi_kontakt)); 109 | KreisbogenPunkte(zeichnung=zeichnung, mittelpunkt=mittelpunkt_aktuell, punkt1=punkta, 110 | punkt2=punktb, richtung=CLOCKWISE, bemasst=bemasst); 111 | # 112 | if (r_aussparung > 0.0): 113 | Kreis(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), radius=r_aussparung); 114 | # 115 | partZahnrad = modell.Part(dimensionality=THREE_D, name=name, type=DEFORMABLE_BODY); 116 | partZahnrad.BaseSolidExtrude(depth=dicke, sketch=zeichnung); 117 | del zeichnung; 118 | instname = 'inst' + name; 119 | instZahnrad = modell.rootAssembly.Instance(dependent=ON, name=instname, part=modell.parts[name]); 120 | return [partZahnrad, instZahnrad]; 121 | # 122 | -------------------------------------------------------------------------------- /docs/abapys.erstellung.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.erstellung 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.erstellung
13 |

erstellung.py   v0.8 (2020-09)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Classes
       
22 |
__builtin__.object 23 |
24 |
25 |
PunktListe 26 |
27 |
28 |
29 |

30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 |
 
33 | class PunktListe(__builtin__.object)
   Mini-Klasse zur Erstellung von Paaren aus Koordinaten und Labels.
 
 Methods defined here:
39 |
__init__(self, coordinates, label)
40 | 41 |
__repr__(self)
42 | 43 |
44 | Data descriptors defined here:
45 |
__dict__
46 |
dictionary for instance variables (if defined)
47 |
48 |
__weakref__
49 |
list of weak references to the object (if defined)
50 |
51 |

52 | 53 | 54 | 56 | 57 | 58 |
 
55 | Functions
       
AxiallagerErstellen(modell, name, punkt1, punkt2, kos)
Erzeuge im modell ein Axiallager name von punkt1 zu punkt2 mit dem Koordinatensystem kos. Beim
59 | Axiallager ist nur eine Verschiebung entlang der x-Achse des uebergebenen KOS moeglich.
60 |
DrehscharnierErstellen(modell, name, punkt1, punkt2, kos)
Erzeuge im modell ein Drehscharnier name von punkt1 zu punkt2 mit dem Koordinatensystem kos.
61 | Beim Drehscharnier ist nur eine Drehung um die x-Achse des uebergebenen KOS moeglich.
62 |
Knotentransformation(punktliste, xneu='x', yneu='y', zneu='z')
Erstelle eine neue Knotenliste basierend auf punktliste. Dabei werden von allen Eintraegen nur
63 | label und coordinates uebernommen. Die Koordinaten koennen ueber die Felder xneu, yneu und zneu
64 | transformiert werden.
65 | Gibt die transformierte punktliste zurueck.
66 |  
67 | Fuer alle drei Variablen kann eine Transformationsanweisung wie bspw.
68 | "sqrt(x**2+y**2)" uebergeben werden, wobei jeweils die Variablen x, y und z zur Verfuegung
69 | stehen, die die Orignalwerte fuer jeden Knoten enthalten.
70 |  
71 | Fuer mathematische Zusammenhaenge stehen die Funktionen pi, sqrt, sin, cos, tan, asin, acos, atan
72 | zur Verfuegung.
73 |  
74 | WICHTIG: Wenn eine Zustandsuebertragung mit Knoten stattfinden soll, die in dieser Funktion
75 |          transformiert worden sind, dann werden auch tatsaechlich nur die Knotenkoordinaten
76 |          und keinerlei Werte modifiziert. Das gilt insbesondere fuer Drehungen wie im angegebenen
77 |          Beispiel, bei dem Tensorergebnisse nicht gedreht, sondern nur an anderer Stelle
78 |          ausgegeben werden.
79 |
NamePartInstance(modell, namensvorschlag)
Ermittle basierend auf namensvorschlag einen Namen fuer ein part/instance im uebergebenen
80 | modell, der eindeutig ist/noch nicht existiert. Dazu wird modell.parts mit <namensvorschlag> und
81 | modell.rootAssembly.instances mit inst<namensvorschlag> untersucht und namensvorschlag und ggs.
82 | mehreren Anpassungen davon ueberprueft. Gibt den (ggfs. angepassten) namensvorschlag zurueck.
83 |
ReferenzpunktErstellenUndKoppeln(modell, punkt, name, flaeche)
In der rootAssembly von modell einen Referenzpunkt an den Koordinaten punkt erstellen, zu name
84 | umbenennen und mit der uebergebenen flaeche verknuepfen.
85 |
86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | abapys 0.6.6 3 | ============ 4 | 5 | [abapys](https://github.com/d-zo/abapys) is a collection of special purpose Python functions 6 | for creating parametrized models or postprocessing simulation results with 7 | the commercial Finite-Element-Analysis software 8 | [Abaqus](https://www.3ds.com/products-services/simulia/products/abaqus/ "SIMULIA Abaqus"). 9 | It was created alongside work at the Institute of Geotechnical Engineering 10 | at the Hamburg University of Technology. 11 | Therefore it is centered around model creation and output processing for simulations of 12 | soil samples and soil-structure interaction. 13 | All functions were tested for Abaqus versions between 6.14-2 (2015) and Abaqus 2020. 14 | 15 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.4467987.svg)](https://doi.org/10.5281/zenodo.4467987) 16 | 17 | 18 | 19 | Installation 20 | ------------ 21 | 22 | abapys requires the commercial Finite-Element-Analysis software 23 | [Abaqus](https://www.3ds.com/products-services/simulia/products/abaqus/ "SIMULIA Abaqus") 24 | and uses its Python interpreter. 25 | Although it could be integrated within Abaqus' Python environment, 26 | it can also be included in the module path and imported. 27 | Therefore it can be stored in an arbitrary folder and loaded by 28 | 29 | ``` 30 | abapys_dir = r'C:\path\to\abapys' # For Windows-based systems 31 | abapys_dir = '/path/to/abapys' # For Linux-based systems 32 | sys.path.insert(0, abapys_dir); 33 | 34 | from abapys import * 35 | ``` 36 | 37 | abapys can use material parameters from Spreadsheets (`.xlsx`-files). 38 | To read those files [openpyxl](https://openpyxl.readthedocs.io) 39 | and its dependencies [et_xmlfile](https://pypi.org/project/et_xmlfile/) 40 | and [jdcal](https://github.com/phn/jdcal) are used as external dependencies 41 | and have to be provided. 42 | One possible solution is to install abapys and those dependencies in one folder, 43 | which has to be included in the module path. The structure should look like the following 44 | 45 | ``` 46 | abapys/ 47 | +- abapys/ 48 | | +- __init__.py 49 | | +- ausgabe.py 50 | | +- beautify.py 51 | | + ... 52 | | 53 | +- Materialdatenbank_20####.xlsx 54 | +- gewichtung.dll 55 | +- gewichtung.so 56 | | 57 | +- openpyxl/ 58 | | +- cell/ 59 | | +- chart/ 60 | | +- chartsheet/ 61 | | + ... 62 | | 63 | +- et_xmlfile/ 64 | | +- tests/ 65 | | +- __init__.py 66 | | +- xmlfile.py 67 | | 68 | +- jdcal.py 69 | ``` 70 | 71 | 72 | 73 | Usage and Documentation 74 | ----------------------- 75 | 76 | A simple function documentation (in german) created with pydoc can be found 77 | [here](https://d-zo.github.io/abapys/abapys.html "abapys documentation"). 78 | The functions can either be called in the Abaqus command prompt for interactive results or 79 | put in scripts with other commands to record a sequence of instructions. 80 | The basic usage and some examples are given in the ”Abaqus scripting with abapys“ tutorial. 81 | A html-version of the tutorial can be found 82 | [here](https://d-zo.github.io/abapys/abapysscripting.html "Abaqus scripting with abapys [html]") 83 | and a pdf-version 84 | [here](https://d-zo.github.io/abapys/abapysscripting.pdf "Abaqus scripting with abapys [pdf]"). 85 | 86 | Another project called [SimpleScriptGenerator](https://github.com/d-zo/SimpleScriptGenerator) 87 | can help to create scripts with abapys functions. 88 | [SimpleScriptGenerator](https://github.com/d-zo/SimpleScriptGenerator) is providing 89 | a user interface for intuitive and interactive script creation. 90 | The logic and content of it can be adjusted with different configuration files. 91 | So a preconfigured configuration named _abapys_front_ can be used 92 | to create scripts with Abaqus commands and abapys functions. 93 | Abaqus and abapys are not necessary to create these scripts. 94 | In order to run the scripts however, both tools are required. 95 | 96 | If you have no or very little knowledge of Abaqus, 97 | you may want to have a look at some tutorials (and the resulting Python code) first. 98 | There is also a tutorial called ”Pile jacking example in Abaqus“, 99 | which can help getting started with Abaqus and Python. 100 | An html-version of the tutorial can be found 101 | [here](https://d-zo.github.io/abapys/pilejackingexample.html "Pile jacking example in Abaqus [html]") 102 | and an pdf-version 103 | [here](https://d-zo.github.io/abapys/pilejackingexample.pdf "Pile jacking example in Abaqus [pdf]"). 104 | 105 | 106 | 107 | Structure 108 | --------- 109 | 110 | Originally all abapys functions were written in Python. 111 | Due to speed issues a library for finding points in elements and their weighting 112 | was converted to C++ (_gewichtung.dll_ and _gewichtung.so_). 113 | The functions are saved in different files, 114 | but those with similar scope are usually saved in the same file: 115 | 116 | - _ausgabe.py_: Adjust/saving the viewport and extracting/plotting/saving simulation results 117 | - _auswahl.py_: Selection of geometric entities by condition/labels 118 | - _beautify.py_: Subjective viewport beautification function 119 | - _boden.py_: Create soil body and assign stress states 120 | - _bodendatenbank.py_: Load soil material parameters from spreadsheet 121 | - _bohrprofil.py_: Create screw and full displacement pile parts 122 | - _erstellung.py_: Connector constraints and reference point coupling 123 | - _gewichtung.cpp_: Weighting of one set of elements/nodes in regard to another set of elements/nodes 124 | - _grundkoerper.py_: Create basic geometric parts 125 | - _hilfen.py_: Initialisation and general-purpose functions 126 | - _punktinelement.py_: Point localisation/weighting and volume calculation of elements 127 | - _uebertragung.py_: Initialise/transfer state variables from one mesh to another 128 | - _zahnrad.py_: Create a gear wheel part (lantern pinion) 129 | - _zeichnung.py_: Create sketches for part extrusion or revolution 130 | 131 | 132 | 133 | Contributing 134 | ------------ 135 | 136 | **Bug reports** 137 | 138 | If you found a bug, make sure you can reproduce it with the latest version of abapys. 139 | Please check that the expected results can actually be achieved by other means 140 | and are not considered invalid operations in Abaqus and its Python interpreter. 141 | Please give detailed and reproducible instructions in your report including 142 | 143 | - the abapys version 144 | - the expected result 145 | - the result you received 146 | - the command(s) used as a _minimal working example_ 147 | 148 | Note: The bug should ideally be reproducible by the _minimal working example_ alone. 149 | Please keep the example code as short as possible (minimal). 150 | Try not to load additional files like `.cae` or `.odb` if possible. 151 | If it can't be avoided make them as small and simple as possible. 152 | 153 | 154 | **Feature requests** 155 | 156 | If you have an idea for a new feature, consider searching the 157 | [open issues](https://github.com/d-zo/abapys/issues) and 158 | [closed issues](https://github.com/d-zo/abapys/issues?q=is%3Aissue+is%3Aclosed) first. 159 | Afterwards, please submit a report in the 160 | [Issue tracker](https://github.com/d-zo/abapys/issues) explaining the feature and especially 161 | 162 | - why this feature would be useful (use cases) 163 | - what could possible drawbacks be (e.g. compatibility, dependencies, ...) 164 | 165 | 166 | 167 | Similar software 168 | ---------------- 169 | 170 | There is a project called [abapy](https://github.com/lcharleux/abapy) which also provides 171 | a collection of Python functions for use in Abaqus. 172 | But the intention and focus of the functions are completely different. 173 | 174 | 175 | 176 | License 177 | ------- 178 | 179 | abapys is released under the 180 | [GPL](https://www.gnu.org/licenses/gpl-3.0.html "GNU General Public License"), 181 | version 3 or greater (see also [LICENSE](https://github.com/d-zo/abapys/blob/master/LICENSE) file). 182 | It is provided without any warranty. 183 | 184 | -------------------------------------------------------------------------------- /abapys/zeichnung.py: -------------------------------------------------------------------------------- 1 | #-*- coding: utf-8 -*- 2 | """ 3 | zeichnung.py v0.75 (2019-08) 4 | """ 5 | 6 | # Copyright 2020-2021 Dominik Zobel. 7 | # All rights reserved. 8 | # 9 | # This file is part of the abapys library. 10 | # abapys is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # abapys is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with abapys. If not, see . 22 | 23 | 24 | # ------------------------------------------------------------------------------------------------- 25 | def Linie(zeichnung, punkt1, punkt2, bemasst=True): 26 | """Erstelle in der zeichnung eine gerade Linie von punkt1 zu punkt2. Optional kann die Bemassung 27 | mit bemasst=False deaktiviert werden. 28 | """ 29 | from math import sqrt 30 | import sketch 31 | # 32 | zeichnung.Line(point1=punkt1, point2=punkt2); 33 | if (punkt1[1] == punkt2[1]): 34 | mittelpunktx = (punkt1[0] + punkt2[0])/2.0; 35 | #zeichnung.HorizontalConstraint(entity=zeichnung.geometry.findAt((mittelpunktx, punkt1[1]), )); 36 | if (bemasst): 37 | zeichnung.HorizontalDimension(textPoint=(mittelpunktx, punkt2[1]+0.25*(punkt2[0]-punkt1[0])), 38 | value=abs(punkt2[0] - punkt1[0]), 39 | vertex1=zeichnung.vertices.findAt(punkt1, ), 40 | vertex2=zeichnung.vertices.findAt(punkt2, )); 41 | elif (punkt1[0] == punkt2[0]): 42 | mittelpunkty = (punkt1[1] + punkt2[1])/2.0; 43 | #zeichnung.VerticalConstraint(entity=zeichnung.geometry.findAt((punkt1[0], mittelpunkty), )); 44 | if (bemasst): 45 | zeichnung.VerticalDimension(textPoint=(punkt1[0]+0.25*(punkt2[1]-punkt1[1]), mittelpunkty), 46 | value=abs(punkt2[1] - punkt1[1]), 47 | vertex1=zeichnung.vertices.findAt(punkt1, ), 48 | vertex2=zeichnung.vertices.findAt(punkt2, )); 49 | else: 50 | if (bemasst): 51 | if ((punkt1[0]**2 + punkt2[1]**2) > (punkt2[0]**2 + punkt1[1]**2)): 52 | textpunkt = (punkt1[0], punkt2[1]); 53 | else: 54 | textpunkt = (punkt2[0], punkt1[1]); 55 | zeichnung.ObliqueDimension(textPoint=textpunkt, 56 | value=sqrt((punkt2[0] - punkt1[0])**2 + (punkt2[1] - punkt1[1])**2), 57 | vertex1=zeichnung.vertices.findAt(punkt1, ), 58 | vertex2=zeichnung.vertices.findAt(punkt2, )); 59 | # 60 | 61 | 62 | # ------------------------------------------------------------------------------------------------- 63 | def Linienzug(zeichnung, punkte, geschlossen=False, bemasst=True): 64 | """Erstelle in der zeichnung einen Linienzug von/durch alle punkte. Optional kann der Linienzug 65 | geschlossen werden (erste Punkt wird mit letztem verbunden). Optional kann ausserdem die 66 | Bemassung mit bemasst=False deaktiviert werden. 67 | """ 68 | for idx, aktuellerpunkt in enumerate(punkte): 69 | if (idx > 0): 70 | Linie(zeichnung=zeichnung, punkt1=punkte[idx-1], punkt2=aktuellerpunkt, bemasst=bemasst); 71 | # 72 | if (geschlossen): 73 | Linie(zeichnung=zeichnung, punkt1=punkte[-1], punkt2=punkte[0], bemasst=False); 74 | # 75 | 76 | 77 | # ------------------------------------------------------------------------------------------------- 78 | def Rechteck(zeichnung, punkt1, punkt2, bemasst=True): 79 | """Erstelle in der zeichnung ein Rechteck von punkt1 zu punkt2. Optional kann die Bemassung mit 80 | bemasst=False deaktiviert werden. 81 | """ 82 | import sketch 83 | # 84 | zeichnung.rectangle(point1=punkt1, point2=punkt2); 85 | #zeichnung.HorizontalConstraint(entity=zeichnung.geometry.findAt( 86 | # ((punkt1[0] + punkt1[0])/2.0, punkt2[1]), )); 87 | zeichnung.HorizontalDimension(value=abs(punkt2[0]-punkt1[0]), 88 | textPoint=((punkt1[0] + punkt2[0])/2.0, punkt2[1]+0.25*(punkt2[0]-punkt1[0])), 89 | vertex1=zeichnung.vertices.findAt((punkt1[0], punkt2[1]), ), 90 | vertex2=zeichnung.vertices.findAt((punkt2[0], punkt2[1]), )); 91 | zeichnung.VerticalDimension(value=abs(punkt2[1]-punkt1[1]), 92 | textPoint=(punkt1[0]+0.25*(punkt2[1]-punkt1[1]), (punkt1[1] + punkt2[1])/2.0), 93 | vertex1=zeichnung.vertices.findAt((punkt1[0], punkt1[1]), ), 94 | vertex2=zeichnung.vertices.findAt((punkt1[0], punkt2[1]), )); 95 | # 96 | 97 | 98 | # ------------------------------------------------------------------------------------------------- 99 | def Kreis(zeichnung, mittelpunkt, radius, bemasst=True): 100 | """Erstelle in der zeichnung einen Kreis mit gegebenem mittelpunkt und radius. Optional kann die 101 | Bemassung mit bemasst=False deaktiviert werden. 102 | """ 103 | from math import sqrt 104 | import sketch 105 | # 106 | zeichnung.CircleByCenterPerimeter(center=mittelpunkt, 107 | point1=(mittelpunkt[0]+radius, mittelpunkt[1])); 108 | if (bemasst): 109 | zeichnung.RadialDimension(radius=radius, 110 | textPoint=(mittelpunkt[0]+radius/2.0, mittelpunkt[1]+radius/2.0), 111 | curve=zeichnung.geometry.findAt((mittelpunkt[0]+radius/sqrt(2), mittelpunkt[1]+radius/sqrt(2)), )); 112 | # 113 | 114 | 115 | # ------------------------------------------------------------------------------------------------- 116 | def KreisbogenWinkel(zeichnung, mittelpunkt, radius, startwinkel, endwinkel, richtung, bemasst=True): 117 | """Erstelle in der zeichnung einen Kreisbogen mit gegebenem mittelpunkt und radius. Startpunkt 118 | und Endpunkt sind ueber startwinkel, endwinkel (in Grad) und richtung definiert (richtung mit 119 | Abaqus-Konstante CLOCKWISE oder COUNTERCLOCKWISE). Optional kann die Bemassung mit bemasst=False 120 | deaktiviert werden. 121 | """ 122 | from math import sin, cos 123 | from hilfen import grad2rad 124 | # 125 | KreisbogenPunkte(zeichnung=zeichnung, mittelpunkt=mittelpunkt, 126 | punkt1=(mittelpunkt[0] + radius*sin(startwinkel*grad2rad), 127 | mittelpunkt[1] + radius*cos(startwinkel*grad2rad)), 128 | punkt2=(mittelpunkt[0] + radius*sin(endwinkel*grad2rad), 129 | mittelpunkt[1] + radius*cos(endwinkel*grad2rad)), 130 | richtung=richtung, bemasst=bemasst); 131 | # 132 | 133 | 134 | # ------------------------------------------------------------------------------------------------- 135 | def KreisbogenPunkte(zeichnung, mittelpunkt, punkt1, punkt2, richtung, bemasst=True): 136 | """Erstelle in der zeichnung einen Kreisbogen mit gegebenem mittelpunkt und radius von punkt1 137 | nach punkt2 in gegebener richtung (Abaqus-Konstante CLOCKWISE oder COUNTERCLOCKWISE). 138 | Optional kann die Bemassung mit bemasst=False deaktiviert werden. 139 | """ 140 | from math import sqrt 141 | import sketch 142 | from abaqusConstants import CLOCKWISE 143 | # 144 | zeichnung.ArcByCenterEnds(center=mittelpunkt, point1=punkt1, point2=punkt2, direction=richtung); 145 | if (bemasst): 146 | # Richtung ist definiert als die Normale der Verbindungslinie 147 | mp_richtung = (punkt1[1] - punkt2[1], punkt2[0] - punkt1[0]); 148 | laenge_mp_richtung = sqrt(mp_richtung[0]**2 + mp_richtung[1]**2); 149 | mp_richtung = (mp_richtung[0]/laenge_mp_richtung, mp_richtung[1]/laenge_mp_richtung); 150 | # 151 | radius = sqrt((mittelpunkt[0]-punkt1[0])**2 + (mittelpunkt[1]-punkt1[1])**2); 152 | # Einer von zwei moeglichen Punkten liegt auf dem Kreisbogen 153 | if (richtung == CLOCKWISE): 154 | masspunkt = (mittelpunkt[0] + mp_richtung[0]*radius, 155 | mittelpunkt[1] + mp_richtung[1]*radius); 156 | else: 157 | masspunkt = (mittelpunkt[0] - mp_richtung[0]*radius, 158 | mittelpunkt[1] - mp_richtung[1]*radius); 159 | # 160 | textpunkt = ((mittelpunkt[0] + masspunkt[0])/2.0, (mittelpunkt[1] + masspunkt[1])/2.0); 161 | zeichnung.RadialDimension(curve=zeichnung.geometry.findAt(masspunkt, ), radius=radius, 162 | textPoint=textpunkt); 163 | # 164 | -------------------------------------------------------------------------------- /abapys/erstellung.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | erstellung.py v0.8 (2020-09) 4 | """ 5 | 6 | # Copyright 2020-2021 Dominik Zobel. 7 | # All rights reserved. 8 | # 9 | # This file is part of the abapys library. 10 | # abapys is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # abapys is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with abapys. If not, see . 22 | 23 | 24 | # ------------------------------------------------------------------------------------------------- 25 | class PunktListe(object): 26 | """Mini-Klasse zur Erstellung von Paaren aus Koordinaten und Labels. 27 | """ 28 | def __init__(self, coordinates, label): 29 | self.coordinates = coordinates; 30 | self.label = label; 31 | def __repr__(self): 32 | return 'PunktListe (abapys)'; 33 | # 34 | 35 | 36 | # ------------------------------------------------------------------------------------------------- 37 | def NamePartInstance(modell, namensvorschlag): 38 | """Ermittle basierend auf namensvorschlag einen Namen fuer ein part/instance im uebergebenen 39 | modell, der eindeutig ist/noch nicht existiert. Dazu wird modell.parts mit und 40 | modell.rootAssembly.instances mit inst untersucht und namensvorschlag und ggs. 41 | mehreren Anpassungen davon ueberprueft. Gibt den (ggfs. angepassten) namensvorschlag zurueck. 42 | """ 43 | name = namensvorschlag; 44 | nameGefunden = False; 45 | while (not nameGefunden): 46 | instname = 'inst' + name; 47 | if ((not modell.parts.has_key(name)) and (not modell.rootAssembly.instances.has_key(instname))): 48 | nameGefunden = True; 49 | else: 50 | name = name + 'x'; 51 | # 52 | return name; 53 | # 54 | 55 | 56 | # ------------------------------------------------------------------------------------------------- 57 | def ReferenzpunktErstellenUndKoppeln(modell, punkt, name, flaeche): 58 | """In der rootAssembly von modell einen Referenzpunkt an den Koordinaten punkt erstellen, zu name 59 | umbenennen und mit der uebergebenen flaeche verknuepfen. 60 | """ 61 | import assembly 62 | import interaction 63 | from abaqusConstants import ON, DISTRIBUTING, WHOLE_SURFACE, UNIFORM 64 | # 65 | modell.rootAssembly.ReferencePoint(point=punkt); 66 | modell.rootAssembly.features.changeKey(fromName='RP-1', toName='RP_' + name); 67 | # 68 | modell.rootAssembly.Set(name='setRP_' + name, referencePoints=( 69 | modell.rootAssembly.referencePoints[modell.rootAssembly.features['RP_' + name].id], )); 70 | # 71 | modell.Coupling(controlPoint=modell.rootAssembly.sets['setRP_' + name], couplingType=DISTRIBUTING, 72 | influenceRadius=WHOLE_SURFACE, localCsys=None, name='Couple_' + name, 73 | surface=flaeche, u1=ON, u2=ON, u3=ON, ur1=ON, ur2=ON, ur3=ON, weightingMethod=UNIFORM); 74 | # 75 | 76 | 77 | # ------------------------------------------------------------------------------------------------- 78 | def _ConnectorErstellen(modell, verbindungstyp, name, punkt1, punkt2, kos): 79 | """Erzeuge im modell einen Connector name von punkt1 zu punkt2 mit dem Koordinatensystem kos. Je 80 | nach verbindungstyp werden gewisse Einschraenkungen der Freiheitsgrade - bezogen auf das 81 | uebergebene KOS (!) - fest zugewiesen: 82 | - 'TranslateConnector': Beim Axiallager ist nur eine Verschiebung entlang der x-Achse moeglich. 83 | - 'HingeConnector': Beim Drehscharnier ist nur eine Drehung um die x-Achse moeglich. 84 | """ 85 | import section 86 | import assembly 87 | from abaqusConstants import TRANSLATOR, HINGE, IMPRINT 88 | from auswahl import BedingteAuswahl 89 | from hilfen import Log 90 | # 91 | if (verbindungstyp == 'TranslateConnector'): 92 | if (not modell.sections.has_key('TranslateConnector')): 93 | modell.ConnectorSection(assembledType=TRANSLATOR, name='TranslateConnector'); 94 | # 95 | elif (verbindungstyp == 'HingeConnector'): 96 | if (not modell.sections.has_key('HingeConnector')): 97 | modell.ConnectorSection(assembledType=HINGE, name='HingeConnector'); 98 | else: 99 | Log('# Warnung: Connector nicht implementiert'); 100 | # 101 | modell.rootAssembly.WirePolyLine(mergeType=IMPRINT, meshable=False, points=((punkt1, punkt2), )); 102 | modell.rootAssembly.features.changeKey(fromName='Wire-1', toName=name); 103 | # 104 | KabelKanten = BedingteAuswahl(elemente=modell.rootAssembly.edges, 105 | bedingung='elem.featureName == \'' + name + '\''); 106 | modell.rootAssembly.Set(edges=KabelKanten, name='set' + name); 107 | # 108 | modell.rootAssembly.SectionAssignment(sectionName=verbindungstyp, 109 | region=modell.rootAssembly.sets['set' + name]); 110 | modell.rootAssembly.ConnectorOrientation(localCsys1=kos, 111 | region=modell.rootAssembly.sets['set' + name]); 112 | # 113 | 114 | 115 | # ------------------------------------------------------------------------------------------------- 116 | def AxiallagerErstellen(modell, name, punkt1, punkt2, kos): 117 | """Erzeuge im modell ein Axiallager name von punkt1 zu punkt2 mit dem Koordinatensystem kos. Beim 118 | Axiallager ist nur eine Verschiebung entlang der x-Achse des uebergebenen KOS moeglich. 119 | """ 120 | _ConnectorErstellen(modell=modell, verbindungstyp='TranslateConnector', name=name, 121 | punkt1=punkt1, punkt2=punkt2, kos=kos); 122 | # 123 | 124 | 125 | # ------------------------------------------------------------------------------------------------- 126 | def DrehscharnierErstellen(modell, name, punkt1, punkt2, kos): 127 | """Erzeuge im modell ein Drehscharnier name von punkt1 zu punkt2 mit dem Koordinatensystem kos. 128 | Beim Drehscharnier ist nur eine Drehung um die x-Achse des uebergebenen KOS moeglich. 129 | """ 130 | _ConnectorErstellen(modell=modell, verbindungstyp='HingeConnector', name=name, 131 | punkt1=punkt1, punkt2=punkt2, kos=kos); 132 | # 133 | 134 | 135 | # ------------------------------------------------------------------------------------------------- 136 | def Knotentransformation(punktliste, xneu='x', yneu='y', zneu='z'): 137 | """Erstelle eine neue Knotenliste basierend auf punktliste. Dabei werden von allen Eintraegen nur 138 | label und coordinates uebernommen. Die Koordinaten koennen ueber die Felder xneu, yneu und zneu 139 | transformiert werden. 140 | Gibt die transformierte punktliste zurueck. 141 | 142 | Fuer alle drei Variablen kann eine Transformationsanweisung wie bspw. 143 | "sqrt(x**2+y**2)" uebergeben werden, wobei jeweils die Variablen x, y und z zur Verfuegung 144 | stehen, die die Orignalwerte fuer jeden Knoten enthalten. 145 | 146 | Fuer mathematische Zusammenhaenge stehen die Funktionen pi, sqrt, sin, cos, tan, asin, acos, atan 147 | zur Verfuegung. 148 | 149 | WICHTIG: Wenn eine Zustandsuebertragung mit Knoten stattfinden soll, die in dieser Funktion 150 | transformiert worden sind, dann werden auch tatsaechlich nur die Knotenkoordinaten 151 | und keinerlei Werte modifiziert. Das gilt insbesondere fuer Drehungen wie im angegebenen 152 | Beispiel, bei dem Tensorergebnisse nicht gedreht, sondern nur an anderer Stelle 153 | ausgegeben werden. 154 | """ 155 | from math import pi, sqrt, sin, cos, tan, asin, acos, atan 156 | from hilfen import Log, _Eval_Basispruefung 157 | # 158 | neue_knotenliste = [] 159 | # 160 | if (any([(not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=['x', 'y', 'z'])) for bedingung in [xneu, yneu, zneu]])): 161 | Log('# Abbruch: Uebergebene xneu/yneu/zneu ungueltig'); 162 | return; 163 | # 164 | for knoten in punktliste: 165 | x = knoten.coordinates[0]; 166 | y = knoten.coordinates[1]; 167 | z = knoten.coordinates[2]; 168 | xmod = eval(xneu); 169 | ymod = eval(yneu); 170 | zmod = eval(zneu); 171 | # 172 | if (not (zneu is None)): 173 | neue_knotenliste += [PunktListe(coordinates=(xmod, ymod, zmod), label=knoten.label)]; 174 | else: 175 | neue_knotenliste += [PunktListe(coordinates=(xmod, ymod), label=knoten.label)]; 176 | # 177 | return neue_knotenliste; 178 | # 179 | -------------------------------------------------------------------------------- /docs/abapys.hilfen.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.hilfen 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.hilfen
13 |

hilfen.py   v3.3 (2020-11)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Functions
       
BibliothekLaden(dateiname)
Lade eine kompilierte Bibliothek (.so unter Linux und .dll unter Windows) und gebe die mit
22 | ctypes geoeffnete Bibliothek zurueck. dateiname ist ohne Endung (d.h. ohne .so/.dll) anzugeben.
23 | Die Bibliothek wird aus dem Verzeichnis von abapys bzw. dem ueber das pfad-Argument im Befehl
24 | InitialisiereAbapys() geladen. Gibt den ctypes-Zugriffspunkt auf die bibliothek zurueck.
25 |
BlockAusgabe(ausgabeliste, eintraegeProZeile=8, trennung=', ')
Die ausgabeliste wird pro Zeile auf eintraegeProZeile begrenzt und der Rest in
26 |    einer oder mehreren Folgezeilen ausgegeben. Dabei wird die trennung zwischen jeden der Eintraege
27 |    eingefuegt. Gibt einen String zurueck, der nach allen eintraegeProZeile ein '
28 | ' enthaelt.
29 |
Einheitsvektor(dim, idxEins)
Erstelle einen Vektor der Groesse dim, der ueberall Nullen hat und eine Eins an der Stelle
30 | idxEins. Gibt den Einheitsvektor zurueck.
31 |
ElementAusOdb(element)
Pruefe anhand des uebergebenen element, aus welchem Kontext das element stammt. Gibt True
32 | zurueck, wenn ein Bezug zu session.odbs[...].rootAssembly.instances[...].elements vorhanden ist,
33 | ansonsten False
34 |
ElementeMitZielwert(elemliste, zielwert)
Pruefe alle Elemente in elemliste, ob deren Wert (elemliste[#].data) dem zielwert entspricht.
35 | Gibt [Labels] der Elemente zurueck, fuer die das gilt.
36 |
ErstelleElementLabelsortierteGeomlist(geomliste)
Gibt ein Dictionary mit den elementLabels und den indizes der uebergebenen geomliste zurueck,
37 | um anschliessend schnell ueber die elementLabels statt Indizes auf die Eintraege aus geomliste
38 | zugreifen zu koennen.
39 |
ErstelleLabelsortierteGeomlist(geomliste)
Gibt ein Dictionary mit den labels und den indizes der uebergebenen geomliste zurueck, um
40 | anschliessend schnell ueber die Labels statt Indizes auf die Eintraege aus geomliste zugreifen
41 | zu koennen.
42 |
ErstelleNodeLabelsortierteGeomlist(geomliste)
Gibt ein Dictionary mit den nodeLabels und den indizes der uebergebenen geomliste zurueck,
43 | um anschliessend schnell ueber die nodeLabels statt Indizes auf die Eintraege aus geomliste
44 | zugreifen zu koennen.
45 |
GueltigenNamenFinden(umgebung, namensvorschlag)
Waehle basierend auf dem namensvorschlag einen eindeutigen Namen, der in der uebergebenen
46 | umgebung noch nicht existiert. Dazu wird der namensvorschlag geprueft und mit einer Zahl von
47 | 000-900 erweitert, bis er eindeutig ist. Gibt den (ggfs. ueberarbeiteten) namensvorschlag zurueck.
48 |
InitialisiereAbapys(session, version=2018, pfad='/exports/all/intern/abapys/', xSkalierung=None, ySkalierung=None)
Erkenne und speichere, ob sich die aktuelle session in der GUI oder Konsole befindet und
49 | welche version von Abaqus verwendet wird. Dazu werden die internen Variablen von Abaqus
50 | uebergeben, so dass session und version nicht manuell definiert werden muessen. Normalerweise
51 | koennen also die Argumente (session=session, version=version) uebergeben werden.
52 |  
53 | Falls nicht der Standardpfad fuer zusaetzliche Dateien (bspw. Bibliotheken oder Materialtabelle)
54 | genutzt werden soll, kann der Pfad explizit ueber pfad angegeben werden. In dieser Funktion
55 | werden Skalierungswerte fuer den Viewport bei einer Bildausgabe berechnet, die aber durch
56 | Uebergabe der Faktoren xSkalierung und ySkalierung ueberschrieben werden koennen.
57 |
Log(ausgabe, ueberschreiben=False)
Die uebergebene ausgabe entweder in Abaqus behalten oder in die Konsole umleiten, falls abapys
58 | initialisiert worden ist und die GUI nicht aktiv ist. Optional kann ein ueberschreiben der
59 | Ausgabe aktiviert werden (z.B. fuer Status-/Prozentangaben).
60 |
OrdnerPruefen(ordnername)
Prueft die Existenz eines Ordners ordnername und erstellt ihn, falls er nicht vorhanden ist.
61 |
ViewportGroesseAendern(viewport, bildgroesse)
Aendere die Groesse von viewport zu bildgroesse (in Pixel).
62 |
ViewportPixelGroesseExtrahieren(viewport)
Gibt die Groesse von viewport in Pixeln [breite, hoehe] zurueck.
63 |

64 | 65 | 66 | 68 | 69 | 70 |
 
67 | Data
       abapys_tol = 1e-06
71 | g = 9.81
72 | grad2rad = 0.017453292519943295
73 | -------------------------------------------------------------------------------- /docs/abapys.punktinelement.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.punktinelement 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.punktinelement
13 |

punktinelement.py   v1.3 (2021-01)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Functions
       
ElementInfolisteErstellen(elemente, knoten, listenhilfe=[])
Erstelle eine Hilfsliste mit Punktkoordinaten und Volumina aller uebergebenen elemente. Dazu
22 | wird neben elemente eine Liste aller Punktkoordinaten (knoten) benoetigt. Die optionale
23 | Uebergabe einer Zuordnung listenhilfe von Labels zu Indizes beschleunigt den Vorgang.
24 | Gibt elementinfoliste zurueck.
25 |  
26 | WICHTIG: Wenn Elemente einer mdb statt einer odb untersucht werden sollen, sollte entweder keine
27 |          oder die folgende listenhilfe uebergeben werden:
28 |  
29 | listenhilfe = [idx for idx in range(len(knoten))];
30 |
ElementVolumen(punkte, dimensionen)
Berechnet das Referenzvolumen eines 3D-Elements oder die Referenzflaeche eines 2D-Elements,
31 | abhaengig davon ob dimensionen 2 oder 3 ist. Unterstuetzt werden Hexaeder, Tetraeder (3D) sowie
32 | Vierecke und Dreiecke (2D). Fuer die korrekte Berechnung muessen die Knoten von Hexaeder und
33 | Viereck-Elements in der dargestellen Reihenfolge gespeichert sein (was Abaqus standardmaessig
34 | tun sollte):
35 |  
36 | 7 __________  6          #
37 |   \         \            #   3  ____________  0
38 |   |\        .\           #     |            |
39 |   | \       . \          #     |            |
40 |   |4 \_________\ 5       #     |            |
41 |   |  |      .  |         #     |            |
42 | 3 |..|....... 2|         #     |            |
43 |   \  |       . |         #     |            |
44 |    \ |        .|         #     |____________|
45 |     \|_________|         #   2                1
46 |    0             1       #
47 |    
48 | Gibt das Volumen eines Elements zurueck.
49 |
KnotengewichtungInElement(element, referenzpunkt, knoten, listenhilfe=[])
Bestimmt die Anteile, die ein referenzpunkt aus den Knotenpunkten des in punkte definierten
50 | Elements hat. Die Koordinaten der Elemente muessen in knoten definiert sein. Die optionale
51 | Uebergabe einer Zuordnung Listenhilfe von Labels zu Indizes beschleunigt den Vorgang.
52 | Gibt [labelsEckpunkte, Knotengewichtung] zurueck.
53 |  
54 | WICHTIG: Wenn Elemente einer mdb statt einer odb untersucht werden sollen, sollte entweder keine
55 |          oder die folgende listenhilfe uebergeben werden:
56 |  
57 | listenhilfe = [idx for idx in range(len(knoten))];
58 |
KnotengewichtungPunktInPunktkoordinaten(punkte, referenzpunkt, dimensionen)
Bestimmt die Anteile, die ein referenzpunkt aus den Knotenpunkten des in punkte definierten
59 | Elements hat. Abhaengig von dimensionen wird eine Flaeche (2D) oder ein Volumen (3D) als Referenz
60 | betrachtet. Gibt gewichtung zurueck.
61 |  
62 | WICHTIG: punkte muss unabhaengig von dimensionen drei Koordinaten fuer jeden Punkt enthalten.
63 |
PartVolumen(part)
Bestimme das Volumen (3D) bzw. die Flaeche (2D) eines gemeshten part. Gibt das Volumen zurueck.
64 |  
65 | Wichtig: Alle Elemente des parts muessen den gleichen Elementyp haben.
66 |
PunktInElement(elemente, knoten, referenzpunkt, listenhilfe=[], elementinfoliste=[])
Gebe den Label des Elements aus elemente zurueck, das referenzpunkt enthaelt. Die
67 | Koordinaten der elemente muessen in knoten definiert sein. Die optionale Uebergabe einer
68 | Zuordnung listenhilfe von Labels zu Indizes beschleunigt den Vorgang. Falls eine elementinfoliste
69 | mit den Volumina und Punktkoordinaten aller Elemente verfuegbar ist, kann ebenfalls eine kleine
70 | Beschleunigung erzielt werden. Gibt zielElement zurueck.
71 |  
72 | WICHTIG: Wenn Elemente einer mdb statt einer odb untersucht werden sollen, sollte entweder keine
73 |          oder die folgende listenhilfe uebergeben werden:
74 |  
75 | listenhilfe = [idx for idx in range(len(knoten))];
76 |
PunktkoordinatenVonElement(element, knoten, listenhilfe)
Bestimme eine Liste mit den Punktkoordinaten, die die Ecken von element sind. Dazu werden alle
77 | knoten mit den Koordinaten der Punkte und eine listenhilfe zur Zuordnung von Labels und Indizes
78 | benoetigt. Gibt die Koordinaten aller Punkte von element zurueck.
79 |
80 | -------------------------------------------------------------------------------- /abapys/bodendatenbank.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | bodendatenbank.py v1.0 (2020-09) 4 | """ 5 | 6 | # Copyright 2020-2021 Dominik Zobel. 7 | # All rights reserved. 8 | # 9 | # This file is part of the abapys library. 10 | # abapys is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # abapys is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with abapys. If not, see . 22 | 23 | 24 | # ------------------------------------------------------------------------------------------------- 25 | def _Name_Aktuellste_Materialdatenbank(): 26 | import os 27 | from hilfen import Log, _PfadZusatzdateien 28 | # 29 | dateien = os.listdir(_PfadZusatzdateien()); 30 | kandidaten = []; 31 | for datei in dateien: 32 | if (datei.startswith('Materialdatenbank')): 33 | kandidaten += [datei]; 34 | # 35 | kandidaten.sort(); 36 | if (len(kandidaten) == 0): 37 | Log('# Fehler: Konnte keine Materialdatenbank finden'); 38 | return None; 39 | else: 40 | return os.path.join(_PfadZusatzdateien(), kandidaten[-1]); 41 | # 42 | 43 | 44 | # ------------------------------------------------------------------------------------------------- 45 | def _Bodenparameter_Aus_Tabelle(name, bezeichnung='labor'): 46 | """Lade fuer den Boden name die Bodenparameter nach dem stoffgesetz aus der hinterlegten Datei 47 | "Materialdatenbank.xlsx". Gibt [eintragVorhanden, bodenwerte, standardwerte] zurueck. 48 | """ 49 | from hilfen import Log 50 | dateiname = _Name_Aktuellste_Materialdatenbank(); 51 | if (dateiname is None): 52 | return [[], [], []]; 53 | # 54 | try: 55 | from openpyxl import load_workbook 56 | except: 57 | Log('# Fehler: openpyxl (und Abhaengigkeiten) zum Laden von xlsx-Dateien nicht gefunden'); 58 | return [[], [], []]; 59 | # 60 | try: 61 | xlsxfile = load_workbook(filename=dateiname, read_only=True); 62 | except: 63 | Log('# Fehler: Konnte Materialdatenbank ' + dateiname + ' nicht laden'); 64 | return [[], [], []]; 65 | # 66 | xlsxsheet = xlsxfile['Materialdatenbank']; 67 | eintragVorhanden = False; 68 | # 69 | anzahlZellen = 39; 70 | standardwerte = anzahlZellen * ['']; 71 | bodenwerte = anzahlZellen * ['']; 72 | for zeile in xlsxsheet.rows: 73 | zeile_bodenname = zeile[0].value; 74 | if (zeile_bodenname is None): 75 | continue; 76 | # 77 | if (zeile_bodenname == 'Standardparameter'): 78 | for iZelle in range(anzahlZellen): 79 | standardwerte[iZelle] = zeile[iZelle].value; 80 | # 81 | if (str(zeile_bodenname) == name): 82 | eintragVorhanden = True; 83 | for iZelle in range(anzahlZellen): 84 | bodenwerte[iZelle] = zeile[iZelle].value; 85 | # 86 | break; 87 | # 88 | return [eintragVorhanden, bodenwerte, standardwerte]; 89 | # 90 | 91 | 92 | # ------------------------------------------------------------------------------------------------- 93 | def Bodenparameter(name, stoffgesetz, bezeichnung='labor'): 94 | """Lade fuer den Boden name die Bodenparameter nach dem stoffgesetz. Die in der dazugehoerigen 95 | Materialdatenbank gespeicherten Eintraege koennen mithilfe ihres Namens - und optional bei 96 | mehreren gleichnamigen Eintraegen mit einer zusaetzlichen bezeichnung - geladen werden. 97 | Gibt die dazugehoerigen bodenparameter zurueck. 98 | """ 99 | from hilfen import grad2rad, Log 100 | # 101 | parameter = None; 102 | eintragVorhanden, bodenwerte, standardwerte = _Bodenparameter_Aus_Tabelle(name, bezeichnung=bezeichnung); 103 | if (eintragVorhanden == []): 104 | return None; 105 | # 106 | if (not eintragVorhanden): 107 | Log('# Warnung: Keine Parameter fuer Eintrag >' + name + '< in der Materialdatenbank gefunden'); 108 | return None; 109 | # Alle fehlenden Eintraege des Datensatzes durch Standardwerte ersetzen 110 | for iWert, kennwert in enumerate(bodenwerte): 111 | if (kennwert is None): 112 | bodenwerte[iWert] = standardwerte[iWert]; 113 | # 114 | idx_basis = 3; 115 | idx_hypo = 9; 116 | idx_visco = 17; 117 | idx_erw = 25; 118 | idx_mc = 31; 119 | # 120 | stoffgesetz_klein = stoffgesetz.lower(); 121 | basisparameter = bodenwerte[idx_basis:idx_basis+3] + [grad2rad*bodenwerte[idx_basis+3]]; 122 | if ((stoffgesetz_klein == 'elastisch') or (stoffgesetz_klein == 'elastic')): 123 | parameter = basisparameter + bodenwerte[idx_mc:idx_mc+2]; 124 | # 0: Korndichte 4: E-Modul 125 | # 1: min. Dichte 5: Querdehnzahl 126 | # 2: max. Dichte 127 | # 3: krit.Reibwinkel 128 | # 129 | elif (stoffgesetz_klein == 'mohr-coulomb'): 130 | parameter = basisparameter + bodenwerte[idx_mc:idx_mc+2] + [bodenwerte[idx_basis+3]] + bodenwerte[idx_mc+2:idx_mc+5]; 131 | # 0: Korndichte 4: E-Modul 6: Reibungswert 7: Dilatanzwinkel 132 | # 1: min. Dichte 5: Querdehnzahl 8: Koh.-Fliessspg. 133 | # 2: max. Dichte 9: Plast.Dehnung 134 | # 3: krit.Reibwinkel 135 | # 136 | elif (('viskohypoplasti' in stoffgesetz_klein) or ('viscohypoplasti' in stoffgesetz_klein)): 137 | # 0: Korndichte 4: 100-Porenzahl 5: Querdehnzahl 6: Kompr-Beiwert 10: Ref.-Dehnung 138 | # 1: min. Dichte 7: Schwellbeiwert 139 | # 2: max. Dichte 8: Belast.-Flaeche 140 | # 3: krit.Reibwinkel 9: I_v 141 | parameter = basisparameter + [bodenwerte[idx_visco]] + [bodenwerte[idx_mc+1]] + bodenwerte[idx_visco+1:idx_visco+5] + [0.000001*bodenwerte[idx_visco+5]] + \ 142 | [0.0] + bodenwerte[idx_erw:idx_erw+2] + [0.000001*bodenwerte[idx_erw+2]] + bodenwerte[idx_erw+3:idx_erw+5] + [bodenwerte[idx_visco+6]]; 143 | # 11: [leer] 12: Faktor m_T 14: Konstante R_max 15: Exponent alpha 16: Ueberkons-grad 144 | # 13: Faktor m_R 16: Exponent beta 145 | # 146 | elif ('hypoplasti' in stoffgesetz_klein): 147 | # 0: Korndichte 4: Querdehnzahl 5: Granulathaerte 6: Exponent n 148 | # 1: min. Dichte 7: dicht.Porenzahl 149 | # 2: max. Dichte 8: lock.Porenzahl 150 | # 3: krit.Reibwinkel 9: krit.Porenzahl 151 | # 10: Exponent alpha 152 | # 11: Exponent beta 153 | parameter = basisparameter + [bodenwerte[idx_mc+1]] + [1000*bodenwerte[idx_hypo]] + bodenwerte[idx_hypo+1:idx_hypo+7] + \ 154 | bodenwerte[idx_erw:idx_erw+2] + [0.000001*bodenwerte[idx_erw+2]] + bodenwerte[idx_erw+3:idx_erw+5]; 155 | # 12: Faktor m_T 14: Konstante R_max 15: Exponent beta_R 156 | # 13: Faktor m_R 16: Exponent chi 157 | # 158 | else: 159 | parameter = None; 160 | Log('# Warnung: Kein passenden Satz an Bodenparametern fuer Stoffgesetz >' + stoffgesetz + '< gefunden'); 161 | return None; 162 | # 163 | # Falls Standardwerte fuer erweiterte hypoplastische Parameter verwendet oder alle ignoriert 164 | # werden sollen 165 | if ('stdig' in stoffgesetz_klein): 166 | # "Standardwerte" der erweiterten hypoplastischen Parameter 167 | # 168 | # Faktor Faktor Konstante Exponent Exponent 169 | # m_T [-] m_R [-] R_max [-] beta_R [-] chi [-] 170 | # |---------|---------|-----------|------------|----------| 171 | parameter[12:17] = [ 2.0, 5.0, 1e-4, 0.5, 5.0 ]; 172 | # 173 | if ('ohneig' in stoffgesetz_klein): 174 | # "Deaktivierung" der erweiterten hypoplastischen Parameter durch m_T und m_R < 2.0 175 | # 176 | # Faktor Faktor Konstante Exponent Exponent 177 | # m_T [-] m_R [-] R_max [-] beta_R [-] chi [-] 178 | # |---------|---------|-----------|------------|----------| 179 | parameter[12:17] = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; 180 | # 181 | return parameter; 182 | # 183 | -------------------------------------------------------------------------------- /abapys/beautify.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | beatify.py v0.65 (2020-11) 4 | """ 5 | 6 | # Copyright 2020-2021 Dominik Zobel. 7 | # All rights reserved. 8 | # 9 | # This file is part of the abapys library. 10 | # abapys is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # abapys is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with abapys. If not, see . 22 | 23 | 24 | # ------------------------------------------------------------------------------------------------- 25 | def ViewportVerschoenern(session, neuerHintergrund=True, saubererViewport=True, saubereLegende=True, 26 | evfSchnitt=False, minimaleKanten=True, farbspektrum='Viridis', diskreteFarben=True, 27 | ausgabeVerschmieren=True, zeigeMarkierungen=True, exportiereHintergrund=False, 28 | Standardansicht=False): 29 | """Wende die in dieser Funktion gespeicherten Standardwerte fuer die Ansicht des aktiven 30 | Viewports der session an. Optional koennen verschiedene Effekte aktiviert oder deaktiviert 31 | werden. Fuer farbspektrum sind die folgenden Spektren definiert: abpViridis, abpCubeHelix, 32 | abpRainbow und abpMoreland sowie deren Inverse (abpViridisINV, abpCubeHelixINV, abpRainbowINV und 33 | abpMorelandINV). Gibt einen Verweis auf den viewport zurueck. 34 | """ 35 | # Basiert hauptsaechlich auf dem Abaqus Scripting Reference Guide (Abschnittstitel und -nummern 36 | # aus der Version 6.14 sowie 37 | # http://ifcuriousthenlearn.com/blog/2015/04/02/Abaqus-FEA-Scripting-with-python/ 38 | # http://desicos.github.io/desicos/_modules/desicos/abaqus/abaqus_functions.html 39 | # 40 | import visualization 41 | from abaqusConstants import FIXED, TRUE, FALSE, ON, OFF, FEATURE, SPECIFY, CONTINUOUS 42 | from abaqusConstants import PARALLEL, MODEL, ABSOLUTE 43 | from hilfen import Log 44 | # 45 | myviewport = session.viewports[session.currentViewportName]; 46 | # 47 | if ((not isinstance(neuerHintergrund, bool)) or (not isinstance(saubererViewport, bool)) or 48 | (not isinstance(saubereLegende, bool)) or(not isinstance(evfSchnitt, bool)) or 49 | (not isinstance(minimaleKanten, bool)) or(not isinstance(diskreteFarben, bool)) or 50 | (not isinstance(ausgabeVerschmieren, bool)) or(not isinstance(zeigeMarkierungen, bool)) or 51 | (not isinstance(exportiereHintergrund, bool)) or(not isinstance(Standardansicht, bool))): 52 | Log('# Abbruch: Alle Argumente ausser session und farbspektrum muessen True/False sein'); 53 | return myviewport; 54 | # 55 | # 56 | ######################################### 57 | # --- GraphicsOptions object (17.9) --- # 58 | ######################################### 59 | # 60 | mygraphicoptions = session.graphicsOptions; 61 | # 62 | if (neuerHintergrund): 63 | # Gradient: 40% der Hoehe -> 85% des Farbwechsels von der unteren zur oberen Farbe 64 | mygraphicoptions.setValues(backgroundColor='#FFFFFF'); 65 | mygraphicoptions.setValues(backgroundBottomColor='#AABBDD'); 66 | # 67 | # 68 | # 69 | # 70 | ##################################################### 71 | # --- ViewportAnnotationsOptions object (17.19) --- # 72 | ##################################################### 73 | # 74 | myannotationoptions = myviewport.viewportAnnotationOptions; 75 | # 76 | # Alle Hilfselemente im Viewport entfernen 77 | if (saubererViewport): 78 | myannotationoptions.setValues(compass=0, triad=0, state=0, title=0); 79 | # 80 | # Anzeige der Legende anpassen 81 | if (saubereLegende): 82 | myannotationoptions.setValues(legendBox=0); 83 | myannotationoptions.setValues(legendNumberFormat=FIXED, legendDecimalPlaces=2); 84 | myannotationoptions.setValues(legendFont='-*-arial-bold-r-normal-*-*-120-*-*-p-*-*-*'); 85 | # 86 | # 87 | # 88 | #################################### 89 | # --- OdbDisplay object (35.1) --- # 90 | #################################### 91 | # 92 | myodbdisplay = myviewport.odbDisplay; 93 | # 94 | # Bei CEL-Modellen den viewCut an leeren Euler-Elementen aktivieren 95 | if (evfSchnitt): 96 | myodbdisplay.setValues(viewCutNames=('EVF_VOID', ), viewCut=TRUE); 97 | # 98 | # 99 | # 100 | ######################################## 101 | # --- CommonOptions object (35.2) --- # 102 | ######################################## 103 | # 104 | mycommonoptions = myviewport.odbDisplay.commonOptions; 105 | # 106 | # Sichtbarkeit der Netzkanten anpassen 107 | if (minimaleKanten): 108 | mycommonoptions.setValues(visibleEdges=FEATURE); 109 | # 110 | # 111 | # 112 | ######################################## 113 | # --- ContourOptions object (35.3) --- # 114 | ######################################## 115 | # 116 | mycontouroptions = myviewport.odbDisplay.contourOptions; 117 | # 118 | # Manuelle Farbwahl fuer Werte ausserhalb der vorgegebenen Grenzen 119 | mycontouroptions.setValues(outsideLimitsMode=SPECIFY); 120 | mycontouroptions.setValues(outsideLimitsAboveColor='#EEEEEE', outsideLimitsBelowColor='#111111'); 121 | # 122 | # Zulaessige Farbspektren 123 | if ((farbspektrum == 'CubeHelix') or (farbspektrum == 'CubeHelixINV') or 124 | (farbspektrum == 'Moreland') or (farbspektrum == 'MorelandINV') or 125 | (farbspektrum == 'UniformRainbow') or (farbspektrum == 'UniformRainbowINV') or 126 | (farbspektrum == 'Viridis') or (farbspektrum == 'ViridisINV')): 127 | # 128 | mycontouroptions.setValues(spectrum=farbspektrum); 129 | else: 130 | Log('# Warnung: farbspektrum unbekannt - wird ignoriert'); 131 | # 132 | if (not diskreteFarben): 133 | mycontouroptions.setValues(contourStyle=CONTINUOUS); 134 | else: 135 | mycontouroptions.setValues(numIntervals=10); 136 | # 137 | # 138 | # 139 | ################################## 140 | # --- Spectrum object (39.8) --- # 141 | ################################## 142 | # 143 | # Spektren aus einer Reihe an Farben definieren (linear interpoliert) 144 | # CubeHelix (http://www.mrao.cam.ac.uk/~dag/CUBEHELIX/) 145 | # - Helligkeitswerte: [0.1 0.75] 146 | # - Anfangswert Rotation: 0.5 147 | # - Anzahl/Richtung Rotationen: -1.3 148 | # - Farbwert: 1.3 149 | # - Gammakorrektur: 0.8 150 | session.Spectrum('CubeHelix', 151 | ['#2C2145', '#2B446D', '#226D74', '#2C905F', '#56A244', '#96A242', '#D59B66', '#F99CA4', '#FDADE1']); 152 | # UniformRainbow (https://peterkovesi.com/projects/colourmaps/index.html rainbow_bgyr_35-85_c72_n256) 153 | session.Spectrum('UniformRainbow', 154 | ['#0034F9', '#2A7F82', '#55A915', '#B9C11C', '#FDBC20', '#FE8212', '#FD482B']); 155 | # Moreland (https://www.kennethmoreland.com/color-maps/) 156 | session.Spectrum('Moreland', 157 | ['#3B4CC0', '#6282EA', '#8DB0FE', '#B8D0F9', '#DDDDDD', '#F5C4AD', '#F49A7B', '#DE604D', '#B40426']); 158 | # Viridis (https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html) 159 | session.Spectrum('Viridis', 160 | ['#440154', '#472D7B', '#3B528B', '#2C728E', '#21918C', '#28AE80', '#5EC962', '#ADDC30', '#FDE725']); 161 | # 162 | # Die invertierten Spektren 163 | session.Spectrum('CubeHelixINV', 164 | ['#FDADE1', '#F99CA4', '#D59B66', '#96A242', '#56A244', '#2C905F', '#226D74', '#2B446D', '#2C2145']); 165 | # 166 | session.Spectrum('UniformRainbowINV', 167 | ['#FD482B', '#FE8212', '#FDBC20', '#B9C11C', '#55A915', '#2A7F82', '#0034F9']); 168 | # 169 | session.Spectrum('MorelandINV', 170 | ['#B4426', '#DE604D', '#F49A7B', '#F5C4AD', '#DDDDDD', '#B8D0F9', '#8DB0FE', '#6282EA', '#3B4CC0']); 171 | # 172 | session.Spectrum('ViridisINV', 173 | ['#FDE725', '#ADDC30', '#5EC962', '#28AE80', '#21918C', '#2C728E', '#3B528B', '#472D7B', '#440154']); 174 | # 175 | # 176 | # 177 | ###################################### 178 | # --- BasicOptions object (40.1) --- # 179 | ###################################### 180 | # 181 | mybasicoptions = myviewport.odbDisplay.basicOptions; 182 | # 183 | # Mitteln der Ergebnisse deaktivieren 184 | if (not ausgabeVerschmieren): 185 | mybasicoptions.setValues(averageElementOutput=OFF); 186 | # 187 | # Winkel der Feature-Kanten anpassen 188 | mybasicoptions.setValues(featureAngle=60); 189 | # 190 | # Sichtbarkeit der Punktelemente 191 | if (not zeigeMarkierungen): 192 | mybasicoptions.setValues(pointElements=OFF); 193 | # 194 | # 195 | # 196 | ###################################### 197 | # --- PrintOptions object (43.1) --- # 198 | ###################################### 199 | # 200 | myprintoptions = session.printOptions; 201 | # 202 | # Viewportdekoration abschalten 203 | myprintoptions.setValues(vpDecorations=OFF); 204 | # 205 | # Viewporthintergrund aktivieren 206 | if (exportiereHintergrund): 207 | myprintoptions.setValues(vpBackground=ON); 208 | # 209 | # Farbreduktion fuer png-Bilder deaktivieren 210 | myprintoptions.setValues(reduceColors=False); 211 | # 212 | # 213 | # 214 | ############################## 215 | # --- View object (54.1) --- # 216 | ############################## 217 | # 218 | myviewoptions = myviewport.view; 219 | # 220 | # Viewportansicht auf eine Standardsicht anpassen 221 | if (Standardansicht): 222 | myviewoptions.setValues(projection=PARALLEL); 223 | myviewoptions.setValues(session.views['Bottom']); 224 | # 225 | myviewoptions.rotate(xAngle=0, yAngle=0, zAngle=90, mode=MODEL); 226 | myviewoptions.rotate(xAngle=0, yAngle=-30, zAngle=0, mode=MODEL); 227 | myviewoptions.zoom(zoomFactor=0.95, mode=ABSOLUTE); 228 | myviewoptions.pan(xFraction=0.12, yFraction=-0.04); 229 | # 230 | return myviewport; 231 | # 232 | -------------------------------------------------------------------------------- /docs/abapys.auswahl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.auswahl 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.auswahl
13 |

auswahl.py   v0.3 (2020-09)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Functions
       
BedingteAuswahl(elemente, bedingung='True', var=[])
Erstelle eine Sequenz aller uebergebenen elemente, die bedingung erfuellen. Alle Variablen aus
22 | bedingung muessen global lesbar oder optional in var uebergeben und als var[...] bezeichnet sein,
23 | sonst kann die bedingung nicht korrekt ausgewertet werden. Gibt die Sequenz der ausgewaehlten
24 | Elemente zurueck.
25 |  
26 | In der Bedingung kann mit elem auf ein einzelnes Element zugegriffen werden. Auf die
27 | Basiskoordinaten eines Elementes kann mit elem.pointOn[0][#] zugegriffen werden, wobei die Raute
28 | fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht.
29 |  
30 | Fuer mathematische Zusammenhaenge stehen die Funktionen pi, sqrt, sin, cos, tan, asin, acos, atan
31 | zur Verfuegung.
32 |
ElementAuswahl(elemente, punktliste, bedingung='True', var=[], listenhilfe=[])
Gib eine Sequenz an Elementen aus den uebergebenen elemente zurueck, die bzw. deren Punkte die
33 | bedingung erfuellen. Fuer die Zuordnung der einzelnen Punkte zu den Elementen muss eine
34 | punktliste uebergeben werden, die alle Punkte aller elemente enthaelt.
35 | Gibt die Sequenz der ausgewaehlten Elemente zurueck.
36 |  
37 | In der Bedingung kann mit elem auf ein einzelnes Element und mit punkt auf einen Punkt des
38 | Elements zugegriffen werden. Die Koordinaten eines Punktes koennen mit punkt.coordinates[#]
39 | erhalten werden, wobei die Raute fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht.
40 |  
41 | Optional kann die korrekte Zuordnung der Labels der Punkte bei odb-elementen durch Uebergabe
42 | einer listenhilfe beschleunigt werden.
43 |  
44 | Fuer mathematische Zusammenhaenge stehen die Funktionen pi, sqrt, sin, cos, tan, asin, acos, atan
45 | zur Verfuegung.
46 |  
47 | WICHTIG: Wenn Elemente einer mdb statt einer odb untersucht werden sollen, sollte entweder keine
48 |          oder die folgende listenhilfe uebergeben werden:
49 |  
50 | listenhilfe = [idx for idx in range(len(punktliste))];
51 |
ElementAuswahlLabelliste(elemente, punktliste, sortierung=0, aufsteigend=True, listenhilfe=[])
Sortiert alle uebergebenen elemente nach der Koordinatenrichtung sortierung basierend auf den
52 | Koordinaten des Elementmittelpunktes. Fuer die Berechnung der Mittelpunktkoordinaten werden die
53 | Knoten der Elemente benutzt. Fuer die Zuordnung der einzelnen Punkte zu den Elementen muss eine
54 | punktliste uebergeben werden, die alle Punkte aller elemente enthaelt. Gibt eine Liste der Labels
55 | aller uebergebenen elemente zurueck, deren Mittelpunkte nach der Koordinatenrichtung sortierung
56 | sortiert ist.
57 |  
58 | Fuer die sortierung ist die jeweilige Richtung (0, 1 oder 2) anzugeben. Die Reihenfolge wird
59 | ueber die Koordinaten der Mittelpunkte der Elemente bestimmt. Die Werte koennen entweder
60 | aufsteigend oder absteigend sortiert werden.
61 |  
62 | Optional kann die korrekte Zuordnung der Labels der Punkte bei odb-elementen durch Uebergabe
63 | einer listenhilfe beschleunigt werden.
64 |  
65 | WICHTIG: Wenn Elemente einer mdb statt einer odb untersucht werden sollen, sollte entweder keine
66 |          oder die folgende listenhilfe uebergeben werden:
67 |  
68 | listenhilfe = [idx for idx in range(len(punktliste))];
69 |
KnotenAuswahlLabelliste(knoten, sortierung=0, aufsteigend=True)
Sortiert alle uebergebenen knoten nach der Koordinatenrichtung sortierung basierend auf den
70 | jeweiligen Koordinaten.
71 |  
72 | Fuer die sortierung ist die jeweilige Richtung (0, 1 oder 2) anzugeben. Die Reihenfolge wird
73 | ueber die Koordinaten der Mittelpunkte der Elemente bestimmt. Die Werte koennen entweder
74 | aufsteigend oder absteigend sortiert werden.
75 |
LabelAuswahl(elemente, labelliste, elementhilfsliste=[])
Erstelle eine Sequenz aller uebergebener elemente, deren Label sich in labelliste befindet.
76 | Optional kann eine elementhilfsliste vorab erzeugt und uebergeben werden, was vorallem bei
77 | mehrmaligen Aufrufen einer LabelAuswahl fuer gleiche elemente deutlich schneller ist.
78 | Falls keine elementhilfsliste uebergeben worden ist, wird (jedes mal) intern eine erstellt.
79 | Gibt die Sequenz der ausgewaehlten Elemente zurueck.
80 |
ZweifachbedingteKantenAuswahl(elemente, bedingung1='True', bedingung2='True', bedingung3='True', var=[])
Erstelle eine Sequenz aller Kanten aus elemente, die bedingung1 und bedingung2 erfuellen.
81 | Die Rueckgabe der Kanten ist sortiert nach bedingung3. Alle Variablen aus bedingung1, bedingung2
82 | und bedingung3 muessen global lesbar oder optional in var uebergeben und als var[...] bezeichnet
83 | sein, sonst koennen die Bedingungen nicht korrekt ausgewertet werden.
84 |  
85 | In der ersten Bedingung kann mit edge auf eine einzelne Kante zugegriffen werden (bspw.
86 | edge.pointOn[0][#], wobei die Raute fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen
87 | steht). In der zweiten und dritten Bedingung kann zusaetzlich auch auf die beiden Endpunkte vert1
88 | sowie vert2 zugegriffen werden (ebenfalls vert.pointOn[0][#] mit Raute als 0, 1 oder 2).
89 |  
90 | Die ersten beiden Bedingungen sind zur Auswahl der der Kanten. Kanten die eine der ersten beiden
91 | Bedingungen nicht erfuellen, werden ignoriert. Die restlichen Kanten werden sortiert, abhaengig
92 | davon, ob sie die letzte Bedingung erfuellen oder nicht. Gibt eine Liste mit zwei Sequenzen der
93 | ausgewaehlten Kanten [kanten_bedingung3_True, kanten_bedingung3_False] zurueck.
94 |  
95 | Fuer mathematische Zusammenhaenge stehen die Funktionen sqrt, sin, cos, tan, asin, acos, atan
96 | zur Verfuegung.
97 |
98 | -------------------------------------------------------------------------------- /docs/abapys.grundkoerper.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.grundkoerper 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.grundkoerper
13 |

grundkoerper.py   v1.3 (2020-02)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Functions
       
Grundkoerper_sets(modell, name)
Erstelle die Hauptsets fuer das Bauteil (Part) name im modell.
22 |
Grundkoerper_standardpartitionen(modell, name, xPartition=True, yPartition=True, zPartition=True, rp=False)
Erstelle die typischen Datums und Partitionen am Bauteil (Part) name im modell. Optional kann
23 | die Erstellung einzelner Partitionen mit (x-/y-/z-Partition) unterdrueckt werden. Wenn rp=True
24 | uebergeben wird, wird zusaetzlich einen Referenzpunkt im Ursprung erstellt.
25 |
Grundkoerper_vernetzen(modell, name, materialtyp, gittergroesse)
Erzeuge ein Standardnetz fuer das Bauteil (Part) name im modell. materialtyp wird fuer die
26 | Zuweisung der korrekten Elemente benoetigt (Abaqus-Konstante, bspw. DEFORMABLE_BODY). Das Mesh
27 | kann ueber gittergroesse (Zahlenwert, [gitter_r, gitter_h] oder [gitter_x, gitter_y, gitter_z])
28 | angepasst werden.
29 |
Kugel(modell, name, radius, materialtyp, gittergroesse, rp=False, extrasets=False, r_innen=[])
Erzeuge eine Kugel name im modell mit dem uebergebenem radius vom Typ materialtyp
30 | (Abaqus-Konstante, bspw. DEFORMABLE_BODY) und der Netzgroesse gittergroesse (Zahlenwert).
31 | Optional kann ein Referenzpunkt rp oder extrasets erstellt werden. Optional kann ausserdem statt
32 | einer Vollkugel eine Hohlkugel erzeugt werden, wenn r_innen gegeben ist.
33 | Gibt [part<name>, inst<name>] zurueck.
34 |
Kugel_erstellen(modell, name, radius, materialtyp, r_innen=[])
Erzeuge eine Kugel (Part) name im Modell modell mit uebergebenem radius und vom Typ
35 | materialtyp (Abaqus-Konstante, bspw. DEFORMABLE_BODY). Erzeuge eine Hohlkugel, falls r_innen
36 | gegeben ist.
37 |
Quader(modell, name, laenge, breite, hoehe, materialtyp, gittergroesse, rp=False, extrasets=False, xypartition=[True, True], viertel=4)
Erzeuge einen Quader name im modell mit den Abmessungen laenge, breite und hoehe vom Typ
38 | materialtyp (Abaqus-Konstante, bspw. DEFORMABLE_BODY) und der Netzgroesse gittergroesse
39 | (Zahlenwert oder [gitter_x, gitter_y, gitter_z]). laenge und breite koennen entweder als
40 | Zahlenwert für eine symmetrische Anordnung um den Ursprung (wird transformiert zu
41 | [-zahl/2.0, zahl/2.0]) oder direkt als (startpunkt, endpunkt) uebergeben werden. Optional kann
42 | ein Referenzpunkt rp oder extrasets erstellt werden. Wenn gewuenscht, kann mit xypartition die
43 | Erzeugung der Standardpartitionen in x- oder y-Richtung unterdrueckt werden.
44 |  
45 | Neben einem Quader mit den Werten in laenge und breite kann ueber viertel auch ein (Teil-)Quader
46 | erzeugt werden (nur die Werte 1, 2 und 4 werden unterstuetzt). In dem Fall werden Partitionen in
47 | der Schnittebene nicht erzeugt (unabhaengig von den Angaben in xypartition).
48 | Gibt [part<name>, inst<name>] zurueck.
49 |
Quader_erstellen(modell, name, laenge, breite, hoehe, materialtyp)
Erzeuge ein quaderfoermiges Bauteil (Part) name im modell mit den Abmessungen laenge, breite
50 | und hoehe vom Typ materialtyp (Abaqus-Konstante, bspw. DEFORMABLE_BODY).
51 |
Quader_flaechensets(modell, name, laenge, breite, hoehe)
Erzeuge Flaechensets an der Oberseite, Unterseite und allen Seiten des Quaderbauteils (Part)
52 | name im modell. Zur richtigen Zuordnung werden die Abmessungen laenge, breite und hoehe des
53 | Quaders benoetigt. laenge und breite koennen entweder als Zahlenwert für eine symmetrische
54 | Anordnung um den Ursprung (-zahl/2.0, zahl/2.0) oder direkt als (startpunkt, endpunkt) uebergeben
55 | werden. Die hoehe wird als Zahlenwert erwartet und immer von Null an gestartet.
56 |
Rotationsprofil_erstellen(modell, name, punkte, materialtyp, viertel=4)
Erzeuge durch eine Drehung um viertel*90 Grad ein Bauteil (Part) name im modell aus den
57 | Koordinaten aus punkte vom Typ materialtyp (Abaqus-Konstante, bspw. DEFORMABLE_BODY). Die in
58 | punke uebergebenen Tupel an x- und y-Koordinaten bilden eine Linie, wobei der letzte Punkt
59 | automatisch mit dem ersten verbunden wird. Fuer die Drehung (um die y-Achse der Zeichnung)
60 | muessen alle x-Koordinaten der Punkte >= 0 sein.
61 | Fuer viertel werden nur die Werte 1,2 und 4 unterstuetzt.
62 |
Zylinder(modell, name, radius, hoehe, materialtyp, gittergroesse, rp=False, extrasets=False, r_innen=[], xypartition=[True, True], viertel=4)
Erzeuge einen Zylinder name im modell mit den Abmessungen radius und hoehe vom Typ materialtyp
63 | (Abaqus-Konstante, bspw. DEFORMABLE_BODY) und der Netzgroesse gittergroesse (Zahlenwert oder
64 | [gitter_r, gitter_h]). Optional kann ein Referenzpunkt rp oder extrasets erstellt werden.
65 | Optional kann ausserdem statt einem Zylinder ein Zylinderring erzeugt werden, wenn r_innen
66 | gegeben ist.
67 |  
68 | Neben einem Zylinder(ring) kann auch nur ein Viertel- oder Halbzylinder(ring) ueber viertel
69 | erzeugt werden (nur die Werte 1, 2 und 4 werden unterstuetzt). Falls nur ein halber/viertel
70 | Zylinder erzeugt wird, werden Partitionen in der Schnittebene nicht erzeugt (unabhaengig von den
71 | Angaben in xypartition). Gibt [part<name>, inst<name>] zurueck.
72 |
Zylinder_erstellen(modell, name, radius, hoehe, materialtyp, r_innen=[], viertel=4)
Erzeuge ein zylindrisches Bauteil (Part) name im modell mit den Abmessungen radius und hoehe
73 | vom Typ materialtyp (Abaqus-Konstante, bspw. DEFORMABLE_BODY). Falls r_innen gegeben ist, wird
74 | statt einem Zylinder ein Zylinderring mit dem Aussparungsradius r_innen erzeugt.
75 |  
76 | Neben einem Zylinder(ring) kann auch nur ein Viertel- oder Halbzylinder(ring) ueber viertel
77 | erzeugt werden. Fuer viertel werden nur die Werte 1,2 und 4 unterstuetzt.
78 |
Zylinder_flaechensets(modell, name, radius, hoehe, r_innen=[], viertel=4)
Erzeuge Flaechensets an der Oberseite, Unterseite und Mantel des Zylinderbauteils (Part) name
79 | im modell. Zur richtigen Zuordnung werden radius und hoehe des Zylinders benoetigt. Falls nur ein
80 | Viertel-/Halbzylinder erzeugt werden soll, werden zusaetzliche Sets erstellt.
81 |
82 | -------------------------------------------------------------------------------- /docs/abapys.uebertragung.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.uebertragung 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.uebertragung
13 |

uebertragung.py   v0.6 (2021-01)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Classes
       
22 |
__builtin__.object 23 |
24 |
25 |
FieldOutputValue 26 |
27 |
28 |
29 |

30 | 31 | 32 | 34 | 35 | 36 | 37 | 38 |
 
33 | class FieldOutputValue(__builtin__.object)
   Mini-Klasse zur Erstellung von FieldOutputValues.
 
 Methods defined here:
39 |
__init__(self, precision, data=None, dataDouble=None, type=None, elementLabel=None, nodeLabel=None)
40 | 41 |
__repr__(self)
42 | 43 |
44 | Data descriptors defined here:
45 |
__dict__
46 |
dictionary for instance variables (if defined)
47 |
48 |
__weakref__
49 |
list of weak references to the object (if defined)
50 |
51 |

52 | 53 | 54 | 56 | 57 | 58 |
 
55 | Functions
       
KonstanteAnfangsloesungFuerSet(modell, instname, setname, ausgabewerte)
Erstelle einen Initial Condition Solution Eintrag im Keyword Block des Modells namens mdbname.
59 | In diesem Block werden allen Elementen aus dem Set setname des Instanz instname die uebergebenen
60 | Werte ausgabewerte als Anfangsloesung zugewiesen. Im Keyword Block wird dazu ein Verweis auf eine
61 | Datei <mdbname>_sdv_init.add verwiesen, die angelegt und mit den Werten beschrieben wird.
62 |
ZielwertquaderEinlesen(dateiname, numKoordinaten, numVar, knotenwerte=False)
Liest aus einer csv-Datei namens dateiname alle Zeilen ein. In jeder Zeile werden
63 | numKoordinaten Eintraege als Koordinaten erwartet (d.h. 2 oder 3) und die restlichen Werte werden
64 | als Ergebnisse an diesen Koordinaten betrachtet. Mit 2 Koordinaten werden Elemente aus vier
65 | Knoten angenommen, mit 3 Koordinaten aus acht.
66 |  
67 | Falls knotenwerte=True werden die Koordinaten als Knotenkoordinaten und die Ergebnisse an den
68 | Knotenkoordinaten interpretiert. Andernfalls werden die Koordinaten als Elementpunkte betrachtet,
69 | um die mithilfe der Nachbarelementpunkte die Elementgrenzen (Knotenkoordinaten) bestimmt werden.
70 |  
71 | Erwartet jeweils die gleiche Anzahl an Werten fuer jeden Vektor einer Koordinatenrichtung, um
72 | daraus ohne weitere Informationen quaderfoermige Elemente zu generieren (fuer knotenweise=True).
73 | Fuer knotenweise=False sollte zusaetzlich jeweils ein konstanter Abstand zwischen den Werten pro
74 | Koordinatenrichtung vorliegen, da ansonsten die Ergebnisse nicht am tatsaechlichen Mittelpunkt
75 | definiert sind (aber so interpretiert werden).
76 |  
77 | Gibt [Koordinaten, Elemente, Ergebnisse] zurueck.
78 |
ZielwertquaderErstellen(dateiname, xwerte, ywerte, zwerte, ergebnisfunktion)
Erstelle eine Ausgabedatei namens dateiname mit Ausgabegroessen fuer alle uebergebenen Werte.
79 | Dabei werden xwerte, ywerte und zwerte Listen mit streng monoton zunehmende oder abnehmende
80 | Punktkoordinaten erwartet. Fuer jede Kombination von Koordinaten aus den drei Vektoren wird mit
81 | der uebergebenen ergebnisfunktion eine Ausgabe berechnet.
82 |  
83 | ergebnisfunktion kann eine beliebige Funktion sein, die jedoch ein Argument punktkoordinaten als
84 | Liste mit drei Eintraegen akzeptieren und eine Liste zurueckgeben muss
85 |  
86 | Jede Kombination von Punktkoordinaten und deren Rueckgabewerte von ergebnisfunktion werden in
87 | eine Zeile der Ausgabedatei geschrieben.
88 |
Zustandsuebertragung(session, odbname, odbinstname, variablenliste, modell, mdbinstname, mdbknoten=[], odbknoten=[], step=-1, frame=-1)
Uebertrage den Zustand aus einer odb namens odbname auf ein in der aktuellen session geladenes
89 | Modell modell. Dazu wird jeden in variablenliste uebergebene Variable an jedem Knoten bzw.
90 | Element (je nach Typ) der odbinstname aus dem angegebenen step und frame ausgelesen und als
91 | Anfangsloesungen von den Koordinaten der odbelemente oder odbknoten auf die Koordinaten der
92 | mdbknoten in der Assembly-Instanz namens mdbinstname übertragen. Da die Position der Knoten nicht
93 | uebereinstimmen muss, wird eine lineare Interpolation der Werte aus der odb-Datei auf die Knoten
94 | des neuen Modells vorgenommen.
95 |  
96 | Fuer eine Zustandsuebertragung auf ein gleichartiges Modell (gleiche Offsets und Geometrien) ist
97 | es nicht noetig, mdbknoten und odbknoten zusaetzlich zu uebergeben. Wenn die Geometrieen aber
98 | verschoben sind (anderes Nulloffset o.ae.), dann bietet sich eine Transformation der Koordinaten
99 | an (bspw. mit der Funktion Knotentransformation). Die aktualisierten mdbknoten oder/und odbknoten
100 | muessen dann entsprechend uebergeben werden.
101 |  
102 | Gibt [gewichtungKnotenLabels, gewichtungKnotenWerte, bezugsElemente] zurueck.
103 |  
104 | Es wird 2D -> 2D und 3D -> 3D unterstuetzt, aber nicht gemischt. Fuer 2D-Elemente sind Dreiecke
105 | und Vierecke zulaessig, fuer 3D-Elemente Tetraeder und Hexahedrons. Die Unterscheidung wird am
106 | Elementnamen getroffen: Alle Elemente mit 3D im Namen zaehlen zu den 3D-Elementen (bspw. C3D8R).
107 |    
108 | Wichtig: Alle Elemente des parts muessen den gleichen Elementyp haben.
109 |
Zustandszuweisung(session, modell, zielkoordinaten, zielelemente, zielwerte, mdbinstname, mdbknoten=[], variablentyp=['SDV'])
Weise die zielwerte an den zielkoordinaten bze. zielelemente einem in der aktuellen session
110 | geladenem Modell modell zu als Anfangsloesung fuer variablentyp SDV zu.
111 |  
112 | Dazu wird fuer die in variablentyp gelistete Variable an jedem Knoten bzw.
113 | Element (je nach Typ) mit den Koordinaten zielkoordinaten die Anfangsloesungen aus zielwerte auf
114 | die Koordinaten der mdbknoten in der Assembly-Instanz namens mdbinstname übertragen. Da die
115 | Position der Knoten nicht uebereinstimmen muss, wird eine lineare Interpolation der zielwerte auf
116 | die Knoten des neuen Modells vorgenommen.
117 |  
118 | Wenn variablentyp an Knoten definiert ist, wird zielkoordinaten als Knotenkoordinaten und
119 | zielwerte als Knotenwerte interpretiert und zugewiesen. Falls variablentyp an Elementen definiert
120 | ist, werden zielkoordinaten als Koordinaten der Elementmittelpunkte definiert und zielwerte als
121 | Elementwerte.
122 |  
123 | Fuer eine Zustandszuweisung ohne zusaetzliche Transformation der Positionen (bspw. Verschiebung
124 | oder Rotation), ist es nicht noetig, mdbknoten zusaetzlich zu uebergeben. Andernfalls bietet sich
125 | eine Transformation der Koordinaten an (bspw. mit der Funktion Knotentransformation). Die
126 | aktualisierten mdbknoten muessen dann entsprechend uebergeben werden.
127 |  
128 | Gibt [gewichtungKnotenLabels, gewichtungKnotenWerte, bezugsElemente] zurueck.
129 |  
130 | Wichtig: Alle Elemente des parts muessen den gleichen Elementyp haben.
131 |
132 | -------------------------------------------------------------------------------- /docs/abapys.boden.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.boden 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.boden
13 |

boden.py   v2.1 (2023-02)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Functions
       
Boden(modell, name, bodentiefe, voidhoehe, bodenbereich, gittergroessen, gitter_boden_vertikal, schichten, schichtmaterial, restmaterial, extrasets=False, netz=True, euler=True, xypartition=[True, True], partition_durchziehen=False, viertel=4, rotationsprofilpunkte=None)
Erzeuge einen Untergrund name im uebergebenen modell. Die folgende Skizze gibt einen
22 | Ueberblick ueber die verwendeten geometrischen Groessen und Bestandteile intern verwendeter
23 | Bezeichnungen (bspw. fuer Sets), wobei in der Darstellung alle bodenbereiche als rund angenommen
24 | werden. Gibt [part<name>, inst<name>] zurueck.
25 |  
26 |        bodenbereich[0]
27 |          ("Aussen")
28 |     _|________________|_
29 |      |                |
30 |      | bodenbereich[1:-1]
31 |      | ("Uebergaenge")|
32 |      | _|__________|_ |
33 |      |  |          |  |
34 |      .  .          .  .
35 |      .  .          .  .
36 |      | bodenbereich[-1]
37 |      |  | ("Innen")|  |
38 |      |  | _|____|_ |  |
39 |      |  |  |    |  |  |
40 |      |                |
41 |          ..------..
42 |        .. ..----.. .. 
43 |       /  /  .--.  \  \    
44 |      |  |  (    )  |  |   ___|_
45 |      |\ |\ |'--'| /| /|      |
46 |      | '+ '+----+' +' |      |
47 |      |  |''+----+''|  |      |
48 |      |  |  |    |  |  |      | voidhoehe (nur bei euler=True)
49 |      |  |..+----+..|  |      |
50 |      | .+ .+----+. +. |      |
51 |      |/ |/ |.--.| \| \|      |
52 |      |  |  (    )  |  |   ___|__________________|_
53 |      |\ |\ |'--'| /| /|      |                  |
54 |      | '+ '+----+' +' |      |                  |
55 |      |  |''+----+''|  |      |                  |
56 |      |  |  |    |  |  |      | schichten[-1]    |
57 |      |  |..+----+..|  |      | ("Schichten")    |
58 |      | .+ .+----+. +. |      |                  |
59 |      |/ |/ |.--.| \| \|      |                  |
60 |      |  |  (    )  |  |   ___|_                 | bodentiefe
61 |      |\ |\ |'--'| /| /|      |                  |
62 |      | '+ '+----+' +' |      |                  |
63 |      |  |''+----+''|  |      |                  |
64 |      |  |  |    |  |  |      | ("Unten")        |
65 |      |  |..+----+..|  |      |                  |
66 |      | .+ .+----+. +. |      |                  |
67 |      |/ |/ |.--.| \| \|      |                  |
68 |      |  |  (    )  |  |   ___|__________________|_
69 |       \  \  '--'  /  /       |                  |
70 |        '' ''----'' ''
71 |          ''------''
72 |  
73 | Der Vektor bodenbereich besteht entweder aus Eintraegen mit einem Element (Radius fuer runde
74 | Geometrie/Partition) oder zwei Elementen (halbe Kantenlaenge fuer rechteckige Geometrie oder
75 | Partition). Zur Vernetzung werden entsprechend viele Eintraege wie in schichten fuer
76 | gittergroessen benoetigt. Dabei kann entweder ein Wert gegeben werden (konstante Gittergroesse)
77 | oder zwei (linear veraendernde Gittergroesse). gitter_boden_vertikal gibt die vertikale
78 | Gitterfeinheit fuer den Schichtenbereich und das Void an. Fuer jeden Eintrag in schichten muss
79 | auch ein Material in schichtmaterial definiert sein. Zusaetzlich ist ein restmaterial, bspw. fuer
80 | den Bereich unterhalb der Schichten, anzugeben. Optional koennen extrasets erstellt werden.
81 | Optional kann der Boden als euler-Koerper oder Lagrange-Loerper ohne void-Bereich) erstellt
82 | werden. Partitionen werden mit einer Standardpartitionierung in x/y-Richtung erzeugt. Das
83 | Verhalten kann mit xypartition explizit deaktiviert werden. Optional kann nur Viertel- oder
84 | Halbmodell mit dem Parameter viertel erzeugt werden (nur die Werte 1,2 und 4 werden
85 | unterstuetzt). Falls nur ein halbes/viertel Modell erzeugt wird, werden Partitionen in der
86 | Schnittebene nicht erzeugt (unabhaengig von den Angaben in xypartition).
87 | Rechteckige Partitionen ziehen sich mit partition_durchziehen=True durch das komplette Modell,
88 | standardmaessig aber nur bis zur naechstgroesseren Partition (ggfs. mit Verbindungen).
89 |  
90 | Zusaetzlich erlaubt die Uebergabe von rotationsprofilpunkte (x-y-Punktkoordinaten) die Erstellung
91 | eines 3D-Profils auf Basis der Zeichnung (aus den Punkten) und einer Rotation um die vertikale
92 | Achse der Zeichnung (experimentell).
93 |
BodenmaterialUndSectionErstellen(modell, verwendeteMaterialien, verfuegbareMaterialien, userroutine='', numDepVar=0, euler=True)
Erstelle im modell je nach euler eine EulerianSection oder mehrere HomogeneousSolidSections
94 | mit allen verwendeteMaterialien. Die Abfolge der Materialschichten wird mit der Reihenfolge in
95 | verfuegbareMaterialien festgelegt. Falls ein Stoffgesetz eine Userroutine benoetigt, muss die
96 | Bezeichnung userroutine und die Anzahl der Rueckgabevariablen numDepVar uebergeben werden.
97 | Gibt [benoetigtUserroutine, verwendeteBodenwerte] zurueck.
98 |  
99 | Jeder Eintrag von verfuegbareMaterialien enthaelt:
100 |    [abqbodenname, dbbodenname, <optional: dbbodenbez,> saettigung, verdichtungsgrad, stoffgesetz]
101 |
BodenspannungDirektZuweisen(modell, bodenname, nullspannung, voidhoehe, schichten, bodentiefe, bodendichten, k0Werte)
Erzeuge im modell fuer den Bodenkoerper bodenname eine Bodenspannungsverteilung (in z-Richtung
102 | mit GOK bei z=0). Nutze dazu eine konstante Vorbelastung nullspannung fuer den Voidbereich der
103 | Hoehe voidhoehe. Fuer jede Schichttiefe in schichten bis bodentiefe werden die uebergebenen Werte
104 | aus bodendichten und k0Werte direkt zugewiesen.
105 |
BodenspannungErstellen(modell, bodenname, nullspannung, voidhoehe, schichten, bodentiefe, materialschichten, verwendeteBodenwerte, verwendeteMaterialien, verbose=False)
Erzeuge im modell fuer den Bodenkoerper bodenname eine Bodenspannungsverteilung (in z-Richtung
106 | mit GOK bei z=0). Nutze dazu eine konstante Vorbelastung nullspannung fuer den Voidbereich der
107 | Hoehe voidhoehe. Fuer jede Schicht der uebergebenen schichten bis bodentiefe werden ueber die
108 | Bezeichnungen in materialschichten die verwendeteBodenwerte fuer verwendeteMaterialien
109 | zugewiesen. Optional kann eine Infoausgabe mit verbose=True erstellt werden.
110 |
111 | 112 | -------------------------------------------------------------------------------- /abapys/hilfen.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | hilfen.py v3.3 (2020-11) 4 | """ 5 | 6 | # Copyright 2020-2021 Dominik Zobel. 7 | # All rights reserved. 8 | # 9 | # This file is part of the abapys library. 10 | # abapys is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # abapys is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with abapys. If not, see . 22 | 23 | 24 | # Oeffentliche globale Hilfsvariablen 25 | abapys_tol = 1e-6; 26 | grad2rad = 3.141592653589793/180.0; 27 | g = 9.81; # m/s^2 28 | 29 | 30 | # Interne globale Hilfsvariablen 31 | _abapysInitialisiert = False; 32 | _abaqusGUIStarted = False; 33 | _abaqusVersion = None; 34 | _abapysPfadZusatzdateien = ''; 35 | _abaqusOS = ''; 36 | 37 | _ppi = 96.0/25.4; # dpi/inch 38 | _xSkalierung = 1.0; 39 | _ySkalierung = 1.0; 40 | 41 | 42 | # ------------------------------------------------------------------------------------------------- 43 | def InitialisiereAbapys(session, version=2018, pfad='/exports/all/intern/abapys/', xSkalierung=None, 44 | ySkalierung=None): 45 | """Erkenne und speichere, ob sich die aktuelle session in der GUI oder Konsole befindet und 46 | welche version von Abaqus verwendet wird. Dazu werden die internen Variablen von Abaqus 47 | uebergeben, so dass session und version nicht manuell definiert werden muessen. Normalerweise 48 | koennen also die Argumente (session=session, version=version) uebergeben werden. 49 | 50 | Falls nicht der Standardpfad fuer zusaetzliche Dateien (bspw. Bibliotheken oder Materialtabelle) 51 | genutzt werden soll, kann der Pfad explizit ueber pfad angegeben werden. In dieser Funktion 52 | werden Skalierungswerte fuer den Viewport bei einer Bildausgabe berechnet, die aber durch 53 | Uebergabe der Faktoren xSkalierung und ySkalierung ueberschrieben werden koennen. 54 | """ 55 | import os 56 | # 57 | global _abapysInitialisiert; 58 | _abapysInitialisiert = True; 59 | # 60 | global _abaqusGUIStarted; 61 | _abaqusGUIStarted = session.attachedToGui; 62 | # 63 | global _abaqusVersion; 64 | _abaqusVersion = version; 65 | # 66 | global _abapysPfadZusatzdateien; 67 | _abapysPfadZusatzdateien = pfad; 68 | # 69 | global _abaqusOS; 70 | global _xSkalierung; 71 | global _ySkalierung; 72 | # platform.system() funtioniert in der untersuchten Windows 10/Abaqus 2018-Kombination nicht. 73 | # Deshalb wird aus Kompatibilitaet os.name verwendet 74 | if (os.name == 'nt'): 75 | _abaqusOS = 'Windows'; 76 | _xSkalierung = 0.9990166; 77 | _ySkalierung = 1.0004557; 78 | elif (os.name == 'posix'): 79 | _abaqusOS = 'Linux'; 80 | _xSkalierung = 1.0; 81 | _ySkalierung = 1.0026315; 82 | else: 83 | Log('# Warnung: Betriebssystem nicht unterstuetzt'); 84 | _abaqusOS = '?'; 85 | # 86 | if (xSkalierung is not None): 87 | _xSkalierung = xSkalierung; 88 | # 89 | if (ySkalierung is not None): 90 | _ySkalierung = ySkalierung; 91 | # 92 | 93 | 94 | # ------------------------------------------------------------------------------------------------- 95 | def _PfadZusatzdateien(): 96 | """Um im Modul ausserhalb der Datei auf eine globale Variable zugreifen zu koennen, die sich 97 | aendern koennte, wird diese Hilfsfunktion verwendet. Gibt den Pfad zu abapys-Zusatzdateien 98 | zurueck. 99 | """ 100 | return _abapysPfadZusatzdateien; 101 | # 102 | 103 | 104 | # ------------------------------------------------------------------------------------------------- 105 | def _VersionAbaqus(): 106 | """Gibt die Version von Abaqus zurueck, sofern abapys entsprechend initialisiert worden ist. 107 | Ansonsten None 108 | """ 109 | return _abaqusVersion; 110 | # 111 | 112 | 113 | # ------------------------------------------------------------------------------------------------- 114 | def BibliothekLaden(dateiname): 115 | """Lade eine kompilierte Bibliothek (.so unter Linux und .dll unter Windows) und gebe die mit 116 | ctypes geoeffnete Bibliothek zurueck. dateiname ist ohne Endung (d.h. ohne .so/.dll) anzugeben. 117 | Die Bibliothek wird aus dem Verzeichnis von abapys bzw. dem ueber das pfad-Argument im Befehl 118 | InitialisiereAbapys() geladen. Gibt den ctypes-Zugriffspunkt auf die bibliothek zurueck. 119 | """ 120 | from os import path 121 | # 122 | bibliothek = None; 123 | # Annahme: Linux oder Windows 124 | if (_abaqusOS == 'Linux'): 125 | from ctypes import cdll 126 | # 127 | name_bibliothek = path.join(_PfadZusatzdateien(), dateiname + '.so'); 128 | Log('# Lade Bibliothek: ' + name_bibliothek); 129 | try: 130 | bibliothek = cdll.LoadLibrary(name_bibliothek); 131 | except: 132 | pass; 133 | elif (_abaqusOS == 'Windows'): 134 | from ctypes import WinDLL 135 | # 136 | # Unter Windows wird die Endung automatisch hinzugefuegt 137 | name_bibliothek = path.join(_PfadZusatzdateien(), dateiname); 138 | Log('# Lade Bibliothek: ' + name_bibliothek + '.dll'); 139 | try: 140 | bibliothek = WinDLL(name_bibliothek); 141 | except: 142 | pass; 143 | else: 144 | Log('# Warnung: Betriebssystem zum Laden von Bibliotheken nicht unterstuetzt - InitialisiereAbapys() vergessen?'); 145 | # 146 | return bibliothek; 147 | # 148 | 149 | 150 | # ------------------------------------------------------------------------------------------------- 151 | def ViewportGroesseAendern(viewport, bildgroesse): 152 | """Aendere die Groesse von viewport zu bildgroesse (in Pixel). 153 | """ 154 | from abaqusConstants import ON 155 | # 156 | # Die Rahmenbreite beruecksichtigen 157 | bildgroesse[0] += 10; # 10px breiter 158 | bildgroesse[1] += 31; # 31px hoeher 159 | # 160 | bildbreite = bildgroesse[0]/_ppi/_xSkalierung; 161 | bildhoehe = bildgroesse[1]/_ppi/_ySkalierung; 162 | try: 163 | viewport.restore(); 164 | viewport.setValues(width=bildbreite, height=bildhoehe); 165 | except: # RangeError: 166 | Log('# Warnung: Ungueltige Bildgroesse (nichts geaendert)'); 167 | # 168 | 169 | 170 | # ------------------------------------------------------------------------------------------------- 171 | def ViewportPixelGroesseExtrahieren(viewport): 172 | """Gibt die Groesse von viewport in Pixeln [breite, hoehe] zurueck. 173 | """ 174 | from abaqusConstants import OFF 175 | # 176 | bildbreite = round(viewport.currentWidth*_ppi*_xSkalierung); 177 | bildhoehe = round(viewport.currentHeight*_ppi*_ySkalierung); 178 | # 179 | # Die Rahmenbreite beruecksichtigen 180 | bildbreite -= 10; 181 | bildhoehe -= 31; 182 | # 183 | return [bildbreite, bildhoehe]; 184 | # 185 | 186 | 187 | # ------------------------------------------------------------------------------------------------- 188 | def ErstelleLabelsortierteGeomlist(geomliste): 189 | """Gibt ein Dictionary mit den labels und den indizes der uebergebenen geomliste zurueck, um 190 | anschliessend schnell ueber die Labels statt Indizes auf die Eintraege aus geomliste zugreifen 191 | zu koennen. 192 | """ 193 | templist = []; 194 | idx = 0; 195 | for geom in geomliste: 196 | templist += [(geom.label, idx),]; 197 | idx += 1; 198 | # 199 | return dict(templist); 200 | # 201 | 202 | 203 | # ------------------------------------------------------------------------------------------------- 204 | def ErstelleElementLabelsortierteGeomlist(geomliste): 205 | """Gibt ein Dictionary mit den elementLabels und den indizes der uebergebenen geomliste zurueck, 206 | um anschliessend schnell ueber die elementLabels statt Indizes auf die Eintraege aus geomliste 207 | zugreifen zu koennen. 208 | """ 209 | templist = []; 210 | idx = 0; 211 | for geom in geomliste: 212 | templist += [(geom.elementLabel, idx),]; 213 | idx += 1; 214 | # 215 | return dict(templist); 216 | # 217 | 218 | 219 | # ------------------------------------------------------------------------------------------------- 220 | def ErstelleNodeLabelsortierteGeomlist(geomliste): 221 | """Gibt ein Dictionary mit den nodeLabels und den indizes der uebergebenen geomliste zurueck, 222 | um anschliessend schnell ueber die nodeLabels statt Indizes auf die Eintraege aus geomliste 223 | zugreifen zu koennen. 224 | """ 225 | templist = []; 226 | idx = 0; 227 | for geom in geomliste: 228 | templist += [(geom.nodeLabel, idx),]; 229 | idx += 1; 230 | # 231 | return dict(templist); 232 | # 233 | 234 | 235 | # ------------------------------------------------------------------------------------------------- 236 | def ElementeMitZielwert(elemliste, zielwert): 237 | """Pruefe alle Elemente in elemliste, ob deren Wert (elemliste[#].data) dem zielwert entspricht. 238 | Gibt [Labels] der Elemente zurueck, fuer die das gilt. 239 | """ 240 | idxZielwert = []; 241 | for elem in elemliste: 242 | if (elem.data == zielwert): 243 | idxZielwert = idxZielwert + [elem.elementLabel]; 244 | # 245 | return idxZielwert; 246 | # 247 | 248 | 249 | # ------------------------------------------------------------------------------------------------- 250 | def ElementAusOdb(element): 251 | """Pruefe anhand des uebergebenen element, aus welchem Kontext das element stammt. Gibt True 252 | zurueck, wenn ein Bezug zu session.odbs[...].rootAssembly.instances[...].elements vorhanden ist, 253 | ansonsten False 254 | """ 255 | # unterstuetzte mdb-Bezuege sind mdb.models[...].rootAssembly.instances[...].elements und 256 | # mdb.models[...].parts[...].elements, nach denen aber nicht explizit geprueft wird. 257 | istOdb = True; 258 | try: 259 | # Versuche herauszufinden, ob es sich um odb-elemente oder mdb-elemente handelt. instanceNames 260 | # scheint nur in odb-elementen zu existieren. Alternativ waere es denkbar, mithilfe von 261 | # elements[0].__subclasshook__ und einer Filterung nach odb zu pruefen 262 | tempNames = element.instanceNames; 263 | except AttributeError: 264 | istOdb = False; 265 | # 266 | return istOdb; 267 | # 268 | 269 | 270 | # ------------------------------------------------------------------------------------------------- 271 | def Einheitsvektor(dim, idxEins): 272 | """Erstelle einen Vektor der Groesse dim, der ueberall Nullen hat und eine Eins an der Stelle 273 | idxEins. Gibt den Einheitsvektor zurueck. 274 | """ 275 | if ((not isinstance(dim, (int, long))) or (not isinstance(dim, (int, long)))): 276 | #Log('# Abbruch: dim und idxEins muessen ganzzahlige Werte sein'); 277 | return []; 278 | # 279 | if (dim <= 0): 280 | #Log('# Abbruch: Ungueltige Dimension (muss >0 sein)'); 281 | return []; 282 | # 283 | if ((idxEins < 0) or (idxEins >= dim)): 284 | #Log('# Abbruch: Ungueltiger Index fuer den Einsereintrag (muss ', '>=', 'in', # Vergleichsoperatoren 363 | 'pi', 'sqrt', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'abs']; # Mathematische Operatoren 364 | # 365 | # Attribute von Abaqus-Elementen: vertices/edges/faces/cells (mdb) sowie nodes und elements 366 | erlaubt += ['coordinates', 'connectivity', 'featureName', 'index', 'instanceName', 367 | 'instanceNames', 'isReferenceRep', 'pointOn', 'sectionCategory', 'label', 'type']; 368 | # 369 | erlaubt += zusatz_erlaubt; 370 | # 371 | # Strings ignorieren 372 | string_idx = []; 373 | temp_idx = 0; 374 | while (True): 375 | temp_idx = code.find('\'', temp_idx+1); 376 | if (temp_idx == -1): 377 | break; 378 | # 379 | string_idx += [temp_idx]; 380 | # 381 | if ((len(string_idx) % 2) != 0): 382 | Log('# Abbruch: Ungueltige Anzahl an Anfuehrungszeichen'); 383 | return False; 384 | # 385 | if (len(string_idx) > 1): 386 | for idx in range(len(string_idx)//2): 387 | code = code[:string_idx[2*idx]] + ' ' * (string_idx[2*idx+1]-string_idx[2*idx]+1) + code[string_idx[2*idx+1]+1:]; 388 | # 389 | # Der Rest sollten nur normale Zahlen sein 390 | remuster = re_compile('^[0-9.]*$'); 391 | # 392 | # Den code in einzelne Segmente aufteilen und einzeln ueberpruefen. 393 | codeteile = code.replace('(', ' ').replace(')', ' ').replace('[', ' ').replace(']', ' ') \ 394 | .replace('.', ' ').replace('+', ' ').replace('-', ' ').replace('*', ' ').replace('/', ' ').split(); 395 | for einzelteil in codeteile: 396 | if (einzelteil not in erlaubt): 397 | if (not (re_search(remuster, einzelteil))): 398 | Log('# Abbruch: Ungueltige Zeichenkette in eval: >' + einzelteil + '<'); 399 | return False; 400 | # 401 | return True; 402 | # 403 | 404 | 405 | # ------------------------------------------------------------------------------------------------- 406 | def Log(ausgabe, ueberschreiben=False): 407 | """Die uebergebene ausgabe entweder in Abaqus behalten oder in die Konsole umleiten, falls abapys 408 | initialisiert worden ist und die GUI nicht aktiv ist. Optional kann ein ueberschreiben der 409 | Ausgabe aktiviert werden (z.B. fuer Status-/Prozentangaben). 410 | """ 411 | from sys import __stdout__ 412 | if (_abapysInitialisiert and (not _abaqusGUIStarted)): 413 | if (ueberschreiben): 414 | print >> __stdout__, "\r" + ausgabe, ; 415 | else: 416 | print >> __stdout__, ausgabe; 417 | else: 418 | if (ueberschreiben): 419 | print "\r" + ausgabe, ; 420 | else: 421 | print(ausgabe); 422 | # 423 | -------------------------------------------------------------------------------- /abapys/auswahl.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | auswahl.py v0.3 (2020-09) 4 | """ 5 | 6 | # Copyright 2020-2021 Dominik Zobel. 7 | # All rights reserved. 8 | # 9 | # This file is part of the abapys library. 10 | # abapys is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # abapys is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with abapys. If not, see . 22 | 23 | 24 | # ------------------------------------------------------------------------------------------------- 25 | def BedingteAuswahl(elemente, bedingung='True', var=[]): 26 | """Erstelle eine Sequenz aller uebergebenen elemente, die bedingung erfuellen. Alle Variablen aus 27 | bedingung muessen global lesbar oder optional in var uebergeben und als var[...] bezeichnet sein, 28 | sonst kann die bedingung nicht korrekt ausgewertet werden. Gibt die Sequenz der ausgewaehlten 29 | Elemente zurueck. 30 | 31 | In der Bedingung kann mit elem auf ein einzelnes Element zugegriffen werden. Auf die 32 | Basiskoordinaten eines Elementes kann mit elem.pointOn[0][#] zugegriffen werden, wobei die Raute 33 | fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht. 34 | 35 | Fuer mathematische Zusammenhaenge stehen die Funktionen pi, sqrt, sin, cos, tan, asin, acos, atan 36 | zur Verfuegung. 37 | """ 38 | method = 'index'; 39 | try: 40 | i = elemente[0].index 41 | except: 42 | method = 'label'; 43 | # 44 | if (method == 'index'): 45 | return _BedingteAuswahlIndex(elemente=elemente, bedingung=bedingung, var=var); 46 | else: 47 | return _BedingteAuswahlLabel(elemente=elemente, bedingung=bedingung, var=var); 48 | # 49 | 50 | 51 | # ------------------------------------------------------------------------------------------------- 52 | def _BedingteAuswahlIndex(elemente, bedingung='True', var=[]): 53 | """Erstelle eine Sequenz aus den Indizes aller uebergebenen elemente, die bedingung erfuellen. 54 | Alle Variablen aus bedingung muessen global lesbar oder optional in var uebergeben und als 55 | var[...] bezeichnet sein, sonst kann die bedingung nicht korrekt ausgewertet werden. 56 | Gibt die Sequenz der ausgewaehlten Elemente zurueck. 57 | 58 | In der Bedingung kann mit elem auf ein einzelnes Element zugegriffen werden. Auf die 59 | Basiskoordinaten eines Elementes kann mit elem.pointOn[0][#] zugegriffen werden, wobei die Raute 60 | fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht. 61 | """ 62 | from math import pi, sqrt, sin, cos, tan, asin, acos, atan 63 | from hilfen import Log, _Eval_Basispruefung 64 | # 65 | ausgewaehlteElemente = elemente[0:0]; 66 | erlaubt = ['coordinates', 'connectivity', 'featureName', 'index', 'instanceName', 'instanceNames', 67 | 'isReferenceRep', 'pointOn', 'sectionCategory', 'label', 'type', 'var', 'elem']; 68 | # 69 | if (not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=erlaubt)): 70 | Log('# Abbruch: Uebergebene bedingung ist ungueltig'); 71 | return ausgewaehlteElemente; 72 | # 73 | for elem in elemente: 74 | if (eval(bedingung)): 75 | ausgewaehlteElemente += elemente[elem.index:elem.index+1]; 76 | # 77 | return ausgewaehlteElemente; 78 | # 79 | 80 | 81 | # ------------------------------------------------------------------------------------------------- 82 | def _BedingteAuswahlLabel(elemente, bedingung='True', var=[]): 83 | """Erstelle eine Sequenz aus den Labels aller uebergebenen elemente, die bedingung erfuellen. 84 | Alle Variablen aus bedingung muessen global lesbar oder optional in var uebergeben und als 85 | var[...] bezeichnet sein, sonst kann die bedingung nicht korrekt ausgewertet werden. 86 | Gibt die Sequenz der ausgewaehlten Elemente zurueck. 87 | 88 | In der Bedingung kann mit elem auf ein einzelnes Element zugegriffen werden. Auf die 89 | Basiskoordinaten eines Elementes kann mit elem.coordinates[#] zugegriffen werden, wobei die Raute 90 | fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht. 91 | """ 92 | from math import pi, sqrt, sin, cos, tan, asin, acos, atan 93 | from hilfen import Log, _Eval_Basispruefung 94 | # 95 | erlaubt = ['coordinates', 'connectivity', 'featureName', 'index', 'instanceName', 'instanceNames', 96 | 'isReferenceRep', 'pointOn', 'sectionCategory', 'label', 'type', 'var', 'elem']; 97 | # 98 | if (not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=erlaubt)): 99 | Log('# Abbruch: Uebergebene bedingung ist ungueltig'); 100 | return elemente[0:0]; 101 | # 102 | ausgewaehlteLabels = []; 103 | for elem in elemente: 104 | if (eval(bedingung)): 105 | ausgewaehlteLabels += [elem.label]; 106 | # 107 | return LabelAuswahl(elemente=elemente, labelliste=ausgewaehlteLabels); 108 | # 109 | 110 | 111 | # ------------------------------------------------------------------------------------------------- 112 | def ZweifachbedingteKantenAuswahl(elemente, bedingung1='True', bedingung2='True', bedingung3='True', 113 | var=[]): 114 | """Erstelle eine Sequenz aller Kanten aus elemente, die bedingung1 und bedingung2 erfuellen. 115 | Die Rueckgabe der Kanten ist sortiert nach bedingung3. Alle Variablen aus bedingung1, bedingung2 116 | und bedingung3 muessen global lesbar oder optional in var uebergeben und als var[...] bezeichnet 117 | sein, sonst koennen die Bedingungen nicht korrekt ausgewertet werden. 118 | 119 | In der ersten Bedingung kann mit edge auf eine einzelne Kante zugegriffen werden (bspw. 120 | edge.pointOn[0][#], wobei die Raute fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen 121 | steht). In der zweiten und dritten Bedingung kann zusaetzlich auch auf die beiden Endpunkte vert1 122 | sowie vert2 zugegriffen werden (ebenfalls vert.pointOn[0][#] mit Raute als 0, 1 oder 2). 123 | 124 | Die ersten beiden Bedingungen sind zur Auswahl der der Kanten. Kanten die eine der ersten beiden 125 | Bedingungen nicht erfuellen, werden ignoriert. Die restlichen Kanten werden sortiert, abhaengig 126 | davon, ob sie die letzte Bedingung erfuellen oder nicht. Gibt eine Liste mit zwei Sequenzen der 127 | ausgewaehlten Kanten [kanten_bedingung3_True, kanten_bedingung3_False] zurueck. 128 | 129 | Fuer mathematische Zusammenhaenge stehen die Funktionen sqrt, sin, cos, tan, asin, acos, atan 130 | zur Verfuegung. 131 | """ 132 | from math import sqrt, sin, cos, tan, asin, acos, atan 133 | from hilfen import Log, _Eval_Basispruefung 134 | # 135 | kanten1 = elemente.edges[0:0]; 136 | kanten2 = elemente.edges[0:0]; 137 | # 138 | erlaubt = ['coordinates', 'connectivity', 'featureName', 'index', 'instanceName', 'instanceNames', 139 | 'isReferenceRep', 'pointOn', 'sectionCategory', 'label', 'type', 'var', 'edge', 'vert1', 'vert2']; 140 | # 141 | if (any([(not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=erlaubt)) for bedingung in [bedingung1, bedingung2, bedingung3]])): 142 | Log('# Abbruch: Uebergebene bedingung1/bedingung2/bedingung3 ungueltig'); 143 | return; 144 | # 145 | for edge in elemente.edges: 146 | if (eval(bedingung1)): 147 | vert1 = elemente.vertices[edge.getVertices()[0]]; 148 | vert2 = elemente.vertices[edge.getVertices()[1]]; 149 | if (eval(bedingung2)): 150 | if (eval(bedingung3)): 151 | kanten1 += elemente.edges[edge.index:edge.index+1]; 152 | else: 153 | kanten2 += elemente.edges[edge.index:edge.index+1]; 154 | # 155 | kanten = [kanten1, kanten2]; 156 | return kanten; 157 | # 158 | 159 | 160 | # ------------------------------------------------------------------------------------------------- 161 | def LabelAuswahl(elemente, labelliste, elementhilfsliste=[]): 162 | """Erstelle eine Sequenz aller uebergebener elemente, deren Label sich in labelliste befindet. 163 | Optional kann eine elementhilfsliste vorab erzeugt und uebergeben werden, was vorallem bei 164 | mehrmaligen Aufrufen einer LabelAuswahl fuer gleiche elemente deutlich schneller ist. 165 | Falls keine elementhilfsliste uebergeben worden ist, wird (jedes mal) intern eine erstellt. 166 | Gibt die Sequenz der ausgewaehlten Elemente zurueck. 167 | """ 168 | from hilfen import ErstelleLabelsortierteGeomlist 169 | # 170 | if (elementhilfsliste == []): 171 | elementhilfsliste = ErstelleLabelsortierteGeomlist(geomliste=elemente); 172 | # 173 | ausgewaehlteElemente = elemente[0:0]; 174 | for label in labelliste: 175 | idxelem = elementhilfsliste[label]; 176 | ausgewaehlteElemente += elemente[idxelem:idxelem+1]; 177 | # 178 | return ausgewaehlteElemente; 179 | # 180 | 181 | 182 | # ------------------------------------------------------------------------------------------------- 183 | def ElementAuswahl(elemente, punktliste, bedingung='True', var=[], listenhilfe=[]): 184 | """Gib eine Sequenz an Elementen aus den uebergebenen elemente zurueck, die bzw. deren Punkte die 185 | bedingung erfuellen. Fuer die Zuordnung der einzelnen Punkte zu den Elementen muss eine 186 | punktliste uebergeben werden, die alle Punkte aller elemente enthaelt. 187 | Gibt die Sequenz der ausgewaehlten Elemente zurueck. 188 | 189 | In der Bedingung kann mit elem auf ein einzelnes Element und mit punkt auf einen Punkt des 190 | Elements zugegriffen werden. Die Koordinaten eines Punktes koennen mit punkt.coordinates[#] 191 | erhalten werden, wobei die Raute fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht. 192 | 193 | Optional kann die korrekte Zuordnung der Labels der Punkte bei odb-elementen durch Uebergabe 194 | einer listenhilfe beschleunigt werden. 195 | 196 | Fuer mathematische Zusammenhaenge stehen die Funktionen pi, sqrt, sin, cos, tan, asin, acos, atan 197 | zur Verfuegung. 198 | 199 | WICHTIG: Wenn Elemente einer mdb statt einer odb untersucht werden sollen, sollte entweder keine 200 | oder die folgende listenhilfe uebergeben werden: 201 | 202 | listenhilfe = [idx for idx in range(len(punktliste))]; 203 | """ 204 | from hilfen import ElementAusOdb 205 | # 206 | if (ElementAusOdb(element=elemente[0])): 207 | return _OdbElementAuswahl(elemente=elemente, punktliste=punktliste, bedingung=bedingung, 208 | var=var, listenhilfe=listenhilfe); 209 | else: 210 | return _MdbElementAuswahl(elemente=elemente, punktliste=punktliste, bedingung=bedingung, 211 | var=var); 212 | # 213 | 214 | 215 | # ------------------------------------------------------------------------------------------------- 216 | def _MdbElementAuswahl(elemente, punktliste, bedingung='True', var=[]): 217 | """Gib eine Sequenz an Elementen aus den uebergebenen elemente zurueck, die bzw. deren Punkte die 218 | bedingung erfuellen (nur mdb). Fuer die Zuordnung der einzelnen Punkte zu den Elementen muss eine 219 | punktliste uebergeben werden, die alle Punkte aller elemente enthaelt. 220 | Gibt die Sequenz der ausgewaehlten Elemente zurueck. 221 | 222 | In der Bedingung kann mit elem auf ein einzelnes Element und mit punkt auf einen Punkt des 223 | Elements zugegriffen werden. Die Koordinaten eines Punktes koennen mit punkt.coordinates[#] 224 | erhalten werden, wobei die Raute fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht. 225 | """ 226 | from math import pi, sqrt, sin, cos, tan, asin, acos, atan 227 | from hilfen import Log, _Eval_Basispruefung 228 | # 229 | ausgewaehlteElemente = elemente[0:0]; 230 | erlaubt = ['coordinates', 'connectivity', 'featureName', 'index', 'instanceName', 'instanceNames', 231 | 'isReferenceRep', 'pointOn', 'sectionCategory', 'label', 'type', 'var', 'elem', 'punkt']; 232 | # 233 | if (not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=erlaubt)): 234 | Log('# Abbruch: Uebergebene bedingung ist ungueltig'); 235 | return ausgewaehlteElemente; 236 | # 237 | numPunkte = len(elemente[0].connectivity); 238 | for idx, elem in enumerate(elemente): 239 | numErfuellt = 0; 240 | for punktidx in elem.connectivity: 241 | punkt = punktliste[punktidx]; 242 | if (eval(bedingung)): 243 | numErfuellt += 1; 244 | # 245 | if (numErfuellt == numPunkte): 246 | ausgewaehlteElemente += elemente[idx:idx+1]; 247 | # 248 | return ausgewaehlteElemente; 249 | # 250 | 251 | 252 | # ------------------------------------------------------------------------------------------------- 253 | def _OdbElementAuswahl(elemente, punktliste, bedingung='True', var=[], listenhilfe=[]): 254 | """Gib eine Sequenz an Elementen aus den uebergebenen elemente zurueck, die bzw. deren Punkte die 255 | bedingung erfuellen (nur odb). Fuer die Zuordnung der einzelnen Punkte zu den Elementen muss eine 256 | punktliste uebergeben werden, die alle Punkte aller elemente enthaelt. Die korrekte Zuordnung der 257 | Labels der Punkte kann durch Uebergabe einer listenhilfe beschleunigt werden. 258 | Gibt die Sequenz der ausgewaehlten Elemente zurueck. 259 | 260 | In der Bedingung kann mit elem auf ein einzelnes Element und mit punkt auf einen Punkt des 261 | Elements zugegriffen werden. Die Koordinaten eines Punktes koennen mit punkt.coordinates[#] 262 | erhalten werden, wobei die Raute fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht. 263 | """ 264 | from math import pi, sqrt, sin, cos, tan, asin, acos, atan 265 | from hilfen import Log, _Eval_Basispruefung, ErstelleLabelsortierteGeomlist 266 | # 267 | ausgewaehlteElemente = elemente[0:0]; 268 | erlaubt = ['coordinates', 'connectivity', 'featureName', 'index', 'instanceName', 'instanceNames', 269 | 'isReferenceRep', 'pointOn', 'sectionCategory', 'label', 'type', 'var', 'elem', 'punkt']; 270 | # 271 | if (not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=erlaubt)): 272 | Log('# Abbruch: Uebergebene bedingung ist ungueltig'); 273 | return ausgewaehlteElemente; 274 | # 275 | if (listenhilfe == []): 276 | listenhilfe = ErstelleLabelsortierteGeomlist(geomliste=punktliste); 277 | # 278 | numPunkte = len(elemente[0].connectivity); 279 | for idx, elem in enumerate(elemente): 280 | numErfuellt = 0; 281 | for punktlabel in elem.connectivity: 282 | punkt = punktliste[listenhilfe[punktlabel]]; 283 | if (eval(bedingung)): 284 | numErfuellt += 1; 285 | else: 286 | continue; 287 | # 288 | if (numErfuellt == numPunkte): 289 | ausgewaehlteElemente += elemente[idx:idx+1]; 290 | # 291 | return ausgewaehlteElemente; 292 | # 293 | 294 | 295 | # ------------------------------------------------------------------------------------------------- 296 | def KnotenAuswahlLabelliste(knoten, sortierung=0, aufsteigend=True): 297 | """Sortiert alle uebergebenen knoten nach der Koordinatenrichtung sortierung basierend auf den 298 | jeweiligen Koordinaten. 299 | 300 | Fuer die sortierung ist die jeweilige Richtung (0, 1 oder 2) anzugeben. Die Reihenfolge wird 301 | ueber die Koordinaten der Mittelpunkte der Elemente bestimmt. Die Werte koennen entweder 302 | aufsteigend oder absteigend sortiert werden. 303 | """ 304 | from operator import itemgetter 305 | # 306 | tempsortierung = sortierung; 307 | if ((not (sortierung == 0)) and (not (sortierung == 1)) and (not (sortierung == 2))): 308 | Log('# Warnung: Ungueltige sortierung, nehme sortierung = 0'); 309 | tempsortierung = 0; 310 | # 311 | if (len(knoten) == 0): 312 | Log('# Hinweis: Keine Knoten uebergeben'); 313 | return []; 314 | # 315 | templiste = []; 316 | for einzelpunkt in knoten: 317 | templiste += [(einzelpunkt.coordinates[tempsortierung], einzelpunkt.label), ]; 318 | # 319 | templiste.sort(key=itemgetter(0)); 320 | labelliste = [x[1] for x in templiste]; 321 | if (aufsteigend): 322 | return labelliste; 323 | else: 324 | return list(reversed(labelliste)); 325 | # 326 | 327 | 328 | # ------------------------------------------------------------------------------------------------- 329 | def ElementAuswahlLabelliste(elemente, punktliste, sortierung=0, aufsteigend=True, 330 | listenhilfe=[]): 331 | """Sortiert alle uebergebenen elemente nach der Koordinatenrichtung sortierung basierend auf den 332 | Koordinaten des Elementmittelpunktes. Fuer die Berechnung der Mittelpunktkoordinaten werden die 333 | Knoten der Elemente benutzt. Fuer die Zuordnung der einzelnen Punkte zu den Elementen muss eine 334 | punktliste uebergeben werden, die alle Punkte aller elemente enthaelt. Gibt eine Liste der Labels 335 | aller uebergebenen elemente zurueck, deren Mittelpunkte nach der Koordinatenrichtung sortierung 336 | sortiert ist. 337 | 338 | Fuer die sortierung ist die jeweilige Richtung (0, 1 oder 2) anzugeben. Die Reihenfolge wird 339 | ueber die Koordinaten der Mittelpunkte der Elemente bestimmt. Die Werte koennen entweder 340 | aufsteigend oder absteigend sortiert werden. 341 | 342 | Optional kann die korrekte Zuordnung der Labels der Punkte bei odb-elementen durch Uebergabe 343 | einer listenhilfe beschleunigt werden. 344 | 345 | WICHTIG: Wenn Elemente einer mdb statt einer odb untersucht werden sollen, sollte entweder keine 346 | oder die folgende listenhilfe uebergeben werden: 347 | 348 | listenhilfe = [idx for idx in range(len(punktliste))]; 349 | """ 350 | from operator import itemgetter 351 | from hilfen import Log, ElementAusOdb, ErstelleLabelsortierteGeomlist 352 | # 353 | tempsortierung = sortierung; 354 | if ((not (sortierung == 0)) and (not (sortierung == 1)) and (not (sortierung == 2))): 355 | Log('# Warnung: Ungueltige sortierung, nehme sortierung = 0'); 356 | tempsortierung = 0; 357 | # 358 | if (len(elemente) == 0): 359 | Log('# Hinweis: Keine Elemente uebergeben'); 360 | return []; 361 | # 362 | if (listenhilfe == []): 363 | if (ElementAusOdb(element=elemente[0])): 364 | listenhilfe = ErstelleLabelsortierteGeomlist(geomliste=punktliste); 365 | else: 366 | listenhilfe = [idx for idx in range(len(punktliste))]; 367 | # 368 | templiste = []; 369 | anzahlpunkte = float(len(elemente[0].connectivity)); 370 | for elem in elemente: 371 | mittelwert = 0; 372 | for punktlabel in elem.connectivity: 373 | punkt = punktliste[listenhilfe[punktlabel]]; 374 | mittelwert = punkt.coordinates[tempsortierung]/anzahlpunkte; 375 | # 376 | templiste += [(mittelwert, elem.label), ]; 377 | # 378 | templiste.sort(key=itemgetter(0)); 379 | labelliste = [x[1] for x in templiste]; 380 | if (aufsteigend): 381 | return labelliste; 382 | else: 383 | return list(reversed(labelliste)); 384 | # 385 | -------------------------------------------------------------------------------- /docs/abapys.ausgabe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Python: module abapys.ausgabe 4 | 5 | 6 | 7 | 8 | 9 |
 
10 |  
abapys.ausgabe
13 |

ausgabe.py   v1.4 (2023-02)

14 |

15 | 16 | 17 | 19 | 20 | 21 |
 
18 | Functions
       
BauteileEinfaerben(viewport, zuweisungen, standardfarbe='#000000', odb=True)
Faerbt das im uebergebenen viewport dargestellte Modell nach Instanzen ein. Mit zuweisungen
22 | wird eine Liste erwartet mit [[Instanzname, Farbe], [...]] wobei, die Farbe im Hexadezimal-Format
23 | zu geben ist (bspw. ist rot '#FF0000'). Alle Instanzen, die nicht in der zuweisung gelistet sind,
24 | werden mit standardfarbe eingefaerbt. Um die korrekte Zuweisung zu ermoeglichen, muss  mit dem
25 | Flag odb angegeben werden, ob es sich um eine odb oder mdb (odb=False) handelt.
26 |
BildSpeichern(dateiname, session, dateityp='png', bildgroesse=[], hintergrund=False)
Speichern die Darstellung des aktiven Viewports aus session als Bilddatei mit dem Namen
27 | dateiname. Optional kann der dateityp ('png' oder 'eps') und die bildgroesse (als Vektor mit
28 | Bildbreite und Bildhoehe in Pixeln) angepasst werden.
29 |
DehnungsInvarianteAlsFieldOutput(name, session, odbname, beschreibung='Dehungsinvariante')
Fuege einen neuen FieldOutput namens name zur Ausgabedatei odbname der session mit der
30 | Dehnungsinvariante hinzu. Optional kann die Beschreibung angepasst werden.
31 |
FieldOutputSpeichern(dateiname, session, odbname, fieldOutput, step, frame)
Ermittle die Ausgabevariable fieldOutput im angeforderten step und frame
32 | (beides Zahlenwerte) der Datei odbname aus der aktuellen session. Speichere
33 | das Ergebnis unter dateiname.erg.
34 |
FieldOutputVorbereiten(session, odbname, var, varposition)
Extrahiere die XY-Daten eines Field-Outputs aus odb namens odbname aus session mit dem Namen
35 | var=[Variablenname, Komponente] und varposition=(Instanzname, [Label(s)]).
36 |  
37 | Wenn mit varposition mehr als ein Label in der Liste uebergeben wird, stimmt die Reihenfolge der
38 | erzeugten Daten im Allgemeinen nicht mit der Reihenfolge der Labels in der Liste uebereinstimmen.
39 |
HistoryOutputVorbereiten(session, odbname, var, varname)
Extrahiere die XY-Daten eines History-Outputs aus einer odb namens odbname aus session mit dem
40 | exakten Namen var oder var=[Instanzname, Ausgabevariable]. Im letzten Fall wird der Name des
41 | dazugehoerigen Outputs automatisch bestimmt. Falls Ausgaben fuer das ganze Modell ohne komplette
42 | Namensnennung erforderlich sind, kann Instanzname auch leer bleiben (bspw. ['', 'ETOTAL']).
43 | Speichere die Daten intern unter dem Namen varname.
44 |
LetzterOutputStepUndFrame(session, odbname)
Ermittle aus der Ausgabedatei odbname in der aktuellen session den letzten Step und
45 | darin den letzten Frame, in dem Outputs geschrieben worden sind.
46 |
Modellansicht(session, ansicht='', rechts=1, oben=2)
Aendere die Ansicht des aktiven Viewports der session entweder durch die interne ansicht
47 | (d.h. 'Front', 'Back', 'Top', 'Bottom', 'Left' oder 'Right') oder durch Angabe der Achsen rechts
48 | und oben (x = +/-1, y = +/-2, z = +/-3).
49 |  
50 |        y                        y                  +-- x                    z          
51 | Front  |              Back      |            Top   |                Bottom  |         
52 |        +-- x                x --+                  z                        +-- x     
53 | (rechts=1, oben=2)    (rechts=-1, oben=2)    (rechts=1, oben=-3)    (rechts=1, oben=3) 
54 |  
55 |  
56 |       y                          y                  y
57 | Left  |               Right      |           Iso    |
58 |       +-- z                  z --+                z   x
59 | (rechts=3, oben=2)    (rechts=-3, oben=2)    --nicht ohne zusaetzliche Drehung---
60 |
MultiBildSpeichern(dateiname, session, anordnung=[1, 1], zeitstempel=None, zeitstempelkanal=0, legendenkanal=0, mehrfachmodus=False, autozoom=False)
Speichere Dateien mit dem Titel dateiname aus dem aktiven Viewport der Session session und odb
61 | namens odbname. Optional kann statt einem Bild mehrere Teilbilder nach der Anordnung anordnung
62 | ausgegeben werden. Falls SINGLE und OVERLAY-Modus gespeichert werden sollen, kann mehrfachmodus
63 | aktiviert werden.
64 | Optional kann mit autozoom der Zoom innerhalb der Funktion abhaengig vom uebergebenen sichtbaren
65 | Bereich und der Aufteilung in anordnung durchgefuehrt werden.
66 |
MultiVideobilderSpeichern(dateiname, session, odbname, anordnung=[1, 1], zeitstempel=None, zeitstempelkanal=0, legendenkanal=0, mehrfachmodus=False, autozoom=False)
Speichere Dateien mit dem Basisnamen dateiname aus der Ausgabedatei odbname, die im aktiven
67 | Viewport der session dargestellt ist. Optional koennen statt einem Bild mehrere Teilbilder in der
68 | gegebenen anordnung (Teilbilder horizontal und vertikal) ausgegeben werden. Optional kann
69 | ausserdem ein zeitstempel uebergeben werden, der nur im Teilbild zeitstempelkanal angezeigt wird.
70 | Auch eine moeglicherweise sichtbare Legende wird nur im legendenkanal dargestellt. Dabei hat das
71 | linke obere Teilbild den Wert 0 und nimmt zeilenweise von links nach rechts zu. Falls
72 | mehrfachmodus aktiviert ist, werden Bilder im SINGLE- und OVERLAY-Modus gespeichert.
73 | Optional kann mit autozoom der Zoom innerhalb der Funktion abhaengig vom uebergebenen sichtbaren
74 | Bereich und der Aufteilung in anordnung durchgefuert werden.
75 |
PlotFormatieren(xyplot, chart, titel='', xlabel='', ylabel='', xlim=[], ylim=[])
Plot xyplot und Darstellung chart verschoenern und an typisches Format anpassen. Optional
76 | koennen titel, xlabel und ylabel als Text definiert werden. Ausserdem kann der
77 | Darstellungsbereich der beiden Achsen durch einen Vektor mit Minimal- und Maximalwert beschraenkt
78 | werden (ohne Angabe erfolgt Autoskalierung).
79 |
PlotLegendeFormatieren(session, chart, curvedata, legendeneintraege, zuerstFarbenwechseln=True, kurvenFarben=[], kurvenStile=[])
Die Legende von chart aus session mit den Kurven curvedata wird mit den Werten aus
80 | legendeneintraege geschrieben. Optional koennen auch kurvenFarben und kurvenStile, sowie deren
81 | Abfolge mit zuerstFarbenwechseln geaendert werden.
82 |
PlotOutput(session, odbname, yvar, yvarposition=[], ylabel='', ylimit=[], posydir=True, xvar=[], xvarposition=[], xlabel='', xlimit=[], posxdir=True, titel='', legendeneintraege=[], plothinzufuegen=False)
Plotte die angegebenen yvar der Auswahl yvarposition ueber xvar an xvarposition der odb namens
83 | odbname aus session. Falls xvar nicht definiert ist, wird diese Achse zur Zeitachse. Es koennen
84 | mehrere Daten (bspw. mehrere Elemente) fuer die y-Richtung uebergeben werden, aber fuer die
85 | x-Richtung darf es nur ein einziger Datensatz sein.
86 |  
87 | Optional koennen auch xlabel und ylabel zur Achsenbeschriftung sowie xlimit und ylimit zur
88 | Beschraenkung der Zeichenebene uebergeben werden. Die Richtung der Werte kann optional ueber
89 | posxdir oder posydir invertiert werden. Optional kann ausserdem ein titel fuer den Plot und die
90 | Bezeichnung der legendeneintraege uebergeben werden. Falls bereits ein Plot existiert, steuert
91 | plothinzufuegen, ob er ueberschrieben oder ergaenzt wird.
92 |  
93 | Erwartet wird bei FieldOuptut-Variablen ein Vektor var=(Variablenname, Komponente) und entweder
94 | die Variablenposition mit yvarposition=(odb-Setname) oder (Instanzname, [Label(s)]).
95 |  
96 | Bei HistoryOutput-Variablen wird nur ein Vektor var=([Instanzname, Ausgabevariable]) oder
97 | var=(Ausgabenname) erwartet (varposition entfaellt). Im Fall var=([Instanzname, Ausgabevariable])
98 | wird der Name des dazugehoerigen Outputs automatisch bestimmt. Falls Ausgaben fuer das ganze
99 | Modell ohne komplette Namensnennung erforderlich sind, kann Instanzname auch leer bleiben
100 | (bspw. ['', 'ETOTAL']).
101 |
PlotXYDaten(session, xyListe, ylimit=[], ylabel='', xlimit=[], xlabel='', titel='', legendeneintraege=[], plothinzufuegen=False)
Plotte die in der xyListe angegebenen XYDaten. Optional koennen xlabel und ylabel zur
102 | Achsenbeschriftung sowie xlimit und ylimit zur Beschraenkung der Zeichenebene uebergeben werden.
103 | Optional kann ausserdem ein titel fuer den Plot und die Bezeichnung der legendeneintraege
104 | uebergeben werden. Falls bereits ein Plot existiert, steuert plothinzufuegen, ob er
105 | ueberschrieben oder ergaenzt wird.
106 |
SkalarenFieldOutputErstellen(name, session, odbname, referenzAusgabe, beschreibung='', bedingung='data11')
Fuege einen neuen FieldOutput name zur Ausgabedatei odbname der session mit Daten aus
107 | referenzAusgabe hinzu. Die Daten im FieldOutput referenzAusgabe koennen skalare Werte oder
108 | Tensoren sein. Optional kann die Beschreibung angepasst werden. Optional kann ausserdem mit
109 | bedingung ein Kommando zur Kombination der Eintraege ausgefuehrt werden. Fuer einen Ausdruck in
110 | bedingung entsprechen [data11, data22, data33, data12, data13, data23] den sechs Eintraegen
111 | eines Tensorfeldes. Bei einem Skalar entspricht data11 dem Zahlenwert.
112 |  
113 | Fuer mathematische Zusammenhaenge stehen die Funktionen sqrt, sin, cos, tan, asin, acos, atan
114 | zur Verfuegung.
115 |
SpannungsSpurAlsFieldOutput(name, session, odbname, spannungstyp='SVAVG', beschreibung='Spur des Spannungstensors')
Fuege einen neuen FieldOutput namens name zur Ausgabedatei odbname der session mit der
116 | Spur des Spannungstensors hinzu. Als spannungstyp kann zwischen 'S' und 'SVAVG'
117 | unterschieden werden. Optional kann ausserdem die Beschreibung angepasst werden.
118 |
StandardFarben()
Gebe den Vektor mit den Standardfarben und deren Reihenfolge in Abaqus aus.
119 |
Ueberlagerung(session, ebenen, versteckteSets=[], versteckteInstances=[], verschiebung=0.0)
Erstelle mehrere Darstellungsebenen im aktiven Viewport der session mit den Bezeichnungen
120 | ebenen. Basierend auf der Anzeige beim Aufruf der Funktion koennen zusaetzliche Sets (mit vollem
121 | Instance-Pfad) oder/und Instances je Ebene versteckt werden. Optional kann eine globale
122 | Verschiebung der Ebenen zueinander definiert werden.
123 |
VideobilderSpeichern(dateiname, session, odbname, dateityp='png', numzahlen=3, zeitstempel=None, startstep=0, startframe=0, stopstep=-1, stopframe=-1, erstedateinummer=None)
Gebe im aktiven viewport von session alle frames aus allen steps als Bilddaten mit dem
124 | Basisnamen name im Format dateityp aus. Bildbreite und Bildhoehe wird von der aktuellen
125 | Einstellung uebernommen.
126 |  
127 | Um nur eine Unterauswahl an Bildern zu speichern kann ein Intervall mit startstep/startframe
128 | sowie stopstep/stopframe definiert werden. Vorallem dann kann es sich auch anbieten, die
129 | Dateiausgabe nicht bei ihrem natuerlichen Start, sondern bei 0 starten zu lassen, indem
130 | erstedateinummer=0 gesetzt wird.
131 |
ViewportBemassung(db, viewport, bezeichnung, punkt1, punkt2, offset, groesse=180)
Bemasse eine Laenge eines Bauteils einer odb (db=odb.userData) oder mdb (db=mdb) im viewport
132 | zwischen punkt1 und punkt2. Die Bemassung benoetigt ein offset zur Bemassungslinie und bekommt
133 | intern die angegebene bezeichnung zugewiesen. Optional kann die groesse der Schrift der Bemassung
134 | angepasst werden. Gibt die Namen der vier erzeugten Annotationen zurueck.
135 |
XYDatenAnElementen(session, odbname, odbinstname, labelliste, zeitpunkt, var, name, beschreibung='')
Erstelle xyDaten namens name (mit beschreibung) aus Daten der in der aktuellen session
136 | geoeffneten odb namens odbname. Die xyDaten werden aus dem FieldOutput der Variable
137 | var=[Variablenname, Komponente] fuer den uebergebenen zeitpunkt aus odbinstname erstellt.
138 | Abhaengig davon, ob var an Elementen oder Knoten definiert ist, wird in labelliste auch eine
139 | Auflistung von Knotenlabels oder Elementlabels erwartet, fuer die die xyDaten erstellt werden
140 | sollen.
141 |
XYDatenSpeichern(dateiname, session, xydatenname, nachkommastellen=4)
Speichert den Datensatz xydatenname des aktiven Viewports von session als csv-Datei dateiname.
142 | Optional kann die Anzahl an nachkommastellen angepasst werden.
143 |
144 | 145 | -------------------------------------------------------------------------------- /abapys/grundkoerper.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | grundkoerper.py v1.3 (2020-02) 4 | """ 5 | 6 | # Copyright 2020-2021 Dominik Zobel. 7 | # All rights reserved. 8 | # 9 | # This file is part of the abapys library. 10 | # abapys is free software: you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation, either version 3 of the License, or 13 | # (at your option) any later version. 14 | # 15 | # abapys is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with abapys. If not, see . 22 | 23 | 24 | # ------------------------------------------------------------------------------------------------- 25 | def Quader(modell, name, laenge, breite, hoehe, materialtyp, gittergroesse, rp=False, 26 | extrasets=False, xypartition=[True, True], viertel=4): 27 | """Erzeuge einen Quader name im modell mit den Abmessungen laenge, breite und hoehe vom Typ 28 | materialtyp (Abaqus-Konstante, bspw. DEFORMABLE_BODY) und der Netzgroesse gittergroesse 29 | (Zahlenwert oder [gitter_x, gitter_y, gitter_z]). laenge und breite koennen entweder als 30 | Zahlenwert für eine symmetrische Anordnung um den Ursprung (wird transformiert zu 31 | [-zahl/2.0, zahl/2.0]) oder direkt als (startpunkt, endpunkt) uebergeben werden. Optional kann 32 | ein Referenzpunkt rp oder extrasets erstellt werden. Wenn gewuenscht, kann mit xypartition die 33 | Erzeugung der Standardpartitionen in x- oder y-Richtung unterdrueckt werden. 34 | 35 | Neben einem Quader mit den Werten in laenge und breite kann ueber viertel auch ein (Teil-)Quader 36 | erzeugt werden (nur die Werte 1, 2 und 4 werden unterstuetzt). In dem Fall werden Partitionen in 37 | der Schnittebene nicht erzeugt (unabhaengig von den Angaben in xypartition). 38 | Gibt [part, inst] zurueck. 39 | """ 40 | import assembly 41 | from abaqusConstants import ON 42 | # 43 | laenge, breite = _Quader_Einheitliche_Geometrieangaben(laenge=laenge, breite=breite); 44 | xPartition, yPartition = xypartition; 45 | if (viertel == 1): 46 | laenge[0] = (laenge[0]+laenge[1])/2.0; 47 | breite[0] = (breite[0]+breite[1])/2.0; 48 | xPartition = False; 49 | yPartition = False; 50 | elif (viertel == 2): 51 | laenge[0] = (laenge[0]+laenge[1])/2.0; 52 | xPartition = False; 53 | # 54 | if ((laenge[0] > 0.0) or (laenge[1] < 0.0)): 55 | xPartition = False; 56 | # 57 | if ((breite[0] > 0.0) or (breite[1] < 0.0)): 58 | yPartition = False; 59 | # 60 | Quader_erstellen(modell=modell, name=name, laenge=laenge, breite=breite, hoehe=hoehe, 61 | materialtyp=materialtyp); 62 | Grundkoerper_standardpartitionen(modell=modell, name=name, 63 | xPartition=xPartition, yPartition=yPartition, zPartition=False, rp=rp); 64 | Grundkoerper_sets(modell=modell, name=name); 65 | if (extrasets): 66 | Quader_flaechensets(modell=modell, name=name, laenge=laenge, breite=breite, hoehe=hoehe); 67 | # 68 | Grundkoerper_vernetzen(modell=modell, name=name, materialtyp=materialtyp, 69 | gittergroesse=gittergroesse); 70 | # 71 | instname = 'inst' + name; 72 | modell.rootAssembly.Instance(dependent=ON, name=instname, part=modell.parts[name]); 73 | return [modell.parts[name], modell.rootAssembly.instances[instname]]; 74 | # 75 | 76 | 77 | # ------------------------------------------------------------------------------------------------- 78 | def Quader_erstellen(modell, name, laenge, breite, hoehe, materialtyp): 79 | """Erzeuge ein quaderfoermiges Bauteil (Part) name im modell mit den Abmessungen laenge, breite 80 | und hoehe vom Typ materialtyp (Abaqus-Konstante, bspw. DEFORMABLE_BODY). 81 | """ 82 | import sketch 83 | import part 84 | from abaqusConstants import THREE_D 85 | from zeichnung import Rechteck 86 | # 87 | laenge, breite = _Quader_Einheitliche_Geometrieangaben(laenge=laenge, breite=breite); 88 | zeichengroesse = 2.0*max([abs(val) for val in laenge + breite]); 89 | modell.ConstrainedSketch(name='__profile__', sheetSize=zeichengroesse); 90 | zeichnung = modell.sketches['__profile__']; 91 | Rechteck(zeichnung=zeichnung, punkt1=(laenge[0], breite[0]), punkt2=(laenge[1], breite[1])); 92 | modell.Part(dimensionality=THREE_D, name=name, type=materialtyp); 93 | modell.parts[name].BaseSolidExtrude(depth=hoehe, sketch=zeichnung); 94 | del zeichnung; 95 | # 96 | 97 | 98 | # ------------------------------------------------------------------------------------------------- 99 | def Quader_flaechensets(modell, name, laenge, breite, hoehe): 100 | """Erzeuge Flaechensets an der Oberseite, Unterseite und allen Seiten des Quaderbauteils (Part) 101 | name im modell. Zur richtigen Zuordnung werden die Abmessungen laenge, breite und hoehe des 102 | Quaders benoetigt. laenge und breite koennen entweder als Zahlenwert für eine symmetrische 103 | Anordnung um den Ursprung (-zahl/2.0, zahl/2.0) oder direkt als (startpunkt, endpunkt) uebergeben 104 | werden. Die hoehe wird als Zahlenwert erwartet und immer von Null an gestartet. 105 | """ 106 | import part 107 | from auswahl import BedingteAuswahl 108 | from hilfen import abapys_tol 109 | # 110 | laenge, breite = _Quader_Einheitliche_Geometrieangaben(laenge=laenge, breite=breite); 111 | partQuader = modell.parts[name]; 112 | # 113 | flaechen_Unterseite = BedingteAuswahl(elemente=partQuader.faces, 114 | bedingung='elem.pointOn[0][2] < var[0]', var=[abapys_tol]); 115 | partQuader.Set(name='setUnterseite', faces=flaechen_Unterseite); 116 | flaechen_Oberseite = BedingteAuswahl(elemente=partQuader.faces, 117 | bedingung='elem.pointOn[0][2] > var[0]-var[1]', var=[hoehe, abapys_tol]); 118 | partQuader.Set(name='setOberseite', faces=flaechen_Oberseite); 119 | # 120 | flaechen_X = BedingteAuswahl(elemente=partQuader.faces, 121 | bedingung='((elem.pointOn[0][0] < var[0]+var[2]) or (elem.pointOn[0][0] > var[1]-var[2]))', 122 | var=[laenge[0], laenge[1], abapys_tol]); 123 | partQuader.Set(name='setXFlaeche', faces=flaechen_X); 124 | flaechen_Y = BedingteAuswahl(elemente=partQuader.faces, 125 | bedingung='((elem.pointOn[0][1] < var[0]+var[2]) or (elem.pointOn[0][1] > var[1]-var[2]))', 126 | var=[breite[0], breite[1], abapys_tol]); 127 | partQuader.Set(name='setYFlaeche', faces=flaechen_Y); 128 | # 129 | 130 | 131 | # ------------------------------------------------------------------------------------------------- 132 | def _Quader_Einheitliche_Geometrieangaben(laenge, breite): 133 | """ 134 | laenge und breite koennen entweder als Zahlenwert für eine symmetrische Anordnung um den Ursprung 135 | (-zahl/2.0, zahl/2.0) oder als (startpunkt, endpunkt) verwendet werden. Diese Funktion stellt 136 | sicher, dass alle Zahlenwerte in Listen mit zwei Einträgen umgewandelt werden. 137 | Gibt [[laenge_start, laenge_ende], [breite_start, breite_ende]] zurueck, sofern laenge und breite 138 | zu Beginn entweder ein Zahlenwert oder [start, ende] waren. 139 | """ 140 | if (not type(laenge) is list): 141 | laenge = [-laenge/2.0, laenge/2.0]; 142 | # 143 | if (not type(breite) is list): 144 | breite = [-breite/2.0, breite/2.0]; 145 | # 146 | return [laenge, breite]; 147 | # 148 | 149 | 150 | # ------------------------------------------------------------------------------------------------- 151 | def Zylinder(modell, name, radius, hoehe, materialtyp, gittergroesse, rp=False, extrasets=False, 152 | r_innen=[], xypartition=[True, True], viertel=4): 153 | """Erzeuge einen Zylinder name im modell mit den Abmessungen radius und hoehe vom Typ materialtyp 154 | (Abaqus-Konstante, bspw. DEFORMABLE_BODY) und der Netzgroesse gittergroesse (Zahlenwert oder 155 | [gitter_r, gitter_h]). Optional kann ein Referenzpunkt rp oder extrasets erstellt werden. 156 | Optional kann ausserdem statt einem Zylinder ein Zylinderring erzeugt werden, wenn r_innen 157 | gegeben ist. 158 | 159 | Neben einem Zylinder(ring) kann auch nur ein Viertel- oder Halbzylinder(ring) ueber viertel 160 | erzeugt werden (nur die Werte 1, 2 und 4 werden unterstuetzt). Falls nur ein halber/viertel 161 | Zylinder erzeugt wird, werden Partitionen in der Schnittebene nicht erzeugt (unabhaengig von den 162 | Angaben in xypartition). Gibt [part, inst] zurueck. 163 | """ 164 | from abaqusConstants import ON 165 | import assembly 166 | # 167 | xPartition, yPartition = xypartition; 168 | if (viertel == 1): 169 | xPartition = False; 170 | yPartition = False; 171 | elif (viertel == 2): 172 | xPartition = False; 173 | # 174 | Zylinder_erstellen(modell=modell, name=name, radius=radius, hoehe=hoehe, 175 | materialtyp=materialtyp, r_innen=r_innen, viertel=viertel); 176 | Grundkoerper_standardpartitionen(modell=modell, name=name, 177 | xPartition=xPartition, yPartition=yPartition, zPartition=False, rp=rp); 178 | Grundkoerper_sets(modell=modell, name=name); 179 | if (extrasets): 180 | Zylinder_flaechensets(modell=modell, name=name, radius=radius, hoehe=hoehe, 181 | r_innen=r_innen, viertel=viertel); 182 | Grundkoerper_vernetzen(modell=modell, name=name, materialtyp=materialtyp, 183 | gittergroesse=gittergroesse); 184 | # 185 | instname = 'inst' + name; 186 | modell.rootAssembly.Instance(dependent=ON, name=instname, part=modell.parts[name]); 187 | return [modell.parts[name], modell.rootAssembly.instances[instname]]; 188 | # 189 | 190 | 191 | # ------------------------------------------------------------------------------------------------- 192 | def Zylinder_erstellen(modell, name, radius, hoehe, materialtyp, r_innen=[], viertel=4): 193 | """Erzeuge ein zylindrisches Bauteil (Part) name im modell mit den Abmessungen radius und hoehe 194 | vom Typ materialtyp (Abaqus-Konstante, bspw. DEFORMABLE_BODY). Falls r_innen gegeben ist, wird 195 | statt einem Zylinder ein Zylinderring mit dem Aussparungsradius r_innen erzeugt. 196 | 197 | Neben einem Zylinder(ring) kann auch nur ein Viertel- oder Halbzylinder(ring) ueber viertel 198 | erzeugt werden. Fuer viertel werden nur die Werte 1,2 und 4 unterstuetzt. 199 | """ 200 | import sketch 201 | import part 202 | from abaqusConstants import CLOCKWISE, THREE_D 203 | from zeichnung import Kreis, Linie, KreisbogenWinkel 204 | # 205 | modell.ConstrainedSketch(name='__profile__', sheetSize=4.0*radius); 206 | zeichnung = modell.sketches['__profile__']; 207 | if (viertel == 1): 208 | hilfspunkt = 0.0; 209 | if (not (r_innen == [])): 210 | hilfspunkt = r_innen; 211 | KreisbogenWinkel(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), radius=r_innen, 212 | startwinkel=0.0, endwinkel=90.0, richtung=CLOCKWISE); 213 | # 214 | Linie(zeichnung=zeichnung, punkt1=(radius, 0.0), punkt2=(hilfspunkt, 0.0)); 215 | Linie(zeichnung=zeichnung, punkt1=(0.0, hilfspunkt), punkt2=(0.0, radius)); 216 | KreisbogenWinkel(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), radius=radius, 217 | startwinkel=0.0, endwinkel=90.0, richtung=CLOCKWISE); 218 | elif (viertel == 2): 219 | hilfspunkt = -radius; 220 | if (not (r_innen == [])): 221 | hilfspunkt = r_innen; 222 | KreisbogenWinkel(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), radius=r_innen, 223 | startwinkel=0.0, endwinkel=180.0, richtung=CLOCKWISE); 224 | Linie(zeichnung=zeichnung, punkt1=(0.0, -radius), punkt2=(0.0, -r_innen)); 225 | # 226 | Linie(zeichnung=zeichnung, punkt1=(0.0, hilfspunkt), punkt2=(0.0, radius)); 227 | KreisbogenWinkel(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), radius=radius, 228 | startwinkel=0.0, endwinkel=180.0, richtung=CLOCKWISE); 229 | else: 230 | Kreis(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), radius=radius); 231 | if (not (r_innen == [])): 232 | Kreis(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), radius=r_innen); 233 | # 234 | modell.Part(dimensionality=THREE_D, name=name, type=materialtyp); 235 | modell.parts[name].BaseSolidExtrude(depth=hoehe, sketch=zeichnung); 236 | del zeichnung; 237 | # 238 | 239 | 240 | # ------------------------------------------------------------------------------------------------- 241 | def Zylinder_flaechensets(modell, name, radius, hoehe, r_innen=[], viertel=4): 242 | """Erzeuge Flaechensets an der Oberseite, Unterseite und Mantel des Zylinderbauteils (Part) name 243 | im modell. Zur richtigen Zuordnung werden radius und hoehe des Zylinders benoetigt. Falls nur ein 244 | Viertel-/Halbzylinder erzeugt werden soll, werden zusaetzliche Sets erstellt. 245 | """ 246 | import part 247 | from auswahl import BedingteAuswahl 248 | from hilfen import abapys_tol 249 | # 250 | partZylinder = modell.parts[name]; 251 | # 252 | flaechen_Unterseite = BedingteAuswahl(elemente=partZylinder.faces, 253 | bedingung='elem.pointOn[0][2] < var[0]', var=[abapys_tol]); 254 | partZylinder.Set(name='setUnterseite', faces=flaechen_Unterseite); 255 | flaechen_Oberseite = BedingteAuswahl(elemente=partZylinder.faces, 256 | bedingung='elem.pointOn[0][2] > var[0]-var[1]', var=[hoehe, abapys_tol]); 257 | partZylinder.Set(name='setOberseite', faces=flaechen_Oberseite); 258 | # 259 | flaechen_Mantel = BedingteAuswahl(elemente=partZylinder.faces, 260 | bedingung='sqrt(elem.pointOn[0][0]**2 + elem.pointOn[0][1]**2) > var[0]-var[1]', 261 | var=[radius, abapys_tol]); 262 | partZylinder.Set(name='setMantelflaeche', faces=flaechen_Mantel); 263 | if ((viertel == 1) or (viertel == 2)): 264 | if (viertel == 1): 265 | flaechen_Y = BedingteAuswahl(elemente=partZylinder.faces, 266 | bedingung='(elem.pointOn[0][1] < var[0])', var=[abapys_tol]); 267 | partZylinder.Set(name='setYFlaeche', faces=flaechen_Y); 268 | # 269 | flaechen_X = BedingteAuswahl(elemente=partZylinder.faces, 270 | bedingung='(elem.pointOn[0][0] < var[0])', var=[abapys_tol]); 271 | partZylinder.Set(name='setXFlaeche', faces=flaechen_X); 272 | # 273 | if (not r_innen == []): 274 | flaechen_Mantelinnen = BedingteAuswahl(elemente=partZylinder.faces, 275 | bedingung='sqrt(elem.pointOn[0][0]**2 + elem.pointOn[0][1]**2) < var[0]+var[1]', 276 | var=[r_innen, abapys_tol]); 277 | partZylinder.Set(name='setMantelinnen', faces=flaechen_Mantelinnen); 278 | # 279 | 280 | 281 | # ------------------------------------------------------------------------------------------------- 282 | def Kugel(modell, name, radius, materialtyp, gittergroesse, rp=False, extrasets=False, r_innen=[]): 283 | """Erzeuge eine Kugel name im modell mit dem uebergebenem radius vom Typ materialtyp 284 | (Abaqus-Konstante, bspw. DEFORMABLE_BODY) und der Netzgroesse gittergroesse (Zahlenwert). 285 | Optional kann ein Referenzpunkt rp oder extrasets erstellt werden. Optional kann ausserdem statt 286 | einer Vollkugel eine Hohlkugel erzeugt werden, wenn r_innen gegeben ist. 287 | Gibt [part, inst] zurueck. 288 | """ 289 | import part 290 | import assembly 291 | from abaqusConstants import TET, FREE, ON 292 | from auswahl import BedingteAuswahl 293 | from hilfen import abapys_tol 294 | # 295 | Kugel_erstellen(modell=modell, name=name, radius=radius, 296 | materialtyp=materialtyp, r_innen=r_innen); 297 | partKugel = modell.parts[name]; 298 | Grundkoerper_standardpartitionen(modell=modell, name=name, rp=rp); 299 | Grundkoerper_sets(modell=modell, name=name); 300 | if (extrasets): 301 | flaechen_Mantel = BedingteAuswahl(elemente=partKugel.faces, 302 | bedingung='sqrt(elem.pointOn[0][0]**2 + elem.pointOn[0][1]**2 + elem.pointOn[0][2]**2)) > var[0]-var[1]', 303 | var=[radius, abapys_tol]); 304 | partKugel.Set(name='setMantelflaeche', faces=flaechen_Mantel); 305 | # 306 | # FIXME: Immer notwendig, Kugeln als TET zu diskretisieren? 307 | partKugel.setMeshControls(elemShape=TET, regions=partKugel.cells, technique=FREE); 308 | Grundkoerper_vernetzen(modell=modell, name=name, materialtyp=materialtyp, 309 | gittergroesse=gittergroesse); 310 | # 311 | instname = 'inst' + name; 312 | modell.rootAssembly.Instance(dependent=ON, name=instname, part=partKugel); 313 | return [partKugel, modell.rootAssembly.instances[instname]]; 314 | # 315 | 316 | 317 | # ------------------------------------------------------------------------------------------------- 318 | def Kugel_erstellen(modell, name, radius, materialtyp, r_innen=[]): 319 | """Erzeuge eine Kugel (Part) name im Modell modell mit uebergebenem radius und vom Typ 320 | materialtyp (Abaqus-Konstante, bspw. DEFORMABLE_BODY). Erzeuge eine Hohlkugel, falls r_innen 321 | gegeben ist. 322 | """ 323 | import sketch 324 | import part 325 | from abaqusConstants import CLOCKWISE, THREE_D, OFF 326 | from zeichnung import Linie, KreisbogenWinkel 327 | # 328 | modell.ConstrainedSketch(name='__profile__', sheetSize=4.0*radius); 329 | zeichnung = modell.sketches['__profile__']; 330 | zeichnung.ConstructionLine(point1=(0.0, -radius), point2=(0.0, radius)); 331 | zeichnung.FixedConstraint(entity=zeichnung.geometry.findAt((0.0, 0.0), )); 332 | # 333 | KreisbogenWinkel(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), radius=radius, 334 | startwinkel=0.0, endwinkel=180.0, richtung=CLOCKWISE); 335 | if (not (r_innen == [])): 336 | Linie(zeichnung=zeichnung, punkt1=(0.0, radius), punkt2=(0.0, r_innen)); 337 | KreisbogenWinkel(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), radius=r_innen, 338 | startwinkel=0.0, endwinkel=180.0, richtung=CLOCKWISE); 339 | Linie(zeichnung=zeichnung, punkt1=(0.0, -radius), punkt2=(0.0, -r_innen)); 340 | else: 341 | Linie(zeichnung=zeichnung, punkt1=(0.0, radius), punkt2=(0.0, -radius)); 342 | # 343 | modell.Part(dimensionality=THREE_D, name=name, type=materialtyp); 344 | modell.parts[name].BaseSolidRevolve(angle=360.0, flipRevolveDirection=OFF, sketch=zeichnung); 345 | del zeichnung; 346 | # 347 | 348 | 349 | # ------------------------------------------------------------------------------------------------- 350 | def Rotationsprofil_erstellen(modell, name, punkte, materialtyp, viertel=4): 351 | """Erzeuge durch eine Drehung um viertel*90 Grad ein Bauteil (Part) name im modell aus den 352 | Koordinaten aus punkte vom Typ materialtyp (Abaqus-Konstante, bspw. DEFORMABLE_BODY). Die in 353 | punke uebergebenen Tupel an x- und y-Koordinaten bilden eine Linie, wobei der letzte Punkt 354 | automatisch mit dem ersten verbunden wird. Fuer die Drehung (um die y-Achse der Zeichnung) 355 | muessen alle x-Koordinaten der Punkte >= 0 sein. 356 | Fuer viertel werden nur die Werte 1,2 und 4 unterstuetzt. 357 | """ 358 | import sketch 359 | import part 360 | from abaqusConstants import CLOCKWISE, THREE_D, ON 361 | from zeichnung import Linienzug 362 | # 363 | maxwert = max([max(abs(x), abs(y)) for x, y in punkte]); 364 | zeichnung = modell.ConstrainedSketch(name='__profile__', sheetSize=2.0*maxwert, 365 | transform=(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0)); 366 | zeichnung.ConstructionLine(point1=(0.0, -100.0), point2=(0.0, 100.0)); 367 | Linienzug(zeichnung=zeichnung, punkte=punkte, geschlossen=True); 368 | modell.Part(dimensionality=THREE_D, name=name, type=materialtyp); 369 | modell.parts[name].BaseSolidRevolve(sketch=zeichnung, angle=viertel*90.0, flipRevolveDirection=ON); 370 | del zeichnung; 371 | # 372 | 373 | 374 | # ------------------------------------------------------------------------------------------------- 375 | def Grundkoerper_standardpartitionen(modell, name, xPartition=True, yPartition=True, zPartition=True, 376 | rp=False): 377 | """Erstelle die typischen Datums und Partitionen am Bauteil (Part) name im modell. Optional kann 378 | die Erstellung einzelner Partitionen mit (x-/y-/z-Partition) unterdrueckt werden. Wenn rp=True 379 | uebergeben wird, wird zusaetzlich einen Referenzpunkt im Ursprung erstellt. 380 | """ 381 | import part 382 | from abaqusConstants import XAXIS, YAXIS, ZAXIS 383 | # 384 | partGrundkoerper = modell.parts[name]; 385 | # 386 | partGrundkoerper.DatumPointByCoordinate(coords=(0.0, 0.0, 0.0)); 387 | partGrundkoerper.features.changeKey(fromName='Datum pt-1', toName='datum_Ursprung'); 388 | datumid = partGrundkoerper.features['datum_Ursprung'].id; 389 | # 390 | partGrundkoerper.DatumAxisByPrincipalAxis(principalAxis=XAXIS); 391 | partGrundkoerper.features.changeKey(fromName='Datum axis-1', toName='xAchse'); 392 | xachsenid = partGrundkoerper.features['xAchse'].id; 393 | partGrundkoerper.DatumAxisByPrincipalAxis(principalAxis=YAXIS); 394 | partGrundkoerper.features.changeKey(fromName='Datum axis-1', toName='yAchse'); 395 | yachsenid = partGrundkoerper.features['yAchse'].id; 396 | partGrundkoerper.DatumAxisByPrincipalAxis(principalAxis=ZAXIS); 397 | partGrundkoerper.features.changeKey(fromName='Datum axis-1', toName='zAchse'); 398 | zachsenid = partGrundkoerper.features['zAchse'].id; 399 | # 400 | if (xPartition): 401 | partGrundkoerper.PartitionCellByPlanePointNormal(cells=partGrundkoerper.cells, 402 | normal=partGrundkoerper.datums[xachsenid], point=partGrundkoerper.datums[datumid]); 403 | # 404 | if (yPartition): 405 | partGrundkoerper.PartitionCellByPlanePointNormal(cells=partGrundkoerper.cells, 406 | normal=partGrundkoerper.datums[yachsenid], point=partGrundkoerper.datums[datumid]); 407 | # 408 | if (zPartition): 409 | partGrundkoerper.PartitionCellByPlanePointNormal(cells=partGrundkoerper.cells, 410 | normal=partGrundkoerper.datums[zachsenid], point=partGrundkoerper.datums[datumid]); 411 | # 412 | if (rp): 413 | partGrundkoerper.ReferencePoint(point=(0.0, 0.0, 0.0)); 414 | partGrundkoerper.features.changeKey(fromName='RP', toName='RP_' + name); 415 | # 416 | 417 | 418 | # ------------------------------------------------------------------------------------------------- 419 | def Grundkoerper_sets(modell, name): 420 | """Erstelle die Hauptsets fuer das Bauteil (Part) name im modell. 421 | """ 422 | import part 423 | # 424 | partGrundkoerper = modell.parts[name]; 425 | partGrundkoerper.Set(cells=partGrundkoerper.cells, name='setAll'); 426 | rpname = 'RP_' + name; 427 | if (partGrundkoerper.features.has_key(rpname)): 428 | rpid = partGrundkoerper.features[rpname].id; 429 | partGrundkoerper.Set(name='setRP', referencePoints=(partGrundkoerper.referencePoints[rpid], )); 430 | # 431 | 432 | 433 | # ------------------------------------------------------------------------------------------------- 434 | def Grundkoerper_vernetzen(modell, name, materialtyp, gittergroesse): 435 | """Erzeuge ein Standardnetz fuer das Bauteil (Part) name im modell. materialtyp wird fuer die 436 | Zuweisung der korrekten Elemente benoetigt (Abaqus-Konstante, bspw. DEFORMABLE_BODY). Das Mesh 437 | kann ueber gittergroesse (Zahlenwert, [gitter_r, gitter_h] oder [gitter_x, gitter_y, gitter_z]) 438 | angepasst werden. 439 | """ 440 | import part 441 | import mesh 442 | from abaqusConstants import EULERIAN, EXPLICIT, OFF, EC3D8R, UNKNOWN_TET, UNKNOWN_WEDGE, DEFAULT 443 | from abaqusConstants import C3D8R, AVERAGE_STRAIN, C3D6, C3D4, FINER 444 | from auswahl import ZweifachbedingteKantenAuswahl 445 | # 446 | partGrundkoerper = modell.parts[name]; 447 | # 448 | if (materialtyp == EULERIAN): 449 | partGrundkoerper.setElementType(elemTypes=( 450 | mesh.ElemType(elemCode=EC3D8R, elemLibrary=EXPLICIT, secondOrderAccuracy=OFF), 451 | mesh.ElemType(elemCode=UNKNOWN_WEDGE, elemLibrary=EXPLICIT), 452 | mesh.ElemType(elemCode=UNKNOWN_TET, elemLibrary=EXPLICIT)), 453 | regions=partGrundkoerper.sets['setAll']); 454 | else: 455 | partGrundkoerper.setElementType(elemTypes=( 456 | mesh.ElemType(elemCode=C3D8R, elemLibrary=EXPLICIT, secondOrderAccuracy=OFF, 457 | kinematicSplit=AVERAGE_STRAIN, hourglassControl=DEFAULT, 458 | distortionControl=DEFAULT), mesh.ElemType(elemCode=C3D6, elemLibrary=EXPLICIT, 459 | secondOrderAccuracy=OFF, distortionControl=DEFAULT), mesh.ElemType( 460 | elemCode=C3D4, elemLibrary=EXPLICIT, secondOrderAccuracy=OFF, 461 | distortionControl=DEFAULT)), regions=partGrundkoerper.sets['setAll']); 462 | # 463 | if (isinstance(gittergroesse, list)): 464 | if (len(gittergroesse) == 2): 465 | gitter_r, gitter_h = gittergroesse; 466 | # Initialisiere mit Mittelwert aus allen drei Werten 467 | partGrundkoerper.seedPart(size=(gitter_r + gitter_h)/2.0, deviationFactor=0.1, 468 | minSizeFactor=0.1); 469 | kanten_r, kanten_h = ZweifachbedingteKantenAuswahl(elemente=partGrundkoerper, 470 | bedingung3='(vert1.pointOn[0][2] == vert2.pointOn[0][2])'); 471 | partGrundkoerper.seedEdgeBySize(constraint=FINER, deviationFactor=0.1, edges=kanten_r, 472 | minSizeFactor=0.1, size=gitter_r); 473 | partGrundkoerper.seedEdgeBySize(constraint=FINER, deviationFactor=0.1, edges=kanten_h, 474 | minSizeFactor=0.1, size=gitter_h); 475 | else: 476 | gitter_x, gitter_y, gitter_z = gittergroesse; 477 | # Initialisiere mit Mittelwert aus allen drei Werten 478 | partGrundkoerper.seedPart(size=(gitter_x + gitter_y + gitter_z)/3.0, deviationFactor=0.1, 479 | minSizeFactor=0.1); 480 | kanten_x = ZweifachbedingteKantenAuswahl(elemente=partGrundkoerper, 481 | bedingung2='(vert1.pointOn[0][1] == vert2.pointOn[0][1]) and (vert1.pointOn[0][2] == vert2.pointOn[0][2])'); 482 | partGrundkoerper.seedEdgeBySize(constraint=FINER, deviationFactor=0.1, edges=kanten_x[0], 483 | minSizeFactor=0.1, size=gitter_x); 484 | kanten_y = ZweifachbedingteKantenAuswahl(elemente=partGrundkoerper, 485 | bedingung2='(vert1.pointOn[0][0] == vert2.pointOn[0][0]) and (vert1.pointOn[0][2] == vert2.pointOn[0][2])'); 486 | partGrundkoerper.seedEdgeBySize(constraint=FINER, deviationFactor=0.1, edges=kanten_y[0], 487 | minSizeFactor=0.1, size=gitter_y); 488 | kanten_z = ZweifachbedingteKantenAuswahl(elemente=partGrundkoerper, 489 | bedingung2='(vert1.pointOn[0][0] == vert2.pointOn[0][0]) and (vert1.pointOn[0][1] == vert2.pointOn[0][1])'); 490 | partGrundkoerper.seedEdgeBySize(constraint=FINER, deviationFactor=0.1, edges=kanten_z[0], 491 | minSizeFactor=0.1, size=gitter_z); 492 | else: 493 | partGrundkoerper.seedPart(size=gittergroesse, deviationFactor=0.1, minSizeFactor=0.1); 494 | # 495 | partGrundkoerper.generateMesh(); 496 | # 497 | --------------------------------------------------------------------------------