16,000,304 members
0.00/5 (No votes)
See more:
I'm working in a simulation of a surface that traps multiple molecules which make some interactions between them. This code is based in another made by @merano99 here.

The steps this code follows are the following:

1) I start with a completely empty surface.

2) I select at random an "site" of the surface, given by its random coordinates x and y.

3) If such a selected site, I continue to the step 4). Otherwise, I select at random another site again

4) The molecules that I would like to trap are N (nitrogen) and NO (nitric oxide). The NO could be possibly split into N and O (O is the label I chose for oxygen). To do those choices, I defined two random numbers (r1 and r2) that will help me to decide which one will be trapped.

5) There are also defined the numbers XNO (probability that NO is chosen) and RNO (probability that NO splits itself into N and O).
6) If r1 is less or equal than XNO, I choose NO to be trapped. Otherwise, I choose N.

7) If I have chosen NO and additionally r2 is less or equal than RNO, NO can be split into N and O (only if I find a nearest neighbor empty. In that case N and O are trapped in two different sites). Otherwise, it remains in its molecular form (said NO).

8) I explore the right nearest neighbor of the sites where the particles were chosen. This "right nearest neighbor" is the neighbor located at right of the chosen site. To do so, I defined the function
`rightneighbor(int x, int y, gstate grid[MAX_X][MAX_Y])`
I also considered periodic boundary conditions by defining the function
`get_limited_coord(int coord, int coord_max)`
just in case the chosen site is located at a border of the surface.

9) Well, if the right neighbor of a trapped N is occupied with another N, it will be created N2 and this reaction will left 2 sites available.

10) If the right neighbor of the trapped N is filled by an NO, it will be generated N2, but O will remain trapped and the interaction will leave 1 available site.

11) If the right site with the NO molecule is occupied by N, also, it will be generated N2, but O will remain trapped and the interaction will leave 1 available site.

What I have tried:

The code I have so far is

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

//define the dimensions of the grid
#define MAX_X 2
#define MAX_Y 2
//define the partial pressure of CO
#define XNO 0.300000
//define the probability that NO can disociate
#define RNO 0.500000

//define the states of a cell in grid
typedef enum  { S_EMPTY, NO_OCCUPIED, N_OCCUPIED, O_OCCUPIED, S_NONE } gstate;

// help generate random coordinate of the grid
int gridrnd(int max)
{
return (rand() % max);
}

// generates random coordinates of the grid
int generate_coords(int* y, int* x )
{
if (!x || !y)
return 1;

*x = gridrnd(MAX_X);
*y = gridrnd(MAX_Y);

printf("(%d,%d)\n\n", *y, *x);
return 0;
}

void grid_init(gstate grid[MAX_Y][MAX_X])
{
for (int y = 0; y < MAX_Y; y++) {
for (int x = 0; x < MAX_X; x++) {
grid[y][x] = S_EMPTY;
}
}
}

//Function that locates the four nearest neighbors of the 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;
}
}

//Function that prints individually the "right" neighbor of the chosen site
gstate rightneighbor(int x, int y, gstate grid[MAX_X][MAX_Y]){
grid [y][x] = grid[get_limited_coord(y, MAX_Y)][get_limited_coord(x+1, MAX_X)];
return grid[y][x];
}

int main()
{
int x = 0, y = 0;
gstate grid[MAX_Y][MAX_X];
int availcells = MAX_X * MAX_Y;
int rounds = 0;
float r1, r2;

srand((unsigned)time(0));

// Initialize grid to be S_EMPTY
grid_init(grid);

while (availcells) // repeat till the grid is full
{
//LOCATE AN ENTRY OF THE MATRIX RANDOMLY
generate_coords(&y, &x);
rounds++;

//EVALUATE THE CHOOSEN SITE
switch (grid[y][x])
{
case S_EMPTY:
printf("IT'S S_EMPTY, LET'S FILL IT WITH A MOLECULE. FIRST LET'S GENERATE A RANDOM NUMBER TO DECIDE WHICH ONE WILL BE TRAPPED\n\n");

r1 = rand()/(float)RAND_MAX;
if(r1 < XNO || r1 == XNO){
//if r1 is less than XNO we choose NO. Now let's see if it can be splitted or if it remains in its molecular form
printf("r1 = %f IS LESS THAN XNO = %f, LET'S SEE IF (NO) CAN SPLIT\n\n",r1,XNO);

r2 = rand()/(float)RAND_MAX;

if(r2 < RNO || r2 == RNO){
//if r2 is less than RNO, NO can be splitted if its right nearest neighbor is also empty
printf("r2 = %f IS LESS THAN RNO = %f, (NO) WILL BE SPLITTED IF I FIND ANOTHER EMPTY NEAREST NEIGHBOR\n\n",r2,RNO);

//let's find its right nearest neighbor
rightneighbor(x,y,grid);

//Is it empty?
if( rightneighbor(x,y,grid) == S_EMPTY ){
grid[y][x] = N_OCCUPIED;
rightneighbor(x,y,grid) == O_OCCUPIED;
availcells = availcells - 2;
printf("THE RIGHT NEIGHBOR IS EMPTY, (NO) IS SPLITTED INTO (N) AND (O)\n\n");

}else{//I the right neighbor is not empty
printf("The right neighbor isn't empty, NO can't disociate and the trial ends. Please, start again\n\n");
}

}else{
//if r2 is greater than RNO, NO remain in its molecular form
printf("r2 = %f IS GREATER THAN RNO = %f, THE (NO) IS LEFT IN ITS MOLECULAR FORM\n\n",r2,RNO);
grid[y][x] = NO_OCCUPIED;
availcells--;

//Let's check its right nearest neighbor. If there is a N, the molecule N2 will be formed, leaving a site with O and one site free
if( rightneighbor(x,y,grid) == N_OCCUPIED ){
printf("IT'S PRODUCED N2!\n\n");
grid[y][x] = O_OCCUPIED;
rightneighbor(x,y,grid) == S_EMPTY;
availcells++;
}else{
printf("There is no an N the right neighbor. N2 isn't produced. Start again\n\n");
}
}

}else{
//if r1 is less than XNO we choose N to be trapped
printf("r1 = %f IS GREATER THAN XNO = %f, LET'S FILL IT WITH AN (N) MOLECULE\n\n",r1,XNO);
grid[y][x] = N_OCCUPIED;
availcells--;

//Let's see if on the right neighbor there is an N or an NO, so that N2 can be created
if(rightneighbor(x,y,grid) == N_OCCUPIED ){
printf("It is formed N2\n\n");
grid[y][x] = S_EMPTY;
rightneighbor(x,y,grid) == S_EMPTY;
availcells = availcells + 2;

}else if(rightneighbor(x,y,grid) == NO_OCCUPIED){
printf("It is formed N2 and an O remains trapped\n\n");
grid[y][x] = S_EMPTY;
rightneighbor(x,y,grid) == O_OCCUPIED;
availcells++;

}else{
printf("There aren't N or NO on the right neighbor. N2 is not created. Start again\n\n");
}
}
break;

case NO_OCCUPIED:
printf("IT'S NO_OCCUPIED. PLEASE, GENERATE ANOTHER SITE ON THE SURFACE\n\n");
break;

case N_OCCUPIED:
printf("IT'S N_OCCUPIED. PLEASE, GENERATE ANOTHER SITE ON THE SURFACE\n\n");
break;

case O_OCCUPIED:
printf("IT'S O_OCCUPIED. PLEASE, GENERATE ANOTHER SITE ON THE SURFACE\n\n");
break;
}
}

printf("Needed %d rounds to fill complete grid\n", rounds);
return 0;
}```

But, when it selects a site an fills a site with N and another with O, it doesn't remember that such sites were filled already by those, if I attempt to trap another molecule. To explain myself better, the following is the result I obtain after the compilation:

```(0,0)

IT'S S_EMPTY, LET'S FILL IT WITH A MOLECULE. FIRST LET'S GENERATE A RANDOM NUMBER TO DECIDE WHICH ONE WILL BE TRAPPED

r1 = 0.053598 IS LESS THAN XNO = 0.300000, LET'S SEE IF (NO) CAN SPLIT

r2 = 0.473955 IS LESS THAN RNO = 0.500000, (NO) WILL BE SPLITTED IF I FIND ANOTHER EMPTY NEAREST NEIGHBOR

THE RIGHT NEIGHBOR IS EMPTY, (NO) IS SPLITTED INTO (N) AND (O)

(0,0)

IT'S S_EMPTY, LET'S FILL IT WITH A MOLECULE. FIRST LET'S GENERATE A RANDOM NUMBER TO DECIDE WHICH ONE WILL BE TRAPPED

r1 = 0.335047 IS GREATER THAN XNO = 0.300000, LET'S FILL IT WITH AN (N) MOLECULE

There aren't N or NO on the right neighbor. N2 is not created. Start again

(0,1)

IT'S S_EMPTY, LET'S FILL IT WITH A MOLECULE. FIRST LET'S GENERATE A RANDOM NUMBER TO DECIDE WHICH ONE WILL BE TRAPPED

r1 = 0.580490 IS GREATER THAN XNO = 0.300000, LET'S FILL IT WITH AN (N) MOLECULE

There aren't N or NO on the right neighbor. N2 is not created. Start again

Needed 3 rounds to fill complete grid```

I put all those "printf" to verify if the code is working as expected, but it doesn't. Thank you in advance
Posted
Updated 3-Feb-23 8:06am
v6

## Solution 1

You have several lines that look like
C
```rightneighbor(x, y, grid) == O_OCCUPIED;
```

With warnings turned on I get warnings about computed values not being used for these lines. Remember that `==` is an equality test, not an assignment. If you did want to do an assignment to a `rightneigbor` you probably want a function like
C
`set_rightneigbor(gstate state, int x, int y, gstate grid[MAX_X][MAX_Y]);`

Comments
yuike 3-Feb-23 12:57pm
Thanks for responding. I have a question: in the definition of the function do I need to write it as
`gstate set_rightneigbor(gstate state, int x, int y, gstate grid[MAX_X][MAX_Y]);`
?
k5054 3-Feb-23 13:21pm
There's a few options for the return value. It could be `void`, if there is no possibility for set_rightneigbor() to fail. If there is a possible failure mode for set_rightneigbor() you might return an `int` with 0 meaning success and other values indicating the failure type. Alternatively, you could return a gstate, which might be the previous value of the rightneighbor. This might be useful if you need to know what that value was before it was changed.
yuike 3-Feb-23 20:13pm
Thank you very much for your advice! I think I got it :)

## Solution 2

As k5054 has already written, comparisons were used instead of assignments. Additionally, the value of the right neighbor was copied before. This does not seem to make sense, does it?
C
`grid[y][x] = grid[get_limited_coord(y, MAX_Y)][get_limited_coord(x+1, MAX_X)];`

// edit:
If I see it correctly you want to check if the right neighbor is unoccupied and then occupy both elements. In my opinion this should look like this.
C++
```case S_EMPTY: {
printf("IT'S S_EMPTY, LET'S FILL IT WITH A MOLECULE\n\n");

//let's find its right nearest neighbor
gstate* rnb = rightneighbor(x, y, grid);

//Is it empty?
if (*rnb == S_EMPTY) {
grid[y][x] = N_OCCUPIED;
*rnb = O_OCCUPIED;
availcells -= 2;
}
}
break;```

v2
Comments
yuike 3-Feb-23 19:40pm
Thank you, I tried with a shorter code (I don't include all the interactions between molecules mentioned above yet). I think it's fixed...Still checking

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

Top Experts
Last 24hrsThis month
 Dave Kreskowiak 138 OriginalGriff 110 Christian Graus 40 honey the codewitch 25 Daniel Pfeffer 20
 OriginalGriff 631 Dave Kreskowiak 271 Pete O'Hanlon 260 Richard Deeming 240 CPallini 120

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