def KnotenAuswahlLabelliste(knoten, sortierung=0, aufsteigend=True): """Sortiert alle uebergebenen knoten nach der Koordinatenrichtung sortierung basierend auf den jeweiligen Koordinaten. Fuer die sortierung ist die jeweilige Richtung (0, 1 oder 2) anzugeben. Die Reihenfolge wird ueber die Koordinaten der Mittelpunkte der Elemente bestimmt. Die Werte koennen entweder aufsteigend oder absteigend sortiert werden. """ from operator import itemgetter # tempsortierung = sortierung; if ((not (sortierung == 0)) and (not (sortierung == 1)) and (not (sortierung == 2))): Log('# Warnung: Ungueltige sortierung, nehme sortierung = 0'); tempsortierung = 0; # if (len(knoten) == 0): Log('# Hinweis: Keine Knoten uebergeben'); return []; # templiste = []; for einzelpunkt in knoten: templiste += [(einzelpunkt.coordinates[tempsortierung], einzelpunkt.label), ]; # templiste.sort(key=itemgetter(0)); labelliste = [x[1] for x in templiste]; if (aufsteigend): return labelliste; else: return list(reversed(labelliste));
def _FieldOutputVariablenliste(bezugsframe, variablenliste): """Erstelle anhand der uebergebenen variablenliste mit ggfs. nicht exakten Namen von FieldOutputs eine modifizierte Liste mit den exakten Namen vorhandener FieldOutputs, die weiter verwendet werden. Gibt die ueberarbeitete variablenliste zurueck. Falls der Eintrag in variablenliste mehreren FieldOutputs entspricht (bspw. "SDV", die alle als einzelne FieldOutputs gespeichert werden), dann erstelle eine Unterliste mit allen FieldOutputs, in deren Namen Eintrag vorkommt. """ from hilfen import Log # exakte_variablenliste = []; for variable in variablenliste: if (bezugsframe.fieldOutputs.has_key(variable)): exakte_variablenliste += [variable]; else: unterliste = []; for outputvariable in bezugsframe.fieldOutputs.keys(): if (variable in outputvariable): if (not (variable == 'SDV')): Log('# Warnung: Angeforderte Variable >' + variable + '< nicht einzeln vorhanden aber im Namen von : ' + outputvariable); # unterliste += [outputvariable]; # if (unterliste == []): Log('# Abbruch: Angeforderte Variable >' + variable + '< nicht im angegebenen Schritt/Frame der odb verfuegbar'); return []; else: exakte_variablenliste += [unterliste]; # return exakte_variablenliste;
def ElementAuswahlLabelliste(elemente, punktliste, sortierung=0, aufsteigend=True, listenhilfe=[]): """Sortiert alle uebergebenen elemente nach der Koordinatenrichtung sortierung basierend auf den Koordinaten des Elementmittelpunktes. Fuer die Berechnung der Mittelpunktkoordinaten werden die Knoten der Elemente benutzt. Fuer die Zuordnung der einzelnen Punkte zu den Elementen muss eine punktliste uebergeben werden, die alle Punkte aller elemente enthaelt. Gibt eine Liste der Labels aller uebergebenen elemente zurueck, deren Mittelpunkte nach der Koordinatenrichtung sortierung sortiert ist. Fuer die sortierung ist die jeweilige Richtung (0, 1 oder 2) anzugeben. Die Reihenfolge wird ueber die Koordinaten der Mittelpunkte der Elemente bestimmt. Die Werte koennen entweder aufsteigend oder absteigend sortiert werden. Optional kann die korrekte Zuordnung der Labels der Punkte bei odb-elementen durch Uebergabe einer listenhilfe beschleunigt werden. WICHTIG: Wenn Elemente einer mdb statt einer odb untersucht werden sollen, sollte entweder keine oder die folgende listenhilfe uebergeben werden: listenhilfe = [idx for idx in range(len(punktliste))]; """ from operator import itemgetter from hilfen import Log, ElementAusOdb, ErstelleLabelsortierteGeomlist # tempsortierung = sortierung; if ((not (sortierung == 0)) and (not (sortierung == 1)) and (not (sortierung == 2))): Log('# Warnung: Ungueltige sortierung, nehme sortierung = 0'); tempsortierung = 0; # if (len(elemente) == 0): Log('# Hinweis: Keine Elemente uebergeben'); return []; # if (listenhilfe == []): if (ElementAusOdb(element=elemente[0])): listenhilfe = ErstelleLabelsortierteGeomlist(geomliste=punktliste); else: listenhilfe = [idx for idx in range(len(punktliste))]; # templiste = []; anzahlpunkte = float(len(elemente[0].connectivity)); for elem in elemente: mittelwert = 0; for punktlabel in elem.connectivity: punkt = punktliste[listenhilfe[punktlabel]]; mittelwert = punkt.coordinates[tempsortierung]/anzahlpunkte; # templiste += [(mittelwert, elem.label), ]; # templiste.sort(key=itemgetter(0)); labelliste = [x[1] for x in templiste]; if (aufsteigend): return labelliste; else: return list(reversed(labelliste));
def _ZustandsuebertragungAusgabeVorbereiten(mdbname, ausgabevariable, bezugsframe=None): rueckgabe = [None, None, None]; """Je nach ausgabevariable entsprechende Dateinamen und keywordBlock-Eintraege vorbereiten. Falls ein bezugsframe uebergeben wird werden die entsprechenden odbergebnisse ermittelt, ansonsten wird dafuer None angenommen. Gibt [ausgabedatei, ausgabetext, odbergebnisse] zurueck. """ from abaqusConstants import DOUBLE_PRECISION from hilfen import Log # odbergebnisse = None; if (isinstance(ausgabevariable, list)): if ('SDV' in ausgabevariable[0]): ausgabedatei = mdbname + '_sdv.add'; ausgabetext = '*Initial Conditions, type=SOLUTION, input=' + ausgabedatei; else: Log('Warnung: Variablenliste ausser SDV nicht unterstuetzt'); return rueckgabe; # if (bezugsframe is not None): # Da nicht nur ein FieldOutput sondern eine Liste an FieldOutputs betrachtet werden soll # (d.h. SDVs sollen zusammengefasst werden), erzeuge eine kuenstliche odbergebnisse-Struktur odbergebnisse = []; num_values = len(bezugsframe.fieldOutputs[ausgabevariable[0]].values); for idx_val in range(num_values): tempdata = None; tempdataDouble = None; tempergebnis = bezugsframe.fieldOutputs[ausgabevariable[0]].values[idx_val]; if (tempergebnis.precision == DOUBLE_PRECISION): tempdataDouble = [bezugsframe.fieldOutputs[einzelvar].values[idx_val].dataDouble for einzelvar in ausgabevariable]; else: tempdata = [bezugsframe.fieldOutputs[einzelvar].values[idx_val].data for einzelvar in ausgabevariable]; # odbergebnisse += [FieldOutputValue(precision=tempergebnis.precision, data=tempdata, dataDouble=tempdataDouble, elementLabel=tempergebnis.elementLabel, nodeLabel=tempergebnis.nodeLabel)]; else: if (ausgabevariable == 'S'): ausgabedatei = mdbname + '_s.add'; ausgabetext = '*Initial Conditions, type=STRESS, input=' + ausgabedatei; elif (ausgabevariable == 'SVAVG'): ausgabedatei = mdbname + '_svavg.add'; ausgabetext = '*Initial Conditions, type=STRESS, input=' + ausgabedatei; elif (ausgabevariable == 'EVF'): ausgabedatei = mdbname + '_evf.add'; ausgabetext = '*Initial Conditions, type=VOLUME FRACTION, input=' + ausgabedatei; else: Log('Warnung: Uebertragung von ' + ausgabevariable + ' nicht getestet - sorgfaeltig pruefen'); ausgabedatei = mdbname + '_' + ausgabevariable.lower() + '.add'; ausgabetext = '*Initial Conditions, type=FIELD, Variable=' + ausgabevariable + ', input=' + ausgabedatei; # if (bezugsframe is not None): odbergebnisse = bezugsframe.fieldOutputs[ausgabevariable].values; # return [ausgabedatei, ausgabetext, odbergebnisse];
def _Bodenparameter_Aus_Tabelle(name, bezeichnung='labor'): """Lade fuer den Boden name die Bodenparameter nach dem stoffgesetz aus der hinterlegten Datei "Materialdatenbank.xlsx". Gibt [eintragVorhanden, bodenwerte, standardwerte] zurueck. """ from hilfen import Log dateiname = _Name_Aktuellste_Materialdatenbank() if (dateiname is None): return [[], [], []] # try: from openpyxl import load_workbook except: Log('# Fehler: openpyxl (und Abhaengigkeiten) zum Laden von xlsx-Dateien nicht gefunden' ) return [[], [], []] # try: xlsxfile = load_workbook(filename=dateiname, read_only=True) except: Log('# Fehler: Konnte Materialdatenbank ' + dateiname + ' nicht laden') return [[], [], []] # xlsxsheet = xlsxfile['Materialdatenbank'] eintragVorhanden = False # anzahlZellen = 39 standardwerte = anzahlZellen * [''] bodenwerte = anzahlZellen * [''] for zeile in xlsxsheet.rows: zeile_bodenname = zeile[0].value if (zeile_bodenname is None): continue # if (zeile_bodenname == 'Standardparameter'): for iZelle in range(anzahlZellen): standardwerte[iZelle] = zeile[iZelle].value # if (str(zeile_bodenname) == name): zeile_bezeichnung = zeile[1].value if ((str(zeile_bezeichnung) == bezeichnung) or (((bezeichnung == 'labor') or (bezeichnung == '')) and ((zeile_bezeichnung is None) or (zeile_bezeichnung == 'labor')))): # eintragVorhanden = True for iZelle in range(anzahlZellen): bodenwerte[iZelle] = zeile[iZelle].value # break # return [eintragVorhanden, bodenwerte, standardwerte]
def _Bohrprofil_vernetzen(modell, name, gitter): """Erzeuge ein Netz fuer das Bauteil (Part) name im modell mit der Netzfeinheit gitter. """ import part import mesh from abaqusConstants import UNKNOWN_HEX, UNKNOWN_WEDGE, EXPLICIT, C3D10M, TET, FREE, OFF, DEFAULT from hilfen import Log # partWerkzeug = modell.parts[name] # Sets partWerkzeug.Set(name='setAll', cells=partWerkzeug.cells) partWerkzeug.Set( name='setRP', referencePoints=( partWerkzeug.referencePoints[partWerkzeug.features['RP'].id], )) # Elementtypen anpassen partWerkzeug.setElementType( elemTypes=(mesh.ElemType(elemCode=UNKNOWN_HEX, elemLibrary=EXPLICIT), mesh.ElemType(elemCode=UNKNOWN_WEDGE, elemLibrary=EXPLICIT), mesh.ElemType(elemCode=C3D10M, elemLibrary=EXPLICIT, secondOrderAccuracy=OFF, distortionControl=DEFAULT)), regions=partWerkzeug.sets['setAll']) # Mesh partWerkzeug.setMeshControls(elemShape=TET, regions=partWerkzeug.cells, technique=FREE) partWerkzeug.seedPart(deviationFactor=0.1, minSizeFactor=0.1, size=gitter) partWerkzeug.generateMesh() if (len(partWerkzeug.elements) == 0): Log('Warnung: Mesh-Erstellung zu ' + name + ' fehlgeschlagen')
def _MdbElementAuswahl(elemente, punktliste, bedingung='True', var=[]): """Gib eine Sequenz an Elementen aus den uebergebenen elemente zurueck, die bzw. deren Punkte die bedingung erfuellen (nur mdb). Fuer die Zuordnung der einzelnen Punkte zu den Elementen muss eine punktliste uebergeben werden, die alle Punkte aller elemente enthaelt. Gibt die Sequenz der ausgewaehlten Elemente zurueck. In der Bedingung kann mit elem auf ein einzelnes Element und mit punkt auf einen Punkt des Elements zugegriffen werden. Die Koordinaten eines Punktes koennen mit punkt.coordinates[#] erhalten werden, wobei die Raute fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht. """ from math import pi, sqrt, sin, cos, tan, asin, acos, atan from hilfen import Log, _Eval_Basispruefung # ausgewaehlteElemente = elemente[0:0]; erlaubt = ['coordinates', 'connectivity', 'featureName', 'index', 'instanceName', 'instanceNames', 'isReferenceRep', 'pointOn', 'sectionCategory', 'label', 'type', 'var', 'elem', 'punkt']; # if (not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=erlaubt)): Log('# Abbruch: Uebergebene bedingung ist ungueltig'); return ausgewaehlteElemente; # numPunkte = len(elemente[0].connectivity); for idx, elem in enumerate(elemente): numErfuellt = 0; for punktidx in elem.connectivity: punkt = punktliste[punktidx]; if (eval(bedingung)): numErfuellt += 1; # if (numErfuellt == numPunkte): ausgewaehlteElemente += elemente[idx:idx+1]; # return ausgewaehlteElemente;
def _BedingteAuswahlLabel(elemente, bedingung='True', var=[]): """Erstelle eine Sequenz aus den Labels aller uebergebenen elemente, die bedingung erfuellen. Alle Variablen aus bedingung muessen global lesbar oder optional in var uebergeben und als var[...] bezeichnet sein, sonst kann die bedingung nicht korrekt ausgewertet werden. Gibt die Sequenz der ausgewaehlten Elemente zurueck. In der Bedingung kann mit elem auf ein einzelnes Element zugegriffen werden. Auf die Basiskoordinaten eines Elementes kann mit elem.coordinates[#] zugegriffen werden, wobei die Raute fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht. """ from math import pi, sqrt, sin, cos, tan, asin, acos, atan from hilfen import Log, _Eval_Basispruefung # erlaubt = ['coordinates', 'connectivity', 'featureName', 'index', 'instanceName', 'instanceNames', 'isReferenceRep', 'pointOn', 'sectionCategory', 'label', 'type', 'var', 'elem']; # if (not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=erlaubt)): Log('# Abbruch: Uebergebene bedingung ist ungueltig'); return elemente[0:0]; # ausgewaehlteLabels = []; for elem in elemente: if (eval(bedingung)): ausgewaehlteLabels += [elem.label]; # return LabelAuswahl(elemente=elemente, labelliste=ausgewaehlteLabels);
def _ZielwertquaderKnotenEinlesen(dateiname, numKoordinaten, numVar): """Liest aus einer csv-Datei namens dateiname alle Zeilen ein. In jeder Zeile werden numKoordinaten Eintraege als Koordinaten erwartet (d.h. 2 oder 3) und die restlichen Werte werden als Ergebnisse an diesen Koordinaten betrachtet. Mit 2 Koordinaten werden Elemente aus vier Knoten angenommen, mit 3 Koordinaten aus acht. Die Koordinaten stehen fuer die Knotenkoordinaten und die Ergebnisse sind an den Knotenkoordinaten definiert. """ from hilfen import Log import csv # tol = 1e-6; reihenfolge = []; numwerte = []; punkte = []; werte = []; with open(dateiname, 'r') as eingabe: eingelesen = csv.reader(eingabe, delimiter=','); for idx_zeile, zeile in enumerate(eingelesen): punkte += [[float(wert) for wert in zeile[:numKoordinaten]]]; if (len(punkte) > 1): diff = [x-y for x, y in zip(punkte[-1], punkte[-2])]; indizes = [idx for idx, zahl in enumerate(diff) if abs(zahl) > tol]; for idx in indizes: if (idx not in reihenfolge): reihenfolge += [idx]; numwerte += [idx_zeile]; # wertzeile = [0 for idx in range(numVar)]; tempwerte = [float(wert) for wert in zeile[numKoordinaten:]]; wertzeile[:len(tempwerte)] = tempwerte; werte += [wertzeile]; # elemente = []; if (len(reihenfolge) == 2): a, b = [numwerte[idx] for idx in reihenfolge]; numA = numwerte[1] - 1; numB = int(len(punkte)/numwerte[1]) - 1; for a_idx in range(numA): for b_idx in range(numB): basispunkt = + a_idx*a + b_idx*b; elemente += [(basispunkt, basispunkt+a, basispunkt+a+b, basispunkt+b), ]; # elif (len(reihenfolge) == 3): a, b, c = [numwerte[idx] for idx in reihenfolge]; numA = numwerte[1] - 1; numB = int(numwerte[2]/numwerte[1]) - 1; numC = int(len(punkte)/numwerte[2]) - 1; for a_idx in range(numA): for b_idx in range(numB): for c_idx in range(numC): basispunkt = + a_idx*a + b_idx*b + c_idx*c; elemente += [(basispunkt, basispunkt+a, basispunkt+a+b, basispunkt+b, basispunkt+c, basispunkt+a+c, basispunkt+a+b+c, basispunkt+b+c), ]; else: Log('# Warnung: Fuer Elementbestimmung nur zwei oder drei Koordinaten erlaubt'); # return [punkte, elemente, werte];
def ElementVolumen(punkte, dimensionen): """Berechnet das Referenzvolumen eines 3D-Elements oder die Referenzflaeche eines 2D-Elements, abhaengig davon ob dimensionen 2 oder 3 ist. Unterstuetzt werden Hexaeder, Tetraeder (3D) sowie Vierecke und Dreiecke (2D). Fuer die korrekte Berechnung muessen die Knoten von Hexaeder und Viereck-Elements in der dargestellen Reihenfolge gespeichert sein (was Abaqus standardmaessig tun sollte): 7 __________ 6 # \ \ # 3 ____________ 0 |\ .\ # | | | \ . \ # | | |4 \_________\ 5 # | | | | . | # | | 3 |..|....... 2| # | | \ | . | # | | \ | .| # |____________| \|_________| # 2 1 0 1 # Gibt das Volumen eines Elements zurueck. """ from hilfen import Log # vol = 0; knotenpunkte = len(punkte); # # WICHTIG: Die selbe Art der Ueberpruefung auch in den Funktionen _ElementZuReferenzpunktVolumen # und KnotengewichtungPunktInPunktkoordinaten anpassen! nichtUnterstuetzt = False; if (dimensionen == 2): punkte2D = [einzelpunkt[0:2] for einzelpunkt in punkte]; if (knotenpunkte == 3): # C3 - Dreieck vol = _DreieckFlaeche(punkt1=punkte2D[0], punkt2=punkte2D[1], punkt3=punkte2D[2]); elif (knotenpunkte == 4): # C4 - Viereck vol = _ViereckFlaeche(punkte=punkte2D); else: nichtUnterstuetzt = True; elif (dimensionen == 3): if (knotenpunkte == 4): # C3D4 - Tetraeder vol = _TetraederVolumen(punkt1=punkte[0], punkt2=punkte[1], punkt3=punkte[2], punkt4=punkte[3]); elif (knotenpunkte == 8): # C3D8 - Hexaeder vol = _HexaederVolumen(punkte=punkte); else: nichtUnterstuetzt = True; else: nichtUnterstuetzt = True; # if (nichtUnterstuetzt): Log('Elementtyp zur Bestimmung des Volumens nicht unterstuetzt C' + str(dimensionen) + 'D' + str(knotenpunkte)); # return vol;
def PunktInElement(elemente, knoten, referenzpunkt, listenhilfe=[], elementinfoliste=[]): """Gebe den Label des Elements aus elemente zurueck, das referenzpunkt enthaelt. Die Koordinaten der elemente muessen in knoten definiert sein. Die optionale Uebergabe einer Zuordnung listenhilfe von Labels zu Indizes beschleunigt den Vorgang. Falls eine elementinfoliste mit den Volumina und Punktkoordinaten aller Elemente verfuegbar ist, kann ebenfalls eine kleine Beschleunigung erzielt werden. Gibt zielElement zurueck. WICHTIG: Wenn Elemente einer mdb statt einer odb untersucht werden sollen, sollte entweder keine oder die folgende listenhilfe uebergeben werden: listenhilfe = [idx for idx in range(len(knoten))]; """ from hilfen import Log, ElementAusOdb, ErstelleLabelsortierteGeomlist # if (listenhilfe == []): if (ElementAusOdb(element=elemente[0])): listenhilfe = ErstelleLabelsortierteGeomlist(geomliste=knoten); else: listenhilfe = [idx for idx in range(len(knoten))]; # zielElement = None; minverhaeltnis = 2.0; dimensionen = 2; if ('3D' in str(elemente[0].type)): dimensionen = 3; # if (elementinfoliste == []): for elem in elemente: punkte = PunktkoordinatenVonElement(element=elem, knoten=knoten, listenhilfe=listenhilfe); if (not _PunktMoeglicherweiseInElement(punkte=punkte, referenzpunkt=referenzpunkt, dimensionen=dimensionen)): continue; # volverhaeltnis = _PunktInnerhalbElement(punkte=punkte, referenzpunkt=referenzpunkt, dimensionen=dimensionen); if (volverhaeltnis < minverhaeltnis): zielElement = elem.label; minverhaeltnis = volverhaeltnis; else: if (not len(elemente) == len(elementinfoliste)): Log('# Abbruch: Anzahl Elemente stimmt nicht mit Eintraegen in Elementlist ueberein'); return zielElement; for idx, elem in enumerate(elemente): if (not _PunktMoeglicherweiseInElement(punkte=elementinfoliste[idx][0], referenzpunkt=referenzpunkt, dimensionen=dimensionen)): continue; # referenzpunktvol = _ElementZuReferenzpunktVolumen(punkte=elementinfoliste[idx][0], referenzpunkt=referenzpunkt, dimensionen=dimensionen); volverhaeltnis = referenzpunktvol/elementinfoliste[idx][1]; if (volverhaeltnis < minverhaeltnis): zielElement = elem.label; minverhaeltnis = volverhaeltnis; # return zielElement;
def _Bohrprofil_vvbpstange(modell, name, laenge, r_aussen, r_innen, spitzenwinkel, rundwinkel, schraublaenge1, profillaenge1, schraublaenge2, profillaenge2, laenge12): """Erstelle ein speziell geformte Stange mit der Bezeichnung name mit aufgeweitetem Verdraengungsbereich im modell mit den Parametern vom Vollverdraengungsbohrprofil. """ import sketch import part from abaqusConstants import CLOCKWISE, THREE_D, DEFORMABLE_BODY, OFF from math import tan from hilfen import grad2rad, Log from zeichnung import Linie, Linienzug, KreisbogenPunkte # spitzenlaenge = _Bohrprofil_spitzenlaenge(breite=r_innen, winkel=spitzenwinkel) # modell.ConstrainedSketch(name='__profile__', sheetSize=2.0 * laenge) zeichnung = modell.sketches['__profile__'] zeichnung.ConstructionLine(point1=(0.0, -laenge), point2=(0.0, laenge)) zeichnung.FixedConstraint(entity=zeichnung.geometry.findAt((0.0, 0.0), )) # if ((rundwinkel >= 90.0) or (rundwinkel < 0.0)): Log('# Ungueltiger Wert fuer Rundwinkel (0 <= winkel < 90) - setze zu Null' ) rundwinkel = 0.0 # if (rundwinkel == 0.0): Linie(zeichnung=zeichnung, punkt1=(0.0, -spitzenlaenge), punkt2=(r_innen, 0.0)) else: rundungsfaktor = 0.5 / tan(0.5 * rundwinkel * grad2rad) KreisbogenPunkte( zeichnung=zeichnung, punkt1=(0.0, -spitzenlaenge), punkt2=(r_innen, 0.0), mittelpunkt=(0.5 * r_innen + rundungsfaktor * spitzenlaenge, -0.5 * spitzenlaenge - rundungsfaktor * r_innen), richtung=CLOCKWISE) # Linienzug(zeichnung=zeichnung, punkte=[(r_innen, 0.0), (r_innen, schraublaenge1 - profillaenge1), (r_aussen, schraublaenge1), (r_aussen, schraublaenge1 + laenge12), (r_innen, schraublaenge1 + laenge12 + profillaenge2), (r_innen, laenge), (0.0, laenge), (0.0, -spitzenlaenge)], geschlossen=False) modell.Part(dimensionality=THREE_D, name=name, type=DEFORMABLE_BODY) modell.parts[name].BaseSolidRevolve(angle=360.0, flipRevolveDirection=OFF, sketch=zeichnung) del zeichnung
def _Rundwinkel_geometrie(zeichnung, spitzenlaenge, r_aussen, spitzenwinkel, rundwinkel): """Erstelle in der uebergebenen zeichnung die Verbindung zwischen der Spitze eines Bohrprofils (mit der Laenge spitzenlaenge) und dem Aussenradius (r_aussen) abhaengig vom gewaehlten spitzenwinkel und rundwinkel. """ import sketch from abaqusConstants import CLOCKWISE from math import tan from hilfen import grad2rad, Log from zeichnung import Linie, KreisbogenPunkte # if ((rundwinkel >= 90.0) or (rundwinkel < 0.0)): Log('# Ungueltiger Wert fuer Rundwinkel (0 <= winkel < 90) - setze zu Null' ) rundwinkel = 0.0 # # Ziehe zusaetzlich 1 Grad vom Maximalwert ab, damit ein gueltiges Mesh entstehen kann # (der Winkel darf aber nicht kleiner als 0 sein). max_rundwinkel = 90.0 - 2.0 * abs(45.0 - spitzenwinkel) - 1.0 if (max_rundwinkel <= 0.0): Log('# max. Rundwinkel ist 0.0') rundwinkel = 0.0 # if (rundwinkel == 0.0): Linie(zeichnung=zeichnung, punkt1=(0.0, -spitzenlaenge), punkt2=(r_aussen, 0.0)) else: if (rundwinkel >= max_rundwinkel): Log('# Rundwinkel zu gross - setze auf ' + str(max_rundwinkel)) rundwinkel = max_rundwinkel # rundungsfaktor = 0.5 / tan(0.5 * rundwinkel * grad2rad) KreisbogenPunkte( zeichnung=zeichnung, punkt1=(0.0, -spitzenlaenge), punkt2=(r_aussen, 0.0), mittelpunkt=(0.5 * r_aussen + rundungsfaktor * spitzenlaenge, -0.5 * spitzenlaenge - rundungsfaktor * r_aussen), richtung=CLOCKWISE)
def ZweifachbedingteKantenAuswahl(elemente, bedingung1='True', bedingung2='True', bedingung3='True', var=[]): """Erstelle eine Sequenz aller Kanten aus elemente, die bedingung1 und bedingung2 erfuellen. Die Rueckgabe der Kanten ist sortiert nach bedingung3. Alle Variablen aus bedingung1, bedingung2 und bedingung3 muessen global lesbar oder optional in var uebergeben und als var[...] bezeichnet sein, sonst koennen die Bedingungen nicht korrekt ausgewertet werden. In der ersten Bedingung kann mit edge auf eine einzelne Kante zugegriffen werden (bspw. edge.pointOn[0][#], wobei die Raute fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht). In der zweiten und dritten Bedingung kann zusaetzlich auch auf die beiden Endpunkte vert1 sowie vert2 zugegriffen werden (ebenfalls vert.pointOn[0][#] mit Raute als 0, 1 oder 2). Die ersten beiden Bedingungen sind zur Auswahl der der Kanten. Kanten die eine der ersten beiden Bedingungen nicht erfuellen, werdne ignoriert. Die restlichen Kanten werden sortiert, abhaengig davon, ob sie die letzte Bedingung erfuellen oder nicht. Gibt eine Liste mit zwei Sequenzen der ausgewaehlten Kanten [kanten_bedingung3_True, kanten_bedingung3_False] zurueck. Fuer mathematische Zusammenhaenge stehen die Funktionen sqrt, sin, cos, tan, asin, acos, atan zur Verfuegung. """ from math import sqrt, sin, cos, tan, asin, acos, atan from hilfen import Log, _Eval_Basispruefung # kanten1 = elemente.edges[0:0] kanten2 = elemente.edges[0:0] # erlaubt = [ 'coordinates', 'connectivity', 'featureName', 'index', 'instanceName', 'instanceNames', 'isReferenceRep', 'pointOn', 'sectionCategory', 'label', 'type', 'var', 'edge', 'vert1', 'vert2' ] # if (any([(not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=erlaubt)) for bedingung in [bedingung1, bedingung2, bedingung3]])): Log('# Abbruch: Uebergebene bedingung1/bedingung2/bedingung3 ungueltig' ) return # for edge in elemente.edges: if (eval(bedingung1)): vert1 = elemente.vertices[edge.getVertices()[0]] vert2 = elemente.vertices[edge.getVertices()[1]] if (eval(bedingung2)): if (eval(bedingung3)): kanten1 += elemente.edges[edge.index:edge.index + 1] else: kanten2 += elemente.edges[edge.index:edge.index + 1] # kanten = [kanten1, kanten2] return kanten
def _Bohrprofil_spitzenlaenge(breite, winkel): """Berechne die Laenge einer Bohrspitze bei gegebener breite (Radius) und winkel der Spitze. Gibt die berechnete Laenge zurueck. """ from math import tan from hilfen import grad2rad, Log # tempwinkel = winkel if ((winkel >= 90.0) or (winkel < 0.0)): Log('# Ungueltiger Wert fuer Spitzenwinkel (0 <= winkel < 90) - setze zu Null' ) tempwinkel = 0.0 # return breite * tan(tempwinkel * grad2rad)
def KnotengewichtungPunktInPunktkoordinaten(punkte, referenzpunkt, dimensionen): """Bestimmt die Anteile, die ein referenzpunkt aus den Knotenpunkten des in punkte definierten Elements hat. Abhaengig von dimensionen wird eine Flaeche (2D) oder ein Volumen (3D) als Referenz betrachtet. Gibt gewichtung zurueck. WICHTIG: punkte muss unabhaengig von dimensionen drei Koordinaten fuer jeden Punkt enthalten. """ from hilfen import Log # nichtUnterstuetzt = False gewichtung = [] knotenpunkte = len(punkte) # # WICHTIG: Die selbe Art der Ueberpruefung auch in den Funktionen ElementVolumen und # _ElementZuReferenzpunktVolumen anpassen! nichtUnterstuetzt = False if (dimensionen == 2): punkte2D = [einzelpunkt[0:2] for einzelpunkt in punkte] referenzpunkt2D = referenzpunkt[0:2] if (knotenpunkte == 3): # C3 - Dreieck gewichtung = _KnotengewichtungPunktInDreieck( punkte=punkte2D, referenzpunkt=referenzpunkt2D) elif (knotenpunkte == 4): # C4 - Viereck gewichtung = _KnotengewichtungPunktInViereck( punkte=punkte2D, referenzpunkt=referenzpunkt2D) else: nichtUnterstuetzt = True elif (dimensionen == 3): if (knotenpunkte == 4): # C3D4 - Tetraeder gewichtung = _KnotengewichtungPunktInTetraeder( punkte=punkte, referenzpunkt=referenzpunkt) elif (knotenpunkte == 8): # C3D8 - Hexaeder gewichtung = _KnotengewichtungPunktInHexaeder( punkte=punkte, referenzpunkt=referenzpunkt) else: nichtUnterstuetzt = True else: nichtUnterstuetzt = True # if (nichtUnterstuetzt): Log('Elementtyp zur Bestimmung der Gewichtung nicht unterstuetzt C' + str(dimensionen) + 'D' + str(knotenpunkte)) # return gewichtung
def Knotentransformation(punktliste, xneu='x', yneu='y', zneu='z'): """Erstelle eine neue Knotenliste basierend auf punktliste. Dabei werden von allen Eintraegen nur label und coordinates uebernommen. Die Koordinaten koennen ueber die Felder xneu, yneu und zneu transformiert werden. Gibt die transformierte punktliste zurueck. Fuer alle drei Variablen kann eine Transformationsanweisung wie bspw. "sqrt(x**2+y**2)" uebergeben werden, wobei jeweils die Variablen x, y und z zur Verfuegung stehen, die die Orignalwerte fuer jeden Knoten enthalten. Fuer mathematische Zusammenhaenge stehen die Funktionen pi, sqrt, sin, cos, tan, asin, acos, atan zur Verfuegung. WICHTIG: Wenn eine Zustandsuebertragung mit Knoten stattfinden soll, die in dieser Funktion transformiert worden sind, dann werden auch tatsaechlich nur die Knotenkoordinaten und keinerlei Werte modifiziert. Das gilt insbesondere fuer Drehungen wie im angegebenen Beispiel, bei dem Tensorergebnisse nicht gedreht, sondern nur an anderer Stelle ausgegeben werden. """ from math import pi, sqrt, sin, cos, tan, asin, acos, atan from hilfen import Log, _Eval_Basispruefung # neue_knotenliste = [] # if (any([(not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=['x', 'y', 'z'])) for bedingung in [xneu, yneu, zneu]])): Log('# Abbruch: Uebergebene xneu/yneu/zneu ungueltig') return # for knoten in punktliste: x = knoten.coordinates[0] y = knoten.coordinates[1] z = knoten.coordinates[2] xmod = eval(xneu) ymod = eval(yneu) zmod = eval(zneu) # if (not (zneu is None)): neue_knotenliste += [ PunktListe(coordinates=(xmod, ymod, zmod), label=knoten.label) ] else: neue_knotenliste += [ PunktListe(coordinates=(xmod, ymod), label=knoten.label) ] # return neue_knotenliste
def _Name_Aktuellste_Materialdatenbank(): import os from hilfen import Log, _PfadZusatzdateien # dateien = os.listdir(_PfadZusatzdateien()); kandidaten = []; for datei in dateien: if (datei.startswith('Materialdatenbank')): kandidaten += [datei]; # kandidaten.sort(); if (len(kandidaten) == 0): Log('# Fehler: Konnte keine Materialdatenbank finden'); return None; else: return os.path.join(_PfadZusatzdateien(), kandidaten[-1]);
def _ElementZuReferenzpunktVolumen(punkte, referenzpunkt, dimensionen): """Bestimme das Volumen (3D) bzw. die Flaeche (2D), das durch die punkte eines Elements mit einem referenzpunkt definiert wird (abhaengig von dimensionen). Gibt das Volumen mit Referenzpunkt als Teil des Elements zurueck. """ from hilfen import Log # vol = 0 knotenpunkte = len(punkte) # # WICHTIG: Die selbe Art der Ueberpruefung auch in den Funktionen _ElementZuReferenzpunktVolumen # und KnotengewichtungPunktInPunktkoordinaten anpassen! nichtUnterstuetzt = False if (dimensionen == 2): punkte2D = [einzelpunkt[0:2] for einzelpunkt in punkte] referenzpunkt2D = referenzpunkt[0:2] if (knotenpunkte == 3): # C3 - Dreieck vol = _XeckZuReferenzpunktFlaeche(punkte=punkte2D, referenzpunkt=referenzpunkt2D, ecken=3) elif (knotenpunkte == 4): # C4 - Viereck vol = _XeckZuReferenzpunktFlaeche(punkte=punkte2D, referenzpunkt=referenzpunkt2D, ecken=4) else: nichtUnterstuetzt = True elif (dimensionen == 3): if (knotenpunkte == 4): # C3D4 - Tetraeder vol = _TetraederZuReferenzpunktVolumen(punkte=punkte, referenzpunkt=referenzpunkt) elif (knotenpunkte == 8): # C3D8 - Hexaeder vol = _HexaederZuReferenzpunktVolumen(punkte=punkte, referenzpunkt=referenzpunkt) else: nichtUnterstuetzt = True else: nichtUnterstuetzt = True # if (nichtUnterstuetzt): Log('Elementtyp zur Bestimmung des ReferenzVolumens nicht unterstuetzt C' + str(dimensionen) + 'D' + str(knotenpunkte)) # return vol
def _OdbElementAuswahl(elemente, punktliste, bedingung='True', var=[], listenhilfe=[]): """Gib eine Sequenz an Elementen aus den uebergebenen elemente zurueck, die bzw. deren Punkte die bedingung erfuellen (nur odb). Fuer die Zuordnung der einzelnen Punkte zu den Elementen muss eine punktliste uebergeben werden, die alle Punkte aller elemente enthaelt. Die korrekte Zuordnung der Labels der Punkte kann durch Uebergabe einer listenhilfe beschleunigt werden. Gibt die Sequenz der ausgewaehlten Elemente zurueck. In der Bedingung kann mit elem auf ein einzelnes Element und mit punkt auf einen Punkt des Elements zugegriffen werden. Die Koordinaten eines Punktes koennen mit punkt.coordinates[#] erhalten werden, wobei die Raute fuer 0, 1 oder 2 und somit eine der drei Bezugsrichtungen steht. """ from math import pi, sqrt, sin, cos, tan, asin, acos, atan from hilfen import Log, _Eval_Basispruefung, ErstelleLabelsortierteGeomlist # ausgewaehlteElemente = elemente[0:0] erlaubt = [ 'coordinates', 'connectivity', 'featureName', 'index', 'instanceName', 'instanceNames', 'isReferenceRep', 'pointOn', 'sectionCategory', 'label', 'type', 'var', 'elem', 'punkt' ] # if (not _Eval_Basispruefung(code=bedingung, zusatz_erlaubt=erlaubt)): Log('# Abbruch: Uebergebene bedingung ist ungueltig') return ausgewaehlteElemente # if (listenhilfe == []): listenhilfe = ErstelleLabelsortierteGeomlist(geomliste=punktliste) # numPunkte = len(elemente[0].connectivity) for idx, elem in enumerate(elemente): numErfuellt = 0 for punktlabel in elem.connectivity: punkt = punktliste[listenhilfe[punktlabel]] if (eval(bedingung)): numErfuellt += 1 else: continue # if (numErfuellt == numPunkte): ausgewaehlteElemente += elemente[idx:idx + 1] # return ausgewaehlteElemente
def _ConnectorErstellen(modell, verbindungstyp, name, punkt1, punkt2, kos): """Erzeuge im modell einen Connector name von punkt1 zu punkt2 mit dem Koordinatensystem kos. Je nach verbindungstyp werden gewisse Einschraenkungen der Freiheitsgrade - bezogen auf das uebergebene KOS (!) - fest zugewiesen: - 'TranslateConnector': Beim Axiallager ist nur eine Verschiebung entlang der x-Achse moeglich. - 'HingeConnector': Beim Drehscharnier ist nur eine Drehung um die x-Achse moeglich. """ import section import assembly from abaqusConstants import TRANSLATOR, HINGE, IMPRINT from auswahl import BedingteAuswahl from hilfen import Log # if (verbindungstyp == 'TranslateConnector'): if (not modell.sections.has_key('TranslateConnector')): modell.ConnectorSection(assembledType=TRANSLATOR, name='TranslateConnector') # elif (verbindungstyp == 'HingeConnector'): if (not modell.sections.has_key('HingeConnector')): modell.ConnectorSection(assembledType=HINGE, name='HingeConnector') else: Log('# Warnung: Connector nicht implementiert') # modell.rootAssembly.WirePolyLine(mergeType=IMPRINT, meshable=False, points=((punkt1, punkt2), )) modell.rootAssembly.features.changeKey(fromName='Wire-1', toName=name) # KabelKanten = BedingteAuswahl(elemente=modell.rootAssembly.edges, bedingung='elem.featureName == \'' + name + '\'') modell.rootAssembly.Set(edges=KabelKanten, name='set' + name) # modell.rootAssembly.SectionAssignment( sectionName=verbindungstyp, region=modell.rootAssembly.sets['set' + name]) modell.rootAssembly.ConnectorOrientation( localCsys1=kos, region=modell.rootAssembly.sets['set' + name])
def Bodenparameter(name, stoffgesetz, bezeichnung='labor'): """Lade fuer den Boden name die Bodenparameter nach dem stoffgesetz. Die in der dazugehoerigen Materialdatenbank gespeicherten Eintraege koennen mithilfe ihres Namens - und optional bei mehreren gleichnamigen Eintraegen mit einer zusaetzlichen bezeichnung - geladen werden. Gibt die dazugehoerigen bodenparameter zurueck. """ from hilfen import grad2rad, Log # parameter = None; eintragVorhanden, bodenwerte, standardwerte = _Bodenparameter_Aus_Tabelle(name, bezeichnung=bezeichnung); if (eintragVorhanden == []): return None; # if (not eintragVorhanden): Log('# Warnung: Keine Parameter fuer Eintrag >' + name + '< in der Materialdatenbank gefunden'); return None; # Alle fehlenden Eintraege des Datensatzes durch Standardwerte ersetzen for iWert, kennwert in enumerate(bodenwerte): if (kennwert is None): bodenwerte[iWert] = standardwerte[iWert]; # idx_basis = 3; idx_hypo = 8; idx_visco = 16; idx_erw = 24; idx_mc = 30; # stoffgesetz_klein = stoffgesetz.lower(); basisparameter = bodenwerte[idx_basis:idx_basis+2] + [grad2rad*bodenwerte[idx_basis+2]]; if ((stoffgesetz_klein == 'elastisch') or (stoffgesetz_klein == 'elastic')): parameter = basisparameter + bodenwerte[idx_mc:idx_mc+2]; # 0: min. Dichte 3: E-Modul # 1: max. Dichte 4: Querdehnzahl # 2: krit.Reibwinkel # elif (stoffgesetz_klein == 'mohr-coulomb'): parameter = basisparameter + bodenwerte[idx_mc:idx_mc+2] + [bodenwerte[idx_basis+2]] + bodenwerte[idx_mc+2:idx_mc+5]; # 0: min. Dichte 3: E-Modul 5: Reibungswert 6: Dilatanzwinkel # 1: max. Dichte 4: Querdehnzahl 7: Koh.-Fliessspg. # 2: krit.Reibwinkel 8: Plast.Dehnung # elif (('viskohypoplasti' in stoffgesetz_klein) or ('viscohypoplasti' in stoffgesetz_klein)): # 0: min. Dichte 3: 100-Porenzahl 4: Querdehnzahl 5: Kompr-Beiwert 9: Ref.-Dehnung # 1: max. Dichte 6: Schwellbeiwert # 2: krit.Reibwinkel 7: Belast.-Flaeche # 8: I_v parameter = basisparameter + [bodenwerte[idx_visco]] + [bodenwerte[idx_mc+1]] + bodenwerte[idx_visco+1:idx_visco+5] + [0.000001*bodenwerte[idx_visco+5]] + \ [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]]; # 10: [leer] 11: Faktor m_T 13: Konstante R_max 14: Exponent alpha 16: Ueberkons-grad # 12: Faktor m_R 15: Exponent beta # elif ('hypoplasti' in stoffgesetz_klein): # 0: min. Dichte 3: Querdehnzahl 4: Granulathaerte 5: Exponent n # 1: max. Dichte 6: dicht.Porenzahl # 2: krit.Reibwinkel 7: lock.Porenzahl # 8: krit.Porenzahl # 9: Exponent alpha # 10: Exponent beta parameter = basisparameter + [bodenwerte[idx_mc+1]] + [1000*bodenwerte[idx_hypo]] + bodenwerte[idx_hypo+1:idx_hypo+7] + \ bodenwerte[idx_erw:idx_erw+2] + [0.000001*bodenwerte[idx_erw+2]] + bodenwerte[idx_erw+3:idx_erw+5]; # 11: Faktor m_T 13: Konstante R_max 14: Exponent beta_R # 12: Faktor m_R 15: Exponent chi # else: parameter = None; Log('# Warnung: Kein passenden Satz an Bodenparametern fuer Stoffgesetz >' + stoffgesetz + '< gefunden'); return None; # # Falls Standardwerte fuer erweiterte hypoplastische Parameter verwendet oder alle ignoriert # werden sollen if ('stdig' in stoffgesetz_klein): # "Standardwerte" der erweiterten hypoplastischen Parameter # # Faktor Faktor Konstante Exponent Exponent # m_T [-] m_R [-] R_max [-] beta_R [-] chi [-] # |---------|---------|-----------|------------|----------| parameter[11:16] = [ 2.0, 5.0, 1e-4, 0.5, 5.0 ]; # if ('ohneig' in stoffgesetz_klein): # "Deaktivierung" der erweiterten hypoplastischen Parameter durch m_T und m_R < 2.0 # # Faktor Faktor Konstante Exponent Exponent # m_T [-] m_R [-] R_max [-] beta_R [-] chi [-] # |---------|---------|-----------|------------|----------| parameter[11:16] = [ 1.0, 1.0, 1.0, 1.0, 1.0 ]; # return parameter;
def 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 r_innen und r_aussen sowie numZylinder zylindrischen Aussparungen (und Zaehnen). Der Radius der Aussparungen betraegt r_zylinder. Optional kann eine eine zylindrische Aussparung mit Radius r_aussparung hinzugefuegt werden. Gibt [part<name>, inst<name>] zurueck. """ from math import sin, cos, acos, atan, sqrt import sketch import part import assembly from abaqusConstants import ON, CLOCKWISE, COUNTERCLOCKWISE, THREE_D, DEFORMABLE_BODY from zeichnung import KreisbogenPunkte, Kreis from hilfen import grad2rad, Log # # Ueberpruefungen mitSpitze = False; mitEvolventenwand = True; # winkel = 360.0/numZylinder*grad2rad; phi = winkel/2.0; zylindermpabstand = 2.0 * (r_innen+r_zylinder)*sin(phi); # r_spitze = (r_innen+r_zylinder)*cos(phi) + \ sqrt((zylindermpabstand-r_zylinder)**2 - (zylindermpabstand/2.0)**2); if (r_aussen > r_spitze): Log('Warnung: r_aussen zu gross, verkuerze auf r_spitze'); r_aussen = r_spitze; beta = 0.0; mitSpitze = True; else: beta = acos((r_aussen**2 + (r_innen + r_zylinder)**2 - (zylindermpabstand-r_zylinder)**2)/ \ (2.0*r_aussen*(r_innen + r_zylinder))) - phi; # r_kontaktloesung = sqrt(((r_innen+r_zylinder)*cos(phi))**2 + (zylindermpabstand/2.0-r_zylinder)**2); if (r_aussen < r_kontaktloesung): # Zahn wird naeher am Mittelpunkt abgeschnitten als Verbindungsgerade der Zylindermittelpunkte la = (r_innen + r_zylinder)/2.0 + (r_zylinder**2 - r_aussen**2)/(2.0*(r_innen + r_zylinder)); psi_kontakt = acos(la/r_zylinder); # l_red = r_zylinder*sin(90*grad2rad-phi-psi_kontakt); h_red = zylindermpabstand/2.0-r_zylinder*cos(90*grad2rad-phi-psi_kontakt); beta = atan(h_red/((r_innen+r_zylinder)*cos(phi)-l_red)); mitEvolventenwand = False; else: psi_kontakt = 90*grad2rad - phi; # modell.ConstrainedSketch(name='__profile__', sheetSize=2.0*r_aussen); zeichnung = modell.sketches['__profile__']; for idxBereich in range(numZylinder): bemasst = False; if (idxBereich == 0): bemasst = True; # offsetwinkel = (idxBereich+0.5)*winkel; # Jeder Bereich wird in vier Teilstrecken unterteilt, um die Kontur zu zeichnen mittelpunkt_aktuell = ((r_innen+r_zylinder)*sin(offsetwinkel), (r_innen+r_zylinder)*cos(offsetwinkel)); mittelpunkt_naechster = ((r_innen+r_zylinder)*sin(offsetwinkel+winkel), (r_innen+r_zylinder)*cos(offsetwinkel+winkel)); # 1) Auflageflaeche der Zylinder am Zahnrad punkta = (mittelpunkt_aktuell[0] - r_zylinder*sin(offsetwinkel+psi_kontakt), mittelpunkt_aktuell[1] - r_zylinder*cos(offsetwinkel+psi_kontakt)); punktb = (mittelpunkt_aktuell[0] - r_zylinder*sin(offsetwinkel-psi_kontakt), mittelpunkt_aktuell[1] - r_zylinder*cos(offsetwinkel-psi_kontakt)); KreisbogenPunkte(zeichnung=zeichnung, mittelpunkt=mittelpunkt_aktuell, punkt1=punkta, punkt2=punktb, richtung=COUNTERCLOCKWISE, bemasst=bemasst); # 2) Erste Evolventenwand, falls vorhanden if (mitEvolventenwand): punkta = punktb; punktb = ((r_aussen)*sin(offsetwinkel+phi-beta), (r_aussen)*cos(offsetwinkel+phi-beta)); KreisbogenPunkte(zeichnung=zeichnung, mittelpunkt=mittelpunkt_naechster, punkt1=punkta, punkt2=punktb, richtung=CLOCKWISE, bemasst=bemasst); # 3) Aussenlaeche, falls keine Spitze if (not mitSpitze): punkta = punktb; punktb = ((r_aussen)*sin(offsetwinkel+phi+beta), (r_aussen)*cos(offsetwinkel+phi+beta)); KreisbogenPunkte(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), punkt1=punkta, punkt2=punktb, richtung=CLOCKWISE, bemasst=bemasst); # 4) Zweite Evolventenwand, falls vorhanden if (mitEvolventenwand): punkta = punktb; punktb = (mittelpunkt_naechster[0] - r_zylinder*sin(offsetwinkel+winkel+psi_kontakt), mittelpunkt_naechster[1] - r_zylinder*cos(offsetwinkel+winkel+psi_kontakt)); KreisbogenPunkte(zeichnung=zeichnung, mittelpunkt=mittelpunkt_aktuell, punkt1=punkta, punkt2=punktb, richtung=CLOCKWISE, bemasst=bemasst); # if (r_aussparung > 0.0): Kreis(zeichnung=zeichnung, mittelpunkt=(0.0, 0.0), radius=r_aussparung); # partZahnrad = modell.Part(dimensionality=THREE_D, name=name, type=DEFORMABLE_BODY); partZahnrad.BaseSolidExtrude(depth=dicke, sketch=zeichnung); del zeichnung; instname = 'inst' + name; instZahnrad = modell.rootAssembly.Instance(dependent=ON, name=instname, part=modell.parts[name]); return [partZahnrad, instZahnrad];
def _ZielwertquaderElementeEinlesen(dateiname, numKoordinaten, numVar): """Liest aus einer csv-Datei namens dateiname alle Zeilen ein. In jeder Zeile werden numKoordinaten Eintraege als Koordinaten erwartet (d.h. 2 oder 3) und die restlichen Werte werden als Ergebnisse an diesen Koordinaten betrachtet. Mit 2 Koordinaten werden Elemente aus vier Knoten angenommen, mit 3 Koordinaten aus acht. Die Koordinaten stehen fuer Punkte in den Elementen an denen die Ergebnisse fuer das ganze Element definiert sind. Nur wenn die Koordinaten pro Koordinatenrichtung die gleichen Abstaende haben, entsprechen die Punkte auch den tatsaechlichen Elementmittelpunkten. """ from hilfen import Log import csv # tol = 1e-6; reihenfolge = []; numwerte = []; elementpunkte = []; elementwerte = []; with open(dateiname, 'r') as eingabe: eingelesen = csv.reader(eingabe, delimiter=','); for idx_zeile, zeile in enumerate(eingelesen): elementpunkte += [[float(wert) for wert in zeile[:numKoordinaten]]]; if (len(elementpunkte) > 1): diff = [x-y for x, y in zip(elementpunkte[-1], elementpunkte[-2])]; indizes = [idx for idx, zahl in enumerate(diff) if abs(zahl) > tol]; for idx in indizes: if (idx not in reihenfolge): reihenfolge += [idx]; numwerte += [idx_zeile]; # wertzeile = [0 for idx in range(numVar)]; tempwerte = [float(wert) for wert in zeile[numKoordinaten:]]; wertzeile[:len(tempwerte)] = tempwerte; elementwerte += [wertzeile]; # punkte = []; elemente = []; if (len(reihenfolge) == 2): elem_a = [elementpunkte[idx][reihenfolge[0]] for idx in range(numwerte[1])]; elem_b = [elementpunkte[int(numwerte[1]*idx)][reihenfolge[1]] for idx in range(int(len(elementpunkte)/numwerte[1]))]; # punkte_a = [0.5*(elem_a[idx] + elem_a[idx-1]) for idx in range(1, len(elem_a))]; punkte_a = [2.0*elem_a[0] - punkte_a[0]] + punkte_a + [2.0*elem_a[-1] - punkte_a[-1]]; # punkte_b = [0.5*(elem_b[idx] + elem_b[idx-1]) for idx in range(1, len(elem_b))]; punkte_b = [2.0*elem_b[0] - punkte_b[0]] + punkte_b + [2.0*elem_b[-1] - punkte_b[-1]]; # a = 1; b = len(punkte_a); for b_idx, bKoord in enumerate(punkte_b): for a_idx, aKoord in enumerate(punkte_a): punkte += [(aKoord, bKoord)]; if ((a_idx == len(punkte_a)-1) or (b_idx == len(punkte_b)-1)): continue; # basispunkt = + a_idx*a + b_idx*b; elemente += [(basispunkt, basispunkt+a, basispunkt+a+b, basispunkt+b), ]; # elif (len(reihenfolge) == 3): elem_a = [elementpunkte[idx][reihenfolge[0]] for idx in range(numwerte[1])]; elem_b = [elementpunkte[int(numwerte[1]*idx)][reihenfolge[1]] for idx in range(int(numwerte[2]/numwerte[1]))]; elem_c = [elementpunkte[int(numwerte[2]*idx)][reihenfolge[2]] for idx in range(int(len(elementpunkte)/numwerte[2]))]; # punkte_a = [0.5*(elem_a[idx] + elem_a[idx-1]) for idx in range(1, len(elem_a))]; punkte_a = [2.0*elem_a[0] - punkte_a[0]] + punkte_a + [2.0*elem_a[-1] - punkte_a[-1]]; # punkte_b = [0.5*(elem_b[idx] + elem_b[idx-1]) for idx in range(1, len(elem_b))]; punkte_b = [2.0*elem_b[0] - punkte_b[0]] + punkte_b + [2.0*elem_b[-1] - punkte_b[-1]]; # punkte_c = [0.5*(elem_c[idx] + elem_c[idx-1]) for idx in range(1, len(elem_c))]; punkte_c = [2.0*elem_c[0] - punkte_c[0]] + punkte_c + [2.0*elem_c[-1] - punkte_c[-1]]; # a = 1; b = len(punkte_a); c = len(punkte_a)*len(punkte_b) for c_idx, cKoord in enumerate(punkte_c): for b_idx, bKoord in enumerate(punkte_b): for a_idx, aKoord in enumerate(punkte_a): punkte += [(aKoord, bKoord, cKoord)]; if ((a_idx == len(punkte_a)-1) or (b_idx == len(punkte_b)-1) or (c_idx == len(punkte_c)-1)): continue; # basispunkt = + a_idx*a + b_idx*b + c_idx*c; elemente += [(basispunkt, basispunkt+a, basispunkt+a+b, basispunkt+b, basispunkt+c, basispunkt+a+c, basispunkt+a+b+c, basispunkt+b+c), ]; else: Log('# Warnung: Fuer Elementbestimmung nur zwei oder drei Koordinaten erlaubt'); # return [punkte, elemente, elementwerte];
def 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 Modell modell. Dazu wird jeden in variablenliste uebergebene Variable an jedem Knoten bzw. Element (je nach Typ) der odbinstname aus dem angegebenen step und frame ausgelesen und als Anfangsloesungen von den Koordinaten der odbelemente oder odbknoten auf die Koordinaten der mdbknoten in der Assembly-Instanz namens mdbinstname übertragen. Da die Position der Knoten nicht uebereinstimmen muss, wird eine lineare Interpolation der Werte aus der odb-Datei auf die Knoten des neuen Modells vorgenommen. Fuer eine Zustandsuebertragung auf ein gleichartiges Modell (gleiche Offsets und Geometrien) ist es nicht noetig, mdbknoten und odbknoten zusaetzlich zu uebergeben. Wenn die Geometrieen aber verschoben sind (anderes Nulloffset o.ae.), dann bietet sich eine Transformation der Koordinaten an (bspw. mit der Funktion Knotentransformation). Die aktualisierten mdbknoten oder/und odbknoten muessen dann entsprechend uebergeben werden. Gibt [gewichtungKnotenLabels, gewichtungKnotenWerte, bezugsElemente] zurueck. Es wird 2D -> 2D und 3D -> 3D unterstuetzt, aber nicht gemischt. Fuer 2D-Elemente sind Dreiecke und Vierecke zulaessig, fuer 3D-Elemente Tetraeder und Hexahedrons. Die Unterscheidung wird am Elementnamen getroffen: Alle Elemente mit 3D im Namen zaehlen zu den 3D-Elementen (bspw. C3D8R). Wichtig: Alle Elemente des parts muessen den gleichen Elementyp haben. """ from ctypes import c_double, c_int import odbAccess from hilfen import Log, BibliothekLaden # Odb-Datei oeffnen, falls nicht schon offen if session.odbData.has_key(odbname): odb = session.odbs[odbname]; else: odb = session.openOdb(name=odbname); # if (odbknoten == []): odbknoten = odb.rootAssembly.instances[odbinstname.upper()].nodes; # if (mdbknoten == []): mdbknoten = modell.rootAssembly.instances[mdbinstname].nodes; # mySteps = session.odbData[odbname].steps.keys(); # Variablen pruefen try: bezugsframe = odb.steps[mySteps[step]].frames[frame]; except: Log('# Abbruch: Angegebener Step/Frame nicht verfuegbar'); return []; # # Erstelle eine modifizierte Variablenliste mit den exakten Namen der geforderten FieldOutputs mod_variablenliste = _FieldOutputVariablenliste(bezugsframe=bezugsframe, variablenliste=variablenliste); if (mod_variablenliste == []): Log('# Abbruch: Variablenliste ungueltig/leer'); return []; # # Lade die Bibliothek zur Bestimmung der Gewichtungen bibliothek = BibliothekLaden(dateiname='gewichtung'); if (bibliothek is None): Log('# Abbruch: Externe Bibliothek gewichtung nicht gefunden'); return []; # cpp_gewichtung_bestimmen = bibliothek.Gewichtung_Bestimmen; # Log('# 1-3: Bereite Daten fuer Zustandsuebertragung vor'); # odbelemente = odb.rootAssembly.instances[odbinstname.upper()].elements; mdbelemente = modell.rootAssembly.instances[mdbinstname].elements; knoten_pro_odbelement = len(odbelemente[0].connectivity); knoten_pro_mdbelement = len(mdbelemente[0].connectivity); # odb_dimensionen = 2; if ('3D' in str(odbelemente[0].type)): odb_dimensionen = 3; # mdb_dimensionen = 2; if ('3D' in str(mdbelemente[0].type)): mdb_dimensionen = 3; # if (not (mdb_dimensionen == odb_dimensionen)): Log('# Abbruch: Zustandsuebertragung nur 2D->2D oder 3D->3D moeglich, nicht gemischt'); return []; # dimensionen = odb_dimensionen; # # Pruefe, ob gueltige Elemente/Knotenformate vorliegen if (not _UebertragungGueltigeElementeCheck(dimensionen=dimensionen, ecken=knoten_pro_odbelement)): Log('# Odb-Elemente/Knoten in nicht unterstuetztem Format'); return []; # if (not _UebertragungGueltigeElementeCheck(dimensionen=dimensionen, ecken=knoten_pro_mdbelement)): Log('# Mdb-Elemente/Knoten in nicht unterstuetztem Format'); return []; # cpp_odbknoten, cpp_odbelemente, cpp_mdbknoten, cpp_mdbelemente = _ZustandsuebertragungDatenVorbereiten(dimensionen=dimensionen, odbknoten=odbknoten, odbelemente=odbelemente, mdbknoten=mdbknoten, mdbelemente=mdbelemente); # # Rueckgabewerte ueber Pointer # Fuer die gewichtungen wird jedem Knoten des neuen Modells (mdb) das Element in der odb bestimmt, # in dem der Punkt liegt. Fuer jeden Knoten aus der odb, die dieses odb-Element definieren, # wird die Gewichtung bestimmt gewichtungKnotenLabels = [0 for idx in range(knoten_pro_odbelement*len(mdbknoten))]; IntArray_gewKnotenLabels = c_int * len(gewichtungKnotenLabels); cpp_gewKnotenLabels = IntArray_gewKnotenLabels(*list(gewichtungKnotenLabels)); # gewichtungKnotenWerte = [0.0 for idx in range(knoten_pro_odbelement*len(mdbknoten))]; DoubleArray_gewKnotenWerte = c_double * len(gewichtungKnotenWerte); cpp_gewKnotenWerte = DoubleArray_gewKnotenWerte(*list(gewichtungKnotenWerte)); # bezugsElemente = [0 for idx in range(len(mdbelemente))]; IntArray_bezugsElemente = c_int * len(bezugsElemente); cpp_bezugsElemente = IntArray_bezugsElemente(*list(bezugsElemente)); # Log('# 2-3: Ermittle Gewichtungen'); cpp_gewichtung_bestimmen(c_int(dimensionen), c_int(knoten_pro_odbelement), c_int(knoten_pro_mdbelement), cpp_odbknoten, c_int(len(odbelemente)), cpp_odbelemente, c_int(len(mdbknoten)), cpp_mdbknoten, c_int(len(mdbelemente)), cpp_mdbelemente, cpp_gewKnotenLabels, cpp_gewKnotenWerte, cpp_bezugsElemente); # # Wieder Listen aus den uebergebenen Pointern erzeugen gewichtungKnotenLabels = list(cpp_gewKnotenLabels); gewichtungKnotenWerte = list(cpp_gewKnotenWerte); bezugsElemente = list(cpp_bezugsElemente); # Log('# 3-3: Weise Werte zu'); idx_naechstereintrag = _ErzeugeAbapysAnfangsbedingungenEintrag(modell=modell); # # Anzahl der Ausgabewerte pro Knoten/Element ermitteln for ausgabevariable in mod_variablenliste: ausgabedatei, ausgabetext, odbergebnisse = _ZustandsuebertragungAusgabeVorbereiten(mdbname=modell.name, ausgabevariable=ausgabevariable, bezugsframe=bezugsframe); if (any([ausgabedatei, ausgabetext, odbergebnisse]) is None): Log('# Abbruch: Zugriffsprobleme auf Datei oder ungueltige Ergebnisse'); return []; # modell.keywordBlock.insert(idx_naechstereintrag, ausgabetext); _ZustandsuebertragungErgebnisdateiSchreiben(ausgabedatei=ausgabedatei, odbergebnisse=odbergebnisse, mdbinstname=mdbinstname, gewichtungKnotenLabels=gewichtungKnotenLabels, gewichtungKnotenWerte=gewichtungKnotenWerte, bezugsElemente=bezugsElemente, mdbknoten=mdbknoten, knoten_pro_mdbelement=knoten_pro_mdbelement); # return [gewichtungKnotenLabels, gewichtungKnotenWerte, bezugsElemente];
def 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 Viewports der session an. Optional koennen verschiedene Effekte aktiviert oder deaktiviert werden. Fuer farbspektrum sind die folgenden Spektren definiert: abpViridis, abpCubeHelix, abpRainbow und abpMoreland sowie deren Inverse (abpViridisINV, abpCubeHelixINV, abpRainbowINV und abpMorelandINV). Gibt einen Verweis auf den viewport zurueck. """ # Basiert hauptsaechlich auf dem Abaqus Scripting Reference Guide (Abschnittstitel und -nummern # aus der Version 6.14 sowie # http://ifcuriousthenlearn.com/blog/2015/04/02/Abaqus-FEA-Scripting-with-python/ # http://desicos.github.io/desicos/_modules/desicos/abaqus/abaqus_functions.html # import visualization from abaqusConstants import FIXED, TRUE, FALSE, ON, OFF, FEATURE, SPECIFY, CONTINUOUS from abaqusConstants import PARALLEL, MODEL, ABSOLUTE from hilfen import Log # myviewport = session.viewports[session.currentViewportName]; # if ((not isinstance(neuerHintergrund, bool)) or (not isinstance(saubererViewport, bool)) or (not isinstance(saubereLegende, bool)) or(not isinstance(evfSchnitt, bool)) or (not isinstance(minimaleKanten, bool)) or(not isinstance(diskreteFarben, bool)) or (not isinstance(ausgabeVerschmieren, bool)) or(not isinstance(zeigeMarkierungen, bool)) or (not isinstance(exportiereHintergrund, bool)) or(not isinstance(Standardansicht, bool))): Log('# Abbruch: Alle Argumente ausser session und farbspektrum muessen True/False sein'); return myviewport; # # ######################################### # --- GraphicsOptions object (17.9) --- # ######################################### # mygraphicoptions = session.graphicsOptions; # if (neuerHintergrund): # Gradient: 40% der Hoehe -> 85% des Farbwechsels von der unteren zur oberen Farbe mygraphicoptions.setValues(backgroundColor='#FFFFFF'); mygraphicoptions.setValues(backgroundBottomColor='#AABBDD'); # # # # ##################################################### # --- ViewportAnnotationsOptions object (17.19) --- # ##################################################### # myannotationoptions = myviewport.viewportAnnotationOptions; # # Alle Hilfselemente im Viewport entfernen if (saubererViewport): myannotationoptions.setValues(compass=0, triad=0, state=0, title=0); # # Anzeige der Legende anpassen if (saubereLegende): myannotationoptions.setValues(legendBox=0); myannotationoptions.setValues(legendNumberFormat=FIXED, legendDecimalPlaces=2); myannotationoptions.setValues(legendFont='-*-arial-bold-r-normal-*-*-120-*-*-p-*-*-*'); # # # #################################### # --- OdbDisplay object (35.1) --- # #################################### # myodbdisplay = myviewport.odbDisplay; # # Bei CEL-Modellen den viewCut an leeren Euler-Elementen aktivieren if (evfSchnitt): myodbdisplay.setValues(viewCutNames=('EVF_VOID', ), viewCut=TRUE); # # # ######################################## # --- CommonOptions object (35.2) --- # ######################################## # mycommonoptions = myviewport.odbDisplay.commonOptions; # # Sichtbarkeit der Netzkanten anpassen if (minimaleKanten): mycommonoptions.setValues(visibleEdges=FEATURE); # # # ######################################## # --- ContourOptions object (35.3) --- # ######################################## # mycontouroptions = myviewport.odbDisplay.contourOptions; # # Manuelle Farbwahl fuer Werte ausserhalb der vorgegebenen Grenzen mycontouroptions.setValues(outsideLimitsMode=SPECIFY); mycontouroptions.setValues(outsideLimitsAboveColor='#EEEEEE', outsideLimitsBelowColor='#111111'); # # Zulaessige Farbspektren if ((farbspektrum == 'CubeHelix') or (farbspektrum == 'CubeHelixINV') or (farbspektrum == 'Moreland') or (farbspektrum == 'MorelandINV') or (farbspektrum == 'UniformRainbow') or (farbspektrum == 'UniformRainbowINV') or (farbspektrum == 'Viridis') or (farbspektrum == 'ViridisINV')): # mycontouroptions.setValues(spectrum=farbspektrum); else: Log('# Warnung: farbspektrum unbekannt - wird ignoriert'); # if (not diskreteFarben): mycontouroptions.setValues(contourStyle=CONTINUOUS); else: mycontouroptions.setValues(numIntervals=10); # # # ################################## # --- Spectrum object (39.8) --- # ################################## # # Spektren aus einer Reihe an Farben definieren (linear interpoliert) # CubeHelix (http://www.mrao.cam.ac.uk/~dag/CUBEHELIX/) # - Helligkeitswerte: [0.1 0.75] # - Anfangswert Rotation: 0.5 # - Anzahl/Richtung Rotationen: -1.3 # - Farbwert: 1.3 # - Gammakorrektur: 0.8 session.Spectrum('CubeHelix', ['#2C2145', '#2B446D', '#226D74', '#2C905F', '#56A244', '#96A242', '#D59B66', '#F99CA4', '#FDADE1']); # UniformRainbow (https://peterkovesi.com/projects/colourmaps/index.html rainbow_bgyr_35-85_c72_n256) session.Spectrum('UniformRainbow', ['#0034F9', '#2A7F82', '#55A915', '#B9C11C', '#FDBC20', '#FE8212', '#FD482B']); # Moreland (https://www.kennethmoreland.com/color-maps/) session.Spectrum('Moreland', ['#3B4CC0', '#6282EA', '#8DB0FE', '#B8D0F9', '#DDDDDD', '#F5C4AD', '#F49A7B', '#DE604D', '#B40426']); # Viridis (https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html) session.Spectrum('Viridis', ['#440154', '#472D7B', '#3B528B', '#2C728E', '#21918C', '#28AE80', '#5EC962', '#ADDC30', '#FDE725']); # # Die invertierten Spektren session.Spectrum('CubeHelixINV', ['#FDADE1', '#F99CA4', '#D59B66', '#96A242', '#56A244', '#2C905F', '#226D74', '#2B446D', '#2C2145']); # session.Spectrum('UniformRainbowINV', ['#FD482B', '#FE8212', '#FDBC20', '#B9C11C', '#55A915', '#2A7F82', '#0034F9']); # session.Spectrum('MorelandINV', ['#B4426', '#DE604D', '#F49A7B', '#F5C4AD', '#DDDDDD', '#B8D0F9', '#8DB0FE', '#6282EA', '#3B4CC0']); # session.Spectrum('ViridisINV', ['#FDE725', '#ADDC30', '#5EC962', '#28AE80', '#21918C', '#2C728E', '#3B528B', '#472D7B', '#440154']); # # # ###################################### # --- BasicOptions object (40.1) --- # ###################################### # mybasicoptions = myviewport.odbDisplay.basicOptions; # # Mitteln der Ergebnisse deaktivieren if (not ausgabeVerschmieren): mybasicoptions.setValues(averageElementOutput=OFF); # # Winkel der Feature-Kanten anpassen mybasicoptions.setValues(featureAngle=60); # # Sichtbarkeit der Punktelemente if (not zeigeMarkierungen): mybasicoptions.setValues(pointElements=OFF); # # # ###################################### # --- PrintOptions object (43.1) --- # ###################################### # myprintoptions = session.printOptions; # # Viewportdekoration abschalten myprintoptions.setValues(vpDecorations=OFF); # # Viewporthintergrund aktivieren if (exportiereHintergrund): myprintoptions.setValues(vpBackground=ON); # # Farbreduktion fuer png-Bilder deaktivieren myprintoptions.setValues(reduceColors=False); # # # ############################## # --- View object (54.1) --- # ############################## # myviewoptions = myviewport.view; # # Viewportansicht auf eine Standardsicht anpassen if (Standardansicht): myviewoptions.setValues(projection=PARALLEL); myviewoptions.setValues(session.views['Bottom']); # myviewoptions.rotate(xAngle=0, yAngle=0, zAngle=90, mode=MODEL); myviewoptions.rotate(xAngle=0, yAngle=-30, zAngle=0, mode=MODEL); myviewoptions.zoom(zoomFactor=0.95, mode=ABSOLUTE); myviewoptions.pan(xFraction=0.12, yFraction=-0.04); # return myviewport;
def Zustandszuweisung(session, modell, zielkoordinaten, zielelemente, zielwerte, mdbinstname, mdbknoten=[], variablentyp=['SDV']): """Weise die zielwerte an den zielkoordinaten bze. zielelemente einem in der aktuellen session geladenem Modell modell zu als Anfangsloesung fuer variablentyp SDV zu. Dazu wird fuer die in variablentyp gelistete Variable an jedem Knoten bzw. Element (je nach Typ) mit den Koordinaten zielkoordinaten die Anfangsloesungen aus zielwerte auf die Koordinaten der mdbknoten in der Assembly-Instanz namens mdbinstname übertragen. Da die Position der Knoten nicht uebereinstimmen muss, wird eine lineare Interpolation der zielwerte auf die Knoten des neuen Modells vorgenommen. Wenn variablentyp an Knoten definiert ist, wird zielkoordinaten als Knotenkoordinaten und zielwerte als Knotenwerte interpretiert und zugewiesen. Falls variablentyp an Elementen definiert ist, werden zielkoordinaten als Koordinaten der Elementmittelpunkte definiert und zielwerte als Elementwerte. Fuer eine Zustandszuweisung ohne zusaetzliche Transformation der Positionen (bspw. Verschiebung oder Rotation), ist es nicht noetig, mdbknoten zusaetzlich zu uebergeben. Andernfalls bietet sich eine Transformation der Koordinaten an (bspw. mit der Funktion Knotentransformation). Die aktualisierten mdbknoten muessen dann entsprechend uebergeben werden. Gibt [gewichtungKnotenLabels, gewichtungKnotenWerte, bezugsElemente] zurueck. Wichtig: Alle Elemente des parts muessen den gleichen Elementyp haben. """ from ctypes import c_double, c_int from hilfen import Log, BibliothekLaden # if (mdbknoten == []): mdbknoten = modell.rootAssembly.instances[mdbinstname].nodes; # # Lade die Bibliothek zur Bestimmung der Gewichtungen bibliothek = BibliothekLaden(dateiname='gewichtung'); if (bibliothek is None): Log('# Abbruch: Externe Bibliothek gewichtung nicht gefunden'); return [None, None, None]; # cpp_gewichtung_bestimmen = bibliothek.Gewichtung_Bestimmen; # Log('# 1-3: Bereite Daten fuer Zustandszuweisung vor'); # mdbelemente = modell.rootAssembly.instances[mdbinstname].elements; odbelemente = zielelemente; knoten_pro_mdbelement = len(mdbelemente[0].connectivity); knoten_pro_odbelement = len(odbelemente[0]); # mdb_dimensionen = 2; if ('3D' in str(mdbelemente[0].type)): mdb_dimensionen = 3; # odb_dimensionen = len(zielkoordinaten[0]); if (not (mdb_dimensionen == odb_dimensionen)): Log('# Abbruch: Zustandszuweisung nur 2D->2D oder 3D->3D moeglich, nicht gemischt'); return [None, None, None]; # # dimensionen = mdb_dimensionen; if (not _UebertragungGueltigeElementeCheck(dimensionen=dimensionen, ecken=knoten_pro_mdbelement)): Log('# Mdb-Elemente/Knoten in nicht unterstuetztem Format'); return [None, None, None]; # if (len(zielelemente) == len(zielwerte)): knotenweise = False; elif (len(zielkoordinaten) == len(zielwerte)): knotenweise = True; else: Log('# Abbruch: Anzahl Ergebnisse muss Anzahl Knoten oder Elementen entsprechen'); return [None, None, None]; # cpp_odbknoten, cpp_odbelemente, cpp_mdbknoten, cpp_mdbelemente = _ZustandsuebertragungDatenVorbereiten(dimensionen=dimensionen, odbknoten=zielkoordinaten, odbelemente=odbelemente, mdbknoten=mdbknoten, mdbelemente=mdbelemente, odbAbaqus=False); # # Rueckgabewerte ueber Pointer # Fuer die gewichtungen wird jedem Knoten des neuen Modells (mdb) das Element in der odb bestimmt, # in dem der Punkt liegt. Fuer jeden Knoten aus der odb, die dieses odb-Element definieren, # wird die Gewichtung bestimmt gewichtungKnotenLabels = [0 for idx in range(knoten_pro_odbelement*len(mdbknoten))]; IntArray_gewKnotenLabels = c_int * len(gewichtungKnotenLabels); cpp_gewKnotenLabels = IntArray_gewKnotenLabels(*list(gewichtungKnotenLabels)); # gewichtungKnotenWerte = [0.0 for idx in range(knoten_pro_odbelement*len(mdbknoten))]; DoubleArray_gewKnotenWerte = c_double * len(gewichtungKnotenWerte); cpp_gewKnotenWerte = DoubleArray_gewKnotenWerte(*list(gewichtungKnotenWerte)); # bezugsElemente = [0 for idx in range(len(mdbelemente))]; IntArray_bezugsElemente = c_int * len(bezugsElemente); cpp_bezugsElemente = IntArray_bezugsElemente(*list(bezugsElemente)); # Log('# 2-3: Ermittle Gewichtungen'); cpp_gewichtung_bestimmen(c_int(dimensionen), c_int(knoten_pro_odbelement), c_int(knoten_pro_mdbelement), cpp_odbknoten, c_int(len(odbelemente)), cpp_odbelemente, c_int(len(mdbknoten)), cpp_mdbknoten, c_int(len(mdbelemente)), cpp_mdbelemente, cpp_gewKnotenLabels, cpp_gewKnotenWerte, cpp_bezugsElemente); # # Wieder Listen aus den uebergebenen Pointern erzeugen gewichtungKnotenLabels = list(cpp_gewKnotenLabels); gewichtungKnotenWerte = list(cpp_gewKnotenWerte); bezugsElemente = list(cpp_bezugsElemente); # Log('# 3-3: Weise Werte zu'); idx_naechstereintrag = _ErzeugeAbapysAnfangsbedingungenEintrag(modell=modell); # ausgabedatei, ausgabetext, odbergebnisse = _ZustandsuebertragungAusgabeVorbereiten(mdbname=modell.name, ausgabevariable=variablentyp, bezugsframe=None); if (any([ausgabedatei, ausgabetext]) is None): Log('# Abbruch: Zugriffsprobleme auf Datei oder ungueltige Ergebnisse'); return []; # modell.keywordBlock.insert(idx_naechstereintrag, ausgabetext); _ZustandszuweisungErgebnisdateiSchreiben(ausgabedatei=ausgabedatei, ergebnisse=zielwerte, mdbinstname=mdbinstname, gewichtungKnotenLabels=gewichtungKnotenLabels, gewichtungKnotenWerte=gewichtungKnotenWerte, bezugsElemente=bezugsElemente, mdbknoten=mdbknoten, knoten_pro_mdbelement=knoten_pro_mdbelement, knotenweise=knotenweise); # return [gewichtungKnotenLabels, gewichtungKnotenWerte, bezugsElemente];