-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PR: Fix vars2fortran: No typespec for argument when compiling HELP3O #50
base: master
Are you sure you want to change the base?
Conversation
This is not the place to do this. Let's not get out of scope here.
This is not the place to do this kind of changes
Note that using Double Precision and DFLOAT instead of REAL and FLOAT make the tests fail.
In function C ***************************** COMPUT *****************************
C COMPUT is used in function AHU, which accumulates heat units and
C radiation to calculate potential heat units for each crop before daily
C simulation begin.
FUNCTION COMPUT(AC,A,B,I,N)
Double Precision, INTENT(IN) :: AC
Double Precision, INTENT(IN) :: A
Double Precision, INTENT(IN) :: B
INTEGER, INTENT(IN) :: I
INTEGER, INTENT(IN) :: N
AI =DFLOAT(I)-0.5
AN =DFLOAT(N)
ANG =6.283185*AI/AN
COMPUT =AC+A*COS(ANG)+B*SIN(ANG)
RETURN
END The tests succeed if I declare the variables as Below are presented the results from the reference RCA test case, the results obtained with PyHELP when declaring the variables as ref_evapo_RCA_case : [32.178, 33.420, 36.540] in/yea As we can see, using |
As explained in the StackOverflow answer (https://stackoverflow.com/a/50918289/4481445):
So here is what I think is probably happening. The RCA test case was run with an executable compiled on a 16bits Windows machine (but I'm not sure this is relevant). They probably compiled with some flags, so that the implicit On my 64bits Windows machine, when compiling without any flags, the implicit precision of C ***************************** COMPUT *****************************
FUNCTION COMPUT(AC,A,B,I,N)
integer, parameter :: sp = selected_real_kind(6, 37)
integer, parameter :: dp = selected_real_kind(15, 307)
integer, parameter :: qp = selected_real_kind(33, 4931)
real(kind=qp) :: AC
real(kind=qp) :: A
real(kind=qp) :: B
INTEGER, INTENT(IN) :: I
INTEGER, INTENT(IN) :: N
AI =REAL(I, qp)-0.5
AN =REAL(N, qp)
ANG =6.283185*AI/AN
COMPUT =AC+A*COS(ANG)+B*SIN(ANG)
RETURN
END Evapo 32bits: [32.1836 33.416042 36.53447 ] in/year The fact that we do not obtain the same results when using 32 and 64 bits precision seems to indicate that using the 32bits precision is not precise enough and introduce round-off errors in the calculation. In this case, using a 32bits precision seems to introduce an underestimation of evapotranspiration by 47.3 mm , 61.9 mm, and 48.1 mm for, respectively, year 1, 2, and 3. This is significant. Note that in other cases, this can cause overestimation of evapotranspiration too. This will need to be considered very carefully. What should I do with this? Should I use 64 bits precision instead when pertinent? In my opinion, I think it would be better to use 64bits precision, even if this means that we do not obtain the same results as in the RCA test case anymore. This topic is somewhat related to what was also discussed in PR #1 Here is the list of compiler flags for gfortran: |
@Rene-Lefebvre-INRS Bonjour René. Est-ce que tu pourrais regarder ce que j'ai documenté ici quand tu auras une minute stp? J'aimerais avoir ton avis sur ce sujet. |
C’est plutôt embêtant…
Il semble que les tests du code aient effectivement été faits avec 32 bits (ce qui était déjà à l’époque de la double précision)… Mais cela semble insuffisant comme précision puisqu’une changement à 64 bits donne des résultats différents.
Je crois aussi qu’il faudrait y aller avec 64 bits. Peux-tu compiler en double précision de façon à éviter de changer explicitement REAL pour « Double Precision » dans le code?
Idéalement cela nous prendrait un test dont nous connaissons le résultat pour juger de la meilleure solution. Cela pourrait provenir d’un autre code ou d’une solution analytique…
|
I went back to compile and test the Fortran code directly (without compiling a Python extension). I tested it when (1) compiling without any flags (32 bits precision for REAL) and when (2) compiling it with the flag -fdefault-real-8 :
I compared the results and they were about the same in both cases. This suggests that the default 32bits precision for REAL is enough. So I went back to investigate a little bit more to understand where the aforementioned computational errors comes from. The problem is that when we decide to explicitly set the
This is what's causing the computational errors. So the solution is simple: fixing all the I think it is better to use DOUBLE PRECISION only when needed in the code because using the |
OK, these tests seem convincing and I agree with the use of double precision only when needed. |
Fixes #24
When compiling the Fortran code for HELP, we get a lot of warnings of the type :
This means that the typespec of the function variables need to be defined explicitly in the code. The goal of this PR is to fix that by declaring explicitly the variables in each function that raises a warning. This need to be done very carefully and rigorously though not to introduce unwanted errors in the computation.
Below is a part of the log from AppVeyor during the building process: