0

I'm trying to write a simple MD program in C/C++ (I'm used to C but I'm trying to learning C++, so my code is a little "mix"... I know that this is suboptimal and I will move to full C++ as soon as I fully understand it).

Everything seems to run but I have divergences in Kinetic energy, the system does not thermalize and temperature (prop to K) goes from order(10°K) to order(10000°K) in a single step.

I'm working with a low time-step of 0.002 (total time of simulation: 30) so I should not have this enormous error...

This is my code, if something is not clear I can try to explain it better

int main(){

...

int n, t, m, i;
double r, K, U, E,P,  totalE, temperature, d, x,y,z, temp;

...

double data[5][PARTICELLE], vel[3][PARTICELLE],dataNew[3][PARTICELLE]; //0,1,2 are x,y,z. 3, 4 for data are Energy and Pressure
double force[3][PARTICELLE], forceNew[3][PARTICELLE];
double velQ[PARTICELLE]; //square velocity

ofstream out(OUTDATA);

//inizio MD

for(t=0; t<PASSI; t++){
    //inizialization
    K=0;
    U=0;
    E=0;
    P=0;
    fill(data[3], data[3]+PARTICELLE, 0); //E=0 for each particle
    fill(data[4], data[4]+PARTICELLE, 0);
    fill(velQ, velQ+PARTICELLE, 0);
    for(i=0; i<3; i++){
        fill(force[i], force[i]+PARTICELLE, 0);
        fill(forceNew[i], forceNew[i]+PARTICELLE, 0);
    }
    for(n=0; n<PARTICELLE; n++) { //for on the n_ particle. A step is a move of n=PARTICELLE particles
        for (i = 0; i < 3; i++) { //compute vSquare
            velQ[n] += vel[i][n] * vel[i][n];
        }
        K += 0.5 * MASSA * velQ[n]; //compute Kinetic Energy
        for(m=0; m<PARTICELLE; m++){ //loop on m!=n to compute F, E, P
            if(m!=n){
                r=0;
                for(i=0; i<3; i++){ //calculation of radius and x,y,z 
                    d = data[i][m] - data[i][n];
                    d = d - (NINT(d / LATO) * LATO);
                    if(i==0)x=d;
                    if(i==1)y=d;
                    if(i==2)z=d;
                    r += d * d;
                }
                //if (t<2) cout << "x y z" << x << " " << y << " " << z << endl;
                r=sqrt(r);
                if (r < R) {
                    data[3][n] += energy(r); //update Energy of n
                    for(i=0; i<3; i++){
                        if(i==0)temp=x;
                        if(i==1)temp=y;
                        if(i==2)temp=z;
                        force[i][n]+=forza(r,temp); //compute force (cartesian components)
                        //if(t<2)cout << "force " <<n << " " << m << " "<< force[i][n] << endl;
                    }
                    if (m < n)data[4][n] += (-energy(r) * (1 + r)); //pressure
                }
            }
        }
        U+=data[3][n]; //total potential energy 
        P+=data[4][n]; //total pressure
        for (i = 0; i < 3; i++) { //Verlet update, part 1
            dataNew[i][n] = data[i][n] + vel[i][n] * DeltaT + 0.5 * force[i][n] * DeltaT * DeltaT / MASSA;
        }
        for(m=0; m<PARTICELLE; m++){ //update force
            if(m!=n){
                r=0;
                for(i=0; i<3; i++){
                    d = data[i][m] - dataNew[i][n];
                    d = d - (NINT(d / LATO) * LATO);
                    if(i==0)x=d;
                    if(i==1)y=d;
                    if(i==2)z=d;
                    r += d * d;
                }
                r=sqrt(r);
                if (r < R) {
                    for(i=0; i<3; i++) {
                        if (i == 0)temp = x;
                        if (i == 1)temp = y;
                        if (i == 2)temp = z;
                        forceNew[i][n] += forza(r, temp);

                    }
                }
            }
        }
        for(i=0; i<3; i++){ //new position and Verlet part 2 
            data[i][n]=dataNew[i][n];
            vel[i][n]=vel[i][n] + DeltaT * 0.5*(forceNew[i][n] + force[i][n]) / MASSA;
        }
    }
    totalE=U+K; //total energy
    temperature = 2*K/(PARTICELLE*3);
    out << t*DeltaT << " " << U  << " " << P  << " " << totalE  << " " << temperature << endl;
}
out.close();
return 0;
}

where my system is under a potential e^-r/r, so I have:

double energy( double r){
return (A*SIGMA*exp(-r/SIGMA)/r);
}
double forza(double r, double h){ //h is for x,y,z
    double bubba;
    bubba= (A*SIGMA*(exp(-r)*h*(r+1)/(r*r*r)));
    return bubba;
}

Thanks for any help. I'm working on this code since April and still I have no solution...

edit: to be clearer: CAPITAL terms and DeltaT are values defined in DEFINE

Aethyr
  • 1
  • 2
  • C and C++ are different languages. Each has features that the other does not. You must choose *one*; you cannot "mix", at least not in the same translation unit. Which one you are actually using ultimately depends on how you are compiling. – John Bollinger Jun 09 '16 at 16:17
  • 1
    In any case, this is Stack Overflow, not Physics SE. Although some of us may know a bit about MD, no one wants to analyze your source to figure out how the problem you describe corresponds to the code. If you want an answer then your best bet is to re-cast the question specifically in terms of the source code you are presenting. Also, your chances would be improved if you were able to provide a [mcve]. – John Bollinger Jun 09 '16 at 16:21
  • It'll take a while, but if you know what the algorithm is supposed to produce at each step, then use a debugger and go through it line by line to figure out where the values being changed diverge from what you expect. – RyanP Jun 09 '16 at 16:49
  • Why not separate your tasks? I am sure you are experienced enough to know that first you should get the program working to your satisfaction in a language you know, and then port it. – Weather Vane Jun 09 '16 at 17:29
  • @JohnBollinger I'm compiling in c++ but a lot of command and syntax is still based on my c knowledge, I'm pretty sure c++ users could improve it. For what concern Stack Overflow, I'm new on this site... do you mean I should repost this question on [this site](https://physics.stackexchange.com)? I read Minimal, complete... link before posting my question, and that's the clearest code I am able to provide. What should I do to improve it? – Aethyr Jun 09 '16 at 18:39
  • @WeatherVane I use c++ only when I don't remember how to write that particular command in c and internet usually provide a better answer in c++. For example I used to set my arrays to 0 with boring for cycles, then I discovered std::fill and I switched to this c++ smart function. I will search on the web about debugger, I have never used one before. I hope I can find something to fix my problem... thanks! – Aethyr Jun 09 '16 at 18:46
  • @Aethyr in C you can set an array to `0` with `memset` or by defining them as say `int array[MYSIZE] = {0};` – Weather Vane Jun 09 '16 at 18:48
  • @WeatherVane I need to set it 0 in my for(t, PASSI) cycle, so I can not simply define it `={0}` . I will read manual for `memset`, I don't know why but I remember I can use it only for an integer array... I'm probably wrong. However, `fill` should work as well, my c++ compiler tells me that using c function in a c++ ambient is deprecated, not completely wrong. Thank you for your advice, I will use it for sure :) – Aethyr Jun 09 '16 at 18:58
  • @Aethyr you can use `memset` for any contiguous block of memory of any type whose size you know. It takes `void*` pointer but you must be careful to provide the size in *bytes* and not in *elements*. – Weather Vane Jun 09 '16 at 19:33
  • @Aethyr, actually no, I do not recommend posting your problem on Physics SE, (or Chemistry SE) either. You might find someone there more familiar with MD, but those are not places for programming problems. No, I mean *exactly what I said*: "re-cast the question specifically in terms of the source code you are presenting. Also, your chances would be improved if you were able to provide a [mcve]." – John Bollinger Jun 09 '16 at 20:50
  • @JohnBollinger I have misread you, english is not my main language, I'm sorry. However, I don't understand how I can re-cast it. I don't know where the problem is,I have a term that should be "constant" and it diverges.This code could be for MD or for a game, this is not the real point: I specified it was for MD because I want to give all the information I have. I checked for _the Minimal, Complete and Verifiable example_. My question is Minimal: I can not remove any part of this code because Energy is a sum of terms, and every term is pretty much small, so I have to give you the entire cycle – Aethyr Jun 09 '16 at 22:58
  • Complete: I give you my entire "Update" cycle, my functions, my declarations... I missed some `DEFINE` but I'm pretty sure they are understandable. Verifiable: my code give not compiling errors, the example reproduce the problem (I tried) and I think I specified where the problem is: approximately constant quantities (in theory) diverge during simulation. What can I do to provide a better question that reflect your link? Thank you ! @WeatherVane Thank you too!! – Aethyr Jun 09 '16 at 23:05

0 Answers0