Müs Lee
Commodore
- Registriert
- Feb. 2007
- Beiträge
- 4.916
Moinsen zusammen,
ich schreibe gerade ein Konvertierungsskript, um aus einer XML-Datei mit Stabelementen (Knoten-ID, Knotenkoordinaten, Radius am Knoten sowie Element-ID, Knoten1, Knoten2) eine Inputdatei für den FEM-Solver Optistruct bzw. Hypermesh zu basteln. Das funktioniert jetzt größtenteils sehr gut, allerdings bereitet mir der letzte Teil große Schwierigkeiten. Damit Hypermesh die Elemente vernünftig sortiert, müssen sie mit dem Befehl HMMOVE in die Komponente 1 bis n (ändert sich je nach Modell) geordnet werden. Das sieht bspw. für Komponente 5 so aus:
Sprich es werden in Komponente 5 die Elemente 1, 10, 13 bis 14, 31 bis 32, 36 verschoben. Jedes Feld mit einer Element-ID ist 8 Zeichen lang, jedes nichtbesetzte Zeichen im Feld wird mit Leerzeichen auf der linken Seite der Zahl aufgefüllt. Sprich, aus der Zahl 412 wird der String
Das Feld THRU zwischen den Element-IDs x und y bedeutet "lese alle Elemente von x eingeschlossen bis y eingeschlossen ein", es besteht aus den vier Buchstaben und vier Leerzeichen auf der rechten Seite. Es können 9 Felder à 8 Zeichen pro Zeile gelesen werden, Delimiter wie Punkte oder Kommata werden nicht benötigt. Dies ist die Konvention von Hypermesh/Optistruct und kann nur so gelesen werden.
Nun zum Problem:
Mir liegen die Element-IDs, die es zu verschieben gilt, in einer spärlich besetzten Matrix vor, die auch im Anhang zu finden ist. In Spalte 1 sind alle Element-IDs pro Komponente 1 etc. Diese Matrix ändert sich je nach Modell. Die Anzahl der Elemente pro Komponente ist nicht identisch, sprich man kann sich nicht direkt die Spalten schnappen, die Nullen eliminieren und in einer einzelnen Matrix speichern. Ich habe die Elemente also zuerst mit einer for-Schleife dynamisch in einem Vektor gespeichert, der mit jedem Durchlauf überschrieben wird. Das ist prinzipiell ok, da ich sie später nicht mehr benötige und nur in der Schleife blockweise in eine Datei schreiben muss. Die Schwierigkeit besteht darin, die THRU-Felder zu handhaben. Die Gesamtanzahl der zu schreibenden Felder liegt irgendwo zwischen der Anzahl der Elemente pro Komponente und dem Doppelten davon. Ich habe bereits eine if-else-Abfrage probiert, um anhand der Abstände zwischen den Element-IDs festzustellen ob ein THRU-Feld geschrieben werden muss. Dann fiel mir auf, dass das ja die Indizes komplett durcheinanderwirft und ab dem Punkt weiss ich ehrlich gesagt nicht mehr weiter. Ich folgte kurz der Idee, eine while-Schleife dafür zu benutzen mitsamt zwei Laufvariablen und einer Abbruchbedingung: eine für den Vektor mit den numerischen Werten der Element-IDs und eine für den zu erstellenden Charaktervektor mit den dazugehörigen THRU-Feldern, die mit der ersten Laufvariablen anfängt und pro THRU-Feld um 1 erhöht wird, aber so ganz blicke ich nicht durch. Wäre es vielleicht einfacher, das mit Cells zu handhaben oder doch besser ganz anders? Übersehe ich eine superleichte Lösung für diesen Fall?
Unten gibts ein Codeschnipsel. In diesem Fall ist number_of_radius_values =6, number_of_beams = 4752, die Matrix beams beinhaltet die Elementinformationen in Spaltenvektoren der Form [ElementID, KomponentenID, Knoten1, Knoten2, Referenzknoten] und ist ebenfalls im Anhang.
Edit: ich glaub ich hab was. Über ne if-else über den Vektor abfragen ob ein THRU notwendig ist, die Anzahl davon zählen, den originalen Vektor um diese Anzahl erweitern und die Felder dazwischenklemmen. Sollte passen, oder?
ich schreibe gerade ein Konvertierungsskript, um aus einer XML-Datei mit Stabelementen (Knoten-ID, Knotenkoordinaten, Radius am Knoten sowie Element-ID, Knoten1, Knoten2) eine Inputdatei für den FEM-Solver Optistruct bzw. Hypermesh zu basteln. Das funktioniert jetzt größtenteils sehr gut, allerdings bereitet mir der letzte Teil große Schwierigkeiten. Damit Hypermesh die Elemente vernünftig sortiert, müssen sie mit dem Befehl HMMOVE in die Komponente 1 bis n (ändert sich je nach Modell) geordnet werden. Das sieht bspw. für Komponente 5 so aus:
Code:
$HMMOVE 5
$ 1 10 13THRU 14 31THRU 32 36
$ THRU 37 54THRU 55 59THRU 60 77
$ THRU 78 82THRU 83 100THRU 101 105
Sprich es werden in Komponente 5 die Elemente 1, 10, 13 bis 14, 31 bis 32, 36 verschoben. Jedes Feld mit einer Element-ID ist 8 Zeichen lang, jedes nichtbesetzte Zeichen im Feld wird mit Leerzeichen auf der linken Seite der Zahl aufgefüllt. Sprich, aus der Zahl 412 wird der String
Code:
" 412"
Nun zum Problem:
Mir liegen die Element-IDs, die es zu verschieben gilt, in einer spärlich besetzten Matrix vor, die auch im Anhang zu finden ist. In Spalte 1 sind alle Element-IDs pro Komponente 1 etc. Diese Matrix ändert sich je nach Modell. Die Anzahl der Elemente pro Komponente ist nicht identisch, sprich man kann sich nicht direkt die Spalten schnappen, die Nullen eliminieren und in einer einzelnen Matrix speichern. Ich habe die Elemente also zuerst mit einer for-Schleife dynamisch in einem Vektor gespeichert, der mit jedem Durchlauf überschrieben wird. Das ist prinzipiell ok, da ich sie später nicht mehr benötige und nur in der Schleife blockweise in eine Datei schreiben muss. Die Schwierigkeit besteht darin, die THRU-Felder zu handhaben. Die Gesamtanzahl der zu schreibenden Felder liegt irgendwo zwischen der Anzahl der Elemente pro Komponente und dem Doppelten davon. Ich habe bereits eine if-else-Abfrage probiert, um anhand der Abstände zwischen den Element-IDs festzustellen ob ein THRU-Feld geschrieben werden muss. Dann fiel mir auf, dass das ja die Indizes komplett durcheinanderwirft und ab dem Punkt weiss ich ehrlich gesagt nicht mehr weiter. Ich folgte kurz der Idee, eine while-Schleife dafür zu benutzen mitsamt zwei Laufvariablen und einer Abbruchbedingung: eine für den Vektor mit den numerischen Werten der Element-IDs und eine für den zu erstellenden Charaktervektor mit den dazugehörigen THRU-Feldern, die mit der ersten Laufvariablen anfängt und pro THRU-Feld um 1 erhöht wird, aber so ganz blicke ich nicht durch. Wäre es vielleicht einfacher, das mit Cells zu handhaben oder doch besser ganz anders? Übersehe ich eine superleichte Lösung für diesen Fall?
Unten gibts ein Codeschnipsel. In diesem Fall ist number_of_radius_values =6, number_of_beams = 4752, die Matrix beams beinhaltet die Elementinformationen in Spaltenvektoren der Form [ElementID, KomponentenID, Knoten1, Knoten2, Referenzknoten] und ist ebenfalls im Anhang.
Code:
%HMMOVE
for component_id=1:number_of_radius_values
for y=1:number_of_beams
if beams(y,2)==component_id
element_ids_in_component(y,component_id)=beams(y,1);
end
end
interm=nonzeros(element_ids_in_component(:,component_id)); diff_interm=diff(interm);
str_interm=pad(string(interm),8,'left');
fprintf('Number of elements in component %d = %d\n',component_id,length(interm));
fprintf(fileID,'$HMMOVE %s\n',pad(num2str(component_id),8,'left'));
% while z<2*length(next_element_diff)
% if next_element_diff(z)<=0
% fprintf('ERROR in next_element_id\n');
% break
%
% elseif next_element_diff(z)>1
%
%
% elseif next_element_diff(z)==1 && next_element_diff(z+1)>1
% %continue
%
% end
% end
end
Edit: ich glaub ich hab was. Über ne if-else über den Vektor abfragen ob ein THRU notwendig ist, die Anzahl davon zählen, den originalen Vektor um diese Anzahl erweitern und die Felder dazwischenklemmen. Sollte passen, oder?
Anhänge
Zuletzt bearbeitet: