MoDeNa  1.0
Software framework facilitating sequential multi-scale modelling
twoTanksMacroscopicProblemFortran.f90
1 !
2 !
3 ! ooo ooooo oooooooooo. ooooo ooo
4 ! `88. .888' `888' `Y8b `888b. `8'
5 ! 888b d'888 .ooooo. 888 888 .ooooo. 8 `88b. 8 .oooo.
6 ! 8 Y88. .P 888 d88' `88b 888 888 d88' `88b 8 `88b. 8 `P )88b
7 ! 8 `888' 888 888 888 888 888 888ooo888 8 `88b.8 .oP"888
8 ! 8 Y 888 888 888 888 d88' 888 .o 8 `888 d8( 888
9 ! o8o o888o `Y8bod8P' o888bood8P' `Y8bod8P' o8o `8 `Y888""8o
10 !
11 !Copyright
12 ! 2014-2016 MoDeNa Consortium, All rights reserved.
13 !
14 !License
15 ! This file is part of Modena.
16 !
17 ! Modena is free software; you can redistribute it and/or modify it under
18 ! the terms of the GNU General Public License as published by the Free
19 ! Software Foundation, either version 3 of the License, or (at your option)
20 ! any later version.
21 !
22 ! Modena is distributed in the hope that it will be useful, but WITHOUT ANY
23 ! WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
24 ! FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
25 ! details.
26 !
27 ! You should have received a copy of the GNU General Public License along
28 ! with Modena. If not, see <http://www.gnu.org/licenses/>.
29 !
30 !Description
31 ! Solving the two tank problem the MoDeNa way.
32 !
33 ! A prototypical macros-scopic code embeds a micro-scale model (flowRate)
34 ! through the MoDeNa interface library.
35 !
36 ! Re-programmed to Fortran
37 !
38 !Authors
39 ! Henrik Rusche
40 !
41 !Contributors
42 ! Pavel Ferkl
43 program twotanksmacroscopicproblemfortran !command line arguments not implemented yet
44  use iso_c_binding
45  use fmodena
46 
47  implicit none
48 
49  integer, parameter ::dp=selected_real_kind(15)
50 
51  real(dp), parameter :: d = 0.01_dp;
52 
53  real(dp) :: p0 = 3e5;
54  real(dp) :: p1 = 10000;
55  real(dp) :: v0 = 0.1_dp;
56  real(dp) :: v1 = 1;
57  real(dp) :: temp = 300;
58 
59  real(dp) :: t = 0.0_dp;
60  real(dp), parameter :: deltat = 1e-3_dp;
61  real(dp), parameter :: tend = 5.5_dp;
62 
63  real(dp) :: m0
64  real(dp) :: m1
65 
66  real(dp) :: rho0
67  real(dp) :: rho1
68 
69  real(dp) :: mdot
70 
71  integer(c_int) :: ret
72 
73  type(c_ptr) :: client = c_null_ptr !mongoc_client_t
74  type(c_ptr) :: model = c_null_ptr !modena_model_t
75  type(c_ptr) :: inputs = c_null_ptr !modena_inputs_t
76  type(c_ptr) :: outputs = c_null_ptr !modena_outputs_t
77 
78  integer(c_size_t) :: dpos
79  integer(c_size_t) :: rho0pos
80  integer(c_size_t) :: p0pos
81  integer(c_size_t) :: p1byp0pos
82 
83  m0 = p0*v0/287.1_dp/temp;
84  m1 = p1*v1/287.1_dp/temp;
85  rho0 = m0/v0;
86  rho1 = m1/v1;
87 
88 ! //Instantiate a model
89  model = modena_model_new(c_char_"flowRate"//c_null_char); !modena_model_t
90 
91 ! //Allocate memory and fetch arg positions
92  inputs = modena_inputs_new(model); !modena_inputs_t
93  outputs = modena_outputs_new(model); !modena_outputs_t
94 
95  dpos = modena_model_inputs_argpos(model, c_char_"D"//c_null_char);
96  rho0pos = modena_model_inputs_argpos(model, c_char_"rho0"//c_null_char);
97  p0pos = modena_model_inputs_argpos(model, c_char_"p0"//c_null_char);
98  p1byp0pos = modena_model_inputs_argpos(model, c_char_"p1Byp0"//c_null_char);
99 
100 ! //TODO: Add checking function that makes sure that the positions of all
101 ! //arguments to the model are requested
102  call modena_model_argpos_check(model);
103 
104  do while(t + deltat < tend + 1e-10_dp)
105 
106  t = t + deltat;
107 
108  if(p0 > p1) then
109 ! //Set input vector
110  call modena_inputs_set(inputs, dpos, d);
111  call modena_inputs_set(inputs, rho0pos, rho0);
112  call modena_inputs_set(inputs, p0pos, p0);
113  call modena_inputs_set(inputs, p1byp0pos, p1/p0);
114 
115 ! // Call the model
116  ret = modena_model_call(model, inputs, outputs);
117 
118 ! // Terminate, if requested
119  if(ret /= 0) then
120 
121  call modena_inputs_destroy (inputs);
122  call modena_outputs_destroy (outputs);
123  call modena_model_destroy (model);
124 
125  call exit(ret)
126  endif
127 
128 ! // Fetch result
129  mdot = modena_outputs_get(outputs, 0_c_size_t);
130 
131  m0 = m0 - mdot*deltat;
132  m1 = m1 + mdot*deltat;
133 
134  else
135 
136 ! // Set input vector
137  call modena_inputs_set(inputs, dpos, d);
138  call modena_inputs_set(inputs, rho0pos, rho1);
139  call modena_inputs_set(inputs, p0pos, p1);
140  call modena_inputs_set(inputs, p1byp0pos, p0/p1);
141 
142 ! // Call the model
143  ret = modena_model_call(model, inputs, outputs);
144 
145 ! // Terminate, if requested
146  if(ret /= 0) then
147 
148  call modena_inputs_destroy (inputs);
149  call modena_outputs_destroy (outputs);
150  call modena_model_destroy (model);
151 
152  call exit(ret)
153  endif
154 
155 ! // Fetch result
156  mdot = modena_outputs_get(outputs, 0_c_size_t);
157 
158  m0 = m0 + mdot*deltat;
159  m1 = m1 - mdot*deltat;
160  endif
161 
162  rho0 = m0/v0;
163  rho1 = m1/v1;
164  p0 = m0/v0*287.1_dp*temp;
165  p1 = m1/v1*287.1_dp*temp;
166 
167  write(*,*) "t = ",t," rho0 = ",rho0," p0 = ",p0," p1 = ",p1
168  enddo
169 
170  call modena_inputs_destroy (inputs);
171  call modena_outputs_destroy (outputs);
172  call modena_model_destroy (model);
173 
174  call exit(0)
175 end program twotanksmacroscopicproblemfortran
double tend
end time, s