Hallo Leute!
Vor einiger Zeit hatte ich das Problem bei der Errechnung von Variablen zur
Festigkeitsberechnung von Rohren. Genauer gesagt den Biegewiderstandmoment.
Das ist der alte Name. Der neue ist axialer Widerstandsmoment. Dabei musste ich
folgende Formel umstellen:
W = (PI * (D^4 -d^4) /(32*D)
die Überschlagsmäßige Berechnung lautet
W = (D^4-d^4)/(10*D)
Die ältere Bezeichung von W war Wb.
Da PI / 32 etwa 9.817477 ergibt, kann man zur Berechnung näherungsweise die letzte
Formel nehmen. Nimmt man statt dessen die Zahl 10, so wird der Wb etwas kleiner als in der
korrekten Formel, das aber bei überschlägigen Berechnungen nicht weiter stören sollte
Stellt man aber die Bedingung, das Wb und die Wandstärke des
Rohres gegeben ist, und daraus die Durchmesser-Werte errechnet werden soll, so
kommt man auf eine kubische Gleichung.
Leider stellte ich fest, das weder der gonimetrische, noch der kardanische
Lösungsweg bei extremen Werten eine ausreichende Genauigkeit liefern. So stellte
sich heraus, das man das am besten durch "ausprobieren" herausfinden kann.
So etwas überlässt man dabei besser einen PC.
Die Funktion SucheInkrementwert(long double m, long double x) vergleicht dabei den
Sollwert m mit dem Istwert x und ermittelt dabei die Schrittgröße.
Dabei muss der Startwert der gesuchten Größe kleiner sein als der später zu ermittelnde
Wert. Daher wird in diesem Beispiel bei der Berechnung des Startwertes des
Außendurchmessers die Formel für ein Vollmaterial genommen. Dessen Durchmesser
liegt naturgemäß unter dem eines Rohres.
Da es aber vorkommen kann, das man dieses Verfahren auch bei anderen Formeln
anwenden möchte, so müsste man jedes mal den Quellcode umschreiben.
Ein Zeiger auf eine Funkion als Parameter, bei der die Funktion quasi die Probe-
Rechnung macht, ob der vorgeschlagene Wert stimmt, war die Lösung.
Der Rest des Quellcodes stellt Funktionen dar, die praktisch schrittweise den
Wert auf das Ergebnis einpendeln lassen. Je näher der Istwert dem Sollwert kommt, desto
kleiner werden die Berechnungsschritte, siehe SucheInkrementwert(long double m, long double x).
Bei diesem Quellcode sind die
Hauptfunktion und die beiden Klassen in einem zusammengefasst.
Hier also der Quellcode.
Zunächst die Datei festi.cpp:
/* Anfang der Datei festi.cpp */
#include <iostream>
#include <math.h>
#include "festi.h"
#include "pi.h"
struct biegen
{
char Belastungsart[3][20];
char Material[7][10];
int Untergrenze[3][7];
int Obergrenze[3][7];
};
struct biegen biegung = { "BiegungI", "BiegungII", "BiegungIII",
"ST-37", "ST-50","ST-70","GS-45", "G-AlSi","AlCuMg2","AlMg3",
110,150,230,110,35,120,90, //ug1
70, 100,150, 70,20, 50,58, //ug2
50, 70, 105, 50,14, 35,45, //ug3
165,220,245,165,50,175,135, //og1
105,150,220,105,28, 70, 88, //og2
75, 105, 125,75,21, 55, 68}; //og3
//char Belastungsart[3][20] = { "BiegungI", "BiegungII", "BiegungIII" };
//char Material[7][10] = { "ST-37", "ST-50","ST-70","GS-45", "G-AlSi","AlCuMg2","AlMg3" };
/*int Untergrenze[3][7]= { {110,150,230,110,35,120,90} , //ug1
{70, 100,150, 70,20, 50,58}, //ug2
{50, 70, 105, 50,14, 35,45} }; //ug3
int Obergrenze[3][7]= {{ 165,220,245,165,50,175,135}, //og1
{ 105,150,220,105,28, 70, 88}, //og2
{ 75, 105, 125,75,21, 55, 68} }; //og3
*/
void Hauptmenue(void)
{
std::cout << std::endl << "\n Festimath V1.34" << std::endl;
std::cout << std::endl << " Rohraussendurchmesser aus wb & Wandstaerke......= 1";
std::cout << std::endl << " Maximale Belastung(Biegewiderstandsmoment) aus..= 2";
std::cout << std::endl << " Rohraussendurchmesser & Wandstaerke\n";
std::cout << std::endl << " Durchmesser eines Rundmaterials aus wb..........= 3";
std::cout << std::endl << " Biegewiderstandsmoment wb eines Rundmaterials...= 4";
std::cout << std::endl << " Biegewiderstandsmoment wb in cmm aus............= 5";
std::cout << std::endl << " Rohrlaenge, angreifender Kraft in N und";
std::cout << std::endl << " zulaessige Biegespannung in N/cmm\n";
std::cout << std::endl << " max. zul angreifende Kraft an einem Rohr........= 6";
std::cout << std::endl << " Materialwahl fuer Simga_b_zul...................= 7";
std::cout << std::endl << " D aus angreifende Kraft, Laenge, Material.......= 8";
std::cout << std::endl << " Belastungsart\n";
std::cout << std::endl << " Rohrgewicht.....................................=9";
std::cout << std::endl << " Ende............................................=10\n";std::
cout << std::endl << " Ihre Eingabe: ";
}
void Traegerf(void)
{
Rohr Hohlmaterial(PI);
Hohlmaterial.ZeigeErklaerung();
Hohlmaterial.getLaengeundF();
Hohlmaterial.calcKraefte();
Hohlmaterial.ShowKraefte();
}
void Rohr::getDundws(void)
{
std::cout << "\nRohr-Aussendurchmesser in mm: ";
std::cin >> gd;
std::cout << "\nWandstärke in mm............: ";
std::cin >> ws;
}
void Rohr::calcRohrwb(void)
{
kd = gd - (ws * 2);
gdh4 = gd * gd * gd * gd;
kdh4 = kd * kd * kd * kd;
wb = (gdh4 - kdh4) / (gd * 10);
}
void Rohr::calcGewicht(void)
{
std::cout << "\nRohr-Aussendurchmesser in mm: "; std::cin >> gd;
std::cout << "\nWandstärke in mm............: "; std::cin >> ws;
std::cout << "\nRohrlaenge in mm............: "; std::cin >> l;
std::cout << "\nMaterialgewicht in kg/cdm...: "; std::cin >> agw;
agd = gd * gd * PI * 0.25;
kd = gd - (2 * ws);
akd = kd * kd * PI * 0.25;
ARohr = (agd - akd) / 10000;
VRohr = (ARohr * l * agw) / 100;
std::cout << "\nKleiner Dmr in mm....: " << kd;
std::cout << "\nRohrgewicht: in kg...: " << VRohr;
}
void Rohr::ShowRohrwb(void)
{
std::cout << "\nAussendurchmesser....: " << gd << " mm";
std::cout << "\nInnendurchmesser.....: " << kd << " mm";
std::cout << "\nBiegewiderstandmoment: " << wb << "cmm";
}
void Rohr::ZeigeErklaerung(void)
{
std::cout << "\nzul. Biegespannung in N/cmm..= sigma_b_zul";
std::cout << "\nzul. Biegemoment in cmm......= Mb_zul";
std::cout << "\nBiegewiderstandsmoment...... = Wb";
std::cout << "\nmax. zul. Belastung in N = Fzul";
std::cout << "\nmbzul = Fzul * l wb = mb_zul / sigma_b_zul";
}
void Rohr::getLaengeundF(void)
{
std::cout << "\nTrägerlaenge in mm l= "; std::cin >> l;
std::cout << "\nBiegewiderstandsmoment wb= "; std::cin >> wb;
std::cout << "\nzul.Biegespannung in N/qmm...sb zul= "; std::cin >> sbzul;
}
void Rohr::calcKraefte(void)
{
mbzul = sbzul * wb;
f = mbzul / l;
}
void Rohr::ShowKraefte(void)
{
std::cout << "\nzulässiges Biegemoment in cmm.....Mb_zul= " << mbzul;
std::cout << "\nmax. zul. Angreifende Kraft in N/ cmm : " << f;
}
void Vollmaterial::getD(void)
{
std::cout << "\nDurchmesser des Rundmaterials in mm: ";
std::cin >> d;
}
void Vollmaterial::calcwb(void)
{
wb = ((d *d *d) * PI) / 32;
}
void Vollmaterial::Showwb(void)
{
std::cout << "\nMaximales Biegewiderstandsmoment in cmm= " << wb;
}
void Vollmaterial::getwb(void)
{
std::cout << "\nBiegewiderstandsmoment in cmm: ";
std::cin >> wb;
}
void Vollmaterial::calcD(void)
{
potenz = 1.00 / 3.00;
dma = (wb * 32) / PI;
dmb = powl( dma, potenz );
}
void Vollmaterial::ShowD(void)
{
std::cout << "\nPotenz " << potenz << " dma " << dma << " wb" << wb;
std::cout << "\nDurchmesser in mm" << dmb;
}
long double Materialwahl(void)
{
long double rewer;
int belart, material, slei;
std::cout << "\nMaterial: " << std::endl;
for (slei = 0; slei <= 6; slei++)
std::cout << "Nr." << (slei + 1) << " " << biegung.Material[slei] << std::endl;
std::cout << "\nBelastungsart: 1=statisch 2=schwellend 3=schwingend";
std::cout << "\nEingabe Belastunsart[1-3]: ";
std::cin >> belart;
std::cout << "\nEingabe Material[1-7]: ";
std::cin >> material;
belart--;
material--;
std::cout << "\nBelastungsart: " <<biegung.Belastungsart[belart] << " Material: " << biegung.Material[material];
rewer = (long double)biegung.Untergrenze[belart][material];
std::cout << "\nsigmab_zul: " << biegung.Untergrenze[belart][material] << "..." << biegung.Obergrenze[belart][material] << " N/mm²";
return(rewer);
}
long double Traeger(long double sbzul)
{
long double l,f,mbzul, wb;
std::cout << "\nTrägerlaenge in mm................l: ";
std::cin >> l;
std::cout << "\nmax. zulaessige Belastung Fzul in N: ";
std::cin >> f;
if (sbzul == 0)
{
std::cout << "\nzul.Biegespannung in N/qmm...sb zul= ";
std::cin >> sbzul;
}
mbzul = f * l;
wb = mbzul / sbzul;
std::cout << "\nzul. Biegespannung sigma_b_zul.....= " << std::fixed << sbzul << " N/cmm";
std::cout << "\nzulaessiges Biegemoment Mb_zul.....= " << mbzul << " cmm";
std::cout << "\nBiegewiderstandsmoment. Wb.........= " << wb << " cmm";
std::cout << "\nmbzul = Fzul * l";
std::cout << "\nwb = Mb_zul / sigma_b_zul";
std::cout << "\nzulässiges Biegemoment Mb_zul......= " << std::fixed << mbzul << " cmm" << std::endl << std::endl;
return(wb);
}
void DiaofTraeger(void)
{
long double sbzul, wb;
sbzul = Materialwahl();
wb = Traeger(sbzul);
RohrDauswbundws(wb,0, SucheInkrementwert);
}
void BelarundD(void)
{
Vollmaterial WbausD(PI);
WbausD.getD();
WbausD.calcwb();
WbausD.Showwb();
}
void RUND(void)
{
Vollmaterial WbausD(PI);
WbausD.getwb();
WbausD.calcD();
WbausD.ShowD();
}
void RohrWBbausD(void)
{
Rohr Hohlmaterial(PI);
Hohlmaterial.getDundws();
Hohlmaterial.calcRohrwb();
Hohlmaterial.ShowRohrwb();
}
/* Eingangswert ist gd und ws(zunaechst Startwert). Daraus wird wb errechnet
* der Innendurchmesser wird an Parameter 1 zurueckgegeben
*/
long double IstWbausRohr(long double ws, long double gd)
{
long double x, t, gdh4, kdh4, N, kd;
kd = gd - (2 * ws); // Errechne Innendurchmesser
gdh4 = gd * gd * gd * gd; // D hoch 4
kdh4 = kd * kd * kd * kd; // d hoch 4
N = gdh4 - kdh4; // N = (d^4) - (d^4)
t = 10 * gd; // t = 10 * D
x = N / t; // (d^4) - (d^4) / (10 * D)
return(x);
}
long double SucheInkrementwert(long double m, long double x)
{
long double b, schrittfaktor;
schrittfaktor = 1 - (x / m);
b = schrittfaktor * 2;
if (( x > (.9 * m)) && (x < (1.1 * m)) ) b = schrittfaktor * 1.5;
if (( x > (.99 * m)) && (x < (1.01 * m)) ) b = schrittfaktor * 0.75;
if (( x > (.999 * m)) && (x < (1.001 * m)) ) b = schrittfaktor * 0.5;
if (( x > (.9999 * m)) && (x < (1.0001 * m)) ) b = schrittfaktor * 0.25;
if (( x > (.99999 * m)) && (x < (1.00001 * m)) ) b = schrittfaktor * 0.125;
if (( x > (.999999 * m)) && (x < (1.000001 * m)) ) b = schrittfaktor * 0.075;
if (( x > (.9999999 * m)) && (x < (1.0000001 * m)) ) b = schrittfaktor * 0.001;
//if (( x > (.999999999 * m)) && (x < (1.000000001 * m)) ) b = (1 - (x / m)) * 0.0001;
if (( x > (.99999999999 * m)) && (x < (1.00000000001 * m)) ) b = 0;
//LOCATE(11,1);
//printf("istwb=%Lf urwb=%Lf b=%Lf slei: %Lf", x, m, b, slei);
//slei++;
return(b);
}
/* Zeiger '(*fuz)'auf eine Funktion*/
void RohrDauswbundws(long double m, long double ws, long double (*fuz)(long double m, long double x))
{
long double gd, kd, istWb, Wandung = 0, schritt = 1;
/* Hole Werte von wb und ws */
if (m == 0)
{
std::cout << "\nBiegewiderstandsmoment in mm³.........Wb = ";
std::cin >> m; // m=gegebener Biegewiderstandsmoment
}
else
std::cout << "\nBiegewiderstandsmoment in mm³.........Wb = " << m; // m=gegebener Biegewiderstandsmoment
if (ws == 0)
{
std::cout << "\nWandstärke in mm.........................= ";
std::cin >> ws;
}
else
std::cout << "\nWandstärke in mm......................ws = " << ws;
Wandung = 2 * ws;
kd = pow(((m * 32) / pi), 0.33333333);
while(schritt > 0.00000000001)
{
gd = Wandung + kd; // errechne D (Startwert)
istWb = IstWbausRohr(ws, gd); // istWb = errechneter wb aus den Vorgabewerten
//std::cout << "\n**gd=" << gd << " kd=" << kd << " ws=" << ws << " Wandung=" << Wandung << "istWb=" << istWb;
//long double SucheInkrementwert(long double sollwert, long double istwert)
schritt = (*fuz)(m, istWb); //alt war: SucheInkrementwert(m, istWb), jetzt Zeifer auf Funktion;
kd += schritt;
}
std::cout << "\nD=" << gd << " d=" << kd << " Ws=" << ws << " Wb=" << istWb << " bei " << ((istWb / m) * 100) << "% Genauigkeit";
}
/* Ende der Datei festi.cpp */
Die "Headerdatei pi.h ist hier:
#ifndef PI_H_INCLUDED
#define PI_H_INCLUDED
#define PI 3.141592653589793
#define pi 3.141592654
#endif // PI_H_INCLUDED
Nun der dazugehörige Header festi.h:
/* Datei festi.h */
long double Traeger(long double sbzul = 0);
long double Materialwahl(void);
class Rohr
{
private:
long double gd, kd, ws, gdh4, kdh4, wb, agd, akd;
long double l,f,mbzul,sbzul, ARohr, VRohr, agw;
public:
Rohr(long double pi) {};
~Rohr(){};
void getDundws(void);
void calcRohrwb(void);
void calcGewicht(void);
void ShowRohrwb(void);
void ZeigeErklaerung(void);
void getLaengeundF(void);
void calcKraefte(void);
void ShowKraefte(void);
};
class Vollmaterial
{
private:
long double d, wb, potenz, dma, dmb;
public:
Vollmaterial(long double pi) {};
~Vollmaterial() {};
void getD(void);
void calcwb(void);
void Showwb(void);
void getwb(void);
void calcD(void);
void ShowD(void);
};
void BelarundD(void);
void RUND(void);
void RohrWBbausD(void);
void Traegerf(void);
long double IstWbausRohr(long double ws, long double gd);
long double SucheInkrementwert(long double m, long double x);
void RohrDauswbundws(long double m, long double ws, long double(*fuz)(long double m, long double x));
//void RohrDauswbundws(long double m = 0, long double ws = 0);
void DiaofTraeger(void);
void Hauptmenue(void);
/* Ende der Datei festi.h */
Jetzt die Datei main.cpp:
/*
* main.cpp
* Copyright (C) 2017 Josef Wismeth
*
* festi is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* festi is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <string.h>
#include "festi.h"
#include "pi.h"
int main(void)
{
int wouhi = 0;
Rohr Hohlmaterial(PI);
do
switch(wouhi)
{
case 0:
Hauptmenue();
std::cin >> wouhi;
if ((wouhi < 1) || (wouhi > 10)) wouhi = 0;
break;
case 1:
RohrDauswbundws(0, 0, SucheInkrementwert);
wouhi = 0;
break;
case 2:
RohrWBbausD();
wouhi = 0;
break;
case 3: RUND();
wouhi = 0;
break;
case 4:
BelarundD();
wouhi = 0;
break;
case 5:
Traeger();
wouhi = 0;
break;
case 6:
Traegerf();
wouhi = 0;
break;
case 7:
Materialwahl();
wouhi = 0;
break;
case 8:
DiaofTraeger();
wouhi = 0;
break;
case 9:
Hohlmaterial.calcGewicht();
wouhi = 0;
break;
case 10:
return 0;
}
while ( wouhi != 10);
return 0;
}
Das ganze hat den Vorteil, das man einzelne Teile der Funktion besser entwickeln kann, da
diese separat sind.
Ich möchte noch anmerken, das ich in diesem Forum in der VBA-Ecke mal eine kleine
Zusammenstellung gemacht habe, über die Angabe der Grenzwerte in Tabellenbüchern.
Zwar hat sich die Herstellung von Stählen und Rohren in den letzten Jahrzehnten verbessert,
aber wetten würde ich im Ernstfall auf die neueren Werte nicht. Das bleibt aber dem
Konstrukteur überlassen, das er da als Grenzwert ansieht.
Erstellt wurde das ganze mit dem Compiler gcc auf SUSE Linux tumbleweed
Guiseppe