Решение уравнения Пуассона с использованием базовых циклов

Моя программа запускается. Однако кажется, что цикл do-while не будет зацикливаться. Это потому, что выходные данные всегда объявляют "... было получено после 1 итерации". Я имею в виду, что это должно занять более 1 итерации. Я хотел бы попросить о помощи, потому что я сейчас стою перед кирпичной стеной. Спасибо!

#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>
#include <string>

using namespace std;

int main()
{
   int i,j,n,iter1=0,iter2=0;
   double L,t,q,E,v,h,D,error,e;

   cout << "\nUse length, L (m): ";
   cin >> L;
   cout << "\nUse thickness, t (m): ";
   cin >> t;
   cout << "\nUse uniform load, q (N/m^2): ";
   cin >> q;
   cout << "\nUse Young's modulus, E (N/m^2): ";
   cin >> E;
   cout << "\nUse Poisson's ratio, v: ";
   cin >> v;
   D=(E*pow(t,3))/(12*(1-pow(v,2)));
   cout << "\nUse uniform interval, n: ";
   cin >> n;
   double u[n+1][n+1],r[n+1][n+1],w[n+1][n+1];
   h = L/n;
   cout << "\nUse tolerance, e: ";
   cin >> e;

   //PERFORM THE ITERATIONS!
   cout << "* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n" ;
   cout.precision(5);
   cout.setf(ios::fixed);

   for (i=0;i<=n;i++)
   for (j=0;j<=n;j++)
   {
      u[i][j]=0;
      r[i][j]=0;
      w[i][j]=0;
   }

  //Set the boundary conditions
  for (i=0;i<=n;i++)
  {
      u[i][0]=0;
      u[i][n]=0;
      u[0][i]=0;
      u[0][i]=0;
  }

  //Solving for the u-matrix
do
{
    error=0;
    for (i=0;i<n;i++)
    for (j=0;j<n;j++)
    {
        r[i][j]=0.25*(u[i-1][j]+u[i+1][j]+u[i][j-1]+u[i][j+1]-4*u[i][j]-pow(h,2)*(q/D));
        u[i][j]+=r[i][j];
    }
    iter1++;

    if (abs(r[i][j])>error)
    error = abs(r[i][j]);
}
while (error>e);

//Solving for the w-matrix
do
{
    error=0;
    for (i=0;i<n;i++)
    for (j=0;j<n;j++)
    {
        r[i][j]=0.25*(w[i-1][j]+w[i+1][j]+w[i][j-1]+w[i][j+1]-4*w[i][j]-pow(h,2)*(u[i][j]));
        w[i][j]+=r[i][j];
    }
    iter2++;

    if (abs(r[i][j])>error)
    error = abs(r[i][j]);
}
while (error>e);

//RESULTS!
cout << "\nThe matrix of deflection w was obtained after " << iter2 << " iterations" << endl;
cout << "\n(The matrix of variable u was obtained after " << iter1 << " iterations" << endl;
cout << "\n";
cout << "\nFor the matrix of deflection w, open the generated Excel file.\n";

return 0;
}

2 ответа

Лучшим решением является использование контейнера, который будет прозрачно управлять назначением, копированием, уничтожением и т. Д. Без утечек памяти.

Есть много реализаций, вот основная

template<typename T>
class Matrix {
private:
  unsigned int m_rows, m_cols;
  std::vector<T> m_data;
public:

  Matrix(unsigned int r, unsigned int c) // constructor
  : m_rows{r}
  , m_cols{c}
  , m_data(r * c)          // size of the vector
  {}
  T * operator[](int r)  // address of first element of row r 
  {
    return & m_data[ r * m_cols ];
  }
};

Пример того, как его использовать

  Matrix<int> m(3,4);        // declare a matrix

  for (int r = 0; r < 3; r++)
     for (int c=0; c<4; c++) 
        m[r][c] =  10*r + c;  // usual notation

  for (int r = 0; r < 3; r++) {
     for (int c=0; c<4; c++) {
      std::cout << m[r][c] << "\t";
     }
  std::cout << std::endl;
 }

Вы не можете объявить такие массивы double u[n+1][n+1],r[n+1][n+1],w[n+1][n+1]; потому что переменная n неизвестно время объявления массива. Я думаю, что это не может быть объявлено таким образом, даже если n известен во время выполнения. Это возможно, только если n известен во время компиляции.

Массивы должны быть объявлены как double **u; и когда переменная n известное использование malloc или же new,

int n;
double **u;
double **r;
double **w;

cout << "\nUse uniform interval, n: ";
cin >> n;

// C style of allocation, requires additional library, I think it's cstdlib
u = (double**)malloc(sizeof(double*)*(n+1));
for(int i = 0; i <= n; ++i) {
    u[i] = (double*)malloc(sizeof(double)*(n+1));
}

// C++ style of allocation
r = new double*[n+1];
for(int i = 0; i <= n; ++i) {
    r[i] = new double[n+1];
}

// C++11 or newer - compile with --c++11 flag
w = new double[n+1][n+1];

// Don't forget to clear memory
// C style
free(u);

// C++ style
delete r;
delete w;
Другие вопросы по тегам