15,997,806 members
0.00/5 (No votes)
See more:
I wrote a code to simulate the NO-CO reaction on a square surface in C language, but every time my program calculates a new site at random, the matrix doesn't look the same, even when in the code hasn't it is not intended.

What I have tried:

```#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>

//define the dimensions of the latice
#define xmax 2
#define ymax 2

//define teh Monte Carlo steps
#define MCSS 100
//define the "empty" and "occupied" states
#define empty 0
#define occupied 1
//define if the site is occupied by CO, NO, N, or O
#define co_occupied 2
#define no_occupied 3
#define n_occupied 4
#define o_occupied 5
//define the probability whether a site is occupied or not
#define p 0.300000
//define the probability that CO is adsorbed
#define xco 0.4
//define the disociation rate of NO
#define rno 0.6

//Function that selects the x-coordinate of the chosen site randomly
int printrandomx(int lower, int upper, int cuenta)
{
int m, num1;
for (m = 0; m < cuenta ; m++) {
num1 = (rand() % (upper - lower + 1)) + lower;
// printf("random x: %d \n", num1);
}
return num1;
}

//Function that selects the y-coordinate of the chosen site randomly
int printrandomy(int bajo, int alto, int contar)
{
int n,num2;
for (n = 0; n < contar; n++) {
num2 = (rand() % (alto - bajo + 1)) + bajo;
//printf("random y: %d \n", num2);
}
return num2;
}

//Function that gives us four nearest neighbors of a chosen site considering periodic boundary conditions
int get_limited_coord(int coord, int coord_max)
{
if (coord >= 0 && coord < coord_max) {

return coord;

} else if (coord >= coord_max) {

return coord - coord_max;

} else {

return coord + coord_max;

}
}

int main(){
FILE *fp;
fp  = fopen ("data.txt", "w");
srand(time(0));

int N = xmax*ymax;
int grid[xmax][ymax];
int lower = 0, bajo=0, upper=xmax-1, alto=ymax-1, cuenta=1, contar=1;
int count = 1, x=0, y=0;
int right, left, up, down;
double random,q,r;
int co = 0, no = 0, n = 0, o = 0, v = N, pco2 = 0, pn2 = 0, po2 = 0;

// Initialize lattice values to 0
for (int i = 0; i < xmax; i++) {
for (int j = 0; j < ymax; j++) {
grid[i][j] = empty;
}
}

step1:
//LOCATE AN ENTRY OF THE MATRIX RANDOMLY
for (int i = 0; i < xmax; i++) {
for (int j = 0; j < ymax; j++) {
grid[i][j] = count++;
printf("%d ", grid[i][j]);
}
printf("\n");
}

x = printrandomx(lower, upper, cuenta);
y = printrandomy(bajo, alto, contar);
printf("(x,y)=(%d,%d)\n\n",y,x);

for (int i = 0; i < xmax; i++)
{
for (int j = 0; j < ymax; j++ )
{

if(x == i && y == j){ grid[x][y] == count; }
// else{ printf("FAILED\n");}
}

}
printf("The coordinates are (%d,%d) and the solicited matrix entry is: %d\n\n", y, x, grid[y][x]);

if (x > xmax || x < 0 || y > ymax || y < 0) {
printf ("Invalid coordinates given\n");
return 1;
}

//EVALUATE IF THE CHOSEN SITE IS EITHER EMPTY OR OCCUPIED
printf("IS IT OCCUPIED???\n\n\n");

//random = (double) rand () / RAND_MAX;
//printf("random = %lf\n\n",random);
// Include particle based on the probability
if (grid[y][x] == occupied){

printf("It's occupied, the trial ends. Choose another site again\n\n");
goto step1;

}
else{

printf("It's empty. Let's go to generate a random number to choose the adsorbates\n\n");
goto step2;

}

//Let's choose the molecule that will be adsorbed
//we generate a random number so that if it is less than xco, CO is adsorbed and if the number is greater than xco, NO is adsorbed

step2:
q = (double) rand () / RAND_MAX;
printf("random q= %lf\n\n",q);

if(q < xco || q == xco){
//se adsorbe CO
printf("CO is adsorbed\n\n");
grid[y][x] = co_occupied;
co = co + 1;
v = v - 1;
printf("adsorbed CO ---> co = %d\n\n",co);

//step3:
printf("FIND THE NEIGHBORS OF THE ADSORBED CO\n\n");
//THESE PRINT THE FOUR NEAREST NEIGHBORS OF THE CHOSEN SITE

right = grid[get_limited_coord(y , ymax)][get_limited_coord(x+1, xmax)];
left = grid[get_limited_coord(y , ymax)][get_limited_coord(x-1, xmax)];
up = grid[get_limited_coord(y-1, ymax)][get_limited_coord(x , xmax)];
down = grid[get_limited_coord(y+1, ymax)][get_limited_coord(x , xmax)];
//printf("The coordinates are (%d,%d) and the solicited matrix entry is: %d\n", x, y, grid[y][x]);
//Printing the eight nearest neighbors
printf("Right: %d\nLeft: %d\nUp: %d\nDown: %d\n\n",right,left,up,down);

//step4:
if( (right == o_occupied) || (left == o_occupied) || (up == o_occupied) || (down == o_occupied) ){
printf("It was encountered a site with O!\n\n");
pco2 = pco2 + 1;
v = v + 2;
printf("produced co2 = %d\n\n",pco2);
} else{
printf("It wasn't encountered a site with O :(\n\n");
printf("CO2 IS NOT PRODUCED\n\n");
}
} else {
//se escoge NO
printf("q = %lf is greater than xco = %lf. We choose NO\n\n", q, xco);
r = (double) rand () / RAND_MAX;
printf("r= %lf\n\n", r);

if(r < rno){
printf("r= %lf is less than rno= %lf\n\n We seek another neighbor to decide if NO can disociate\n\n", r,rno);

printf("FIND THE NEIGHBORS SO THAT NO CAN BE DISOCIATED\n\n");
//THESE PRINT THE FOUR NEAREST NEIGHBORS OF THE CHOSEN SITE
//Looking up the nearest 8 neighbors (If the chosen entry is not on any edge of the matrix)
right = grid[get_limited_coord(y , ymax)][get_limited_coord(x+1, xmax)];
left = grid[get_limited_coord(y , ymax)][get_limited_coord(x-1, xmax)];
up = grid[get_limited_coord(y-1, ymax)][get_limited_coord(x , xmax)];
down = grid[get_limited_coord(y+1, ymax)][get_limited_coord(x , xmax)];
//printf("The coordinates are (%d,%d) and the solicited matrix entry is: %d\n", x, y, grid[y][x]);
//Printing the eight nearest neighbors
printf("Right: %d\nLeft: %d\nUp: %d\nDown: %d\n\n",right,left,up,down);

if( (right == empty) || (left == empty) || (up == empty) || (down == empty) ){
printf("It was encountered another site so that NO can disociate!\n\n");
n = n + 1;
o = o + 1;
v = v - 2;

printf("adsorbed N ---> n= %d\n adsorbed O ---> o= %d\n",n, o);
}else{
printf("****WE DIDN'T FIND AN EMPTY NEIGHBOR SO,THE TRIAL ENDS, START AGAIN****\n\n");
goto step1;
}
}else{  printf("r= %lf is greater than rno= %lf\n\n So, NO remains in its molecular form\n\n",r, rno);
printf("FIND THE NEIGHBORS OF THE NO IN ITS MOLECULAR FORM\n\n");
//THESE PRINT THE FOUR NEAREST NEIGHBORS OF THE CHOSEN SITE
//Looking up the nearest 8 neighbors (If the chosen entry is not on any edge of the matrix)
right = grid[get_limited_coord(y , ymax)][get_limited_coord(x+1, xmax)];
left = grid[get_limited_coord(y , ymax)][get_limited_coord(x-1, xmax)];
up = grid[get_limited_coord(y-1, ymax)][get_limited_coord(x , xmax)];
down = grid[get_limited_coord(y+1, ymax)][get_limited_coord(x , xmax)];

//Printing the eight nearest neighbors
printf("Right: %d\nLeft: %d\nUp: %d\nDown: %d\n\n",right,left,up,down);

if( (right == n_occupied) || (left == n_occupied) || (up == n_occupied) || (down == n_occupied) ){
printf("se ha encontrado un N, entonces se va a formar N2 y quedara adsorbido O, dejando un sitio vacante\n\n");
pn2 = pn2 +1;
o = o + 1;
v = v + 1;
}else{

printf("****THERE IS NO N TO REACT ---> THE TRIAL ENDS, START AGAIN****\n\n\n");
goto step1;
}
}

}

fclose(fp);
return 0;
}```

I think the code is not "remembering" the prior state and that's the reason it gives me a new matrix very time it finds a new site at random. How could I fix this?
Posted
Updated 29-Jan-23 13:11pm
v2
Comments
Rick York 29-Jan-23 22:04pm
You are opening a file for write access but nothing is written to it so that is unnecessary.

As mentioned, using gotos is not recommended. There are at least two alternatives : use functions or use looping constructs. The keywords continue and break are very useful with loops. The three looping options are do, while, and for. This page : https://cplusplus.com/doc/tutorial/control/ is from a tutorial and it covers flow control mechanisms including loops.
yuike 30-Jan-23 7:00am
Thank you. I will check it right now:)
yuike 30-Jan-23 6:58am
Also, I see that the program doesn't even remember if a "site" of the matrix is occupied or not by NO, O, CO or N.

## Solution 1

C
`grid[x][y] == count;`

operator has no effect; is "=" intended?

C
`goto step1;`

gotos are very bad style

C
```// FILE *fp;
// int upleft, upright, downleft, downright;  unused vars
// double random;```

several vars not used

Comments in Spanish are not very helpful in an English-speaking forum.

For example, a sample run after troubleshooting results in this:

```9 10
11 12
(x,y)=(1,1)

The coordinates are (1,1) and the solicited matrix entry is: 13

IS IT OCCUPIED???

It's empty. Let's go to generate a random number to choose the adsorbates

random q= 0.262246

CO is adsorbed

adsorbed CO ---> co = 1

FIND THE NEIGHBORS OF THE ADSORBED CO

Right: 11
Left: 11
Up: 10
Down: 10

It wasn't encountered a site with O :(

CO2 IS NOT PRODUCED```

Where exactly is the problem to be found here?

Comments
yuike 29-Jan-23 19:02pm
To explain myself better, the following is the output of my code

```1 2
3 4
(x,y)=(0,0)

The coordinates are (0,0) and the solicited matrix entry is: 1

IS IT OCCUPIED???

It's occupied, the trial ends. Choose another site again

5 6
7 8
(x,y)=(0,1)

The coordinates are (0,1) and the solicited matrix entry is: 6

IS IT OCCUPIED???

It's empty. Let's go to generate a random number to choose the adsorbates

random q= 0.663232

q = 0.663232 is greater than xco = 0.400000. We choose NO

r= 0.045448

r= 0.045448 is less than rno= 0.600000

We seek another neighbor to decide if NO can disociate

FIND THE NEIGHBORS SO THAT NO CAN BE DISOCIATED

Right: 5
Left: 5
Up: 8
Down: 8

****WE DIDN'T FIND AN EMPTY NEIGHBOR SO,THE TRIAL ENDS, START AGAIN****

9 10
11 12
(x,y)=(1,0)

The coordinates are (1,0) and the solicited matrix entry is: 11

IS IT OCCUPIED???

It's empty. Let's go to generate a random number to choose the adsorbates

random q= 0.896695

q = 0.896695 is greater than xco = 0.400000. We choose NO

r= 0.358901

r= 0.358901 is less than rno= 0.600000

We seek another neighbor to decide if NO can disociate

FIND THE NEIGHBORS SO THAT NO CAN BE DISOCIATED

Right: 12
Left: 12
Up: 9
Down: 9

****WE DIDN'T FIND AN EMPTY NEIGHBOR SO,THE TRIAL ENDS, START AGAIN****

13 14
15 16
(x,y)=(0,0)

The coordinates are (0,0) and the solicited matrix entry is: 13

IS IT OCCUPIED???

It's empty. Let's go to generate a random number to choose the adsorbates

random q= 0.540815

q = 0.540815 is greater than xco = 0.400000. We choose NO

r= 0.274174

r= 0.274174 is less than rno= 0.600000

We seek another neighbor to decide if NO can disociate

FIND THE NEIGHBORS SO THAT NO CAN BE DISOCIATED

Right: 14
Left: 14
Up: 15
Down: 15

****WE DIDN'T FIND AN EMPTY NEIGHBOR SO,THE TRIAL ENDS, START AGAIN****

17 18
19 20
(x,y)=(1,1)

The coordinates are (1,1) and the solicited matrix entry is: 20

IS IT OCCUPIED???

It's empty. Let's go to generate a random number to choose the adsorbates

random q= 0.474475

q = 0.474475 is greater than xco = 0.400000. We choose NO

r= 0.114339

r= 0.114339 is less than rno= 0.600000

We seek another neighbor to decide if NO can disociate

FIND THE NEIGHBORS SO THAT NO CAN BE DISOCIATED

Right: 19
Left: 19
Up: 18
Down: 18

****WE DIDN'T FIND AN EMPTY NEIGHBOR SO,THE TRIAL ENDS, START AGAIN****

21 22
23 24
(x,y)=(1,1)

The coordinates are (1,1) and the solicited matrix entry is: 24

IS IT OCCUPIED???

It's empty. Let's go to generate a random number to choose the adsorbates

random q= 0.141615

CO is adsorbed

adsorbed CO ---> co = 1

FIND THE NEIGHBORS OF THE ADSORBED CO

Right: 23
Left: 23
Up: 22
Down: 22

It wasn't encountered a site with O :(

CO2 IS NOT PRODUCED

```

It shows that the original matrix is not preserved, and even when it said the coordinate (0,0) is occupied (originally it has the label "1" in the original matrix), later on, it says that the same coordinate (now labeled by "13") is empty.

That's the problem I'm having. It seems that the matrix doesn't remember its original state
merano99 30-Jan-23 2:58am
I had noted errors that probably change the flow completely. It would be necessary to take these remarks into account in the code and adjust it. Where at the run tested by me still an error occurs I did not experience.
Instead of writing another new output here as a comment it would surely be much better to write an example output at the top of the question and explain exactly where something goes wrong, what the calculation base should be and what output is actually expected.
Since the source code is long and confusing, also because of the gotos, a further limitation in the source code would be helpful. Usually one writes subroutines and avoids gotos.
yuike 30-Jan-23 10:06am
Thank you for your remarks. I already got rid of the gotos and currently finding a better way to write the loops
yuike 30-Jan-23 11:01am
Thanks. I got rid of the gotos and now the matrix renains the same as expected. Now I'm trying to fix the issue that the program doesn't remember if a site is or not occupied
CPallini 30-Jan-23 2:26am
5.

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

Top Experts
Last 24hrsThis month
 Richard Deeming 50 Dave Kreskowiak 10 Manas Bhardwaj 5 Sergey Alexandrovich Kryukov 0
 OriginalGriff 431 Pete O'Hanlon 225 Richard Deeming 175 Dave Kreskowiak 133 CPallini 110

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900