functions - imprimir en fortran
FunciĆ³n en fortran, pasando array, recibiendo array (1)
Con RESULT(FluxArray)
, fluxArray
es el nombre de la variable de resultado . Como tal, su intento de declarar las características en la cláusula de resultado está mal colocado.
En cambio, la variable de resultado debe especificarse dentro del cuerpo de la función:
function Flux(W1,W2) result(fluxArray)
double precision, dimension(3), intent(in)::W1, W2
double precision, dimension(3) :: fluxArray ! Note, no intent for result.
end function Flux
Sí, uno puede declarar el tipo de la variable de resultado en la declaración de la function
, pero la matriz no se puede declarar allí. No recomendaría tener una declaración de dimension
distinta en el cuerpo de la función para la variable de resultado.
Tenga en cuenta que, al hacer referencia a una función que devuelve una matriz, se requiere que haya una interfaz explícita disponible para la persona que llama. Una forma es colocar la función en un módulo que sea use
d. Ver en otro lugar en SO, o tutoriales de idiomas, para más detalles.
Llegando a los errores de su pregunta sin el result
.
DOUBLE PRECISION FUNCTION Flux(W1,W2)
DOUBLE PRECISION, DIMENSION(3), INTENT(OUT):: Flux
Aquí el tipo de Flux
ha sido declarado dos veces. Además, no es un argumento ficticio para la función, por lo que no es necesario que tenga el atributo de intent
.
Uno podría escribir
FUNCTION Flux(W1,W2)
DOUBLE PRECISION, DIMENSION(3) :: Flux ! Deleting intent
o (estremecimiento)
DOUBLE PRECISION FUNCTION Flux(W1,W2)
DIMENSION :: Flux(3)
La queja sobre una función de declaración no es importante aquí, después de la mala declaración.
Tengo esta función, que se muestra a continuación. Pasa en dos vectores con tres valores cada uno, y debe pasar un vector con tres valores también. Llamo a la función así:
Fr = Flux(W(:,i),W(:,i+1))
Lo que me he dado cuenta al meterme con el código, probar funciones puras y módulos, e investigar la declaración de error (que incluiré en la parte inferior), es que fortran está leyendo mi función Flux, y piensa que los vectores de entrada son un intentar llamar a una entrada de la matriz. Esa es mi mejor suposición acerca de lo que está pasando. Pregunté por el laboratorio y la mayoría de la gente sugirió usar subrutinas, pero eso parecía torpe, y pensé que probablemente debería haber una manera más elegante, pero aún no lo he encontrado. Traté de definir un resultado diciendo:
DOUBLE PRECISION FUNCTION Flux(W1,W2) Result(FluxArray(3))
y luego devolver fluxarray pero eso no funciona, ya que fortran no puede entender la sintaxis
La función real es esta:
DOUBLE PRECISION FUNCTION Flux(W1,W2)
USE parameters
IMPLICIT NONE
DOUBLE PRECISION, DIMENSION(3), INTENT(IN)::W1, W2
DOUBLE PRECISION, DIMENSION(3), INTENT(OUT):: Flux
DOUBLE PRECISION, DIMENSION(3):: F1, F2
DOUBLE PRECISION::U1,U2,Rh1,Rh2,P1,P2,E1,E2,Rh,P,u,c,Lambda
INTEGER:: k
U1=W1(2)/W1(1)
U2=W2(2)/W2(1)
Rh1=W1(1)
Rh2=W2(1)
P1=(gamma_constant-1.d0)*(W1(3)-.5d0*Rh1*U1**2)
P2=(gamma_constant-1.d0)*(W2(3)-.5d0*Rh2*U2**2)
E1=W1(3)
E2=W2(3)
F1=[Rh1*U1,Rh1*U1**2+P1,(E1+P1)*U1]
F2=[Rh2*U2,Rh2*U2**2+P2,(E2+P2)*U2]
Rh=.5d0*(Rh1+Rh2)
P=.5d0*(P1+P2)
u=.5d0*(U1+U2)
c=sqrt(gamma_constant*P/Rh)
Lambda=max(u, u+c, u-c)
do k=1,3,1
Flux(k)=.5d0*(F1(k)+F2(k))-.5d0*eps*Lambda*(W2(k)-W1(k))
end do
RETURN
END FUNCTION Flux
Aquí está la declaración de error:
Quasi1DEuler.f90:191.51:
DOUBLE PRECISION, DIMENSION(3), INTENT(OUT):: Flux
1
Error: Symbol ''flux'' at (1) already has basic type of REAL
Quasi1DEuler.f90:217.58:
Flux(k)=.5d0*(F1(k)+F2(k))-.5d0*eps*Lambda*(W2(k)-W1(k))
1
Error: Unexpected STATEMENT FUNCTION statement at (1)
Quasi1DEuler.f90:76.18:
Fr = Flux(W(:,i),W(:,i+1))
El último error ocurre para Fr y Fl. ¡Gracias por su tiempo y cualquier ayuda o consideración que pueda brindar!
EDIT / Seguimiento :: Gracias por la ayuda, no conozco una mejor manera de presentar esto, así que voy a editar la pregunta inicial.
Hice lo que sugirió y resolvió ese problema, ahora dice:
Fr = Flux(W(:,i),W(:,i+1))
1
Error: The reference to function ''flux'' at (1) either needs an explicit INTERFACE or the rank is incorrect
Vi un problema similar en SO en este enlace:
Calculando el producto cruzado de dos vectores en Fortran 90
donde sugirieron que él pusiera todas sus funciones en módulos. ¿Hay alguna manera mejor / más simple para solucionar este error?