Logo Cineca Logo SCAI

You are here

Serial source code

Serial source code

 

C source 

/*
* It evolves the equation:
* u,t + u,x + u,y = 0
* Using a Lax scheme.
* The initial data is a cruddy gaussian.
* Boundaries are flat: copying the value of the neighbour
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define NX 100
#define NY 100
#define LX 2.0
#define LY 2.0

#define sigma 0.1
#define tmax 100


/*
* conversions from discrete to real coordinates
*/
float ix2x(int ix){
return ((ix-1) - (NX-1) / 2.0)*LX/(NX-1);
}

float iy2y(int iy){
return ((iy-1) - (NY-1) / 2.0)*LY/(NY-1);
}


/* Function for evaluating the results that calculates the sum of the array values */
float summa(int nx, int ny, float* val){
float summma=0.0;
int ix,iy;
for(iy=1;iy<=ny;++iy)
for(ix=1;ix<=nx;++ix){
summma+=val[((nx+2)*iy)+ix];
}
return(summma);
}


/*
* initialize the system with a gaussian temperature distribution
*/
int init_transport(float *temp){
int ix,iy;
float x,y;

for(iy=1;iy<=NY;++iy)
for(ix=1;ix<=NX;++ix){
x=ix2x(ix);
y=iy2y(iy);
temp[((NX+2)*iy)+ix] = tmax*exp((-((x*x)+(y*y)))/(2.0*(sigma*sigma)));
}
return 0;
}

/*
* save the temperature distribution
* the ascii format is suitable for splot gnuplot function
*/
int save_gnuplot(char *filename, float *temp) {
int ix,iy;
FILE *fp;

fp = fopen(filename, "w");
for(iy=1;iy<=NY;++iy){
for(ix=1;ix<=NX;++ix)
fprintf(fp, "\t%f\t%f\t%g\n", ix2x(ix), iy2y(iy), temp[((NX+2)*iy)+ix]);
fprintf(fp, "\n");
}
fclose(fp);

return 0;
}

int update_boundaries_FLAT(float *temp){
int ix=0, iy=0;

for(iy=0;iy<=NY+1;++iy){
temp[(NX+2)*iy] = temp[((NX+2)*iy)+1];
temp[((NX+2)*iy)+(NX+1)] = temp[((NX+2)*iy)+NX];
}

for(ix=0;ix<=NX+1;++ix){
temp[ix] = temp[(NX+2)+ix];
temp[((NX+2)*(NY+1))+ix] = temp[((NX+2)*NY)+ix];
}
return 0;
}


int evolve(float dtfact, float *temp, float *temp_new){
float dx, dt;
int ix, iy;
float temp0;

dx = 2*LX/NX;
dt = dtfact*dx/sqrt(3.0);
for(iy=1;iy<=NY;++iy)
for(ix=1;ix<=NX;++ix){
temp0 = temp[((NX+2)*iy)+ix];
temp_new[((NX+2)*iy)+ix] = temp0-0.5*dt*(temp[((NX+2)*(iy+1))+ix]
-temp[((NX+2)*(iy-1))+ix]+temp[((NX+2)*iy)+(ix+1)]-temp[((NX+2)*iy)+(ix-1)])/dx;
}

for(iy=0;iy<=NY+1;++iy)
for(ix=0;ix<=NX+1;++ix)
temp[((NX+2)*iy)+ix] = temp_new[((NX+2)*iy)+ix];


return 0;
}

int main(int argc, char* argv[]){
int i=0, nRow=NX+2, nCol=NY+2;
float *temp, *temp_new;


temp = (float *) malloc (nRow*nCol*sizeof(float));
temp_new = (float *) malloc (nRow*nCol*sizeof(float));

init_transport(temp);
update_boundaries_FLAT(temp);

float before=summa(NX, NY, temp);
printf(" sum temp before: %f\n",before);

save_gnuplot("transport.dat", temp);

for(i=1;i<=500;++i) {
evolve(0.1, temp, temp_new);
update_boundaries_FLAT(temp);
}

float after=summa(NX, NY, temp);
printf(" sum temp after: %f\n",after);
save_gnuplot("transport_end.dat", temp);


free(temp);
free(temp_new);
return 0;
}

 

Fortran source 

!
! It evolves the equation:
! u,t + u,x + u,y = 0
! Using a Lax scheme.
! The initial data is a cruddy gaussian.
! Boundaries are flat: copying the value of the neighbour
!

module transport
implicit none
save

integer, parameter :: NX=100
integer, parameter :: NY=100
real, parameter :: LX=2.0
real, parameter :: LY=2.0

real temp(0:NX+1 , 0:NY+1)
real temp_new(0:NX+1 , 0:NY+1)


CONTAINS
!conversions from discrete to real coordinates

real function ix2x(ix)
integer ix
ix2x = ((ix-1)-(NX-1)/ 2.0)*LX/(NX-1)
end function ix2x

real function iy2y(iy)
integer iy
iy2y = ((iy-1)-(NY-1)/ 2.0)*LY/(NY-1)
end function iy2y


! initialize the system with a gaussian temperature distribution

subroutine init_transport
integer ix,iy
real x,y
real,parameter :: sigma = 0.1
real,parameter :: tmax = 100

do iy=1,NY
do ix=1,NX
x=ix2x(ix)
y=iy2y(iy)
temp(ix,iy) = tmax*exp(-(x**2+y**2)/(2.0*sigma**2))
enddo
enddo

end subroutine init_transport

! save the temperature distribution
! the ascii format is suitable for splot gnuplot function
subroutine save_gnuplot(filename)

character(len=*) filename
integer ix,iy

open(unit=20,file=filename,form='formatted')
do iy=1,NY
do ix=1,NX
write(20,*) ix2x(ix),iy2y(iy),temp(ix,iy)
enddo
write(20,*)
enddo

close(20)
end subroutine save_gnuplot

subroutine update_boundaries_FLAT
temp(0 , 1:NY) = temp(1 , 1:NY)
temp(NX+1, 1:NY) = temp(NX , 1:NY)

temp(1:NX , 0) = temp(1:NX , 1)
temp(1:NX , NY+1) = temp(1:NX , NY)
end subroutine update_boundaries_FLAT

subroutine evolve(dtfact)
real :: dtfact
real :: dx,dt
integer :: ix,iy
real :: temp0


dx = 2*LX/NX
dt = dtfact*dx/sqrt(3.0)
do iy=1,NY
do ix=1,NX
temp0 = temp(ix,iy)
temp_new(ix,iy) = temp0 - 0.5 * dt * (temp(ix+1,iy)-temp(ix-1,iy)+temp(ix,iy+1)-temp(ix,iy-1)) / dx
enddo
enddo

temp = temp_new

end subroutine evolve
end module transport

program prova
use transport
implicit none

integer i

call init_transport
call update_boundaries_FLAT
write(*,*) 'sum temp before',sum(temp(1:NX,1:NY))
call save_gnuplot('transport.dat')

do i=1,500
call evolve(0.1)
call update_boundaries_FLAT
enddo

call save_gnuplot('transport_end.dat')
write(*,*) 'sum temp after',sum(temp(1:NX,1:NY))

end program prova


 

Jobscript template (FERMI)

#!/bin/bash
# @ job_type=bluegene
# @ bg_size=64
# @ wall_clock_limit = 00:10:00
# @ account_no =
# @ queue
module load bgq-gnu zlib
runjob --np 1 --env-all : ./transport-serial.x

 

Jobscript template (PLX)

#!/bin/bash
#PBS -N transser
#PBS -l select=1:ncpus=1:mpiprocs=1
#PBS -l walltime=0:10:00
#PBS -A
#PBS -q debug

cd $PBS_O_WORKDIR

./transport-serial.x