Thanks a lot everyone. I think I have solved my problem, but using a different method. I am actually sorry for not providing you all the complete context of what I am doing, so that you could understand the problem I was having. Nevertheless, all of your solutions are definitely intuitive and surely each one of them would have been correct had it not been for the specific application. But my own implementation may be just one of the possible ways of doing it and perhaps you may have better suggestions if I tell you exactly what is my problem. Please feel free to decide whether or not you wish to read on and give me better suggestions, but all suggestions will definitely be welcome.
First of all, this is an elaborate Monte Carlo simulation program which I had originally written for electrons. I am trying to extend this to atoms, ions, phonons, photons protons and specific nuclei. The applications could vary from being used in CERN, research universities, nuclear power plants, defense organizations, semiconductor industry, chemical industry and so on. The program should do the following:
1. Generate a large number of particles about 1 million of them. This is a small number but because each particle object will occupy a minimum of 104 bytes of memory, this will soon explode in size, especially if we are simulating different kinds of particles in the same closed system. Note that even small systems in real life will have 10
20+ particles per cm
3. It is obviously impossible to make a program that can replicate that. So we use a scaling factor and upscale all results after the simulation.
2. Distribute the particles with random energy, momenta and positions in the system depending on certain specific conditions that will be application specific. Each type of particle will obey a certain thermodynamic statistics and that will be encoded separately.
3. In the presence of a particular kind of field (gravitational, electric or magnetic) the particles will move, but in the process they are likely to collide into neighbors. The simulation program's strength is in calculating this for different types of particles since the physics for each type of particle is slightly different. For example, F = ma wouldn't be right for electrons in crystals, nor would it be right for photons or phonons.
4. This iterative scattering is repeated over several cycles and the results are aggregated. The repetition over several cycles is normally sent to a MPI (message passing interface) to make it faster.
Now, if I hadn't this large an application, making
mass and
dia into non-static members would have been fine. But that would mean more space. Each particle contains two vectors (position and momentum) and a scalar, Energy along with other data for calculating the mean free path of the particle. So each byte comes at a premium. So static members are important wherever the data is identical. At the same time, I also needed that I can make atoms of different types. So in the program, I wanted to define
dia and
mass for a Hydrogen atom as well as for a Helium atom, but while using static members. One possible way, was to make Helium and Hydrogen as inherited classes of atom, but that would mean that we'll have to define every single kind of atom. Since the physics for atoms in a gas is nearly identical across elements, except for these two parameters, I did not want to keep defining every type of atom.
Instead, I did the following:
I moved the class definition of atom to a separate file atom.h. In another file called atomtypes.h I created several namespaces as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
namespace Hydrogen {
#ifndef __ATOM_H
#include "atom.h"
#endif
double atom::dia = (2*GSL_CONST_MKSA_BOHR_RADIUS);
double atom::mass = GSL_CONST_MKSA_MASS_PROTON;
}
namespace Helium {
#ifndef __ATOM_H
#include "atom.h"
#endif
double atom::dia = (2.34*GSL_CONST_MKSA_BOHR_RADIUS);
double atom::mass = 2*(GSL_CONST_MKSA_MASS_PROTON + GSL_CONST_MKSA_MASS_NEUTRON);
}
|
So in my main program, I could simply say:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
int main() {
system("del gas.mat");
System gas;
gas.setsize(1.0e-5, 1.0e-5, 1.0e-5);
gas.setTemp(650); //in Kelvin scale
simulation<Hydrogen::atom> Hsim;
Hsim.setup(NUMPARTICLES, NUMTSTEPS, 1.0e-12, &gas);
simulation<Hydrogen::atom> Hesim;
Hesim.setup(NUMPARTICLES, NUMTSTEPS, 1.0e-12, &gas);
mpich.runparallel(Hsim.simulate, Hesim.simulate);
simulation.dumpdata(gas.mat); //In MATLAB format
return 0;
}
|
Any of you have a better software architecture for this problem?