From 82c29edd9ada9cd4c3a44ca75ddb597fa37f98a7 Mon Sep 17 00:00:00 2001 From: Ariane Date: Wed, 6 May 2020 17:10:57 +0200 Subject: [PATCH] Aenderungen --- H3.c | 105 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 27 deletions(-) diff --git a/H3.c b/H3.c index 2463adb..a2daf2b 100644 --- a/H3.c +++ b/H3.c @@ -40,13 +40,11 @@ double IntRomb(double x1, double x2, int n, double a, double z, h = (double*) malloc((mmax + 1) * sizeof(double)); //Speicherplatz für Array allozieren T = (double**) malloc(((mmax + 1)) * sizeof(double*)); - for (i = 0; i <= mmax; i++) { + for (i = 0; i <= mmax; i++) + { T[i] = (double*) malloc(((mmax + 1)) * sizeof(double)); //Speicherplatz für 2-dim Array allozieren - } - h[0] = (x2 - x1) / (n); //Erste Schrittweite berechnen - T[0][0] = trapez(n, a, z, func, x1, x2); //erstes Trapez berechnen for (i = 1; i <= mmax; i++) { @@ -60,15 +58,12 @@ double IntRomb(double x1, double x2, int n, double a, double z, / ((h[i] * h[i]) - (h[i - k] * h[i - k])) * T[i][k - 1]) + (h[i] * h[i] / (h[i] * h[i] - h[i - k] * h[i - k]) * T[i - 1][k - 1]); - } - //printf("%d",i); if (abs(T[i][i] - T[i - 1][i - 1]) <= eps) { //Abschätzen ob das Ergebnis genau genug ist wenn ja aus Schleife raus ergebnis = T[i][i]; break; } - } if (i==mmax){ printf("Fehler, Integral ist ungenau"); // Fehler falls Abbruchbedingung der vorherigen Schleife nicht greift @@ -137,19 +132,70 @@ void efeld(double a, double z, int n, double Q, double eps, f[0] = potenzial( n, a, z +(h), Q, f1, eps); //f(z+h) berechnen f[1] = potenzial(n, a, z - h, Q, f1, eps); //f(z-h) berechnen - *dfp = -1* (f[0] - f[1]) / (2 * h); //Differenzenquotient } while((lastdf/(*dfp)<(1-eps)) || (lastdf/(*dfp)>(1+eps))); //Werte vergleichen ,sodass deren Änderung kleiner als eps ist } +double ges_efeld(int n, double a1, double a2, double z, double Q1, double Q2, double d, + double *df1, double *df2, double (*func)(double, double, double), double eps) +{ //verwendet numerisch berechnetes E-Feld + efeld(a1, z, n, Q1, eps, df1, func); //Berechnung E-Feld des 1. Drahtes + efeld(a2, z-d , n, Q2, eps, df2, func); //Berechnung E-Feld des 2. Drahtes + double E_ges = *df1 + *df2; //Superposition der E-Felder der einzelnen Drähte + return E_ges; +} + +double ges_efeld2(int n, double a1, double a2, double z, double Q1, double Q2, double d, + double (*func)(double, double, double), double eps) +{ //verwendet analytisch berechnetes E-Feld + double E_ges2; + //Superposition der E-Felder der einzelnen Drähte + E_ges2 = potenzial(n, a1, z, Q1, func, eps) + potenzial(n, a2, z-d, Q2, func, eps); + return E_ges2; +} + +double secant(int n, double z1, double z2, double a1, double a2, double Q1, double Q2, + double d, double *df1, double *df2, double (*func)(double, double, double), double eps, int *schritt) +{ //verwendet numerisch berechnetes E-Feld + //Bestimmung des Glechgewichtspuntes bzw.der Nullstelle des addierten E-Feldes mit den Startwerten z1, z2 + double zn; //Variable zum Speichern des neu berechneten z-Wertes + *schritt = 0; + while (fabs(z2-z1) > eps) //solange bis gewünschte Genauigkeit erreicht wurde + { //Berechnung des nächsten Schätzwertes und speichern dieses Wertes als neuen wert + zn = z2 - ges_efeld(n, a1, a2, z2, Q1, Q2, d, df1, df2, func, eps) * (z2-z1)/ + (ges_efeld(n, a1, a2, z2, Q1, Q2, d, df1, df2, func, eps) - + ges_efeld(n, a1, a2, z1, Q1, Q2, d, df1, df2, func, eps)); + z1 = z2; + z2 = zn; + (*schritt)++; //Schrittezähler + } + return zn; +} + +double secant2(int n, double z1, double z2, double a1, double a2, double Q1, double Q2, + double d, double (*func)(double, double, double), double eps, int *schritt) +{ //verwendet analytisch berechnetes E-Feld + //Bestimmung des Glechgewichtspuntes bzw.der Nullstelle des addierten E-Feldes mit den Startwerten z1, z2 + double zn; //Variable zum Speichern des neu berechneten z-Wertes + *schritt = 0; + while (fabs(z2-z1) > eps) //solange bis gewünschte Genauigkeit erreicht wurde + { //Berechnung des nächsten Schätzwertes und speichern dieses Wertes als neuen wert + zn = z2 - ges_efeld2(n, a1, a2, z2, Q1, Q2, d, func, eps) * (z2-z1)/ + (ges_efeld2(n, a1, a2, z2, Q1, Q2, d, func, eps) - + ges_efeld2(n, a1, a2, z1, Q1, Q2, d, func, eps)); + z1 = z2; + z2 = zn; + (*schritt)++; //Schrittezähler + } + return zn; +} int main(void) { - double z, a2; - double a1 = 4; - int n = 30; //n darf nicht zu klein sein, sonst kein Ergebnis - double eps = 1e-8; //genauigkeit epsilon + double z, z1, z2, a1, a2; + int n = 30; + const double eps = 1e-8; //genauigkeit epsilon double d = 12; //Abstand 2.Draht zum 1. double Q1 = 1; //Gesamtladung der Drähte 1 und 2 @@ -157,26 +203,31 @@ int main(void) double df1; //Variable zum speichern des Differenzenquotienten double df2; + + + //Eingabe der Variablen: printf("Bitte geben Sie den Abstand der Punktladung von der x-Achse z ein\n "); scanf("%lf", &z); - printf("Bitte geben Sie a2 ein\n"); //Werte für a2: a1/10 <= a2 <=a1 + printf("Bitte geben Sie a1 ein (0 < a1 <= 4):\n"); //Eingabe der Breiten der Drähte + scanf("%lf", &a1); + printf("Bitte geben Sie a2 ein (a1/10 <= a2 <= a1):\n"); scanf("%lf", &a2); - - - printf("Unendliches Inegral %lf\n", InfInt(n, a1, z, eps, f1)); //Integral berechnen mit InfInt - printf("Das Potenzial ist %f\n", potenzial(n, a1, z, Q1, f1, eps)); //Potenzial aus Integral berechnen - //H2.1 Berechnung des Efeldes mit Hilfe numerischer Ableitung - efeld(a1, z, n, Q1, eps, &df1, f1); //E-feld berechnen - printf("Das E-Feld (numerisch berechnet) an der Stelle %3.2lf ist:%f\n", z, df1); - //H2.2 Berechnung des Efeldes mit Hilfe analytischer Ableitung - printf("Das E-Feld (analytisch berechnet) der Stelle %3.2lf ist:%f\n", z, potenzial(n, a1, z, Q1, f2, eps)); - double diff=fabs(df1-potenzial(n, a1, z, Q1, f2, eps)); - printf("Differenz der E-Feld Berechnungen: %1.10f\n", diff); printf("Gesamtes Potenzial der beiden Drähte: %f\n", ges_potenzial(n, a1, a2, z, Q1, Q2, d, f1, eps)); - efeld(a2, z-d , n, Q2, eps, &df2, f1); //Berechnung E-Feld des 2. Drahtes - double ges_E = df1 + df2; //Superposition der E-Felder der einzelnen Drähte - printf("Gesamtes E-Feld durch Addition ist: %f\n", ges_E); + printf("Gesamtes E-Feld (numerisch berechnet) durch Addition ist: %f\n", ges_efeld(n, a1, a2, z, Q1, Q2, d, &df1, &df2, f1, eps)); + printf("Gesamtes E-Feld (analytisch berechnet) durch Addition ist: %f\n", ges_efeld2(n, a1, a2, z, Q1, Q2, d, f2, eps)); + //H3.2 Nullstellenberechnung mit Sekantenverfahren + int schritt; //Variable zum speichern der Schrittanzahl des Sekantenverfahrens + + printf("Bitte geben Sie die Startwerte z1, z2 für die Bestimmung der Gleichgewichtslage an:\n"); + scanf("%lf %lf", &z1, &z2); + + /*Numerische Methode dauert aber sehr lange + printf("Gleichgewichtspunkt des Teilchens: %1.8f\n", secant(n, z1, z2, a1, a2, Q1, Q2, d, &df1, &df2, f1, eps, &schritt)); + */ + //analytische Methode + /*printf("Gleichgewichtspunkt des Teilchens: %1.8f\n", secant2(n, z1, z2, a1, a2, Q1, Q2, d, f2, eps, &schritt)); + printf("Schrittanzahl:%d\n",schritt);*/ return 0; }