MoDeNa  1.0
Software framework facilitating sequential multi-scale modelling
integration.f90
Go to the documentation of this file.
1 
7 module integration
8  use constants
9  use globals
10  use foaming_globals_m
11  use fmodena
12  use modenastuff
13  use in_out, only: save_integration_header,save_integration_step,&
14  save_integration_close
15  use model, only:odesystem,dim_var,molar_balance
16  use phys_prop, only:set_initial_physical_properties
17  implicit none
18  private
19  !time integration variables for sundials
20  integer :: meth, itmeth, iatol, jpretype, igstype, maxl, ier!, itask
21  integer(c_long) :: ipar(1), mu, ml, iouts(25), maxtss
22  real(dp) :: rout(10), rpar(1), delt!, tout, atol, rtol, t
23  !time integration variables for lsode
24  integer :: iout, iopt, istate, itask, itol, liw, lrw, nnz, lenrat, neq, mf
25  real(dp) :: jac,tout,rtol,atol,t
26  real(dp), dimension(:), allocatable :: rwork!,y
27  integer, dimension(:), allocatable :: iwork
28  !needed for selection of subroutine for evaluation of derivatives
29  abstract interface
30  subroutine sub (neq, t, y, ydot)
31  use constants
32  integer, intent(in) :: neq
33  real(dp), intent(in) :: t
34  real(dp), intent(in) :: y(neq)
35  real(dp), intent(out) :: ydot(neq)
36  end subroutine sub
37  end interface
38  procedure(sub), pointer :: sub_ptr => odesystem
39  public bblpreproc,bblinteg,neq
40 contains
41 !********************************BEGINNING*************************************
45 subroutine bblpreproc
46  write(*,*) 'preparing simulation...'
47  call checks
48  call set_initial_physical_properties
49  call set_equation_order
50  call create_mesh(0.0_dp,s0**3-r0**3,p,mshco)
51  call set_initial_conditions
52  call set_integrator
53  write(*,*) 'done: simulation prepared'
54  write(*,*)
55 end subroutine bblpreproc
56 !***********************************END****************************************
57 
58 
59 !********************************BEGINNING*************************************
64 subroutine checks
65  select case (kin_model)
66  case(1)
67  case(3)
68  case(4)
69  case default
70  stop 'unknown kinetic model'
71  end select
72  if (geometry /= "2D" .and. geometry /= "3D") then
73  print*, 'geometry can be 3D or 2D'
74  stop
75  endif
76 end subroutine checks
77 !***********************************END****************************************
78 
79 
80 !********************************BEGINNING*************************************
85 subroutine create_mesh(a,b,p,s)
86  integer, intent(in) :: p
87  real(dp), intent(in) :: &
88  a,& !< lower bound
89  b,& !< upper bound
90  s
91  integer :: i,info
92  real(dp),allocatable :: atri(:),btri(:),ctri(:),rtri(:),utri(:)
93  allocate(atri(p),btri(p),ctri(p),rtri(p),utri(p),dz(p+1))
94  atri=-s !lower diagonal
95  btri=1+s !main diagonal
96  ctri=-1 !upper diagonal
97  rtri=a !rhs
98  rtri(p)=b
99  utri=rtri
100  call dgtsl(p,atri,btri,ctri,utri,info)
101  if ((utri(2)-utri(1))/utri(1)<10*epsilon(utri)) stop 'set smaller mesh &
102  coarsening parameter'
103  dz(1)=utri(1)+rtri(1)/s
104  do i=2,p
105  dz(i)=utri(i)-utri(i-1)
106  enddo
107  dz(p+1)=rtri(p)-utri(p)
108  deallocate(atri,btri,ctri,rtri,utri)
109 end subroutine create_mesh
110 !***********************************END****************************************
111 
112 
113 !********************************BEGINNING*************************************
118 subroutine set_equation_order
119  integer :: i
120  neq=(p+1)*ngas
121  if (firstrun) then
122  neq = neq+4+ngas
123  req=1 !radius index
124  fpeq=2 !pressure index
125  if (inertial_term) then
126  neq=neq+1
127  fpeq=fpeq+1
128  endif
129  else
130  neq = neq+3+ngas
131  fpeq=1 !pressure index
132  endif
133  lpeq=fpeq+ngas-1
134  teq=lpeq+1 !temperature index
135  xoheq=teq+1 !polyol conversion index
136  xweq=xoheq+1 !water conversion index
137  fceq = xweq+1 !concentration index
138  if (kin_model==4) then
139  allocate(kineq(20),kinsource(20))
140  endif
141  if (kin_model==4) then
142  neq=neq+size(kineq)
143  do i=1,size(kineq)
144  kineq(i)=xweq+i
145  enddo
146  fceq=kineq(size(kineq))+1
147  endif
148 end subroutine set_equation_order
149 !***********************************END****************************************
150 
151 
152 !********************************BEGINNING*************************************
156 subroutine set_integrator
157  if (integrator==1 .or. integrator==2) then
158  mf=int_meth
159  select case(integrator)
160  case(1)
161  select case(mf)
162  case(10)
163  allocate(rwork(20+16*neq),iwork(20))
164  case(22)
165  allocate(rwork(22+9*neq+neq**2),iwork(20+neq))
166  case default
167  stop 'unknown mf'
168  end select
169  case(2)
170  select case(mf)
171  case(10)
172  allocate(rwork(20+16*neq),iwork(30))
173  case(222)
174  nnz=neq**2 !not sure, smaller numbers make problems for low p
175  lenrat=2 !depends on dp
176  allocate(rwork(int(20+(2+1._dp/lenrat)*nnz+(11+9._dp/lenrat)*neq)),&
177  iwork(30))
178  case default
179  stop 'unknown mf'
180  end select
181  case default
182  stop 'unknown integrator'
183  end select
184  itask = 4
185  istate = 1
186  iopt = 1
187  rwork(1)=tend+epsilon(tend)*1.0e3_dp
188  rwork(5:10)=0
189  iwork(5:10)=0
190  lrw = size(rwork)
191  liw = size(iwork)
192  iwork(6)=maxts
193  itol = 1 !don't change, or you must declare atol as atol(neq)
194  rtol=rel_tol
195  atol=abs_tol
196  elseif (integrator==3) then
197  meth = int_meth ! integration method: 1=Adams (nonstiff), 2=BDF (stiff)
198  itmeth = 2 ! nonlinear iteration method: 1=functional, 2=Newton
199  iatol = 1
200  rtol=rel_tol
201  atol=abs_tol
202  itask = 1
203  jpretype=0 ! preconditioner type; 0=no, 1=left, 2=right, 3=both
204  igstype=1 ! gram-schmidt; 1=modified, 2=classical
205  maxl=0 ! maximum krylov subspace dimension
206  delt=0 ! linear tolerence convergence factor
207  ! initialize vector specification
208  call fnvinits(1, neq, ier)
209  if (ier .ne. 0) then
210  write(*,*) ' sundials_error: fnvinits returned ier = ',ier
211  stop
212  endif
213  ! initialize cvode
214  call fcvmalloc(t, y, meth, itmeth, iatol, rtol, atol,&
215  iouts, rout, ipar, rpar, ier)
216  if (ier .ne. 0) then
217  write(*,*) ' sundials_error: fcvmalloc returned ier = ',ier
218  stop
219  endif
220  ! set maximum number of internal steps
221  call fcvsetiin("MAX_NSTEPS",maxts,ier)
222  if (ier .ne. 0) then
223  write(*,*) ' sundials_error: fcvsetiin returned ier = ',ier
224  stop
225  endif
226  ! initialize spgmr solver
227  call fcvspgmr(jpretype, igstype, maxl, delt, ier)
228  if (ier .ne. 0) then
229  write(*,*) ' sundials_error: fcvspgmr returned ier = ',ier
230  stop
231  endif
232  ! ! initialize Scaled Preconditioned Bi-CGStab solver
233  ! call fcvspbcg(jpretype, maxl, delt, ier)
234  ! if (ier .ne. 0) then
235  ! write(*,*) ' sundials_error: fcspbcg returned ier = ',ier
236  ! stop
237  ! endif
238  ! ! initialize Scaled Preconditioned Transpose-Free Quasi-Minimal Residual
239  ! call fcvsptfqmr(jpretype, maxl, delt, ier)
240  ! if (ier .ne. 0) then
241  ! write(*,*) ' sundials_error: fcvsptfqmr returned ier = ',ier
242  ! stop
243  ! endif
244  ! initialize band preconditioner
245  ! may be good for pdes
246  mu = 3
247  ml = 3
248  call fcvbpinit(neq, mu, ml, ier)
249  if (ier .ne. 0) then
250  write(*,*) ' sundials_error: fcvbpinit returned ier = ',ier
251  stop
252  endif
253  endif
254 end subroutine set_integrator
255 !***********************************END****************************************
256 
257 
258 !********************************BEGINNING*************************************
262 subroutine set_initial_conditions
263  integer :: i,j
264  t = tstart
265  tout = t+timestep
266  allocate(y(neq))
267  y=0
268  if (firstrun) then
269  y(req)=radius !radius
270  if (inertial_term) y(req+1) = 0 !velocity
271  endif
272  y(teq) = temp !temperature
273  y(xoheq) = conv !xOH
274  y(xweq) = 0 !xW
275  if (kin_model==4) then
276  y(kineq(1)) = catalyst*1e-3_dp
277  y(kineq(2)) = polyol1_ini*1e-3_dp
278  y(kineq(3)) = polyol2_ini*1e-3_dp
279  y(kineq(4)) = amine_ini*1e-3_dp
280  y(kineq(5)) = w0*1e-3_dp
281  y(kineq(6)) = isocyanate1_ini*1e-3_dp
282  y(kineq(7)) = isocyanate2_ini*1e-3_dp
283  y(kineq(8)) = isocyanate3_ini*1e-3_dp
284  y(kineq(19)) = temp-273.15_dp
285  endif
286  do j=1,ngas
287  do i=1,p+1
288  y(fceq+(i-1)*ngas+j-1) = cbl(j) !blowing agent concentration
289  enddo
290  enddo
291  do i=1,ngas
292  y(fpeq+i-1) = xgas(i+1)*(pamb+2*sigma/r0) !pressure
293  if (y(fpeq+i-1)<1e-16_dp) y(fpeq+i-1)=1e-16_dp
294  enddo
295 end subroutine set_initial_conditions
296 !***********************************END****************************************
297 
298 
299 !********************************BEGINNING*************************************
303 subroutine growth_rate
304  integer :: i
305  do i=1,ngas
306  grrate(i)=(mb2(i)-nold(i))/timestep
307  enddo
308  do i=1,ngas
309  nold(i)=mb2(i)
310  enddo
311 end subroutine growth_rate
312 !***********************************END****************************************
313 
314 
315 !********************************BEGINNING*************************************
319 subroutine bblinteg
320  write(*,*) 'integrating...'
321  if (firstrun) then
322  call save_integration_header
323  call dim_var(t,y)
324  call molar_balance(y)
325  call growth_rate
326  call save_integration_step(0)
327  endif
328  do iout = 1,its
329  select case (integrator)
330  case(1)
331  call dlsode (sub_ptr, neq, y, t, tout, itol, rtol, atol, itask, &
332  istate, iopt, rwork, lrw, iwork, liw, jac, mf)
333  case(2)
334  call dlsodes (sub_ptr, neq, y, t, tout, itol, rtol, atol, itask, &
335  istate, iopt, rwork, lrw, iwork, liw, jac, mf)
336  case(3)
337  call fcvode(tout, t, y, itask, ier)
338  if (ier .ne. 0) then
339  write(*,*) ' sundials_error: fcvode returned ier = ',ier
340  write(*,*) ' linear solver returned ier = ',iouts(15)
341  call fcvfree
342  stop
343  endif
344  case default
345  stop 'unknown integrator'
346  end select
347  call dim_var(t,y)
348  call molar_balance(y)
349  call growth_rate
350  if (firstrun) call save_integration_step(iout)
351  if (printout) then
352  write(*,'(2x,A4,F8.3,A3,A13,F10.3,A4,A19,F8.3,A3)') &
353  't = ', time, ' s,',&
354  'p_b - p_o = ', bub_pres, ' Pa,', &
355  'p_b - p_o - p_L = ', bub_pres-laplace_pres, ' Pa'
356  endif
357  tout = time+timestep
358  if (gelpoint) then
359  write(*,'(2x,A,f7.3,A)') 'gel point reached at time t = ',time,' s'
360  write(*,'(2x,A,f6.1,A)') 'temperature at gel point T = ',temp,' K'
361  write(*,'(2x,A,f5.3)') 'conversion at gel point X = ',conv
362  exit
363  endif
364  end do
365  if (firstrun) call save_integration_close(iout)
366  write(*,*) 'done: integration'
367  call destroymodenamodels
368  deallocate(d,cbl,xgas,kh,mbl,dhv,mb,mb2,mb3,avconc,pressure,&
369  diff_model,sol_model,cpblg,cpbll,rwork,iwork,dz,y,wblpol,d0)
370 end subroutine bblinteg
371 !***********************************END****************************************
372 end module integration
logical gelpoint
gel point reached (t/f)
Definition: globals.f90:22
real(dp) polyol1_ini
initial concentration of polyol 1
Definition: globals.f90:49
real(dp), dimension(2) nold
moles in bubble
Definition: globals.f90:49
real(dp), dimension(:), allocatable dhv
evaporation heat of blowing agent (for each gas)
Definition: globals.f90:106
integer teq
temperature equation (index)
Definition: globals.f90:29
integer ngas
number of dissolved gases
Definition: globals.f90:29
integer, dimension(:), allocatable sol_model
solubility model 1=constant,2=modena
Definition: globals.f90:102
real(dp) temp
temperature (K)
Definition: globals.f90:49
real(dp), dimension(:), allocatable y
state variables
Definition: globals.f90:106
real(dp) amine_ini
initial concentration of amine
Definition: globals.f90:49
integer req
radius equation (index)
Definition: globals.f90:29
real(dp) radius
bubble radius (m)
Definition: globals.f90:49
real(dp), dimension(:), allocatable kh
Henry constants (for each dissolved gas)
Definition: globals.f90:106
real(dp), dimension(:), allocatable mb2
moles in bubble
Definition: globals.f90:106
real(dp) rel_tol
relative tolerance
Definition: globals.f90:49
real(dp) w0
initial concentration of water (can be zero)
Definition: globals.f90:49
real(dp) isocyanate2_ini
initial concentration of isocyanate 2
Definition: globals.f90:49
real(dp), dimension(:), allocatable dz
spatial discretization
Definition: globals.f90:106
real(dp), dimension(:), allocatable pressure
partial pressure(Pa)
Definition: globals.f90:106
real(dp), dimension(:), allocatable kinsource
kinetic source term
Definition: globals.f90:106
real(dp) s0
initial shell thickness
Definition: globals.f90:49
real(dp) laplace_pres
Laplace pressure (Pa)
Definition: globals.f90:49
logical inertial_term
include inertial term in equations (t/f)
Definition: globals.f90:22
real(dp) sigma
interfacial tension
Definition: globals.f90:49
integer, dimension(:), allocatable diff_model
diffusivity model 1=constant,2=modena
Definition: globals.f90:102
real(dp) isocyanate3_ini
initial concentration of isocyanate 3
Definition: globals.f90:49
real(dp), dimension(:), allocatable mbl
blowing agent molar mass (for each dissolved gas)
Definition: globals.f90:106
real(dp) conv
conversion of polyol
Definition: globals.f90:49
real(dp) time
time (s)
Definition: globals.f90:49
character(len=99) geometry
geometry 3D=spherical, 2D=cylindrical
Definition: globals.f90:11
integer, dimension(:), allocatable kineq
kinetics state variable equations (indexes)
Definition: globals.f90:102
subroutine dgtsl(n, c, d, e, b, info)
Definition: dgtsl.f90:8
real(dp) abs_tol
absolute tolerance
Definition: globals.f90:49
real(dp), dimension(:), allocatable cpbll
heat capacity of blowing agent in liquid phase (for each gas)
Definition: globals.f90:106
real(dp), dimension(:), allocatable d0
initial diffusion coefficients used in non-dimensional routines
Definition: globals.f90:106
real(dp) mshco
mesh coarsening parameter
Definition: globals.f90:49
real(dp), dimension(:), allocatable mb3
total moles
Definition: globals.f90:106
integer lpeq
last pressure equation (index)
Definition: globals.f90:29
real(dp), dimension(:), allocatable xgas
initial molar fraction of gases in the bubble
Definition: globals.f90:106
real(dp), dimension(:), allocatable cbl
concentration profile in reaction mixture
Definition: globals.f90:106
integer integrator
integrator. 1=dlsode,2=dlsodes
Definition: globals.f90:29
real(dp), dimension(:), allocatable d
diffusion coefficients (for each dissolved gas)
Definition: globals.f90:106
real(dp), dimension(:), allocatable avconc
average concentration in reaction mixture
Definition: globals.f90:106
real(dp), dimension(:), allocatable mb
moles in polymer
Definition: globals.f90:106
real(dp) pamb
ambient pressure (in the liquid)
Definition: globals.f90:49
real(dp) polyol2_ini
initial concentration of polyol 2
Definition: globals.f90:49
integer kin_model
reaction kinetics model.
Definition: globals.f90:29
real(dp) timestep
timestep
Definition: globals.f90:49
real(dp), dimension(:), allocatable wblpol
weight fraction of blowing agents in reaction mixture
Definition: globals.f90:106
integer its
number of outer integration outer time steps
Definition: globals.f90:29
integer fceq
first concentration equation (index)
Definition: globals.f90:29
integer xoheq
polyol conversion equation (index)
Definition: globals.f90:29
real(dp), dimension(2) grrate
growth rate
Definition: globals.f90:49
real(dp) isocyanate1_ini
initial concentration of isocyanate 1
Definition: globals.f90:49
real(dp) r0
initial radius
Definition: globals.f90:49
integer fpeq
first pressure equation (index)
Definition: globals.f90:29
namespace with global variables
Definition: globals.f90:8
integer p
number of internal nodes
Definition: globals.f90:29
integer maxts
maximum inner time steps between t and t+h
Definition: globals.f90:29
real(dp), dimension(:), allocatable cpblg
heat capacity of blowing agent in gas phase (for each gas)
Definition: globals.f90:106
real(dp) catalyst
concentration of catalyst
Definition: globals.f90:49
integer xweq
water conversion equation (index)
Definition: globals.f90:29
integer int_meth
stiff or no? See MF for ODEPACK
Definition: globals.f90:29