-1

My program runs. However, it seems that the do-while loop won't loop. This is because the output always declare "...was obtained after 1 iterations". I mean it should take more than 1 iterations. I would like to ask for help for I am facing a brick wall right now. Thanks!

#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;
}
  • `double u[n+1][n+1],r[n+1][n+1],w[n+1][n+1];` -- This is not valid C++ code. Arrays in C++ must use a constant expression to denote the number of entries, not a variable. Second, even if it were valid code, why are you using `n` in there when `n` is uninitialized? C++ programs run top-down -- you set `n` far below in the `cin` statement, way after you've declared your arrays. That `n` isn't magically going to make those arrays have `n` size. – PaulMcKenzie May 25 '17 at 16:03
  • Also, your n is not initialized before you try to use it as an array size. Instead of using n from user input for your array sizes, you should #define MAX_N (WHATEVER) and make your arrays that size. – Dmitri May 25 '17 at 16:06
  • Oh thanks man for the insight. Honestly, I am new to c++ or any programming language. Will check again my code – Mark Louie May 25 '17 at 16:07
  • I have corrected it. And it works now. However, the solution ALWAYS terminate after 1 iteration only. I mean it should take more than 1 iteration. – Mark Louie May 25 '17 at 16:18

2 Answers2

1

A better solution is to use a container, which will transparently manage assignment, copy, destruction, etc. without memory leaks.

There are plenty of implementations, here is a basic one

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 ];
  }
};

Example of how to use it

  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;
 }
Michel Billaud
  • 1,758
  • 11
  • 14
0

You can't declare arrays like that double u[n+1][n+1],r[n+1][n+1],w[n+1][n+1]; because variable n isn't known the time when array is declared. I guess it can't be declared that way even if the n is known during run time. It's possible only if the n is known during compilation.

The arrays should be declared as double **u; and when variable n is known use malloc or 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;
Jirka Picek
  • 589
  • 5
  • 19
  • what's the trade off between the 2 methods? it seems that the 2nd method of allocation is pretty straightforward. Anyways, thanks man. Will check my code. – Mark Louie May 25 '17 at 16:30
  • error: array size in new-expression must be constant. So how can I pull this off? the n is a variable – Mark Louie May 25 '17 at 16:36
  • Yes the second should be better for C++ language, but I was using C language more so I'm more used to it. and I forget to mention clearing memory. – Jirka Picek May 25 '17 at 16:40
  • The answer for the new error should be [here](https://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new), I'll update my answer. I thought that C++ supports it, maybe in new version like C++14 or so – Jirka Picek May 25 '17 at 16:40