Generating Coordinates for Silver Atoms in C and Fortran

Click For Summary

Discussion Overview

The discussion revolves around converting a C program that generates coordinates for silver atoms in a simple cubic lattice into Fortran code. Participants are addressing issues related to data types, array sizes, and the logic of the code, focusing on both theoretical and practical aspects of programming in C and Fortran.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant shares a C code snippet that generates coordinates for silver atoms and requests help in translating it to Fortran.
  • Another participant asks for clarification on the current state of the Fortran code and where the original poster is facing difficulties.
  • A participant provides an initial Fortran translation but notes that it produces incorrect values, suggesting potential issues with data types and array sizes.
  • Concerns are raised about the use of the REAL data type in Fortran, with one participant suggesting that REAL*8 should be used to match the double type in C.
  • Some participants discuss the significance of the variable N in the C code, which defines the number of atoms, and how it relates to the size of the arrays in the Fortran code.
  • There is a suggestion that the Fortran code should use specific indices (e.g., x(n), y(n), z(n)) instead of attempting to assign values to the entire array at once.
  • One participant expresses frustration with the lack of comments in both the C and Fortran code, which complicates understanding the purpose of certain variables and constants.
  • Another participant points out that the starting index for the variable n in the Fortran code differs from that in the C code, which could affect the output.
  • Further suggestions are made to simplify the calculations by removing unnecessary additions (e.g., adding 0.0) when assigning values to the arrays.

Areas of Agreement / Disagreement

Participants express differing views on the appropriate array sizes and data types, with some advocating for larger arrays and others arguing for smaller ones based on the context of the simple cubic lattice. The discussion remains unresolved regarding the best approach to translating the code accurately.

Contextual Notes

There are unresolved issues regarding the assumptions made about the number of atoms in the lattice and the implications of using different data types in Fortran compared to C. The purpose of certain constants and variables in the original C code is also unclear to some participants.

teqnick
Messages
5
Reaction score
0
Hello
Could anyone help me rewrite following C code to Fortran code? It generates coords for sc silver atoms.

Code:
#include <stdio.h>
#include <math.h>

int main(void) {
	int
		i, j, k,
		n = 0;
	double
		A = 4.08,
		L_X = 20.0,
		L_Y = 20.0,
		L_Z = 15.0;
	int
		iMax = ceil(L_X/A),
		jMax = ceil(L_Y/A),
		kMax = ceil(L_Z/A),
		N = (iMax + 1) * (jMax + 1) * (kMax + 1) * 1;
	const int
		NN = 1000;
	double x[NN], y[NN], z[NN];
	
	FILE* fileOut = fopen("Zad-VI.txt", "w");
	FILE* fileOut2 = fopen("Zad-VI.xyz", "w");
    
    for(k = 0; k <= kMax; k++) {
		for(j = 0; j <= jMax; j++) {
			for(i = 0; i <= iMax; i++) {
                x[n] = (i + 0.0) * A;
                y[n] = (j + 0.0) * A;
                z[n] = (k + 0.0) * A;

				n++;
            }
        }
    }
    
	fprintf(fileOut, "# atomN x y z\n");
	for(i = 0; i < N; i++) {
		fprintf(fileOut, "%d %f %f %f\n", i + 1, x[i], y[i], z[i]);
	}
	
	fprintf(fileOut2, "%d\n", N);
	fprintf(fileOut2, "atomName x y z\n");
    for(i = 0; i < N; i++) {
		fprintf(fileOut2, "%s %f %f %f\n", "Ag", x[i], y[i], z[i]);
    }
	    
    fclose(fileOut);
	fclose(fileOut2);
	
    return 0;
}
 
Last edited:
Technology news on Phys.org
What do you have so far and where are you stuck?
 
So far I've got this, but it gives me wrong values

Code:
PROGRAM SC

integer :: i, j, k
integer :: n = 0
REAL :: A = 4.08
REAL :: L_X = 20.0
REAL ::	L_Y = 20.0
REAL :: L_Z = 15.0
INTEGER :: N
INTEGER :: iMax
INTEGER :: jMax 
INTEGER :: kMax 
		
	REAL, DIMENSION(180) :: x
		REAL, DIMENSION(180) :: y
			REAL, DIMENSION(180) :: z
	
OPEN (UNIT=1, FILE='out.xyz', STATUS='REPLACE', ACTION='WRITE', DECIMAL='POINT')

iMax = ceiling(L_X/A)
jMax = ceiling(L_Y/A)
kMax = ceiling(L_Z/A)

    WRITE(*,*) imax, kmax, jmax
    k1: DO k = 1, kmax , 1
		j1:	DO j = 1, jmax, 1
			i1:	DO i = 1, imax, 1
                x = (i + 0.0) * A
                y = (j + 0.0) * A
                z = (k + 0.0) * A

				n=n+1
END DO i1
END DO j1
END DO k1
    

  WRITE(1,200) x, y, z 
		  200 FORMAT (3F10.3) 

END PROGRAM SC
 
I'm not sure this is your problem, but in your fortran code you are using real where the C code uses double. The double type in C is 8 bytes, and I believe real in fortran defaults to 4 bytes. To get a better match, use real*8 for all the variables that are declared as double in the C code.

This code should be very easy to port from C to Fortran if you do exactly the same thing in Fortran that the C code is doing. Unfortunately, your Fortran code departs from what the C code is doing.

For example, in the C code, x, y, and z are 1000-element arrays, but in your Fortran code, each of these is a 180-element array.

Also, there is a variable N in the C code that is initialized like this:
N = (iMax + 1) * (jMax + 1) * (kMax + 1) * 1;
(I have no idea why that 1 appears at the right end.) You don't have this in your Fortran code.
 
U aren't really helping, you just stated the obvious. There is only 180 atoms in sc lattice so there is no need for using 1000 array. There is nothing wrong with REAL declarations.
Also I have no idea what that variable N does in the program. (I have not written that C code, and do not fully understand the C language)
 
fortran:
x = (i + 0.0) * A
y = (j + 0.0) * A
z = (k + 0.0) * A

you multiply whole array. i guess it should be x(n), y(n), z(n).. (?)
 
teqnick said:
U aren't really helping, you just stated the obvious. There is only 180 atoms in sc lattice so there is no need for using 1000 array.
There isn't much in either program that is obvious. There's not a single comment in either program to help a reader understand what the program is trying to do.

I made a comment about the 1000-element arrays and 180-element arrays because I have no knowledge about how many atoms are in an sc lattice (or even what an sc lattice is). There are lots of "magic" numbers such as 4.08, 15.0, and 20.0 whose purpose is a complete mystery to me.
teqnick said:
There is nothing wrong with REAL declarations.
Maybe or maybe not. The person who wrote the C code thought that 8-byte floating point precision should be used, but you have decided that using 4-byte precision is enough. If you need more than 7 decimal places of precision, that smaller data type can make a difference.
teqnick said:
Also I have no idea what that variable N does in the program.
Nor do I. There's also a variable named n that is used in the C version that you don't have.

teqnick said:
(I have not written that C code, and do not fully understand the C language)
 
Pinčiukas said:
fortran:
x = (i + 0.0) * A
y = (j + 0.0) * A
z = (k + 0.0) * A

you multiply whole array. i guess it should be x(n), y(n), z(n).. (?)

Yes of course, but I do not now how to write it in fortran. That why i put it on that forum.

I know where most of the mistakes are, but i do not now how to make it work.
 
The mysterious N variable defines the number of atoms in simple cubic silver lattice, with is 180 so I put an array of the size of 180 instead of N. The L_X, L_Y, L_Z are size of lattice.

Corrected code is below but it still gives me wrong values.

Code:
PROGRAM SC

integer :: i, j, k
integer :: n = 1
REAL :: A = 4.08
REAL :: L_X = 20.0
REAL ::	L_Y = 20.0
REAL :: L_Z = 15.0
INTEGER :: iMax
INTEGER :: jMax 
INTEGER :: kMax 
		
	REAL, DIMENSION(180) :: x
		REAL, DIMENSION(180) :: y
			REAL, DIMENSION(180) :: z
	
OPEN (UNIT=1, FILE='out.xyz', STATUS='REPLACE', ACTION='WRITE', DECIMAL='POINT')

iMax = ceiling(L_X/A)
jMax = ceiling(L_Y/A)
kMax = ceiling(L_Z/A)

    k1: DO k = 1, kmax , 1
		j1: DO j = 1, jmax, 1
			i1: DO i = 1, imax, 1

                x(n) = (i + 0.0) * A
                y(n) = (j + 0.0) * A
                z(n) = (k + 0.0) * A

	     n=n+1

END DO i1
END DO j1
END DO k1
    

  WRITE(1,200) x, y, z 
		  200 FORMAT (3F10.3) 

END PROGRAM SC
 
  • #10
You are still confused about what data type the variables x, y, z are. Each of them is an array, not a single value. If you want to display all the values of these variables, you'll need to use a loop, something like this:
Code:
DO i=0, n
  WRITE (1, 200) x(i), y(i), z(i)
END DO
200 FORMAT (F10.3, 2X, F10.3, 2X, F10.3)
I changed the format statement to add a couple of spaces between successive numbers on a line.

Also, the C code starts off with n = 0, but your code starts off with n = 1. This might make a difference when you get you fortran code running.

Additional comments
1. I don't see any purpose in adding 0.0 as is done in the body of your nested loop. These statements could be written more simply, like this, and should produce the same values.
Code:
     x(n) = i * A
     y(n) = j * A
     z(n) = k * A

2. I find the C code and your FORTRAN code a little difficult to read, due to the random indentation in both. Here is my version of your code, with what I think is more reasonable indentation.
Code:
PROGRAM SC

integer :: i, j, k
integer :: n = 1
REAL :: A = 4.08
REAL :: L_X = 20.0
REAL ::	L_Y = 20.0
REAL :: L_Z = 15.0
INTEGER :: iMax
INTEGER :: jMax 
INTEGER :: kMax 
		
REAL, DIMENSION(180) :: x
REAL, DIMENSION(180) :: y
REAL, DIMENSION(180) :: z
	
OPEN (UNIT=1, FILE='out.xyz', STATUS='REPLACE', ACTION='WRITE', DECIMAL='POINT')

iMax = ceiling(L_X/A)
jMax = ceiling(L_Y/A)
kMax = ceiling(L_Z/A)

k1: DO k = 1, kmax , 1
  j1: DO j = 1, jmax, 1
    i1: DO i = 1, imax, 1
        x(n) = i  * A
        y(n) = j  * A
        z(n) = k * A
        n=n+1
    END DO i1
  END DO j1
END DO k1

DO i=0, n
  WRITE (1, 200) x(i), y(i), z(i)
END DO
200 FORMAT (F10.3, 2X, F10.3, 2X, F10.3)

END PROGRAM SC
 

Similar threads

  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 8 ·
Replies
8
Views
3K
Replies
6
Views
4K
  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 6 ·
Replies
6
Views
2K
Replies
1
Views
3K
  • · Replies 6 ·
Replies
6
Views
5K
  • · Replies 2 ·
Replies
2
Views
4K
  • · Replies 8 ·
Replies
8
Views
6K