program subroutinesAndFunctions

!=======================================================================================|
! Este programa ejemplifica el uso de código externo mediante modulos y bibliotecas     |
! Las formas de introducir código externo son basicamente 3:                            |
!   - subrutinas y funciones externas                                                   |
!   - modulos                                                                           |
!   - bibliotecas                                                                       |
! ----- MODULOS ------                                                                  |
! Los modulos son bloques de codigo con declaraciones de variables y/o procedimientos   |
! La estructura de un modulo es:                                                        |
!                                                                                       |
!   MODULE moduleName                                                                   |
!     Decalracion vars                                                                  |
!     CONTAINS                                                                          |
!     subrutinas y funciones                                                            |
!   END MODULE namemoudule                                                              |
!                                                                                       |
! En el programa principal se incluye el modulo mediante la sentencia use (al comienzo) |
!   PROGRAM programName                                                                 |
!     use moduleName                                                                    |
!       ......                                                                          |
! ----- BILIOTECAS -----                                                                |
! Las bibliotecas son compendios de subrutinas, funciones, etc. armados en uno o mas    |
! archivos. Son utiles cuando se tiene un grupo grande de procedimientos o cuando se    |
! quiere usar bibliotecas externas de terceros.                                         |
! Las bibliotecas tienen terminaciones del tipo .a y .so y se encuentran en general     |
! en un directorio libs.                                                                |
! Para armar una biblioteca se puede usar el comando "ar":                              |
!                                                                                       |
!   ar rcvf libsubs.a sub1.o sub2.o ...   construye la bib libsubs                      |
!   ar dv libsubs.a sub1.o          ...   elimina sub1.o de libsubs                     |
!                                                                                       |
!   El nombre del archivo de la bib "subs" es "libsubs.s", inicia con lib y .a al final |
! Para usar una biblioteca en nuestro program principal, debemos compilarlo junto con   |
! la biblioteca:                                                                        |
!                                                                                       |
!   gfortran progName.f90 -o proOut -L/path/libsdir -lnameLib1 -lnameLib2 ....          |
!                                                                                       |
! Se invocan las vasr u procedimientos coo de costumbre en el prog. principal           |
!=======================================================================================|
                                 

 
!------ use va siempre al comienzo de un bloque de programa, antes q las declaraciones -----
use testModule

real     ::  x1,y1,z1 
real     ::  x2,y2,z2
real     ::  absoluteValue , cosine, result
integer  :: fact

! ---- El kind INTDP, REALSP,REALDP estan definidos en el modulo -----
integer (kind=INTDP)  :: int
real    (kind=REALSP) :: real1
real    (kind=REALDP) :: real2
! ---- tambien PI --------
real    :: dosPi = 2* PI


! ---- instancio las vars -----

x1 = 1.0
y1 = 2.8
z1 = 5.6

x2 = 1.0
y2 = 3.1
z2 = 8.0

print *, "Llamo al las subrutinas incluidas en el modulo testModule:"
print * ,"subrutina sum del modulo: "
 call sum(3.0,1.0)
print *,

!----instancio las vars realsp, realdp --------

real1 = 1.0/3.0
print *, "1/3 en simple precision: ", real1

real2 = 1.0_8/3.0
print *, "1/3 en doble precision: ", real2

print *, "El valor de PI esta definido en el modulo, 2*PI es: ", dosPI
print *,

 call sub_addTwoNumbers(1.0,3.0,result)
write(*,*),"subrutina addTwoNumbers de la biblioteca subs: ",result

cosine = fun_cosineAngleVectors(x1,y1,z1,x2,y2,z2)
write(*,*),"funcion externa funCosineAngleVectors de la bilbioteca subs, el coseno es: ",cosine

end program subroutinesAndFunctions