[ anterior ] [ Contenidos ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ 13 ] [ siguiente ]


Lecciones de Fortran 90 para la asignatura Química Computacional
Capítulo 8 - Subprogramas (I): funciones


8.1 Objetivos

Los objetivos de esta clase son los siguientes:

  1. presentar las ventajas que ofrece el uso de funciones, subrutinas y módulos.

  1. presentar el concepto de función en Fortran.

  1. mostrar los diferentes tipos de funciones que pueden usarse: intrínsecas, genéricas, elementales, transformacionales e internas.

  1. hacer posible la definición de funciones por el usuario.

  1. mostrar la diferencia entre funciones externas y funciones contenidas en el programa principal.

El uso de estas estructuras permite desarrollar una programación más estructurada y eficaz ya que permiten


8.2 Puntos destacables.

En primer lugar nos centramos en las funciones y, en la siguiente unidad, tratamos las subrutinas.


8.3 Programas usados como ejemplo.


8.3.1 Programa ejemplo_8_1.f90

     PROGRAM EJEMPLO_8_1
       IMPLICIT NONE
       !Definicion de variables
       INTEGER, PARAMETER :: Long=SELECTED_REAL_KIND(18,310)
       !
       REAL (KIND=Long), PARAMETER :: DPI = ACOS(-1.0_Long) ! Definimos el número Pi
       REAL (KIND=Long) :: DANGLE, DANGLERAD
       !
       REAL, PARAMETER :: PI = ACOS(-1.0) ! Definimos el número Pi
       REAL :: ANGLERAD
       !
       PRINT*, 'INTRODUZCA UN ANGULO (EN GRADOS)'
       READ*, DANGLE
       PRINT*
       ! PASO A RADIANES
       DANGLERAD = DPI*DANGLE/180.0_Long
       ANGLERAD = PI*DANGLE/180.0
       !
       PRINT 20, DANGLE, DANGLERAD
       PRINT 21, DANGLE, ANGLERAD
       PRINT*
       PRINT*
       !
       PRINT 22, DANGLERAD, SIN(DANGLERAD), COS(DANGLERAD), SIN(DANGLERAD)**2+COS(DANGLERAD)**2,&
            1.0_Long-(SIN(DANGLERAD)**2+COS(DANGLERAD)**2) 
       PRINT*
       PRINT 22, ANGLERAD, SIN(ANGLERAD), COS(ANGLERAD), SIN(ANGLERAD)**2+COS(ANGLERAD)**2,1.0 - (SIN(ANGLERAD)**2+COS(ANGLERAD)**2) 
       !
     20 FORMAT (1X, 'UN ANGULO DE ',F14.8,' GRADOS = ', F14.8, ' RADIANES. (dp)')
     21 FORMAT (1X, 'UN ANGULO DE ',F14.8,' GRADOS = ', F14.8, ' RADIANES. (sp)')
     22 FORMAT (1X, 'ANGULO ',F14.8,', SIN = ', F13.9, ', COS =',F13.9,/'SIN**2+COS**2 = ', F16.12, ', 1 - SIN**2+COS**2 = ', F16.12)
     END PROGRAM EJEMPLO_8_1

8.3.2 Programa ejemplo_8_2.f90

     PROGRAM EJEMPLO_8_2
       IMPLICIT NONE
       !Definicion de variables
       INTEGER , PARAMETER :: NEL=5
       REAL, PARAMETER :: PI = ACOS(-1.0) ! Definimos el número Pi
       REAL , DIMENSION(1:NEL)   :: XR = (/ 0.0, PI/2.0, PI, 3.0*PI/2.0, 2.0*PI/)
       INTEGER , DIMENSION(1:NEL):: XI = (/ 0, 1, 2, 3, 4/)
       !
       PRINT*, 'SENO DE ', XR, ' = ', SIN(XR)
       PRINT*, 'LOG10 DE ', XR, ' = ', LOG10(XR)
       PRINT*, 'REAL ', XI, ' = ', REAL(XI)
     END PROGRAM EJEMPLO_8_2

8.3.3 Programa ejemplo_8_3.f90

     PROGRAM EJEMPLO_8_3
       IMPLICIT NONE
       INTEGER :: I,J,Result
       INTEGER :: MCD
       EXTERNAL MCD
       PRINT *,' INTRODUCE DOS NUMEROS ENTEROS:'
       READ(*,*),I,J
       RESULT = MCD(I,J)
       PRINT *,' EL MAX COMUN DIV DE ',I,' Y ',J,' ES ',RESULT
     END PROGRAM EJEMPLO_8_3
     !
     INTEGER FUNCTION MCD(A,B)
     IMPLICIT NONE
     INTEGER , INTENT(IN) :: A,B
     INTEGER :: Temp
       IF (A < B) THEN
          Temp=A
       ELSE
          Temp=B
       ENDIF
       DO WHILE ((MOD(A,Temp) /= 0) .OR. (MOD(B,Temp) /=0))
          Temp=Temp-1
       END DO
       MCD=Temp
     END FUNCTION MCD

8.3.4 Programa ejemplo_8_4.f90

     PROGRAM EJEMPLO_8_4
       IMPLICIT NONE
       ! Uso de una función interna en el cálculo de la fórmula
       ! E(v) = we (v+1/2) - wexe (v+1/2)**2.
       INTEGER :: V, VMAX
       REAL :: we, wexe, Energy
       PRINT *,' INTRODUCE EL VALOR DE Vmax:'
       READ(*,*), VMAX
       PRINT *,' INTRODUCE EL VALOR DE we Y DE wexe:'
       READ(*,*),we, wexe
       DO V = 0, VMAX
          Energy = FEN(V)
          PRINT 100, V, Energy
       ENDDO
     100 FORMAT(1X,'E(',I3,') = ',F14.6)
     CONTAINS 
     !
       REAL FUNCTION FEN(V)
         IMPLICIT NONE
         INTEGER , INTENT(IN) :: V
         FEN = we*(V+0.5)-wexe*(V+0.5)**2
       END FUNCTION FEN
     !
     END PROGRAM EJEMPLO_8_4

8.3.5 Programa ejemplo_8_5.f90

     PROGRAM EJEMPLO_8_5
       !
       ! Simple program to compute the prime divisors of a given integer number.
       !
       IMPLICIT NONE
       INTEGER :: NUMVAL
       INTEGER :: NUM
       !
       READ(*,*), NUMVAL ! input
       !
       DO
          NUM = QUOT(NUMVAL)
          IF (NUM == NUMVAL) THEN
             PRINT*, NUM
             EXIT
          ELSE
             PRINT*, NUMVAL/NUM, NUM
             NUMVAL = NUM
          ENDIF
       ENDDO
       !
     CONTAINS
       ! 
       INTEGER FUNCTION QUOT(NUM1)
         !
         INTEGER, INTENT(IN) :: NUM1
         INTEGER :: I
         !
         QUOT = NUM1
         !
         DO I = 2, NUM1-1
            IF (MOD(NUM1,I) == 0) THEN
               QUOT = NUM1/I
               EXIT
            ENDIF
         ENDDO
         !
       END FUNCTION QUOT
       !
     END PROGRAM EJEMPLO_8_5

8.3.6 Programa ejemplo_8_6.f90

     PROGRAM EJEMPLO_8_6
       !
       ! Program to evaluate a 1D potential function on grid points
       !
       IMPLICIT NONE
       !
       REAL, DIMENSION(:), ALLOCATABLE :: X_grid, Pot_grid
       !
       REAL :: X_min, X_max, Delta_X
       REAL :: V_0 = 10.0, a_val = 1.0
       INTEGER :: Index, X_dim
       INTEGER :: Ierr
       !
       !
       INTERFACE Potf
          ELEMENTAL FUNCTION Potf(Depth, Inv_length, X)
            !
            IMPLICIT NONE
            !
            REAL, INTENT(IN) :: Depth, Inv_length, X
            REAL :: Potf
            !
          END FUNCTION Potf
       END INTERFACE Potf
       !
       !
       READ(*,*), X_min, X_max, X_dim ! input minimum and maximum values of X and number of points
       !
       ALLOCATE(X_grid(1:X_dim), STAT = Ierr)
       IF (Ierr /= 0) THEN
          STOP 'X_grid allocation failed'
       ENDIF
       !
       ALLOCATE(Pot_grid(1:X_dim), STAT = Ierr)
       IF (Ierr /= 0) THEN
          STOP 'Pot_grid allocation failed'
       ENDIF
       !
       !
       Delta_X = (X_max - X_min)/REAL(X_dim - 1)
       !
       X_grid = (/ (Index, Index = 0 , X_dim - 1 ) /)
       X_grid = X_min + Delta_X*X_grid
       !
       Pot_grid = Potf(V_0, a_val, X_grid)
       !
       DO Index = 1, X_dim
          PRINT*, X_grid, Pot_grid
       ENDDO
       !
       DEALLOCATE(X_grid, STAT = Ierr)
       IF (Ierr /= 0) THEN
          STOP 'X_grid deallocation failed'
       ENDIF
       !
       DEALLOCATE(Pot_grid, STAT = Ierr)
       IF (Ierr /= 0) THEN
          STOP 'Pot_grid deallocation failed'
       ENDIF
       !
       !
     END PROGRAM EJEMPLO_8_6
     !
     ELEMENTAL FUNCTION Potf(Depth, Inv_length, X)
       !
       IMPLICIT NONE
       !
       REAL, INTENT(IN) :: Depth, Inv_length, X
       !
       REAL :: Potf
       !
       Potf = -Depth/(COSH(Inv_length*X)**2)
       !
     END FUNCTION Potf

[ anterior ] [ Contenidos ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ 13 ] [ siguiente ]


Lecciones de Fortran 90 para la asignatura Química Computacional

$Id: clases_fortran.sgml,v 1.24 2013/07/02 09:38:58 curro Exp curro $

Curro Pérez Bernal mailto:francisco.perez@dfaie.uhu.es