flow_module.f90
Go to the documentation of this file.
1 !> @file flow_module.f90
2 !!
3 !! The error file code for this file is ***W20***.
4 !! @brief Module \ref flow_module for calculating reaction flows
5 !!
6 
7 !> Provides subroutines to calculate reaction flows
8 !!
9 !! @author Christian Winteler
10 !! @date 07.10.10
11 !!
12 !! \b Edited:
13 !! - 03.04.18, M. Jacobi , Rewrote the module, the flows are now
14 !! calculated with the help of the Jacobian
15 !! - 22.01.21, M. Reichert , added more comments
16 !! .
17 #include "macros.h"
20  use pardiso_class, only: jind, vals
21  implicit none
22 
23 
24 
25  type(flow_vector),dimension(:),allocatable, public :: flows
26 
27  !
28  ! Public and private fields and methods of the module
29  !
30  public:: &
32 
33  private:: &
34  flowsort
35 
36 contains
37 
38 
39 
40 !>
41 !! Initialise flow subroutine
42 !!
43 !! This subroutine counts the number of possible flows
44 !! and allocates the \ref flows array.
45 !!
46 !! \b Edited:
47 !! - 11.01.14
48 !! - 03.04.18, M. Jacobi
49 subroutine flow_init()
50  implicit none
51 
52  integer :: ind, i, j
53 
54  info_entry("flow_init")
55 
56  ind=0
57 
58  ! Cycle through Jacobian and look at J_ij and J_ji
59  ! Get amount of flow instances
60  do i=1,net_size
61  ! Ignore hydrogen, neutrons and helium
62  if (i.eq.ihe4) cycle
63  if (i.eq.ipro) cycle
64  if (i.eq.ineu) cycle
65 
66  do j=1,net_size
67  if (j.eq.ihe4) cycle
68  if (j.eq.ipro) cycle
69  if (j.eq.ineu) cycle
70 
71  ! Ignore diagonal
72  if (i.eq.j) cycle
73  ! Account for entries that are only present at one of the diagonals
74  if (jind(i,j).eq.0) cycle
75  if (i .lt. j) then
76  if (.not. jind(j,i).eq.0) cycle
77  end if
78 
79  ! Count amount of possible flows
80  ind = ind +1
81 
82  end do
83  end do
84 
85  allocate (flows(ind))
86 
87  info_exit("flow_init")
88 
89  return
90 
91 end subroutine flow_init
92 
93 
94 
95 !>
96 !! Flow calculation from jacobian. It is calculated with the help of the Jacobian.
97 !! \f[
98 !! F_{ij} = |(1/h - J_{ij}) \times Y_i - (1/h - J_{ji}) \times Y_j|
99 !! \f]
100 !!
101 !! @note Using the jacobian directly has the advantage
102 !! that the flow will be correct if the calculation
103 !! is correct. In previous versions, the flow
104 !! was not calculated by using the jacobian.
105 !!
106 !! \b Edited:
107 !! - 03.04.18, M. Jacobi
108 !! .
109 subroutine flowcalc(Y)
110  implicit none
111 
112  real(r_kind),dimension(:),intent(in) :: y !< abundance
113  integer :: ind, i, j
114 
115  info_entry("flowcalc")
116 
117  ind=0
118  ! Cycle through values of the Jacobian and calculate flows
119  do i=1,net_size
120  ! Ignore hydrogen, neutrons and helium
121  if (i.eq.ihe4) cycle
122  if (i.eq.ipro) cycle
123  if (i.eq.ineu) cycle
124 
125  do j=1,net_size
126  if (j.eq.ihe4) cycle
127  if (j.eq.ipro) cycle
128  if (j.eq.ineu) cycle
129  ! Ignore diagonal
130  if (i.eq.j) cycle
131  ! Account for entries that are only present at one of the triangle matrix
132  if (jind(i,j).eq.0) cycle
133  if (i .lt. j) then
134  if (.not. jind(j,i).eq.0) cycle
135  end if
136 
137  ind = ind +1
138 
139  ! Store the flow i->j
140  flows(ind)%iin = i
141  flows(ind)%iout = j
142  flows(ind)%fwd = -vals(jind(i,j))*y(i)
143 
144  ! Store the flow j->i
145  if (jind(j,i).eq.0) then
146  flows(ind)%bwd = 0
147  else
148  flows(ind)%bwd = -vals(jind(j,i))*y(j)
149  end if
150  end do
151  end do
152 
153  ! Swap fwd and bwd flows if necessary
154  call flowsort()
155 
156  info_exit("flowcalc")
157 
158  return
159 
160 end subroutine flowcalc
161 
162 
163 !> Bring flows to correct format
164 !!
165 !! Make the flows positive and swap ingoing neutron and proton numbers
166 !! in case of negative flows.
167 subroutine flowsort
168  implicit none
169  integer :: i !< Loop variable
170  integer :: tmp !< Temporary helper variable for an index
171  real(r_kind) :: ftmp !< Temporary helper variable for a flow
172 
173  do i = 1,size(flows)
174  if(flows(i)%bwd.gt.flows(i)%fwd) then
175  ftmp = flows(i)%fwd
176  flows(i)%fwd = flows(i)%bwd
177  flows(i)%bwd = ftmp
178  tmp = flows(i)%iin
179  flows(i)%iin = flows(i)%iout
180  flows(i)%iout = tmp
181  end if
182 
183  end do
184 
185 end subroutine flowsort
186 
187 !>
188 !! Output reaction flows to a file
189 !!
190 !! An example of this file may look like:
191 !!\file{
192 !! time temp dens
193 !! 1.03895957612263E-01 7.19136097013393E+00 1.40977753502083E+06
194 !! nin zin yin nout zout yout flow
195 !! 2 1 4.81807892321990E-08 1 1 2.13994533749120E-06 0.00000000000000E+00
196 !! 1 2 1.26489216252989E-09 1 1 2.13994533749120E-06 0.00000000000000E+00
197 !! 1 2 1.26489216252989E-09 2 1 4.81807892321990E-08 1.58426675189734E-10
198 !! 4 2 9.86495465952053E-13 3 3 2.15833022688002E-11 8.53665754802155E-13
199 !! ...}
200 !!
201 !! \b Edited:
202 !! - 11.01.14
203 !! - 03.04.18, M. Jacobi
204 !! .
205 subroutine flowprint(t,t9,dens,abu,cnt)
206  use global_class, only: isotope_type, isotope
208  implicit none
209 
210  real(r_kind),intent(in) :: t !< time [s]
211  real(r_kind),intent(in) :: t9 !< temperature [GK]
212  real(r_kind),intent(in) :: dens !< density [g/cm3]
213  real(r_kind),dimension(:),intent(in) :: abu !< abundances
214  integer,intent(in) :: cnt !< flow snapshot counter
215  !
216  type(isotope_type) :: nucin,nucout
217  integer :: i
218  integer :: ini,ino
219  integer :: flowunit
220  character*50 :: flowfile
221  real(r_kind) :: y_ini, y_ino, flow_diff
222 
223  info_entry("flowprint")
224 
225  select case (cnt)
226  case(:9)
227  write(flowfile,'(a16,i1,a4)')'flow/flow_000',cnt,'.dat'
228  case(10:99)
229  write(flowfile,'(a15,i2,a4)')'flow/flow_00',cnt,'.dat'
230  case(100:999)
231  write(flowfile,'(a14,i3,a4)')'flow/flow_0',cnt,'.dat'
232  case default
233  write(flowfile,'(a13,i4,a4)')'flow/flow_',cnt,'.dat'
234  end select
235  flowunit= open_outfile(adjustl(flowfile))
236 
237  write(flowunit,'(3a8)')'time','temp','dens'
238  write(flowunit,'(3es23.14)')t,t9,dens
239  write(flowunit,'(7(a8))')'nin','zin','yin','nout','zout','yout',&
240  'flow'
241  do i = 1,size(flows)
242  ! Declare helper variables
243  ini = flows(i)%iin
244  ino = flows(i)%iout
245  nucin = isotope(ini)
246  nucout = isotope(ino)
247 
248  ! Make a matching format and prevent something like 1.89-392 instead of 1.89E-392
249  flow_diff = flows(i)%fwd - flows(i)%bwd
250  y_ino = abu(ino)
251  y_ini = abu(ini)
252  if (abu(ini) .ne. 0.) y_ini = max(1.d-99,abu(ini))
253  if (abu(ino) .ne. 0.) y_ino = max(1.d-99,abu(ino))
254  if (flow_diff .ne. 0.) flow_diff = max(1.d-99,flows(i)%fwd - flows(i)%bwd)
255 
256  if (flow_diff .ne. 0) then
257  write(flowunit,'(2(2i4,es23.14),es23.14)') &
258  nucin%n_nr,nucin%p_nr,y_ini, &
259  nucout%n_nr,nucout%p_nr,y_ino, &
260  flow_diff
261  end if
262  end do
263 
264  call close_io_file(flowunit,flowfile)
265 
266  info_exit("flowprint")
267 
268  return
269 
270 end subroutine flowprint
271 
272 end module flow_module
pardiso_class::vals
real(r_kind), dimension(:), allocatable, public vals
contains non-zero matrix elements (of the Jacobian)
Definition: pardiso_class.f90:30
global_class::ipro
integer, public ipro
index of alphas, neutrons and protons
Definition: global_class.f90:94
global_class::ihe4
integer, public ihe4
Definition: global_class.f90:94
global_class::flow_vector
Flow type to store flows.
Definition: global_class.f90:85
flow_module::flows
type(flow_vector), dimension(:), allocatable, public flows
Definition: flow_module.f90:25
flow_module::flowprint
subroutine, public flowprint(t, t9, dens, abu, cnt)
Output reaction flows to a file.
Definition: flow_module.f90:206
global_class::isotope_type
data fields for the nuclides contained in the network
Definition: global_class.f90:24
flow_module::flowsort
subroutine, private flowsort
Bring flows to correct format.
Definition: flow_module.f90:168
global_class::ineu
integer, public ineu
Definition: global_class.f90:94
global_class::isotope
type(isotope_type), dimension(:), allocatable, public isotope
all nuclides used in the network
Definition: global_class.f90:34
pardiso_class::jind
integer, dimension(:,:), allocatable, public jind
jind(i,j) contains the index of jacobian entry in vals
Definition: pardiso_class.f90:35
flow_module::flowcalc
subroutine, public flowcalc(Y)
Flow calculation from jacobian. It is calculated with the help of the Jacobian.
Definition: flow_module.f90:110
global_class::net_size
integer, public net_size
total number of isotopes (network size)
Definition: global_class.f90:93
file_handling_class
Provide some basic file-handling routines.
Definition: file_handling_class.f90:18
pardiso_class
Contains subroutines for sparse matrix assembly and the solver core.
Definition: pardiso_class.f90:24
flow_module::flow_init
subroutine, public flow_init()
Initialise flow subroutine.
Definition: flow_module.f90:50
r_kind
#define r_kind
Definition: macros.h:46
flow_module
Provides subroutines to calculate reaction flows.
Definition: flow_module.f90:18
file_handling_class::open_outfile
integer function, public open_outfile(file_name)
Shorthand for opening a new file for writing (output file)
Definition: file_handling_class.f90:108
global_class
Contains types and objects shared between multiple modules.
Definition: global_class.f90:19
file_handling_class::close_io_file
subroutine, public close_io_file(unit_no, file_name)
Close an external file.
Definition: file_handling_class.f90:144