Acabo de empezar con fotran95; Me dieron un código y lo estoy estudiando; Encontré una subrutina que llama a una función pero no entiendo cuál es el resultado:

Aquí está la subrutina :

SUBROUTINE collisione(vga, ga, vgb, gb)

IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(3), INTENT(INOUT) :: ga, gb    
DOUBLE PRECISION, DIMENSION(3), INTENT(INOUT) :: vga, vgb  

DOUBLE PRECISION, DIMENSION(3)   :: r, ra, rb, r_r

ra = pos_ini(ga)
rb = pos_ini(gb)


END SUBROUTINE

Aquí está la función:

FUNCTION pos_ini(g)

IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(3) :: pos_ini
DOUBLE PRECISION, DIMENSION(3), INTENT(IN) :: g

DOUBLE PRECISION, DIMENSION(3) :: es, eg, es_p
DOUBLE PRECISION :: rnd, b, kos, ang 

CALL RANDOM_NUMBER(rnd)
b = 1.D0 - 2.D0*rnd 
kos = SQRT(1.D0 - b*b)
CALL RANDOM_NUMBER(rnd)
ang = pi2 * rnd

es(1) = kos * COS(ang)
es(2) = kos * SIN(ang)
es(3) = b

eg = g / SQRT(DOT_PRODUCT(g,g))

es_p = es - DOT_PRODUCT(es,eg) * eg

pos_ini = d * es_p/SQRT(DOT_PRODUCT(es_p,es_p)) ! IS THIS THE OUTPUT THAT GIVES THE VALUE OF ra and rb???????

END FUNCTION

(lea el comentario). Entonces aquí viene mi pregunta: en la subrutina veo que las variables ra y rb se definen luego de usar la función pos_ini donde la entrada es el vector ga o gb . Sin embargo, en la función pos_ini no entiendo cuál es la salida; es pos_ini = d * es_p/SQRT(DOT_PRODUCT(es_p,es_p)) ?? si es así por qué? y ¿cómo es que no hay intención (FUERA) en la función pos_ini?

0
Federico Gentile 18 feb. 2015 a las 20:14

3 respuestas

La mejor respuesta

En Fortran, el valor de la función devuelto está conectado al nombre de la función o una variable en la cláusula opcional result. Por lo tanto, el valor de la función será el valor de pos_ini al final de la función.

En su caso, es la expresión {{X 0}}.

Esto está cubierto por cualquier tutorial de Fortran.

2
Vladimir F 18 feb. 2015 a las 17:25

Pos_ini es una función de doble precisión que devuelve una matriz de tres elementos. Supongo que está declarado dentro de un módulo (porque no hay declaración para pi2 y para d), pero eso realmente no importa aquí.

En Fortran, el valor de retorno se establece mediante la asignación al nombre de la función (o al nombre en una cláusula RESULT, que no se aplica aquí). Esto se hace con la línea

pos_ini = d * es_p/SQRT(DOT_PRODUCT(es_p,es_p))

Lo que te desconcertó.

En este caso, se trata de una asignación de matriz. En Fortran, puede tener asignaciones a matrices desde escalares u otras matrices, aritmética de matrices (que se realiza por elementos) y aritmética mixta entre escalares y matrices.

Debido a que d carece de una definición, no puedo decir cuál es. Sería válido como una matriz con una extensión de 3 o como un escalar. es_p es una matriz con la misma extensión que pos_ini, por lo que está bien. DOT_PRODUCT debe ser autoexplicativo; es un sclar, como lo es SQRT.

Le recomendaría que lea este artículo sobre las funciones de Fortran 95.

0
user4490638user4490638 18 feb. 2015 a las 17:51

Entonces esta línea

FUNCTION pos_ini(g)

Comienza la definición de una función llamada pos_ini. Y esta linea

DOUBLE PRECISION, DIMENSION(3) :: pos_ini

Nos dice (y al compilador) que pos_ini devolverá una matriz de precisión doble con 3 elementos. A menos que se codifique de otro modo (con una cláusula result), una función de Fortran declara (automáticamente o, como aquí, escribiendo código explícitamente) una variable de resultado con el mismo nombre que la función. Y la linea

pos_ini = d * es_p/SQRT(DOT_PRODUCT(es_p,es_p))

Que define un valor para pos_ini define lo que se devolverá de una invocación de la función. No es necesario, y sería un error que el compilador detectaría, declarar que la variable de retorno tiene intent(out).

Para funciones que devuelven un valor escalar de un tipo intrínseco, la declaración del tipo de la función (o del tipo de la variable de retorno si quiere pensar en las cosas de esa manera) puede escribir una declaración de apertura de función a lo largo de las líneas de

DOUBLE PRECISION FUNCTION pos_ini(g)

Pero, dado que su función devuelve una matriz, debe codificar como lo hizo, declarando la variable de retorno explícitamente.

0
High Performance Mark 18 feb. 2015 a las 17:25