Решение уравнения Пуассона с использованием базовых циклов
Моя программа запускается. Однако кажется, что цикл 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;