Click here to Skip to main content
14,430,480 members
Rate this:
Please Sign up or sign in to vote.
See more:
Hello everybody. I'm trying to create the structure describing particles with some positions and velocity. I'm doing the following:
#define SIZE 1000000
#define nx 1000

typedef struct Species{
  double x[SIZE];
  double y[SIZE];
  double vx[SIZE];
  double vy[SIZE];
  double vz[SIZE];
  double dens[nx];
  double charge;
  double mass;
  long int num; //actual number of particles
  double QtoM;
  double sw; //weight of macroparticles
  char *bc_l;
  char *bc_r;
} species;


What I have tried:

I fill all arrays within the main function. When I compile the code, I don't see any warning or error message. But, when I run it, I see the message "stack overflow". As I understand correctly, the problem is with SIZE=1000000 because the code runs when I use SIZE=10000. Can anybody help me with this?

Thanks.May be, I should change my approach?
Posted
Updated 7-Apr-19 22:08pm
v2
Comments
Patrice T 7-Apr-19 20:13pm
   
you forgot to show the code.
Try to show enough code so that we can reproduce the error.
[no name] 10-Apr-19 11:48am
   
1
Rate this:
Please Sign up or sign in to vote.

Solution 1

Your struct Species has five members of size sizeof(double) * SIZE. For an X86 system that works out to about 38 MB of data when SIZE = 1,000,000. That means that for every struct Species you declare, you are using that much space on the stack.

I can think of 4 options:
1) modify your run-time environment to provide a larger stack
2) If you only have one instance of struct Species, you might consider declaring it globally. There's a whole lot of literature about global variables and when, where, why or why-not, so you should look into that before deciding to go that route
3) allocate on the heap e.g.
struct Species *s;
s = malloc(sizeof *s);

4) you have a member variable species.num. This seems to be the actual number of items you're tracking. If that's read in from somewhere, e.g a database or file, then you can minimize your memory use my allocating the large arrays individually e.g.
typedef struct  Species {
   double *x;
   double *y;
   // ? are we missing a double *z; here? 
   double *vx;
   double *vy;
   double *vz;
   size_t num; // actual number of particles n.b. changed to size_t
   ...
}species;
...
int main()
{
   species sp;

   sp.num = get_num_particles();   // determine number of particles in the system
   sp.x = malloc(num * sizeof *sp.x);
   sp.y = malloc(num *sizeof *sp.y);
   ...
   sp.vz = malloc(num *sizeof *sp.z);
   
   // do something interesting with sp

   free(sp.x);
   free(sp.y);
   ....
   free(sp.vz);
   
   return 0;
}

Note that we're not using sp.x = malloc(num * sizeof(double) to allocate memory. By using sp.x = malloc(num * sizeof *sp.x), if we change the type of sp.x to e.g. long double, we don't then need to go and find all the places we alloc() sp.x and make sure the type agrees, that's handled for us by the compiler.
   
Comments
DimaLevko 7-Apr-19 20:35pm
   
k5054, Thanks a lot. You answered my question. Now the code works. Thanks.
[no name] 10-Apr-19 11:48am
   
1
Rate this:
Please Sign up or sign in to vote.

Solution 2

The code is the following:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

// --- physical constants:
#define boltzmann (1.38e-23)
#define eps0 (8.89e-12)
#define AMU (1.67e-27)
#define qe (1.6e-19)
#define me (9.11e-31)
#define mi (4.0*AMU)
#define PI (3.1415926)
#define sq(x) (x*x)

#define SIZE 100000 //the largest number of particles
#define NP0 9000
#define nx 1000 //number of grid cells
#define time_step (1e-12)
#define pw (1e7) //weight of macroparticles
#define Scath (1e-4) //cathode surface area

#define Ucathode (-100.0)
#define ca_gap (1e-2)

long int seed;
long int i_max = 1000;

typedef struct Species{
  double x[SIZE];
  //double y[SIZE];
  double vx[SIZE];
  double vy[SIZE];
  //double vz[SIZE];
  double dens[nx];
  double charge;
  double mass;
  long int num; //actual number of particles
  double QtoM;
  double sw; //weight of macroparticles
  char *bc_l;
  char *bc_r;

} species;

int main(void){


  // --- define species:
  species electrons;
  electrons.charge = -qe;
  electrons.mass = me;
  electrons.num = NP0;
  electrons.QtoM = electrons.charge/electrons.mass;
  electrons.bc_l = "absorb";
  electrons.bc_r = "absorb";
  electrons.sw = pw;

  // --- seed initial plasma:
  seed = getpid();
  for (int j = 0; j < electrons.num; j++){
    electrons.x[j] = 0.0;
    electrons.vx[j] = 0.0;
  }

}</string.h></unistd.h></stdlib.h></math.h></stdio.h>
   
Comments
[no name] 10-Apr-19 11:48am
   
1
Rate this:
Please Sign up or sign in to vote.

Solution 3

I would go another way and define a "single specie only" struct and than dynamicly create an array. If you have global settings I would use another struct to hold them.

typedef struct SingleSpecie{
  double x;
  double y;
  double vx;
  double vy;
  double vz;
  double dens;
  double charge;
  double mass;
  //long int num; //actual number of particles - doesnt belong her
  double QtoM;
  double sw; //weight of macroparticles
  char *bc_l;
  char *bc_r;
} specie;
//create array 
SingleSpecie* allCreatures = malloc( myCount * sizeof(SingleSpecie) );
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100