Community Tip - Your Friends List is a way to easily have access to the community members that you interact with the most! X
Hey guys,
i modified my iterative calculation and it is better to work with that functions and variables.
Having now the problem, that the calculation for the second row is not correct.
It should be an independend calculation for every loadcase with a different maxiter.
And the second example is not working.
Can anyone see the failure?
THx guys
I think i solved a part of my failure but still dont know why my second example doesnt work.
Hopefully anyone can help me finding the failure.
Is this now correct iteration?
Best thx to all!
Hello Mr. Stefan, maxiter is a scalar or a vector?
F.M. wrote:
Hello Mr. Stefan, maxiter is a scalar or a vector?
He is never using the scalar "maxiter" (the worksheet variable) as argument of his function when calling it.
He is always using
which IS a vector
Its a bit strange, and confusing indeed. The global worksheet variable "maxiter" is a scalar, but the formal function argument "maxiter" always is a vector. Again same name for different things. So in this respect all is OK (given we are looking for the error in his sheet), apart from the fact, that its a very bad habit doing things like that.
Werner
Thats exactly what can happen if you are using your vectors from the very beginning. You end up with data structures which are hard to keep track of.
The problem is, that you are comparing a vector with a scalar (Mathcad is telling you so more or less anyway).
d.m is a nested vector and a.m a regular vector .So a.m[s is a scalar, but d.m[s is a 2 x 1 vector and of course you can not compare those.
Delete the index s (marked in red) and I think you get what you intended
If the title of your file is a question addressed at me, the answer is "no".
Its only partly what I was talking in the other threrad and I think its a good idea to modularize your monster programs (they will be monsters once you implement all input arguments) by defining auxiliary functions.
But what I meant was that you also make Iter() a function taking ALL relevant arguments and Iter() should work with scalar arguments only (you avoid errors like this one that way - all are scalars). So you would get rid of your s-loop and it would be a good idea to define (and test) that new Iter() function right before you define any variables. That way Iter() cannot use any worksheet variables (you will immediately get an error as those variables are not yet defined) but relies solely on its arguments.
When this function(s) works OK for a set of scalar arguments, then its time to define your variables (the 2 x 1 vectors) and feed them into your function using vectorization.
At least thats the way I would try to do the job but maybe I am wrong. Honestly I have only looked very shortly at your Iteration_not_working.xmcd.zip file in the other thread Re: recursivic Calculation as the routine was far too large, cluttered and complicated for me to debug. It would be necessary to check all variables for consistency concerning data strucure and units and it sure is a good idea to split the calculation in a couple of smaller, more handsome parts using functions.
Werner
OK thx for input. But how can formulate it better?
Not sure how i should do it 😞
Still have the problem that i dont know how to show the result of the previous iteration step
OK thx for input. But how can formulate it better?
Not sure how i should do it 😞
Still have the problem that i dont know how to show the result of the previous iteration step
Not sure which post of whom this is an answer to.
I just sketched a way to implement your calculations in a different way here above in the answer where I told you the reason for your Iter1() failing.
I guessed I answered to your question concerning the previous iteration step already here Re: recursivic Calculation
Sure its just a qucik, dirty hack, but it does the job and leaves your routines unchanged otherwise.
Of course you could add to your F.new and F.old a local variable F.veryold to keep track of the previous versions of your variables if you prefer.
OK thx for the input!!!!
Now i only need to know how to get the output of the previous iterationstep.
Because of the conditions i need to write.
Example:
break if Stress_actual >= Stress_maximum
Now i think i need to know which was the iteration in which the condition is true and how much was the stress of the latest possible iteration.
Thx !!!
Ok so i out in the iter() all variables i need in the following loop code.
But what i still dont get is, im working in that code with scalars?
But how do i handle the Vectors later on because i have more than 10 loadcases?
OK im gonna try it thx
> Now i only need to know how to get the output of the previous iterationstep.
Do you even read my answers? Was already answered twice.
> But how do i handle the Vectors later on because i have more than 10 loadcases?
Sorry, no idea what you mean by loadcase.
If you mean input values - your function iter() would have more than 10 arguements then.
If you mean the size of your inputs (which at the time is 2) - it would not matter if your vectors are 2 x 1 or 10000 x 1 when you call a function with them vectorized.
WE
Yes i tryed but i need more than only getting the last force.
How do i get for example the diameter
Well begun is half done .... To avoid ambiguous definitions for me it is a rule.
yes im on the way to get a correct iteration
OK i made the Iteration on your tipps and i hope it is better now. ANd it is what you meant:
But having problems with row 7 of the Result.
Hopefully i did understand what you tryed to explain to me
I think there is a general failure in my code because when i am changing am in the vector of row 7 it has an influence on the following result of row 8
Strange...
I think i need to change the code to get the program work properly
Keine Notwendigkeit, einen Vektor mit den Elementen alle gleich zu erstellen. Einfach verwenden die Konstante maxiter.
danke für den Tipp
@F.M.
der Grund warum ich maxiter auf jeden Loadcase appliziert habe ist, das ich es als vektor brauche, da ich dann den letzten Iterationsschritt jedes loadcases hernehme und um 1 reduziere
Anschließend führe ich die ganze Iteration nochmal durch, allerdings setze ich hier nun als maxiter: den alten -1 ein, um die Ergebnisse zu bekommen des letzten Iterationsschrittes.
(Ergebnisse des Iterationsschrittes), wo noch gerade alles "OK" ist.
Funktioniert jetzt
Deshalb brauche ich maxiter als vektor, um anschließend nur bis zu dem "i" zu rechnen, wo alles "OK" ist, um alle Variablen ausschreiben zu können.
Geht es besser und effizienter? Ich weiß es leider nicht, falls mir jemand einen Tipp geben könnte wäre ich dankbar 😃
Schönen Nachmittag!
Sind die Werte, die dein neues Blatt liefert, wirklich realistisch?
Ich würde das an deiner Stelle nachprüfen.
Die ersten beiden Zeilen liefern schon wieder unterschiedliche Werte obwohl die Eingabewerte identisch sind?
Da scheint noch der Wurm drin zu sein und ich vermute, es liegt wieder einmal an der Tatsache, dass deine Routine mit Vektoren und nicht mit skalaren Werten arbeitet. Möglicherweise werden aber auch Werte in deiner s-Schleife nicht korrekt initialisert und dadurch geänderte Werte vom ersten Schleifendurchlauf in den zweiten übertragen. aber auch das wäre ja dann letztlich wieder die Schuld der Vektoren, denn ohne diese wäre diese äußere Schleife ja gar nicht nötig.
Du treibst einen ziemlich hohen Aufwand um den letzten Wert von F zu bestimmen, bei dem der Durchmesser gerade noch kleiner als das Soll war.
Warum greifst du den von mir nun schon mehrmals geäußerten Vorschlag nicht auf, einfach den Wert von F um die 100 N, um die du immer vergrößerst, zu verringern und diesen Wert (samt zugörigem Radius, etc.) zurückzuliefern?
Ein wenig eleganter wäre es, wenn du dir den letzten noch gültigen F-Wert in einer Variablen merkst (jeweils nach dem break, denn wenn wir dort hinkommen, dann war alles noch OK) und diesen mit zugehörigem Durchmesser zurücklieferst.
Zum Glück hast du ja die Durchmesserberechnung in eine Funktion ausgelagert, daher ist das leicht realisierbar.
Jedenfalls denke ich, dass du dich allein mit der Tatsache, dass du jetzt irgendwelche Werte zurückbekommst, noch nicht zufriedengegeben darfst. Denn irgendwas an den Werten scheint mir faul zu sein.
WE
Wir gratulieren Stefan!
Shouldn't those two values (and others) be the same?
I can't spot any difference in the input data
What about the values for M.E, S.bo, p.D ? They are all the same. So at the time there would be no vector be needed for them. Are they subject to be changed later (different values in one vector)? If not, you should replace them for scalars.
Hello Stefan do you like this solution?
@ F.M.
Looks to me like the force values in your last table are wrong!
Could it be you haven't created a solution on your own but just used Stefans faulty calculation routines?
Can't tell without the sheet.
E.g. in row number 6 F should be around 1334000 N yielding a bolt diameter of approx 37.3223 mm (slightly smaller than the limit 37.323 mm).
Your table says F=983401 N and you get a bolt diameter of 34,302 mm which is much /too) smaller than the 37,323 mm.
WE
You are right Werner. The reason is that I used a very great tolerance. If I use a much smaller tolerance, the result is more satisfactory.
F.M. wrote:
You are right Werner. The reason is that I used a very great tolerance. If I use a much smaller tolerance, the result is more satisfactory.
??? I don't see much difference.
The effect I noticed is the very same on your new pic.
The values in your first table look OK on first sight, but Force values are slightly too high, I guess thats because like Stefan you stop iteration when it fails the first time and like him you don't go back one step in the very same routine which would solve the problem the easiest way. Instead like Stefan you call the same iteration a second time and this time it looks like something is going wrong for some of the cases.
Can it be tolerance alone? Not sure, but probably not.
Danke für den INput
Da s ist der Fehler nehme ich an
Den Rest habe ich leider nicht verstanden wie ich mit weniger Aufwand den letzten Iterationsschritt aufrufen kann nach dem break.
Verstehe es nicht 😞
zumindest schaut es ja jetzt richtig aus oder
Wie meinst du das nach dem break den vorletzten schritt aufrufen und mit der variable merken?
Verstehe das nicht ganz.
Although I don't know what is a.m, I would introduce a relative tolerance to be compared with that obtained between the calculated diameter of the bolt and a.m, and stop the iterations when the latter is less than or equal to the given tolerance. As you can see in the program, the operations are all between scalar variables (elements of vectors) with indices.
Es gibt keine wesentlichen Änderungen im Vergleich zu früheren Versionen. Dies ist vielleicht abhängig von der Unkenntnis des Problems, und das Fehlen einer Beschreibung der Daten.
Best regards
F,M.
danke für die Hilfe.
Also kurz zusammengefasst. Es geht um komplexe Flanschberechnungen. Hier ist der Ausschnitt wo es um Schraubenberechnung geht und F ist einfach die Belastung, Die soll immer um einen Betrag erhöht werden, bis die benötigte Schraubenfläche gerade noch ausreicht. (Abhängig von der Festigkeit Sbo). Und am ist die Schraubenfläche die lokal vorhanden ist.
Kurz gesagt: Erhöhe mir die KRaft, welche auf die Schraubenverbindung wirkt jedesmal um 1 KN, bis die vorhandene Schraubenfläche nicht mehr ausreicht.
Gebe mir anschließend die Ergebnisse der vorletzten Rechnung aus, bei dem die Kraft noch übertragen werden kann.
Später muss ich die Rechnung noch um andere sachen erweitern, sodas sich dann viele andere Abbruchkriterien für die Kraft habe. (Schraubenverbindung, Bauteilfestigkeit etc.
Die sachen lassen sich nciht direkt lösen und müssen itertaiv bestimmt werden.
> Später muss ich die Rechnung noch um andere sachen erweitern, sodas sich dann viele andere Abbruchkriterien für die Kraft habe. (Schraubenverbindung, Bauteilfestigkeit etc.
Ja. daher ist es sinnvoll, die dazu nötigen Berechnungen (wie hier eben den Bolzendurchmesser) in Funktionen auszulagern, um das eigentliche Iterationsprogramm möglichst übersichtlich zu halten.
Ich denke ja noch immer, dass die Aufgabe(n) trotz unterschiedlichster Abbruchkriterien doch mit einem Lösungsblock realisierbar sein könnte. Für den Bolzendurchmesser allein hab ich das ja in dem anderen Thread gezeigt, wie es gehen könnte.
> Die sachen lassen sich nciht direkt lösen und müssen itertaiv bestimmt werden.
Naja, zumindest für Kraft/Bolzendm. stimmt das nicht. Auch da hatte ich ja schon eine direkte Formel zur Berechnung angegeben. Allerdings wird es bei zusätzlichen anderen Kriterien wohl so sein, dass man tatsächlich keine direkte Berechnungsformel angeben kann.
Aber vielleicht können wir ja zumindest die Angelegenheit hier doch noch zufriedenstellend abschließen.
Im Anhang meine Lösungsvariante, welche hoffentlich auch demonstriert, was ich mit meinen bisherigen Anmerkungen meinte.
Zunächst ist die Dmberechnung und auch die OK/NOK "Berechnung" ausgelagert, da ich sie in meiner Routine mehr als einmal benutze. Danach folgt die von mir immer wieder "eingeforderte" Berechnungsroutine, die nur und ausschließlich auf skalaren Größen operiert. Diese wird vorzugsweise oberhalb der Definition der Eingabevariablen geschrieben, damit man nicht irrtümlich etwas benutzt, das nicht als Parameter übergeben wird. Diese Routine, die also nur einen Satz Daten berücksichtigt, habe ich "Iter_single" genannt:
Du siehst, dass ich hier nicht mit F.alt und F.neu herumeiere, ein F reicht völlig. Nur, um nach den Abbruch noch den vorherigen Wert zur Verfügung zu haben, speichere ich jeweils den letzten Wert von F, bei dem der Vergleich noch OK war, in einer Variablen F.OK. Und nur diese und der zu diesem Wert gehörige Durchmesser und OK-Wert werden dann zurückgegeben. Deshalb müssen diese nach der for-Schleife neuerlich berechnet werden. Man könnte alternativ so wie das F.OK auch ein d.OK und vl ein OK.OK mitführen und sich damit diese Neuberechnung ersparen
Probleme kann es hier geben, wenn bereits der Initialwert zu einem zu großen Durchmesser führt (als F,OK wird dann 0 angenommen). Das sollte man der Ordnung halber vl noch abfangen. Ich wähle aber bei den folgenden Aufrufen ohnehin immer 0 N als Initial-Wert, da passiert das offenbar nicht.
Jetzt gibt es mehrere Möglichkeiten, diese Routine zu verwenden. Entweder tatsächlich nur mit einem Datensatz
oder aber mit Vektoren als aktuelle Parameter, dann aber muss der Aufruf vektorisiert werden
Hier sieht man jetzt schon die Problematik - das Ergebnis ist eine verschachtelte Matrix. Wir erhalten einen Vektor dessen Einträge jeweils 1 x 5 Matrizen sind. Das ist für weitere Berechnungen und Ausgaben recht unhandlich, weswegen ich noch eine eigene Routine "Iter" nachgeschaltet habe. Diese ruft "Iter_single" in jedem Fall vektorisiert auf, prüft danach, ob das Ergbenis eine verschachtelte Matrix ist und schreibt diese dann gegebenenfalls in eine normale Matrix um.
Ich hab der Rückgabematrix auch noch einen Zeile mit Spaltenköpfen spendiert.
Die Routine "Iter" kann jetzt also sowohl mit skalaren Werten, als auch mit (gleich großen) Vektoren aufgerufen werden. Wenn ein Eingabevektor nur aus lauter gleichen Einträgen bestehen würde, kannst du stattdessen auch einfach nur den skalaren Wert hinschreiben, so wie ich das mit F.init und maxiter gemacht habe:
Mit deinen Werten ergibt sich dann folgende Tabelle:
Das wärs eigentlich auch schon. Schmerzlos und im Grunde recht kurze Routinen.
Ich hab auch noch als Alternative eine weiter Funktion "Iter_neu" geschrieben. Diese orientiert sich an deinem ursprünglichen Ansatz indem sie die Vektoreingabewerte mit einer Schleife (ich hab den Schleiferzähler s als Name übernommen) einzeln abklappert, damit die Funktion Iter_single aufruft und die Ergebnisse gleich in einer Matrix (auch mit Spaltenköpfen) aufsammelt. "Iter_neu" hat eigentlich keine Vorteile gegenüber "Iter". Im Gegenteil, denn "Iter_neu" kann nicht mit lauter skalaren Werten aufgerufen werden, sondern es müssen hier F.init und maxiter Skalare sein und die anderen Parameter müssen (gleichgroße) Vektoren sein. Also ist "Iter_neu" eher eingeschränkt und weniger flexibel.
Hoffe, dass wir damit diesen Thread erledigen können.
LG
Werner
Eine Ergänzung noch dazu, nämlich eine weitere Möglichkeit, nach dem Abbruch der for-Schleife zu einem gültigen F-Wert zu kommen und diesen auch noch genauer als auf 100N genau zu bekommen.
Nachdem die for-Schleife abgebrochen wurde, geht es in eine neue Schleife, die solange F um 1N verringert, bis der Vergleich von d und a ein "OK" ergibt. Auf diese Weise hast du nun die Kraft F auf 1 N genau. Das ist jetzt sozusagen die verfeinerte Version meines allerersten Vorschlags zur Rückgabe des letzten gültigen F-Werts, den ich bereits in dem anderen Thread gemacht hatte. Dort hatte ich gemeint, dass du mit F doch nur einen Schritt, also 100 N, zurückgehen musst.
Ich habe mir hier nicht die Mühe gemacht, den Iterationszähler "i" in dieser zweiten Schleife weiter hinauf (oder runter?) zu zählen, weil ich ohnedies nicht verstehe, warum du diesen Zähler überhaupt ausgibst. Wenn du mit 0N als Startwert beginnst, immer um 100N erhöhst und es stellt sich dann F=983400 N ein, dann ist doch ohnedies klar, dass F eben 9834-Mal erhöht wurde und nach deiner Zählweise sind das dann 9835 Iterationsschritte.
Hier die neue "Iter_single2":
Die neue "Iter2" ist gegenüber "Iter" unverändert, nur ruft sie eben "Iter_single2" auf.
Hier zum Vergleich die Ergebnisse von "Iter" und die genaueren von "Iter2" (noch genauer machts ein Lösungsblock 😉
Der Unterschied zwischen a.m und d.m ist nun schon so klein, dass er kleiner als ein Mikrometer ist und daher in der Tabelle nicht mehr zu erkennen ist.
WE
hey vielen Dank,
schaut echt supper aus!
Genau so brauche ich es =).
Das mit der Tabelle und den Namen oben is auch toll.
Jetzt werd ich mir den Code genauer anschauen. Wusste nicht wie ich es schreiben soll das er runterzählt und der while Schleife.