Einzelnen Beitrag anzeigen

Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#1

Finde kein Konvergenzkriterium für eine Iteration

  Alt 10. Nov 2015, 20:39
Delphi-Version: 2007
Ich habe eine Iteration. Ausgehend von einem Wert kX wir ein erster Wert "Force" ermittelt. Anschließend werden 3 weitere Werte ermittelt. Das geschieht aus 3 Gleichungen mit 3 Unbekannten (-> "TopRight", "BottomLeft" und "BottomRight"). Diese Werte werden in die Gleichungen eingesetzt und überprüft, ob alle 3 Gleichungen Null werden. Ist das so, dann hat man das richtige kX gefundent. Mein Problem hier ist, daß ich kein Konvergenzkriterium finde. Es iteriert nicht. Die Werte springen. Wie könnte man denn das machen? Probiere schon ein ganze Weile..

Delphi-Quellcode:
function TBoltApproximationEx.CalcDefault: boolean; // KX = 0 .. 1;
var
  I: integer;
  OldValue: double;
  NewValue: double;
  Alpha: double;
  KxV: double;
  dKxV: double;
  XV: double;
  C: double;
  B: double;
  D: double;
  X: double;
  hx: double;
  hy: double;
  c1: double;
  d1: double;
  aX: double;
  aY: double;
  TopRight: double;
  BottomLeft: double;
  BottomRight: double;
  Force: double;
  SigmaD: double;
  Mx: double;
  My: double;
  SumN: double;
  SumMx: double;
  SumMy: double;
  TopRightX: double;
  TopRightY: double;
  BottomLeftX: double;
  BottomLeftY: double;
begin
  FStrings.Clear;

  Alpha := GetAlpha;
  C := Cos(Alpha);

  Mx := Abs(FMX);
  My := Abs(FMY);

  b := FB / 1000; // m;
  d := FD / 1000;
  c1 := FC1 / 1000;
  d1 := FD1 / 1000;

  hx := d - c1; // c2 = c1;
  hy := b - d1; // d2 = d1;

  TopRightX := b - d1; // TopRight;
  TopRightY := -c1;
  BottomLeftX := d1; // BottomLeft;
  BottomLeftY := -d + c1;

  KxV := 0;
  dKxV := 0.001;

  NewValue := 0;
  I := 0;
  repeat // KxV;
    Inc(I);
    OldValue := NewValue;

    XV := KxV * hx; // m;
    FPolygon.SetFromBemeRect(b, d, XV, Alpha);
    FPolygon.Calc;

    X := XV * C;
    SigmaD := 0.5 * Min(FFy * 1E3, FFy * 1E3 * X / (hx - X)); // kN/m2; FFy = Material N/mm2;

    Force := -FPolygon.Area * SigmaD; // kN;
    aX := FPolygon.CenterX; // m;
    aY := -FPolygon.CenterY; // m;

    if FPolygon.PtIn(TopRightX, TopRightY) and FPolygon.PtIn(BottomLeftX, BottomLeftY) then
    begin
      TopRight := 0;
      BottomLeft := 0;
      BottomRight := FN - Force;
    end
    else
      if FPolygon.PtIn(TopRightX, TopRightY) then
      begin
        TopRight := 0;

        FGauss.Count := 2;

        FGauss.A[0, 0] := hx;
        FGauss.A[0, 1] := hx;
        FGauss.B[0] := Mx + FN * d / 2 - Force * aY;

        FGauss.A[1, 0] := d1;
        FGauss.A[1, 1] := hy;
        FGauss.B[1] := My + FN * b / 2 - Force * aX;

        FGauss.Complete;
        FGauss.Solve;
        BottomLeft := Max(FGauss.X[0], 0);
        BottomRight := Max(FGauss.X[1], 0);
      end
      else
        if FPolygon.PtIn(BottomLeftX, BottomLeftY) then
        begin
          BottomLeft := 0;

          FGauss.Count := 2;

          FGauss.A[0, 0] := hx;
          FGauss.A[0, 1] := c1;
          FGauss.B[0] := Mx + FN * d / 2 - Force * aY;

          FGauss.A[1, 0] := hy;
          FGauss.A[1, 1] := hy;
          FGauss.B[1] := My + FN * b / 2 - Force * aX;

          FGauss.Complete;
          FGauss.Solve;
          BottomRight := Max(FGauss.X[0], 0);
          TopRight := Max(FGauss.X[1], 0);
        end
        else
        begin
          FGauss.Count := 3;

          FGauss.A[0, 0] := hx;
          FGauss.A[0, 1] := hx;
          FGauss.A[0, 2] := c1;
          FGauss.B[0] := Mx + FN * d / 2 - Force * aY;

          FGauss.A[1, 0] := d1;
          FGauss.A[1, 1] := hy;
          FGauss.A[1, 2] := hy;
          FGauss.B[1] := My + FN * b / 2 - Force * aX;

          FGauss.A[2, 0] := 1;
          FGauss.A[2, 1] := 1;
          FGauss.A[2, 2] := 1;
          FGauss.B[2] := FN - Force;

          FGauss.Complete;
          FGauss.Solve;
          BottomLeft := Max(FGauss.X[0], 0);
          BottomRight := Max(FGauss.X[1], 0);
          TopRight := Max(FGauss.X[2], 0);
        end;

    // Bedingung 1: Summe Mx = 0;
    SumMx := -Mx -FN * d / 2 + Force * aY + BottomLeft * hx + BottomRight * hx + TopRight * c1; // kNm;
    // Bedingung 2: Summe My = 0;
    SumMy := -My -FN * b / 2 + Force * aX + BottomLeft * d1 + BottomRight * hy + TopRight * hy; // kNm;
    // Bedingung 3: Summe N = 0;
    SumN := -FN + Force + BottomLeft + BottomRight + TopRight; // kN;

    NewValue := SumN; // oder SumMx oder SumMy ???
    if NewValue * OldValue < 0 then dKxV := -dKxV / 2;

    KxV := KxV + dKxV;

    FStrings.Add(Format('I %4d N %4d X %.2f SumMx %.4f SumMy %.4f SumN %.4f Force %.4f TopRight %.4f BottomLeft %.4f BottomRight %.4f',
      [I, FGauss.Count, 100 * X, SumMx, SumMy, SumN, Force, TopRight, BottomLeft, BottomRight]));

  until (I = 10000) or (Abs(NewValue) < 0.01);
end;
  Mit Zitat antworten Zitat