- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear,
I have 3 Modules in Fortran. Those modules return 3 variables. Let's call them: Modules A, B and C and variables A, B and C.
I'm exporting the Modules through a DLL to be showed in three diferent TextBoxes in C#. Module A is independent. Module B calls Module A and Module C calls both Modules A and B.
When I importing those Modules in C# and display the variables A, B and C, what I get is a correct value for variable A in the fisrt TextBox and NaN for variables B and C! (See the attatched figure)
I really don't know I to do now. I get all the right results when I run the code in a main program only in Fortran.
Can somebody help me, please?
Thanks in advance.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We really need to see your code to understand what you are doing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Guys,
I discovered that when I fix the value of the variable reyOleo, for example: reyOleo = 4000, it calculates the fatAtrito. However, if reyOleo is calculated, it returns a correct value for reyOleo, but NaN for fatAtrito.
I'm really don't understanding. It seems that C# is not undestading the follwing peace of code:
reyOleo = (39370.1/86400.0) * (vazaoOleo * diametroTubo * massaEspecOleo / (viscOleo * areaTubo))
Any clue?
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Given a problem description that is imprecise and vague, there may be little that we can do to help you. Try to remember that we are not standing at your shoulder observing all the things that you do. If you are going to do mixed language programming with shared variables, you need a good understanding of the scope of variables, accessibility of variables and the consequences of aliasing.
Nevertheless, I spot one source of trouble: in the Reynol.f90 file, you have module variables with the same names as the formal (dummy) arguments to a contained subprogram. Read the the Fortran documentation as to the implications of doing this, and ask yourself, "what do I want the compiler to do when it sees a reference or an assignment to one of these variables in the subprogram code? Use/update the formal argument, the module variables, or both? Furthermore, if the caller also uses the module, you could have two seemingly different variables that are tied to the same memory address, and chaos can follow -- the left hand does not know what the right hand is doing.
Try the following test: add the following lines to reynol.f90, and run the program. You will see that the variable Reyoleo retains the original value of 20000, whereas you might have expected it to have the newly computed value of the actual argument e, which corresponds to the formal argument ReyOleo in the subroutine.
program bugrey use Reynolds double precision a,b,c,d,e ReyOleo = 20000 a=5; b=0.1; c=800; d=10; e=20 call Reynol(a,b,c,d,e) write(*,*)ReyOleo,e end program
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, mecej4.
I think I got it. I did what you suggested. In Reynol.f90 I have no more module variables with the same name of the dummy arguments.
Now I have different variables in this module with this call:
call Reynol(vazaoOleo_, diametroTubo_, massaEspecOleo_, viscOleo_, reyOleo_)
However, it's resulting in fatrito = 1, i.e, when reyOleo is passed to reyOleo_ , for some reason it assumes a zero value or:(reyOleo_ <= 2100d0).
Jesus, it's not so simple...
In FatFan.f90 I did:
module Fatrito
use Reynolds
implicit none
contains
subroutine Fatfan(rugoTubo, fatAtrito)
!DEC$ ATTRIBUTES DLLEXPORT :: Fatfan
double precision, intent(in) :: rugoTubo
double precision, intent(out) :: fatAtrito
double precision :: A1
double precision :: A2
double precision :: vazaoOleo_, diametroTubo_, massaEspecOleo_, viscOleo_, reyOleo_
call Reynol(vazaoOleo_, diametroTubo_, massaEspecOleo_, viscOleo_, reyOleo_)
if (reyOleo_ <= 2100d0) then
fatAtrito = 1
end if
if (reyOleo_ >= 4000.d0) then
fatAtrito = 2
end if
if (reyOleo_ >2100d0 .and. reyOleo_ <4000d0) then
fatAtrito = 3
end if
end subroutine
end module
module Reynolds
implicit none
contains
subroutine Reynol(vazaoOleo, diametroTubo, massaEspecOleo, viscOleo, reyOleo)
! ReyOleo = Número de Reynolds do óleo
!DEC$ ATTRIBUTES DLLEXPORT :: Reynol
double precision, intent(in) :: vazaoOleo, diametroTubo, massaEspecOleo, viscOleo
double precision, intent(out) :: reyOleo
double precision :: areaTubo
parameter pi = 3.1415927d0
areaTubo = (pi * diametroTubo **2) / 4
reyOleo = (39370.1/86400.0) * (vazaoOleo * diametroTubo * massaEspecOleo / (viscOleo * areaTubo))
end subroutine
end module
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is not worthwhile to mix code fragments that are scattered in the various posts. Please show a complete example and we can look at the problem.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
mecej4,
I reproduced this problem in a simpler example of 2 modules. In one I sum two numbers and in the other to get the result of this sum and multiply it for another entry value. For the first module I got the right result, but for the other I had a problem, as you can see below.
module SumTwoNumbers
implicit none
contains
subroutine SumNumbers(a, b, c)
!DEC$ ATTRIBUTES DLLEXPORT :: SumNumbers
! Declaring variables:
double precision, intent(in) :: a, b
double precision, intent(out) :: c
! Summing two numbers:
c = a + b
end subroutine
end module
module MultiplyNumbers
use SumTwoNumbers
implicit none
contains
subroutine MultiNumbers(d, e)
!DEC$ ATTRIBUTES DLLEXPORT :: MultiNumbers
!Declaring variables:
double precision, intent(in) :: d
double precision, intent(out) :: e
double precision :: a_,b_,c_
call SumNumbers(a_,b_,c_)
!Multiplying numbers:
e = c_ * d
end subroutine
end module
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ewerton C. wrote:
..
.. subroutine MultiNumbers(d, e) !DEC$ ATTRIBUTES DLLEXPORT :: MultiNumbers !Declaring variables: double precision, intent(in) :: d double precision, intent(out) :: e double precision :: a_,b_,c_ call SumNumbers(a_,b_,c_) !Multiplying numbers: e = c_ * d end subroutine end module
Amongst other things, in your MultiNumbers procedure, think about where and how the variables a_, b_, and c_ get their values.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It WORKED!
See what I did in module SumTwoNumbers.
Variables a_, b_ and c_ receives a, b and c, respectively. And I declared a_, b_ and c_ globally.
In MultiplyNumbers module, I didn't need to call SumNumbers, just used the USE statement. However, I dont know if it's the only and most appropriate way to pass variables through modules.
module SumTwoNumbers
implicit none
double precision :: a_,b_,c_
contains
subroutine SumNumbers(a, b, c)
!DEC$ ATTRIBUTES DLLEXPORT :: SumNumbers
! Declaring variables:
double precision, intent(in) :: a, b
double precision, intent(out) :: c
! Summing two numbers:
c = a + b
a_ = a
b_ = b
c_ = c
end subroutine
end module
module MultiplyNumbers
use SumTwoNumbers
implicit none
contains
subroutine MultiNumbers(d, e)
!DEC$ ATTRIBUTES DLLEXPORT :: MultiNumbers
!Declaring variables:
double precision, intent(in) :: d
double precision, intent(out) :: e
!Multiplying numbers:
e = c_ * d
end subroutine
end module
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page